Merge branch 'develop' of git://github.com/EllisLab/CodeIgniter into develop

Conflicts:
	system/core/Loader.php
	system/database/DB_query_builder.php
	system/database/drivers/cubrid/cubrid_driver.php
	system/database/drivers/mssql/mssql_driver.php
	system/database/drivers/mysql/mysql_driver.php
	system/database/drivers/mysqli/mysqli_driver.php
	system/database/drivers/oci8/oci8_driver.php
	system/database/drivers/odbc/odbc_driver.php
	system/database/drivers/pdo/pdo_driver.php
	system/database/drivers/postgre/postgre_driver.php
	system/database/drivers/sqlite/sqlite_driver.php
	user_guide_src/source/changelog.rst
	user_guide_src/source/database/query_builder.rst
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..84029b9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+
+env:
+  - DB=mysql
+  - DB=pgsql
+  - DB=sqlite
+
+before_script:
+  - pyrus channel-discover pear.php-tools.net
+  - pyrus install http://pear.php-tools.net/get/vfsStream-0.11.2.tgz
+  - phpenv rehash
+  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS ci_test;' -U postgres; fi"
+  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database ci_test;' -U postgres; fi"
+  - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS ci_test;'; fi"
+
+script: phpunit --configuration tests/travis/$DB.phpunit.xml
+
+branches:
+  only:
+    - develop
+    - master
\ No newline at end of file
diff --git a/application/config/autoload.php b/application/config/autoload.php
index db49ca1..b3e63cb 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.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
+ * An open source application development framework for PHP 5.2.4 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:
diff --git a/application/config/config.php b/application/config/config.php
index 17b854b..2628885 100644
--- a/application/config/config.php
+++ b/application/config/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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -297,12 +297,14 @@
 | 'cookie_domain' = Set to .your-domain.com for site-wide cookies
 | 'cookie_path'   =  Typically will be a forward slash
 | 'cookie_secure' =  Cookies will only be set if a secure HTTPS connection exists.
+| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) 
 |
 */
 $config['cookie_prefix']	= "";
 $config['cookie_domain']	= "";
 $config['cookie_path']		= "/";
 $config['cookie_secure']	= FALSE;
+$config['cookie_httponly'] 	= FALSE;
 
 /*
 |--------------------------------------------------------------------------
diff --git a/application/config/constants.php b/application/config/constants.php
index c7203e4..d22d296 100644
--- a/application/config/constants.php
+++ b/application/config/constants.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -66,8 +66,8 @@
 | Display Debug backtrace
 |--------------------------------------------------------------------------
 |
-| If set to TRUE, a backtrace will be displayed along with php errors. If 
-| error_reporting is disabled, the backtrace will not display, regardless 
+| If set to TRUE, a backtrace will be displayed along with php errors. If
+| error_reporting is disabled, the backtrace will not display, regardless
 | of this setting
 |
 */
diff --git a/application/config/database.php b/application/config/database.php
index b1cad90..1949873 100644
--- a/application/config/database.php
+++ b/application/config/database.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -43,7 +43,8 @@
 |	['password'] The password used to connect to the database
 |	['database'] The name of the database you want to connect to
 |	['dbdriver'] The database type. e.g.: mysql.  Currently supported:
-				 mysql, mysqli, pdo, postgre, odbc, mssql, sqlite, oci8
+|				 cubrid, interbase, mssql, mysql, mysqli, oci8, 
+|				 odbc, pdo, postgre, sqlite, sqlite3, sqlsrv
 |	['dbprefix'] You can add an optional prefix, which will be added
 |				 to the table name when using the  Query Builder class
 |	['pconnect'] TRUE/FALSE - Whether to use a persistent connection
@@ -75,23 +76,25 @@
 $active_group = 'default';
 $query_builder = 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'] = FALSE;
-$db['default']['db_debug'] = TRUE;
-$db['default']['cache_on'] = FALSE;
-$db['default']['cachedir'] = '';
-$db['default']['char_set'] = 'utf8';
-$db['default']['dbcollat'] = 'utf8_general_ci';
-$db['default']['swap_pre'] = '';
-$db['default']['autoinit'] = TRUE;
-$db['default']['stricton'] = FALSE;
-$db['default']['failover'] = array();
+$db['default'] = array(
+	'dsn'	=> '',
+	'hostname' => 'localhost',
+	'username' => '',
+	'password' => '',
+	'database' => '',
+	'dbdriver' => 'mysqli',
+	'dbprefix' => '',
+	'pconnect' => FALSE,
+	'db_debug' => TRUE,
+	'cache_on' => FALSE,
+	'cachedir' => '',
+	'char_set' => 'utf8',
+	'dbcollat' => 'utf8_general_ci',
+	'swap_pre' => '',
+	'autoinit' => TRUE,
+	'stricton' => FALSE,
+	'failover' => array()
+);
 
 /* End of file database.php */
 /* Location: ./application/config/database.php */
\ No newline at end of file
diff --git a/application/config/doctypes.php b/application/config/doctypes.php
index 984da59..c7f5b55 100644
--- a/application/config/doctypes.php
+++ b/application/config/doctypes.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -26,15 +26,25 @@
  */
 
 $_doctypes = array(
-					'xhtml11'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
-					'xhtml1-strict'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
-					'xhtml1-trans'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
-					'xhtml1-frame'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
-					'xhtml-basic11'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
-					'html5'			=> '<!DOCTYPE html>',
-					'html4-strict'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
-					'html4-trans'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
-					'html4-frame'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
+					'xhtml11'			=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+					'xhtml1-strict'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+					'xhtml1-trans'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+					'xhtml1-frame'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+					'xhtml-basic11'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
+					'html5'				=> '<!DOCTYPE html>',
+					'html4-strict'		=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+					'html4-trans'		=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+					'html4-frame'		=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+					'mathml1'			=> '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
+					'mathml2'			=> '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
+					'svg10'				=> '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
+					'svg11'				=> '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
+					'svg11-basic'		=> '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
+					'svg11-tiny'		=> '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
+					'xhtml-math-svg-xh'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+					'xhtml-math-svg-sh'	=> '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+					'xhtml-rdfa-1'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
+					'xhtml-rdfa-2'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">'
 					);
 
 /* End of file doctypes.php */
diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php
index 1ae0cef..41de123 100644
--- a/application/config/foreign_chars.php
+++ b/application/config/foreign_chars.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -40,50 +40,55 @@
 	'/Ä/' => 'Ae',
 	'/Ü/' => 'Ue',
 	'/Ö/' => 'Oe',
-	'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
-	'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
+	'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά/' => 'A',
+	'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά/' => 'a',
 	'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
 	'/ç|ć|ĉ|ċ|č/' => 'c',
-	'/Ð|Ď|Đ/' => 'Dj',
-	'/ð|ď|đ/' => 'dj',
-	'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
-	'/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
-	'/Ĝ|Ğ|Ġ|Ģ/' => 'G',
-	'/ĝ|ğ|ġ|ģ/' => 'g',
+	'/Ð|Ď|Đ|Δ/' => 'Dj',
+	'/ð|ď|đ|δ/' => 'dj',
+	'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ/' => 'E',
+	'/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε/' => 'e',
+	'/Ĝ|Ğ|Ġ|Ģ|Γ/' => 'G',
+	'/ĝ|ğ|ġ|ģ|γ/' => 'g',
 	'/Ĥ|Ħ/' => 'H',
 	'/ĥ|ħ/' => 'h',
-	'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
-	'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
+	'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ/' => 'I',
+	'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ/' => 'i',
 	'/Ĵ/' => 'J',
 	'/ĵ/' => 'j',
-	'/Ķ/' => 'K',
-	'/ķ/' => 'k',
-	'/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
-	'/ĺ|ļ|ľ|ŀ|ł/' => 'l',
-	'/Ñ|Ń|Ņ|Ň/' => 'N',
-	'/ñ|ń|ņ|ň|ʼn/' => 'n',
-	'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
-	'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
-	'/Ŕ|Ŗ|Ř/' => 'R',
-	'/ŕ|ŗ|ř/' => 'r',
-	'/Ś|Ŝ|Ş|Š/' => 'S',
-	'/ś|ŝ|ş|š|ſ/' => 's',
-	'/Ţ|Ť|Ŧ/' => 'T',
-	'/ţ|ť|ŧ/' => 't',
+	'/Ķ|Κ/' => 'K',
+	'/ķ|κ/' => 'k',
+	'/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ/' => 'L',
+	'/ĺ|ļ|ľ|ŀ|ł|λ/' => 'l',
+	'/Ñ|Ń|Ņ|Ň|Ν/' => 'N',
+	'/ñ|ń|ņ|ň|ʼn|ν/' => 'n',
+	'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ/' => 'O',
+	'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ/' => 'o',
+	'/Ŕ|Ŗ|Ř|Ρ/' => 'R',
+	'/ŕ|ŗ|ř|ρ/' => 'r',
+	'/Ś|Ŝ|Ş|Ș|Š|Σ/' => 'S',
+	'/ś|ŝ|ş|ș|š|ſ|σ|ς/' => 's',
+	'/Ț|Ţ|Ť|Ŧ|τ/' => 'T',
+	'/ț|ţ|ť|ŧ/' => 't',
 	'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
-	'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
-	'/Ý|Ÿ|Ŷ/' => 'Y',
+	'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ/' => 'u',
+	'/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ/' => 'Y',
 	'/ý|ÿ|ŷ/' => 'y',
 	'/Ŵ/' => 'W',
 	'/ŵ/' => 'w',
-	'/Ź|Ż|Ž/' => 'Z',
-	'/ź|ż|ž/' => 'z',
+	'/Ź|Ż|Ž|Ζ/' => 'Z',
+	'/ź|ż|ž|ζ/' => 'z',
 	'/Æ|Ǽ/' => 'AE',
 	'/ß/'=> 'ss',
 	'/IJ/' => 'IJ',
 	'/ij/' => 'ij',
 	'/Œ/' => 'OE',
-	'/ƒ/' => 'f'
+	'/ƒ/' => 'f',
+	'/ξ/' => 'ks',
+	'/π/' => 'p',
+	'/β/' => 'v',
+	'/μ/' => 'm',
+	'/ψ/' => 'ps',
 );
 
 /* End of file foreign_chars.php */
diff --git a/application/config/hooks.php b/application/config/hooks.php
index 80269df..3500503 100644
--- a/application/config/hooks.php
+++ b/application/config/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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -37,6 +37,5 @@
 */
 
 
-
 /* End of file hooks.php */
 /* Location: ./application/config/hooks.php */
\ No newline at end of file
diff --git a/application/config/memcached.php b/application/config/memcached.php
index 2b1a772..7166b70 100644
--- a/application/config/memcached.php
+++ b/application/config/memcached.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/application/config/migration.php b/application/config/migration.php
index 668c357..88e3982 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -1,8 +1,8 @@
-<?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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -89,5 +89,5 @@
 */
 $config['migration_path'] = APPPATH . 'migrations/';
 
-
-/* End of file migration.php */
\ No newline at end of file
+/* End of file migration.php */
+/* Location: ./application/config/migration.php */
\ No newline at end of file
diff --git a/application/config/mimes.php b/application/config/mimes.php
index d69497a..02e12c0 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,7 +34,8 @@
 |
 */
 
-$mimes = array('hqx'	=>	array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
+$mimes = array(
+				'hqx'	=>	array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
 				'cpt'	=>	'application/mac-compactpro',
 				'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
 				'bin'	=>	array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
@@ -165,4 +166,4 @@
 			);
 
 /* End of file mimes.php */
-/* Location: ./application/config/mimes.php */
+/* Location: ./application/config/mimes.php */
\ No newline at end of file
diff --git a/application/config/profiler.php b/application/config/profiler.php
index f956142..c161a4d 100644
--- a/application/config/profiler.php
+++ b/application/config/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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -38,6 +38,5 @@
 */
 
 
-
 /* End of file profiler.php */
 /* Location: ./application/config/profiler.php */
\ No newline at end of file
diff --git a/application/config/routes.php b/application/config/routes.php
index 53fc7e7..474bda9 100644
--- a/application/config/routes.php
+++ b/application/config/routes.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -67,6 +67,5 @@
 $route['default_controller'] = "welcome";
 $route['404_override'] = '';
 
-
 /* End of file routes.php */
 /* Location: ./application/config/routes.php */
\ No newline at end of file
diff --git a/application/config/smileys.php b/application/config/smileys.php
index 4132aed..baefe53 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.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
+ * An open source application development framework for PHP 5.2.4 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:
diff --git a/application/config/user_agents.php b/application/config/user_agents.php
index e7a6894..60f256e 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.php
@@ -1,8 +1,8 @@
-<?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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -211,4 +211,4 @@
 );
 
 /* End of file user_agents.php */
-/* Location: ./application/config/user_agents.php */
+/* Location: ./application/config/user_agents.php */
\ No newline at end of file
diff --git a/application/controllers/welcome.php b/application/controllers/welcome.php
index 5eb0e96..1ed82d2 100644
--- a/application/controllers/welcome.php
+++ b/application/controllers/welcome.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
+ * An open source application development framework for PHP 5.2.4 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:
@@ -32,10 +32,10 @@
 	 *
 	 * Maps to the following URL
 	 * 		http://example.com/index.php/welcome
-	 *	- or -  
+	 *	- or -
 	 * 		http://example.com/index.php/welcome/index
 	 *	- or -
-	 * Since this controller is set as the default controller in 
+	 * Since this controller is set as the default controller in
 	 * config/routes.php, it's displayed at http://example.com/
 	 *
 	 * So any other public methods not prefixed with an underscore will
diff --git a/application/errors/error_404.php b/application/errors/error_404.php
index 4dd8fc4..7460329 100644
--- a/application/errors/error_404.php
+++ b/application/errors/error_404.php
@@ -1,13 +1,13 @@
-<?php
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 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:
@@ -24,9 +24,7 @@
  * @since		Version 1.0
  * @filesource
  */
-?>
-
-<!DOCTYPE html>
+?><!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="utf-8">
diff --git a/application/errors/error_db.php b/application/errors/error_db.php
index 130ffc1..eb3a752 100644
--- a/application/errors/error_db.php
+++ b/application/errors/error_db.php
@@ -1,13 +1,13 @@
-<?php
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 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:
@@ -24,9 +24,7 @@
  * @since		Version 1.0
  * @filesource
  */
-?>
-
-<!DOCTYPE html>
+?><!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="utf-8">
diff --git a/application/errors/error_general.php b/application/errors/error_general.php
index 2a844a8..59896e1 100644
--- a/application/errors/error_general.php
+++ b/application/errors/error_general.php
@@ -1,13 +1,13 @@
-<?php
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 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:
@@ -24,9 +24,7 @@
  * @since		Version 1.0
  * @filesource
  */
-?>
-
-<!DOCTYPE html>
+?><!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="utf-8">
diff --git a/application/errors/error_php.php b/application/errors/error_php.php
index 8e293cd..3855720 100644
--- a/application/errors/error_php.php
+++ b/application/errors/error_php.php
@@ -1,13 +1,13 @@
-<?php
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 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:
@@ -35,11 +35,11 @@
 <p>Filename: <?php echo $filepath; ?></p>
 <p>Line Number: <?php echo $line; ?></p>
 
-<?php if(defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
-	
+<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
+
 	<p>Backtrace: </p>
 	<?php foreach(debug_backtrace() as $error): ?>
-	
+
 		<?php if(isset($error['file']) &&  ! stristr($error['file'], SYSDIR)): ?>
 			<p style="margin-left:10px">
 			File: <?php echo $error['file'] ?><br />
@@ -47,7 +47,7 @@
 			Function: <?php echo $error['function'] ?>
 			</p>
 		<?php endif ?>
-	
+
 	<?php endforeach ?></p>
 
 <?php endif ?>
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
index acc36b6..45360da 100644
--- a/application/views/welcome_message.php
+++ b/application/views/welcome_message.php
@@ -1,13 +1,13 @@
-<?php
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 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:
@@ -24,9 +24,7 @@
  * @since		Version 1.0
  * @filesource
  */
-?>
-
-<!DOCTYPE html>
+?><!DOCTYPE html>
 <html lang="en">
 <head>
 	<meta charset="utf-8">
@@ -75,7 +73,7 @@
 	#body{
 		margin: 0 15px 0 15px;
 	}
-	
+
 	p.footer{
 		text-align: right;
 		font-size: 11px;
@@ -84,7 +82,7 @@
 		padding: 0 10px 0 10px;
 		margin: 20px 0 0 0;
 	}
-	
+
 	#container{
 		margin: 10px;
 		border: 1px solid #D0D0D0;
diff --git a/index.php b/index.php
index a378266..5a11901 100644
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
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/readme.rst b/readme.rst
index 2369a8d..4707847 100644
--- a/readme.rst
+++ b/readme.rst
@@ -29,7 +29,7 @@
 Server Requirements
 *******************
 
--  PHP version 5.1.6 or newer.
+-  PHP version 5.2.4 or newer.
 
 ************
 Installation
@@ -90,9 +90,9 @@
 Compatibility
 =============
 
-CodeIgniter is compatible with PHP 5.1.6 so all code supplied must stick to
-this requirement. If PHP 5.2 or 5.3 functions or features are used then there
-must be a fallback for PHP 5.1.6.
+CodeIgniter is compatible with PHP 5.2.4 so all code supplied must stick to
+this requirement. If PHP 5.3 or 5.4 functions or features are used then there
+must be a fallback for PHP 5.2.4.
 
 Branching
 =========
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index f4dfd3d..39027e8 100755
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -61,7 +61,7 @@
 	 */
 	public function mark($name)
 	{
-		$this->marker[$name] = microtime();
+		$this->marker[$name] = microtime(TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -93,13 +93,10 @@
 
 		if ( ! isset($this->marker[$point2]))
 		{
-			$this->marker[$point2] = microtime();
+			$this->marker[$point2] = microtime(TRUE);
 		}
 
-		list($sm, $ss) = explode(' ', $this->marker[$point1]);
-		list($em, $es) = explode(' ', $this->marker[$point2]);
-
-		return number_format(($em + $es) - ($sm + $ss), $decimals);
+		return number_format($this->marker[$point2] - $this->marker[$point1], $decimals);
 	}
 
 	// --------------------------------------------------------------------
@@ -122,4 +119,4 @@
 }
 
 /* End of file Benchmark.php */
-/* Location: ./system/core/Benchmark.php */
+/* Location: ./system/core/Benchmark.php */
\ No newline at end of file
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 7af3c48..92187fa 100755
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -133,7 +133,7 @@
  *  Is there a "pre_system" hook?
  * ------------------------------------------------------
  */
-	$EXT->_call_hook('pre_system');
+	$EXT->call_hook('pre_system');
 
 /*
  * ------------------------------------------------------
@@ -194,7 +194,7 @@
  *	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)
 	{
 		exit;
@@ -275,12 +275,12 @@
 		{
 			$x = explode('/', $RTR->routes['404_override'], 2);
 			$class = $x[0];
-			$method = (isset($x[1]) ? $x[1] : 'index');
+			$method = isset($x[1]) ? $x[1] : 'index';
 			if ( ! class_exists($class))
 			{
 				if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
 				{
-					show_404("{$class}/{$method}");
+					show_404($class.'/'.$method);
 				}
 
 				include_once(APPPATH.'controllers/'.$class.'.php');
@@ -288,7 +288,7 @@
 		}
 		else
 		{
-			show_404("{$class}/{$method}");
+			show_404($class.'/'.$method);
 		}
 	}
 
@@ -297,7 +297,7 @@
  *  Is there a "pre_controller" hook?
  * ------------------------------------------------------
  */
-	$EXT->_call_hook('pre_controller');
+	$EXT->call_hook('pre_controller');
 
 /*
  * ------------------------------------------------------
@@ -314,7 +314,7 @@
  *  Is there a "post_controller_constructor" hook?
  * ------------------------------------------------------
  */
-	$EXT->_call_hook('post_controller_constructor');
+	$EXT->call_hook('post_controller_constructor');
 
 /*
  * ------------------------------------------------------
@@ -337,12 +337,12 @@
 			{
 				$x = explode('/', $RTR->routes['404_override'], 2);
 				$class = $x[0];
-				$method = (isset($x[1]) ? $x[1] : 'index');
+				$method = isset($x[1]) ? $x[1] : 'index';
 				if ( ! class_exists($class))
 				{
 					if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
 					{
-						show_404("{$class}/{$method}");
+						show_404($class.'/'.$method);
 					}
 
 					include_once(APPPATH.'controllers/'.$class.'.php');
@@ -352,7 +352,7 @@
 			}
 			else
 			{
-				show_404("{$class}/{$method}");
+				show_404($class.'/'.$method);
 			}
 		}
 
@@ -369,14 +369,14 @@
  *  Is there a "post_controller" hook?
  * ------------------------------------------------------
  */
-	$EXT->_call_hook('post_controller');
+	$EXT->call_hook('post_controller');
 
 /*
  * ------------------------------------------------------
  *  Send the final rendered output to the browser
  * ------------------------------------------------------
  */
-	if ($EXT->_call_hook('display_override') === FALSE)
+	if ($EXT->call_hook('display_override') === FALSE)
 	{
 		$OUT->_display();
 	}
@@ -386,17 +386,17 @@
  *  Is there a "post_system" hook?
  * ------------------------------------------------------
  */
-	$EXT->_call_hook('post_system');
+	$EXT->call_hook('post_system');
 
 /*
  * ------------------------------------------------------
  *  Close the DB connection if one exists
  * ------------------------------------------------------
  */
-	if (class_exists('CI_DB') && isset($CI->db))
+	if (class_exists('CI_DB') && isset($CI->db) && ! $CI->db->pconnect)
 	{
 		$CI->db->close();
 	}
 
 /* End of file CodeIgniter.php */
-/* Location: ./system/core/CodeIgniter.php */
+/* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file
diff --git a/system/core/Common.php b/system/core/Common.php
index 4919793..aeb784b 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Common Functions
  *
@@ -42,15 +40,14 @@
 // ------------------------------------------------------------------------
 
 /**
-* Determines if the current version of PHP is greater then the supplied value
-*
-* Since there are a few places where we conditionally test for PHP > 5
-* we'll set a static variable.
-*
-* @access	public
-* @param	string
-* @return	bool	TRUE if the current version is $version or higher
-*/
+ * Determines if the current version of PHP is greater then the supplied value
+ *
+ * Since there are a few places where we conditionally test for PHP > 5
+ * we'll set a static variable.
+ *
+ * @param	string
+ * @return	bool	TRUE if the current version is $version or higher
+ */
 if ( ! function_exists('is_php'))
 {
 	function is_php($version = '5.0.0')
@@ -76,7 +73,7 @@
  * the file, based on the read-only attribute. is_writable() is also unreliable
  * on Unix servers if safe_mode is on.
  *
- * @access	public
+ * @param	string
  * @return	void
  */
 if ( ! function_exists('is_really_writable'))
@@ -118,18 +115,17 @@
 // ------------------------------------------------------------------------
 
 /**
-* Class registry
-*
-* This function acts as a singleton. If the requested class does not
-* exist it is instantiated and set to a static variable.  If it has
-* previously been instantiated the variable is returned.
-*
-* @access	public
-* @param	string	the class name being requested
-* @param	string	the directory where the class should be found
-* @param	string	the class name prefix
-* @return	object
-*/
+ * Class registry
+ *
+ * This function acts as a singleton. If the requested class does not
+ * exist it is instantiated and set to a static variable. If it has
+ * previously been instantiated the variable is returned.
+ *
+ * @param	string	the class name being requested
+ * @param	string	the directory where the class should be found
+ * @param	string	the class name prefix
+ * @return	object
+ */
 if ( ! function_exists('load_class'))
 {
 	function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
@@ -192,12 +188,12 @@
 // --------------------------------------------------------------------
 
 /**
-* Keeps track of which libraries have been loaded. This function is
-* called by the load_class() function above
-*
-* @access	public
-* @return	array
-*/
+ * Keeps track of which libraries have been loaded. This function is
+ * called by the load_class() function above
+ *
+ * @param	string
+ * @return	array
+ */
 if ( ! function_exists('is_loaded'))
 {
 	function &is_loaded($class = '')
@@ -216,14 +212,14 @@
 // ------------------------------------------------------------------------
 
 /**
-* Loads the main config.php file
-*
-* This function lets us grab the config file even if the Config class
-* hasn't been instantiated yet
-*
-* @access	private
-* @return	array
-*/
+ * Loads the main config.php file
+ *
+ * This function lets us grab the config file even if the Config class
+ * hasn't been instantiated yet
+ *
+ * @param	array
+ * @return	array
+ */
 if ( ! function_exists('get_config'))
 {
 	function &get_config($replace = array())
@@ -276,11 +272,11 @@
 // ------------------------------------------------------------------------
 
 /**
-* Returns the specified config item
-*
-* @access	public
-* @return	mixed
-*/
+ * Returns the specified config item
+ *
+ * @param	string
+ * @return	mixed
+ */
 if ( ! function_exists('config_item'))
 {
 	function config_item($item)
@@ -305,17 +301,19 @@
 // ------------------------------------------------------------------------
 
 /**
-* Error Handler
-*
-* This function lets us invoke the exception class and
-* display errors using the standard error template located
-* in application/errors/errors.php
-* This function will send the error page directly to the
-* browser and exit.
-*
-* @access	public
-* @return	void
-*/
+ * Error Handler
+ *
+ * This function lets us invoke the exception class and
+ * display errors using the standard error template located
+ * in application/errors/errors.php
+ * This function will send the error page directly to the
+ * browser and exit.
+ *
+ * @param	string
+ * @param	int
+ * @param	string
+ * @return	void
+ */
 if ( ! function_exists('show_error'))
 {
 	function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
@@ -329,15 +327,16 @@
 // ------------------------------------------------------------------------
 
 /**
-* 404 Page Handler
-*
-* This function is similar to the show_error() function above
-* However, instead of the standard error template it displays
-* 404 errors.
-*
-* @access	public
-* @return	void
-*/
+ * 404 Page Handler
+ *
+ * This function is similar to the show_error() function above
+ * However, instead of the standard error template it displays
+ * 404 errors.
+ *
+ * @param	string
+ * @param	bool
+ * @return	void
+ */
 if ( ! function_exists('show_404'))
 {
 	function show_404($page = '', $log_error = TRUE)
@@ -351,14 +350,16 @@
 // ------------------------------------------------------------------------
 
 /**
-* Error Logging Interface
-*
-* We use this as a simple mechanism to access the logging
-* class and send messages to be logged.
-*
-* @access	public
-* @return	void
-*/
+ * Error Logging Interface
+ *
+ * We use this as a simple mechanism to access the logging
+ * class and send messages to be logged.
+ *
+ * @param	string
+ * @param	string
+ * @param	bool
+ * @return	void
+ */
 if ( ! function_exists('log_message'))
 {
 	function log_message($level = 'error', $message, $php_error = FALSE)
@@ -380,8 +381,7 @@
 /**
  * Set HTTP Status Header
  *
- * @access	public
- * @param	int		the status code
+ * @param	int	the status code
  * @param	string
  * @return	void
  */
@@ -467,19 +467,22 @@
 // --------------------------------------------------------------------
 
 /**
-* Exception Handler
-*
-* This is the custom exception handler that is declaired at the top
-* of Codeigniter.php.  The main reason we use this is to permit
-* PHP errors to be logged in our own log files since the user may
-* not have access to server logs. Since this function
-* effectively intercepts PHP errors, however, we also need
-* to display errors based on the current error_reporting level.
-* We do that with the use of a PHP error template.
-*
-* @access	private
-* @return	void
-*/
+ * Exception Handler
+ *
+ * This is the custom exception handler that is declaired at the top
+ * of Codeigniter.php. The main reason we use this is to permit
+ * PHP errors to be logged in our own log files since the user may
+ * not have access to server logs. Since this function
+ * effectively intercepts PHP errors, however, we also need
+ * to display errors based on the current error_reporting level.
+ * We do that with the use of a PHP error template.
+ *
+ * @param	int
+ * @param	string
+ * @param	string
+ * @param	int
+ * @return	void
+ */
 if ( ! function_exists('_exception_handler'))
 {
 	function _exception_handler($severity, $message, $filepath, $line)
@@ -521,8 +524,8 @@
  * This prevents sandwiching null characters
  * between ascii characters, like Java\0script.
  *
- * @access	public
  * @param	string
+ * @param	bool
  * @return	string
  */
 if ( ! function_exists('remove_invisible_characters'))
@@ -554,12 +557,11 @@
 // ------------------------------------------------------------------------
 
 /**
-* Returns HTML escaped variable
-*
-* @access	public
-* @param	mixed
-* @return	mixed
-*/
+ * Returns HTML escaped variable
+ *
+ * @param	mixed
+ * @return	mixed
+ */
 if ( ! function_exists('html_escape'))
 {
 	function html_escape($var)
@@ -571,4 +573,4 @@
 }
 
 /* End of file Common.php */
-/* Location: ./system/core/Common.php */
+/* Location: ./system/core/Common.php */
\ No newline at end of file
diff --git a/system/core/Config.php b/system/core/Config.php
index 6841743..91826bd 100755
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -76,7 +76,7 @@
 		log_message('debug', 'Config Class Initialized');
 
 		// Set the base_url automatically if none was provided
-		if ($this->config['base_url'] == '')
+		if (empty($this->config['base_url']))
 		{
 			if (isset($_SERVER['HTTP_HOST']))
 			{
diff --git a/system/core/Controller.php b/system/core/Controller.php
index 0dc1317..05e1bf5 100644
--- a/system/core/Controller.php
+++ b/system/core/Controller.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index bf99012..f36b315 100755
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Exceptions Class
  *
@@ -163,7 +161,7 @@
 	 * @param	string	the error line number
 	 * @return	string
 	 */
-	function show_php_error($severity, $message, $filepath, $line)
+	public function show_php_error($severity, $message, $filepath, $line)
 	{
 		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
 		$filepath = str_replace('\\', '/', $filepath);
@@ -189,4 +187,4 @@
 }
 
 /* End of file Exceptions.php */
-/* Location: ./system/core/Exceptions.php */
+/* Location: ./system/core/Exceptions.php */
\ No newline at end of file
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index e1ac58e..68e30ef 100755
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Hooks Class
  *
@@ -51,7 +49,7 @@
 	 *
 	 * @var array
 	 */
-	public $hooks			= array();
+	public $hooks		= array();
 	/**
 	 * Determines wether hook is in progress, used to prevent infinte loops
 	 *
@@ -59,23 +57,17 @@
 	 */
 	public $in_progress	= FALSE;
 
-	public function __construct()
-	{
-		$this->_initialize();
-		log_message('debug', 'Hooks Class Initialized');
-	}
-
-	// --------------------------------------------------------------------
-
 	/**
 	 * Initialize the Hooks Preferences
 	 *
 	 * @return	void
 	 */
-	private function _initialize()
+	public function __construct()
 	{
 		$CFG =& load_class('Config', 'core');
 
+		log_message('debug', 'Hooks Class Initialized');
+
 		// If hooks are not enabled in the config file
 		// there is nothing else to do
 		if ($CFG->item('enable_hooks') == FALSE)
@@ -84,7 +76,7 @@
 		}
 
 		// Grab the "hooks" definition file.
-		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
 		}
@@ -113,14 +105,14 @@
 	 * @param	string	the hook name
 	 * @return	mixed
 	 */
-	public function _call_hook($which = '')
+	public function call_hook($which = '')
 	{
 		if ( ! $this->enabled OR ! isset($this->hooks[$which]))
 		{
 			return FALSE;
 		}
 
-		if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
+		if (isset($this->hooks[$which][0]) && is_array($this->hooks[$which][0]))
 		{
 			foreach ($this->hooks[$which] as $val)
 			{
@@ -167,7 +159,7 @@
 		// Set file path
 		// -----------------------------------
 
-		if ( ! isset($data['filepath']) OR ! isset($data['filename']))
+		if ( ! isset($data['filepath'], $data['filename']))
 		{
 			return FALSE;
 		}
@@ -187,12 +179,12 @@
 		$function	= FALSE;
 		$params		= '';
 
-		if (isset($data['class']) AND $data['class'] != '')
+		if ( ! empty($data['class']))
 		{
 			$class = $data['class'];
 		}
 
-		if (isset($data['function']))
+		if ( ! empty($data['function']))
 		{
 			$function = $data['function'];
 		}
@@ -202,7 +194,7 @@
 			$params = $data['params'];
 		}
 
-		if ($class === FALSE AND $function === FALSE)
+		if ($class === FALSE && $function === FALSE)
 		{
 			return FALSE;
 		}
@@ -244,4 +236,4 @@
 }
 
 /* End of file Hooks.php */
-/* Location: ./system/core/Hooks.php */
+/* Location: ./system/core/Hooks.php */
\ No newline at end of file
diff --git a/system/core/Input.php b/system/core/Input.php
index 5a4659a..6e68859 100755
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -228,7 +228,7 @@
 	/**
 	* Set cookie
 	*
-	* Accepts six parameter, or you can submit an associative
+	* Accepts seven parameters, or you can submit an associative
 	* array in the first parameter containing all the values.
 	*
 	* @param	mixed
@@ -238,14 +238,15 @@
 	* @param	string	the cookie path
 	* @param	string	the cookie prefix
 	* @param	bool	true makes the cookie secure
+	* @param	bool	true makes the cookie accessible via http(s) only (no javascript)
 	* @return	void
 	*/
-	public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
+	public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
 	{
 		if (is_array($name))
 		{
 			// always leave 'name' in last place, as the loop will break otherwise, due to $$item
-			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item)
+			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item)
 			{
 				if (isset($name[$item]))
 				{
@@ -270,6 +271,10 @@
 		{
 			$secure = config_item('cookie_secure');
 		}
+		if ($httponly == FALSE && config_item('cookie_httponly') != FALSE)
+		{
+			$httponly = config_item('cookie_httponly');
+		}
 
 		if ( ! is_numeric($expire))
 		{
@@ -280,7 +285,7 @@
 			$expire = ($expire > 0) ? time() + $expire : 0;
 		}
 
-		setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);
+		setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
 	}
 
 	// --------------------------------------------------------------------
@@ -366,36 +371,7 @@
 	*/
 	public function valid_ip($ip)
 	{
-		// if php version >= 5.2, use filter_var to check validate ip.
-		if (function_exists('filter_var'))
-		{
-			return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
-		}
-
-		$ip_segments = explode('.', $ip);
-
-		// Always 4 segments needed
-		if (count($ip_segments) !== 4)
-		{
-			return FALSE;
-		}
-		// IP can not start with 0
-		if ($ip_segments[0][0] == '0')
-		{
-			return FALSE;
-		}
-		// Check each segment
-		foreach ($ip_segments as $segment)
-		{
-			// 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)
-			{
-				return FALSE;
-			}
-		}
-
-		return TRUE;
+		return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/core/Lang.php b/system/core/Lang.php
index c40a685..9ef76f4 100755
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/system/core/Loader.php b/system/core/Loader.php
index b1e315d..5f283dc 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Loader Class
  *
@@ -281,7 +279,7 @@
 				continue;
 			}
 
-			if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
+			if ($db_conn !== FALSE && ! class_exists('CI_DB'))
 			{
 				if ($db_conn === TRUE)
 				{
@@ -324,7 +322,7 @@
 		$CI =& get_instance();
 
 		// Do we even need to load the database class?
-		if (class_exists('CI_DB') AND $return == FALSE AND $query_builder == NULL AND isset($CI->db) AND is_object($CI->db))
+		if (class_exists('CI_DB') && $return == FALSE && $query_builder == NULL && isset($CI->db) && is_object($CI->db))
 		{
 			return FALSE;
 		}
@@ -399,13 +397,13 @@
 	/**
 	 * Load View
 	 *
-	 * This function is used to load a "view" file.  It has three parameters:
+	 * This function is used to load a "view" file. It has three parameters:
 	 *
 	 * 1. The name of the "view" file to be included.
 	 * 2. An associative array of data to be extracted for use in the view.
-	 * 3. TRUE/FALSE - whether to return the data or load it.  In
-	 * some cases it's advantageous to be able to return data so that
-	 * a developer can process it in some way.
+	 * 3. TRUE/FALSE - whether to return the data or load it. In
+	 *    some cases it's advantageous to be able to return data so that
+	 *    a developer can process it in some way.
 	 *
 	 * @param	string
 	 * @param	array
@@ -447,14 +445,14 @@
 	 */
 	public function vars($vars = array(), $val = '')
 	{
-		if ($val != '' AND is_string($vars))
+		if ($val != '' && is_string($vars))
 		{
 			$vars = array($vars => $val);
 		}
 
 		$vars = $this->_ci_object_to_array($vars);
 
-		if (is_array($vars) AND count($vars) > 0)
+		if (is_array($vars) && count($vars) > 0)
 		{
 			foreach ($vars as $key => $val)
 			{
@@ -615,13 +613,22 @@
 	 *
 	 * Loads a driver library
 	 *
-	 * @param	string	the name of the class
+	 * @param	mixed	the name of the class or array of classes
 	 * @param	mixed	the optional parameters
 	 * @param	string	an optional object name
 	 * @return	void
 	 */
 	public function driver($library = '', $params = NULL, $object_name = NULL)
 	{
+		if (is_array($library))
+		{
+			foreach ($library as $driver)
+			{
+				$this->driver($driver);
+			}
+			return FALSE;
+		}
+
 		if ( ! class_exists('CI_Driver_Library'))
 		{
 			// we aren't instantiating an object here, that'll be done by the Library itself
@@ -651,7 +658,7 @@
 	 * Prepends a parent path to the library, model, helper, and config path arrays
 	 *
 	 * @param	string
-	 * @param 	boolean
+	 * @param 	bool
 	 * @return	void
 	 */
 	public function add_package_path($path, $view_cascade=TRUE)
@@ -692,9 +699,9 @@
 	 * Remove a path from the library, model, and helper path arrays if it exists
 	 * If no path is provided, the most recently added path is removed.
 	 *
-	 * @param	type
+	 * @param	string
 	 * @param 	bool
-	 * @return	type
+	 * @return	void
 	 */
 	public function remove_package_path($path = '', $remove_config_path = TRUE)
 	{
@@ -755,7 +762,7 @@
 		// Set the default data variables
 		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
 		{
-			$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
+			$$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE;
 		}
 
 		$file_exists = FALSE;
@@ -1010,11 +1017,11 @@
 	 * @param	string
 	 * @param	bool
 	 * @param	string	an optional object name
-	 * @return	null
+	 * @return	void
 	 */
 	protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
 	{
-		// Is there an associated config file for this class?  Note: these should always be lowercase
+		// Is there an associated config file for this class? Note: these should always be lowercase
 		if ($config === NULL)
 		{
 			// Fetch the config paths containing any package paths
@@ -1029,24 +1036,24 @@
 					// We test for both uppercase and lowercase, for servers that
 					// are case-sensitive with regard to file names. Check for environment
 					// first, global next
-					if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
+					if (defined('ENVIRONMENT') && file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
 					{
-						include($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
+						include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
 						break;
 					}
-					elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
+					elseif (defined('ENVIRONMENT') && file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
 					{
-						include($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
+						include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
 						break;
 					}
-					elseif (file_exists($path .'config/'.strtolower($class).'.php'))
+					elseif (file_exists($path.'config/'.strtolower($class).'.php'))
 					{
-						include($path .'config/'.strtolower($class).'.php');
+						include($path.'config/'.strtolower($class).'.php');
 						break;
 					}
-					elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php'))
+					elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
 					{
-						include($path .'config/'.ucfirst(strtolower($class)).'.php');
+						include($path.'config/'.ucfirst(strtolower($class)).'.php');
 						break;
 					}
 				}
@@ -1086,7 +1093,7 @@
 
 		if (is_null($object_name))
 		{
-			$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
+			$classvar = isset($this->_ci_varmap[$class]) ? $this->_ci_varmap[$class] : $class;
 		}
 		else
 		{
@@ -1104,7 +1111,7 @@
 		}
 		else
 		{
-			$CI->$classvar = new $name;
+			$CI->$classvar = new $name();
 		}
 	}
 
@@ -1121,7 +1128,7 @@
 	 */
 	protected function _ci_autoloader()
 	{
-		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
+		if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
 		}
@@ -1157,14 +1164,14 @@
 		// Autoload helpers and languages
 		foreach (array('helper', 'language') as $type)
 		{
-			if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
+			if (isset($autoload[$type]) && count($autoload[$type]) > 0)
 			{
 				$this->$type($autoload[$type]);
 			}
 		}
 
 		// Load libraries
-		if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
+		if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
 		{
 			// Load the database driver.
 			if (in_array('database', $autoload['libraries']))
@@ -1199,7 +1206,7 @@
 	 */
 	protected function _ci_object_to_array($object)
 	{
-		return (is_object($object)) ? get_object_vars($object) : $object;
+		return is_object($object) ? get_object_vars($object) : $object;
 	}
 
 	// --------------------------------------------------------------------
@@ -1243,6 +1250,7 @@
 			return $filename;
 		}
 	}
+
 }
 
 /* End of file Loader.php */
diff --git a/system/core/Model.php b/system/core/Model.php
index a595a6a..49b8d34 100755
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/system/core/Output.php b/system/core/Output.php
index abd8a0e..3cb4062 100755
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Output Class
  *
@@ -45,37 +43,37 @@
 	 *
 	 * @var string
 	 */
-	protected $final_output;
+	public $final_output;
 	/**
 	 * Cache expiration time
 	 *
 	 * @var int
 	 */
-	protected $cache_expiration	= 0;
+	public $cache_expiration	= 0;
 	/**
 	 * List of server headers
 	 *
 	 * @var array
 	 */
-	protected $headers			= array();
+	public $headers			= array();
 	/**
 	 * List of mime types
 	 *
 	 * @var array
 	 */
-	protected $mime_types		= array();
+	public $mime_types		= array();
 	/**
 	 * Determines wether profiler is enabled
 	 *
 	 * @var book
 	 */
-	protected $enable_profiler	= FALSE;
+	public $enable_profiler		= FALSE;
 	/**
 	 * Determines if output compression is enabled
 	 *
 	 * @var bool
 	 */
-	protected $_zlib_oc			= FALSE;
+	protected $_zlib_oc		= FALSE;
 	/**
 	 * List of profiler sections
 	 *
@@ -87,14 +85,14 @@
 	 *
 	 * @var bool
 	 */
-	protected $parse_exec_vars	= TRUE;
+	public $parse_exec_vars		= TRUE;
 
 	public function __construct()
 	{
 		$this->_zlib_oc = @ini_get('zlib.output_compression');
 
 		// Get mime types for later
-		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
+		if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
 		{
 			include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
 		}
@@ -226,10 +224,30 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Get Current Content Type Header
+	 *
+	 * @return	string	'text/html', if not already set
+	 */
+	public function get_content_type()
+	{
+		for ($i = 0, $c = count($this->headers); $i < $c; $i++)
+		{
+			if (preg_match('/^Content-Type:\s(.+)$/', $this->headers[$i][0], $matches))
+			{
+				return $matches[1];
+			}
+		}
+
+		return 'text/html';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Set HTTP Status Header
 	 * moved to Common procedural functions in 1.7.2
 	 *
-	 * @param	int		the status code
+	 * @param	int	the status code
 	 * @param	string
 	 * @return	void
 	 */
@@ -249,7 +267,7 @@
 	 */
 	public function enable_profiler($val = TRUE)
 	{
-		$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
+		$this->enable_profiler = is_bool($val) ? $val : TRUE;
 		return $this;
 	}
 
@@ -267,7 +285,7 @@
 	{
 		foreach ($sections as $section => $enable)
 		{
-			$this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
+			$this->_profiler_sections[$section] = ($enable !== FALSE);
 		}
 
 		return $this;
@@ -278,12 +296,12 @@
 	/**
 	 * Set Cache
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @return	void
 	 */
 	public function cache($time)
 	{
-		$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
+		$this->cache_expiration = is_numeric($time) ? $time : 0;
 		return $this;
 	}
 
@@ -297,7 +315,7 @@
 	 * $this->final_output
 	 *
 	 * This function sends the finalized output data to the browser along
-	 * with any server headers and profile data.  It also stops the
+	 * with any server headers and profile data. It also stops the
 	 * benchmark timer so the page rendering speed and memory usage can be shown.
 	 *
 	 * @param 	string
@@ -343,7 +361,7 @@
 
 		if ($this->parse_exec_vars === TRUE)
 		{
-			$memory	 = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
+			$memory	= function_exists('memory_get_usage') ? round(memory_get_usage()/1024/1024, 2).'MB' : '0';
 
 			$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
 		}
@@ -520,4 +538,4 @@
 }
 
 /* End of file Output.php */
-/* Location: ./system/core/Output.php */
+/* Location: ./system/core/Output.php */
\ No newline at end of file
diff --git a/system/core/Router.php b/system/core/Router.php
index d213195..5477fed 100755
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Router Class
  *
@@ -111,7 +109,7 @@
 		// 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();
-		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
+		if ($this->config->item('enable_query_strings') === TRUE && isset($_GET[$this->config->item('controller_trigger')]))
 		{
 			if (isset($_GET[$this->config->item('directory_trigger')]))
 			{
@@ -133,7 +131,7 @@
 		}
 
 		// Load the routes.php file.
-		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
 		}
@@ -147,7 +145,7 @@
 
 		// Set the default controller so we can display it in the event
 		// 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']);
+		$this->default_controller = empty($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.
 		if (count($segments) > 0)
@@ -248,8 +246,8 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Validates the supplied segments.  Attempts to determine the path to
-	 * the controller.
+	 * Validates the supplied segments.
+	 * Attempts to determine the path to the controller.
 	 *
 	 * @param	array
 	 * @return	array
@@ -340,7 +338,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Parse Routes
+	 * Parse Routes
 	 *
 	 * This function matches any routes that may exist in
 	 * the config/routes.php file against the URI to
@@ -369,7 +367,7 @@
 			if (preg_match('#^'.$key.'$#', $uri))
 			{
 				// Do we have a back-reference?
-				if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
+				if (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
 				{
 					$val = preg_replace('#^'.$key.'$#', $val, $uri);
 				}
@@ -411,7 +409,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Set the method name
+	 * Set the method name
 	 *
 	 * @param	string
 	 * @return	void
@@ -424,7 +422,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Fetch the current method
+	 * Fetch the current method
 	 *
 	 * @return	string
 	 */
@@ -441,7 +439,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Set the directory name
+	 * Set the directory name
 	 *
 	 * @param	string
 	 * @return	void
@@ -454,7 +452,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Fetch the sub-directory (if any) that contains the requested controller class
+	 * Fetch the sub-directory (if any) that contains the requested controller class
 	 *
 	 * @return	string
 	 */
@@ -466,10 +464,10 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Set the controller overrides
+	 * Set the controller overrides
 	 *
 	 * @param	array
-	 * @return	null
+	 * @return	void
 	 */
 	public function _set_overrides($routing)
 	{
@@ -483,7 +481,7 @@
 			$this->set_directory($routing['directory']);
 		}
 
-		if (isset($routing['controller']) AND $routing['controller'] != '')
+		if (isset($routing['controller']) && $routing['controller'] != '')
 		{
 			$this->set_class($routing['controller']);
 		}
@@ -498,4 +496,4 @@
 }
 
 /* End of file Router.php */
-/* Location: ./system/core/Router.php */
+/* Location: ./system/core/Router.php */
\ No newline at end of file
diff --git a/system/core/Security.php b/system/core/Security.php
index 2bffa41..ac39ce9 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -196,7 +196,15 @@
 			return FALSE;
 		}
 
-		setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
+		setcookie(
+			$this->_csrf_cookie_name, 
+			$this->_csrf_hash, 
+			$expire, 
+			config_item('cookie_path'), 
+			config_item('cookie_domain'), 
+			$secure_cookie,
+			config_item('cookie_httponly')
+		);
 		log_message('debug', 'CRSF cookie Set');
 
 		return $this;
diff --git a/system/core/URI.php b/system/core/URI.php
index b28ee19..48bb7ae 100755
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -22,7 +22,6 @@
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
- * @filesource
  */
 
 // ------------------------------------------------------------------------
@@ -93,7 +92,7 @@
 		if (strtoupper($this->config->item('uri_protocol')) === 'AUTO')
 		{
 			// Is the request coming from the command line?
-			if (php_sapi_name() === 'cli' OR defined('STDIN'))
+			if ($this->_is_cli_request())
 			{
 				$this->_set_uri_string($this->_parse_cli_args());
 				return;
@@ -227,6 +226,21 @@
 	}
 
 	// --------------------------------------------------------------------
+	
+	/**
+	 * Is cli Request?
+	 *
+	 * Duplicate of function from the Input class to test to see if a request was made from the command line
+	 *
+	 * @return 	boolean
+	 */
+	protected function _is_cli_request()
+	{
+		return (php_sapi_name() == 'cli') OR defined('STDIN');
+	}
+
+	
+	// --------------------------------------------------------------------
 
 	/**
 	 * Parse cli arguments
@@ -444,9 +458,7 @@
 				return array();
 			}
 
-			return function_exists('array_fill_keys')
-				? array_fill_keys($default, FALSE)
-				: array_combine($default, array_fill(0, count($default), FALSE));
+			return array_fill_keys($default, FALSE);
 		}
 
 		$segments = array_slice($this->$segment_array(), ($n - 1));
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 0e180d3..ba35674 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/system/database/DB.php b/system/database/DB.php
index 9ce6103..b28439b 100755
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -37,11 +37,11 @@
 function &DB($params = '', $query_builder_override = NULL)
 {
 	// Load the DB config file if a DSN string wasn't passed
-	if (is_string($params) AND strpos($params, '://') === FALSE)
+	if (is_string($params) && strpos($params, '://') === FALSE)
 	{
 		// Is the config file in the environment folder?
 		if (( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php'))
-			AND ! file_exists($file_path = APPPATH.'config/database.php'))
+			&& ! file_exists($file_path = APPPATH.'config/database.php'))
 		{
 			show_error('The configuration file database.php does not exist.');
 		}
@@ -74,34 +74,30 @@
 		 *  parameter. DSNs must have this prototype:
 		 *  $dsn = 'driver://username:password@hostname/database';
 		 */
-		if (($dns = @parse_url($params)) === FALSE)
+		if (($dsn = @parse_url($params)) === FALSE)
 		{
 			show_error('Invalid DB Connection String');
 		}
 
 		$params = array(
-				'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)) : ''
+				'dbdriver'	=> $dsn['scheme'],
+				'hostname'	=> isset($dsn['host']) ? rawurldecode($dsn['host']) : '',
+				'port'		=> isset($dsn['port']) ? rawurldecode($dsn['port']) : '',
+				'username'	=> isset($dsn['user']) ? rawurldecode($dsn['user']) : '',
+				'password'	=> isset($dsn['pass']) ? rawurldecode($dsn['pass']) : '',
+				'database'	=> isset($dsn['path']) ? rawurldecode(substr($dsn['path'], 1)) : ''
 			);
 
 		// were additional config items set?
-		if (isset($dns['query']))
+		if (isset($dsn['query']))
 		{
-			parse_str($dns['query'], $extra);
+			parse_str($dsn['query'], $extra);
+
 			foreach ($extra as $key => $val)
 			{
-				// booleans please
-				if (strtoupper($val) === 'TRUE')
+				if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL')))
 				{
-					$val = TRUE;
-				}
-				elseif (strtoupper($val) === 'FALSE')
-				{
-					$val = FALSE;
+					$val = var_export($val);
 				}
 
 				$params[$key] = $val;
@@ -138,7 +134,12 @@
 		class CI_DB extends CI_DB_driver { }
 	}
 
-	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');
+	// Load the DB driver
+	$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
+
+	if ( ! file_exists($driver_file)) show_error('Invalid DB driver');
+
+	require_once($driver_file);
 
 	// Instantiate the DB adapter
 	$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 79651fc..ff94285 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -177,10 +177,10 @@
 	 */
 	public function delete_all()
 	{
-		delete_files($this->db->cachedir, TRUE);
+		delete_files($this->db->cachedir, TRUE, 0, TRUE);
 	}
 
 }
 
 /* End of file DB_cache.php */
-/* Location: ./system/database/DB_cache.php */
+/* Location: ./system/database/DB_cache.php */
\ No newline at end of file
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 6a20c00..ef77b59 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -38,7 +38,7 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-class CI_DB_driver {
+abstract class CI_DB_driver {
 
 	public $dsn;
 	public $username;
@@ -99,9 +99,13 @@
 	 */
 	public function initialize()
 	{
-		// If an existing connection resource is available
-		// there is no need to connect and select the database
-		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		/* If an established connection is available, then there's
+		 * no need to connect and select the database.
+		 *
+		 * Depending on the database driver, conn_id can be either
+		 * boolean TRUE, a resource or an object.
+		 */
+		if ($this->conn_id)
 		{
 			return TRUE;
 		}
@@ -165,7 +169,39 @@
 		}
 
 		// Now we set the character set and that's all
-		return $this->db_set_charset($this->char_set, $this->dbcollat);
+		return $this->db_set_charset($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.
+	 *
+	 * This is just a dummy method to allow drivers without such
+	 * functionality to not declare it, while others will override it.
+	 *
+	 * @return      void
+	 */
+	public function reconnect()
+	{
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select database
+	 *
+	 * This is just a dummy method to allow drivers without such
+	 * functionality to not declare it, while others will override it.
+	 *
+	 * @return      bool
+	 */
+	public function db_select()
+	{
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -174,12 +210,11 @@
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
-	public function db_set_charset($charset, $collation = '')
+	public function db_set_charset($charset)
 	{
-		if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset, $collation))
+		if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset))
 		{
 			log_message('error', 'Unable to set database connection charset: '.$charset);
 
@@ -266,17 +301,13 @@
 		{
 			log_message('error', 'Invalid query: '.$sql);
 
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_invalid_query');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
 		}
 
 		// Verify table prefix and replace if necessary
-		if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )
+		if ($this->dbprefix != '' && $this->swap_pre != '' && $this->dbprefix != $this->swap_pre)
 		{
-			$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
+			$sql = preg_replace('/(\W)'.$this->swap_pre.'(\S+?)/', '\\1'.$this->dbprefix.'\\2', $sql);
 		}
 
 		// Compile binds if needed
@@ -288,15 +319,12 @@
 		// Is query caching enabled? If the query is a "read type"
 		// we will load the caching class and return the previously
 		// cached query if it exists
-		if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
+		if ($this->cache_on == TRUE && stripos($sql, 'SELECT') !== FALSE && $this->_cache_init())
 		{
-			if ($this->_cache_init())
+			$this->load_rdriver();
+			if (FALSE !== ($cache = $this->CACHE->read($sql)))
 			{
-				$this->load_rdriver();
-				if (FALSE !== ($cache = $this->CACHE->read($sql)))
-				{
-					return $cache;
-				}
+				return $cache;
 			}
 		}
 
@@ -307,7 +335,7 @@
 		}
 
 		// Start the Query Timer
-		$time_start = list($sm, $ss) = explode(' ', microtime());
+		$time_start = microtime(TRUE);
 
 		// Run the Query
 		if (FALSE === ($this->result_id = $this->simple_query($sql)))
@@ -335,25 +363,19 @@
 				$this->trans_complete();
 
 				// Display errors
-				return $this->display_error(
-								array(
-									'Error Number: '.$error['code'],
-									$error['message'],
-									$sql
-								)
-							);
+				return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql));
 			}
 
 			return FALSE;
 		}
 
 		// Stop and aggregate the query time results
-		$time_end = list($em, $es) = explode(' ', microtime());
-		$this->benchmark += ($em + $es) - ($sm + $ss);
+		$time_end = microtime(TRUE);
+		$this->benchmark += $time_end - $time_start;
 
 		if ($this->save_queries == TRUE)
 		{
-			$this->query_times[] = ($em + $es) - ($sm + $ss);
+			$this->query_times[] = $time_end - $time_start;
 		}
 
 		// Increment the query counter
@@ -365,7 +387,7 @@
 		{
 			// If caching is enabled we'll auto-cleanup any
 			// existing files related to this particular URI
-			if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
+			if ($this->cache_on == TRUE && $this->cache_autodel == TRUE && $this->_cache_init())
 			{
 				$this->CACHE->delete();
 			}
@@ -385,11 +407,9 @@
 		$driver		= $this->load_rdriver();
 		$RES		= new $driver($this);
 
-		$RES->num_rows	= $RES->num_rows();
-
-		// Is query caching enabled?  If so, we'll serialize the
+		// Is query caching enabled? If so, we'll serialize the
 		// result object and save it to a cache file.
-		if ($this->cache_on == TRUE AND $this->_cache_init())
+		if ($this->cache_on == TRUE && $this->_cache_init())
 		{
 			// We'll create a new instance of the result object
 			// only without the platform specific driver since
@@ -398,9 +418,9 @@
 			// result object, so we'll have to compile the data
 			// and save it)
 			$CR = new CI_DB_result();
-			$CR->num_rows		= $RES->num_rows();
 			$CR->result_object	= $RES->result_object();
 			$CR->result_array	= $RES->result_array();
+			$CR->num_rows		= $RES->num_rows();
 
 			// Reset these since cached objects can not utilize resource IDs.
 			$CR->conn_id		= NULL;
@@ -591,7 +611,8 @@
 
 		// The count of bind should be 1 less then the count of segments
 		// If there are more bind arguments trim it down
-		if (count($binds) >= count($segments)) {
+		if (count($binds) >= count($segments))
+		{
 			$binds = array_slice($binds, 0, count($segments)-1);
 		}
 
@@ -600,8 +621,7 @@
 		$i = 0;
 		foreach ($binds as $bind)
 		{
-			$result .= $this->escape($bind);
-			$result .= $segments[++$i];
+			$result .= $this->escape($bind).$segments[++$i];
 		}
 
 		return $result;
@@ -617,7 +637,7 @@
 	 */
 	public function is_write_type($sql)
 	{
-		return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|OPTIMIZE|REINDEX)\s+/i', $sql);
+		return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -670,17 +690,17 @@
 	 */
 	public function escape($str)
 	{
-		if (is_string($str))
+		if (is_string($str) OR method_exists($str, '__toString'))
 		{
-			$str = "'".$this->escape_str($str)."'";
+			return "'".$this->escape_str($str)."'";
 		}
 		elseif (is_bool($str))
 		{
-			$str = ($str === FALSE) ? 0 : 1;
+			return ($str === FALSE) ? 0 : 1;
 		}
 		elseif (is_null($str))
 		{
-			$str = 'NULL';
+			return 'NULL';
 		}
 
 		return $str;
@@ -716,13 +736,7 @@
 	public function primary($table = '')
 	{
 		$fields = $this->list_fields($table);
-
-		if ( ! is_array($fields))
-		{
-			return FALSE;
-		}
-
-		return current($fields);
+		return is_array($fields) ? current($fields) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -742,35 +756,40 @@
 
 		if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
 
-		$retval = array();
+		$this->data_cache['table_names'] = array();
 		$query = $this->query($sql);
 
-		if ($query->num_rows() > 0)
+		foreach ($query->result_array() as $row)
 		{
-			$table = FALSE;
-			$rows = $query->result_array();
-			$key = (($row = current($rows)) && in_array('table_name', array_map('strtolower', array_keys($row))));
-
-			if ($key)
+			// Do we know from which column to get the table name?
+			if ( ! isset($key))
 			{
-				$table = array_key_exists('TABLE_NAME', $row) ? 'TABLE_NAME' : 'table_name';
+				if (isset($row['table_name']))
+				{
+					$key = 'table_name';
+				}
+				elseif (isset($row['TABLE_NAME']))
+				{
+					$key = 'TABLE_NAME';
+				}
+				else
+				{
+					/* We have no other choice but to just get the first element's key.
+					 * Due to array_shift() accepting it's argument by reference, if
+					 * E_STRICT is on, this would trigger a warning. So we'll have to
+					 * assign it first.
+					 */
+					$key = array_keys($row);
+					$key = array_shift($key);
+				}
 			}
 
-			foreach ($rows as $row)
-			{
-				$retval[] = ( ! $table) ? current($row) : $row[$table];
-			}
+			$this->data_cache['table_names'][] = $row[$key];
 		}
 
-		$this->data_cache['table_names'] = $retval;
-
 		return $this->data_cache['table_names'];
 	}
 
@@ -804,38 +823,45 @@
 
 		if ($table == '')
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_field_param_missing');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
 
 		if (FALSE === ($sql = $this->_list_columns($table)))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
 
 		$query = $this->query($sql);
+		$this->data_cache['field_names'][$table] = array();
 
-		$retval = array();
 		foreach ($query->result_array() as $row)
 		{
-			if (isset($row['COLUMN_NAME']))
+			// Do we know from where to get the column's name?
+			if ( ! isset($key))
 			{
-				$retval[] = $row['COLUMN_NAME'];
+				if (isset($row['column_name']))
+				{
+					$key = 'column_name';
+				}
+				elseif (isset($row['COLUMN_NAME']))
+				{
+					$key = 'COLUMN_NAME';
+				}
+				else
+				{
+					/* We have no other choice but to just get the first element's key.
+					 * Due to array_shift() accepting it's argument by reference, if
+					 * E_STRICT is on, this would trigger a warning. So we'll have to
+					 * assign it first.
+					 */
+					$key = array_keys($row);
+					$key = array_shift($key);
+				}
 			}
-			else
-			{
-				$retval[] = current($row);
-			}
+
+			$this->data_cache['field_names'][$table][] = $row[$key];
 		}
 
-		$this->data_cache['field_names'][$table] = $retval;
 		return $this->data_cache['field_names'][$table];
 	}
 
@@ -850,7 +876,7 @@
 	 */
 	public function field_exists($field_name, $table_name)
 	{
-		return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
+		return in_array($field_name, $this->list_fields($table_name));
 	}
 
 	// --------------------------------------------------------------------
@@ -865,21 +891,53 @@
 	{
 		if ($table == '')
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_field_param_missing');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
 
 		$query = $this->query($this->_field_data($this->protect_identifiers($table, TRUE, NULL, FALSE)));
-
 		return $query->field_data();
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	public function escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$item = str_replace('.', $this->_escape_char.'.', $item);
+
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
+			}
+		}
+
+		if (strpos($item, '.') !== FALSE)
+		{
+			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
+		}
+
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Generate an insert string
 	 *
 	 * @param	string	the table upon which the query will be performed
@@ -888,12 +946,11 @@
 	 */
 	public function insert_string($table, $data)
 	{
-		$fields = array();
-		$values = array();
+		$fields = $values = array();
 
 		foreach ($data as $key => $val)
 		{
-			$fields[] = $this->_escape_identifiers($key);
+			$fields[] = $this->escape_identifiers($key);
 			$values[] = $this->escape($val);
 		}
 
@@ -962,13 +1019,7 @@
 	 */
 	protected function _has_operator($str)
 	{
-		$str = trim($str);
-		if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
-		{
-			return FALSE;
-		}
-
-		return TRUE;
+		return (bool) preg_match('/(\s|<|>|!|=|IS NULL|IS NOT NULL)/i', trim($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -991,25 +1042,12 @@
 
 		if ( ! function_exists($function))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
-		else
-		{
-			$args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
 
-			if (is_null($args))
-			{
-				return call_user_func($function);
-			}
-			else
-			{
-				return call_user_func_array($function, $args);
-			}
-		}
+		return (func_num_args() > 1)
+			? call_user_func_array($function, array_splice(func_get_args(), 1))
+			: call_user_func($function);
 	}
 
 	// --------------------------------------------------------------------
@@ -1034,8 +1072,7 @@
 	 */
 	public function cache_on()
 	{
-		$this->cache_on = TRUE;
-		return TRUE;
+		return $this->cache_on = TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1047,8 +1084,7 @@
 	 */
 	public function cache_off()
 	{
-		$this->cache_on = FALSE;
-		return FALSE;
+		return $this->cache_on = FALSE;
 	}
 
 
@@ -1061,11 +1097,9 @@
 	 */
 	public function cache_delete($segment_one = '', $segment_two = '')
 	{
-		if ( ! $this->_cache_init())
-		{
-			return FALSE;
-		}
-		return $this->CACHE->delete($segment_one, $segment_two);
+		return ($this->_cache_init())
+			? $this->CACHE->delete($segment_one, $segment_two)
+			: FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1077,12 +1111,9 @@
 	 */
 	public function cache_delete_all()
 	{
-		if ( ! $this->_cache_init())
-		{
-			return FALSE;
-		}
-
-		return $this->CACHE->delete_all();
+		return ($this->_cache_init())
+			? $this->CACHE->delete_all()
+			: FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1094,18 +1125,17 @@
 	 */
 	protected function _cache_init()
 	{
-		if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
+		if (class_exists('CI_DB_Cache'))
 		{
-			return TRUE;
-		}
-
-		if ( ! class_exists('CI_DB_Cache'))
-		{
-			if ( ! @include(BASEPATH.'database/DB_cache.php'))
+			if (is_object($this->CACHE))
 			{
-				return $this->cache_off();
+				return TRUE;
 			}
 		}
+		elseif ( ! @include_once(BASEPATH.'database/DB_cache.php'))
+		{
+			return $this->cache_off();
+		}
 
 		$this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects
 		return TRUE;
@@ -1120,11 +1150,11 @@
 	 */
 	public function close()
 	{
-		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		if ($this->conn_id)
 		{
 			$this->_close($this->conn_id);
+			$this->conn_id = FALSE;
 		}
-		$this->conn_id = FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1156,9 +1186,7 @@
 		// Find the most likely culprit of the error by going through
 		// the backtrace until the source file is no longer in the
 		// database folder.
-
 		$trace = debug_backtrace();
-
 		foreach ($trace as $call)
 		{
 			if (isset($call['file']) && strpos($call['file'], BASEPATH.'database') === FALSE)
@@ -1166,7 +1194,6 @@
 				// Found it - use a relative path for safety
 				$message[] = 'Filename: '.str_replace(array(BASEPATH, APPPATH), '', $call['file']);
 				$message[] = 'Line Number: '.$call['line'];
-
 				break;
 			}
 		}
@@ -1184,7 +1211,7 @@
 	 * This function is used extensively by the Query Builder class, and by
 	 * a couple functions in this class.
 	 * It takes a column or table name (optionally with an alias) and inserts
-	 * the table prefix onto it.  Some logic is necessary in order to deal with
+	 * the table prefix onto it. Some logic is necessary in order to deal with
 	 * column names that include the path. Consider a query like this:
 	 *
 	 * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table
@@ -1227,12 +1254,15 @@
 
 		// If the item has an alias declaration we remove it and set it aside.
 		// Basically we remove everything to the right of the first space
-		$alias = '';
 		if (strpos($item, ' ') !== FALSE)
 		{
-			$alias = strstr($item, " ");
+			$alias = strstr($item, ' ');
 			$item = substr($item, 0, - strlen($alias));
 		}
+		else
+		{
+			$alias = '';
+		}
 
 		// This is basically a bug fix for queries that use MAX, MIN, etc.
 		// If a parenthesis is found we know that we do not need to
@@ -1261,12 +1291,13 @@
 					{
 						if ( ! in_array($val, $this->_reserved_identifiers))
 						{
-							$parts[$key] = $this->_escape_identifiers($val);
+							$parts[$key] = $this->escape_identifiers($val);
 						}
 					}
 
 					$item = implode('.', $parts);
 				}
+
 				return $item.$alias;
 			}
 
@@ -1301,13 +1332,12 @@
 				}
 
 				// Verify table prefix and replace if necessary
-				if ($this->swap_pre != '' && strncmp($parts[$i], $this->swap_pre, strlen($this->swap_pre)) === 0)
+				if ($this->swap_pre != '' && strpos($parts[$i], $this->swap_pre) === 0)
 				{
-					$parts[$i] = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $parts[$i]);
+					$parts[$i] = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $parts[$i]);
 				}
-
 				// We only add the table prefix if it does not already exist
-				if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix)
+				elseif (strpos($parts[$i], $this->dbprefix) !== 0)
 				{
 					$parts[$i] = $this->dbprefix.$parts[$i];
 				}
@@ -1318,7 +1348,7 @@
 
 			if ($protect_identifiers === TRUE)
 			{
-				$item = $this->_escape_identifiers($item);
+				$item = $this->escape_identifiers($item);
 			}
 
 			return $item.$alias;
@@ -1328,21 +1358,20 @@
 		if ($this->dbprefix != '')
 		{
 			// Verify table prefix and replace if necessary
-			if ($this->swap_pre != '' && strncmp($item, $this->swap_pre, strlen($this->swap_pre)) === 0)
+			if ($this->swap_pre != '' && strpos($item, $this->swap_pre) === 0)
 			{
-				$item = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $item);
+				$item = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $item);
 			}
-
 			// Do we prefix an item with no segments?
-			if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix)
+			elseif ($prefix_single == TRUE && strpos($item, $this->dbprefix) !== 0)
 			{
 				$item = $this->dbprefix.$item;
 			}
 		}
 
-		if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers))
+		if ($protect_identifiers === TRUE && ! in_array($item, $this->_reserved_identifiers))
 		{
-			$item = $this->_escape_identifiers($item);
+			$item = $this->escape_identifiers($item);
 		}
 
 		return $item.$alias;
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 336e949..a519575 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,22 +25,26 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
- * Database Utility Class
+ * Database Forge Class
  *
  * @category	Database
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-class CI_DB_forge {
+abstract class CI_DB_forge {
 
 	public $fields		= array();
 	public $keys		= array();
 	public $primary_keys	= array();
 	public $db_char_set	=	'';
 
+	// Platform specific SQL strings
+	protected $_create_database	= 'CREATE DATABASE %s';
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE IF EXISTS %s';
+	protected $_rename_table	= 'ALTER TABLE %s RENAME TO %s';
+
 	public function __construct()
 	{
 		// Assign the main database object to $this->db
@@ -59,8 +63,16 @@
 	 */
 	public function create_database($db_name)
 	{
-		$sql = $this->_create_database($db_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($this->_create_database === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+		elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat)))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -73,8 +85,21 @@
 	 */
 	public function drop_database($db_name)
 	{
-		$sql = $this->_drop_database($db_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($db_name == '')
+		{
+			show_error('A table name is required for that operation.');
+			return FALSE;
+		}
+		elseif ($this->_drop_database === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+		elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name)))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -197,8 +222,16 @@
 	 */
 	public function drop_table($table_name)
 	{
-		$sql = $this->_drop_table($this->db->dbprefix.$table_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($table_name == '')
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE;
+		}
+		elseif ($this->_drop_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+
+		return $this->db->query(sprintf($this->_drop_table, $this->db->escape_identifiers($this->db->dbprefix.$table_name)));
 	}
 
 	// --------------------------------------------------------------------
@@ -215,9 +248,17 @@
 		if ($table_name == '' OR $new_table_name == '')
 		{
 			show_error('A table name is required for that operation.');
+			return FALSE;
+		}
+		elseif ($this->_rename_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		return $this->db->query($this->_rename_table($this->db->dbprefix.$table_name, $this->db->dbprefix.$new_table_name));
+		return $this->db->query(sprintf($this->_rename_table,
+						$this->db->escape_identifiers($this->db->dbprefix.$table_name),
+						$this->db->escape_identifiers($this->db->dbprefix.$new_table_name))
+					);
 	}
 
 	// --------------------------------------------------------------------
@@ -346,4 +387,4 @@
 }
 
 /* End of file DB_forge.php */
-/* Location: ./system/database/DB_forge.php */
+/* Location: ./system/database/DB_forge.php */
\ No newline at end of file
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 8979dc1..393a1cd 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Query Builder Class
  *
@@ -38,7 +36,8 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-class CI_DB_query_builder extends CI_DB_driver {
+
+abstract class CI_DB_query_builder extends CI_DB_driver {
 
 	protected $return_delete_sql		= FALSE;
 	protected $reset_delete_data		= FALSE;
@@ -213,7 +212,9 @@
 		}
 
 		$sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->protect_identifiers(trim($alias));
+		
 		$this->qb_select[] = $sql;
+		$this->qb_no_escape[] = NULL;
 
 		if ($this->qb_caching === TRUE)
 		{
@@ -423,7 +424,7 @@
 
 		foreach ($key as $k => $v)
 		{
-			$prefix = (count($this->qb_where) === 0 AND count($this->qb_cache_where) === 0) ? '' : $type;
+			$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
 
 			if (is_null($v) && ! $this->_has_operator($k))
 			{
@@ -538,7 +539,7 @@
 	 *
 	 * @param	string	The field to search
 	 * @param	array	The values searched on
-	 * @param	boolean	If the statement would be IN or NOT IN
+	 * @param	bool	If the statement would be IN or NOT IN
 	 * @param	string
 	 * @return	object
 	 */
@@ -719,8 +720,9 @@
 	public function group_start($not = '', $type = 'AND ')
 	{
 		$type = $this->_group_get_type($type);
+
 		$this->qb_where_group_started = TRUE;
-		$prefix = (count($this->qb_where) === 0 AND count($this->qb_cache_where) === 0) ? '' : $type;
+		$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
 		$this->qb_where[] = $value = $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (';
 
 		if ($this->qb_caching)
@@ -985,8 +987,8 @@
 	/**
 	 * Sets the LIMIT value
 	 *
-	 * @param	integer	the limit value
-	 * @param	integer	the offset value
+	 * @param	int	the limit value
+	 * @param	int	the offset value
 	 * @return	object
 	 */
 	public function limit($value, $offset = NULL)
@@ -1006,7 +1008,7 @@
 	/**
 	 * Sets the OFFSET value
 	 *
-	 * @param	integer	the offset value
+	 * @param	int	the offset value
 	 * @return	object
 	 */
 	public function offset($offset)
@@ -1022,7 +1024,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	boolean
+	 * @param	bool
 	 * @return	object
 	 */
 	public function set($key, $value = '', $escape = TRUE)
@@ -1056,9 +1058,8 @@
 	 *
 	 * Compiles a SELECT query string and returns the sql.
 	 *
-	 * @access	public
 	 * @param	string	the table name to select from (optional)
-	 * @param	boolean	TRUE: resets QB values; FALSE: leave QB vaules alone
+	 * @param	bool	TRUE: resets QB values; FALSE: leave QB vaules alone
 	 * @return	string
 	 */
 	public function get_compiled_select($table = '', $reset = TRUE)
@@ -1223,11 +1224,28 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Insert_batch statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data.
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _insert_batch($table, $keys, $values)
+	{
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * The "set_insert_batch" function.  Allows key/value pairs to be set for batch inserts
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @param	boolean
+	 * @param	bool
 	 * @return	object
 	 */
 	public function set_insert_batch($key, $value = '', $escape = TRUE)
@@ -1239,11 +1257,12 @@
 			$key = array($key => $value);
 		}
 
-		$keys = array_keys(current($key));
+		$keys = array_keys($this->_object_to_array(current($key)));
 		sort($keys);
 
 		foreach ($key as $row)
 		{
+			$row = $this->_object_to_array($row);
 			if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
 			{
 				// batch function above returns an error on an empty array
@@ -1284,9 +1303,8 @@
 	 *
 	 * Compiles an insert query and returns the sql
 	 *
-	 * @access	public
 	 * @param	string	the table to insert into
-	 * @param	boolean	TRUE: reset QB values; FALSE: leave QB values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_insert($table = '', $reset = TRUE)
@@ -1319,7 +1337,6 @@
 	 *
 	 * Compiles an insert string and runs the query
 	 *
-	 * @access	public
 	 * @param	string	the table to insert data into
 	 * @param	array	an associative array of insert values
 	 * @return	object
@@ -1351,13 +1368,29 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _insert($table, $keys, $values)
+	{
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Validate Insert
 	 *
 	 * This method is used by both insert() and get_compiled_insert() to
 	 * validate that the there data is actually being set and that table
 	 * has been chosen to be inserted into.
 	 *
-	 * @access	public
 	 * @param	string	the table to insert data into
 	 * @return	string
 	 */
@@ -1425,13 +1458,29 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Replace statement
+	 *
+	 * Generates a platform-specific replace string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _replace($table, $keys, $values)
+	{
+		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Get UPDATE query string
 	 *
 	 * Compiles an update query and returns the sql
 	 *
-	 * @access	public
 	 * @param	string	the table to update
-	 * @param	boolean	TRUE: reset QB values; FALSE: leave QB values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_update($table = '', $reset = TRUE)
@@ -1500,13 +1549,47 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @param	array	the like clause
+	 * @return	string
+	 */
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
+	{
+		foreach ($values as $key => $val)
+		{
+			$valstr[] = $key.' = '.$val;
+		}
+
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
+
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
+			.$where
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
+			.($limit ? ' LIMIT '.$limit : '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Validate Update
 	 *
 	 * This method is used by both update() and get_compiled_update() to
 	 * validate that data is actually being set and that a table has been
 	 * chosen to be update.
 	 *
-	 * @access	public
 	 * @param	string	the table to update data on
 	 * @return	bool
 	 */
@@ -1591,7 +1674,7 @@
 	 *
 	 * @param	array
 	 * @param	string
-	 * @param	boolean
+	 * @param	bool
 	 * @return	object
 	 */
 	public function set_update_batch($key, $index = '', $escape = TRUE)
@@ -1699,13 +1782,30 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _truncate($table)
+	{
+		return 'TRUNCATE '.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Get DELETE query string
 	 *
 	 * Compiles a delete query string and returns the sql
 	 *
-	 * @access	public
 	 * @param	string	the table to delete from
-	 * @param	boolean	TRUE: reset QB values; FALSE: leave QB values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_delete($table = '', $reset = TRUE)
@@ -1726,7 +1826,7 @@
 	 * @param	mixed	the table(s) to delete from. String or array
 	 * @param	mixed	the where clause
 	 * @param	mixed	the limit clause
-	 * @param	boolean
+	 * @param	bool
 	 * @return	object
 	 */
 	public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
@@ -1785,6 +1885,31 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = array();
+
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+
+		return 'DELETE FROM '.$table
+			.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '')
+			.($limit ? ' LIMIT '.$limit : '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * DB Prefix
 	 *
 	 * Prepends a database prefix if one exists in configuration
@@ -2069,7 +2194,6 @@
 	 *
 	 * Empties the QB cache
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function flush_cache()
@@ -2121,7 +2245,7 @@
 
 		// If we are "protecting identifiers" we need to examine the "from"
 		// portion of the query to determine if there are any aliases
-		if ($this->_protect_identifiers === TRUE AND count($this->qb_cache_from) > 0)
+		if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0)
 		{
 			$this->_track_aliases($this->qb_from);
 		}
@@ -2204,19 +2328,19 @@
 	protected function _reset_write()
 	{
 		$this->_reset_run(array(
-					'qb_set'	=> array(),
-					'qb_from'	=> array(),
-					'qb_where'	=> array(),
-					'qb_like'	=> array(),
-					'qb_orderby'	=> array(),
-					'qb_keys'	=> array(),
-					'qb_limit'	=> FALSE,
-					'qb_order'	=> FALSE
-					)
-				);
+			'qb_set'	=> array(),
+			'qb_from'	=> array(),
+			'qb_where'	=> array(),
+			'qb_like'	=> array(),
+			'qb_orderby'	=> array(),
+			'qb_keys'	=> array(),
+			'qb_limit'	=> FALSE,
+			'qb_order'	=> FALSE
+			)
+		);
 	}
 
 }
 
 /* End of file DB_query_builder.php */
-/* Location: ./system/database/DB_query_builder.php */
+/* Location: ./system/database/DB_query_builder.php */
\ No newline at end of file
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index 61aa561..196febe 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -57,7 +57,7 @@
 	 * Query result.  Acts as a wrapper function for the following functions.
 	 *
 	 * @param	string	can be "object" or "array"
-	 * @return	mixed	either a result object or array
+	 * @return	object
 	 */
 	public function result($type = 'object')
 	{
@@ -108,9 +108,9 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Query result.  "object" version.
+	 * Query result. "object" version.
 	 *
-	 * @return	object
+	 * @return	array
 	 */
 	public function result_object()
 	{
@@ -224,7 +224,7 @@
 			return;
 		}
 
-		if ($key != '' AND ! is_null($value))
+		if ($key != '' && ! is_null($value))
 		{
 			$this->row_data[$key] = $value;
 		}
@@ -245,7 +245,7 @@
 			return $result;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n != $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -266,7 +266,7 @@
 			return $result;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n != $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -289,7 +289,7 @@
 			return $result;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n != $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -297,7 +297,6 @@
 		return $result[$this->current_row];
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -374,9 +373,9 @@
 	/**
 	 * The following functions are normally overloaded by the identically named
 	 * methods in the platform-specific driver -- except when query caching
-	 * is used.  When caching is enabled we do not load the other driver.
+	 * is used. When caching is enabled we do not load the other driver.
 	 * These functions are primarily here to prevent undefined function errors
-	 * when a cached result object is in use.  They are not otherwise fully
+	 * when a cached result object is in use. They are not otherwise fully
 	 * operational due to the unavailability of the database resource IDs with
 	 * cached results.
 	 */
@@ -384,12 +383,12 @@
 	public function num_fields() { return 0; }
 	public function list_fields() { return array(); }
 	public function field_data() { return array(); }
-	public function free_result() { return TRUE; }
-	protected function _data_seek() { return TRUE; }
+	public function free_result() { $this->result_id = FALSE; }
+	protected function _data_seek() { return FALSE; }
 	protected function _fetch_assoc() { return array(); }
 	protected function _fetch_object() { return array(); }
 
 }
 
 /* End of file DB_result.php */
-/* Location: ./system/database/DB_result.php */
+/* Location: ./system/database/DB_result.php */
\ No newline at end of file
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 4c881d8..587dfdc 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -32,11 +32,16 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-class CI_DB_utility extends CI_DB_forge {
+abstract class CI_DB_utility extends CI_DB_forge {
 
 	public $db;
 	public $data_cache		= array();
 
+	// Platform specific SQL strings
+	// Just setting those defaults to FALSE as they are mostly MySQL-specific
+	protected $_optimize_table	= FALSE;
+	protected $_repair_table	= FALSE;
+
 	public function __construct()
 	{
 		// Assign the main database object to $this->db
@@ -50,7 +55,7 @@
 	/**
 	 * List databases
 	 *
-	 * @return	bool
+	 * @return	array
 	 */
 	public function list_databases()
 	{
@@ -59,18 +64,25 @@
 		{
 			return $this->data_cache['db_names'];
 		}
-
-		$query = $this->db->query($this->_list_databases());
-		$dbs = array();
-		if ($query->num_rows() > 0)
+		elseif ($this->_list_databases === FALSE)
 		{
-			foreach ($query->result_array() as $row)
-			{
-				$dbs[] = current($row);
-			}
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		return $this->data_cache['db_names'] = $dbs;
+		$this->data_cache['db_names'] = array();
+
+		$query = $this->db->query($this->_list_databases);
+		if ($query === FALSE)
+		{
+			return $this->data_cache['db_names'];
+		}
+
+		for ($i = 0, $c = count($query); $i < $c; $i++)
+		{
+			$this->data_cache['db_names'] = current($query[$i]);
+		}
+
+		return $this->data_cache['db_names'];
 	}
 
 	// --------------------------------------------------------------------
@@ -79,48 +91,36 @@
 	 * Determine if a particular database exists
 	 *
 	 * @param	string
-	 * @return	boolean
+	 * @return	bool
 	 */
 	public function database_exists($database_name)
 	{
-		// Some databases won't have access to the list_databases() function, so
-		// this is intended to allow them to override with their own functions as
-		// defined in $driver_utility.php
-		if (method_exists($this, '_database_exists'))
-		{
-			return $this->_database_exists($database_name);
-		}
-		else
-		{
-			return ( ! in_array($database_name, $this->list_databases())) ? FALSE : TRUE;
-		}
+		return in_array($database_name, $this->list_databases());
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Optimize Table
 	 *
 	 * @param	string	the table name
-	 * @return	bool
+	 * @return	mixed
 	 */
 	public function optimize_table($table_name)
 	{
-		$sql = $this->_optimize_table($table_name);
-
-		if (is_bool($sql))
+		if ($this->_optimize_table === FALSE)
 		{
-			show_error('db_must_use_set');
-			return FALSE;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		$query = $this->db->query($sql);
-		$res = $query->result_array();
+		$query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
+		if ($query !== FALSE)
+		{
+			$query = $query->result_array();
+			return current($res);
+		}
 
-		// Note: Due to a bug in current() that affects some versions
-		// of PHP we can not pass function call directly into it
-		return current($res);
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -128,26 +128,26 @@
 	/**
 	 * Optimize Database
 	 *
-	 * @return	array
+	 * @return	mixed
 	 */
 	public function optimize_database()
 	{
+		if ($this->_optimize_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+
 		$result = array();
 		foreach ($this->db->list_tables() as $table_name)
 		{
-			$sql = $this->_optimize_table($table_name);
-
-			if (is_bool($sql))
+			$res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
+			if (is_bool($res))
 			{
-				return $sql;
+				return $res;
 			}
 
-			$query = $this->db->query($sql);
-
 			// Build the result array...
-			// Note: Due to a bug in current() that affects some versions
-			// of PHP we can not pass function call directly into it
-			$res = $query->result_array();
+			$res = $res->result_array();
 			$res = current($res);
 			$key = str_replace($this->db->database.'.', '', current($res));
 			$keys = array_keys($res);
@@ -165,23 +165,23 @@
 	 * Repair Table
 	 *
 	 * @param	string	the table name
-	 * @return	bool
+	 * @return	mixed
 	 */
 	public function repair_table($table_name)
 	{
-		$sql = $this->_repair_table($table_name);
-
-		if (is_bool($sql))
+		if ($this->_repair_table === FALSE)
 		{
-			return $sql;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		$query = $this->db->query($sql);
+		$query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
+		if (is_bool($query))
+		{
+			return $query;
+		}
 
-		// Note: Due to a bug in current() that affects some versions
-		// of PHP we can not pass function call directly into it
-		$res = $query->result_array();
-		return current($res);
+		$query = $query->result_array();
+		return current($query);
 	}
 
 	// --------------------------------------------------------------------
@@ -257,18 +257,18 @@
 		$CI->load->helper('xml');
 
 		// Generate the result
-		$xml = "<{$root}>".$newline;
+		$xml = '<'.$root.'>'.$newline;
 		foreach ($query->result_array() as $row)
 		{
-			$xml .= $tab."<{$element}>".$newline;
+			$xml .= $tab.'<'.$element.'>'.$newline;
 			foreach ($row as $key => $val)
 			{
-				$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
+				$xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
 			}
-			$xml .= $tab."</{$element}>".$newline;
+			$xml .= $tab.'</'.$element.'>'.$newline;
 		}
 
-		return $xml .= "</$root>".$newline;
+		return $xml.'</'.$root.'>'.$newline;
 	}
 
 	// --------------------------------------------------------------------
@@ -328,8 +328,8 @@
 
 		// Is the encoder supported? If not, we'll either issue an
 		// error or use plain text depending on the debug settings
-		if (($prefs['format'] === 'gzip' AND ! @function_exists('gzencode'))
-			OR ($prefs['format'] === 'zip'  AND ! @function_exists('gzcompress')))
+		if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
+			OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
 		{
 			if ($this->db->db_debug)
 			{
@@ -384,4 +384,4 @@
 }
 
 /* End of file DB_utility.php */
-/* Location: ./system/database/DB_utility.php */
+/* Location: ./system/database/DB_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index f2f88e7..c5018bf 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Database Adapter Class
  *
@@ -42,79 +40,102 @@
  */
 class CI_DB_cubrid_driver extends CI_DB {
 
-	// Default CUBRID Broker port. Will be used unless user
-	// explicitly specifies another one.
-	const DEFAULT_PORT = 33000;
-
-	var $dbdriver = 'cubrid';
+	public $dbdriver = 'cubrid';
 
 	// The character used for escaping - no need in CUBRID
-	var	$_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences - not used in CUBRID
-	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
+
+	// CUBRID-specific properties
+	public $auto_commit = TRUE;
+
+	public function __construct($params)
+	{
+		parent::__construct($params);
+
+		if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:[^:]*:[^:]*:(\?.+)?$/', $this->dsn, $matches))
+		{
+			if (stripos($matches[2], 'autocommit=off') !== FALSE)
+			{
+				$this->auto_commit = FALSE;
+			}
+		}
+		else
+		{
+			// If no port is defined by the user, use the default value
+			$this->port == '' OR $this->port = 33000;
+		}
+	}
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		// If no port is defined by the user, use the default value
-		if ($this->port == '')
-		{
-			$this->port = self::DEFAULT_PORT;
-		}
-
-		$conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
-
-		if ($conn)
-		{
-			// Check if a user wants to run queries in dry, i.e. run the
-			// queries but not commit them.
-			if (isset($this->auto_commit) && ! $this->auto_commit)
-			{
-				cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_FALSE);
-			}
-			else
-			{
-				cubrid_set_autocommit($conn, CUBRID_AUTOCOMMIT_TRUE);
-				$this->auto_commit = TRUE;
-			}
-		}
-
-		return $conn;
+		return $this->_cubrid_connect();
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
 	 * Persistent database connection
+	 *
 	 * In CUBRID persistent DB connection is supported natively in CUBRID
 	 * engine which can be configured in the CUBRID Broker configuration
 	 * file by setting the CCI_PCONNECT parameter to ON. In that case, all
 	 * connections established between the client application and the
-	 * server will become persistent. This is calling the same
-	 * @cubrid_connect function will establish persisten connection
-	 * considering that the CCI_PCONNECT is ON.
+	 * server will become persistent.
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return $this->db_connect();
+		return $this->_cubrid_connect(TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * CUBRID connection
+	 *
+	 * A CUBRID-specific method to create a connection to the database.
+	 * Except for determining if a persistent connection should be used,
+	 * the rest of the logic is the same for db_connect() and db_pconnect().
+	 *
+	 * @param	bool
+	 * @return	resource
+	 */
+	protected function _cubrid_connect($persistent = FALSE)
+	{
+		if (preg_match('/^CUBRID:[^:]+(:[0-9][1-9]{0,4})?:[^:]+:([^:]*):([^:]*):(\?.+)?$/', $this->dsn, $matches))
+		{
+			$_temp = ($persistent !== TRUE) ? 'cubrid_connect_with_url' : 'cubrid_pconnect_with_url';
+			$conn_id = ($matches[2] === '' && $matches[3] === '' && $this->username !== '' && $this->password !== '')
+					? $_temp($this->dsn, $this->username, $this->password)
+					: $_temp($this->dsn);
+		}
+		else
+		{
+			$_temp = ($persistent !== TRUE) ? 'cubrid_connect' : 'cubrid_pconnect';
+			$conn_id = ($this->username !== '')
+					? $_temp($this->hostname, $this->port, $this->database, $this->username, $this->password)
+					: $_temp($this->hostname, $this->port, $this->database);
+		}
+
+		return $conn_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -125,10 +146,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 (cubrid_ping($this->conn_id) === FALSE)
 		{
@@ -139,23 +159,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// In CUBRID there is no need to select a database as the database
-		// is chosen at the connection time.
-		// So, to determine if the database is "selected", all we have to
-		// do is ping the server and return that value.
-		return cubrid_ping($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -172,42 +175,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @cubrid_query($sql, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		// No need to prepare
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -238,10 +221,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -269,10 +251,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -300,12 +281,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))
 		{
@@ -352,10 +332,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @cubrid_insert_id($this->conn_id);
 	}
@@ -368,11 +347,10 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified table
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	string
+	 * @return	int
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
 		{
@@ -397,11 +375,10 @@
 	 *
 	 * 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";
 
@@ -420,11 +397,10 @@
 	 *
 	 * 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);
 	}
@@ -436,11 +412,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -460,46 +435,6 @@
 		return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id));
 	}
 
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -508,11 +443,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	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -525,109 +459,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * 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)
-	{
-		return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Update statement
-	 *
-	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = sprintf('"%s" = %s', $key, $val);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @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 ' : '';
@@ -667,72 +508,18 @@
 	}
 
 	// --------------------------------------------------------------------
-
-
-	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _truncate($table)
-	{
-		return "TRUNCATE ".$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * 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)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
-	}
-
-	// --------------------------------------------------------------------
-
+	
 	/**
 	 * Limit string
 	 *
 	 * 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)
 		{
@@ -751,17 +538,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@cubrid_close($conn_id);
 	}
 
 }
 
-
 /* End of file cubrid_driver.php */
 /* 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 76002cb..16478ee 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Forge Class
  *
@@ -36,51 +34,21 @@
  */
 class CI_DB_cubrid_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		// CUBRID does not allow to create a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// CUBRID does not allow to drop a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
 
 	/**
 	 * Process Fields
 	 *
-	 * @access	private
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields)
+	protected 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
@@ -172,15 +140,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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -190,9 +157,7 @@
 			// As of version 8.4.0 CUBRID does not support this SQL syntax.
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-
-		$sql .= $this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		// If there is a PK defined
 		if (count($primary_keys) > 0)
@@ -230,32 +195,18 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
 	 * 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 = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -275,24 +226,7 @@
 		return $sql;
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'RENAME TABLE '.$this->db->protect_identifiers($table_name).' AS '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file cubrid_forge.php */
-/* Location: ./system/database/drivers/cubrid/cubrid_forge.php */
+/* Location: ./system/database/drivers/cubrid/cubrid_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 4c0fede..58dcff2 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// --------------------------------------------------------------------
-
 /**
  * CUBRID 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 @cubrid_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 @cubrid_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()
 	{
 		return cubrid_column_names($this->result_id);
 	}
@@ -84,10 +79,9 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
 
@@ -147,9 +141,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if(is_resource($this->result_id) ||
 			get_resource_type($this->result_id) == "Unknown" &&
@@ -169,10 +163,9 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @access	private
-	 * @return	array
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return cubrid_data_seek($this->result_id, $n);
 	}
@@ -184,10 +177,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return cubrid_fetch_assoc($this->result_id);
 	}
@@ -199,16 +191,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return cubrid_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file cubrid_result.php */
 /* Location: ./system/database/drivers/cubrid/cubrid_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index 750c0d8..274ff6a 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CUBRID Utility Class
  *
@@ -39,75 +37,27 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _list_databases()
+	public function list_databases()
 	{
-		// CUBRID does not allow to see the list of all databases on the
-		// server. It is the way its architecture is designed. Every
-		// database is independent and isolated.
-		// For this reason we can return only the name of the currect
-		// connected database.
-		if ($this->conn_id)
+		if (isset($this->data_cache['db_names']))
 		{
-			return "SELECT '" . $this->database . "'";
+			return $this->data_cache['db_names'];
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return $this->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 * @link 	http://www.cubrid.org/manual/840/en/Optimize%20Database
-	 */
-	function _optimize_table($table)
-	{
-		// No SQL based support in CUBRID as of version 8.4.0. Database or
-		// table optimization can be performed using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 * @link 	http://www.cubrid.org/manual/840/en/Checking%20Database%20Consistency
-	 */
-	function _repair_table($table)
-	{
-		// Not supported in CUBRID as of version 8.4.0. Database or
-		// table consistency can be checked using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-	/**
 	 * CUBRID Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// No SQL based support in CUBRID as of version 8.4.0. Database or
 		// table backup can be performed using CUBRID Manager
diff --git a/system/database/drivers/interbase/interbase_driver.php b/system/database/drivers/interbase/interbase_driver.php
index bacb668..6587d72 100644
--- a/system/database/drivers/interbase/interbase_driver.php
+++ b/system/database/drivers/interbase/interbase_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Firebird/Interbase Database Adapter Class
  *
@@ -56,8 +54,8 @@
 	 * 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
+	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;
@@ -87,34 +85,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
@@ -148,41 +118,20 @@
 	 */
 	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)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -190,7 +139,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->trans = @ibase_trans($this->conn_id);
 
@@ -206,13 +155,8 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans->depth > 0)
 		{
 			return TRUE;
 		}
@@ -229,13 +173,8 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -267,9 +206,9 @@
 		// 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;
@@ -280,7 +219,7 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function affected_rows()
 	{
@@ -292,9 +231,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @param	string $generator_name
-	 * @param	integer $inc_by
-	 * @return	integer
+	 * @param	string	$generator_name
+	 * @param	int	$inc_by
+	 * @return	int
 	 */
 	public function insert_id($generator_name, $inc_by=0)
 	{
@@ -326,9 +265,9 @@
 			return 0;
 		}
 
-		$row = $query->row();
+		$query = $query->row();
 		$this->_reset_select();
-		return (int) $row->numrows;
+		return (int) $query->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -338,21 +277,18 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @param	boolean
+	 * @param	bool
 	 * @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;
+		$sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $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.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
+
 		return $sql;
 	}
 
@@ -368,10 +304,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return <<<SQL
-			SELECT "RDB\$FIELD_NAME" FROM "RDB\$RELATION_FIELDS" 
-			WHERE "RDB\$RELATION_NAME"='{$table}';
-SQL;
+		return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = \''.$this->escape_str($table)."'";
 	}
 
 	// --------------------------------------------------------------------
@@ -382,14 +315,14 @@
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
 	protected function _field_data($table)
 	{
 		// Need to find a more efficient way to do this
 		// but Interbase/Firebird seems to lack the
 		// limit clause
-		return "SELECT * FROM {$table}";
+		return 'SELECT * FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -410,49 +343,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
+	 * @param	array
+	 * @return	string
 	 */
 	protected function _from_tables($tables)
 	{
@@ -468,23 +365,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
@@ -493,27 +373,27 @@
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		$sql = "UPDATE {$table} SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? ' WHERE '.implode(' ', $where) : '';
-
-		$sql .= $orderby;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
+			.$where
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '');
 	}
 
 
@@ -523,15 +403,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This public function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return $this->_delete($table);
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -543,28 +424,18 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
-	 * @param	string	the limit clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM {$table}{$conditions}";
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -575,36 +446,25 @@
 	 * 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
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	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;
-			}
+			$select = 'FIRST '. (int) $limit
+				.($offset > 0 ? ' SKIP '. (int) $offset : '');
 		}
 		else
 		{
-			$sql = 'ROWS ' . (int) $limit;
-
-			if ($offset > 0)
-			{
-				$sql = 'ROWS '. (int) $offset . ' TO ' . ($limit + $offset);
-			}
+			$select = 'ROWS '
+				.($offset > 0 ? (int) $offset.' TO '.($limit + $offset) : (int) $limit);
 		}
 
-		return preg_replace('`SELECT`i', "SELECT {$sql}", $orig_sql);
+		return preg_replace('`SELECT`i', 'SELECT '.$select, $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -623,4 +483,4 @@
 }
 
 /* End of file interbase_driver.php */
-/* Location: ./system/database/drivers/interbase/interbase_driver.php */
+/* Location: ./system/database/drivers/interbase/interbase_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/interbase/interbase_forge.php b/system/database/drivers/interbase/interbase_forge.php
index 023d278..c850656 100644
--- a/system/database/drivers/interbase/interbase_forge.php
+++ b/system/database/drivers/interbase/interbase_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Forge Class
  *
@@ -36,18 +34,22 @@
  */
 class CI_DB_interbase_forge extends CI_DB_forge {
 
+	protected $_drop_table	= 'DROP TABLE %s';
+
 	/**
 	 * Create database
 	 *
 	 * @param	string	the database name
 	 * @return	string
 	 */
-	protected function _create_database($filename='')
+	public function create_database($db_name)
 	{
-		// Firebird databases are flat files, so a path is required 
+		// Firebird databases are flat files, so a path is required
+
 		// Hostname is needed for remote access
-		return 'CREATE DATABASE "'.$this->hostname.':'.$filename.'"';
-		
+		empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name;
+
+		return parent::create_database('"'.$db_name.'"');
 	}
 
 	// --------------------------------------------------------------------
@@ -55,14 +57,20 @@
 	/**
 	 * Drop database
 	 *
-	 * @param	string	the database name - not used in this driver 
-	 *	- the current db is dropped
+	 * @param	string	the database name
+	 *		- not used in this driver, the current db is dropped
 	 * @return	bool
 	 */
-	protected function _drop_database($name='')
+	public function drop_database($db_name = '')
 	{
-		return ibase_drop_db($this->conn_id);
+		if ( ! ibase_drop_db($this->conn_id))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -72,7 +80,7 @@
 	 * @param	array	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	string
 	 */
 	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
@@ -167,18 +175,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
@@ -189,7 +185,7 @@
 	 * @param	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
@@ -222,21 +218,6 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	protected function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file interbase_forge.php */
diff --git a/system/database/drivers/interbase/interbase_result.php b/system/database/drivers/interbase/interbase_result.php
index 4b15eee..5ddb6fa 100644
--- a/system/database/drivers/interbase/interbase_result.php
+++ b/system/database/drivers/interbase/interbase_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Result Class
  *
@@ -43,18 +41,18 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function num_rows()
 	{
-		if( ! is_null($this->num_rows))
+		if (is_int($this->num_rows))
 		{
 			return $this->num_rows;
 		}
-		
-		//Get the results so that you can get an accurate rowcount
+
+		// Get the results so that you can get an accurate rowcount
 		$this->result();
-		
+
 		return $this->num_rows;
 	}
 
@@ -63,7 +61,7 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function num_fields()
 	{
@@ -102,20 +100,17 @@
 	 */
 	public function field_data()
 	{
-		
 		$retval = array();
-		for ($i = 0, $num_fields = $this->num_fields(); $i < $num_fields; $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $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;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $info['name'];
+			$retval[$i]->type		= $info['type'];
+			$retval[$i]->max_length		= $info['length'];
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -126,7 +121,7 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	public function free_result()
 	{
@@ -136,26 +131,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	array
-	 */
-	protected function _data_seek($n = 0)
-	{
-		//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
@@ -169,7 +144,7 @@
 			//Increment row count
 			$this->num_rows++;
 		}
-	
+
 		return $row;
 	}
 
@@ -189,10 +164,10 @@
 			//Increment row count
 			$this->num_rows++;
 		}
-		
+
 		return $row;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -202,29 +177,20 @@
 	 */
 	public function result_object()
 	{
-		if (count($this->result_object) > 0)
+		if (count($this->result_object) === $this->num_rows)
 		{
 			return $this->result_object;
 		}
-		
-		// Convert result array to object so that 
+
+		// Convert result array to object so that
 		// We don't have to get the result again
-		if (count($this->result_array) > 0)
+		if (($c = count($this->result_array)) > 0)
 		{
-			$i = 0;
-		
-			foreach ($this->result_array as $array)
+			for ($i = 0; $i < $c; $i++)
 			{
-				$this->result_object[$i] = new StdClass();
-			
-				foreach ($array as $key => $val)
-				{
-					$this->result_object[$i]->{$key} = $val;
-				}
-				
-				++$i;
+				$this->result_object[$i] = (object) $this->result_array[$i];
 			}
-			
+
 			return $this->result_object;
 		}
 
@@ -254,20 +220,20 @@
 	 */
 	public function result_array()
 	{
-		if (count($this->result_array) > 0)
+		if (count($this->result_array) === $this->num_rows)
 		{
 			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)
+		if (($c = count($this->result_object)) > 0)
 		{
-			foreach ($this->result_object as $obj)
+			for ($i = 0; $i < $c; $i++)
 			{
-				$this->result_array[] = (array) $obj;
+				$this->result_array[$i] = (array) $this->result_object[$i];
 			}
-		
+
 			return $this->result_array;
 		}
 
diff --git a/system/database/drivers/interbase/interbase_utility.php b/system/database/drivers/interbase/interbase_utility.php
index 76a0497..1b92af9 100644
--- a/system/database/drivers/interbase/interbase_utility.php
+++ b/system/database/drivers/interbase/interbase_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Utility Class
  *
@@ -36,56 +34,7 @@
  */
 class CI_DB_interbase_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with Firebird
-	 * since each database is its own file.  I suppose we could
-	 * try reading a directory looking for Firebird files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		if ($this->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Is optimization even supported in Interbase/Firebird?
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Table repairs are not supported in Interbase/Firebird
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * Interbase/Firebird Export
@@ -93,22 +42,20 @@
 	 * @param	string	$filename
 	 * @return	mixed
 	 */
-	public function backup($filename)
+	protected function backup($filename)
 	{
 		if ($service = ibase_service_attach($this->db->hostname, $this->db->username, $this->db->password))
 		{
 			$res = ibase_backup($service, $this->db->database, $filename.'.fbk');
-			
-			//Close the service connection	
+
+			// Close the service connection
 			ibase_service_detach($service);
-			
 			return $res;
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
+
 }
 
 /* End of file interbase_utility.php */
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 563210c..f60ec81 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Database Adapter Class
  *
@@ -42,30 +40,29 @@
  */
 class CI_DB_mssql_driver extends CI_DB {
 
-	var $dbdriver = 'mssql';
+	public $dbdriver = 'mssql';
 
 	// The character used for escaping
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " ESCAPE '%s' ";
-	var $_like_escape_chr = '!';
+	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.
+	 * used for the count_all() and count_all_results() methods.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' ASC'; // not currently supported
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' NEWID()';
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
 		if ($this->port != '')
 		{
@@ -80,10 +77,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		if ($this->port != '')
 		{
@@ -96,22 +92,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		// not implemented in MSSQL
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Select the database
 	 *
 	 * @param	string	database name
@@ -140,41 +120,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @mssql_query($sql, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -201,10 +162,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -226,10 +186,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -251,12 +210,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))
 		{
@@ -289,10 +247,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @mssql_rows_affected($this->conn_id);
 	}
@@ -300,14 +257,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Insert ID
-	*
-	* Returns the last id created in the Identity column.
-	*
-	* @access public
-	* @return integer
-	*/
-	function insert_id()
+	 * Insert ID
+	 *
+	 * Returns the last id created in the Identity column.
+	 *
+	 * @return	string
+	 */
+	public function insert_id()
 	{
 		$ver = self::_parse_major_version($this->version());
 		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
@@ -319,16 +275,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Parse major version
-	*
-	* Grabs the major version number from the
-	* database server version string passed in.
-	*
-	* @access private
-	* @param string $version
-	* @return int16 major version number
-	*/
-	function _parse_major_version($version)
+	 * Parse major version
+	 *
+	 * Grabs the major version number from the
+	 * database server version string passed in.
+	 *
+	 * @param	string	$version
+	 * @return	int	major version number
+	 */
+	protected function _parse_major_version($version)
 	{
 		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
 		return $ver_info[1]; // return the major version b/c that's all we're interested in.
@@ -337,10 +292,10 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Version number query string
-	*
-	* @return	string
-	*/
+	 * Version number query string
+	 *
+	 * @return	string
+	 */
 	protected function _version()
 	{
 		return 'SELECT @@VERSION AS ver';
@@ -354,11 +309,10 @@
 	 * 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 == '')
 		{
@@ -383,11 +337,10 @@
 	 *
 	 * 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 = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
 
@@ -408,11 +361,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
 	}
@@ -424,11 +376,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT TOP 1 * FROM ".$table;
 	}
@@ -453,58 +404,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -517,73 +425,51 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
-		foreach ($values as $key => $val)
+		foreach($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).' WHERE '.$where;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -593,31 +479,24 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like 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 = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -627,13 +506,12 @@
 	 *
 	 * 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)
 	{
 		$i = $limit + $offset;
 
@@ -645,18 +523,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@mssql_close($conn_id);
 	}
 
 }
 
-
-
 /* End of file mssql_driver.php */
 /* 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 ec97805..8f8e7c5 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Forge Class
  *
@@ -36,59 +34,19 @@
  */
 class CI_DB_mssql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * 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
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	string
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -97,10 +55,10 @@
 			$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
@@ -190,17 +148,16 @@
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
@@ -235,25 +192,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mssql_forge.php */
-/* Location: ./system/database/drivers/mssql/mssql_forge.php */
+/* Location: ./system/database/drivers/mssql/mssql_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index bba2e62..4cc87f4 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL 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 @mssql_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 @mssql_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 = mssql_fetch_field($this->result_id))
@@ -90,10 +85,9 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
 		while ($field = mssql_fetch_field($this->result_id))
@@ -116,9 +110,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -132,14 +126,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
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return mssql_data_seek($this->result_id, $n);
 	}
@@ -151,10 +144,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return mssql_fetch_assoc($this->result_id);
 	}
@@ -166,16 +158,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return mssql_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file mssql_result.php */
 /* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index be6ed5b..6d47618 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MS SQL Utility Class
  *
@@ -36,59 +34,16 @@
  */
 class CI_DB_mssql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
 	 * MSSQL Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 21fb171..32c5186 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -144,14 +144,11 @@
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
-	protected function _db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset)
 	{
-		return function_exists('mysql_set_charset')
-			? @mysql_set_charset($charset, $this->conn_id)
-			: @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);
+		return @mysql_set_charset($charset, $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -289,18 +286,7 @@
 	   		return $str;
 	   	}
 
-		if (function_exists('mysql_real_escape_string') && is_resource($this->conn_id))
-		{
-			$str = mysql_real_escape_string($str, $this->conn_id);
-		}
-		elseif (function_exists('mysql_escape_string'))
-		{
-			$str = mysql_escape_string($str);
-		}
-		else
-		{
-			$str = addslashes($str);
-		}
+		$str = is_resource($this->conn_id) ? mysql_real_escape_string($str, $this->conn_id) : addslashes($str);
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
@@ -453,43 +439,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -511,92 +460,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key.' = '.$val;
-		}
-
-		$where = ($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '';
-		if (count($like) > 0)
-		{
-			$where .= ($where == '' ? ' WHERE ' : ' AND ').implode(' ', $like);
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -638,53 +501,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index a907b20..0e39aff 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -66,7 +42,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	private function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -138,7 +114,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -180,19 +156,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @param	string	table name
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -204,7 +167,7 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -218,23 +181,7 @@
 			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mysql_forge.php */
-/* Location: ./system/database/drivers/mysql/mysql_forge.php */
+/* Location: ./system/database/drivers/mysql/mysql_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index 5a65d9c..14d6d07 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -128,7 +128,7 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
@@ -166,4 +166,4 @@
 }
 
 /* End of file mysql_result.php */
-/* Location: ./system/database/drivers/mysql/mysql_result.php */
+/* Location: ./system/database/drivers/mysql/mysql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index 952f887..642323d 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,54 +34,17 @@
  */
 class CI_DB_mysql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
 	/**
 	 * MySQL Export
 	 *
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		if (count($params) === 0)
 		{
@@ -204,4 +167,4 @@
 }
 
 /* End of file mysql_utility.php */
-/* Location: ./system/database/drivers/mysql/mysql_utility.php */
+/* Location: ./system/database/drivers/mysql/mysql_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 677da13..e2684e4 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -72,8 +72,8 @@
 	public function db_connect()
 	{
 		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);
+			? @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @new mysqli($this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -92,8 +92,8 @@
 		}
 
 		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);
+			? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -108,7 +108,7 @@
 	 */
 	public function reconnect()
 	{
-		if (mysqli_ping($this->conn_id) === FALSE)
+		if ($this->conn_id !== FALSE && $this->conn_id->ping() === FALSE)
 		{
 			$this->conn_id = FALSE;
 		}
@@ -129,7 +129,7 @@
 			$database = $this->database;
 		}
 
-		if (@mysqli_select_db($this->conn_id, $database))
+		if (@$this->conn_id->select_db($database))
 		{
 			$this->database = $database;
 			return TRUE;
@@ -144,14 +144,11 @@
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
-	protected function _db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset)
 	{
-		return function_exists('mysqli_set_charset')
-			? @mysqli_set_charset($this->conn_id, $charset)
-			: @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
+		return @$this->conn_id->set_charset($charset);
 	}
 
 	// --------------------------------------------------------------------
@@ -165,7 +162,7 @@
 	{
 		return isset($this->data_cache['version'])
 			? $this->data_cache['version']
-			: $this->data_cache['version'] = @mysqli_get_server_info($this->conn_id);
+			: $this->data_cache['version'] = $this->conn_id->server_info;
 	}
 
 	// --------------------------------------------------------------------
@@ -178,7 +175,7 @@
 	 */
 	protected function _execute($sql)
 	{
-		return @mysqli_query($this->conn_id, $this->_prep_query($sql));
+		return @$this->conn_id->query($this->_prep_query($sql));
 	}
 
 	// --------------------------------------------------------------------
@@ -289,18 +286,7 @@
 			return $str;
 		}
 
-		if (function_exists('mysqli_real_escape_string') && is_object($this->conn_id))
-		{
-			$str = mysqli_real_escape_string($this->conn_id, $str);
-		}
-		elseif (function_exists('mysql_escape_string'))
-		{
-			$str = mysql_escape_string($str);
-		}
-		else
-		{
-			$str = addslashes($str);
-		}
+		$str = is_object($this->conn_id) ? $this->conn_id->real_escape_string($str) : addslashes($str);
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
@@ -320,7 +306,7 @@
 	 */
 	public function affected_rows()
 	{
-		return @mysqli_affected_rows($this->conn_id);
+		return $this->conn_id->affected_rows;
 	}
 
 	// --------------------------------------------------------------------
@@ -332,7 +318,7 @@
 	 */
 	public function insert_id()
 	{
-		return @mysqli_insert_id($this->conn_id);
+		return $this->conn_id->insert_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -371,7 +357,6 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
 	 * @param	bool
 	 * @return	string
 	 */
@@ -448,44 +433,7 @@
 	 */
 	public function error()
 	{
-		return array('code' => mysqli_errno($this->conn_id), 'message' => mysqli_error($this->conn_id));
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
+		return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error);
 	}
 
 	// --------------------------------------------------------------------
@@ -512,85 +460,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key.' = '.$val;
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
-			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -634,52 +503,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
@@ -705,7 +528,8 @@
 	 */
 	protected function _close($conn_id)
 	{
-		@mysqli_close($conn_id);
+		$this->conn_id->close();
+		$this->conn_id = FALSE;
 	}
 
 }
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index 744525f..503574d 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysqli_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -66,7 +42,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	public function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -86,9 +62,32 @@
 
 				$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' : '')
+				;
+
+				if ( ! empty($attributes['TYPE']))
+				{
+					$sql .=  ' '.$attributes['TYPE'];
+
+					if ( ! empty($attributes['CONSTRAINT']))
+					{
+						switch (strtolower($attributes['TYPE']))
+						{
+							case 'decimal':
+							case 'float':
+							case 'numeric':
+								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
+								break;
+							case 'enum':
+							case 'set':
+								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
+								break;
+							default:
+								$sql .= '('.$attributes['CONSTRAINT'].')';
+						}
+					}
+				}
+
+				$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' : '');
@@ -116,7 +115,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -125,7 +124,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' ('.$this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		if (count($primary_keys) > 0)
 		{
@@ -158,18 +157,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -181,7 +168,7 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -195,23 +182,7 @@
 			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file mysqli_forge.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index 8b909cc..9b4d494 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -43,7 +43,7 @@
 	 */
 	public function num_rows()
 	{
-		return @mysqli_num_rows($this->result_id);
+		return $this->result_id->num_rows;
 	}
 
 	// --------------------------------------------------------------------
@@ -55,7 +55,7 @@
 	 */
 	public function num_fields()
 	{
-		return @mysqli_num_fields($this->result_id);
+		return $this->result_id->field_count;
 	}
 
 	// --------------------------------------------------------------------
@@ -70,7 +70,7 @@
 	public function list_fields()
 	{
 		$field_names = array();
-		while ($field = mysqli_fetch_field($this->result_id))
+		while ($field = $this->result_id->fetch_field())
 		{
 			$field_names[] = $field->name;
 		}
@@ -90,7 +90,7 @@
 	public function field_data()
 	{
 		$retval = array();
-		$field_data = mysqli_fetch_fields($this->result_id);
+		$field_data = $this->result_id->fetch_fields();
 		for ($i = 0, $c = count($field_data); $i < $c; $i++)
 		{
 			$retval[$i]			= new stdClass();
@@ -115,7 +115,7 @@
 	{
 		if (is_object($this->result_id))
 		{
-			mysqli_free_result($this->result_id);
+			$this->result_id->free();
 			$this->result_id = FALSE;
 		}
 	}
@@ -125,15 +125,15 @@
 	/**
 	 * Data Seek
 	 *
-	 * Moves the internal pointer to the desired offset.  We call
+	 * Moves the internal pointer to the desired offset. We call
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
-		return mysqli_data_seek($this->result_id, $n);
+		return $this->result_id->data_seek($n);
 	}
 
 	// --------------------------------------------------------------------
@@ -147,7 +147,7 @@
 	 */
 	protected function _fetch_assoc()
 	{
-		return mysqli_fetch_assoc($this->result_id);
+		return $this->result_id->fetch_assoc();
 	}
 
 	// --------------------------------------------------------------------
@@ -161,10 +161,10 @@
 	 */
 	protected function _fetch_object()
 	{
-		return mysqli_fetch_object($this->result_id);
+		return $this->result_id->fetch_object();
 	}
 
 }
 
 /* End of file mysqli_result.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index 3fdc5c7..27d4ef8 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,47 +34,9 @@
  */
 class CI_DB_mysqli_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
 	/**
 	 * MySQLi Export
@@ -82,7 +44,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -90,4 +52,4 @@
 }
 
 /* End of file mysqli_utility.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 81eff70..33a89df 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * oci8 Database Adapter Class
  *
@@ -48,48 +46,126 @@
  * permit access to oracle databases
  *
  * @author	  Kelly McArdle
- *
  */
-
 class CI_DB_oci8_driver extends CI_DB {
 
-	var $dbdriver = 'oci8';
+	public $dbdriver = 'oci8';
 
 	// The character used for excaping
-	var $_escape_char = '"';
+	protected $_escape_char = '"';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " escape '%s' ";
-	var $_like_escape_chr = '!';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(1) AS ";
-	var $_random_keyword = ' ASC'; // not currently supported
+	protected $_count_string = 'SELECT COUNT(1) AS ';
+	protected $_random_keyword = ' ASC'; // not currently supported
 
 	// Set "auto commit" by default
-	var $_commit = OCI_COMMIT_ON_SUCCESS;
+	public $commit_mode = OCI_COMMIT_ON_SUCCESS;
 
 	// need to track statement id and cursor id
-	var $stmt_id;
-	var $curs_id;
+	public $stmt_id;
+	public $curs_id;
 
 	// if we use a limit, we will add a field that will
 	// throw off num_fields later
-	var $limit_used;
+	public $limit_used;
+
+	public function __construct($params)
+	{
+		parent::__construct($params);
+
+		$valid_dsns = array(
+					'tns'	=> '/^\(DESCRIPTION=(\(.+\)){2,}\)$/', // TNS
+					// Easy Connect string (Oracle 10g+)
+					'ec'	=> '/^(\/\/)?[a-z0-9.:_-]+(:[1-9][0-9]{0,4})?(\/[a-z0-9$_]+)?(:[^\/])?(\/[a-z0-9$_]+)?$/i',
+					'in'	=> '/^[a-z0-9$_]+$/i' // Instance name (defined in tnsnames.ora)
+				);
+
+		/* Space characters don't have any effect when actually
+		 * connecting, but can be a hassle while validating the DSN.
+		 */
+		$this->dsn = str_replace(array("\n", "\r", "\t", ' '), '', $this->dsn);
+
+		if ($this->dsn !== '')
+		{
+			foreach ($valid_dsns as $regexp)
+			{
+				if (preg_match($regexp, $this->dsn))
+				{
+					return;
+				}
+			}
+		}
+
+		// Legacy support for TNS in the hostname configuration field
+		$this->hostname = str_replace(array("\n", "\r", "\t", ' '), '', $this->hostname);
+		if (preg_match($valid_dsns['tns'], $this->hostname))
+		{
+			$this->dsn = $this->hostname;
+			return;
+		}
+		elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
+			&& (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
+		{
+			/* If the hostname field isn't empty, doesn't contain
+			 * ':' and/or '/' and if port and/or database aren't
+			 * empty, then the hostname field is most likely indeed
+			 * just a hostname. Therefore we'll try and build an
+			 * Easy Connect string from these 3 settings, assuming
+			 * that the database field is a service name.
+			 */
+			$this->dsn = $this->hostname
+					.(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
+					.($this->database !== '' ? '/'.ltrim($this->database, '/') : '');
+
+			if (preg_match($valid_dsns['ec'], $this->dsn))
+			{
+				return;
+			}
+		}
+
+		/* At this point, we can only try and validate the hostname and
+		 * database fields separately as DSNs.
+		 */
+		if (preg_match($valid_dsns['ec'], $this->hostname) OR preg_match($valid_dsns['in'], $this->hostname))
+		{
+			$this->dsn = $this->hostname;
+			return;
+		}
+
+		$this->database = str_replace(array("\n", "\r", "\t", ' '), '', $this->database);
+		foreach ($valid_dsns as $regexp)
+		{
+			if (preg_match($regexp, $this->database))
+			{
+				return;
+			}
+		}
+
+		/* Well - OK, an empty string should work as well.
+		 * PHP will try to use environment variables to
+		 * determine which Oracle instance to connect to.
+		 */
+		$this->dsn = '';
+	}
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access  private called by the base class
-	 * @return  resource
+	 * @return	resource
 	 */
 	public function db_connect()
 	{
-		return @oci_connect($this->username, $this->password, $this->hostname, $this->char_set);
+		return ( ! empty($this->char_set))
+			? @oci_connect($this->username, $this->password, $this->dsn, $this->char_set)
+			: @oci_connect($this->username, $this->password, $this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -97,43 +173,13 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access  private called by the base class
-	 * @return  resource
+	 * @return	resource
 	 */
 	public function db_pconnect()
 	{
-		return @oci_pconnect($this->username, $this->password, $this->hostname, $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
-	 *
-	 * @access	public
-	 * @return	void
-	 */
-	public function reconnect()
-	{
-		// not implemented in oracle
-		return;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access  private called by the base class
-	 * @return  resource
-	 */
-	public function db_select()
-	{
-		// Not in Oracle - schemas are actually usernames
-		return TRUE;
+		return ( ! empty($this->char_set))
+			? @oci_pconnect($this->username, $this->password, $this->dsn, $this->char_set)
+			: @oci_pconnect($this->username, $this->password, $this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -155,63 +201,44 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access  protected  called by the base class
-	 * @param   string  an SQL query
-	 * @return  resource
+	 * @param	string	an SQL query
+	 * @return	resource
 	 */
 	protected function _execute($sql)
 	{
-		// oracle must parse the query before it is run. All of the actions with
-		// the query are based on the statement id returned by ociparse
+		/* Oracle must parse the query before it is run. All of the actions with
+		 * the query are based on the statement id returned by oci_parse().
+		 */
 		$this->stmt_id = FALSE;
 		$this->_set_stmt_id($sql);
 		oci_set_prefetch($this->stmt_id, 1000);
-		return @oci_execute($this->stmt_id, $this->_commit);
+		return @oci_execute($this->stmt_id, $this->commit_mode);
 	}
 
 	/**
 	 * Generate a statement ID
 	 *
-	 * @access  private
-	 * @param   string  an SQL query
-	 * @return  none
+	 * @param	string	an SQL query
+	 * @return	void
 	 */
-	private function _set_stmt_id($sql)
+	protected function _set_stmt_id($sql)
 	{
 		if ( ! is_resource($this->stmt_id))
 		{
-			$this->stmt_id = oci_parse($this->conn_id, $this->_prep_query($sql));
+			$this->stmt_id = oci_parse($this->conn_id, $sql);
 		}
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
+	 * Get cursor. Returns a cursor from the database
 	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access  private called by execute()
-	 * @param   string  an SQL query
-	 * @return  string
-	 */
-	private function _prep_query($sql)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * getCursor.  Returns a cursor from the datbase
-	 *
-	 * @access  public
-	 * @return  cursor id
+	 * @return	cursor id
 	 */
 	public function get_cursor()
 	{
-		$this->curs_id = oci_new_cursor($this->conn_id);
-		return $this->curs_id;
+		return $this->curs_id = oci_new_cursor($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -219,20 +246,19 @@
 	/**
 	 * Stored Procedure.  Executes a stored procedure
 	 *
-	 * @access  public
-	 * @param   package	 package stored procedure is in
-	 * @param   procedure   stored procedure to execute
-	 * @param   params	  array of parameters
-	 * @return  array
+	 * @param	string	package name in which the stored procedure is in
+	 * @param	string	stored procedure name to execute
+	 * @param	array	parameters
+	 * @return	mixed
 	 *
 	 * params array keys
 	 *
 	 * KEY	  OPTIONAL	NOTES
-	 * name		no		the name of the parameter should be in :<param_name> format
-	 * value	no		the value of the parameter.  If this is an OUT or IN OUT parameter,
-	 *					this should be a reference to a variable
-	 * type		yes		the type of the parameter
-	 * length	yes		the max size of the parameter
+	 * name		no	the name of the parameter should be in :<param_name> format
+	 * value	no	the value of the parameter.  If this is an OUT or IN OUT parameter,
+	 *				this should be a reference to a variable
+	 * type		yes	the type of the parameter
+	 * length	yes	the max size of the parameter
 	 */
 	public function stored_procedure($package, $procedure, $params)
 	{
@@ -247,24 +273,24 @@
 		}
 
 		// build the query string
-		$sql = "begin $package.$procedure(";
+		$sql = 'BEGIN '.$package.'.'.$procedure.'(';
 
 		$have_cursor = FALSE;
 		foreach ($params as $param)
 		{
-			$sql .= $param['name'] . ",";
+			$sql .= $param['name'].',';
 
-			if (array_key_exists('type', $param) && ($param['type'] === OCI_B_CURSOR))
+			if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
 			{
 				$have_cursor = TRUE;
 			}
 		}
-		$sql = trim($sql, ",") . "); end;";
+		$sql = trim($sql, ',') . '); END;';
 
 		$this->stmt_id = FALSE;
 		$this->_set_stmt_id($sql);
 		$this->_bind_params($params);
-		$this->query($sql, FALSE, $have_cursor);
+		return $this->query($sql, FALSE, $have_cursor);
 	}
 
 	// --------------------------------------------------------------------
@@ -272,10 +298,9 @@
 	/**
 	 * Bind parameters
 	 *
-	 * @access  private
-	 * @return  none
+	 * @return	void
 	 */
-	private function _bind_params($params)
+	protected function _bind_params($params)
 	{
 		if ( ! is_array($params) OR ! is_resource($this->stmt_id))
 		{
@@ -301,7 +326,6 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function trans_begin($test_mode = FALSE)
@@ -322,7 +346,7 @@
 		// even if the queries produce a successful result.
 		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
 
-		$this->_commit = OCI_DEFAULT;
+		$this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
 		return TRUE;
 	}
 
@@ -331,7 +355,6 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function trans_commit()
@@ -347,9 +370,8 @@
 			return TRUE;
 		}
 
-		$ret = oci_commit($this->conn_id);
-		$this->_commit = OCI_COMMIT_ON_SUCCESS;
-		return $ret;
+		$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
+		return oci_commit($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -357,25 +379,18 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @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)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$ret = oci_rollback($this->conn_id);
-		$this->_commit = OCI_COMMIT_ON_SUCCESS;
-		return $ret;
+		$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
+		return oci_rollback($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -417,8 +432,7 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function affected_rows()
 	{
@@ -430,8 +444,7 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function insert_id()
 	{
@@ -447,9 +460,8 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access  public
-	 * @param   string
-	 * @return  string
+	 * @param	string
+	 * @return	int
 	 */
 	public function count_all($table = '')
 	{
@@ -476,17 +488,16 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	protected
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SELECT TABLE_NAME FROM ALL_TABLES";
+		$sql = 'SELECT TABLE_NAME FROM ALL_TABLES';
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix != '')
 		{
-			$sql .= " WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+			return $sql." WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
 
 		return $sql;
@@ -499,13 +510,12 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access  protected
-	 * @param   string  the table name
-	 * @return  string
+	 * @param	string	the table name
+	 * @return	string
 	 */
 	protected function _list_columns($table = '')
 	{
-		return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'";
+		return 'SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = \''.$table.'\'';
 	}
 
 	// --------------------------------------------------------------------
@@ -515,13 +525,12 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access  public
-	 * @param   string  the table name
-	 * @return  object
+	 * @param	string	the table name
+	 * @return	string
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." where rownum = 1";
+		return 'SELECT * FROM '.$table.' WHERE rownum = 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -558,83 +567,17 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	protected
-	 * @param	string
-	 * @return	string
-	 */
-	protected function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	protected
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @access  public
-	 * @param   string  the table name
-	 * @param   array   the insert keys
-	 * @param   array   the insert values
-	 * @return  string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -644,10 +587,10 @@
 	 *
 	 * 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
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param 	array	the insert values
+	 * @return	string
 	 */
 	protected function _insert_batch($table, $keys, $values)
 	{
@@ -656,47 +599,10 @@
 
 		for ($i = 0, $c = count($values); $i < $c; $i++)
 		{
-			$sql .= '	INTO ' . $table . ' (' . $keys . ') VALUES ' . $values[$i] . "\n";
+			$sql .= '	INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
 		}
 
-		$sql .= 'SELECT * FROM dual';
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	protected
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return $sql.'SELECT * FROM dual';
 	}
 
 	// --------------------------------------------------------------------
@@ -705,16 +611,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	protected
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return "TRUNCATE TABLE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -724,31 +630,21 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	protected
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+		empty($limit) OR $conditions[] = 'rownum <= '.$limit;
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -758,26 +654,16 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access  protected
-	 * @param   string  the sql query string
-	 * @param   integer the number of rows to limit the query to
-	 * @param   integer the offset value
-	 * @return  string
+	 * @param	string	the sql query string
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
+	 * @return	string
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		$limit = $offset + $limit;
-		$newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)";
-
-		if ($offset != 0)
-		{
-			$newsql .= " WHERE rnum >= $offset";
-		}
-
-		// remember that we used limits
 		$this->limit_used = TRUE;
-
-		return $newsql;
+		return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit).')'
+			.($offset != 0 ? ' WHERE rnum >= '.$offset : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -785,19 +671,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access  protected
-	 * @param   resource
-	 * @return  void
+	 * @param	resource
+	 * @return	void
 	 */
 	protected function _close($conn_id)
 	{
 		@oci_close($conn_id);
 	}
 
-
 }
 
-
-
 /* End of file oci8_driver.php */
 /* Location: ./system/database/drivers/oci8/oci8_driver.php */
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index 48f98d0..bd265b6 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Oracle Forge Class
  *
@@ -36,33 +34,9 @@
  */
 class CI_DB_oci8_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	public
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -72,9 +46,9 @@
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
-	 * @return	bool
+	 * @return	string
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -83,7 +57,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' (';
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
 		foreach ($fields as $field => $attributes)
@@ -132,7 +106,7 @@
 					$key = array($this->db->protect_identifiers($key));
 				}
 
-				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).")";
+				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).')';
 			}
 		}
 
@@ -142,87 +116,38 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
+		return $sql.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @access	private
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	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 oci8_forge.php */
-/* Location: ./system/database/drivers/oci8/oci8_forge.php */
+/* Location: ./system/database/drivers/oci8/oci8_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index 383b9f1..7b05e0a 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * oci8 Result Class
  *
@@ -41,6 +39,12 @@
 	public $stmt_id;
 	public $curs_id;
 	public $limit_used;
+	public $commit_mode;
+
+	/* Overwriting the parent here, so we have a way to know if it's
+	 * already called or not:
+	 */
+	public $num_rows;
 
 	public function __construct(&$driver_object)
 	{
@@ -48,30 +52,32 @@
 		$this->stmt_id = $driver_object->stmt_id;
 		$this->curs_id = $driver_object->curs_id;
 		$this->limit_used = $driver_object->limit_used;
+		$this->commit_mode =& $driver_object->commit_mode;
 		$driver_object->stmt_id = FALSE;
 	}
 
 	/**
 	 * Number of rows in the result set.
 	 *
-	 * Oracle doesn't have a graceful way to retun the number of rows
+	 * Oracle doesn't have a graceful way to return the number of rows
 	 * so we have to use what amounts to a hack.
 	 *
-	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function num_rows()
 	{
-		if ($this->num_rows === 0 && count($this->result_array()) > 0)
+		if ( ! is_int($this->num_rows))
 		{
-			$this->num_rows = count($this->result_array());
-			@oci_execute($this->stmt_id, OCI_DEFAULT);
-
-			if ($this->curs_id)
+			if (count($this->result_array) > 0)
 			{
-				@oci_execute($this->curs_id, OCI_DEFAULT);
+				return $this->num_rows = count($this->result_array);
 			}
+			elseif (count($this->result_object) > 0)
+			{
+				return $this->num_rows = count($this->result_object);
+			}
+
+			return $this->num_rows = count($this->result_array());
 		}
 
 		return $this->num_rows;
@@ -82,20 +88,14 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access  public
-	 * @return  integer
+	 * @return	int
 	 */
 	public function num_fields()
 	{
 		$count = @oci_num_fields($this->stmt_id);
 
 		// if we used a limit we subtract it
-		if ($this->limit_used)
-		{
-			$count = $count - 1;
-		}
-
-		return $count;
+		return ($this->limit_used) ? $count - 1 : $count;
 	}
 
 	// --------------------------------------------------------------------
@@ -105,7 +105,6 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function list_fields()
@@ -125,18 +124,17 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access  public
-	 * @return  array
+	 * @return	array
 	 */
 	public function field_data()
 	{
 		$retval = array();
 		for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
 		{
-			$F			= new stdClass();
-			$F->name		= oci_field_name($this->stmt_id, $c);
-			$F->type		= oci_field_type($this->stmt_id, $c);
-			$F->max_length		= oci_field_size($this->stmt_id, $c);
+			$F		= new stdClass();
+			$F->name	= oci_field_name($this->stmt_id, $c);
+			$F->type	= oci_field_type($this->stmt_id, $c);
+			$F->max_length	= oci_field_size($this->stmt_id, $c);
 
 			$retval[] = $F;
 		}
@@ -149,7 +147,7 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	public function free_result()
 	{
@@ -158,6 +156,17 @@
 			oci_free_statement($this->result_id);
 			$this->result_id = FALSE;
 		}
+
+		if (is_resource($this->stmt_id))
+		{
+			oci_free_statement($this->stmt_id);
+		}
+
+		if (is_resource($this->curs_id))
+		{
+			oci_cancel($this->curs_id);
+			$this->curs_id = NULL;
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -167,8 +176,7 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access  protected
-	 * @return  array
+	 * @return	array
 	 */
 	protected function _fetch_assoc()
 	{
@@ -183,22 +191,20 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access  protected
-	 * @return  object
+	 * @return	object
 	 */
 	protected function _fetch_object()
 	{
 		$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
-		return @oci_fetch_object($id);
+		return oci_fetch_object($id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Query result.  "array" version.
+	 * Query result. Array version.
 	 *
-	 * @access  public
-	 * @return  array
+	 * @return	array
 	 */
 	public function result_array()
 	{
@@ -206,14 +212,429 @@
 		{
 			return $this->result_array;
 		}
+		elseif (count($this->result_object) > 0)
+		{
+			for ($i = 0, $c = count($this->result_object); $i < $c; $i++)
+			{
+				$this->result_array[$i] = (array) $this->result_object[$i];
+			}
+
+			return $this->result_array;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_array;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
 
 		$row = NULL;
 		while ($row = $this->_fetch_assoc())
 		{
-			$this->result_array[] = $row;
+			$this->row_data[$row_index++] = $row;
 		}
 
-		return $this->result_array;
+		return $this->result_array = $this->row_data;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "object" version.
+	 *
+	 * @return	array
+	 */
+	public function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		elseif (count($this->result_array) > 0)
+		{
+			for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
+			{
+				$this->result_object[] = (object) $this->result_array[$i];
+			}
+
+			return $this->result_object;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_object;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+				for ($i = 0; $i < $row_index; $i++)
+				{
+					$this->result_object[$i] = (object) $this->row_data[$i];
+				}
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_object())
+		{
+			$this->row_data[$row_index] = (array) $row;
+			$this->result_object[$row_index++] = $row;
+		}
+
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. Custom object version.
+	 *
+	 * @param	string	class name used to instantiate rows to
+	 * @return	array
+	 */
+	public function custom_result_object($class_name)
+	{
+		if (isset($this->custom_result_object[$class_name]))
+		{
+			return $this->custom_result_object[$class_name];
+		}
+
+		if ( ! class_exists($class_name) OR $this->result_id === FALSE OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if we didn't have result_array or result_object
+		 * set prior to custom_result_object() being called,
+		 * num_rows() has already done so.
+		 * Pass by reference, as we don't know how
+		 * large it might be and we don't want 1000 row
+		 * sets being copied.
+		 */
+		if (count($this->result_array) > 0)
+		{
+			$data = &$this->result_array;
+		}
+		elseif (count($this->result_object) > 0)
+		{
+			$data = &$this->result_object;
+		}
+
+		$this->custom_result_object[$class_name] = array();
+		for ($i = 0, $c = count($data); $i < $c; $i++)
+		{
+			$this->custom_result_object[$class_name][$i] = new $class_name();
+			foreach ($data[$i] as $key => $value)
+			{
+				$this->custom_result_object[$class_name][$i]->$key = $value;
+			}
+		}
+
+		return $this->custom_result_object[$class_name];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result.
+	 *
+	 * Acts as a wrapper for row_object(), row_array()
+	 * and custom_row_object(). Also used by first_row(), next_row()
+	 * and previous_row().
+	 *
+	 * @param	int	row index
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function row($n = 0, $type = 'object')
+	{
+		if ($type === 'object')
+		{
+			return $this->row_object($n);
+		}
+		elseif ($type === 'array')
+		{
+			return $this->row_array($n);
+		}
+
+		return $this->custom_row_object($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Array version.
+	 *
+	 * @param	int	row index
+	 * @return	array
+	 */
+	public function row_array($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* If row_data is initialized, it means that we've already tried
+		 * (at least) to fetch some data, so ... check if we already have
+		 * this row.
+		*/
+		if (is_array($this->row_data))
+		{
+			/* If we already have row_data[$n] - return it.
+			 *
+			 * If we enter the elseif, there's a number of reasons to
+			 * return an empty array:
+			 *
+			 *	- count($this->row_data) === 0 means there are no results
+			 *	- num_rows being set, result_array and/or result_object
+			 *	  having count() > 0 means that we've already fetched all
+			 *	  data and $n is greater than our highest row index available
+			 *	- $n < $this->current_row means that if such row existed,
+			 *	  we would've already returned it, therefore $n is an
+			 *	  invalid index
+			 */
+			if (isset($this->row_data[$n])) // We already have this row
+			{
+				$this->current_row = $n;
+				return $this->row_data[$n];
+			}
+			elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
+				OR count($this->result_array) > 0 OR count($this->result_object) > 0
+				OR $n < $this->current_row)
+			{
+				// No such row exists
+				return array();
+			}
+
+			// Get the next row index that would actually need to be fetched
+			$current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
+		}
+		else
+		{
+			$current_row = $this->current_row = 0;
+			$this->row_data = array();
+		}
+
+		/* Fetch more data, if available
+		 *
+		 * NOTE: Operator precedence is important here, if you change
+		 *	 'AND' with '&&' - it WILL BREAK the results, as
+		 *	 $row will be assigned the scalar value of both
+		 *	 expressions!
+		 */
+		while ($row = $this->_fetch_assoc() AND $current_row <= $n)
+		{
+			$this->row_data[$current_row++] = $row;
+		}
+
+		// This would mean that there's no (more) data to fetch
+		if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
+		{
+			// Cache what we already have
+			if (is_array($this->row_data))
+			{
+				$this->num_rows = count($this->row_data);
+				/* Usually, row_data could have less elements than result_array,
+				 * but at this point - they should be exactly the same.
+				 */
+				$this->result_array = $this->row_data;
+			}
+			else
+			{
+				$this->num_rows = 0;
+			}
+
+			return array();
+		}
+
+		$this->current_row = $n;
+		return $this->row_data[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Object version.
+	 *
+	 * @param	int	row index
+	 * @return	mixed	object if row found; empty array if not
+	 */
+	public function row_object($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+		/* Logic here is exactly the same as in row_array,
+		 * except we have to cast row_data[$n] to an object.
+		 *
+		 * If we already have result_object though - we can
+		 * directly return from it.
+		 */
+		if (isset($this->result_object[$n]))
+		{
+			$this->current_row = $n;
+			// Set this, if not already done.
+			if ( ! is_int($this->num_rows))
+			{
+				$this->num_rows = count($this->result_object);
+			}
+
+			return $this->result_object[$n];
+		}
+
+		$row = $this->row_array($n);
+		// Cast only if the row exists
+		if (count($row) > 0)
+		{
+			$this->current_row = $n;
+			return (object) $row;
+		}
+
+		return array();
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Custom object version.
+	 *
+	 * @param	int	row index
+	 * @param	string	custom class name
+	 * @return	mixed	custom object if row found; empty array otherwise
+	 */
+	public function custom_row_object($n = 0, $class_name)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			/* We already have a the whole result set with this class_name,
+			 * return the specified row if it exists, and an empty array if
+			 * it doesn't.
+			 */
+			if (isset($this->custom_result_object[$class_name][$n]))
+			{
+				$this->current_row = $n;
+				return $this->custom_result_object[$class_name][$n];
+			}
+			else
+			{
+				return array();
+			}
+		}
+		elseif ( ! class_exists($class_name)) // No such class exists
+		{
+			return array();
+		}
+
+		$row = $this->row_array($n);
+		// An array would mean that the row doesn't exist
+		if (is_array($row))
+		{
+			return $row;
+		}
+
+		// Convert to the desired class and return
+		$row_object = new $class_name();
+		foreach ($row as $key => $value)
+		{
+			$row_object->$key = $value;
+		}
+
+		$this->current_row = $n;
+		return $row_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* First row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function first_row($type = 'object')
+	{
+		return $this->row(0, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Last row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function last_row($type = 'object')
+	{
+		$result = &$this->result($type);
+		if ( ! isset($this->num_rows))
+		{
+			$this->num_rows = count($result);
+		}
+		$this->current_row = $this->num_rows - 1;
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Next row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function next_row($type = 'object')
+	{
+		if (is_array($this->row_data))
+		{
+			$count = count($this->row_data);
+			if ($this->current_row > $count OR ($this->current_row === 0 && $count === 0))
+			{
+				$n = $count;
+			}
+			else
+			{
+				$n = $this->current_row + 1;
+			}
+		}
+		else
+		{
+			$n = 0;
+		}
+
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Previous row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function previous_row($type = 'object')
+	{
+		$n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
+		return $this->row($n, $type);
 	}
 
 	// --------------------------------------------------------------------
@@ -221,20 +642,59 @@
 	/**
 	 * 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
+	 * result set starts at zero.
 	 *
-	 * @access	protected
-	 * @return	array
+	 * Oracle's PHP extension doesn't have an easy way of doing this
+	 * and the only workaround is to (re)execute the statement or cursor
+	 * in order to go to the first (zero) index of the result set.
+	 * Then, we would need to "dummy" fetch ($n - 1) rows to get to the
+	 * right one.
+	 *
+	 * This is as ridiculous as it sounds and it's the reason why every
+	 * other method that is fetching data tries to use an already "cached"
+	 * result set. Keeping this just in case it becomes needed at
+	 * some point in the future, but it will only work for resetting the
+	 * pointer to zero.
+	 *
+	 * @return	bool
 	 */
-	protected function _data_seek($n = 0)
+	protected function _data_seek()
 	{
-		return FALSE; // Not needed
+		/* The PHP manual says that if OCI_NO_AUTO_COMMIT mode
+		 * is used, and oci_rollback() and/or oci_commit() are
+		 * not subsequently called - this will cause an unnecessary
+		 * rollback to be triggered at the end of the script execution.
+		 *
+		 * Therefore we'll try to avoid using that mode flag
+		 * if we're not currently in the middle of a transaction.
+		 */
+		if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+		{
+			$result = @oci_execute($this->stmt_id, $this->commit_mode);
+		}
+		else
+		{
+			$result = @oci_execute($this->stmt_id);
+		}
+
+		if ($result && $this->curs_id)
+		{
+			if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+			{
+				return @oci_execute($this->curs_id, $this->commit_mode);
+			}
+			else
+			{
+				return @oci_execute($this->curs_id);
+			}
+		}
+
+		return $result;
 	}
 
 }
 
-
 /* End of file oci8_result.php */
-/* Location: ./system/database/drivers/oci8/oci8_result.php */
+/* Location: ./system/database/drivers/oci8/oci8_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index d60f98b..0183eda 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Oracle Utility Class
  *
@@ -36,63 +34,20 @@
  */
 class CI_DB_oci8_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT username FROM dba_users'; // Schemas are actual usernames
 
 	/**
 	 * Oracle Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
 	}
+
 }
 
 /* End of file oci8_utility.php */
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index a616c9d..e36f2d2 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Database Adapter Class
  *
@@ -42,40 +40,44 @@
  */
 class CI_DB_odbc_driver extends CI_DB {
 
-	var $dbdriver = 'odbc';
+	public $dbdriver = 'odbc';
 
 	// the character used to excape - not necessary for ODBC
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " {escape '%s'} ";
-	var $_like_escape_chr = '!';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword;
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword;
 
-
-	function __construct($params)
+	public function __construct($params)
 	{
 		parent::__construct($params);
 
 		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
+
+		// Legacy support for DSN in the hostname field
+		if ($this->dsn == '')
+		{
+			$this->dsn = $this->hostname;
+		}
 	}
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		return @odbc_connect($this->hostname, $this->username, $this->password);
+		return @odbc_connect($this->dsn, $this->username, $this->password);
 	}
 
 	// --------------------------------------------------------------------
@@ -83,42 +85,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return @odbc_pconnect($this->hostname, $this->username, $this->password);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		// not implemented in odbc
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for ODBC
-		return TRUE;
+		return @odbc_pconnect($this->dsn, $this->username, $this->password);
 	}
 
 	// --------------------------------------------------------------------
@@ -126,41 +97,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @odbc_exec($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -186,10 +138,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -212,10 +163,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -238,12 +188,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))
 		{
@@ -261,9 +210,9 @@
 		// 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;
@@ -274,10 +223,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @odbc_num_rows($this->conn_id);
 	}
@@ -302,11 +250,10 @@
 	 * 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 == '')
 		{
@@ -332,11 +279,10 @@
 	 *
 	 * 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->database."`";
 
@@ -356,11 +302,10 @@
 	 *
 	 * 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 ".$table;
 	}
@@ -372,11 +317,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT TOP 1 FROM ".$table;
 	}
@@ -399,58 +343,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -463,107 +364,19 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * 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)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -573,13 +386,12 @@
 	 *
 	 * 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)
 	{
 		// Does ODBC doesn't use the LIMIT clause?
 		return $sql;
@@ -590,19 +402,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@odbc_close($conn_id);
 	}
 
-
 }
 
-
-
 /* End of file odbc_driver.php */
 /* 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 51addf0..d59b8a9 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Forge Class
  *
@@ -36,58 +34,20 @@
  */
 class CI_DB_odbc_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database()
-	{
-		// ODBC has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// ODBC has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
 	 *
-	 * @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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -96,10 +56,10 @@
 			$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
@@ -184,40 +144,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
@@ -252,25 +193,7 @@
 
 	}
 
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file odbc_forge.php */
-/* Location: ./system/database/drivers/odbc/odbc_forge.php */
+/* Location: ./system/database/drivers/odbc/odbc_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index de2c58c..ecba597 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Result Class
  *
@@ -128,9 +126,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -142,33 +140,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
-		if (function_exists('odbc_fetch_object'))
+		if (function_exists('odbc_fetch_array'))
 		{
 			return odbc_fetch_array($this->result_id);
 		}
@@ -185,10 +165,9 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		if (function_exists('odbc_fetch_object'))
 		{
@@ -200,6 +179,7 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
 	/**
 	 * Result - object
@@ -207,21 +187,24 @@
 	 * subsititutes the odbc_fetch_object function when
 	 * not available (odbc_fetch_object requires unixODBC)
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _odbc_fetch_object(& $odbc_result) {
+	protected function _odbc_fetch_object(& $odbc_result)
+	{
 		$rs = array();
 		$rs_obj = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs)) {
-			foreach ($rs as $k=>$v) {
-				$field_name= odbc_field_name($odbc_result, $k+1);
+		if (odbc_fetch_into($odbc_result, $rs))
+		{
+			foreach ($rs as $k => $v)
+			{
+				$field_name = odbc_field_name($odbc_result, $k+1);
 				$rs_obj->$field_name = $v;
 			}
 		}
 		return $rs_obj;
 	}
 
+	// --------------------------------------------------------------------
 
 	/**
 	 * Result - array
@@ -229,16 +212,18 @@
 	 * subsititutes the odbc_fetch_array function when
 	 * not available (odbc_fetch_array requires unixODBC)
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _odbc_fetch_array(& $odbc_result) {
+	protected function _odbc_fetch_array(& $odbc_result)
+	{
 		$rs = array();
 		$rs_assoc = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs)) {
-			$rs_assoc=array();
-			foreach ($rs as $k=>$v) {
-				$field_name= odbc_field_name($odbc_result, $k+1);
+		if (odbc_fetch_into($odbc_result, $rs))
+		{
+			$rs_assoc = array();
+			foreach ($rs as $k => $v)
+			{
+				$field_name = odbc_field_name($odbc_result, $k+1);
 				$rs_assoc[$field_name] = $v;
 			}
 		}
@@ -318,4 +303,4 @@
 }
 
 /* End of file odbc_result.php */
-/* Location: ./system/database/drivers/odbc/odbc_result.php */
+/* Location: ./system/database/drivers/odbc/odbc_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php
index bae3fe8..224d48d 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * ODBC Utility Class
  *
@@ -36,74 +34,15 @@
  */
 class CI_DB_odbc_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		// Not sure if ODBC lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * ODBC Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index 83a9c31..f4c3a74 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Database Adapter Class
  *
@@ -42,28 +40,28 @@
  */
 class CI_DB_pdo_driver extends CI_DB {
 
-	var $dbdriver = 'pdo';
+	public $dbdriver = 'pdo';
 
 	// the character used to excape - not necessary for PDO
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str;
-	var $_like_escape_chr;
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword;
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword;
 
 	// need to track the pdo driver and options
-	var $pdodriver;
-	var $options = array();
+	public $pdodriver;
+	public $options = array();
 
-	function __construct($params)
+	public function __construct($params)
 	{
 		parent::__construct($params);
 
@@ -83,32 +81,30 @@
 		// this one depends on the driver being used
 		if ($this->pdodriver == 'mysql')
 		{
+			$this->_escape_char = '`';
 			$this->_like_escape_str = '';
 			$this->_like_escape_chr = '';
 		}
 		elseif ($this->pdodriver == 'odbc')
 		{
 			$this->_like_escape_str = " {escape '%s'} ";
-			$this->_like_escape_chr = '!';
 		}
-		else
+		elseif ( ! in_array($this->pdodriver, array('sqlsrv', 'mssql', 'dblib', 'sybase')))
 		{
-			$this->_like_escape_str = " ESCAPE '%s' ";
-			$this->_like_escape_chr = '!';
+			$this->_escape_char = '"';
 		}
-		
-		$this->trans_enabled   = FALSE;
+
+		$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)
+	protected function _connect_string($params)
 	{
 		if (strpos($this->hostname, ':'))
 		{
@@ -138,7 +134,7 @@
 			$this->dsn = $this->pdodriver.':';
 
 			// Add hostname to the DSN for databases that need it
-			if ( ! empty($this->hostname) 
+			if ( ! empty($this->hostname)
 				&& strpos($this->hostname, ':') === FALSE
 				&& in_array($this->pdodriver, array('informix', 'mysql', 'pgsql', 'sybase', 'mssql', 'dblib', 'cubrid')))
 			{
@@ -153,7 +149,7 @@
 		}
 
 		// Add the database name to the DSN, if needed
-	    if (stripos($this->dsn, 'dbname') === FALSE 
+	    if (stripos($this->dsn, 'dbname') === FALSE
 	       && in_array($this->pdodriver, array('4D', 'pgsql', 'mysql', 'firebird', 'sybase', 'mssql', 'dblib', 'cubrid')))
 	    {
 	        $this->dsn .= 'dbname='.$this->database.';';
@@ -187,17 +183,16 @@
 	    }
 	}
 
+	// --------------------------------------------------------------------
+
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
-
-		return $this->pdo_connect();
+		return $this->_pdo_connect();
 	}
 
 	// --------------------------------------------------------------------
@@ -205,15 +200,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		$this->options[PDO::ATTR_ERRMODE]    = PDO::ERRMODE_SILENT;
-		$this->options[PDO::ATTR_PERSISTENT] = TRUE;
-	
-		return $this->pdo_connect();
+		return $this->_pdo_connect(TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -221,23 +212,31 @@
 	/**
 	 * PDO connection
 	 *
-	 * @access	private called by the PDO driver class
-	 * @return	resource
+	 * @param	bool
+	 * @return	object
 	 */
-	function pdo_connect()
+	protected function _pdo_connect($persistent = FALSE)
 	{
-		// Refer : http://php.net/manual/en/ref.pdo-mysql.connection.php
-		if ($this->pdodriver == 'mysql' && is_php('5.3.6'))
+		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
+		$persistent === FALSE OR $this->options[PDO::ATTR_PERSISTENT] = TRUE;
+
+		/* Prior to PHP 5.3.6, even if the charset was supplied in the DSN
+		 * on connect - it was ignored. This is a work-around for the issue.
+		 *
+		 * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php
+		 */
+		if ($this->subdriver === 'mysql' && ! is_php('5.3.6') && ! empty($this->char_set))
 		{
-			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES $this->char_set COLLATE '$this->dbcollat'";
+			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set
+					.( ! empty($this->db_collat) ? " COLLATE '".$this->dbcollat."'" : '');
 		}
 
 		// Connecting...
-		try 
+		try
 		{
-			$db = new PDO($this->dsn, $this->username, $this->password, $this->options);
-		} 
-		catch (PDOException $e) 
+			return new PDO($this->dsn, $this->username, $this->password, $this->options);
+		}
+		catch (PDOException $e)
 		{
 			if ($this->db_debug && empty($this->failover))
 			{
@@ -246,43 +245,6 @@
 
 			return FALSE;
 		}
-
-		return $db;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for PDO
-		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -304,53 +266,12 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
-	 * @return	object
+	 * @return	mixed
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-
-		$result_id = $this->conn_id->query($sql);
-		
-		if (is_object($result_id))
-		{
-			$this->affect_rows = $result_id->rowCount();
-		}
-		else
-		{
-			$this->affect_rows = 0;
-		}
-		
-		return $result_id;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @access	private called by execute()
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	function _prep_query($sql)
-	{
-		if ($this->pdodriver === 'pgsql')
-		{
-			// Change the backtick(s) for Postgre
-			$sql = str_replace('`', '"', $sql);
-		}
-		elseif ($this->pdodriver === 'sqlite')
-		{
-			// Change the backtick(s) for SQLite
-			$sql = str_replace('`', '', $sql);
-		}
-
-		return $sql;
+		return $this->conn_id->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -358,18 +279,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;
 		}
@@ -377,7 +292,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = (bool) ($test_mode === TRUE);
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		return $this->conn_id->beginTransaction();
 	}
@@ -387,25 +302,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;
 		}
 
-		$ret = $this->conn->commit();
-		
-		return $ret;
+		return $this->conn_id->commit();
 	}
 
 	// --------------------------------------------------------------------
@@ -413,25 +320,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;
 		}
 
-		$ret = $this->conn_id->rollBack();
-
-		return $ret;
+		return $this->conn_id->rollBack();
 	}
 
 	// --------------------------------------------------------------------
@@ -439,12 +338,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))
 		{
@@ -455,24 +353,22 @@
 
 			return $str;
 		}
-		
-		//Escape the string
+
+		// Escape the string
 		$str = $this->conn_id->quote($str);
-		
-		//If there are duplicated quotes, trim them away
+
+		// If there are duplicated quotes, trim them away
 		if (strpos($str, "'") === 0)
 		{
 			$str = substr($str, 1, -1);
 		}
-		
+
 		// 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;
@@ -483,12 +379,11 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
-		return $this->affect_rows;
+		return is_object($this->result_id) ? $this->result_id->rowCount() : 0;
 	}
 
 	// --------------------------------------------------------------------
@@ -496,6 +391,7 @@
 	/**
 	 * Insert ID
 	 *
+	 * @param	string
 	 * @return	int
 	 */
 	public function insert_id($name = NULL)
@@ -518,11 +414,10 @@
 	 * 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 == '')
 		{
@@ -550,25 +445,29 @@
 	 *
 	 * 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)
 	{
 		if ($this->pdodriver == 'pgsql')
 		{
 			// Analog function to show all tables in postgre
 			$sql = "SELECT * FROM information_schema.tables WHERE table_schema = 'public'";
 		}
+		elseif ($this->pdodriver == 'sqlite')
+		{
+			// Analog function to show all tables in sqlite
+			$sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'";
+		}
 		else
 		{
-			$sql = "SHOW TABLES FROM `".$this->database."`";
+			$sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database);
 		}
 
 		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
 		{
-			return FALSE; 
+			return FALSE;
 		}
 
 		return $sql;
@@ -581,13 +480,12 @@
 	 *
 	 * 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->_from_tables($table);
+		return 'SHOW COLUMNS FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -597,13 +495,28 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
-		return 'SELECT TOP 1 FROM '.$this->_from_tables($table);
+		if ($this->pdodriver == 'mysql' or $this->pdodriver == 'pgsql')
+		{
+			// Analog function for mysql and postgre
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' LIMIT 1';
+		}
+		elseif ($this->pdodriver == 'oci')
+		{
+			// Analog function for oci
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' WHERE ROWNUM <= 1';
+		}
+		elseif ($this->pdodriver == 'sqlite')
+		{
+			// Analog function for sqlite
+			return 'PRAGMA table_info('.$this->escape_identifiers($table).')';
+		}
+
+		return 'SELECT TOP 1 FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -638,150 +551,37 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str  = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-			$str .= $this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
 			$tables = array($tables);
 		}
 
-		return (count($tables) == 1) ? '`'.$tables[0].'`' : '('.implode(', ', $tables).')';
+		return (count($tables) === 1) ? $tables[0] : '('.implode(', ', $tables).')';
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-	
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @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)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit   = ( ! $limit) ? '' : ' LIMIT '.$limit;
-		$orderby = (count($orderby) >= 1) ? ' ORDER BY '.implode(', ', $orderby) : '';
-
-		$sql  = 'UPDATE '.$this->_from_tables($table).' SET '.implode(', ', $valstr);
-		$sql .= ($where != '' && count($where) >= 1) ? ' WHERE '.implode(' ', $where) : '';
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-	
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @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 != '' && count($where) >=1) ? implode(" ", $where).' AND ' : '';
@@ -799,7 +599,7 @@
 			}
 		}
 
-		$sql   = 'UPDATE '.$this->_from_tables($table).' SET ';
+		$sql   = 'UPDATE '.$table.' SET ';
 		$cases = '';
 
 		foreach ($final as $k => $v)
@@ -820,58 +620,22 @@
 		return $sql;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * 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)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions  = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return 'DELETE FROM '.$this->_from_tables($table).$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -881,13 +645,12 @@
 	 *
 	 * 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 ($this->pdodriver == 'cubrid' OR $this->pdodriver == 'sqlite')
 		{
@@ -899,7 +662,7 @@
 		{
 			$sql .= 'LIMIT '.$limit;
 			$sql .= ($offset > 0) ? ' OFFSET '.$offset : '';
-			
+
 			return $sql;
 		}
 	}
@@ -909,13 +672,12 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
-	 * @param	resource
+	 * @param	object
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
-		$this->conn_id = null;
+		$this->conn_id = NULL;
 	}
 
 }
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index b4ddca5..ca8657a 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Forge Class
  *
@@ -36,58 +34,20 @@
  */
 class CI_DB_pdo_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database()
-	{
-		// PDO has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		// PDO has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
 	 *
-	 * @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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -96,10 +56,10 @@
 			$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
@@ -189,40 +149,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE `'.$this->db->protect_identifiers($table).'` '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
@@ -257,25 +198,7 @@
 
 	}
 
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file pdo_forge.php */
-/* Location: ./system/database/drivers/pdo/pdo_forge.php */
+/* Location: ./system/database/drivers/pdo/pdo_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index c333abc..19aee1d 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Result Class
  *
@@ -51,10 +49,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		if (empty($this->result_id) OR ! is_object($this->result_id))
 		{
@@ -74,10 +71,9 @@
 	/**
 	 * Fetch the result handler
 	 *
-	 * @access	public
 	 * @return	mixed
 	 */
-	function result_assoc()
+	public function result_assoc()
 	{
 		// If the result already fetched before, use that one
 		if (count($this->result_array) > 0 OR $this->is_fetched)
@@ -94,9 +90,8 @@
 			// 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())
 			{
@@ -116,10 +111,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return $this->result_id->columnCount();
 	}
@@ -131,16 +125,15 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
-	 * @return	array
+	 * @return	bool
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		if ($this->db->db_debug)
 		{
 			return $this->db->display_error('db_unsuported_feature');
 		}
-		
+
 		return FALSE;
 	}
 
@@ -151,20 +144,58 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$data = array();
-	
+
 		try
 		{
-			for($i = 0; $i < $this->num_fields(); $i++)
+			if (strpos($this->result_id->queryString, 'PRAGMA') !== FALSE)
 			{
-				$data[] = $this->result_id->getColumnMeta($i);
+				foreach ($this->result_array() as $field)
+				{
+					preg_match('/([a-zA-Z]+)(\(\d+\))?/', $field['type'], $matches);
+
+					$F		= new stdClass();
+					$F->name	= $field['name'];
+					$F->type	= ( ! empty($matches[1])) ? $matches[1] : NULL;
+					$F->default	= NULL;
+					$F->max_length	= ( ! empty($matches[2])) ? preg_replace('/[^\d]/', '', $matches[2]) : NULL;
+					$F->primary_key = (int) $field['pk'];
+					$F->pdo_type	= NULL;
+
+					$data[] = $F;
+				}
 			}
-			
+			else
+			{
+				for($i = 0, $max = $this->num_fields(); $i < $max; $i++)
+				{
+					$field = $this->result_id->getColumnMeta($i);
+
+					$F		= new stdClass();
+					$F->name	= $field['name'];
+					$F->type	= $field['native_type'];
+					$F->default	= NULL;
+					$F->pdo_type	= $field['pdo_type'];
+
+					if ($field['precision'] < 0)
+					{
+						$F->max_length	= NULL;
+						$F->primary_key = 0;
+					}
+					else
+					{
+						$F->max_length	= ($field['len'] > 255) ? 0 : $field['len'];
+						$F->primary_key = (int) ( ! empty($field['flags']) && in_array('primary_key', $field['flags']));
+					}
+
+					$data[] = $F;
+				}
+			}
+
 			return $data;
 		}
 		catch (Exception $e)
@@ -183,9 +214,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_object($this->result_id))
 		{
@@ -196,31 +227,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return $this->result_id->fetch(PDO::FETCH_ASSOC);
 	}
@@ -232,11 +245,10 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
-	{	
+	protected function _fetch_object()
+	{
 		return $this->result_id->fetchObject();
 	}
 
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index 971ec88..9308421 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * PDO Utility Class
  *
@@ -36,74 +34,15 @@
  */
 class CI_DB_pdo_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		// Not sure if PDO lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases = FALSE;
 
 	/**
 	 * PDO Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 9f21e9b..d858f01 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgre Database Adapter Class
  *
@@ -42,47 +40,81 @@
  */
 class CI_DB_postgre_driver extends CI_DB {
 
-	var $dbdriver = 'postgre';
+	public $dbdriver = 'postgre';
 
-	var $_escape_char = '"';
+	protected $_escape_char = '"';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " ESCAPE '%s' ";
-	var $_like_escape_chr = '!';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' RANDOM()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RANDOM()'; // database specific random keyword
 
 	/**
-	 * Connection String
+	 * Constructor
 	 *
-	 * @access	private
-	 * @return	string
+	 * Creates a DSN string to be used for db_connect() and db_pconnect()
+	 *
+	 * @return	void
 	 */
-	function _connect_string()
+	public function __construct($params)
 	{
-		$components = array(
-								'hostname'	=> 'host',
-								'port'		=> 'port',
-								'database'	=> 'dbname',
-								'username'	=> 'user',
-								'password'	=> 'password'
-							);
+		parent::__construct($params);
 
-		$connect_string = "";
-		foreach ($components as $key => $val)
+		if ( ! empty($this->dsn))
 		{
-			if (isset($this->$key) && $this->$key != '')
+			return;
+		}
+
+		$this->dsn === '' OR $this->dsn = '';
+
+		if (strpos($this->hostname, '/') !== FALSE)
+		{
+			// If UNIX sockets are used, we shouldn't set a port
+			$this->port = '';
+		}
+
+		$this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' ';
+
+		if ( ! empty($this->port) && ctype_digit($this->port))
+		{
+			$this->dsn .= 'port='.$this->port.' ';
+		}
+
+		if ($this->username !== '')
+		{
+			$this->dsn .= 'user='.$this->username.' ';
+
+			/* An empty password is valid!
+			 *
+			 * $db['password'] = NULL must be done in order to ignore it.
+			 */
+			$this->password === NULL OR $this->dsn .= "password='".$this->password."' ";
+		}
+
+		$this->database === '' OR $this->dsn .= 'dbname='.$this->database.' ';
+
+		/* We don't have these options as elements in our standard configuration
+		 * array, but they might be set by parse_url() if the configuration was
+		 * provided via string. Example:
+		 *
+		 * postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1
+		 */
+		foreach (array('connect_timeout', 'options', 'sslmode', 'service') as $key)
+		{
+			if (isset($this->$key) && is_string($this->key) && $this->key !== '')
 			{
-				$connect_string .= " $val=".$this->$key;
+				$this->dsn .= $key."='".$this->key."' ";
 			}
 		}
-		return trim($connect_string);
+
+		$this->dsn = rtrim($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -90,12 +122,11 @@
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		return @pg_connect($this->_connect_string());
+		return @pg_connect($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -103,12 +134,11 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return @pg_pconnect($this->_connect_string());
+		return @pg_pconnect($this->dsn);
 	}
 
 	// --------------------------------------------------------------------
@@ -119,10 +149,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 (pg_ping($this->conn_id) === FALSE)
 		{
@@ -133,20 +162,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		// Not needed for Postgre so we'll return TRUE
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Set client character set
 	 *
 	 * @param       string
@@ -191,35 +206,17 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @pg_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
 	 * @return	bool
@@ -281,12 +278,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))
 		{
@@ -303,9 +299,9 @@
 		// 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;
@@ -316,10 +312,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @pg_affected_rows($this->result_id);
 	}
@@ -329,10 +324,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	string
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		$v = $this->version();
 
@@ -372,11 +366,10 @@
 	 * 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 == '')
 		{
@@ -401,11 +394,10 @@
 	 *
 	 * 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 = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
 
@@ -424,11 +416,10 @@
 	 *
 	 * 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 "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
 	}
@@ -440,11 +431,10 @@
 	 *
 	 * 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)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -467,58 +457,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -531,84 +478,33 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * 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)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @access	public
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _truncate($table)
-	{
-		return "TRUNCATE ".$table;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
 
 	// --------------------------------------------------------------------
@@ -618,29 +514,20 @@
 	 *
 	 * 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
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return "DELETE FROM ".$table.$conditions;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -649,13 +536,12 @@
 	 *
 	 * 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;
 
@@ -672,18 +558,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@pg_close($conn_id);
 	}
 
-
 }
 
-
 /* End of file postgre_driver.php */
 /* 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 4a7348a..8b214eb 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgre Forge Class
  *
@@ -36,46 +34,20 @@
  */
 class CI_DB_postgre_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
+	protected $_drop_table	= 'DROP TABLE IF EXISTS %s CASCADE';
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-	
 	/**
 	 * Process Fields
 	 *
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields, $primary_keys=array())
+	protected function _process_fields($fields, $primary_keys=array())
 	{
 		$sql = '';
 		$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
@@ -168,7 +140,7 @@
 				$sql .= ',';
 			}
 		}
-		
+
 		return $sql;
 	}
 
@@ -177,15 +149,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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -198,8 +169,7 @@
 			}
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-		$sql .= $this->_process_fields($fields, $primary_keys);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields, $primary_keys);
 
 		if (count($primary_keys) > 0)
 		{
@@ -240,22 +210,11 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table)." CASCADE";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
 	 * 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	string	the table name
@@ -263,9 +222,9 @@
 	 * @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	object
+	 * @return	string
 	 */
- 	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
  	{
  		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -285,23 +244,7 @@
  		return $sql;
  	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file postgre_forge.php */
-/* Location: ./system/database/drivers/postgre/postgre_forge.php */
+/* Location: ./system/database/drivers/postgre/postgre_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php
index 9161bf9..f913bc9 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgres 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 @pg_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 @pg_num_fields($this->result_id);
 	}
@@ -69,13 +65,12 @@
 	 *
 	 * 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++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
 			$field_names[] = pg_field_name($this->result_id, $i);
 		}
@@ -90,22 +85,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, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= pg_field_name($this->result_id, $i);
-			$F->type		= pg_field_type($this->result_id, $i);
-			$F->max_length	= pg_field_size($this->result_id, $i);
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= pg_field_name($this->result_id, $i);
+			$retval[$i]->type		= pg_field_type($this->result_id, $i);
+			$retval[$i]->max_length		= pg_field_size($this->result_id, $i);
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -116,9 +108,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -132,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
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return pg_result_seek($this->result_id, $n);
 	}
@@ -151,10 +142,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return pg_fetch_assoc($this->result_id);
 	}
@@ -166,16 +156,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return pg_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file postgre_result.php */
 /* Location: ./system/database/drivers/postgre/postgre_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php
index c426b36..c95e6df 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,43 +34,8 @@
  */
 class CI_DB_postgre_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SELECT datname FROM pg_database';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'REINDEX TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT datname FROM pg_database';
+	protected $_optimize_table	= 'REINDEX TABLE %s';
 
 	/**
 	 * Postgre Export
@@ -78,7 +43,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -86,4 +51,4 @@
 }
 
 /* End of file postgre_utility.php */
-/* Location: ./system/database/drivers/postgre/postgre_utility.php */
+/* Location: ./system/database/drivers/postgre/postgre_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 69de12e..551704f 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,10 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
-
-
 /**
  * SQLite Database Adapter Class
  *
@@ -44,30 +40,29 @@
  */
 class CI_DB_sqlite_driver extends CI_DB {
 
-	var $dbdriver = 'sqlite';
+	public $dbdriver = 'sqlite';
 
 	// The character used to escape with - not needed for SQLite
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " ESCAPE '%s' ";
-	var $_like_escape_chr = '!';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' Random()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' Random()'; // database specific random keyword
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect()
+	public function db_connect()
 	{
 		if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))
 		{
@@ -89,10 +84,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))
 		{
@@ -112,35 +106,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		// not implemented in SQLite
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
-	 */
-	function db_select()
-	{
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -157,41 +122,22 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return @sqlite_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -218,10 +164,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -243,10 +188,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -268,12 +212,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))
 		{
@@ -290,9 +233,9 @@
 		// 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;
@@ -303,10 +246,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return sqlite_changes($this->conn_id);
 	}
@@ -316,10 +258,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @sqlite_last_insert_rowid($this->conn_id);
 	}
@@ -332,11 +273,10 @@
 	 * 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 == '')
 		{
@@ -361,11 +301,10 @@
 	 *
 	 * 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 = "SELECT name from sqlite_master WHERE type='table'";
 
@@ -383,11 +322,10 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	string
+	 * @return	bool
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
 		// Not supported
 		return FALSE;
@@ -400,11 +338,10 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
 		return "SELECT * FROM ".$table." LIMIT 1";
 	}
@@ -429,58 +366,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -493,107 +387,36 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
+	 * Replace statement
 	 *
-	 * Generates a platform-specific insert string from the supplied data
+	 * 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 _insert($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @access	public
-	 * @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
-	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this function maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * 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)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->qb_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -603,13 +426,12 @@
 	 *
 	 * 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)
 		{
@@ -628,18 +450,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@sqlite_close($conn_id);
 	}
 
-
 }
 
-
 /* End of file sqlite_driver.php */
 /* 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 4f379d9..dd6f0f7 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLite Forge Class
  *
@@ -39,11 +37,10 @@
 	/**
 	 * Create database
 	 *
-	 * @access	public
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _create_database()
+	public function create_database($db_name = '')
 	{
 		// In SQLite, a database is created when you connect to the database.
 		// We'll return TRUE so that an error isn't generated
@@ -55,36 +52,32 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
-	 * @param	string	the database name
+	 * @param	string	the database name (ignored)
 	 * @return	bool
 	 */
-	function _drop_database($name)
+	public function drop_database($db_name = '')
 	{
 		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))
 		{
-			if ($this->db->db_debug)
-			{
-				return $this->db->display_error('db_unable_to_drop');
-			}
-			return FALSE;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
 		}
+
 		return TRUE;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * 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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -94,10 +87,10 @@
 			$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
@@ -182,41 +175,21 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 *  Unsupported feature in SQLite
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return array();
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
@@ -254,24 +227,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file sqlite_forge.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
+/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index 74c0dc5..741dc9d 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLite 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 @sqlite_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 @sqlite_num_fields($this->result_id);
 	}
@@ -69,15 +65,14 @@
 	 *
 	 * 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++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$field_names[] = sqlite_field_name($this->result_id, $i);
+			$field_names[$i] = sqlite_field_name($this->result_id, $i);
 		}
 
 		return $field_names;
@@ -90,22 +85,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, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= sqlite_field_name($this->result_id, $i);
-			$F->type		= 'varchar';
-			$F->max_length	= 0;
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= sqlite_field_name($this->result_id, $i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -114,28 +106,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Free the result
-	 *
-	 * @return	null
-	 */
-	function free_result()
-	{
-		// Not implemented in SQLite
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * 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
+	 * @return	bool
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return sqlite_seek($this->result_id, $n);
 	}
@@ -147,10 +126,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return sqlite_fetch_array($this->result_id);
 	}
@@ -162,30 +140,20 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		if (function_exists('sqlite_fetch_object'))
 		{
 			return sqlite_fetch_object($this->result_id);
 		}
-		else
-		{
-			$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
-			if (is_array($arr))
-			{
-				$obj = (object) $arr;
-				return $obj;
-			} else {
-				return NULL;
-			}
-		}
+
+		$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
+		return is_array($arr) ? (object) $arr : FALSE;
 	}
 
 }
 
-
 /* End of file sqlite_result.php */
 /* Location: ./system/database/drivers/sqlite/sqlite_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index 8fefcd9..1bcb42d 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -34,50 +34,7 @@
  */
 class CI_DB_sqlite_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with SQLite
-	 * since each database is its own file. I suppose we could
-	 * try reading a directory looking for SQLite files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		return ($this->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * SQLite Export
@@ -85,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -94,4 +51,4 @@
 }
 
 /* End of file sqlite_utility.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
+/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/index.html b/system/database/drivers/sqlite3/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/system/database/drivers/sqlite3/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
new file mode 100644
index 0000000..fb45bee
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -0,0 +1,431 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		Andrey Andreev
+ * @link		http://codeigniter.com/user_guide/database/
+ * @since		Version 3.0
+ */
+class CI_DB_sqlite3_driver extends CI_DB {
+
+	public $dbdriver = 'sqlite3';
+
+	// The character used for escaping
+	protected $_escape_char = '"';
+
+	// clause and character used for LIKE escape sequences
+	protected $_like_escape_str = ' ESCAPE \'%s\' ';
+	protected $_like_escape_chr = '!';
+
+	/**
+	 * The syntax to count rows is slightly different across different
+	 * database engines, so this string appears in each driver and is
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RANDOM()';
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @return	object	type SQLite3
+	 */
+	public function db_connect()
+	{
+		try
+		{
+			return ( ! $this->password)
+				? new SQLite3($this->database)
+				: new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
+		}
+		catch (Exception $e)
+		{
+			return FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @return  object	type SQLite3
+	 */
+	public function db_pconnect()
+	{
+		log_message('debug', 'SQLite3 doesn\'t support persistent connections');
+		return $this->db_pconnect();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database version number
+	 *
+	 * @return	string
+	 */
+	public function version()
+	{
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		$version = $this->conn_id->version();
+		return $this->data_cache['version'] = $version['versionString'];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @param	string	an SQL query
+	 * @return	mixed	SQLite3Result object or bool
+	 */
+	protected function _execute($sql)
+	{
+		// TODO: Implement use of SQLite3::querySingle(), if needed
+
+		return $this->is_write_type($sql)
+			? $this->conn_id->exec($sql)
+			: $this->conn_id->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_begin($test_mode = FALSE)
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE);
+
+		return $this->conn_id->exec('BEGIN TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_commit()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('END TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_rollback()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('ROLLBACK');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
+	 * @return	string
+	 */
+	public function escape_str($str, $like = FALSE)
+	{
+		if (is_array($str))
+		{
+			foreach ($str as $key => $val)
+			{
+				$str[$key] = $this->escape_str($val, $like);
+			}
+
+			return $str;
+		}
+
+		$str = $this->conn_id->escapeString(remove_invisible_characters($str));
+
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @return	int
+	 */
+	public function affected_rows()
+	{
+		return $this->conn_id->changes();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @return	int
+	 */
+	public function insert_id()
+	{
+		return $this->conn_id->lastInsertRowID();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @param	string
+	 * @return	int
+	 */
+	public function count_all($table = '')
+	{
+		if ($table == '')
+		{
+			return 0;
+		}
+
+		$result = $this->conn_id->querySingle($this->_count_string.$this->protect_identifiers('numrows')
+							.' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
+
+		return empty($result) ? 0 : (int) $result;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @param	bool
+	 * @return	string
+	 */
+	protected function _list_tables($prefix_limit = FALSE)
+	{
+		return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
+			.(($prefix_limit !== FALSE && $this->dbprefix != '')
+				? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
+				: '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * Generates a platform-specific query string so that the column names can be fetched
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _list_columns($table = '')
+	{
+		// Not supported
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * Generates a platform-specific query so that the column data can be retrieved
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _field_data($table)
+	{
+		return 'SELECT * FROM '.$table.' LIMIT 0,1';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @return	string
+	 */
+	protected function _error_message()
+	{
+		return $this->conn_id->lastErrorMsg();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @return	int
+	 */
+	protected function _error_number()
+	{
+		return $this->conn_id->lastErrorCode();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	protected function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Replace statement
+	 *
+	 * Generates a platform-specific replace string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _replace($table, $keys, $values)
+	{
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 *
+	 * If the database does not support the truncate() command, then,
+	 * then this method maps to 'DELETE FROM table'
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _truncate($table)
+	{
+		return 'DELETE FROM '.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @param	string	the sql query string
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
+	 * @return	string
+	 */
+	protected function _limit($sql, $limit, $offset)
+	{
+		return $sql.' LIMIT '.($offset ? $offset.',' : '').$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @param	object (ignored)
+	 * @return	void
+	 */
+	protected function _close($conn_id)
+	{
+		$this->conn_id->close();
+	}
+
+}
+
+/* End of file sqlite3_driver.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
new file mode 100644
index 0000000..20f1e6f
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -0,0 +1,195 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Forge Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	public function create_database($db_name = '')
+	{
+		// In SQLite, a database is created when you connect to the database.
+		// We'll return TRUE so that an error isn't generated
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @param	string	the database name (ignored)
+	 * @return	bool
+	 */
+	public function drop_database($db_name = '')
+	{
+		// In SQLite, a database is dropped when we delete a file
+		if (@file_exists($this->db->database))
+		{
+			// We need to close the pseudo-connection first
+			$this->db->close();
+			if ( ! @unlink($this->db->database))
+			{
+				return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+			}
+
+			return TRUE;
+		}
+
+		return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+
+		// IF NOT EXISTS added to SQLite in 3.3.0
+		if ($if_not_exists === TRUE && version_compare($this->db->version(), '3.3.0', '>=') === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+
+		$sql .= $this->db->escape_identifiers($table).' (';
+		$current_field_count = 0;
+
+		foreach ($fields as $field => $attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t".$attributes;
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+
+				$sql .= "\n\t".$this->db->protect_identifiers($field)
+					.' '.$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
+			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).')';
+			}
+		}
+
+		return $sql."\n)";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	bool	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	string
+	 */
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		/* SQLite only supports adding new columns and it does
+		 * NOT support the AFTER statement. Each new column will
+		 * be added as the last one in the table.
+		 */
+		if ($alter_type !== 'ADD COLUMN')
+		{
+			// Not supported
+			return FALSE;
+		}
+
+		return 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name)
+			.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT '.$default_value : '')
+			// If NOT NULL is specified, the field must have a DEFAULT value other than NULL
+			.(($null !== NULL && $default_value !== 'NULL') ? ' NOT NULL' : ' NULL');
+	}
+
+}
+
+/* End of file sqlite3_forge.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
new file mode 100644
index 0000000..d83d6b2
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -0,0 +1,615 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_result extends CI_DB_result {
+
+	// Overwriting the parent here, so we have a way to know if it's already set
+	public $num_rows;
+
+	// num_fields() might be called multiple times, so we'll use this one to cache it's result
+	protected $_num_fields;
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_rows()
+	{
+		/* The SQLite3 driver doesn't have a graceful way to do this,
+		 * so we'll have to do it on our own.
+		 */
+		return is_int($this->num_rows)
+			? $this->num_rows
+			: $this->num_rows = count($this->result_array());
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_fields()
+	{
+		return ( ! is_int($this->_num_fields))
+			? $this->_num_fields = $this->result_id->numColumns()
+			: $this->_num_fields;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @return	array
+	 */
+	public function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
+		{
+			$field_names[] = $this->result_id->columnName($i);
+		}
+
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @return	array
+	 */
+	public function field_data()
+	{
+		$retval = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $this->num_fields(); $i++)
+		{
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $this->result_id->columnName($i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	void
+	 */
+	public function free_result()
+	{
+		if (is_object($this->result_id))
+		{
+			$this->result_id->finalize();
+			$this->result_id = NULL;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @return	array
+	 */
+	protected function _fetch_assoc()
+	{
+		return $this->result_id->fetchArray(SQLITE3_ASSOC);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @return	object
+	 */
+	protected function _fetch_object()
+	{
+		// No native support for fetching as an object
+		$row = $this->_fetch_assoc();
+		return ($row !== FALSE) ? (object) $row : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "array" version.
+	 *
+	 * return	array
+	 */
+	public function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_array;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->row_data[$row_index++] = $row;
+		}
+
+		return $this->result_array = $this->row_data;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "object" version.
+	 *
+	 * @return	array
+	 */
+	public function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		elseif (count($this->result_array) > 0)
+		{
+			for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
+			{
+				$this->result_object[] = (object) $this->result_array[$i];
+			}
+
+			return $this->result_object;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_object;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+				for ($i = 0; $i < $row_index; $i++)
+				{
+					$this->result_object[$i] = (object) $this->row_data[$i];
+				}
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->row_data[$row_index] = $row;
+			$this->result_object[$row_index++] = (object) $row;
+		}
+
+		$this->result_array = $this->row_data;
+
+		/* As described for the num_rows() method - there's no easy
+		 * way to get the number of rows selected. Our work-around
+		 * solution (as in here as well) first checks if result_array
+		 * exists and returns its count. It doesn't however check for
+		 * custom_object_result, so - do it here.
+		 */
+		if ( ! is_int($this->num_rows))
+		{
+			$this->num_rows = count($this->result_object);
+		}
+
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. Custom object version.
+	 *
+	 * @param	string	class name used to instantiate rows to
+	 * @return	array
+	 */
+	public function custom_result_object($class_name)
+	{
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			return $this->custom_result_object[$class_name];
+		}
+
+		if ( ! class_exists($class_name) OR ! is_object($this->result_id) OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if result_array hasn't been set prior to custom_result_object being called,
+		 * num_rows() has done it.
+		*/
+		$data = &$this->result_array;
+
+		$result_object = array();
+		for ($i = 0, $c = count($data); $i < $c; $i++)
+		{
+			$result_object[$i] = new $class_name();
+			foreach ($data[$i] as $key => $value)
+			{
+				$result_object[$i]->$key = $value;
+			}
+		}
+
+		/* As described for the num_rows() method - there's no easy
+		 * way to get the number of rows selected. Our work-around
+		 * solution (as in here as well) first checks if result_array
+		 * exists and returns its count. It doesn't however check for
+		 * custom_object_result, so - do it here.
+		 */
+		if ( ! is_int($this->num_rows))
+		{
+			$this->num_rows = count($result_object);
+		}
+
+		// Cache and return the array
+		return $this->custom_result_object[$class_name] = $result_object;
+        }
+
+	// --------------------------------------------------------------------
+
+	/* Single row result.
+	 *
+	 * Acts as a wrapper for row_object(), row_array()
+	 * and custom_row_object(). Also used by first_row(), next_row()
+	 * and previous_row().
+	 *
+	 * @param	int	row index
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function row($n = 0, $type = 'object')
+	{
+		if ($type === 'object')
+		{
+			return $this->row_object($n);
+		}
+		elseif ($type === 'array')
+		{
+			return $this->row_array($n);
+		}
+
+		return $this->custom_row_object($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Array version.
+	 *
+	 * @param	int	row index
+	 * @return	array
+	 */
+	public function row_array($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* If row_data is initialized, it means that we've already tried
+		 * (at least) to fetch some data, so ... check if we already have
+		 * this row.
+		*/
+		if (is_array($this->row_data))
+		{
+			/* If we already have row_data[$n] - return it.
+			 *
+			 * If we enter the elseif, there's a number of reasons to
+			 * return an empty array:
+			 *
+			 *	- count($this->row_data) === 0 means there are no results
+			 *	- num_rows being set or result_array having count() > 0 means
+			 *	  that we've already fetched all data and $n is greater than
+			 *	  our highest row index available
+			 *	- $n < $this->current_row means that if such row existed,
+			 *	  we would've already returned it, therefore $n is an
+			 *	  invalid index
+			 */
+			if (isset($this->row_data[$n])) // We already have this row
+			{
+				$this->current_row = $n;
+				return $this->row_data[$n];
+			}
+			elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
+				OR count($this->result_array) > 0 OR $n < $this->current_row)
+			{
+				// No such row exists
+				return array();
+			}
+
+			// Get the next row index that would actually need to be fetched
+			$current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
+		}
+		else
+		{
+			$current_row = $this->current_row = 0;
+			$this->row_data = array();
+		}
+
+		/* Fetch more data, if available
+		 *
+		 * NOTE: Operator precedence is important here, if you change
+		 *	 'AND' with '&&' - it WILL BREAK the results, as
+		 *	 $row will be assigned the scalar value of both
+		 *	 expressions!
+		 */
+		while ($row = $this->_fetch_assoc() AND $current_row <= $n)
+		{
+			$this->row_data[$current_row++] = $row;
+		}
+
+		// This would mean that there's no (more) data to fetch
+		if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
+		{
+			// Cache what we already have
+			if (is_array($this->row_data))
+			{
+				$this->num_rows = count($this->row_data);
+				/* Usually, row_data could have less elements than result_array,
+				 * but at this point - they should be exactly the same.
+				 */
+				$this->result_array = $this->row_data;
+			}
+			else
+			{
+				$this->num_rows = 0;
+			}
+
+			return array();
+		}
+
+		$this->current_row = $n;
+		return $this->row_data[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Object version.
+	 *
+	 * @param	int	row index
+	 * @return	mixed	object if row found; empty array if not
+	 */
+	public function row_object($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* Logic here is exactly the same as in row_array,
+		 * except we have to cast row_data[$n] to an object.
+		 *
+		 * If we already have result_object though - we can
+		 * directly return from it.
+		 */
+		if (isset($this->result_object[$n]))
+		{
+			$this->current_row = $n;
+			return $this->result_object[$n];
+		}
+
+		$row = $this->row_array($n);
+		// Cast only if the row exists
+		if (count($row) > 0)
+		{
+			$this->current_row = $n;
+			return (object) $row;
+		}
+
+		return array();
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Custom object version.
+	 *
+	 * @param	int	row index
+	 * @param	string	custom class name
+	 * @return	mixed	custom object if row found; empty array otherwise
+	 */
+	public function custom_row_object($n = 0, $class_name)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			/* We already have a the whole result set with this class_name,
+			 * return the specified row if it exists, and an empty array if
+			 * it doesn't.
+			 */
+			if (isset($this->custom_result_object[$class_name][$n]))
+			{
+				$this->current_row = $n;
+				return $this->custom_result_object[$class_name][$n];
+			}
+			else
+			{
+				return array();
+			}
+		}
+		elseif ( ! class_exists($class_name)) // No such class exists
+		{
+			return array();
+		}
+
+		$row = $this->row_array($n);
+		// An array would mean that the row doesn't exist
+		if (is_array($row))
+		{
+			return $row;
+		}
+
+		// Convert to the desired class and return
+		$row_object = new $class_name();
+		foreach ($row as $key => $value)
+		{
+			$row_object->$key = $value;
+		}
+
+		$this->current_row = $n;
+		return $row_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* First row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function first_row($type = 'object')
+	{
+		return $this->row(0, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Last row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function last_row($type = 'object')
+	{
+		$result = &$this->result($type);
+		if ( ! isset($this->num_rows))
+		{
+			$this->num_rows = count($result);
+		}
+		$this->current_row = $this->num_rows - 1;
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Next row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function next_row($type = 'object')
+	{
+		if (is_array($this->row_data))
+		{
+			$count = count($this->row_data);
+			$n = ($this->current_row > $count OR ($this->current_row === 0 && $count === 0)) ? $count : $this->current_row + 1;
+		}
+		else
+		{
+			$n = 0;
+		}
+
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Previous row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function previous_row($type = 'object')
+	{
+		$n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset. We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @return	array
+	 */
+	protected function _data_seek($n = 0)
+	{
+		// Only resetting to the start of the result set is supported
+		return $this->result_id->reset();
+	}
+
+}
+
+/* End of file sqlite3_result.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php
new file mode 100644
index 0000000..965c838
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_utility.php
@@ -0,0 +1,54 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Utility Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_utility extends CI_DB_utility {
+
+	protected $_list_databases	= FALSE;
+
+	/**
+	 * SQLite Export
+	 *
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	protected function _backup($params = array())
+	{
+		// Not supported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+}
+
+/* End of file sqlite3_utility.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 6665b50..8cc500f 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Database Adapter Class
  *
@@ -42,46 +40,46 @@
  */
 class CI_DB_sqlsrv_driver extends CI_DB {
 
-	var $dbdriver = 'sqlsrv';
+	public $dbdriver = 'sqlsrv';
 
 	// The character used for escaping
-	var $_escape_char = '';
+	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	var $_like_escape_str = " ESCAPE '%s' ";
-	var $_like_escape_chr = '!';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' ASC'; // not currently supported
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' NEWID()'; // not currently supported
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_connect($pooling = false)
+	public function db_connect($pooling = FALSE)
 	{
 		// Check for a UTF-8 charset being passed as CI's default 'utf8'.
 		$character_set = (0 === strcasecmp('utf8', $this->char_set)) ? 'UTF-8' : $this->char_set;
 
 		$connection = array(
-			'UID'				=> empty($this->username) ? '' : $this->username,
-			'PWD'				=> empty($this->password) ? '' : $this->password,
-			'Database'			=> $this->database,
-			'ConnectionPooling' => $pooling ? 1 : 0,
+			'UID'			=> empty($this->username) ? '' : $this->username,
+			'PWD'			=> empty($this->password) ? '' : $this->password,
+			'Database'		=> $this->database,
+			'ConnectionPooling'	=> $pooling ? 1 : 0,
 			'CharacterSet'		=> $character_set,
-			'ReturnDatesAsStrings' => 1
+			'ReturnDatesAsStrings'	=> 1
 		);
-		
-		// If the username and password are both empty, assume this is a 
+
+		// If the username and password are both empty, assume this is a
 		// 'Windows Authentication Mode' connection.
-		if(empty($connection['UID']) && empty($connection['PWD'])) {
+		if (empty($connection['UID']) && empty($connection['PWD']))
+		{
 			unset($connection['UID'], $connection['PWD']);
 		}
 
@@ -93,10 +91,9 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		return $this->db_connect(TRUE);
 	}
@@ -104,22 +101,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reconnect
-	 *
-	 * 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()
-	{
-		// not implemented in MSSQL
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Select the database
 	 *
 	 * @param	string	database name
@@ -146,33 +127,16 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
 	 * @return	resource
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-		return sqlsrv_query($this->conn_id, $sql, null, array(
-			'Scrollable'				=> SQLSRV_CURSOR_STATIC,
-			'SendStreamParamsAtExec'	=> true
-		));
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Prep the query
-	 *
-	 * 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)
-	{
-		return $sql;
+		return sqlsrv_query($this->conn_id,
+					$sql,
+					NULL,
+					array('Scrollable'=> SQLSRV_CURSOR_STATIC, 'SendStreamParamsAtExec' => TRUE)
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -180,10 +144,9 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	public function trans_begin($test_mode = FALSE)
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -209,10 +172,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -233,10 +195,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -257,12 +218,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)
 	{
 		// Escape single quotes
 		return str_replace("'", "''", $str);
@@ -273,10 +233,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @sqlrv_rows_affected($this->conn_id);
 	}
@@ -284,34 +243,17 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Insert ID
-	*
-	* Returns the last id created in the Identity column.
-	*
-	* @access public
-	* @return integer
-	*/
-	function insert_id()
+	 * Insert ID
+	 *
+	 * Returns the last id created in the Identity column.
+	 *
+	 * @return	string
+	 */
+	public function insert_id()
 	{
-		return $this->query('select @@IDENTITY as insert_id')->row('insert_id');
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	* Parse major version
-	*
-	* Grabs the major version number from the
-	* database server version string passed in.
-	*
-	* @access private
-	* @param string $version
-	* @return int16 major version number
-	*/
-	function _parse_major_version($version)
-	{
-		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
-		return $ver_info[1]; // return the major version b/c that's all we're interested in.
+		$query = $this->query('SELECT @@IDENTITY AS insert_id');
+		$query = $query->row();
+		return $query->insert_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -344,23 +286,25 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	string
+	 * @return	int
 	 */
-	function count_all($table = '')
+	public function count_all($table = '')
 	{
 		if ($table == '')
-			return '0';
-	
+		{
+			return 0;
+		}
+
 		$query = $this->query("SELECT COUNT(*) AS numrows FROM " . $this->dbprefix . $table);
-		
 		if ($query->num_rows() == 0)
-			return '0';
+		{
+			return 0;
+		}
 
 		$row = $query->row();
 		$this->_reset_select();
-		return $row->numrows;
+		return (int) $row->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -370,11 +314,10 @@
 	 *
 	 * 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)
 	{
 		return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
 	}
@@ -386,13 +329,12 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
-		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'";
+		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";
 	}
 
 	// --------------------------------------------------------------------
@@ -402,13 +344,12 @@
 	 *
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
-	 * @access	public
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _field_data($table)
+	protected function _field_data($table)
 	{
-		return "SELECT TOP 1 * FROM " . $this->_escape_table($table);	
+		return 'SELECT TOP 1 * FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -452,48 +393,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape Table Name
-	 *
-	 * This function adds backticks if the table name has a period
-	 * in it. Some DBs will get cranky unless periods are escaped
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	function _escape_table($table)
-	{
-		return $table;
-	}	
-
-
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _escape_identifiers($item)
-	{
-		return $item;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * 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	array
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -506,62 +414,51 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * 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)
-	{	
-		return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update statement
 	 *
 	 * 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
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
-	
-		return "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
+
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
+
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -571,15 +468,24 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		return "DELETE FROM ".$this->_escape_table($table)." WHERE ".implode(" ", $where);
+		$conditions = array();
+
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
+
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -589,17 +495,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)
 	{
-		$i = $limit + $offset;
-	
-		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);		
+		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -607,18 +510,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@sqlsrv_close($conn_id);
 	}
 
 }
 
-
-
-/* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
+/* End of file sqlsrv_driver.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_driver.php */
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index 1521922..e9143b2 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Forge Class
  *
@@ -36,59 +34,19 @@
  */
 class CI_DB_sqlsrv_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @access	private
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * 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)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -97,10 +55,10 @@
 			$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
@@ -190,17 +148,16 @@
 	 * 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	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
 
@@ -235,25 +192,7 @@
 
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * 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)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
-
 }
 
 /* End of file sqlsrv_forge.php */
-/* Location: ./system/database/drivers/sqlsrv/sqlsrv_forge.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 1ee19c2..0802677 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV 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 @sqlsrv_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 @sqlsrv_num_fields($this->result_id);
 	}
@@ -69,17 +65,16 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
-		foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field)
+		foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field)
 		{
 			$field_names[] = $field['Name'];
 		}
-		
+
 		return $field_names;
 	}
 
@@ -90,13 +85,12 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field)
+		foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field)
 		{
 			$F 				= new stdClass();
 			$F->name 		= $field['Name'];
@@ -104,10 +98,10 @@
 			$F->max_length	= $field['Size'];
 			$F->primary_key = 0;
 			$F->default		= '';
-			
+
 			$retval[] = $F;
 		}
-		
+
 		return $retval;
 	}
 
@@ -116,9 +110,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -130,31 +124,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
-	 *
-	 * @access	private
-	 * @return	array
-	 */
-	function _data_seek($n = 0)
-	{
-		// Not implemented
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return sqlsrv_fetch_array($this->result_id, SQLSRV_FETCH_ASSOC);
 	}
@@ -166,16 +142,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return sqlsrv_fetch_object($this->result_id);
 	}
 
 }
 
-
-/* End of file mssql_result.php */
-/* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
+/* End of file sqlsrv_result.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index e96df96..394964b 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * SQLSRV Utility Class
  *
@@ -36,59 +34,16 @@
  */
 class CI_DB_sqlsrv_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @access	private
-	 * @return	bool
-	 */
-	function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
-	 * Optimize table query
+	 * SQLSRV Export
 	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * MSSQL Export
-	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -96,5 +51,5 @@
 
 }
 
-/* End of file mssql_utility.php */
-/* Location: ./system/database/drivers/mssql/mssql_utility.php */
\ No newline at end of file
+/* End of file sqlsrv_utility.php */
+/* Location: ./system/database/drivers/sqlsrv/sqlsrv_utility.php */
\ No newline at end of file
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index c46c4d1..6f56d9d 100644
--- a/system/helpers/array_helper.php
+++ b/system/helpers/array_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Array Helpers
  *
@@ -45,7 +43,6 @@
  * Lets you determine whether an array index is set and whether it has a value.
  * If the element is empty it returns FALSE (or whatever you specify as the default value.)
  *
- * @access	public
  * @param	string
  * @param	array
  * @param	mixed
@@ -55,12 +52,7 @@
 {
 	function element($item, $array, $default = FALSE)
 	{
-		if ( ! isset($array[$item]) OR $array[$item] == "")
-		{
-			return $default;
-		}
-
-		return $array[$item];
+		return empty($array[$item]) ? $default : $array[$item];
 	}
 }
 
@@ -69,7 +61,6 @@
 /**
  * Random Element - Takes an array as input and returns a random element
  *
- * @access	public
  * @param	array
  * @return	mixed	depends on what the array contains
  */
@@ -77,12 +68,7 @@
 {
 	function random_element($array)
 	{
-		if ( ! is_array($array))
-		{
-			return $array;
-		}
-
-		return $array[array_rand($array)];
+		return is_array($array) ? $array[array_rand($array)] : $array;
 	}
 }
 
@@ -91,10 +77,9 @@
 /**
  * Elements
  *
- * Returns only the array items specified.  Will return a default value if
+ * Returns only the array items specified. Will return a default value if
  * it is not set.
  *
- * @access	public
  * @param	array
  * @param	array
  * @param	mixed
@@ -105,22 +90,12 @@
 	function elements($items, $array, $default = FALSE)
 	{
 		$return = array();
-		
-		if ( ! is_array($items))
-		{
-			$items = array($items);
-		}
-		
+
+		is_array($items) OR $items = array($items);
+
 		foreach ($items as $item)
 		{
-			if (isset($array[$item]))
-			{
-				$return[$item] = $array[$item];
-			}
-			else
-			{
-				$return[$item] = $default;
-			}
+			$return[$item] = isset($array[$item]) ? $array[$item] : $default;
 		}
 
 		return $return;
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 4a48df2..bdbc620 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -1,8 +1,8 @@
-<?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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter CAPTCHA Helper
  *
@@ -42,7 +40,6 @@
 /**
  * Create CAPTCHA
  *
- * @access	public
  * @param	array	array of data for the CAPTCHA
  * @param	string	path to create the image in
  * @param	string	URL to the CAPTCHA image folder
@@ -57,35 +54,19 @@
 
 		foreach ($defaults as $key => $val)
 		{
-			if ( ! is_array($data))
+			if ( ! is_array($data) && empty($$key))
 			{
-				if ( ! isset($$key) OR $$key == '')
-				{
-					$$key = $val;
-				}
+				$$key = $val;
 			}
 			else
 			{
-				$$key = ( ! isset($data[$key])) ? $val : $data[$key];
+				$$key = isset($data[$key]) ? $data[$key] : $val;
 			}
 		}
 
-		if ($img_path == '' OR $img_url == '')
-		{
-			return FALSE;
-		}
-
-		if ( ! @is_dir($img_path))
-		{
-			return FALSE;
-		}
-
-		if ( ! is_writable($img_path))
-		{
-			return FALSE;
-		}
-
-		if ( ! extension_loaded('gd'))
+		if ($img_path == '' OR $img_url == ''
+			OR ! @is_dir($img_path) OR ! is_writeable($img_path)
+			OR ! extension_loaded('gd'))
 		{
 			return FALSE;
 		}
@@ -97,17 +78,12 @@
 		$now = microtime(TRUE);
 
 		$current_dir = @opendir($img_path);
-
 		while ($filename = @readdir($current_dir))
 		{
-			if ($filename != '.' && $filename != '..' && $filename != 'index.html')
+			if ($filename !== '.' && $filename !== '..' && $filename !== 'index.html'
+				&& (str_replace('.jpg', '', $filename) + $expiration) < $now)
 			{
-				$name = str_replace('.jpg', '', $filename);
-
-				if (($name + $expiration) < $now)
-				{
-					@unlink($img_path.$filename);
-				}
+				@unlink($img_path.$filename);
 			}
 		}
 
@@ -117,141 +93,114 @@
 		// Do we have a "word" yet?
 		// -----------------------------------
 
-	   if ($word == '')
-	   {
+		if ($word == '')
+		{
 			$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-			$str = '';
-			for ($i = 0; $i < 8; $i++)
+			$word = '';
+			for ($i = 0, $mt_rand_max = strlen($pool) - 1; $i < 8; $i++)
 			{
-				$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+				$word .= $pool[mt_rand(0, $mt_rand_max)];
 			}
-
-			$word = $str;
-	   }
+		}
 
 		// -----------------------------------
 		// Determine angle and position
 		// -----------------------------------
-
 		$length	= strlen($word);
 		$angle	= ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
 		$x_axis	= rand(6, (360/$length)-16);
-		$y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);
+		$y_axis = ($angle >= 0) ? rand($img_height, $img_width) : rand(6, $img_height);
 
-		// -----------------------------------
 		// Create image
-		// -----------------------------------
-
 		// PHP.net recommends imagecreatetruecolor(), but it isn't always available
-		if (function_exists('imagecreatetruecolor'))
-		{
-			$im = imagecreatetruecolor($img_width, $img_height);
-		}
-		else
-		{
-			$im = imagecreate($img_width, $img_height);
-		}
+		$im = function_exists('imagecreatetruecolor')
+			? imagecreatetruecolor($img_width, $img_height)
+			: imagecreate($img_width, $img_height);
 
 		// -----------------------------------
 		//  Assign colors
 		// -----------------------------------
-
-		$bg_color		= imagecolorallocate ($im, 255, 255, 255);
-		$border_color	= imagecolorallocate ($im, 153, 102, 102);
-		$text_color		= imagecolorallocate ($im, 204, 153, 153);
-		$grid_color		= imagecolorallocate($im, 255, 182, 182);
+		$bg_color	= imagecolorallocate($im, 255, 255, 255);
+		$border_color	= imagecolorallocate($im, 153, 102, 102);
+		$text_color	= imagecolorallocate($im, 204, 153, 153);
+		$grid_color	= imagecolorallocate($im, 255, 182, 182);
 		$shadow_color	= imagecolorallocate($im, 255, 240, 240);
 
-		// -----------------------------------
 		//  Create the rectangle
-		// -----------------------------------
-
 		ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);
 
 		// -----------------------------------
 		//  Create the spiral pattern
 		// -----------------------------------
-
 		$theta		= 1;
 		$thetac		= 7;
 		$radius		= 16;
 		$circles	= 20;
 		$points		= 32;
 
-		for ($i = 0; $i < ($circles * $points) - 1; $i++)
+		for ($i = 0, $cp = ($circles * $points) - 1; $i < $cp; $i++)
 		{
-			$theta = $theta + $thetac;
-			$rad = $radius * ($i / $points );
+			$theta += $thetac;
+			$rad = $radius * ($i / $points);
 			$x = ($rad * cos($theta)) + $x_axis;
 			$y = ($rad * sin($theta)) + $y_axis;
-			$theta = $theta + $thetac;
+			$theta += $thetac;
 			$rad1 = $radius * (($i + 1) / $points);
 			$x1 = ($rad1 * cos($theta)) + $x_axis;
-			$y1 = ($rad1 * sin($theta )) + $y_axis;
+			$y1 = ($rad1 * sin($theta)) + $y_axis;
 			imageline($im, $x, $y, $x1, $y1, $grid_color);
-			$theta = $theta - $thetac;
+			$theta -= $thetac;
 		}
 
 		// -----------------------------------
 		//  Write the text
 		// -----------------------------------
 
-		$use_font = ($font_path != '' && file_exists($font_path) && function_exists('imagettftext')) ? TRUE : FALSE;
-
-		if ($use_font == FALSE)
+		$use_font = ($font_path != '' && file_exists($font_path) && function_exists('imagettftext'));
+		if ($use_font === FALSE)
 		{
 			$font_size = 5;
-			$x = rand(0, $img_width/($length/3));
+			$x = rand(0, $img_width / ($length / 3));
 			$y = 0;
 		}
 		else
 		{
-			$font_size	= 16;
-			$x = rand(0, $img_width/($length/1.5));
-			$y = $font_size+2;
+			$font_size = 16;
+			$x = rand(0, $img_width / ($length / 1.5));
+			$y = $font_size + 2;
 		}
 
-		for ($i = 0; $i < strlen($word); $i++)
+		for ($i = 0; $i < $length; $i++)
 		{
-			if ($use_font == FALSE)
+			if ($use_font === FALSE)
 			{
-				$y = rand(0 , $img_height/2);
-				imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);
-				$x += ($font_size*2);
+				$y = rand(0 , $img_height / 2);
+				imagestring($im, $font_size, $x, $y, $word[$i], $text_color);
+				$x += ($font_size * 2);
 			}
 			else
 			{
-				$y = rand($img_height/2, $img_height-3);
-				imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));
+				$y = rand($img_height / 2, $img_height - 3);
+				imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, $word[$i]);
 				$x += $font_size;
 			}
 		}
 
 
-		// -----------------------------------
-		//  Create the border
-		// -----------------------------------
-
-		imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);
+		// Create the border
+		imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $border_color);
 
 		// -----------------------------------
 		//  Generate the image
 		// -----------------------------------
-
 		$img_name = $now.'.jpg';
-
 		ImageJPEG($im, $img_path.$img_name);
-
-		$img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";
-
+		$img = '<img src="'.$img_url.$img_name.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />';
 		ImageDestroy($im);
 
 		return array('word' => $word, 'time' => $now, 'image' => $img);
 	}
 }
 
-// ------------------------------------------------------------------------
-
 /* End of file captcha_helper.php */
 /* Location: ./system/helpers/captcha_helper.php */
\ No newline at end of file
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 7b439c4..06560e7 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Cookie Helpers
  *
@@ -42,25 +40,26 @@
 /**
  * Set cookie
  *
- * Accepts six parameter, or you can submit an associative
+ * Accepts seven parameters, 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
  * @param	string	the cookie domain.  Usually:  .yourdomain.com
  * @param	string	the cookie path
  * @param	string	the cookie prefix
+ * @param	bool	true makes the cookie secure
+ * @param	bool	true makes the cookie accessible via http(s) only (no javascript)
  * @return	void
  */
 if ( ! function_exists('set_cookie'))
 {
-	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
+	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
 	{
 		// Set the config file options
 		$CI =& get_instance();
-		$CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure);
+		$CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure, $httponly);
 	}
 }
 
@@ -69,7 +68,6 @@
 /**
  * Fetch an item from the COOKIE array
  *
- * @access	public
  * @param	string
  * @param	bool
  * @return	mixed
@@ -79,14 +77,7 @@
 	function get_cookie($index = '', $xss_clean = FALSE)
 	{
 		$CI =& get_instance();
-
-		$prefix = '';
-
-		if ( ! isset($_COOKIE[$index]) && config_item('cookie_prefix') != '')
-		{
-			$prefix = config_item('cookie_prefix');
-		}
-
+		$prefix = isset($_COOKIE[$index]) ? '' : config_item('cookie_prefix');
 		return $CI->input->cookie($prefix.$index, $xss_clean);
 	}
 }
@@ -97,7 +88,7 @@
  * Delete a COOKIE
  *
  * @param	mixed
- * @param	string	the cookie domain.  Usually:  .yourdomain.com
+ * @param	string	the cookie domain. Usually: .yourdomain.com
  * @param	string	the cookie path
  * @param	string	the cookie prefix
  * @return	void
@@ -110,6 +101,5 @@
 	}
 }
 
-
 /* End of file cookie_helper.php */
 /* Location: ./system/helpers/cookie_helper.php */
\ No newline at end of file
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 9e58d86..f1ba364 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -1,8 +1,8 @@
-<?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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Date Helpers
  *
@@ -44,8 +42,7 @@
  *
  * Returns time() or its GMT equivalent based on the config file preference
  *
- * @access	public
- * @return	integer
+ * @return	int
  */
 if ( ! function_exists('now'))
 {
@@ -85,10 +82,9 @@
  * have to worry about escaping your text letters that
  * match the date codes.
  *
- * @access	public
  * @param	string
- * @param	integer
- * @return	integer
+ * @param	int
+ * @return	int
  */
 if ( ! function_exists('mdate'))
 {
@@ -118,9 +114,8 @@
  *
  * Returns a date formatted according to the submitted standard.
  *
- * @access	public
  * @param	string	the chosen format
- * @param	integer	Unix timestamp
+ * @param	int	Unix timestamp
  * @return	string
  */
 if ( ! function_exists('standard_date'))
@@ -128,15 +123,16 @@
 	function standard_date($fmt = 'DATE_RFC822', $time = '')
 	{
 		$formats = array(
-						'DATE_ATOM'		=>	'%Y-%m-%dT%H:%i:%s%Q',
+						'DATE_ATOM'		=>	'%Y-%m-%dT%H:%i:%s%O',
 						'DATE_COOKIE'	=>	'%l, %d-%M-%y %H:%i:%s UTC',
-						'DATE_ISO8601'	=>	'%Y-%m-%dT%H:%i:%s%Q',
+						'DATE_ISO8601'	=>	'%Y-%m-%dT%H:%i:%s%O',
 						'DATE_RFC822'	=>	'%D, %d %M %y %H:%i:%s %O',
 						'DATE_RFC850'	=>	'%l, %d-%M-%y %H:%i:%s UTC',
 						'DATE_RFC1036'	=>	'%D, %d %M %y %H:%i:%s %O',
 						'DATE_RFC1123'	=>	'%D, %d %M %Y %H:%i:%s %O',
+						'DATE_RFC2822'	=>	'%D, %d %M %Y %H:%i:%s %O',
 						'DATE_RSS'		=>	'%D, %d %M %Y %H:%i:%s %O',
-						'DATE_W3C'		=>	'%Y-%m-%dT%H:%i:%s%Q'
+						'DATE_W3C'		=>	'%Y-%m-%dT%H:%i:%s%O'
 						);
 
 		if ( ! isset($formats[$fmt]))
@@ -156,14 +152,14 @@
  * Returns a span of seconds in this format:
  *	10 days 14 hours 36 minutes 47 seconds
  *
- * @access	public
- * @param	integer	a number of seconds
- * @param	integer	Unix timestamp
- * @return	integer
+ * @param	int	a number of seconds
+ * @param	int	Unix timestamp
+ * @param	int	a number of display units
+ * @return	string
  */
 if ( ! function_exists('timespan'))
 {
-	function timespan($seconds = 1, $time = '')
+	function timespan($seconds = 1, $time = '', $units = 7)
 	{
 		$CI =& get_instance();
 		$CI->lang->load('date');
@@ -178,24 +174,29 @@
 			$time = time();
 		}
 
+		if ( ! is_numeric($units))
+		{
+			$units = 7;
+		}
+
 		$seconds = ($time <= $seconds) ? 1 : $time - $seconds;
 
-		$str = '';
+		$str = array();
 		$years = floor($seconds / 31557600);
 
 		if ($years > 0)
 		{
-			$str .= $years.' '.$CI->lang->line((($years	> 1) ? 'date_years' : 'date_year')).', ';
+			$str[] = $years.' '.$CI->lang->line((($years	> 1) ? 'date_years' : 'date_year'));
 		}
 
 		$seconds -= $years * 31557600;
 		$months = floor($seconds / 2629743);
 
-		if ($years > 0 OR $months > 0)
+		if (count($str) < $units && ($years > 0 OR $months > 0))
 		{
 			if ($months > 0)
 			{
-				$str .= $months.' '.$CI->lang->line((($months	> 1) ? 'date_months' : 'date_month')).', ';
+				$str[] = $months.' '.$CI->lang->line((($months	> 1) ? 'date_months' : 'date_month'));
 			}
 
 			$seconds -= $months * 2629743;
@@ -203,11 +204,11 @@
 
 		$weeks = floor($seconds / 604800);
 
-		if ($years > 0 OR $months > 0 OR $weeks > 0)
+		if (count($str) < $units && ($years > 0 OR $months > 0 OR $weeks > 0))
 		{
 			if ($weeks > 0)
 			{
-				$str .= $weeks.' '.$CI->lang->line((($weeks	> 1) ? 'date_weeks' : 'date_week')).', ';
+				$str[] = $weeks.' '.$CI->lang->line((($weeks	> 1) ? 'date_weeks' : 'date_week'));
 			}
 
 			$seconds -= $weeks * 604800;
@@ -215,11 +216,11 @@
 
 		$days = floor($seconds / 86400);
 
-		if ($months > 0 OR $weeks > 0 OR $days > 0)
+		if (count($str) < $units && ($months > 0 OR $weeks > 0 OR $days > 0))
 		{
 			if ($days > 0)
 			{
-				$str .= $days.' '.$CI->lang->line((($days	> 1) ? 'date_days' : 'date_day')).', ';
+				$str[] = $days.' '.$CI->lang->line((($days	> 1) ? 'date_days' : 'date_day'));
 			}
 
 			$seconds -= $days * 86400;
@@ -227,11 +228,11 @@
 
 		$hours = floor($seconds / 3600);
 
-		if ($days > 0 OR $hours > 0)
+		if (count($str) < $units && ($days > 0 OR $hours > 0))
 		{
 			if ($hours > 0)
 			{
-				$str .= $hours.' '.$CI->lang->line((($hours	> 1) ? 'date_hours' : 'date_hour')).', ';
+				$str[] = $hours.' '.$CI->lang->line((($hours	> 1) ? 'date_hours' : 'date_hour'));
 			}
 
 			$seconds -= $hours * 3600;
@@ -239,22 +240,22 @@
 
 		$minutes = floor($seconds / 60);
 
-		if ($days > 0 OR $hours > 0 OR $minutes > 0)
+		if (count($str) < $units && ($days > 0 OR $hours > 0 OR $minutes > 0))
 		{
 			if ($minutes > 0)
 			{
-				$str .= $minutes.' '.$CI->lang->line((($minutes	> 1) ? 'date_minutes' : 'date_minute')).', ';
+				$str[] = $minutes.' '.$CI->lang->line((($minutes	> 1) ? 'date_minutes' : 'date_minute'));
 			}
 
 			$seconds -= $minutes * 60;
 		}
 
-		if ($str == '')
+		if (count($str) === 0)
 		{
-			$str .= $seconds.' '.$CI->lang->line((($seconds	> 1) ? 'date_seconds' : 'date_second')).', ';
+			$str[] = $seconds.' '.$CI->lang->line((($seconds	> 1) ? 'date_seconds' : 'date_second'));
 		}
 
-		return substr(trim($str), 0, -1);
+		return implode(', ', $str);
 	}
 }
 
@@ -266,10 +267,9 @@
  * Takes a month/year as input and returns the number of days
  * for the given month/year. Takes leap years into consideration.
  *
- * @access	public
- * @param	integer a numeric month
- * @param	integer	a numeric year
- * @return	integer
+ * @param	int	a numeric month
+ * @param	int	a numeric year
+ * @return	int
  */
 if ( ! function_exists('days_in_month'))
 {
@@ -287,7 +287,7 @@
 
 		if ($month == 2)
 		{
-			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
+			if ($year % 400 == 0 OR ($year % 4 == 0 && $year % 100 != 0))
 			{
 				return 29;
 			}
@@ -303,9 +303,8 @@
 /**
  * Converts a local Unix timestamp to GMT
  *
- * @access	public
- * @param	integer Unix timestamp
- * @return	integer
+ * @param	int	Unix timestamp
+ * @return	int
  */
 if ( ! function_exists('local_to_gmt'))
 {
@@ -336,11 +335,10 @@
  * at the local value based on the timezone and DST setting
  * submitted
  *
- * @access	public
- * @param	integer Unix timestamp
+ * @param	int	Unix timestamp
  * @param	string	timezone
  * @param	bool	whether DST is active
- * @return	integer
+ * @return	int
  */
 if ( ! function_exists('gmt_to_local'))
 {
@@ -367,9 +365,8 @@
 /**
  * Converts a MySQL Timestamp to Unix
  *
- * @access	public
- * @param	integer Unix timestamp
- * @return	integer
+ * @param	int	Unix timestamp
+ * @return	int
  */
 if ( ! function_exists('mysql_to_unix'))
 {
@@ -402,8 +399,7 @@
  *
  * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
  *
- * @access	public
- * @param	integer Unix timestamp
+ * @param	int	Unix timestamp
  * @param	bool	whether to show seconds
  * @param	string	format: us or euro
  * @return	string
@@ -444,9 +440,8 @@
  *
  * Reverses the above process
  *
- * @access	public
  * @param	string	format: us or euro
- * @return	integer
+ * @return	int
  */
 if ( ! function_exists('human_to_unix'))
 {
@@ -492,12 +487,12 @@
 		{
 			$ampm = strtolower($split['2']);
 
-			if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
+			if (substr($ampm, 0, 1) === 'p' && $hour < 12)
 			{
 				$hour = $hour + 12;
 			}
 
-			if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
+			if (substr($ampm, 0, 1) === 'a' && $hour == 12)
 			{
 				$hour =  '00';
 			}
@@ -518,10 +513,9 @@
  * Turns many "reasonably-date-like" strings into something
  * that is actually useful. This only works for dates after unix epoch.
  *
- * @access  public
- * @param   string  The terribly formatted date-like string
- * @param   string  Date format to return (same as php date function)
- * @return  string
+ * @param	string	The terribly formatted date-like string
+ * @param	string	Date format to return (same as php date function)
+ * @return	string
  */
 if ( ! function_exists('nice_date'))
 {
@@ -586,7 +580,6 @@
  *
  * Generates a drop-down menu of timezones.
  *
- * @access	public
  * @param	string	timezone
  * @param	string	classname
  * @param	string	menu name
@@ -627,10 +620,9 @@
 /**
  * Timezones
  *
- * Returns an array of timezones.  This is a helper function
+ * Returns an array of timezones. This is a helper function
  * for various other ones in this library
  *
- * @access	public
  * @param	string	timezone
  * @return	string
  */
@@ -691,7 +683,7 @@
 
 		$tz = ($tz == 'GMT') ? 'UTC' : $tz;
 
-		return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];
+		return isset($zones[$tz]) ? $zones[$tz] : 0;
 	}
 }
 
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index be65b38..4044ace 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Directory Helpers
  *
@@ -43,12 +41,11 @@
  * Create a Directory Map
  *
  * Reads the specified directory and builds an array
- * representation of it.  Sub-folders contained with the
+ * representation of it. Sub-folders contained with the
  * directory will be mapped as well.
  *
- * @access	public
  * @param	string	path to source
- * @param	int		depth of directories to traverse (0 = fully recursive, 1 = current dir, etc)
+ * @param	int	depth of directories to traverse (0 = fully recursive, 1 = current dir, etc)
  * @return	array
  */
 if ( ! function_exists('directory_map'))
@@ -64,7 +61,7 @@
 			while (FALSE !== ($file = readdir($fp)))
 			{
 				// Remove '.', '..', and hidden files [optional]
-				if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.'))
+				if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] === '.'))
 				{
 					continue;
 				}
@@ -87,6 +84,5 @@
 	}
 }
 
-
 /* End of file directory_helper.php */
 /* Location: ./system/helpers/directory_helper.php */
\ No newline at end of file
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index a8c59c2..8b87f81 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -42,7 +42,6 @@
  *
  * Generates headers that force a download to happen
  *
- * @access	public
  * @param	string	filename
  * @param	mixed	the data to be downloaded
  * @param	bool	wether to try and send the actual file MIME type
@@ -60,19 +59,19 @@
 		// Set the default MIME type to send
 		$mime = 'application/octet-stream';
 
+		$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, '.'))
+			if (count($x) === 1 OR $extension === '')
 			{
+				/* If we're going to detect the MIME type,
+				 * we'll need a file extension.
+				 */
 				return FALSE;
 			}
 
-			$extension = explode('.', $filename);
-			$extension = end($extension);
-
 			// Load the mime types
 			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
 			{
@@ -90,8 +89,23 @@
 			}
 		}
 
+		/* It was reported that browsers on Android 2.1 (and possibly older as well)
+		 * need to have the filename extension upper-cased in order to be able to
+		 * download it.
+		 *
+		 * Reference: http://digiblog.de/2011/04/19/android-and-the-download-file-headers/
+		 */
+		if (count($x) !== 1 && isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/Android\s(1|2\.[01])/', $_SERVER['HTTP_USER_AGENT']))
+		{
+			$x[count($x) - 1] = strtoupper($extension);
+			$filename = implode('.', $x);
+		}
+		
+		// Clean output buffer
+		ob_clean();
+
 		// Generate the server headers
-		header('Content-Type: "'.$mime.'"');
+		header('Content-Type: '.$mime);
 		header('Content-Disposition: attachment; filename="'.$filename.'"');
 		header('Expires: 0');
 		header('Content-Transfer-Encoding: binary');
@@ -113,4 +127,4 @@
 }
 
 /* End of file download_helper.php */
-/* Location: ./system/helpers/download_helper.php */
+/* Location: ./system/helpers/download_helper.php */
\ No newline at end of file
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index f184031..497625c 100644
--- a/system/helpers/email_helper.php
+++ b/system/helpers/email_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Email Helpers
  *
@@ -42,7 +40,7 @@
 /**
  * Validate email address
  *
- * @access	public
+ * @param	string
  * @return	bool
  */
 if ( ! function_exists('valid_email'))
@@ -58,7 +56,9 @@
 /**
  * Send an email
  *
- * @access	public
+ * @param	string
+ * @param	string
+ * @param	string
  * @return	bool
  */
 if ( ! function_exists('send_email'))
@@ -70,4 +70,4 @@
 }
 
 /* End of file email_helper.php */
-/* Location: ./system/helpers/email_helper.php */
+/* Location: ./system/helpers/email_helper.php */
\ No newline at end of file
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 2d4b10e..a5aabec 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter File Helpers
  *
@@ -44,7 +42,6 @@
  *
  * Opens the file specfied in the path and returns it as a string.
  *
- * @access	public
  * @param	string	path to file
  * @return	string
  */
@@ -90,7 +87,6 @@
  * Writes data to the file specified in the path.
  * Creates a new file if non-existent.
  *
- * @access	public
  * @param	string	path to file
  * @param	string	file data
  * @return	bool
@@ -123,14 +119,15 @@
  * If the second parameter is set to TRUE, any directories contained
  * within the supplied base directory will be nuked as well.
  *
- * @access	public
  * @param	string	path to file
  * @param	bool	whether to delete any directories found in the path
+ * @param	int
+ * @param	bool	whether to skip deleting .htaccess and index page files
  * @return	bool
  */
 if ( ! function_exists('delete_files'))
 {
-	function delete_files($path, $del_dir = FALSE, $level = 0)
+	function delete_files($path, $del_dir = FALSE, $level = 0, $htdocs = FALSE)
 	{
 		// Trim the trailing slash
 		$path = rtrim($path, DIRECTORY_SEPARATOR);
@@ -142,21 +139,21 @@
 
 		while (FALSE !== ($filename = @readdir($current_dir)))
 		{
-			if ($filename !== '.' and $filename !== '..')
+			if ($filename !== '.' && $filename !== '..')
 			{
 				if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.')
 				{
-					delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
+					delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1, $htdocs);
 				}
-				else
+				elseif ($htdocs === TRUE && ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))
 				{
-					unlink($path.DIRECTORY_SEPARATOR.$filename);
+					@unlink($path.DIRECTORY_SEPARATOR.$filename);
 				}
 			}
 		}
 		@closedir($current_dir);
 
-		if ($del_dir == TRUE AND $level > 0)
+		if ($del_dir == TRUE && $level > 0)
 		{
 			return @rmdir($path);
 		}
@@ -173,7 +170,6 @@
  * Reads the specified directory and builds an array containing the filenames.
  * Any sub-folders contained within the specified path are read as well.
  *
- * @access	public
  * @param	string	path to source
  * @param	bool	whether to include the path as part of the filename
  * @param	bool	internal variable to determine recursion status - do not use in calls
@@ -224,7 +220,6 @@
  *
  * Any sub-folders contained within the specified path are read as well.
  *
- * @access	public
  * @param	string	path to source
  * @param	bool	Look only at the top level directory specified?
  * @param	bool	internal variable to determine recursion status - do not use in calls
@@ -278,7 +273,6 @@
 * Options are: name, server_path, size, date, readable, writable, executable, fileperms
 * Returns FALSE if the file cannot be found.
 *
-* @access	public
 * @param	string	path to file
 * @param	mixed	array or comma separated string of information returned
 * @return	array
@@ -345,7 +339,6 @@
  * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
  * It should NOT be trusted, and should certainly NOT be used for security
  *
- * @access	public
  * @param	string	path to file
  * @return	mixed
  */
@@ -399,7 +392,6 @@
  * Takes a numeric value representing a file's permissions and returns
  * standard symbolic notation representing that value
  *
- * @access	public
  * @param	int
  * @return	string
  */
@@ -467,7 +459,6 @@
  * Takes a numeric value representing a file's permissions and returns
  * a three character string representing the file's octal permissions
  *
- * @access	public
  * @param	int
  * @return	string
  */
@@ -480,4 +471,4 @@
 }
 
 /* End of file file_helper.php */
-/* Location: ./system/helpers/file_helper.php */
+/* Location: ./system/helpers/file_helper.php */
\ No newline at end of file
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 6efef23..e5b4876 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -24,8 +24,6 @@
  * @since		Version 1.0
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Form Helpers
  *
@@ -43,7 +41,6 @@
  *
  * Creates the opening portion of the form.
  *
- * @access	public
  * @param	string	the URI segments of the form destination
  * @param	array	a key/value pair of attributes
  * @param	array	a key/value pair hidden data
@@ -71,15 +68,15 @@
 
 		$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->base_url()) === FALSE OR strpos($form, 'method="get"')))	
+		// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites
+		if ($CI->config->item('csrf_protection') === TRUE && ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))
 		{
 			$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
 		}
 
-		if (is_array($hidden) AND count($hidden) > 0)
+		if (is_array($hidden) && count($hidden) > 0)
 		{
-			$form .= sprintf("<div style=\"display:none\">%s</div>", form_hidden($hidden));
+			$form .= sprintf('<div style="display:none;">%s</div>', form_hidden($hidden));
 		}
 
 		return $form;
@@ -93,7 +90,6 @@
  *
  * Creates the opening portion of the form, but with "multipart/form-data".
  *
- * @access	public
  * @param	string	the URI segments of the form destination
  * @param	array	a key/value pair of attributes
  * @param	array	a key/value pair hidden data
@@ -121,10 +117,9 @@
 /**
  * Hidden Input Field
  *
- * Generates hidden fields.  You can pass a simple key/value string or an associative
- * array with multiple values.
+ * Generates hidden fields. You can pass a simple key/value string or
+ * an associative array with multiple values.
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @return	string
@@ -157,7 +152,7 @@
 		{
 			foreach ($value as $k => $v)
 			{
-				$k = (is_int($k)) ? '' : $k;
+				$k = is_int($k) ? '' : $k;
 				form_hidden($name.'['.$k.']', $v, TRUE);
 			}
 		}
@@ -171,7 +166,6 @@
 /**
  * Text Input Field
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -181,7 +175,7 @@
 {
 	function form_input($data = '', $value = '', $extra = '')
 	{
-		$defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+		$defaults = array('type' => 'text', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
 
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
@@ -194,7 +188,6 @@
  *
  * Identical to the input function but adds the "password" type
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -221,7 +214,6 @@
  *
  * Identical to the input function but adds the "file" type
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -246,7 +238,6 @@
 /**
  * Textarea field
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -256,7 +247,7 @@
 {
 	function form_textarea($data = '', $value = '', $extra = '')
 	{
-		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '40', 'rows' => '10');
+		$defaults = array('name' => ( ! is_array($data) ? $data : ''), 'cols' => '40', 'rows' => '10');
 
 		if ( ! is_array($data) OR ! isset($data['value']))
 		{
@@ -268,7 +259,7 @@
 			unset($data['value']); // textareas don't use the value attribute
 		}
 
-		$name = (is_array($data)) ? $data['name'] : $data;
+		$name = is_array($data) ? $data['name'] : $data;
 		return '<textarea '._parse_form_attributes($data, $defaults).$extra.'>'.form_prep($val, $name)."</textarea>\n";
 	}
 }
@@ -278,12 +269,11 @@
 /**
  * Multi-select menu
  *
- * @access	public
  * @param	string
  * @param	array
  * @param	mixed
  * @param	string
- * @return	type
+ * @return	string
  */
 if ( ! function_exists('form_multiselect'))
 {
@@ -303,7 +293,6 @@
 /**
  * Drop-down Menu
  *
- * @access	public
  * @param	string
  * @param	array
  * @param	string
@@ -314,6 +303,16 @@
 {
 	function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
 	{
+		// If name is really an array then we'll call the function again using the array
+		if (is_array($name) && isset($name['name']))
+		{
+			isset($name['options']) OR $name['options'] = array();
+			isset($name['selected']) OR $name['selected'] = array();
+			isset($name['extra']) OR $name['extra'] = array();
+
+			return form_dropdown($name['name'], $name['options'], $name['selected'], $name['extra']);
+		}
+
 		if ( ! is_array($selected))
 		{
 			$selected = array($selected);
@@ -341,11 +340,11 @@
 
 				foreach ($val as $optgroup_key => $optgroup_val)
 				{
-					$sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
+					$sel = in_array($optgroup_key, $selected) ? ' selected="selected"' : '';
 					$form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
 				}
 
-				$form .= '</optgroup>'."\n";
+				$form .= "</optgroup>\n";
 			}
 			else
 			{
@@ -353,9 +352,7 @@
 			}
 		}
 
-		$form .= "</select>\n";
-
-		return $form;
+		return $form."</select>\n";
 	}
 }
 
@@ -364,7 +361,6 @@
 /**
  * Checkbox Field
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	bool
@@ -375,9 +371,9 @@
 {
 	function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')
 	{
-		$defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+		$defaults = array('type' => 'checkbox', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
 
-		if (is_array($data) AND array_key_exists('checked', $data))
+		if (is_array($data) && array_key_exists('checked', $data))
 		{
 			$checked = $data['checked'];
 
@@ -409,7 +405,6 @@
 /**
  * Radio Button
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	bool
@@ -435,7 +430,6 @@
 /**
  * Submit Button
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -445,7 +439,7 @@
 {
 	function form_submit($data = '', $value = '', $extra = '')
 	{
-		$defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+		$defaults = array('type' => 'submit', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -455,7 +449,6 @@
 /**
  * Reset Button
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -465,7 +458,7 @@
 {
 	function form_reset($data = '', $value = '', $extra = '')
 	{
-		$defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+		$defaults = array('type' => 'reset', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
 		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
@@ -475,7 +468,6 @@
 /**
  * Form Button
  *
- * @access	public
  * @param	mixed
  * @param	string
  * @param	string
@@ -485,8 +477,8 @@
 {
 	function form_button($data = '', $content = '', $extra = '')
 	{
-		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'button');
-		if ( is_array($data) AND isset($data['content']))
+		$defaults = array('name' => ( ! is_array($data) ? $data : ''), 'type' => 'button');
+		if (is_array($data) && isset($data['content']))
 		{
 			$content = $data['content'];
 			unset($data['content']); // content is not an attribute
@@ -501,7 +493,6 @@
 /**
  * Form Label Tag
  *
- * @access	public
  * @param	string	The text to appear onscreen
  * @param	string	The id the label applies to
  * @param	string	Additional attributes
@@ -516,10 +507,10 @@
 
 		if ($id != '')
 		{
-			$label .= " for=\"$id\"";
+			$label .= ' for="'.$id.'"';
 		}
 
-		if (is_array($attributes) AND count($attributes) > 0)
+		if (is_array($attributes) && count($attributes) > 0)
 		{
 			foreach ($attributes as $key => $val)
 			{
@@ -527,7 +518,7 @@
 			}
 		}
 
-		return $label .= ">$label_text</label>";
+		return $label.'>'.$label_text.'</label>';
 	}
 }
 
@@ -538,7 +529,6 @@
  * Used to produce <fieldset><legend>text</legend>.  To close fieldset
  * use form_fieldset_close()
  *
- * @access	public
  * @param	string	The legend text
  * @param	string	Additional attributes
  * @return	string
@@ -550,7 +540,7 @@
 		$fieldset = '<fieldset'._attributes_to_string($attributes, FALSE).">\n";
 		if ($legend_text != '')
 		{
-			$fieldset .= "<legend>$legend_text</legend>\n";
+			return $fieldset.'<legend>'.$legend_text."</legend>\n";
 		}
 
 		return $fieldset;
@@ -562,7 +552,6 @@
 /**
  * Fieldset Close Tag
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -570,7 +559,7 @@
 {
 	function form_fieldset_close($extra = '')
 	{
-		return "</fieldset>".$extra;
+		return '</fieldset>'.$extra;
 	}
 }
 
@@ -579,7 +568,6 @@
 /**
  * Form Close Tag
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -587,7 +575,7 @@
 {
 	function form_close($extra = '')
 	{
-		return "</form>".$extra;
+		return '</form>'.$extra;
 	}
 }
 
@@ -598,7 +586,6 @@
  *
  * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -648,10 +635,9 @@
  * Form Value
  *
  * Grabs a value from the POST array for the specified field so you can
- * re-populate an input field or textarea.  If Form Validation
+ * re-populate an input field or textarea. If Form Validation
  * is active it retrieves the info from the validation class
  *
- * @access	public
  * @param	string
  * @return	mixed
  */
@@ -681,7 +667,6 @@
  * Let's you set the selected value of a <select> menu via data in the POST array.
  * If Form Validation is active it retrieves the info from the validation class
  *
- * @access	public
  * @param	string
  * @param	string
  * @param	bool
@@ -697,7 +682,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 AND $default == TRUE)
+				if (count($_POST) === 0 && $default == TRUE)
 				{
 					return ' selected="selected"';
 				}
@@ -713,12 +698,9 @@
 					return '';
 				}
 			}
-			else
+			elseif (($field == '' OR $value == '') OR ($field != $value))
 			{
-				if (($field == '' OR $value == '') OR ($field != $value))
-				{
-					return '';
-				}
+				return '';
 			}
 
 			return ' selected="selected"';
@@ -736,7 +718,6 @@
  * Let's you set the selected value of a checkbox via the value in the POST array.
  * If Form Validation is active it retrieves the info from the validation class
  *
- * @access	public
  * @param	string
  * @param	string
  * @param	bool
@@ -752,7 +733,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 AND $default == TRUE)
+				if (count($_POST) === 0 && $default == TRUE)
 				{
 					return ' checked="checked"';
 				}
@@ -768,12 +749,9 @@
 					return '';
 				}
 			}
-			else
+			elseif (($field == '' OR $value == '') OR ($field != $value))
 			{
-				if (($field == '' OR $value == '') OR ($field != $value))
-				{
-					return '';
-				}
+				return '';
 			}
 
 			return ' checked="checked"';
@@ -791,7 +769,6 @@
  * Let's you set the selected value of a radio field via info in the POST array.
  * If Form Validation is active it retrieves the info from the validation class
  *
- * @access	public
  * @param	string
  * @param	string
  * @param	bool
@@ -807,7 +784,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 AND $default == TRUE)
+				if (count($_POST) === 0 && $default == TRUE)
 				{
 					return ' checked="checked"';
 				}
@@ -843,10 +820,9 @@
 /**
  * Form Error
  *
- * Returns the error for a specific form field.  This is a helper for the
+ * Returns the error for a specific form field. This is a helper for the
  * form validation class.
  *
- * @access	public
  * @param	string
  * @param	string
  * @param	string
@@ -870,10 +846,9 @@
 /**
  * Validation Error String
  *
- * Returns all the errors associated with a form submission.  This is a helper
+ * Returns all the errors associated with a form submission. This is a helper
  * function for the form validation class.
  *
- * @access	public
  * @param	string
  * @param	string
  * @return	string
@@ -898,7 +873,6 @@
  *
  * Helper function used by some of the form helpers
  *
- * @access	private
  * @param	array
  * @param	array
  * @return	string
@@ -933,7 +907,7 @@
 				$val = form_prep($val, $default['name']);
 			}
 
-			$att .= $key . '="' . $val . '" ';
+			$att .= $key.'="'.$val.'" ';
 		}
 
 		return $att;
@@ -947,7 +921,6 @@
  *
  * Helper function used by some of the form helpers
  *
- * @access	private
  * @param	mixed
  * @param	bool
  * @return	string
@@ -956,14 +929,14 @@
 {
 	function _attributes_to_string($attributes, $formtag = FALSE)
 	{
-		if (is_string($attributes) AND strlen($attributes) > 0)
+		if (is_string($attributes) && strlen($attributes) > 0)
 		{
-			if ($formtag == TRUE AND strpos($attributes, 'method=') === FALSE)
+			if ($formtag == TRUE && strpos($attributes, 'method=') === FALSE)
 			{
 				$attributes .= ' method="post"';
 			}
 
-			if ($formtag == TRUE AND strpos($attributes, 'accept-charset=') === FALSE)
+			if ($formtag == TRUE && strpos($attributes, 'accept-charset=') === FALSE)
 			{
 				$attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"';
 			}
@@ -971,21 +944,21 @@
 			return ' '.$attributes;
 		}
 
-		if (is_object($attributes) AND count($attributes) > 0)
+		if (is_object($attributes) && count($attributes) > 0)
 		{
-			$attributes = (array)$attributes;
+			$attributes = (array) $attributes;
 		}
 
-		if (is_array($attributes) AND ($formtag === TRUE OR count($attributes) > 0))
+		if (is_array($attributes) && ($formtag === TRUE OR count($attributes) > 0))
 		{
 			$atts = '';
 
-			if ( ! isset($attributes['method']) AND $formtag === TRUE)
+			if ( ! isset($attributes['method']) && $formtag === TRUE)
 			{
 				$atts .= ' method="post"';
 			}
 
-			if ( ! isset($attributes['accept-charset']) AND $formtag === TRUE)
+			if ( ! isset($attributes['accept-charset']) && $formtag === TRUE)
 			{
 				$atts .= ' accept-charset="'.strtolower(config_item('charset')).'"';
 			}
@@ -1008,7 +981,6 @@
  * Determines what the form validation class was instantiated as, fetches
  * the object and returns it.
  *
- * @access	private
  * @return	mixed
  */
 if ( ! function_exists('_get_validation_object'))
@@ -1035,4 +1007,4 @@
 }
 
 /* End of file form_helper.php */
-/* Location: ./system/helpers/form_helper.php */
+/* Location: ./system/helpers/form_helper.php */
\ No newline at end of file
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index 72970d9..0417bd2 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter HTML Helpers
  *
@@ -42,12 +40,10 @@
 /**
  * Heading
  *
- * Generates an HTML heading tag.  First param is the data.
- * Second param is the size of the heading tag.
+ * Generates an HTML heading tag.
  *
- * @access	public
- * @param	string
- * @param	integer
+ * @param	string	content
+ * @param	int	heading level
  * @return	string
  */
 if ( ! function_exists('heading'))
@@ -65,7 +61,6 @@
  *
  * Generates an HTML unordered list from an single or multi-dimensional array.
  *
- * @access	public
  * @param	array
  * @param	mixed
  * @return	string
@@ -85,7 +80,6 @@
  *
  * Generates an HTML ordered list from an single or multi-dimensional array.
  *
- * @access	public
  * @param	array
  * @param	mixed
  * @return	string
@@ -105,11 +99,10 @@
  *
  * Generates an HTML ordered list from an single or multi-dimensional array.
  *
- * @access	private
  * @param	string
  * @param	mixed
  * @param	mixed
- * @param	integer
+ * @param	int
  * @return	string
  */
 if ( ! function_exists('_list'))
@@ -131,13 +124,13 @@
 			$atts = '';
 			foreach ($attributes as $key => $val)
 			{
-				$atts .= ' ' . $key . '="' . $val . '"';
+				$atts .= ' '.$key.'="'.$val.'"';
 			}
 			$attributes = $atts;
 		}
-		elseif (is_string($attributes) AND strlen($attributes) > 0)
+		elseif (is_string($attributes) && strlen($attributes) > 0)
 		{
-			$attributes = ' '. $attributes;
+			$attributes = ' '.$attributes;
 		}
 
 		// Write the opening list tag
@@ -175,8 +168,7 @@
 /**
  * Generates HTML BR tags based on number supplied
  *
- * @access	public
- * @param	integer
+ * @param	int
  * @return	string
  */
 if ( ! function_exists('br'))
@@ -194,8 +186,8 @@
  *
  * Generates an <img /> element
  *
- * @access	public
  * @param	mixed
+ * @param	bool
  * @return	string
  */
 if ( ! function_exists('img'))
@@ -217,7 +209,7 @@
 
 		foreach ($src as $k => $v)
 		{
-			if ($k === 'src' AND strpos($v, '://') === FALSE)
+			if ($k === 'src' && strpos($v, '://') === FALSE)
 			{
 				$CI =& get_instance();
 
@@ -232,7 +224,7 @@
 			}
 			else
 			{
-				$img .= " $k=\"$v\"";
+				$img .= ' '.$k.'="'.$v.'"';
 			}
 		}
 
@@ -248,10 +240,9 @@
  * Generates a page document type declaration
  *
  * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,
- * html4-strict, html4-trans, and html4-frame.  Values are saved in the
+ * html4-strict, html4-trans, and html4-frame. Values are saved in the
  * doctypes config file.
  *
- * @access	public
  * @param	string	type	The doctype to be generated
  * @return	string
  */
@@ -263,7 +254,7 @@
 
 		if ( ! is_array($_doctypes))
 		{
-			if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php'))
+			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php'))
 			{
 				include(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php');
 			}
@@ -278,7 +269,7 @@
 			}
 		}
 
-		return (isset($_doctypes[$type])) ? $_doctypes[$type] : FALSE;
+		return isset($_doctypes[$type]) ? $_doctypes[$type] : FALSE;
 	}
 }
 
@@ -289,13 +280,12 @@
  *
  * Generates link to a CSS file
  *
- * @access	public
  * @param	mixed	stylesheet hrefs or an array
  * @param	string	rel
  * @param	string	type
  * @param	string	title
  * @param	string	media
- * @param	boolean	should index_page be added to the css path
+ * @param	bool	should index_page be added to the css path
  * @return	string
  */
 if ( ! function_exists('link_tag'))
@@ -309,7 +299,7 @@
 		{
 			foreach ($href as $k => $v)
 			{
-				if ($k === 'href' AND strpos($v, '://') === FALSE)
+				if ($k === 'href' && strpos($v, '://') === FALSE)
 				{
 					if ($index_page === TRUE)
 					{
@@ -322,11 +312,9 @@
 				}
 				else
 				{
-					$link .= "$k=\"$v\" ";
+					$link .= $k.'="'.$v.'" ';
 				}
 			}
-
-			$link .= '/>';
 		}
 		else
 		{
@@ -354,11 +342,9 @@
 			{
 				$link .= 'title="'.$title.'" ';
 			}
-
-			$link .= '/>';
 		}
 
-		return $link."\n";
+		return $link."/>\n";
 	}
 }
 
@@ -367,8 +353,10 @@
 /**
  * Generates meta tags from an array of key/values
  *
- * @access	public
  * @param	array
+ * @param	string
+ * @param	string
+ * @param	string
  * @return	string
  */
 if ( ! function_exists('meta'))
@@ -381,13 +369,10 @@
 		{
 			$name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));
 		}
-		else
+		elseif (isset($name['name']))
 		{
 			// Turn single array into multidimensional
-			if (isset($name['name']))
-			{
-				$name = array($name);
-			}
+			$name = array($name);
 		}
 
 		$str = '';
@@ -410,8 +395,7 @@
 /**
  * Generates non-breaking space entities based on number supplied
  *
- * @access	public
- * @param	integer
+ * @param	int
  * @return	string
  */
 if ( ! function_exists('nbs'))
@@ -423,4 +407,4 @@
 }
 
 /* End of file html_helper.php */
-/* Location: ./system/helpers/html_helper.php */
+/* Location: ./system/helpers/html_helper.php */
\ No newline at end of file
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index 02c425b..feeaf57 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Inflector Helpers
  *
@@ -37,7 +35,6 @@
  * @link		http://codeigniter.com/user_guide/helpers/inflector_helper.html
  */
 
-
 // --------------------------------------------------------------------
 
 /**
@@ -58,7 +55,7 @@
 		{
 			return $result;
 		}
-		
+
 		$singular_rules = array(
 			'/(matr)ices$/'         => '\1ix',
 			'/(vert|ind)ices$/'     => '\1ex',
@@ -116,7 +113,7 @@
 if ( ! function_exists('plural'))
 {
 	function plural($str, $force = FALSE)
-	{	
+	{
 		$result = strval($str);
 
 		if ( ! is_countable($result))
@@ -145,7 +142,7 @@
 			'/s$/'                     => 's',          // no change (compatibility)
 			'/$/'                      => 's',
 		);
-		
+
 		foreach ($plural_rules as $rule => $replacement)
 		{
 			if (preg_match($rule, $result))
@@ -173,7 +170,7 @@
 {
 	function camelize($str)
 	{
-		return substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
+		return strtolower($str[0]).substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
 	}
 }
 
@@ -202,8 +199,8 @@
  *
  * Takes multiple words separated by the separator and changes them to spaces
  *
- * @param	string $str
- * @param 	string $separator
+ * @param	string	$str
+ * @param 	string	$separator
  * @return	str
  */
 if ( ! function_exists('humanize'))
@@ -217,17 +214,19 @@
 /**
  * Checks if the given word has a plural version.
  *
- * @param   string  the word to check
- * @return  bool    if the word is countable
+ * @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'
-		)));
+		return ! in_array(strtolower(strval($word)),
+					array(
+						'equipment', 'information', 'rice', 'money',
+						'species', 'series', 'fish', 'meta'
+					)
+			);
 	}
 }
 
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index a83580a..b31c971 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Language Helpers
  *
@@ -44,7 +42,6 @@
  *
  * Fetches a language variable and optionally outputs a form label
  *
- * @access	public
  * @param	string	the language line
  * @param	string	the id of the form element
  * @return	string
@@ -58,7 +55,7 @@
 
 		if ($id != '')
 		{
-			$line = '<label for="'.$id.'">'.$line."</label>";
+			$line = '<label for="'.$id.'">'.$line.'</label>';
 		}
 
 		return $line;
@@ -66,4 +63,4 @@
 }
 
 /* End of file language_helper.php */
-/* Location: ./system/helpers/language_helper.php */
+/* Location: ./system/helpers/language_helper.php */
\ No newline at end of file
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 331b468..40da6e7 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Number Helpers
  *
@@ -42,7 +40,6 @@
 /**
  * Formats a numbers as bytes, based on size, and adds the appropriate suffix
  *
- * @access	public
  * @param	mixed	// will be cast as int
  * @return	string
  */
@@ -84,4 +81,4 @@
 }
 
 /* End of file number_helper.php */
-/* Location: ./system/helpers/number_helper.php */
+/* Location: ./system/helpers/number_helper.php */
\ No newline at end of file
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index cd87a73..6ee9907 100644
--- a/system/helpers/path_helper.php
+++ b/system/helpers/path_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Path Helpers
  *
@@ -42,7 +40,6 @@
 /**
  * Set Realpath
  *
- * @access	public
  * @param	string
  * @param	bool	checks to see if the path exists
  * @return	string
@@ -51,30 +48,26 @@
 {
 	function set_realpath($path, $check_existance = FALSE)
 	{
-		// Security check to make sure the path is NOT a URL.  No remote file inclusion!
-		if (preg_match("#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i", $path))
+		// Security check to make sure the path is NOT a URL. No remote file inclusion!
+		if (preg_match('#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i', $path))
 		{
 			show_error('The path you submitted must be a local server path, not a URL');
 		}
 
 		// Resolve the path
-		if (function_exists('realpath') AND @realpath($path) !== FALSE)
+		if (function_exists('realpath') && @realpath($path) !== FALSE)
 		{
 			$path = realpath($path);
 		}
-
-		// Add a trailing slash
-		$path = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
-
-		// Make sure the path exists
-		if ($check_existance == TRUE && ! is_dir($path))
+		elseif ($check_existance && ! is_dir($path) && ! is_file($path))
 		{
 			show_error('Not a valid path: '.$path);
 		}
 
-		return $path;
+		// Add a trailing slash, if this is a directory
+		return is_dir($path) ? rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR : $path;
 	}
 }
 
 /* End of file path_helper.php */
-/* Location: ./system/helpers/path_helper.php */
+/* Location: ./system/helpers/path_helper.php */
\ No newline at end of file
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index 99fda56..d6f134c 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Security Helpers
  *
@@ -42,7 +40,6 @@
 /**
  * XSS Filtering
  *
- * @access	public
  * @param	string
  * @param	bool	whether or not the content is an image file
  * @return	string
@@ -61,7 +58,6 @@
 /**
  * Sanitize Filename
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -79,7 +75,6 @@
 /**
  * Hash encode a string
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -87,7 +82,12 @@
 {
 	function do_hash($str, $type = 'sha1')
 	{
-		return ($type === 'sha1') ? sha1($str) : md5($str);
+		if ( ! in_array(strtolower($type), hash_algos()))
+		{
+			$type = 'md5';
+		}
+
+		return hash($type, $str);
 	}
 }
 
@@ -96,7 +96,6 @@
 /**
  * Strip Image Tags
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -104,7 +103,7 @@
 {
 	function strip_image_tags($str)
 	{
-		return preg_replace(array("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "#<img\s+.*?src\s*=\s*(.+?).*?\>#"), "\\1", $str);
+		return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
 	}
 }
 
@@ -113,7 +112,6 @@
 /**
  * Convert PHP tags to entities
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -126,4 +124,4 @@
 }
 
 /* End of file security_helper.php */
-/* Location: ./system/helpers/security_helper.php */
+/* Location: ./system/helpers/security_helper.php */
\ No newline at end of file
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 700f448..8dba74e 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Smiley Helpers
  *
@@ -45,7 +43,6 @@
  * Returns the javascript required for the smiley insertion.  Optionally takes
  * an array of aliases to loosely couple the smiley array to the view.
  *
- * @access	public
  * @param	mixed	alias name or array of alias->field_id pairs
  * @param	string	field_id if alias name was passed in
  * @return	array
@@ -139,7 +136,6 @@
  * Returns an array of image tag links that can be clicked to be inserted
  * into a form field.
  *
- * @access	public
  * @param	string	the URL to the folder containing the smiley images
  * @return	array
  */
@@ -193,7 +189,6 @@
  *
  * Takes a string as input and swaps any contained smileys for the actual image
  *
- * @access	public
  * @param	string	the text to be parsed
  * @param	string	the URL to the folder containing the smiley images
  * @return	string
@@ -234,14 +229,13 @@
  *
  * Fetches the config/smiley.php file
  *
- * @access	private
  * @return	mixed
  */
 if ( ! function_exists('_get_smiley_array'))
 {
 	function _get_smiley_array()
 	{
-		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'))
+		if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php');
 		}
@@ -249,8 +243,8 @@
 		{
 			include(APPPATH.'config/smileys.php');
 		}
-		
-		if (isset($smileys) AND is_array($smileys))
+
+		if (isset($smileys) && is_array($smileys))
 		{
 			return $smileys;
 		}
@@ -268,7 +262,6 @@
  *
  * DEPRECATED as of version 1.7.2, use smiley_js instead
  *
- * @access	public
  * @param	string	form name
  * @param	string	field name
  * @return	string
@@ -288,6 +281,5 @@
 	}
 }
 
-
 /* End of file smiley_helper.php */
 /* Location: ./system/helpers/smiley_helper.php */
\ No newline at end of file
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 04d51c2..aed35c1 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter String Helpers
  *
@@ -50,7 +48,6 @@
  *
  * this/that/theother
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -69,7 +66,6 @@
  *
  * Removes slashes contained in a string or in an array
  *
- * @access	public
  * @param	mixed	string or array
  * @return	mixed	string or array
  */
@@ -100,7 +96,6 @@
  *
  * Removes single and double quotes from a string
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -119,7 +114,6 @@
  *
  * Converts single and double quotes to entities
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -145,7 +139,6 @@
  *
  * http://www.some-site.com/index.php
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -153,7 +146,7 @@
 {
 	function reduce_double_slashes($str)
 	{
-		return preg_replace("#(^|[^:])//+#", "\\1/", $str);
+		return preg_replace('#(^|[^:])//+#', '\\1/', $str);
 	}
 }
 
@@ -170,7 +163,6 @@
  *
  * Fred, Bill, Joe, Jimmy
  *
- * @access	public
  * @param	string
  * @param	string	the character you wish to reduce
  * @param	bool	TRUE/FALSE - whether to trim the character from the beginning/end
@@ -184,7 +176,7 @@
 
 		if ($trim === TRUE)
 		{
-			$str = trim($str, $character);
+			return trim($str, $character);
 		}
 
 		return $str;
@@ -198,9 +190,8 @@
  *
  * Useful for generating passwords or hashes.
  *
- * @access	public
  * @param	string	type of random string.  basic, alpha, alunum, numeric, nozero, unique, md5, encrypt and sha1
- * @param	integer	number of characters
+ * @param	int	number of characters
  * @return	string
  */
 if ( ! function_exists('random_string'))
@@ -227,9 +218,9 @@
 						case 'nozero'	:	$pool = '123456789';
 							break;
 					}
-					
+
 					$str = substr(str_shuffle(str_repeat($pool, ceil($len/strlen($pool)))),0,$len);
-					
+
 					return $str;
 				break;
 			case 'unique'	:
@@ -254,16 +245,19 @@
 /**
  * Add's _1 to a string or increment the ending number to allow _2, _3, etc
  *
- * @param   string  $str  required
- * @param   string  $separator  What should the duplicate number be appended with
- * @param   string  $first  Which number should be used for the first dupe increment
- * @return  string
+ * @param	string	required
+ * @param	string	What should the duplicate number be appended with
+ * @param	string	Which number should be used for the first dupe increment
+ * @return	string
  */
-function increment_string($str, $separator = '_', $first = 1)
+if ( ! function_exists('increment_string'))
 {
-	preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match);
+	function increment_string($str, $separator = '_', $first = 1)
+	{
+		preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match);
 
-	return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
+		return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
+	}
 }
 
 // ------------------------------------------------------------------------
@@ -271,9 +265,8 @@
 /**
  * Alternator
  *
- * Allows strings to be alternated.  See docs...
+ * Allows strings to be alternated. See docs...
  *
- * @access	public
  * @param	string (as many parameters as needed)
  * @return	string
  */
@@ -298,19 +291,17 @@
 /**
  * Repeater function
  *
- * @access	public
  * @param	string
- * @param	integer	number of repeats
+ * @param	int	number of repeats
  * @return	string
  */
 if ( ! function_exists('repeater'))
 {
 	function repeater($data, $num = 1)
 	{
-		return (($num > 0) ? str_repeat($data, $num) : '');
+		return ($num > 0) ? str_repeat($data, $num) : '';
 	}
 }
 
-
 /* End of file string_helper.php */
 /* Location: ./system/helpers/string_helper.php */
\ No newline at end of file
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index 6e9ea57..cc501c3 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Text Helpers
  *
@@ -44,9 +42,8 @@
  *
  * Limits a string to X number of words.
  *
- * @access	public
  * @param	string
- * @param	integer
+ * @param	int
  * @param	string	the end character. Usually an ellipsis
  * @return	string
  */
@@ -78,9 +75,8 @@
  * Limits the string based on the character count.  Preserves complete words
  * so the character count may not be exactly as specified.
  *
- * @access	public
  * @param	string
- * @param	integer
+ * @param	int
  * @param	string	the end character. Usually an ellipsis
  * @return	string
  */
@@ -121,7 +117,6 @@
  *
  * Converts High ascii text and MS Word special characters to character entities
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -182,7 +177,6 @@
  *
  * Converts character entities back to ASCII
  *
- * @access	public
  * @param	string
  * @param	bool
  * @return	string
@@ -240,7 +234,6 @@
  * matched words will be converted to #### or to the replacement
  * word you've submitted.
  *
- * @access	public
  * @param	string	the text string
  * @param	string	the array of censoered words
  * @param	string	the optional replacement value
@@ -286,7 +279,6 @@
  *
  * Colorizes code strings
  *
- * @access	public
  * @param	string	the text string
  * @return	string
  */
@@ -330,7 +322,6 @@
  *
  * Highlights a phrase within a text string
  *
- * @access	public
  * @param	string	the text string
  * @param	string	the phrase you'd like to highlight
  * @param	string	the openging tag to precede the phrase with
@@ -360,7 +351,6 @@
 /**
  * Convert Accented Foreign Characters to ASCII
  *
- * @access	public
  * @param	string	the text string
  * @return	string
  */
@@ -368,7 +358,7 @@
 {
 	function convert_accented_characters($str)
 	{
-		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'))
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php');
 		}
@@ -395,9 +385,8 @@
  * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
  * will URLs.
  *
- * @access	public
  * @param	string	the text string
- * @param	integer	the number of characters to wrap at
+ * @param	int	the number of characters to wrap at
  * @return	string
  */
 if ( ! function_exists('word_wrap'))
@@ -497,11 +486,11 @@
  *
  * This function will strip tags from a string, split it at its max_length and ellipsize
  *
- * @param	string		string to ellipsize
- * @param	integer		max length of string
- * @param	mixed		int (1|0) or float, .5, .2, etc for position to split
- * @param	string		ellipsis ; Default '...'
- * @return	string		ellipsized string
+ * @param	string	string to ellipsize
+ * @param	int	max length of string
+ * @param	mixed	int (1|0) or float, .5, .2, etc for position to split
+ * @param	string	ellipsis ; Default '...'
+ * @return	string	ellipsized string
  */
 if ( ! function_exists('ellipsize'))
 {
@@ -534,4 +523,4 @@
 }
 
 /* End of file text_helper.php */
-/* Location: ./system/helpers/text_helper.php */
+/* Location: ./system/helpers/text_helper.php */
\ No newline at end of file
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index c49348e..7a3db5d 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Typography Helpers
  *
@@ -42,7 +40,6 @@
 /**
  * Convert newlines to HTML line breaks except within PRE tags
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -61,8 +58,6 @@
 /**
  * Auto Typography Wrapper Function
  *
- *
- * @access	public
  * @param	string
  * @param	bool	whether to allow javascript event handlers
  * @param	bool	whether to reduce multiple instances of double newlines to two
@@ -86,7 +81,6 @@
  *
  * This function is a replacement for html_entity_decode()
  *
- * @access	public
  * @param	string
  * @param	string
  * @return	string
@@ -101,4 +95,4 @@
 }
 
 /* End of file typography_helper.php */
-/* Location: ./system/helpers/typography_helper.php */
+/* Location: ./system/helpers/typography_helper.php */
\ No newline at end of file
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 3f0fef5..5576c27 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter URL Helpers
  *
@@ -45,7 +43,6 @@
  * Create a local URL based on your basepath. Segments can be passed via the
  * first parameter either as a string or an array.
  *
- * @access	public
  * @param	string
  * @return	string
  */
@@ -67,8 +64,7 @@
  * 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.
  *
- * @access	public
- * @param string
+ * @param	string
  * @return	string
  */
 if ( ! function_exists('base_url'))
@@ -88,7 +84,6 @@
  * Returns the full URL (including segments) of the page where this
  * function is placed
  *
- * @access	public
  * @return	string
  */
 if ( ! function_exists('current_url'))
@@ -106,7 +101,6 @@
  *
  * Returns the URI segments.
  *
- * @access	public
  * @return	string
  */
 if ( ! function_exists('uri_string'))
@@ -125,7 +119,6 @@
  *
  * Returns the "index_page" from your config file
  *
- * @access	public
  * @return	string
  */
 if ( ! function_exists('index_page'))
@@ -144,7 +137,6 @@
  *
  * Creates an anchor based on the local URL.
  *
- * @access	public
  * @param	string	the URL
  * @param	string	the link title
  * @param	mixed	any attributes
@@ -158,7 +150,7 @@
 
 		if ( ! is_array($uri))
 		{
-			$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+			$site_url = preg_match('!^\w+://! i', $uri) ? $uri : site_url($uri);
 		}
 		else
 		{
@@ -187,7 +179,6 @@
  * Creates an anchor based on the local URL. The link
  * opens a new window based on the attributes specified.
  *
- * @access	public
  * @param	string	the URL
  * @param	string	the link title
  * @param	mixed	any attributes
@@ -198,7 +189,7 @@
 	function anchor_popup($uri = '', $title = '', $attributes = FALSE)
 	{
 		$title = (string) $title;
-		$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+		$site_url = preg_match('!^\w+://! i', $uri) ? $uri : site_url($uri);
 
 		if ($title == '')
 		{
@@ -207,7 +198,7 @@
 
 		if ($attributes === FALSE)
 		{
-			return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title."</a>";
+			return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title.'</a>';
 		}
 
 		if ( ! is_array($attributes))
@@ -217,7 +208,7 @@
 
 		foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)
 		{
-			$atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];
+			$atts[$key] = isset($attributes[$key]) ? $attributes[$key] : $val;
 			unset($attributes[$key]);
 		}
 
@@ -226,7 +217,7 @@
 			$attributes = _parse_attributes($attributes);
 		}
 
-		return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"$attributes>".$title."</a>";
+		return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"".$attributes.'>'.$title.'</a>';
 	}
 }
 
@@ -235,7 +226,6 @@
 /**
  * Mailto Link
  *
- * @access	public
  * @param	string	the email address
  * @param	string	the link title
  * @param	mixed	any attributes
@@ -263,7 +253,6 @@
  *
  * Create a spam-protected mailto link written in Javascript
  *
- * @access	public
  * @param	string	the email address
  * @param	string	the link title
  * @param	mixed	any attributes
@@ -373,10 +362,9 @@
  *
  * Automatically links URL and Email addresses.
  * Note: There's a bit of extra code here to deal with
- * URLs or emails that end in a period.  We'll strip these
+ * URLs or emails that end in a period. We'll strip these
  * off and add them after the link.
  *
- * @access	public
  * @param	string	the string
  * @param	string	the type: email, url, or both
  * @param	bool	whether to create pop-up links
@@ -440,7 +428,6 @@
  *
  * Simply adds the http:// part if no scheme is included
  *
- * @access	public
  * @param	string	the URL
  * @return	string
  */
@@ -470,12 +457,12 @@
  * Create URL Title
  *
  * Takes a "title" string as input and creates a
- * human-friendly URL string with a "separator" string 
+ * human-friendly URL string with a "separator" string
  * as the word separator.
  *
- * @access	public
  * @param	string	the string
  * @param	string	the separator
+ * @param	bool
  * @return	string
  */
 if ( ! function_exists('url_title'))
@@ -484,21 +471,21 @@
 	{
 		if ($separator === 'dash')
 		{
-		    $separator = '-';
+			$separator = '-';
 		}
-		else if ($separator == 'underscore')
+		elseif ($separator === 'underscore')
 		{
-		    $separator = '_';
+			$separator = '_';
 		}
-		
+
 		$q_separator = preg_quote($separator);
 
 		$trans = array(
-			'&.+?;'                 => '',
-			'[^a-z0-9 _-]'          => '',
-			'\s+'                   => $separator,
-			'('.$q_separator.')+'   => $separator
-		);
+				'&.+?;'			=> '',
+				'[^a-z0-9 _-]'		=> '',
+				'\s+'			=> $separator,
+				'('.$q_separator.')+'	=> $separator
+			);
 
 		$str = strip_tags($str);
 		foreach ($trans as $key => $val)
@@ -524,7 +511,6 @@
  * For very fine grained control over headers, you could use the Output
  * Library's set_header() function.
  *
- * @access	public
  * @param	string	the URL
  * @param	string	the method: location or refresh
  * @return	string
@@ -564,7 +550,6 @@
  *
  * Some of the functions use this
  *
- * @access	private
  * @param	array
  * @param	bool
  * @return	string
@@ -583,15 +568,15 @@
 		{
 			if ($javascript == TRUE)
 			{
-				$att .= $key . '=' . $val . ',';
+				$att .= $key.'='.$val.',';
 			}
 			else
 			{
-				$att .= ' ' . $key . '="' . $val . '"';
+				$att .= ' '.$key.'="'.$val.'"';
 			}
 		}
 
-		if ($javascript == TRUE AND $att != '')
+		if ($javascript == TRUE && $att != '')
 		{
 			return substr($att, 0, -1);
 		}
@@ -601,4 +586,4 @@
 }
 
 /* End of file url_helper.php */
-/* Location: ./system/helpers/url_helper.php */
+/* Location: ./system/helpers/url_helper.php */
\ No newline at end of file
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 5242193..67fd34b 100644
--- a/system/helpers/xml_helper.php
+++ b/system/helpers/xml_helper.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter XML Helpers
  *
@@ -42,8 +40,8 @@
 /**
  * Convert Reserved XML characters to Entities
  *
- * @access	public
  * @param	string
+ * @param	bool
  * @return	string
  */
 if ( ! function_exists('xml_convert'))
@@ -54,11 +52,11 @@
 
 		// Replace entities to temporary markers so that
 		// ampersands won't get messed up
-		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
+		$str = preg_replace('/&#(\d+);/', $temp.'\\1;', $str);
 
 		if ($protect_all == TRUE)
 		{
-			$str = preg_replace('/&(\w+);/', "$temp\\1;", $str);
+			$str = preg_replace('/&(\w+);/', $temp.'\\1;', $str);
 		}
 
 		$str = str_replace(array('&', '<', '>', '"', "'", '-'),
@@ -66,11 +64,11 @@
 					$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)
 		{
-			return preg_replace("/$temp(\w+);/", '&\\1;', $str);
+			return preg_replace('/'.$temp.'(\w+);/', '&\\1;', $str);
 		}
 
 		return $str;
@@ -78,4 +76,4 @@
 }
 
 /* End of file xml_helper.php */
-/* Location: ./system/helpers/xml_helper.php */
+/* Location: ./system/helpers/xml_helper.php */
\ No newline at end of file
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
index bf61db0..2d477e6 100644
--- a/system/language/english/calendar_lang.php
+++ b/system/language/english/calendar_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index cd6cf39..5335637 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
index 2a91597..a135d1a 100644
--- a/system/language/english/db_lang.php
+++ b/system/language/english/db_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
index e0ef427..23296a2 100644
--- a/system/language/english/email_lang.php
+++ b/system/language/english/email_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index ea58961..6cf0b46 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
index 18ca927..4e39e43 100644
--- a/system/language/english/ftp_lang.php
+++ b/system/language/english/ftp_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index fbb92ab..67ca942 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php
index 9765562..2085cee 100644
--- a/system/language/english/migration_lang.php
+++ b/system/language/english/migration_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php
index 5dfd882..0c19ec6 100644
--- a/system/language/english/number_lang.php
+++ b/system/language/english/number_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
index 1d10efa..11d7912 100644
--- a/system/language/english/profiler_lang.php
+++ b/system/language/english/profiler_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
index ed98439..3a8e144 100644
--- a/system/language/english/unit_test_lang.php
+++ b/system/language/english/unit_test_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
index a9a2fe7..4fa8394 100644
--- a/system/language/english/upload_lang.php
+++ b/system/language/english/upload_lang.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  * 
@@ -35,7 +35,7 @@
 $lang['upload_no_file_selected'] = "You did not select a file to upload.";
 $lang['upload_invalid_filetype'] = "The filetype you are attempting to upload is not allowed.";
 $lang['upload_invalid_filesize'] = "The file you are attempting to upload is larger than the permitted size.";
-$lang['upload_invalid_dimensions'] = "The image you are attempting to upload exceedes the maximum height or width.";
+$lang['upload_invalid_dimensions'] = "The image you are attempting to upload exceeds the maximum height or width.";
 $lang['upload_destination_error'] = "A problem was encountered while attempting to move the uploaded file to the final destination.";
 $lang['upload_no_filepath'] = "The upload path does not appear to be valid.";
 $lang['upload_no_file_types'] = "You have not specified any allowed file types.";
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index 2e78a66..f982416 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Caching Class
  *
@@ -39,122 +37,26 @@
 class CI_Cache extends CI_Driver_Library {
 
 	protected $valid_drivers 	= array(
-		'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy'
-	);
+						'cache_apc',
+						'cache_file',
+						'cache_memcached',
+						'cache_dummy',
+						'cache_wincache'
+					);
 
-	protected $_cache_path		= NULL;		// Path of cache files (if file-based cache)
-	protected $_adapter			= 'dummy';
+	protected $_cache_path		= NULL;	// Path of cache files (if file-based cache)
+	protected $_adapter		= 'dummy';
 	protected $_backup_driver;
 
-	// ------------------------------------------------------------------------
-
 	/**
 	 * Constructor
 	 *
-	 * @param array
-	 */
-	public function __construct($config = array())
-	{
-		if ( ! empty($config))
-		{
-			$this->_initialize($config);
-		}
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Get
-	 *
-	 * Look for a value in the cache.  If it exists, return the data
-	 * if not, return FALSE
-	 *
-	 * @param 	string
-	 * @return 	mixed		value that is stored/FALSE on failure
-	 */
-	public function get($id)
-	{
-		return $this->{$this->_adapter}->get($id);
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Cache Save
-	 *
-	 * @param 	string		Unique Key
-	 * @param 	mixed		Data to store
-	 * @param 	int			Length of time (in seconds) to cache the data
-	 *
-	 * @return 	boolean		true on success/false on failure
-	 */
-	public function save($id, $data, $ttl = 60)
-	{
-		return $this->{$this->_adapter}->save($id, $data, $ttl);
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Delete from Cache
-	 *
-	 * @param 	mixed		unique identifier of the item in the cache
-	 * @return 	boolean		true on success/false on failure
-	 */
-	public function delete($id)
-	{
-		return $this->{$this->_adapter}->delete($id);
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Clean the cache
-	 *
-	 * @return 	boolean		false on failure/true on success
-	 */
-	public function clean()
-	{
-		return $this->{$this->_adapter}->clean();
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Cache Info
-	 *
-	 * @param 	string		user/filehits
-	 * @return 	mixed		array on success, false on failure
-	 */
-	public function cache_info($type = 'user')
-	{
-		return $this->{$this->_adapter}->cache_info($type);
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Get Cache Metadata
-	 *
-	 * @param 	mixed		key to get cache metadata on
-	 * @return 	mixed		return value from child method
-	 */
-	public function get_metadata($id)
-	{
-		return $this->{$this->_adapter}->get_metadata($id);
-	}
-
-	// ------------------------------------------------------------------------
-
-	/**
-	 * Initialize
-	 *
 	 * Initialize class properties based on the configuration array.
 	 *
 	 * @param	array
-	 * @return 	void
+	 * @return	void
 	 */
-	private function _initialize($config)
+	public function __construct($config = array())
 	{
 		$default_config = array(
 				'adapter',
@@ -183,10 +85,92 @@
 	// ------------------------------------------------------------------------
 
 	/**
+	 * Get
+	 *
+	 * Look for a value in the cache. If it exists, return the data
+	 * if not, return FALSE
+	 *
+	 * @param	string
+	 * @return	mixed	value that is stored/FALSE on failure
+	 */
+	public function get($id)
+	{
+		return $this->{$this->_adapter}->get($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Save
+	 *
+	 * @param	string	Unique Key
+	 * @param	mixed	Data to store
+	 * @param	int	Length of time (in seconds) to cache the data
+	 * @return	bool	true on success/false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return $this->{$this->_adapter}->save($id, $data, $ttl);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param	mixed	unique identifier of the item in the cache
+	 * @return	bool	true on success/false on failure
+	 */
+	public function delete($id)
+	{
+		return $this->{$this->_adapter}->delete($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the cache
+	 *
+	 * @return	bool	false on failure/true on success
+	 */
+	public function clean()
+	{
+		return $this->{$this->_adapter}->clean();
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @param	string	user/filehits
+	 * @return	mixed	array on success, false on failure
+	 */
+	public function cache_info($type = 'user')
+	{
+		return $this->{$this->_adapter}->cache_info($type);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param	mixed	key to get cache metadata on
+	 * @return	mixed	return value from child method
+	 */
+	public function get_metadata($id)
+	{
+		return $this->{$this->_adapter}->get_metadata($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
 	 * Is the requested driver supported in this environment?
 	 *
-	 * @param 	string	The driver to test.
-	 * @return 	array
+	 * @param	string	The driver to test.
+	 * @return	array
 	 */
 	public function is_supported($driver)
 	{
@@ -205,8 +189,8 @@
 	/**
 	 * __get()
 	 *
-	 * @param 	child
-	 * @return 	object
+	 * @param	child
+	 * @return	object
 	 */
 	public function __get($child)
 	{
@@ -220,9 +204,7 @@
 		return $obj;
 	}
 
-	// ------------------------------------------------------------------------
 }
-// End Class
 
 /* End of file Cache.php */
-/* Location: ./system/libraries/Cache/Cache.php */
+/* Location: ./system/libraries/Cache/Cache.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index a3dd469..59ab675 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter APC Caching Class
  *
@@ -36,23 +34,22 @@
  * @author		EllisLab Dev Team
  * @link
  */
-
 class CI_Cache_apc extends CI_Driver {
 
 	/**
 	 * 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
-	 * @return 	mixed		value that is stored/FALSE on failure
+	 * @param	string
+	 * @return	mixed	value that is stored/FALSE on failure
 	 */
 	public function get($id)
 	{
 		$data = apc_fetch($id);
 
-		return (is_array($data)) ? $data[0] : FALSE;
+		return is_array($data) ? $data[0] : FALSE;
 	}
 
 	// ------------------------------------------------------------------------
@@ -60,11 +57,11 @@
 	/**
 	 * Cache Save
 	 *
-	 * @param 	string		Unique Key
-	 * @param 	mixed		Data to store
-	 * @param 	int			Length of time (in seconds) to cache the data
+	 * @param	string	Unique Key
+	 * @param	mixed	Data to store
+	 * @param	int	Length of time (in seconds) to cache the data
 	 *
-	 * @return 	boolean		true on success/false on failure
+	 * @return	bool	true on success/false on failure
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
@@ -77,8 +74,8 @@
 	/**
 	 * Delete from Cache
 	 *
-	 * @param 	mixed		unique identifier of the item in the cache
-	 * @param 	boolean		true on success/false on failure
+	 * @param	mixed	unique identifier of the item in the cache
+	 * @param	bool	true on success/false on failure
 	 */
 	public function delete($id)
 	{
@@ -90,7 +87,7 @@
 	/**
 	 * Clean the cache
 	 *
-	 * @return 	boolean		false on failure/true on success
+	 * @return	bool	false on failure/true on success
 	 */
 	public function clean()
 	{
@@ -102,8 +99,8 @@
 	/**
 	 * Cache Info
 	 *
-	 * @param 	string		user/filehits
-	 * @return 	mixed		array on success, false on failure
+	 * @param	string	user/filehits
+	 * @return	mixed	array on success, false on failure
 	 */
 	 public function cache_info($type = NULL)
 	 {
@@ -115,8 +112,8 @@
 	/**
 	 * Get Cache Metadata
 	 *
-	 * @param 	mixed		key to get cache metadata on
-	 * @return 	mixed		array on success/false on failure
+	 * @param	mixed	key to get cache metadata on
+	 * @return	mixed	array on success/false on failure
 	 */
 	public function get_metadata($id)
 	{
@@ -142,10 +139,12 @@
 	 * is_supported()
 	 *
 	 * Check to see if APC is available on this system, bail if it isn't.
+	 *
+	 * @return	bool
 	 */
 	public function is_supported()
 	{
-		if ( ! extension_loaded('apc') OR ini_get('apc.enabled') != "1")
+		if ( ! extension_loaded('apc') OR ! (bool) @ini_get('apc.enabled'))
 		{
 			log_message('error', 'The APC PHP extension must be loaded to use APC Cache.');
 			return FALSE;
@@ -154,11 +153,7 @@
 		return TRUE;
 	}
 
-	// ------------------------------------------------------------------------
-
-
 }
-// End Class
 
 /* End of file Cache_apc.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index fcd55da..e8b791c 100644
--- a/system/libraries/Cache/drivers/Cache_dummy.php
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Dummy Caching Class
  *
@@ -36,7 +34,6 @@
  * @author		EllisLab Dev Team
  * @link
  */
-
 class CI_Cache_dummy extends CI_Driver {
 
 	/**
@@ -44,8 +41,8 @@
 	 *
 	 * Since this is the dummy class, it's always going to return FALSE.
 	 *
-	 * @param 	string
-	 * @return 	Boolean		FALSE
+	 * @param	string
+	 * @return	bool	FALSE
 	 */
 	public function get($id)
 	{
@@ -57,11 +54,10 @@
 	/**
 	 * Cache Save
 	 *
-	 * @param 	string		Unique Key
-	 * @param 	mixed		Data to store
-	 * @param 	int			Length of time (in seconds) to cache the data
-	 *
-	 * @return 	boolean		TRUE, Simulating success
+	 * @param	string	Unique Key
+	 * @param	mixed	Data to store
+	 * @param	int	Length of time (in seconds) to cache the data
+	 * @return	bool	TRUE, Simulating success
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
@@ -73,8 +69,8 @@
 	/**
 	 * Delete from Cache
 	 *
-	 * @param 	mixed		unique identifier of the item in the cache
-	 * @param 	boolean		TRUE, simulating success
+	 * @param	mixed	unique identifier of the item in the cache
+	 * @param	bool	TRUE, simulating success
 	 */
 	public function delete($id)
 	{
@@ -86,7 +82,7 @@
 	/**
 	 * Clean the cache
 	 *
-	 * @return 	boolean		TRUE, simulating success
+	 * @return	bool	TRUE, simulating success
 	 */
 	public function clean()
 	{
@@ -98,8 +94,8 @@
 	/**
 	 * Cache Info
 	 *
-	 * @param 	string		user/filehits
-	 * @return 	boolean		FALSE
+	 * @param	string	user/filehits
+	 * @return	bool	FALSE
 	 */
 	 public function cache_info($type = NULL)
 	 {
@@ -111,8 +107,8 @@
 	/**
 	 * Get Cache Metadata
 	 *
-	 * @param 	mixed		key to get cache metadata on
-	 * @return 	boolean		FALSE
+	 * @param	mixed	key to get cache metadata on
+	 * @return	bool	FALSE
 	 */
 	public function get_metadata($id)
 	{
@@ -125,17 +121,14 @@
 	 * Is this caching driver supported on the system?
 	 * Of course this one is.
 	 *
-	 * @return TRUE;
+	 * @return	bool	TRUE
 	 */
 	public function is_supported()
 	{
 		return TRUE;
 	}
 
-	// ------------------------------------------------------------------------
-
 }
-// End Class
 
 /* End of file Cache_dummy.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_dummy.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_dummy.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index a960730..dd27aa9 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Memcached Caching Class
  *
@@ -36,14 +34,10 @@
  * @author		EllisLab Dev Team
  * @link
  */
-
 class CI_Cache_file extends CI_Driver {
 
 	protected $_cache_path;
 
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
 		$CI =& get_instance();
@@ -57,8 +51,8 @@
 	/**
 	 * Fetch from cache
 	 *
-	 * @param 	mixed		unique key id
-	 * @return 	mixed		data on success/false on failure
+	 * @param	mixed	unique key id
+	 * @return	mixed	data on success/false on failure
 	 */
 	public function get($id)
 	{
@@ -83,11 +77,11 @@
 	/**
 	 * Save into cache
 	 *
-	 * @param 	string		unique key
-	 * @param 	mixed		data to store
-	 * @param 	int			length of time (in seconds) the cache is valid
-	 *						- Default is 60 seconds
-	 * @return 	boolean		true on success/false on failure
+	 * @param	string	unique key
+	 * @param	mixed	data to store
+	 * @param	int	length of time (in seconds) the cache is valid
+	 *				- Default is 60 seconds
+	 * @return	bool	true on success/false on failure
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
@@ -111,12 +105,12 @@
 	/**
 	 * Delete from Cache
 	 *
-	 * @param 	mixed		unique identifier of item in cache
-	 * @return 	boolean		true on success/false on failure
+	 * @param	mixed	unique identifier of item in cache
+	 * @return	bool	true on success/false on failure
 	 */
 	public function delete($id)
 	{
-		return (file_exists($this->_cache_path.$id)) ? unlink($this->_cache_path.$id) : FALSE;
+		return file_exists($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE;
 	}
 
 	// ------------------------------------------------------------------------
@@ -124,7 +118,7 @@
 	/**
 	 * Clean the Cache
 	 *
-	 * @return 	boolean		false on failure/true on success
+	 * @return	bool	false on failure/true on success
 	 */
 	public function clean()
 	{
@@ -138,8 +132,8 @@
 	 *
 	 * Not supported by file-based caching
 	 *
-	 * @param 	string	user/filehits
-	 * @return 	mixed 	FALSE
+	 * @param	string	user/filehits
+	 * @return	mixed	FALSE
 	 */
 	public function cache_info($type = NULL)
 	{
@@ -151,8 +145,8 @@
 	/**
 	 * Get Cache Metadata
 	 *
-	 * @param 	mixed		key to get cache metadata on
-	 * @return 	mixed		FALSE on failure, array on success.
+	 * @param	mixed	key to get cache metadata on
+	 * @return	mixed	FALSE on failure, array on success.
 	 */
 	public function get_metadata($id)
 	{
@@ -188,16 +182,14 @@
 	 *
 	 * In the file driver, check to see that the cache directory is indeed writable
 	 *
-	 * @return boolean
+	 * @return	bool
 	 */
 	public function is_supported()
 	{
 		return is_really_writable($this->_cache_path);
 	}
 
-	// ------------------------------------------------------------------------
 }
-// End Class
 
 /* End of file Cache_file.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index ffe6f2f..4cd5f3d 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Memcached Caching Class
  *
@@ -36,12 +34,11 @@
  * @author		EllisLab Dev Team
  * @link
  */
-
 class CI_Cache_memcached extends CI_Driver {
 
-	private $_memcached;	// Holds the memcached object
+	protected $_memcached;	// Holds the memcached object
 
-	protected $_memcache_conf 	= array(
+	protected $_memcache_conf	= array(
 					'default' => array(
 						'default_host'		=> '127.0.0.1',
 						'default_port'		=> 11211,
@@ -49,19 +46,17 @@
 					)
 				);
 
-	// ------------------------------------------------------------------------
-
 	/**
 	 * Fetch from cache
 	 *
-	 * @param 	mixed		unique key id
-	 * @return 	mixed		data on success/false on failure
+	 * @param	mixed	unique key id
+	 * @return	mixed	data on success/false on failure
 	 */
 	public function get($id)
 	{
 		$data = $this->_memcached->get($id);
 
-		return (is_array($data)) ? $data[0] : FALSE;
+		return is_array($data) ? $data[0] : FALSE;
 	}
 
 	// ------------------------------------------------------------------------
@@ -69,18 +64,18 @@
 	/**
 	 * Save
 	 *
-	 * @param 	string		unique identifier
-	 * @param 	mixed		data being cached
-	 * @param 	int			time to live
-	 * @return 	boolean 	true on success, false on failure
+	 * @param	string	unique identifier
+	 * @param	mixed	data being cached
+	 * @param	int	time to live
+	 * @return	bool true on success, false on failure
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
-		if (get_class($this->_memcached) == 'Memcached')
+		if (get_class($this->_memcached) === 'Memcached')
 		{
 			return $this->_memcached->set($id, array($data, time(), $ttl), $ttl);
 		}
-		else if (get_class($this->_memcached) == 'Memcache')
+		elseif (get_class($this->_memcached) === 'Memcache')
 		{
 			return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
 		}
@@ -93,8 +88,8 @@
 	/**
 	 * Delete from Cache
 	 *
-	 * @param 	mixed		key to be deleted.
-	 * @return 	boolean 	true on success, false on failure
+	 * @param	mixed	key to be deleted.
+	 * @return	bool true on success, false on failure
 	 */
 	public function delete($id)
 	{
@@ -106,7 +101,7 @@
 	/**
 	 * Clean the Cache
 	 *
-	 * @return 	boolean		false on failure/true on success
+	 * @return	bool	false on failure/true on success
 	 */
 	public function clean()
 	{
@@ -118,10 +113,9 @@
 	/**
 	 * Cache Info
 	 *
-	 * @param 	null		type not supported in memcached
-	 * @return 	mixed 		array on success, false on failure
+	 * @return	mixed	array on success, false on failure
 	 */
-	public function cache_info($type = NULL)
+	public function cache_info()
 	{
 		return $this->_memcached->getStats();
 	}
@@ -131,8 +125,8 @@
 	/**
 	 * Get Cache Metadata
 	 *
-	 * @param 	mixed		key to get cache metadata on
-	 * @return 	mixed		FALSE on failure, array on success.
+	 * @param	mixed	key to get cache metadata on
+	 * @return	mixed	FALSE on failure, array on success.
 	 */
 	public function get_metadata($id)
 	{
@@ -156,8 +150,10 @@
 
 	/**
 	 * Setup memcached.
+	 *
+	 * @return	bool
 	 */
-	private function _setup_memcached()
+	protected function _setup_memcached()
 	{
 		// Try to load memcached server info from the config file.
 		$CI =& get_instance();
@@ -179,14 +175,13 @@
 		{
 			$this->_memcached = new Memcached();
 		}
-		else if (class_exists('Memcache'))
+		elseif (class_exists('Memcache'))
 		{
 			$this->_memcached = new Memcache();
 		}
 		else
 		{
 			log_message('error', 'Failed to create object for Memcached Cache; extension not loaded?');
-
 			return FALSE;
 		}
 
@@ -194,17 +189,17 @@
 		{
 			if ( ! array_key_exists('hostname', $cache_server))
 			{
-				$cache_server['hostname'] = $this->_default_options['default_host'];
+				$cache_server['hostname'] = $this->_memcache_conf['default']['default_host'];
 			}
 
 			if ( ! array_key_exists('port', $cache_server))
 			{
-				$cache_server['port'] = $this->_default_options['default_port'];
+				$cache_server['port'] = $this->_memcache_conf['default']['default_port'];
 			}
 
 			if ( ! array_key_exists('weight', $cache_server))
 			{
-				$cache_server['weight'] = $this->_default_options['default_weight'];
+				$cache_server['weight'] = $this->_memcache_conf['default']['default_weight'];
 			}
 
 			if (get_class($this->_memcached) == 'Memcache')
@@ -237,23 +232,21 @@
 	 *
 	 * Returns FALSE if memcached is not supported on the system.
 	 * If it is, we setup the memcached object & return TRUE
+	 *
+	 * @return	bool
 	 */
 	public function is_supported()
 	{
 		if ( ! extension_loaded('memcached') && ! extension_loaded('memcache'))
 		{
 			log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');
-
 			return FALSE;
 		}
 
 		return $this->_setup_memcached();
 	}
 
-	// ------------------------------------------------------------------------
-
 }
-// End Class
 
 /* End of file Cache_memcached.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
new file mode 100644
index 0000000..b32e66a
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -0,0 +1,162 @@
+<?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) 2006 - 2012 EllisLab, Inc.
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 3.0
+ * @filesource
+ */
+
+/**
+ * CodeIgniter Wincache Caching Class
+ *
+ * Read more about Wincache functions here:
+ * http://www.php.net/manual/en/ref.wincache.php
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		Mike Murkovic
+ * @link
+ */
+class CI_Cache_wincache extends CI_Driver {
+
+	/**
+	 * Get
+	 *
+	 * Look for a value in the cache. If it exists, return the data,
+	 * if not, return FALSE
+	 *
+	 * @param	string
+	 * @return	mixed	value that is stored/FALSE on failure
+	 */
+	public function get($id)
+	{
+		$success = FALSE;
+		$data = wincache_ucache_get($id, $success);
+
+		// Success returned by reference from wincache_ucache_get()
+		return ($success) ? $data : FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Save
+	 *
+	 * @param	string	Unique Key
+	 * @param	mixed	Data to store
+	 * @param	int	Length of time (in seconds) to cache the data
+	 * @return	bool	true on success/false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return wincache_ucache_set($id, $data, $ttl);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param	mixed	unique identifier of the item in the cache
+	 * @param	bool	true on success/false on failure
+	 */
+	public function delete($id)
+	{
+		return wincache_ucache_delete($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the cache
+	 *
+	 * @return	bool	false on failure/true on success
+	 */
+	public function clean()
+	{
+		return wincache_ucache_clear();
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @return	mixed	array on success, false on failure
+	 */
+	 public function cache_info()
+	 {
+		 return wincache_ucache_info(TRUE);
+	 }
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param	mixed	key to get cache metadata on
+	 * @return	mixed	array on success/false on failure
+	 */
+	public function get_metadata($id)
+	{
+		if ($stored = wincache_ucache_info(FALSE, $id))
+		{
+			$age = $stored['ucache_entries'][1]['age_seconds'];
+			$ttl = $stored['ucache_entries'][1]['ttl_seconds'];
+			$hitcount = $stored['ucache_entries'][1]['hitcount'];
+
+			return array(
+				'expire'    => $ttl - $age,
+				'hitcount'  => $hitcount,
+				'age'       => $age,
+				'ttl'       => $ttl
+			);
+		}
+
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * is_supported()
+	 *
+	 * Check to see if WinCache is available on this system, bail if it isn't.
+	 *
+	 * @return	bool
+	 */
+	public function is_supported()
+	{
+		if ( ! extension_loaded('wincache'))
+		{
+			log_message('error', 'The Wincache PHP extension must be loaded to use Wincache Cache.');
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+}
+
+/* End of file Cache_wincache.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_wincache.php */
\ No newline at end of file
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index a05a7ba..b6f145d 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Calendar Class
  *
@@ -40,7 +38,7 @@
  */
 class CI_Calendar {
 
-	private $CI;
+	protected $CI;
 	public $lang;
 	public $local_time;
 	public $template		= '';
@@ -54,6 +52,9 @@
 	 * Constructor
 	 *
 	 * Loads the calendar language file and sets the default time reference
+	 *
+	 * @param	array
+	 * @return	void
 	 */
 	public function __construct($config = array())
 	{
@@ -71,7 +72,7 @@
 			$this->initialize($config);
 		}
 
-		log_message('debug', "Calendar Class Initialized");
+		log_message('debug', 'Calendar Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -81,7 +82,6 @@
 	 *
 	 * Accepts an associative array as input, containing display preferences
 	 *
-	 * @access	public
 	 * @param	array	config preferences
 	 * @return	void
 	 */
@@ -101,9 +101,8 @@
 	/**
 	 * Generate the calendar
 	 *
-	 * @access	public
-	 * @param	integer	the year
-	 * @param	integer	the month
+	 * @param	int	the year
+	 * @param	int	the month
 	 * @param	array	the data to be shown in the calendar cells
 	 * @return	string
 	 */
@@ -147,7 +146,7 @@
 		// Set the starting day number
 		$local_date = mktime(12, 0, 0, $month, 1, $year);
 		$date = getdate($local_date);
-		$day  = $start_day + 1 - $date["wday"];
+		$day  = $start_day + 1 - $date['wday'];
 
 		while ($day > 1)
 		{
@@ -160,7 +159,7 @@
 		$cur_month	= date('m', $this->local_time);
 		$cur_day	= date('j', $this->local_time);
 
-		$is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;
+		$is_current_month = ($cur_year == $year && $cur_month == $month);
 
 		// Generate the template data array
 		$this->parse_template();
@@ -172,7 +171,7 @@
 		if ($this->show_next_prev == TRUE)
 		{
 			// Add a trailing slash to the  URL if needed
-			$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->next_prev_url);
+			$this->next_prev_url = preg_replace('/(.+?)\/*$/', '\\1/',  $this->next_prev_url);
 
 			$adjusted_date = $this->adjust_date($month - 1, $year);
 			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell'])."\n";
@@ -213,21 +212,21 @@
 
 			for ($i = 0; $i < 7; $i++)
 			{
-				$out .= ($is_current_month === TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
+				$out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
 
-				if ($day > 0 AND $day <= $total_days)
+				if ($day > 0 && $day <= $total_days)
 				{
 					if (isset($data[$day]))
 					{
 						// Cells with content
-						$temp = ($is_current_month === TRUE AND $day == $cur_day) ?
+						$temp = ($is_current_month === TRUE && $day == $cur_day) ?
 								$this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
 						$out .= str_replace(array('{content}', '{day}'), array($data[$day], $day), $temp);
 					}
 					else
 					{
 						// Cells with no content
-						$temp = ($is_current_month === TRUE AND $day == $cur_day) ?
+						$temp = ($is_current_month === TRUE && $day == $cur_day) ?
 								$this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
 						$out .= str_replace('{day}', $day, $temp);
 					}
@@ -238,7 +237,7 @@
 					$out .= $this->temp['cal_cell_blank'];
 				}
 
-				$out .= ($is_current_month === TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
+				$out .= ($is_current_month === TRUE && $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];
 				$day++;
 			}
 
@@ -258,8 +257,7 @@
 	 * Generates a textual month name based on the numeric
 	 * month provided.
 	 *
-	 * @access	public
-	 * @param	integer	the month
+	 * @param	int	the month
 	 * @return	string
 	 */
 	public function get_month_name($month)
@@ -289,9 +287,8 @@
 	 * Get Day Names
 	 *
 	 * Returns an array of day names (Sunday, Monday, etc.) based
-	 * on the type.  Options: long, short, abrev
+	 * on the type. Options: long, short, abrev
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	array
 	 */
@@ -333,9 +330,8 @@
 	 * For example, if you submit 13 as the month, the year will
 	 * increment and the month will become January.
 	 *
-	 * @access	public
-	 * @param	integer	the month
-	 * @param	integer	the year
+	 * @param	int	the month
+	 * @param	int	the year
 	 * @return	array
 	 */
 	public function adjust_date($month, $year)
@@ -370,10 +366,9 @@
 	/**
 	 * Total days in a given month
 	 *
-	 * @access	public
-	 * @param	integer	the month
-	 * @param	integer	the year
-	 * @return	integer
+	 * @param	int	the month
+	 * @param	int	the year
+	 * @return	int
 	 */
 	public function get_total_days($month, $year)
 	{
@@ -387,7 +382,7 @@
 		// Is the year a leap year?
 		if ($month == 2)
 		{
-			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
+			if ($year % 400 == 0 OR ($year % 4 == 0 && $year % 100 != 0))
 			{
 				return 29;
 			}
@@ -403,8 +398,7 @@
 	 *
 	 * This is used in the event that the user has not created their own template
 	 *
-	 * @access	public
-	 * @return array
+	 * @return	array
 	 */
 	public function default_template()
 	{
@@ -441,7 +435,6 @@
 	 * Harvests the data within the template {pseudo-variables}
 	 * used to display the calendar
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function parse_template()
@@ -457,7 +450,7 @@
 
 		foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content',  'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val)
 		{
-			if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))
+			if (preg_match('/\{'.$val.'\}(.*?)\{\/'.$val.'\}/si', $this->template, $match))
 			{
 				$this->temp[$val] = $match[1];
 			}
@@ -470,7 +463,5 @@
 
 }
 
-// END CI_Calendar class
-
 /* End of file Calendar.php */
-/* Location: ./system/libraries/Calendar.php */
+/* Location: ./system/libraries/Calendar.php */
\ No newline at end of file
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
index 10b5362..ca7be55 100644
--- a/system/libraries/Cart.php
+++ b/system/libraries/Cart.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Shopping Cart Class
  *
@@ -41,12 +39,11 @@
 	// These are the regular expression rules that we use to validate the product ID and product name
 	public $product_id_rules	= '\.a-z0-9_-'; // alpha-numeric, dashes, underscores, or periods
 	public $product_name_rules	= '\.\:\-_ a-z0-9'; // alpha-numeric, dashes, underscores, colons or periods
-	public $product_name_safe  = true; // only allow safe product names
+	public $product_name_safe	= TRUE; // only allow safe product names
 
-	// Private variables.  Do not change!
-	private $CI;
-	private $_cart_contents	= array();
-
+	// Protected variables. Do not change!
+	protected $CI;
+	protected $_cart_contents	= array();
 
 	/**
 	 * Shopping Class Constructor
@@ -72,7 +69,7 @@
 			$this->_cart_contents = array('cart_total' => 0, 'total_items' => 0);
 		}
 
-		log_message('debug', "Cart Class Initialized");
+		log_message('debug', 'Cart Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -80,7 +77,6 @@
 	/**
 	 * Insert items into the cart and save it to the session table
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	bool
 	 */
@@ -110,7 +106,7 @@
 		{
 			foreach ($items as $val)
 			{
-				if (is_array($val) AND isset($val['id']))
+				if (is_array($val) && isset($val['id']))
 				{
 					if ($this->_insert($val))
 					{
@@ -135,11 +131,10 @@
 	/**
 	 * Insert
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	bool
 	 */
-	private function _insert($items = array())
+	protected function _insert($items = array())
 	{
 		// Was any cart data passed? No? Bah...
 		if ( ! is_array($items) OR count($items) === 0)
@@ -213,7 +208,7 @@
 		// Internally, we need to treat identical submissions, but with different options, as a unique product.
 		// Our solution is to convert the options array to a string and MD5 it along with the product ID.
 		// This becomes the unique "row ID"
-		if (isset($items['options']) AND count($items['options']) > 0)
+		if (isset($items['options']) && count($items['options']) > 0)
 		{
 			$rowid = md5($items['id'].implode('', $items['options']));
 		}
@@ -249,7 +244,6 @@
 	 * changes to the quantity before checkout. That array must contain the
 	 * product ID and quantity for each item.
 	 *
-	 * @access	public
 	 * @param	array
 	 * @param	string
 	 * @return	bool
@@ -308,11 +302,10 @@
 	 * changes to the quantity before checkout. That array must contain the
 	 * product ID and quantity for each item.
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	bool
 	 */
-	private function _update($items = array())
+	protected function _update($items = array())
 	{
 		// Without these array indexes there is nothing we can do
 		if ( ! isset($items['qty']) OR ! isset($items['rowid']) OR ! isset($this->_cart_contents[$items['rowid']]))
@@ -348,10 +341,9 @@
 	/**
 	 * Save the cart array to the session DB
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _save_cart()
+	protected function _save_cart()
 	{
 		// Lets add up the individual prices and set the cart sub-total
 		$this->_cart_contents['total_items'] = $this->_cart_contents['cart_total'] = 0;
@@ -390,8 +382,7 @@
 	/**
 	 * Cart Total
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
 	public function total()
 	{
@@ -405,8 +396,7 @@
 	 *
 	 * Removes an item from the cart
 	 *
-	 * @access	public
-	 * @return	boolean
+	 * @return	bool
 	 */
 	 public function remove($rowid)
 	 {
@@ -423,8 +413,7 @@
 	 *
 	 * Returns the total item count
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
 	public function total_items()
 	{
@@ -438,7 +427,6 @@
 	 *
 	 * Returns the entire cart array
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function contents($newest_first = FALSE)
@@ -461,7 +449,6 @@
 	 * Returns TRUE if the rowid passed to this function correlates to an item
 	 * that has options associated with it.
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function has_options($rowid = '')
@@ -476,7 +463,7 @@
 	 *
 	 * Returns the an array of options, for a particular product row ID
 	 *
-	 * @access	public
+	 * @param	int
 	 * @return	array
 	 */
 	public function product_options($rowid = '')
@@ -491,7 +478,7 @@
 	 *
 	 * Returns the supplied number with commas and a decimal point.
 	 *
-	 * @access	public
+	 * @param	float
 	 * @return	string
 	 */
 	public function format_number($n = '')
@@ -514,7 +501,6 @@
 	 *
 	 * Empties the cart and kills the session
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function destroy()
@@ -523,9 +509,7 @@
 		$this->CI->session->unset_userdata('cart_contents');
 	}
 
-
 }
-// END Cart Class
 
 /* End of file Cart.php */
-/* Location: ./system/libraries/Cart.php */
+/* Location: ./system/libraries/Cart.php */
\ No newline at end of file
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index 4e89443..f409f47 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Driver Library Class
  *
@@ -84,8 +82,8 @@
 				// it's a valid driver, but the file simply can't be found
 				if ( ! class_exists($child_class))
 				{
-					log_message('error', "Unable to load the requested driver: ".$child_class);
-					show_error("Unable to load the requested driver: ".$child_class);
+					log_message('error', 'Unable to load the requested driver: '.$child_class);
+					show_error('Unable to load the requested driver: '.$child_class);
 				}
 			}
 
@@ -96,15 +94,11 @@
 		}
 
 		// The requested driver isn't valid!
-		log_message('error', "Invalid driver requested: ".$child_class);
-		show_error("Invalid driver requested: ".$child_class);
+		log_message('error', 'Invalid driver requested: '.$child_class);
+		show_error('Invalid driver requested: '.$child_class);
 	}
 
-	// --------------------------------------------------------------------
-
 }
-// END CI_Driver_Library CLASS
-
 
 /**
  * CodeIgniter Driver Class
@@ -120,12 +114,12 @@
  */
 class CI_Driver {
 
-	protected $parent;
+	protected $_parent;
 
-	private $methods = array();
-	private $properties = array();
+	protected $_methods = array();
+	protected $_properties = array();
 
-	private static $reflections = array();
+	protected static $_reflections = array();
 
 	/**
 	 * Decorate
@@ -137,14 +131,14 @@
 	 */
 	public function decorate($parent)
 	{
-		$this->parent = $parent;
+		$this->_parent = $parent;
 
 		// Lock down attributes to what is defined in the class
 		// and speed up references in magic methods
 
 		$class_name = get_class($parent);
 
-		if ( ! isset(self::$reflections[$class_name]))
+		if ( ! isset(self::$_reflections[$class_name]))
 		{
 			$r = new ReflectionObject($parent);
 
@@ -152,7 +146,7 @@
 			{
 				if ($method->isPublic())
 				{
-					$this->methods[] = $method->getName();
+					$this->_methods[] = $method->getName();
 				}
 			}
 
@@ -160,15 +154,15 @@
 			{
 				if ($prop->isPublic())
 				{
-					$this->properties[] = $prop->getName();
+					$this->_properties[] = $prop->getName();
 				}
 			}
 
-			self::$reflections[$class_name] = array($this->methods, $this->properties);
+			self::$_reflections[$class_name] = array($this->_methods, $this->_properties);
 		}
 		else
 		{
-			list($this->methods, $this->properties) = self::$reflections[$class_name];
+			list($this->_methods, $this->_properties) = self::$_reflections[$class_name];
 		}
 	}
 
@@ -179,16 +173,15 @@
 	 *
 	 * Handles access to the parent driver library's methods
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	array
 	 * @return	mixed
 	 */
 	public function __call($method, $args = array())
 	{
-		if (in_array($method, $this->methods))
+		if (in_array($method, $this->_methods))
 		{
-			return call_user_func_array(array($this->parent, $method), $args);
+			return call_user_func_array(array($this->_parent, $method), $args);
 		}
 
 		$trace = debug_backtrace();
@@ -208,9 +201,9 @@
 	 */
 	public function __get($var)
 	{
-		if (in_array($var, $this->properties))
+		if (in_array($var, $this->_properties))
 		{
-			return $this->parent->$var;
+			return $this->_parent->$var;
 		}
 	}
 
@@ -227,16 +220,13 @@
 	 */
 	public function __set($var, $val)
 	{
-		if (in_array($var, $this->properties))
+		if (in_array($var, $this->_properties))
 		{
-			$this->parent->$var = $val;
+			$this->_parent->$var = $val;
 		}
 	}
 
-	// --------------------------------------------------------------------
-
 }
-// END CI_Driver CLASS
 
 /* End of file Driver.php */
-/* Location: ./system/libraries/Driver.php */
+/* Location: ./system/libraries/Driver.php */
\ No newline at end of file
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 8d839d0..103c3cb 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -59,6 +59,7 @@
 	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 $dsn		= FALSE;		// Delivery Status Notification
 	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_size	= 200;		// If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
@@ -406,11 +407,11 @@
 	 * @param	string
 	 * @return	object
 	 */
-	public function attach($filename, $disposition = '', $newname = NULL)
+	public function attach($filename, $disposition = '', $newname = NULL, $mime = '')
 	{
 		$this->_attach_name[] = array($filename, $newname);
-		$this->_attach_type[] = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
 		$this->_attach_disp[] = empty($disposition) ? 'attachment' : $disposition; // Can also be 'inline'  Not sure if it matters
+		$this->_attach_type[] = $mime;
 		return $this;
 	}
 
@@ -1048,29 +1049,39 @@
 			$filename = $this->_attach_name[$i][0];
 			$basename = (is_null($this->_attach_name[$i][1])) ? basename($filename) : $this->_attach_name[$i][1];
 			$ctype = $this->_attach_type[$i];
+			$file_content = '';
 
-			if ( ! file_exists($filename))
+			if ($this->_attach_type[$i] == '')
 			{
-				$this->_set_error_message('lang:email_attachment_missing', $filename);
-				return FALSE;
-			}
+				if ( ! file_exists($filename))
+				{
+					$this->_set_error_message('lang:email_attachment_missing', $filename);
+					return FALSE;
+				}
 
+				$file = filesize($filename) +1;
+
+				if ( ! $fp = fopen($filename, FOPEN_READ))
+				{
+					$this->_set_error_message('lang:email_attachment_unreadable', $filename);
+					return FALSE;
+				}
+
+				$ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
+				$file_content = fread($fp, $file);
+				fclose($fp);
+			}
+			else
+			{
+				$file_content =& $this->_attach_content[$i];
+			}
 			$attachment[$z++] = "--".$this->_atc_boundary.$this->newline
 				. "Content-type: ".$ctype."; "
 				. "name=\"".$basename."\"".$this->newline
 				. "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline
 				. "Content-Transfer-Encoding: base64".$this->newline;
 
-			$file = filesize($filename) +1;
-
-			if ( ! $fp = fopen($filename, FOPEN_READ))
-			{
-				$this->_set_error_message('lang:email_attachment_unreadable', $filename);
-				return FALSE;
-			}
-
-			$attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
-			fclose($fp);
+			$attachment[$z++] = chunk_split(base64_encode($file_content));
 		}
 
 		$body .= implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
@@ -1567,9 +1578,15 @@
 						$resp = 250;
 			break;
 			case 'to'	:
-
-						$this->_send_data('RCPT TO:<'.$data.'>');
-
+						
+						if ($this->dsn)
+						{
+							$this->_send_data('RCPT TO:<'.$data.'> NOTIFY=SUCCESS,DELAY,FAILURE ORCPT=rfc822;'.$data);
+						}
+						else
+						{
+							$this->_send_data('RCPT TO:<'.$data.'>');
+						}
 						$resp = 250;
 			break;
 			case 'data'	:
@@ -1874,6 +1891,7 @@
 						'tiff'	=>	'image/tiff',
 						'tif'	=>	'image/tiff',
 						'css'	=>	'text/css',
+						'ics'	=>	'text/calendar',
 						'html'	=>	'text/html',
 						'htm'	=>	'text/html',
 						'shtml'	=>	'text/html',
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 0b06189..54b5bf7 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -38,15 +38,15 @@
  */
 class CI_Encrypt {
 
-	public $encryption_key	= '';
-	protected $_hash_type	= 'sha1';
-	protected $_mcrypt_exists = FALSE;
+	public $encryption_key		= '';
+	protected $_hash_type		= 'sha1';
+	protected $_mcrypt_exists	= FALSE;
 	protected $_mcrypt_cipher;
 	protected $_mcrypt_mode;
 
 	public function __construct()
 	{
-		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
+		$this->_mcrypt_exists = function_exists('mcrypt_encrypt');
 		log_message('debug', 'Encrypt Class Initialized');
 	}
 
@@ -349,8 +349,8 @@
 	 *
 	 * Function description
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	string
+	 * @return	string
 	 */
 	protected function _remove_cipher_noise($data, $key)
 	{
@@ -382,8 +382,8 @@
 	/**
 	 * Set the Mcrypt Cipher
 	 *
-	 * @param	constant
-	 * @return	string
+	 * @param	int
+	 * @return	object
 	 */
 	public function set_cipher($cipher)
 	{
@@ -396,8 +396,8 @@
 	/**
 	 * Set the Mcrypt Mode
 	 *
-	 * @param	constant
-	 * @return	string
+	 * @param	int
+	 * @return	object
 	 */
 	public function set_mode($mode)
 	{
@@ -410,7 +410,7 @@
 	/**
 	 * Get Mcrypt cipher Value
 	 *
-	 * @return	string
+	 * @return	int
 	 */
 	protected function _get_cipher()
 	{
@@ -427,7 +427,7 @@
 	/**
 	 * Get Mcrypt Mode Value
 	 *
-	 * @return	string
+	 * @return	int
 	 */
 	protected function _get_mode()
 	{
@@ -464,7 +464,8 @@
 	{
 		return ($this->_hash_type === 'sha1') ? sha1($str) : md5($str);
 	}
+
 }
 
 /* End of file Encrypt.php */
-/* Location: ./system/libraries/Encrypt.php */
+/* Location: ./system/libraries/Encrypt.php */
\ No newline at end of file
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index bd8b7c2..22bc7dd 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Form Validation Class
  *
@@ -39,20 +37,32 @@
 class CI_Form_validation {
 
 	protected $CI;
-	protected $_field_data			= array();
-	protected $_config_rules		= array();
-	protected $_error_array			= array();
-	protected $_error_messages		= array();
-	protected $_error_prefix		= '<p>';
-	protected $_error_suffix		= '</p>';
-	protected $error_string			= '';
-	protected $_safe_form_data		= FALSE;
-	protected $validation_data		= array();
+	protected $_field_data		= array();
+	protected $_config_rules	= array();
+	protected $_error_array		= array();
+	protected $_error_messages	= array();
+	protected $_error_prefix	= '<p>';
+	protected $_error_suffix	= '</p>';
+	protected $error_string		= '';
+	protected $_safe_form_data	= FALSE;
+	protected $validation_data	= array();
 
 	public function __construct($rules = array())
 	{
 		$this->CI =& get_instance();
 
+		// applies delimiters set in config file.
+		if (isset($rules['error_prefix']))
+		{
+			$this->_error_prefix = $rules['error_prefix'];
+			unset($rules['error_prefix']);
+		}
+		if (isset($rules['error_suffix']))
+		{
+			$this->_error_suffix = $rules['error_suffix'];
+			unset($rules['error_suffix']);
+		}
+
 		// Validation rules can be stored in a config file.
 		$this->_config_rules = $rules;
 
@@ -60,7 +70,7 @@
 		$this->CI->load->helper('form');
 
 		// Set the character encoding in MB.
-		if (function_exists('mb_internal_encoding'))
+		if (MB_ENABLED === TRUE)
 		{
 			mb_internal_encoding($this->CI->config->item('charset'));
 		}
@@ -78,7 +88,7 @@
 	 *
 	 * @param	mixed
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_rules($field, $label = '', $rules = '')
 	{
@@ -89,24 +99,25 @@
 			return $this;
 		}
 
-		// If an array was passed via the first parameter instead of indidual string
+		// If an array was passed via the first parameter instead of individual string
 		// values we cycle through it and recursively call this function.
 		if (is_array($field))
 		{
 			foreach ($field as $row)
 			{
 				// Houston, we have a problem...
-				if ( ! isset($row['field']) OR ! isset($row['rules']))
+				if ( ! isset($row['field'], $row['rules']))
 				{
 					continue;
 				}
 
 				// If the field label wasn't passed we use the field name
-				$label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];
+				$label = isset($row['label']) ? $row['label'] : $row['field'];
 
 				// Here we go!
 				$this->set_rules($row['field'], $label, $row['rules']);
 			}
+
 			return $this;
 		}
 
@@ -186,12 +197,12 @@
 	/**
 	 * Set Error Message
 	 *
-	 * Lets users set their own error messages on the fly.  Note:  The key
-	 * name has to match the function name that it corresponds to.
+	 * Lets users set their own error messages on the fly. Note:
+	 * The key name has to match the function name that it corresponds to.
 	 *
+	 * @param	array
 	 * @param	string
-	 * @param	string
-	 * @return	string
+	 * @return	object
 	 */
 	public function set_message($lang, $val = '')
 	{
@@ -201,7 +212,6 @@
 		}
 
 		$this->_error_messages = array_merge($this->_error_messages, $lang);
-
 		return $this;
 	}
 
@@ -214,13 +224,12 @@
 	 *
 	 * @param	string
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
 	{
 		$this->_error_prefix = $prefix;
 		$this->_error_suffix = $suffix;
-
 		return $this;
 	}
 
@@ -232,11 +241,11 @@
 	 * Gets the error message associated with a particular field
 	 *
 	 * @param	string	the field name
-	 * @return	void
+	 * @return	string
 	 */
 	public function error($field = '', $prefix = '', $suffix = '')
 	{
-		if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
+		if (empty($this->_field_data[$field]['error']))
 		{
 			return '';
 		}
@@ -277,7 +286,7 @@
 	 *
 	 * @param	string
 	 * @param	string
-	 * @return	str
+	 * @return	string
 	 */
 	public function error_string($prefix = '', $suffix = '')
 	{
@@ -322,7 +331,7 @@
 	public function run($group = '')
 	{
 		// Do we even have any data to process?  Mm?
-		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;
+		$validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
 		if (count($validation_array) === 0)
 		{
 			return FALSE;
@@ -341,7 +350,7 @@
 			// Is there a validation rule for the particular URI being accessed?
 			$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
 
-			if ($uri != '' AND isset($this->_config_rules[$uri]))
+			if ($uri != '' && isset($this->_config_rules[$uri]))
 			{
 				$this->set_rules($this->_config_rules[$uri]);
 			}
@@ -350,10 +359,10 @@
 				$this->set_rules($this->_config_rules);
 			}
 
-			// We're we able to set the rules correctly?
+			// Were we able to set the rules correctly?
 			if (count($this->_field_data) === 0)
 			{
-				log_message('debug', "Unable to find validation rules");
+				log_message('debug', 'Unable to find validation rules');
 				return FALSE;
 			}
 		}
@@ -367,17 +376,13 @@
 		{
 			// Fetch the data from the corresponding $_POST or validation array and cache it in the _field_data array.
 			// Depending on whether the field name is an array or a string will determine where we get it from.
-
 			if ($row['is_array'] === TRUE)
 			{
 				$this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']);
 			}
-			else
+			elseif ( ! empty($validation_array[$field]))
 			{
-				if (isset($validation_array[$field]) AND $validation_array[$field] != "")
-				{
-					$this->_field_data[$field]['postdata'] = $validation_array[$field];
-				}
+				$this->_field_data[$field]['postdata'] = $validation_array[$field];
 			}
 
 			$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
@@ -385,7 +390,6 @@
 
 		// Did we end up with any errors?
 		$total_errors = count($this->_error_array);
-
 		if ($total_errors > 0)
 		{
 			$this->_safe_form_data = TRUE;
@@ -404,7 +408,7 @@
 	 *
 	 * @param	array
 	 * @param	array
-	 * @param	integer
+	 * @param	int
 	 * @return	mixed
 	 */
 	protected function _reduce_array($array, $keys, $i = 0)
@@ -422,7 +426,7 @@
 	/**
 	 * Re-populate the _POST array with our finalized and processed data
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	protected function _reset_post_array()
 	{
@@ -482,7 +486,7 @@
 	 * @param	array
 	 * @param	array
 	 * @param	mixed
-	 * @param	integer
+	 * @param	int
 	 * @return	mixed
 	 */
 	protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
@@ -499,17 +503,15 @@
 			return;
 		}
 
-		// --------------------------------------------------------------------
-
 		// If the field is blank, but NOT required, no further tests are necessary
 		$callback = FALSE;
-		if ( ! in_array('required', $rules) AND is_null($postdata))
+		if ( ! in_array('required', $rules) && is_null($postdata))
 		{
 			// Before we bail out, does the rule contain a callback?
-			if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match))
+			if (preg_match('/(callback_\w+(\[.*?\])?)/', implode(' ', $rules), $match))
 			{
 				$callback = TRUE;
-				$rules = (array('1' => $match[1]));
+				$rules = array(1 => $match[1]);
 			}
 			else
 			{
@@ -517,15 +519,13 @@
 			}
 		}
 
-		// --------------------------------------------------------------------
-
 		// Isset Test. Typically this rule will only apply to checkboxes.
-		if (is_null($postdata) AND $callback === FALSE)
+		if (is_null($postdata) && $callback === FALSE)
 		{
 			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
 			{
 				// Set the message type
-				$type = (in_array('required', $rules)) ? 'required' : 'isset';
+				$type = in_array('required', $rules) ? 'required' : 'isset';
 
 				if ( ! isset($this->_error_messages[$type]))
 				{
@@ -557,13 +557,13 @@
 		// --------------------------------------------------------------------
 
 		// Cycle through each rule and run it
-		foreach ($rules As $rule)
+		foreach ($rules as $rule)
 		{
 			$_in_array = FALSE;
 
 			// We set the $postdata variable with the current data in our master array so that
 			// each cycle of the loop is dealing with the processed data from the last cycle
-			if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
+			if ($row['is_array'] == TRUE && is_array($this->_field_data[$row['field']]['postdata']))
 			{
 				// We shouldn't need this safety, but just in case there isn't an array index
 				// associated with this cycle we'll bail out
@@ -580,11 +580,9 @@
 				$postdata = $this->_field_data[$row['field']]['postdata'];
 			}
 
-			// --------------------------------------------------------------------
-
 			// Is the rule a callback?
 			$callback = FALSE;
-			if (substr($rule, 0, 9) == 'callback_')
+			if (strpos($rule, 'callback_') === 0)
 			{
 				$rule = substr($rule, 9);
 				$callback = TRUE;
@@ -593,7 +591,7 @@
 			// Strip the parameter (if exists) from the rule
 			// Rules can contain a parameter: max_length[5]
 			$param = FALSE;
-			if (preg_match("/(.*?)\[(.*)\]/", $rule, $match))
+			if (preg_match('/(.*?)\[(.*)\]/', $rule, $match))
 			{
 				$rule	= $match[1];
 				$param	= $match[2];
@@ -604,68 +602,69 @@
 			{
 				if ( ! method_exists($this->CI, $rule))
 				{
-					continue;
+					log_message('debug', 'Unable to find callback validation rule: '.$rule);
+					$result = FALSE;
 				}
-
-				// Run the function and grab the result
-				$result = $this->CI->$rule($postdata, $param);
+				else
+				{
+					// Run the function and grab the result
+					$result = $this->CI->$rule($postdata, $param);
+				}
 
 				// Re-assign the result to the master data array
 				if ($_in_array === TRUE)
 				{
-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
 				}
 				else
 				{
-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
 				}
 
 				// If the field isn't required and we just processed a callback we'll move on...
-				if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
+				if ( ! in_array('required', $rules, TRUE) && $result !== FALSE)
 				{
 					continue;
 				}
 			}
+			elseif ( ! method_exists($this, $rule))
+			{
+				// If our own wrapper function doesn't exist we see if a native PHP function does.
+				// Users can use any native PHP function call that has one param.
+				if (function_exists($rule))
+				{
+					$result = ($param !== FALSE) ? $rule($postdata, $param) : $rule($postdata);
+
+					if ($_in_array === TRUE)
+					{
+						$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
+					}
+					else
+					{
+						$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
+					}
+				}
+				else
+				{
+					log_message('debug', 'Unable to find validation rule: '.$rule);
+					$result = FALSE;
+				}
+			}
 			else
 			{
-				if ( ! method_exists($this, $rule))
-				{
-					// If our own wrapper function doesn't exist we see if a native PHP function does.
-					// Users can use any native PHP function call that has one param.
-					if (function_exists($rule))
-					{
-						$result = $rule($postdata);
-
-						if ($_in_array === TRUE)
-						{
-							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
-						}
-						else
-						{
-							$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
-						}
-					}
-					else
-					{
-						log_message('debug', "Unable to find validation rule: ".$rule);
-					}
-
-					continue;
-				}
-
 				$result = $this->$rule($postdata, $param);
 
 				if ($_in_array === TRUE)
 				{
-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
 				}
 				else
 				{
-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
 				}
 			}
 
-			// Did the rule test negatively?  If so, grab the error.
+			// Did the rule test negatively? If so, grab the error.
 			if ($result === FALSE)
 			{
 				if ( ! isset($this->_error_messages[$rule]))
@@ -681,7 +680,7 @@
 				}
 
 				// Is the parameter we are inserting into the error message the name
-				// of another field?  If so we need to grab its "field label"
+				// of another field? If so we need to grab its "field label"
 				if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
 				{
 					$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
@@ -715,7 +714,7 @@
 	{
 		// Do we need to translate the field name?
 		// We look for the prefix lang: to determine this
-		if (substr($fieldname, 0, 5) === 'lang:')
+		if (strpos($fieldname, 'lang:') === 0)
 		{
 			// Grab the variable
 			$line = substr($fieldname, 5);
@@ -779,7 +778,6 @@
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
-
 		if (is_array($field))
 		{
 			if ( ! in_array($value, $field))
@@ -815,7 +813,6 @@
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
-
 		if (is_array($field))
 		{
 			if ( ! in_array($value, $field))
@@ -823,12 +820,9 @@
 				return '';
 			}
 		}
-		else
+		elseif (($field == '' OR $value == '') OR ($field != $value))
 		{
-			if (($field == '' OR $value == '') OR ($field != $value))
-			{
-				return '';
-			}
+			return '';
 		}
 
 		return ' checked="checked"';
@@ -862,7 +856,7 @@
 	 */
 	public function required($str)
 	{
-		return ( ! is_array($str)) ? (trim($str) !== '') : ( ! empty($str));
+		return is_array($str) ? (bool) count($str) : (trim($str) !== '');
 	}
 
 	// --------------------------------------------------------------------
@@ -871,7 +865,7 @@
 	 * Performs a Regular Expression match test.
 	 *
 	 * @param	string
-	 * @param	regex
+	 * @param	string	regex
 	 * @return	bool
 	 */
 	public function regex_match($str, $regex)
@@ -885,12 +879,12 @@
 	 * Match one field to another
 	 *
 	 * @param	string
-	 * @param	field
+	 * @param	string	field
 	 * @return	bool
 	 */
 	public function matches($str, $field)
 	{
-		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;
+		$validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
 		if ( ! isset($validation_array[$field]))
 		{
 			return FALSE;
@@ -908,7 +902,7 @@
 	 * in the specified database field.
 	 *
 	 * @param	string
-	 * @param	field
+	 * @param	string	field
 	 * @return	bool
 	 */
 	public function is_unique($str, $field)
@@ -928,7 +922,7 @@
 	 * Minimum Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function min_length($str, $val)
@@ -938,12 +932,9 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
-		{
-			return ! (mb_strlen($str) < $val);
-		}
-
-		return ! (strlen($str) < $val);
+		return (MB_ENABLED === TRUE)
+			? ($val <= mb_strlen($str))
+			: ($val <= strlen(str));
 	}
 
 	// --------------------------------------------------------------------
@@ -952,7 +943,7 @@
 	 * Max Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function max_length($str, $val)
@@ -962,12 +953,9 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
-		{
-			return ! (mb_strlen($str) > $val);
-		}
-
-		return ! (strlen($str) > $val);
+		return (MB_ENABLED === TRUE)
+			? ($val >= mb_strlen($str))
+			: ($val >= strlen($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -976,7 +964,7 @@
 	 * Exact Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function exact_length($str, $val)
@@ -986,12 +974,9 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
-		{
-			return (mb_strlen($str) == $val);
-		}
-
-		return (strlen($str) == $val);
+		return (MB_ENABLED === TRUE)
+			? (mb_strlen($str) == $val)
+			: (strlen($str) == $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1102,19 +1087,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Is Numeric
-	 *
-	 * @param	string
-	 * @return	bool
-	 */
-	public function is_numeric($str)
-	{
-		return is_numeric($str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Integer
 	 *
 	 * @param	string
@@ -1148,11 +1120,7 @@
 	 */
 	public function greater_than($str, $min)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str > $min;
+		return is_numeric($str) ? ($str > $min) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1165,11 +1133,7 @@
 	 */
 	public function greater_than_equal_to($str, $min)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str >= $min;
+		return is_numeric($str) ? ($str >= $min) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1182,11 +1146,7 @@
 	 */
 	public function less_than($str, $max)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str < $max;
+		return is_numeric($str) ? ($str < $max) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1199,11 +1159,7 @@
 	 */
 	public function less_than_equal_to($str, $max)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str <= $max;
+		return is_numeric($str) ? ($str <= $max) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1289,14 +1245,14 @@
 	 */
 	public function prep_url($str = '')
 	{
-		if ($str == 'http://' OR $str == '')
+		if ($str === 'http://' OR $str == '')
 		{
 			return '';
 		}
 
-		if (substr($str, 0, 7) !== 'http://' && substr($str, 0, 8) !== 'https://')
+		if (strpos($str, 'http://') !== 0 && strpos($str, 'https://') !== 0)
 		{
-			$str = 'http://'.$str;
+			return 'http://'.$str;
 		}
 
 		return $str;
@@ -1363,4 +1319,4 @@
 }
 
 /* End of file Form_validation.php */
-/* Location: ./system/libraries/Form_validation.php */
+/* Location: ./system/libraries/Form_validation.php */
\ No newline at end of file
diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php
index ab395b0..8aa1650 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * FTP Class
  *
@@ -42,16 +40,11 @@
 	public $username	= '';
 	public $password	= '';
 	public $port		= 21;
-	public $passive	= TRUE;
+	public $passive		= TRUE;
 	public $debug		= FALSE;
-	public $conn_id	= FALSE;
+	public $conn_id		= FALSE;
 
 
-	/**
-	 * Constructor - Sets Preferences
-	 *
-	 * The constructor can be passed an array of config values
-	 */
 	public function __construct($config = array())
 	{
 		if (count($config) > 0)
@@ -59,7 +52,7 @@
 			$this->initialize($config);
 		}
 
-		log_message('debug', "FTP Class Initialized");
+		log_message('debug', 'FTP Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -67,7 +60,6 @@
 	/**
 	 * Initialize preferences
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
@@ -90,7 +82,6 @@
 	/**
 	 * FTP Connect
 	 *
-	 * @access	public
 	 * @param	array	 the connection values
 	 * @return	bool
 	 */
@@ -133,10 +124,9 @@
 	/**
 	 * FTP Login
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _login()
+	protected function _login()
 	{
 		return @ftp_login($this->conn_id, $this->username, $this->password);
 	}
@@ -146,10 +136,9 @@
 	/**
 	 * Validates the connection ID
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _is_conn()
+	protected function _is_conn()
 	{
 		if ( ! is_resource($this->conn_id))
 		{
@@ -164,17 +153,15 @@
 
 	// --------------------------------------------------------------------
 
-
 	/**
 	 * Change directory
 	 *
 	 * The second parameter lets us momentarily turn off debugging so that
 	 * this function can be used to test for the existence of a folder
-	 * without throwing an error.  There's no FTP equivalent to is_dir()
+	 * without throwing an error. There's no FTP equivalent to is_dir()
 	 * so we do it by trying to change to a particular directory.
 	 * Internally, this parameter is only used by the "mirror" function below.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool
 	 * @return	bool
@@ -190,7 +177,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE AND $supress_debug == FALSE)
+			if ($this->debug == TRUE && $supress_debug == FALSE)
 			{
 				$this->_error('ftp_unable_to_changedir');
 			}
@@ -205,8 +192,8 @@
 	/**
 	 * Create a directory
 	 *
-	 * @access	public
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function mkdir($path = '', $permissions = NULL)
@@ -230,7 +217,7 @@
 		// Set file permissions if needed
 		if ( ! is_null($permissions))
 		{
-			$this->chmod($path, (int)$permissions);
+			$this->chmod($path, (int) $permissions);
 		}
 
 		return TRUE;
@@ -241,10 +228,10 @@
 	/**
 	 * Upload a file to the server
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
@@ -284,7 +271,7 @@
 		// Set file permissions if needed
 		if ( ! is_null($permissions))
 		{
-			$this->chmod($rempath, (int)$permissions);
+			$this->chmod($rempath, (int) $permissions);
 		}
 
 		return TRUE;
@@ -295,7 +282,6 @@
 	/**
 	 * Download a file from a remote server to the local server
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @param	string
@@ -337,7 +323,6 @@
 	/**
 	 * Rename (or move) a file
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @param	bool
@@ -369,7 +354,6 @@
 	/**
 	 * Move a file
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	bool
@@ -384,7 +368,6 @@
 	/**
 	 * Rename (or move) a file
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -415,7 +398,6 @@
 	 * Delete a folder and recursively delete everything (including sub-folders)
 	 * containted within it.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -427,11 +409,11 @@
 		}
 
 		// Add a trailing slash to the file path if needed
-		$filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);
+		$filepath = preg_replace('/(.+?)\/*$/', '\\1/',  $filepath);
 
 		$list = $this->list_files($filepath);
 
-		if ($list !== FALSE AND count($list) > 0)
+		if ($list !== FALSE && count($list) > 0)
 		{
 			foreach ($list as $item)
 			{
@@ -463,7 +445,6 @@
 	/**
 	 * Set file permissions
 	 *
-	 * @access	public
 	 * @param	string	the file path
 	 * @param	string	the permissions
 	 * @return	bool
@@ -494,7 +475,6 @@
 	/**
 	 * FTP List files in the specified directory
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function list_files($path = '.')
@@ -512,11 +492,11 @@
 	/**
 	 * Read a directory and recreate it remotely
 	 *
-	 * This function recursively reads a folder and everything it contains (including
-	 * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure
-	 * of the original file path will be recreated on the server.
+	 * This function recursively reads a folder and everything it contains
+	 * (including sub-folders) and creates a mirror via FTP based on it.
+	 * Whatever the directory structure of the original file path will be
+	 * recreated on the server.
 	 *
-	 * @access	public
 	 * @param	string	path to source with trailing slash
 	 * @param	string	path to destination - include the base folder with trailing slash
 	 * @return	bool
@@ -532,7 +512,7 @@
 		if ($fp = @opendir($locpath))
 		{
 			// Attempt to open the remote file path and try to create it, if it doesn't exist
-			if ( ! $this->changedir($rempath, TRUE) AND ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath)))
+			if ( ! $this->changedir($rempath, TRUE) && ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath)))
 			{
 				return FALSE;
 			}
@@ -542,9 +522,9 @@
 			{
 				if (@is_dir($locpath.$file) && $file[0] !== '.')
 				{
-					$this->mirror($locpath.$file."/", $rempath.$file."/");
+					$this->mirror($locpath.$file.'/', $rempath.$file.'/');
 				}
-				elseif ($file[0] !== ".")
+				elseif ($file[0] !== '.')
 				{
 					// Get the file extension so we can se the upload type
 					$ext = $this->_getext($file);
@@ -565,11 +545,10 @@
 	/**
 	 * Extract the file extension
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	private function _getext($filename)
+	protected function _getext($filename)
 	{
 		if (FALSE === strpos($filename, '.'))
 		{
@@ -580,36 +559,34 @@
 		return end($x);
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Set the upload type
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	private function _settype($ext)
+	protected function _settype($ext)
 	{
 		$text_types = array(
-							'txt',
-							'text',
-							'php',
-							'phps',
-							'php4',
-							'js',
-							'css',
-							'htm',
-							'html',
-							'phtml',
-							'shtml',
-							'log',
-							'xml'
-							);
+					'txt',
+					'text',
+					'php',
+					'phps',
+					'php4',
+					'js',
+					'css',
+					'htm',
+					'html',
+					'phtml',
+					'shtml',
+					'log',
+					'xml'
+				);
 
 
-		return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
+		return in_array($ext, $text_types) ? 'ascii' : 'binary';
 	}
 
 	// ------------------------------------------------------------------------
@@ -617,7 +594,6 @@
 	/**
 	 * Close the connection
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function close()
@@ -635,20 +611,17 @@
 	/**
 	 * Display error message
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	void
 	 */
-	private function _error($line)
+	protected function _error($line)
 	{
 		$CI =& get_instance();
 		$CI->lang->load('ftp');
 		show_error($CI->lang->line($line));
 	}
 
-
 }
-// END FTP Class
 
 /* End of file Ftp.php */
-/* Location: ./system/libraries/Ftp.php */
+/* Location: ./system/libraries/Ftp.php */
\ No newline at end of file
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 9826eab..1ab8b23 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -251,7 +251,7 @@
 		}
 		else
 		{
-			if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
+			if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
 			{
 				$full_dest_path = str_replace('\\', '/', realpath($this->new_image));
 			}
@@ -1462,4 +1462,4 @@
 }
 
 /* End of file Image_lib.php */
-/* Location: ./system/libraries/Image_lib.php */
+/* Location: ./system/libraries/Image_lib.php */
\ No newline at end of file
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 33df600..629a3ad 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Javascript Class
  *
@@ -46,7 +44,7 @@
 
 		foreach ($defaults as $key => $val)
 		{
-			if (isset($params[$key]) && $params[$key] !== "")
+			if (isset($params[$key]) && $params[$key] !== '')
 			{
 				$defaults[$key] = $params[$key];
 			}
@@ -61,7 +59,7 @@
 		// make js to refer to current library
 		$this->js =& $this->CI->$js_library_driver;
 
-		log_message('debug', "Javascript Class Initialized and loaded.  Driver used: $js_library_driver");
+		log_message('debug', 'Javascript Class Initialized and loaded. Driver used: '.$js_library_driver);
 	}
 
 	// --------------------------------------------------------------------
@@ -107,7 +105,7 @@
 	 *
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
-	 * @param	boolean	whether or not to return false
+	 * @param	bool	whether or not to return false
 	 * @return	string
 	 */
 	public function click($element = 'this', $js = '', $ret_false = TRUE)
@@ -375,7 +373,6 @@
 	// Effects
 	// --------------------------------------------------------------------
 
-
 	/**
 	 * Add Class
 	 *
@@ -618,12 +615,9 @@
 		{
 			$this->_javascript_location = $external_file;
 		}
-		else
+		elseif ($this->CI->config->item('javascript_location') != '')
 		{
-			if ($this->CI->config->item('javascript_location') != '')
-			{
-				$this->_javascript_location = $this->CI->config->item('javascript_location');
-			}
+			$this->_javascript_location = $this->CI->config->item('javascript_location');
 		}
 
 		if ($relative === TRUE OR strncmp($external_file, 'http://', 7) === 0 OR strncmp($external_file, 'https://', 8) === 0)
@@ -650,13 +644,13 @@
 	 * Outputs a <script> tag
 	 *
 	 * @param	string	The element to attach the event to
-	 * @param	boolean	If a CDATA section should be added
+	 * @param	bool	If a CDATA section should be added
 	 * @return	string
 	 */
 	public function inline($script, $cdata = TRUE)
 	{
 		return $this->_open_script()
-			. ($cdata ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n")
+			. ($cdata ? "\n// <![CDATA[\n".$script."\n// ]]>\n" : "\n".$script."\n")
 			. $this->_close_script();
 	}
 
@@ -673,7 +667,7 @@
 	protected function _open_script($src = '')
 	{
 		return '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'
-			. ($src == '' ? '>' : ' src="'.$src.'">');
+			.($src == '' ? '>' : ' src="'.$src.'">');
 	}
 
 	// --------------------------------------------------------------------
@@ -688,15 +682,12 @@
 	 */
 	protected function _close_script($extra = "\n")
 	{
-		return "</script>$extra";
+		return '</script>'.$extra;
 	}
 
-
-	// --------------------------------------------------------------------
 	// --------------------------------------------------------------------
 	// AJAX-Y STUFF - still a testbed
 	// --------------------------------------------------------------------
-	// --------------------------------------------------------------------
 
 	/**
 	 * Update
@@ -751,9 +742,9 @@
 		$json = array();
 		$_is_assoc = TRUE;
 
-		if ( ! is_array($json_result) AND empty($json_result))
+		if ( ! is_array($json_result) && empty($json_result))
 		{
-			show_error("Generate JSON Failed - Illegal key, value pair.");
+			show_error('Generate JSON Failed - Illegal key, value pair.');
 		}
 		elseif ($match_array_type)
 		{
@@ -774,7 +765,7 @@
 
 		$json = implode(',', $json);
 
-		return $_is_assoc ? "{".$json."}" : "[".$json."]";
+		return $_is_assoc ? '{'.$json.'}' : '['.$json.']';
 
 	}
 
@@ -785,8 +776,8 @@
 	 *
 	 * Checks for an associative array
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	bool
 	 */
 	protected function _is_associative_array($arr)
 	{
@@ -808,8 +799,8 @@
 	 *
 	 * Ensures a standard json value and escapes values
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	mixed
+	 * @return	string
 	 */
 	protected function _prep_args($result, $is_key = FALSE)
 	{
@@ -831,9 +822,7 @@
 		}
 	}
 
-	// --------------------------------------------------------------------
 }
-// END Javascript Class
 
 /* End of file Javascript.php */
-/* Location: ./system/libraries/Javascript.php */
+/* Location: ./system/libraries/Javascript.php */
\ No newline at end of file
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 944173f..66f9ebf 100644
--- a/system/libraries/Log.php
+++ b/system/libraries/Log.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Logging Class
  *
@@ -43,12 +41,9 @@
 	protected $_threshold_max	= 0;
 	protected $_threshold_array	= array();
 	protected $_date_fmt		= 'Y-m-d H:i:s';
-	protected $_enabled			= TRUE;
-	protected $_levels			= array('ERROR' => 1, 'DEBUG' => 2,  'INFO' => 3, 'ALL' => 4);
+	protected $_enabled		= TRUE;
+	protected $_levels		= array('ERROR' => 1, 'DEBUG' => 2,  'INFO' => 3, 'ALL' => 4);
 
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
 		$config =& get_config();
@@ -98,7 +93,7 @@
 		$level = strtoupper($level);
 
 		if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
-			AND ! isset($this->_threshold_array[$this->_levels[$level]]))
+			&& ! isset($this->_threshold_array[$this->_levels[$level]]))
 		{
 			return FALSE;
 		}
@@ -125,15 +120,15 @@
 		flock($fp, LOCK_UN);
 		fclose($fp);
 
-		if (isset($newfile) AND $newfile === TRUE)
+		if (isset($newfile) && $newfile === TRUE)
 		{
 			@chmod($filepath, FILE_WRITE_MODE);
 		}
+
 		return TRUE;
 	}
 
 }
-// END Log Class
 
 /* End of file Log.php */
-/* Location: ./system/libraries/Log.php */
+/* Location: ./system/libraries/Log.php */
\ No newline at end of file
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index d070972..a18fcb9 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Migration Class
  *
@@ -71,7 +69,7 @@
 		}
 
 		// If not set, set it
-		$this->_migration_path == '' AND $this->_migration_path = APPPATH.'migrations/';
+		$this->_migration_path != '' OR $this->_migration_path = APPPATH.'migrations/';
 
 		// Add trailing slash if not set
 		$this->_migration_path = rtrim($this->_migration_path, '/').'/';
@@ -101,7 +99,7 @@
 		}
 
 		// Do we auto migrate to the latest migration?
-		if ($this->_migration_auto_latest === TRUE AND ! $this->latest())
+		if ($this->_migration_auto_latest === TRUE && ! $this->latest())
 		{
 			show_error($this->error_string());
 		}
@@ -115,8 +113,7 @@
 	 * Calls each migration step required to get to the schema version of
 	 * choice
 	 *
-	 * @access	public
-	 * @param $version integer	Target schema version
+	 * @param	int	Target schema version
 	 * @return	mixed	TRUE if already latest, FALSE if failed, int if upgraded
 	 */
 	public function version($target_version)
@@ -241,7 +238,6 @@
 	/**
 	 * Set's the schema to the latest migration
 	 *
-	 * @access	public
 	 * @return	mixed	true if already latest, false if failed, int if upgraded
 	 */
 	public function latest()
@@ -264,7 +260,6 @@
 	/**
 	 * Set's the schema to the migration version set in config
 	 *
-	 * @access	public
 	 * @return	mixed	true if already current, false if failed, int if upgraded
 	 */
 	public function current()
@@ -277,7 +272,6 @@
 	/**
 	 * Error string
 	 *
-	 * @access	public
 	 * @return	string	Error message returned as a string
 	 */
 	public function error_string()
@@ -290,7 +284,6 @@
 	/**
 	 * Set's the schema to the latest migration
 	 *
-	 * @access	protected
 	 * @return	mixed	true if already latest, false if failed, int if upgraded
 	 */
 	protected function find_migrations()
@@ -317,8 +310,7 @@
 	/**
 	 * Retrieves current schema version
 	 *
-	 * @access	protected
-	 * @return	integer	Current Migration
+	 * @return	int	Current Migration
 	 */
 	protected function _get_version()
 	{
@@ -331,9 +323,8 @@
 	/**
 	 * Stores the current schema version
 	 *
-	 * @access	protected
-	 * @param $migrations integer	Migration reached
-	 * @return	void					Outputs a report of the migration
+	 * @param	int	Migration reached
+	 * @return	void	Outputs a report of the migration
 	 */
 	protected function _update_version($migrations)
 	{
@@ -347,8 +338,7 @@
 	/**
 	 * Enable the use of CI super-global
 	 *
-	 * @access	public
-	 * @param $var
+	 * @param	$var
 	 * @return	mixed
 	 */
 	public function __get($var)
@@ -358,4 +348,4 @@
 }
 
 /* End of file Migration.php */
-/* Location: ./system/libraries/Migration.php */
+/* Location: ./system/libraries/Migration.php */
\ No newline at end of file
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 35ac541..0fe73d6 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Pagination Class
  *
@@ -74,13 +72,12 @@
 	/**
 	 * Constructor
 	 *
-	 * @access	public
 	 * @param	array	initialization parameters
 	 */
 	public function __construct($params = array())
 	{
 		$this->initialize($params);
-		log_message('debug', "Pagination Class Initialized");
+		log_message('debug', 'Pagination Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -88,7 +85,6 @@
 	/**
 	 * Initialize Preferences
 	 *
-	 * @access	public
 	 * @param	array	initialization parameters
 	 * @return	void
 	 */
@@ -116,7 +112,6 @@
 	/**
 	 * Generate the pagination links
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function create_links()
@@ -155,13 +150,13 @@
 				$this->cur_page = (int) $CI->input->get($this->query_string_segment);
 			}
 		}
-		elseif ( ! $this->cur_page AND $CI->uri->segment($this->uri_segment) != $base_page)
+		elseif ( ! $this->cur_page && $CI->uri->segment($this->uri_segment) != $base_page)
 		{
 			$this->cur_page = (int) $CI->uri->segment($this->uri_segment);
 		}
 
 		// Set current page to 1 if it's not valid or if using page numbers instead of offset
-		if ( ! is_numeric($this->cur_page) OR ($this->use_page_numbers AND $this->cur_page == 0))
+		if ( ! is_numeric($this->cur_page) OR ($this->use_page_numbers && $this->cur_page == 0))
 		{
 			$this->cur_page = $base_page;
 		}
@@ -182,12 +177,9 @@
 				$this->cur_page = $num_pages;
 			}
 		}
-		else
+		elseif ($this->cur_page > $this->total_rows)
 		{
-			if ($this->cur_page > $this->total_rows)
-			{
-				$this->cur_page = ($num_pages - 1) * $this->per_page;
-			}
+			$this->cur_page = ($num_pages - 1) * $this->per_page;
 		}
 
 		$uri_page_number = $this->cur_page;
@@ -199,10 +191,10 @@
 
 		// Calculate the start and end numbers. These determine
 		// which number to start and end the digit links with
-		$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
-		$end   = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
+		$start	= (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
+		$end	= (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
 
-		// Is pagination being used over GET or POST?  If get, add a per_page query
+		// Is pagination being used over GET or POST? If get, add a per_page query
 		// string. If post, add a trailing slash to the base URL if needed
 		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
 		{
@@ -217,18 +209,18 @@
 		$output = '';
 
 		// Render the "First" link
-		if  ($this->first_link !== FALSE AND $this->cur_page > ($this->num_links + 1))
+		if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1))
 		{
 			$first_url = ($this->first_url == '') ? $this->base_url : $this->first_url;
 			$output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
 		}
 
 		// Render the "previous" link
-		if  ($this->prev_link !== FALSE AND $this->cur_page != 1)
+		if  ($this->prev_link !== FALSE && $this->cur_page != 1)
 		{
 			$i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
 
-			if ($i == $base_page AND $this->first_url != '')
+			if ($i == $base_page && $this->first_url != '')
 			{
 				$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
 			}
@@ -274,7 +266,7 @@
 		}
 
 		// Render the "next" link
-		if ($this->next_link !== FALSE AND $this->cur_page < $num_pages)
+		if ($this->next_link !== FALSE && $this->cur_page < $num_pages)
 		{
 			$i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
 
@@ -282,7 +274,7 @@
 		}
 
 		// Render the "Last" link
-		if ($this->last_link !== FALSE AND ($this->cur_page + $this->num_links) < $num_pages)
+		if ($this->last_link !== FALSE && ($this->cur_page + $this->num_links) < $num_pages)
 		{
 			$i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
 
@@ -291,15 +283,13 @@
 
 		// Kill double slashes. Note: Sometimes we can end up with a double slash
 		// in the penultimate link so we'll kill all double slashes.
-		$output = preg_replace("#([^:])//+#", "\\1/", $output);
+		$output = preg_replace('#([^:])//+#', '\\1/', $output);
 
 		// Add the wrapper HTML if exists
-		$output = $this->full_tag_open.$output.$this->full_tag_close;
-
-		return $output;
+		return $this->full_tag_open.$output.$this->full_tag_close;
 	}
+
 }
-// END Pagination Class
 
 /* End of file Pagination.php */
-/* Location: ./system/libraries/Pagination.php */
+/* Location: ./system/libraries/Pagination.php */
\ No newline at end of file
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index 3212482..d1b5b76 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Parser Class
  *
@@ -41,15 +39,14 @@
 	public $l_delim = '{';
 	public $r_delim = '}';
 	public $object;
-	private $CI;
+	protected $CI;
 
 	/**
-	 *  Parse a template
+	 * Parse a template
 	 *
 	 * Parses pseudo-variables contained in the specified template view,
 	 * replacing them with the data in the second param
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	array
 	 * @param	bool
@@ -66,12 +63,11 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Parse a String
+	 * Parse a String
 	 *
 	 * Parses pseudo-variables contained in the specified string,
 	 * replacing them with the data in the second param
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	array
 	 * @param	bool
@@ -85,18 +81,17 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Parse a template
+	 * Parse a template
 	 *
 	 * Parses pseudo-variables contained in the specified template,
 	 * replacing them with the data in the second param
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	array
 	 * @param	bool
 	 * @return	string
 	 */
-	private function _parse($template, $data, $return = FALSE)
+	protected function _parse($template, $data, $return = FALSE)
 	{
 		if ($template == '')
 		{
@@ -126,9 +121,8 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Set the left/right variable delimiters
+	 * Set the left/right variable delimiters
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	void
@@ -142,15 +136,14 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Parse a single key/value
+	 * Parse a single key/value
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	private function _parse_single($key, $val, $string)
+	protected function _parse_single($key, $val, $string)
 	{
 		return str_replace($this->l_delim.$key.$this->r_delim, (string) $val, $string);
 	}
@@ -158,17 +151,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Parse a tag pair
+	 * Parse a tag pair
 	 *
-	 * Parses tag pairs:  {some_tag} string... {/some_tag}
+	 * Parses tag pairs: {some_tag} string... {/some_tag}
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	array
 	 * @param	string
 	 * @return	string
 	 */
-	private function _parse_pair($variable, $data, $string)
+	protected function _parse_pair($variable, $data, $string)
 	{
 		if (FALSE === ($match = $this->_match_pair($string, $variable)))
 		{
@@ -200,25 +192,20 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *  Matches a variable pair
+	 * Matches a variable pair
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @return	mixed
 	 */
-	private function _match_pair($string, $variable)
+	protected function _match_pair($string, $variable)
 	{
-		if ( ! preg_match("|" . preg_quote($this->l_delim) . $variable . preg_quote($this->r_delim) . "(.+?)". preg_quote($this->l_delim) . '/' . $variable . preg_quote($this->r_delim) . "|s", $string, $match))
-		{
-			return FALSE;
-		}
-
-		return $match;
+		return preg_match('|'.preg_quote($this->l_delim).$variable.preg_quote($this->r_delim).'(.+?)'.preg_quote($this->l_delim).'/'.$variable.preg_quote($this->r_delim).'|s',
+					$string, $match)
+			? $match : FALSE;
 	}
 
 }
-// END Parser Class
 
 /* End of file Parser.php */
-/* Location: ./system/libraries/Parser.php */
+/* Location: ./system/libraries/Parser.php */
\ No newline at end of file
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 04216be..6320ab5 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Profiler Class
  *
@@ -45,24 +43,22 @@
 class CI_Profiler {
 
 	protected $_available_sections = array(
-										'benchmarks',
-										'get',
-										'memory_usage',
-										'post',
-										'uri_string',
-										'controller_info',
-										'queries',
-										'http_headers',
-										'session_data',
-										'config'
-										);
+						'benchmarks',
+						'get',
+						'memory_usage',
+						'post',
+						'uri_string',
+						'controller_info',
+						'queries',
+						'http_headers',
+						'session_data',
+						'config'
+					);
 
 	protected $_query_toggle_count = 25;
 
 	protected $CI;
 
-	// --------------------------------------------------------------------
-
 	public function __construct($config = array())
 	{
 		$this->CI =& get_instance();
@@ -102,7 +98,7 @@
 		{
 			if (in_array($method, $this->_available_sections))
 			{
-				$this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE;
+				$this->_compile_{$method} = ($enable !== FALSE);
 			}
 		}
 	}
@@ -127,7 +123,7 @@
 			// We match the "end" marker so that the list ends
 			// up in the order that it was defined
 			if (preg_match('/(.+?)_end/i', $key, $match)
-				AND isset($this->CI->benchmark->marker[$match[1].'_end'], $this->CI->benchmark->marker[$match[1].'_start']))
+				&& isset($this->CI->benchmark->marker[$match[1].'_end'], $this->CI->benchmark->marker[$match[1].'_start']))
 			{
 				$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
 			}
@@ -135,18 +131,20 @@
 
 		// Build a table containing the profile data.
 		// Note: At some point we should turn this into a template that can
-		// be modified.  We also might want to make this data available to be logged
+		// be modified. We also might want to make this data available to be logged
 
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>'
-			. "\n\n\n<table style='width:100%'>\n";
+			.'<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks')."&nbsp;&nbsp;</legend>"
+			."\n\n\n<table style=\"width:100%;\">\n";
 
 		foreach ($profile as $key => $val)
 		{
 			$key = ucwords(str_replace(array('_', '-'), ' ', $key));
-			$output .= "<tr><td style='padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;">'
+					.$key.'&nbsp;&nbsp;</td><td style="padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;">'
+					.$val."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -166,7 +164,7 @@
 		// Let's determine which databases are currently connected to
 		foreach (get_object_vars($this->CI) as $CI_object)
 		{
-			if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') )
+			if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB'))
 			{
 				$dbs[] = $CI_object;
 			}
@@ -175,13 +173,13 @@
 		if (count($dbs) === 0)
 		{
 			return "\n\n"
-				. '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
-				. "\n"
-				. '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>'
-				. "\n\n\n<table style='border:none; width:100%;'>\n"
-				. '<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
-				. $this->CI->lang->line('profiler_no_db')
-				. "</td></tr>\n</table>\n</fieldset>";
+				.'<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+				."\n"
+				.'<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>'
+				."\n\n\n<table style=\"border:none; width:100%;\">\n"
+				.'<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
+				.$this->CI->lang->line('profiler_no_db')
+				."</td></tr>\n</table>\n</fieldset>";
 		}
 
 		// Load the text helper so we can highlight the SQL
@@ -191,7 +189,6 @@
 		$highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR&nbsp;', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');
 
 		$output  = "\n\n";
-
 		$count = 0;
 
 		foreach ($dbs as $db)
@@ -205,21 +202,23 @@
 				$show_hide_js = '(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_queries_db_'.$count.'\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)';
 			}
 
-			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-				. "\n"
-				. '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'&nbsp;&nbsp;'.$show_hide_js.'</legend>'
-				. "\n\n\n<table style='width:100%;{$hide_queries}' id='ci_profiler_queries_db_{$count}'>\n";
+			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+				."\n"
+				.'<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database')
+				.':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries')
+				.': '.count($db->queries).'&nbsp;&nbsp;'.$show_hide_js."</legend>\n\n\n"
+				.'<table style="width:100%;'.$hide_queries.'" id="ci_profiler_queries_db_'.$count."\">\n";
 
 			if (count($db->queries) === 0)
 			{
-				$output .= "<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
+				$output .= '<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
+						.$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
 			}
 			else
 			{
 				foreach ($db->queries as $key => $val)
 				{
 					$time = number_format($db->query_times[$key], 4);
-
 					$val = highlight_code($val, ENT_QUOTES);
 
 					foreach ($highlight as $bold)
@@ -227,18 +226,18 @@
 						$val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
 					}
 
-					$output .= "<tr><td style='padding:5px; vertical-align: top;width:1%;color:#900;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+					$output .= '<tr><td style="padding:5px;vertical-align:top;width:1%;color:#900;font-weight:normal;background-color:#ddd;">'
+							.$time.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;font-weight:normal;background-color:#ddd;">'
+							.$val."</td></tr>\n";
 				}
 			}
 
 			$output .= "</table>\n</fieldset>";
-
 		}
 
 		return $output;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -248,19 +247,18 @@
 	 */
 	protected function _compile_get()
 	{
-		$output  = "\n\n"
-			. '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>'
-			. "\n";
+		$output = "\n\n"
+			.'<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data')."&nbsp;&nbsp;</legend>\n";
 
 		if (count($_GET) === 0)
 		{
-			$output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
+			$output .= '<div style="color:#cd6e00;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_get').'</div>';
 		}
 		else
 		{
-			$output .= "\n\n<table style='width:100%; border:none'>\n";
+			$output .= "\n\n<table style=\"width:100%;border:none;\">\n";
 
 			foreach ($_GET as $key => $val)
 			{
@@ -269,9 +267,10 @@
 					$key = "'".$key."'";
 				}
 
-				$output .= "<tr><td style='width:50%;color:#000;background-color:#ddd;padding:5px'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;'>"
-					. ((is_array($val) OR is_object($val)) ? "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>" : htmlspecialchars(stripslashes($val)))
-					. "</td></tr>\n";
+				$output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">&#36;_GET['
+					.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">'
+					.((is_array($val) OR is_object($val)) ? '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>' : htmlspecialchars(stripslashes($val)))
+					."</td></tr>\n";
 			}
 
 			$output .= "</table>\n";
@@ -290,18 +289,17 @@
 	protected function _compile_post()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>'
-			. "\n";
+			.'<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data')."&nbsp;&nbsp;</legend>\n";
 
 		if (count($_POST) == 0)
 		{
-			$output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
+			$output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>';
 		}
 		else
 		{
-			$output .= "\n\n<table style='width:100%'>\n";
+			$output .= "\n\n<table style=\"width:100%;\">\n";
 
 			foreach ($_POST as $key => $val)
 			{
@@ -310,15 +308,18 @@
 					$key = "'".$key."'";
 				}
 
-				$output .= "<tr><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;'>";
+				$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_POST['
+					.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
+
 				if (is_array($val) OR is_object($val))
 				{
-					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>";
+					$output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
 				}
 				else
 				{
 					$output .= htmlspecialchars(stripslashes($val));
 				}
+
 				$output .= "</td></tr>\n";
 			}
 
@@ -338,12 +339,12 @@
 	protected function _compile_uri_string()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>"
-			. ($this->CI->uri->uri_string == '' ? $this->CI->lang->line('profiler_no_uri') : $this->CI->uri->uri_string)
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#000;font-weight:normal;padding:4px 0 4px 0;">'
+			.($this->CI->uri->uri_string == '' ? $this->CI->lang->line('profiler_no_uri') : $this->CI->uri->uri_string)
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -356,11 +357,11 @@
 	protected function _compile_controller_info()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class().'/'.$this->CI->router->fetch_method()
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#995300;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->router->fetch_class().'/'.$this->CI->router->fetch_method()
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -375,12 +376,12 @@
 	protected function _compile_memory_usage()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>"
-			. ((function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') ? number_format($usage).' bytes' : $this->CI->lang->line('profiler_no_memory'))
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#5a0099;font-weight:normal;padding:4px 0 4px 0;">'
+			.((function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') ? number_format($usage).' bytes' : $this->CI->lang->line('profiler_no_memory'))
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -395,15 +396,17 @@
 	protected function _compile_http_headers()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "\n\n\n<table style='width:100%;display:none' id='ci_profiler_httpheaders_table'>\n";
+			.'<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers')
+			.'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n"
+			.'<table style="width:100%;display:none;" id="ci_profiler_httpheaders_table">'."\n";
 
 		foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
 		{
-			$val = (isset($_SERVER[$header])) ? $_SERVER[$header] : '';
-			$output .= "<tr><td style='vertical-align: top;width:50%;padding:5px;color:#900;background-color:#ddd;'>".$header."&nbsp;&nbsp;</td><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>".$val."</td></tr>\n";
+			$val = isset($_SERVER[$header]) ? $_SERVER[$header] : '';
+			$output .= '<tr><td style="vertical-align:top;width:50%;padding:5px;color:#900;background-color:#ddd;">'
+				.$header.'&nbsp;&nbsp;</td><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">'.$val."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -421,10 +424,10 @@
 	protected function _compile_config()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_config_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "\n\n\n<table style='width:100%; display:none' id='ci_profiler_config_table'>\n";
+			.'<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_config_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n"
+			.'<table style="width:100%;display:none;" id="ci_profiler_config_table">'."\n";
 
 		foreach ($this->CI->config->config as $config => $val)
 		{
@@ -433,7 +436,8 @@
 				$val = print_r($val, TRUE);
 			}
 
-			$output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$config."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
+				.$config.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val)."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -453,9 +457,9 @@
 			return;
 		}
 
-		$output = '<fieldset id="ci_profiler_csession" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "<table style='width:100%;display:none' id='ci_profiler_session_data'>";
+		$output = '<fieldset id="ci_profiler_csession" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
+			.'<table style="width:100%;display:none;" id="ci_profiler_session_data">';
 
 		foreach ($this->CI->session->all_userdata() as $key => $val)
 		{
@@ -464,7 +468,8 @@
 				$val = print_r($val, TRUE);
 			}
 
-			$output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
+				.$key.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val)."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -479,14 +484,14 @@
 	 */
 	public function run()
 	{
-		$output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";
+		$output = '<div id="codeigniter_profiler" style="clear:both;background-color:#fff;padding:10px;">';
 		$fields_displayed = 0;
 
 		foreach ($this->_available_sections as $section)
 		{
 			if ($this->_compile_{$section} !== FALSE)
 			{
-				$func = "_compile_{$section}";
+				$func = '_compile_'.$section;
 				$output .= $this->{$func}();
 				$fields_displayed++;
 			}
@@ -494,7 +499,8 @@
 
 		if ($fields_displayed === 0)
 		{
-			$output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee">'.$this->CI->lang->line('profiler_no_profiles').'</p>';
+			$output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee;">'
+				.$this->CI->lang->line('profiler_no_profiles').'</p>';
 		}
 
 		return $output.'</div>';
@@ -502,4 +508,4 @@
 }
 
 /* End of file Profiler.php */
-/* Location: ./system/libraries/Profiler.php */
+/* Location: ./system/libraries/Profiler.php */
\ No newline at end of file
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 104b888..3515764 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -48,6 +48,7 @@
 	public $cookie_path			= '';
 	public $cookie_domain			= '';
 	public $cookie_secure			= FALSE;
+	public $cookie_httponly 		= FALSE;
 	public $sess_time_to_update		= 300;
 	public $encryption_key			= '';
 	public $flashdata_key			= 'flash';
@@ -72,7 +73,7 @@
 
 		// Set all the session preferences, which can either be set
 		// manually via the $params array above or via the config file
-		foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
+		foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'cookie_httponly', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
 		{
 			$this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
 		}
@@ -469,6 +470,29 @@
 		return $this->userdata;
 	}
 
+	// --------------------------------------------------------------------------
+
+	/**
+	 * Fetch all flashdata
+	 *
+	 * @return	array
+	 */
+	public function all_flashdata()
+	{
+		$out = array();
+
+		// loop through all userdata
+		foreach ($this->all_userdata() as $key => $val)
+		{
+			// if it contains flashdata, add it
+			if (strpos($key, 'flash:old:') !== FALSE)
+			{
+				$out[$key] = $val;
+			}
+		}
+		return $out;
+	}
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -666,13 +690,14 @@
 
 		// 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,
+			$this->cookie_httponly
+		);
 	}
 
 	// --------------------------------------------------------------------
@@ -791,4 +816,4 @@
 }
 
 /* End of file Session.php */
-/* Location: ./system/libraries/Session.php */
+/* Location: ./system/libraries/Session.php */
\ No newline at end of file
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index fb154e5..3777d29 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * HTML Table Generating Class
  *
@@ -40,18 +38,30 @@
  */
 class CI_Table {
 
-	public $rows			= array();
-	public $heading			= array();
-	public $auto_heading		= TRUE;
-	public $caption			= NULL;
-	public $template		= NULL;
-	public $newline			= "\n";
-	public $empty_cells		= '';
-	public $function		= FALSE;
+	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()
+	/**
+	 * Set the template from the table config file if it exists
+	 *
+	 * @param	array	$config	(default: array())
+	 * @return	void
+	 */
+	public function __construct($config = array())
 	{
-		log_message('debug', "Table Class Initialized");
+		// initialize config
+		foreach ($config as $key => $val)
+		{
+			$this->template[$key] = $val;
+		}
+
+		log_message('debug', 'Table Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -60,7 +70,7 @@
 	 * Set the template
 	 *
 	 * @param	array
-	 * @return	void
+	 * @return	bool
 	 */
 	public function set_template($template)
 	{
@@ -70,6 +80,7 @@
 		}
 
 		$this->template = $template;
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -91,9 +102,9 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set columns.  Takes a one-dimensional array as input and creates
+	 * Set columns. Takes a one-dimensional array as input and creates
 	 * a multi-dimensional array with a depth equal to the number of
-	 * columns.  This allows a single array with many elements to  be
+	 * columns. This allows a single array with many elements to be
 	 * displayed in a table that has a fixed column count.
 	 *
 	 * @param	array
@@ -102,7 +113,7 @@
 	 */
 	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 OR ! is_int($col_limit))
 		{
 			return FALSE;
 		}
@@ -174,29 +185,22 @@
 	 *
 	 * Ensures a standard associative array format for all cell data
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	array
 	 */
 	protected function _prep_args($args)
 	{
 		// If there is no $args[0], skip this and treat as an associative array
 		// This can happen if there is only a single key, for example this is passed to table->generate
 		// array(array('foo'=>'bar'))
-		if (isset($args[0]) AND (count($args) === 1 && is_array($args[0])))
+		if (isset($args[0]) && count($args) === 1 && is_array($args[0]))
 		{
 			// args sent as indexed array
 			if ( ! isset($args[0]['data']))
 			{
 				foreach ($args[0] as $key => $val)
 				{
-					if (is_array($val) && isset($val['data']))
-					{
-						$args[$key] = $val;
-					}
-					else
-					{
-						$args[$key] = array('data' => $val);
-					}
+					$args[$key] = (is_array($val) && isset($val['data'])) ? $val : array('data' => $val);
 				}
 			}
 		}
@@ -247,13 +251,13 @@
 			}
 			elseif (is_array($table_data))
 			{
-				$set_heading = (count($this->heading) === 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
+				$set_heading = (count($this->heading) !== 0 OR $this->auto_heading != FALSE);
 				$this->_set_from_array($table_data, $set_heading);
 			}
 		}
 
-		// Is there anything to display?  No?  Smite them!
-		if (count($this->heading) === 0 AND count($this->rows) === 0)
+		// Is there anything to display? No? Smite them!
+		if (count($this->heading) === 0 && count($this->rows) === 0)
 		{
 			return 'Undefined table data';
 		}
@@ -287,7 +291,7 @@
 				{
 					if ($key != 'data')
 					{
-						$temp = str_replace('<th', "<th $key='$val'", $temp);
+						$temp = str_replace('<th', '<th '.$key.'="'.$val.'"', $temp);
 					}
 				}
 
@@ -311,7 +315,7 @@
 				}
 
 				// We use modulus to alternate the row colors
-				$name = (fmod($i++, 2)) ? '' : 'alt_';
+				$name = fmod($i++, 2) ? '' : 'alt_';
 
 				$out .= $this->template['row_'.$name.'start'].$this->newline;
 
@@ -323,27 +327,24 @@
 					{
 						if ($key !== 'data')
 						{
-							$temp = str_replace('<td', "<td $key='$val'", $temp);
+							$temp = str_replace('<td', '<td '.$key.'="'.$val.'"', $temp);
 						}
 					}
 
 					$cell = isset($cell['data']) ? $cell['data'] : '';
 					$out .= $temp;
 
-					if ($cell === "" OR $cell === NULL)
+					if ($cell === '' OR $cell === NULL)
 					{
 						$out .= $this->empty_cells;
 					}
+					elseif ($function !== FALSE && is_callable($function))
+					{
+						$out .= call_user_func($function, $cell);
+					}
 					else
 					{
-						if ($function !== FALSE && is_callable($function))
-						{
-							$out .= call_user_func($function, $cell);
-						}
-						else
-						{
-							$out .= $cell;
-						}
+						$out .= $cell;
 					}
 
 					$out .= $this->template['cell_'.$name.'end'];
@@ -372,9 +373,9 @@
 	 */
 	public function clear()
 	{
-		$this->rows				= array();
-		$this->heading			= array();
-		$this->auto_heading		= TRUE;
+		$this->rows		= array();
+		$this->heading		= array();
+		$this->auto_heading	= TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -389,22 +390,21 @@
 	{
 		if ( ! is_object($query))
 		{
-			return FALSE;
+			return;
 		}
 
 		// First generate the headings from the table column names
 		if (count($this->heading) === 0)
 		{
-			if ( ! method_exists($query, 'list_fields'))
+			if ( ! is_callable(array($query, 'list_fields')))
 			{
-				return FALSE;
+				return;
 			}
 
 			$this->heading = $this->_prep_args($query->list_fields());
 		}
 
 		// Next blast through the result array and build out the rows
-
 		if ($query->num_rows() > 0)
 		{
 			foreach ($query->result_array() as $row)
@@ -433,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 && count($data) > 1 && count($this->heading) === 0 && $set_heading == TRUE)
 			{
 				$this->heading = $this->_prep_args($row);
 			}
@@ -478,36 +478,35 @@
 	 */
 	protected function _default_template()
 	{
-		return  array (
-						'table_open'			=> '<table border="0" cellpadding="4" cellspacing="0">',
+		return  array(
+				'table_open'		=> '<table border="0" cellpadding="4" cellspacing="0">',
 
-						'thead_open'			=> '<thead>',
-						'thead_close'			=> '</thead>',
+				'thead_open'		=> '<thead>',
+				'thead_close'		=> '</thead>',
 
-						'heading_row_start'		=> '<tr>',
-						'heading_row_end'		=> '</tr>',
-						'heading_cell_start'	=> '<th>',
-						'heading_cell_end'		=> '</th>',
+				'heading_row_start'	=> '<tr>',
+				'heading_row_end'	=> '</tr>',
+				'heading_cell_start'	=> '<th>',
+				'heading_cell_end'	=> '</th>',
 
-						'tbody_open'			=> '<tbody>',
-						'tbody_close'			=> '</tbody>',
+				'tbody_open'		=> '<tbody>',
+				'tbody_close'		=> '</tbody>',
 
-						'row_start'				=> '<tr>',
-						'row_end'				=> '</tr>',
-						'cell_start'			=> '<td>',
-						'cell_end'				=> '</td>',
+				'row_start'		=> '<tr>',
+				'row_end'		=> '</tr>',
+				'cell_start'		=> '<td>',
+				'cell_end'		=> '</td>',
 
-						'row_alt_start'		=> '<tr>',
-						'row_alt_end'			=> '</tr>',
-						'cell_alt_start'		=> '<td>',
-						'cell_alt_end'			=> '</td>',
+				'row_alt_start'		=> '<tr>',
+				'row_alt_end'		=> '</tr>',
+				'cell_alt_start'	=> '<td>',
+				'cell_alt_end'		=> '</td>',
 
-						'table_close'			=> '</table>'
-					);
+				'table_close'		=> '</table>'
+			);
 	}
 
-
 }
 
 /* End of file Table.php */
-/* Location: ./system/libraries/Table.php */
+/* Location: ./system/libraries/Table.php */
\ No newline at end of file
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 79a0091..6761f63 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Trackback Class
  *
@@ -49,7 +47,7 @@
 
 	public function __construct()
 	{
-		log_message('debug', "Trackback Class Initialized");
+		log_message('debug', 'Trackback Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -97,9 +95,10 @@
 		}
 
 		// Build the Trackback data string
-		$charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];
+		$charset = isset($tb_data['charset']) ? $tb_data['charset'] : $this->charset;
 
-		$data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);
+		$data = 'url='.rawurlencode($url).'&title='.rawurlencode($title).'&blog_name='.rawurlencode($blog_name)
+			.'&excerpt='.rawurlencode($excerpt).'&charset='.rawurlencode($charset);
 
 		// Send Trackback(s)
 		$return = TRUE;
@@ -139,9 +138,9 @@
 				return FALSE;
 			}
 
-			$this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));
+			$this->data['charset'] = isset($_POST['charset']) ? strtoupper(trim($_POST['charset'])) : 'auto';
 
-			if ($val != 'url' && function_exists('mb_convert_encoding'))
+			if ($val != 'url' && MB_ENABLED === TRUE)
 			{
 				$_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
 			}
@@ -164,7 +163,7 @@
 	/**
 	 * Send Trackback Error Message
 	 *
-	 * Allows custom errors to be set.  By default it
+	 * Allows custom errors to be set. By default it
 	 * sends the "incomplete information" error, as that's
 	 * the most common one.
 	 *
@@ -173,7 +172,7 @@
 	 */
 	public function send_error($message = 'Incomplete Information')
 	{
-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
+		echo '<?xml version="1.0" encoding="utf-8"?'.">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
 		exit;
 	}
 
@@ -189,7 +188,7 @@
 	 */
 	public function send_success()
 	{
-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";
+		echo '<?xml version="1.0" encoding="utf-8"?'.">\n<response>\n<error>0</error>\n</response>";
 		exit;
 	}
 
@@ -203,7 +202,7 @@
 	 */
 	public function data($item)
 	{
-		return ( ! isset($this->data[$item])) ? '' : $this->data[$item];
+		return isset($this->data[$item]) ? $this->data[$item] : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -212,7 +211,7 @@
 	 * Process Trackback
 	 *
 	 * Opens a socket connection and passes the data to
-	 * the server.  Returns TRUE on success, FALSE on failure
+	 * the server. Returns TRUE on success, FALSE on failure
 	 *
 	 * @param	string
 	 * @param	string
@@ -230,37 +229,36 @@
 		}
 
 		// Build the path
-		$ppath = ( ! isset($target['path'])) ? $url : $target['path'];
+		$ppath = isset($target['path']) ? $target['path'] : $url;
 
-		$path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;
+		$path = empty($target['query']) ? $ppath : $ppath.'?'.$target['query'];
 
 		// Add the Trackback ID to the data string
 		if ($id = $this->get_id($url))
 		{
-			$data = "tb_id=".$id."&".$data;
+			$data = 'tb_id='.$id.'&'.$data;
 		}
 
 		// Transfer the data
-		fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );
-		fputs ($fp, "Host: " . $target['host'] . "\r\n" );
-		fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );
-		fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );
-		fputs ($fp, "Connection: close\r\n\r\n" );
-		fputs ($fp, $data);
+		fputs($fp, 'POST '.$path." HTTP/1.0\r\n");
+		fputs($fp, 'Host: '.$target['host']."\r\n");
+		fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
+		fputs($fp, 'Content-length: '.strlen($data)."\r\n");
+		fputs($fp, "Connection: close\r\n\r\n");
+		fputs($fp, $data);
 
 		// Was it successful?
-		$this->response = "";
 
+		$this->response = '';
 		while ( ! feof($fp))
 		{
 			$this->response .= fgets($fp, 128);
 		}
 		@fclose($fp);
 
-
 		if (stripos($this->response, '<error>0</error>') === FALSE)
 		{
-			$message = (preg_match('/<message>(.*?)<\/message>/is', $this->response, $match)) ? trim($match[1]) : 'An unknown error was encountered';
+			$message = preg_match('/<message>(.*?)<\/message>/is', $this->response, $match) ? trim($match[1]) : 'An unknown error was encountered';
 			$this->set_error($message);
 			return FALSE;
 		}
@@ -282,11 +280,8 @@
 	 */
 	public function extract_urls($urls)
 	{
-		// Remove the pesky white space and replace with a comma.
-		$urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);
-
-		// If they use commas get rid of the doubles.
-		$urls = str_replace(",,", ",", $urls);
+		// Remove the pesky white space and replace with a comma, then replace doubles.
+		$urls = str_replace(',,', ',', preg_replace('/\s*(\S+)\s*/', '\\1,', $urls));
 
 		// Remove any comma that might be at the end
 		if (substr($urls, -1) === ',')
@@ -294,11 +289,8 @@
 			$urls = substr($urls, 0, -1);
 		}
 
-		// Break into an array via commas
-		$urls = preg_split('/[,]/', $urls);
-
-		// Removes duplicates
-		$urls = array_unique($urls);
+		// Break into an array via commas and remove duplicates
+		$urls = array_unique(preg_split('/[,]/', $urls));
 
 		array_walk($urls, array($this, 'validate_url'));
 
@@ -313,9 +305,9 @@
 	 * Simply adds "http://" if missing
 	 *
 	 * @param	string
-	 * @return	string
+	 * @return	void
 	 */
-	public function validate_url($url)
+	public function validate_url(&$url)
 	{
 		$url = trim($url);
 
@@ -335,7 +327,7 @@
 	 */
 	public function get_id($url)
 	{
-		$tb_id = "";
+		$tb_id = '';
 
 		if (strpos($url, '?') !== FALSE)
 		{
@@ -359,18 +351,11 @@
 
 			if ( ! is_numeric($tb_id))
 			{
-				$tb_id  = $tb_array[count($tb_array)-2];
+				$tb_id = $tb_array[count($tb_array)-2];
 			}
 		}
 
-		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
-		{
-			return FALSE;
-		}
-		else
-		{
-			return $tb_id;
-		}
+		return preg_match('/^[0-9]+$/', $tb_id) ? $tb_id : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -385,15 +370,13 @@
 	{
 		$temp = '__TEMP_AMPERSANDS__';
 
-		$str = preg_replace(array('/&#(\d+);/', '/&(\w+);/'), "$temp\\1;", $str);
+		$str = preg_replace(array('/&#(\d+);/', '/&(\w+);/'), $temp.'\\1;', $str);
 
-		$str = str_replace(array("&","<",">","\"", "'", "-"),
-							array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
-							$str);
+		$str = str_replace(array('&', '<', '>', '"', "'", '-'),
+					array('&amp;', '&lt;', '&gt;', '&quot;', '&#39;', '&#45;'),
+					$str);
 
-		$str = preg_replace(array("/$temp(\d+);/", "/$temp(\w+);/"), array('&#\\1;', '&\\1;'), $str);
-
-		return $str;
+		return preg_replace(array('/'.$temp.'(\d+);/', '/'.$temp.'(\w+);/'), array('&#\\1;', '&\\1;'), $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -404,7 +387,7 @@
 	 * Limits the string based on the character count. Will preserve complete words.
 	 *
 	 * @param	string
-	 * @param	integer
+	 * @param	int
 	 * @param	string
 	 * @return	string
 	 */
@@ -415,7 +398,7 @@
 			return $str;
 		}
 
-		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+		$str = preg_replace('/\s+/', ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
 
 		if (strlen($str) <= $n)
 		{
@@ -469,7 +452,9 @@
 
 				if (count($temp) === $count)
 				{
-					$number = ($count == 3) ? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64) : (($temp[0] % 32) * 64) + ($temp[1] % 64);
+					$number = ($count === 3)
+						? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
+						: (($temp[0] % 32) * 64) + ($temp[1] % 64);
 
 					$out .= '&#'.$number.';';
 					$count = 1;
@@ -506,11 +491,10 @@
 	 */
 	public function display_errors($open = '<p>', $close = '</p>')
 	{
-		return (count($this->error_msg) > 0) ? $open . implode($close . $open, $this->error_msg) . $close : '';
+		return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
 	}
 
 }
-// END Trackback Class
 
 /* End of file Trackback.php */
-/* Location: ./system/libraries/Trackback.php */
+/* Location: ./system/libraries/Trackback.php */
\ No newline at end of file
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index 46c73ef..21bbad0 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,13 +25,11 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Typography Class
  *
- *
- * @access		protected
+ * @package		CodeIgniter
+ * @subpackage	Libraries
  * @category	Helpers
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/typography.html
@@ -67,7 +65,6 @@
 	 *	- Converts double dashes into em-dashes.
 	 *  - Converts two spaces into entities
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether to reduce more then two consecutive newlines to two
 	 * @return	string
@@ -94,15 +91,12 @@
 
 		// HTML comment tags don't conform to patterns of normal tags, so pull them out separately, only if needed
 		$html_comments = array();
-		if (strpos($str, '<!--') !== FALSE)
+		if (strpos($str, '<!--') !== FALSE && preg_match_all('#(<!\-\-.*?\-\->)#s', $str, $matches))
 		{
-			if (preg_match_all("#(<!\-\-.*?\-\->)#s", $str, $matches))
+			for ($i = 0, $total = count($matches[0]); $i < $total; $i++)
 			{
-				for ($i = 0, $total = count($matches[0]); $i < $total; $i++)
-				{
-					$html_comments[] = $matches[0][$i];
-					$str = str_replace($matches[0][$i], '{@HC'.$i.'}', $str);
-				}
+				$html_comments[] = $matches[0][$i];
+				$str = str_replace($matches[0][$i], '{@HC'.$i.'}', $str);
 			}
 		}
 
@@ -110,22 +104,22 @@
 		// not contain <pre> tags, and it keeps the PCRE patterns below simpler and faster
 		if (strpos($str, '<pre') !== FALSE)
 		{
-			$str = preg_replace_callback("#<pre.*?>.*?</pre>#si", array($this, '_protect_characters'), $str);
+			$str = preg_replace_callback('#<pre.*?>.*?</pre>#si', array($this, '_protect_characters'), $str);
 		}
 
 		// Convert quotes within tags to temporary markers.
-		$str = preg_replace_callback("#<.+?>#si", array($this, '_protect_characters'), $str);
+		$str = preg_replace_callback('#<.+?>#si', array($this, '_protect_characters'), $str);
 
 		// Do the same with braces if necessary
 		if ($this->protect_braced_quotes === TRUE)
 		{
-			$str = preg_replace_callback("#\{.+?\}#si", array($this, '_protect_characters'), $str);
+			$str = preg_replace_callback('#\{.+?\}#si', array($this, '_protect_characters'), $str);
 		}
 
 		// Convert "ignore" tags to temporary marker.  The parser splits out the string at every tag
 		// it encounters.  Certain inline tags, like image tags, links, span tags, etc. will be
 		// 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);
+		$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:
 		 *
@@ -148,9 +142,9 @@
 		{
 			// 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.").*?>#", $chunks[$i], $match))
+			if (preg_match('#<(/*)('.$this->block_elements.').*?>#', $chunks[$i], $match))
 			{
-				if (preg_match("#".$this->skip_elements."#", $match[2]))
+				if (preg_match('#'.$this->skip_elements.'#', $match[2]))
 				{
 					$process = ($match[1] === '/');
 				}
@@ -180,10 +174,10 @@
 			$str .= $this->_format_newlines($chunks[$i]);
 		}
 
-		// No opening block level tag?  Add it if needed.
-		if ( ! preg_match("/^\s*<(?:".$this->block_elements.")/i", $str))
+		// No opening block level tag? Add it if needed.
+		if ( ! preg_match('/^\s*<(?:'.$this->block_elements.')/i', $str))
 		{
-			$str = preg_replace("/^(.*?)<(".$this->block_elements.")/i", '<p>$1</p><$2', $str);
+			$str = preg_replace('/^(.*?)<('.$this->block_elements.')/i', '<p>$1</p><$2', $str);
 		}
 
 		// Convert quotes, elipsis, em-dashes, non-breaking spaces, and ampersands
@@ -230,7 +224,7 @@
 
 						// Similarly, there might be cases where a closing </block> will follow
 						// a closing </p> tag, so we'll correct it by adding a newline in between
-						"#</p></#"			=> "</p>\n</"
+						'#</p></#'			=> "</p>\n</"
 						);
 
 		// Do we need to reduce empty lines?
@@ -258,7 +252,6 @@
 	 * to curly entities, but it also converts em-dashes,
 	 * double spaces, and ampersands
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -322,13 +315,12 @@
 	 *
 	 * Converts newline characters into either <p> tags or <br />
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @return	string
 	 */
 	protected function _format_newlines($str)
 	{
-		if ($str == '' OR (strpos($str, "\n") === FALSE AND ! in_array($this->last_block_element, $this->inner_block_required)))
+		if ($str == '' OR (strpos($str, "\n") === FALSE && ! in_array($this->last_block_element, $this->inner_block_required)))
 		{
 			return $str;
 		}
@@ -337,7 +329,7 @@
 		$str = str_replace("\n\n", "</p>\n\n<p>", $str);
 
 		// Convert single spaces to <br /> tags
-		$str = preg_replace("/([^\n])(\n)([^\n])/", "\\1<br />\\2\\3", $str);
+		$str = preg_replace("/([^\n])(\n)([^\n])/", '\\1<br />\\2\\3', $str);
 
 		// Wrap the whole enchilada in enclosing paragraphs
 		if ($str != "\n")
@@ -350,9 +342,7 @@
 
 		// Remove empty paragraphs if they are on the first line, as this
 		// is a potential unintended consequence of the previous code
-		$str = preg_replace("/<p><\/p>(.*)/", "\\1", $str, 1);
-
-		return $str;
+		return preg_replace('/<p><\/p>(.*)/', '\\1', $str, 1);
 	}
 
 	// ------------------------------------------------------------------------
@@ -365,7 +355,6 @@
 	 * 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	protected
 	 * @param	array
 	 * @return	string
 	 */
@@ -379,7 +368,6 @@
 	/**
 	 * Convert newlines to HTML line breaks except within PRE tags
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -399,7 +387,6 @@
 	}
 
 }
-// END Typography Class
 
 /* End of file Typography.php */
-/* Location: ./system/libraries/Typography.php */
+/* Location: ./system/libraries/Typography.php */
\ No newline at end of file
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 38d767c..0f6e2df 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Unit Testing Class
  *
@@ -60,7 +58,7 @@
 							'notes'
 						);
 
-		log_message('debug', "Unit Testing Class Initialized");
+		log_message('debug', 'Unit Testing Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -75,7 +73,7 @@
 	 */
 	public function set_test_items($items = array())
 	{
-		if ( ! empty($items) AND is_array($items))
+		if ( ! empty($items) && is_array($items))
 		{
 			$this->_test_items_visible = $items;
 		}
@@ -102,8 +100,8 @@
 
 		if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
 		{
-			$expected = str_replace('is_float', 'is_double', $expected);
-			$result = ($expected($test)) ? TRUE : FALSE;
+			$expected = str_replace('is_double', 'is_float', $expected);
+			$result = $expected($test);
 			$extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));
 		}
 		else
@@ -186,7 +184,7 @@
 	 * Causes the evaluation to use === rather than ==
 	 *
 	 * @param	bool
-	 * @return	null
+	 * @return	void
 	 */
 	public function use_strict($state = TRUE)
 	{
@@ -201,7 +199,7 @@
 	 * Enables/disables unit testing
 	 *
 	 * @param	bool
-	 * @return	null
+	 * @return	void
 	 */
 	public function active($state = TRUE)
 	{
@@ -311,10 +309,10 @@
 	 */
 	protected function _default_template()
 	{
-		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">{rows}'."\n".'</table>';
+		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">{rows}'."\n</table>";
 
 		$this->_template_rows = "\n\t<tr>\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>'
-					. "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'."\n\t</tr>";
+					."\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'."\n\t</tr>";
 	}
 
 	// --------------------------------------------------------------------
@@ -333,7 +331,7 @@
 			return;
 		}
 
-		if (is_null($this->_template) OR ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
+		if (is_null($this->_template) OR ! preg_match('/\{rows\}(.*?)\{\/rows\}/si', $this->_template, $match))
 		{
 			$this->_default_template();
 			return;
@@ -344,7 +342,6 @@
 	}
 
 }
-// END Unit_test Class
 
 /**
  * Helper functions to test boolean true/false
@@ -353,13 +350,12 @@
  */
 function is_true($test)
 {
-	return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
+	return (is_bool($test) && $test === TRUE);
 }
 function is_false($test)
 {
-	return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
+	return (is_bool($test) && $test === FALSE);
 }
 
-
 /* End of file Unit_test.php */
-/* Location: ./system/libraries/Unit_test.php */
+/* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 89575c8..8ad6705 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * File Uploading Class
  *
@@ -38,39 +36,40 @@
  */
 class CI_Upload {
 
-	public $max_size				= 0;
-	public $max_width				= 0;
-	public $max_height				= 0;
-	public $max_filename			= 0;
+	public $max_size		= 0;
+	public $max_width		= 0;
+	public $max_height		= 0;
+	public $max_filename		= 0;
 	public $max_filename_increment 	= 100;
-	public $allowed_types			= "";
-	public $file_temp				= "";
-	public $file_name				= "";
-	public $orig_name				= "";
-	public $file_type				= "";
-	public $file_size				= "";
-	public $file_ext				= "";
-	public $upload_path				= "";
-	public $overwrite				= FALSE;
-	public $encrypt_name			= FALSE;
-	public $is_image				= FALSE;
-	public $image_width				= '';
-	public $image_height			= '';
-	public $image_type				= '';
-	public $image_size_str			= '';
-	public $error_msg				= array();
-	public $mimes					= array();
-	public $remove_spaces			= TRUE;
-	public $xss_clean				= FALSE;
-	public $temp_prefix				= "temp_file_";
-	public $client_name				= '';
+	public $allowed_types		= '';
+	public $file_temp		= '';
+	public $file_name		= '';
+	public $orig_name		= '';
+	public $file_type		= '';
+	public $file_size		= '';
+	public $file_ext		= '';
+	public $upload_path		= '';
+	public $overwrite		= FALSE;
+	public $encrypt_name		= FALSE;
+	public $is_image		= FALSE;
+	public $image_width		= '';
+	public $image_height		= '';
+	public $image_type		= '';
+	public $image_size_str		= '';
+	public $error_msg		= array();
+	public $mimes			= array();
+	public $remove_spaces		= TRUE;
+	public $xss_clean		= FALSE;
+	public $temp_prefix		= 'temp_file_';
+	public $client_name		= '';
 
 	protected $_file_name_override	= '';
 
 	/**
 	 * Constructor
 	 *
-	 * @access	public
+	 * @param	array
+	 * @return	void
 	 */
 	public function __construct($props = array())
 	{
@@ -79,7 +78,7 @@
 			$this->initialize($props);
 		}
 
-		log_message('debug', "Upload Class Initialized");
+		log_message('debug', 'Upload Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -93,33 +92,33 @@
 	public function initialize($config = array())
 	{
 		$defaults = array(
-							'max_size'					=> 0,
-							'max_width'					=> 0,
-							'max_height'				=> 0,
-							'max_filename'				=> 0,
-							'max_filename_increment'	=> 100,
-							'allowed_types'				=> "",
-							'file_temp'					=> "",
-							'file_name'					=> "",
-							'orig_name'					=> "",
-							'file_type'					=> "",
-							'file_size'					=> "",
-							'file_ext'					=> "",
-							'upload_path'				=> "",
-							'overwrite'					=> FALSE,
-							'encrypt_name'				=> FALSE,
-							'is_image'					=> FALSE,
-							'image_width'				=> '',
-							'image_height'				=> '',
-							'image_type'				=> '',
-							'image_size_str'			=> '',
-							'error_msg'					=> array(),
-							'mimes'						=> array(),
-							'remove_spaces'				=> TRUE,
-							'xss_clean'					=> FALSE,
-							'temp_prefix'				=> "temp_file_",
-							'client_name'				=> ''
-						);
+					'max_size'			=> 0,
+					'max_width'			=> 0,
+					'max_height'			=> 0,
+					'max_filename'			=> 0,
+					'max_filename_increment'	=> 100,
+					'allowed_types'			=> '',
+					'file_temp'			=> '',
+					'file_name'			=> '',
+					'orig_name'			=> '',
+					'file_type'			=> '',
+					'file_size'			=> '',
+					'file_ext'			=> '',
+					'upload_path'			=> '',
+					'overwrite'			=> FALSE,
+					'encrypt_name'			=> FALSE,
+					'is_image'			=> FALSE,
+					'image_width'			=> '',
+					'image_height'			=> '',
+					'image_type'			=> '',
+					'image_size_str'		=> '',
+					'error_msg'			=> array(),
+					'mimes'				=> array(),
+					'remove_spaces'			=> TRUE,
+					'xss_clean'			=> FALSE,
+					'temp_prefix'			=> 'temp_file_',
+					'client_name'			=> ''
+				);
 
 
 		foreach ($defaults as $key => $val)
@@ -156,8 +155,7 @@
 	 */
 	public function do_upload($field = 'userfile')
 	{
-
-	// Is $_FILES[$field] set? If not, no reason to continue.
+		// Is $_FILES[$field] set? If not, no reason to continue.
 		if ( ! isset($_FILES[$field]))
 		{
 			$this->set_error('upload_no_file_selected');
@@ -176,7 +174,7 @@
 		{
 			$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
 
-			switch($error)
+			switch ($error)
 			{
 				case 1:	// UPLOAD_ERR_INI_SIZE
 					$this->set_error('upload_file_exceeds_limit');
@@ -199,19 +197,19 @@
 				case 8: // UPLOAD_ERR_EXTENSION
 					$this->set_error('upload_stopped_by_extension');
 					break;
-				default :   $this->set_error('upload_no_file_selected');
+				default:
+					$this->set_error('upload_no_file_selected');
 					break;
 			}
 
 			return FALSE;
 		}
 
-
 		// Set the uploaded data as class variables
 		$this->file_temp = $_FILES[$field]['tmp_name'];
 		$this->file_size = $_FILES[$field]['size'];
 		$this->_file_mime_type($_FILES[$field]);
-		$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $this->file_type);
+		$this->file_type = preg_replace('/^(.+?);.*$/', '\\1', $this->file_type);
 		$this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
 		$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
 		$this->file_ext	 = $this->get_extension($this->file_name);
@@ -234,11 +232,10 @@
 			{
 				$this->file_name .= $this->file_ext;
 			}
-
-			// An extension was provided, lets have it!
 			else
 			{
-				$this->file_ext	 = $this->get_extension($this->_file_name_override);
+				// An extension was provided, lets have it!
+				$this->file_ext	= $this->get_extension($this->_file_name_override);
 			}
 
 			if ( ! $this->is_allowed_filetype(TRUE))
@@ -281,7 +278,7 @@
 		// Remove white spaces in the name
 		if ($this->remove_spaces == TRUE)
 		{
-			$this->file_name = preg_replace("/\s+/", "_", $this->file_name);
+			$this->file_name = preg_replace('/\s+/', '_', $this->file_name);
 		}
 
 		/*
@@ -305,23 +302,20 @@
 		/*
 		 * Run the file through the XSS hacking filter
 		 * This helps prevent malicious code from being
-		 * embedded within a file.  Scripts can easily
+		 * embedded within a file. Scripts can easily
 		 * be disguised as images or other file types.
 		 */
-		if ($this->xss_clean)
+		if ($this->xss_clean && $this->do_xss_clean() === FALSE)
 		{
-			if ($this->do_xss_clean() === FALSE)
-			{
-				$this->set_error('upload_unable_to_write_file');
-				return FALSE;
-			}
+			$this->set_error('upload_unable_to_write_file');
+			return FALSE;
 		}
 
 		/*
 		 * Move the file to the final destination
 		 * To deal with different server configurations
-		 * we'll attempt to use copy() first.  If that fails
-		 * we'll use move_uploaded_file().  One of the two should
+		 * we'll attempt to use copy() first. If that fails
+		 * we'll use move_uploaded_file(). One of the two should
 		 * reliably work in most environments
 		 */
 		if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))
@@ -336,7 +330,7 @@
 		/*
 		 * Set the finalized image dimensions
 		 * This sets the image width/height (assuming the
-		 * file was an image).  We use this information
+		 * file was an image). We use this information
 		 * in the "data" function.
 		 */
 		$this->set_image_properties($this->upload_path.$this->file_name);
@@ -356,22 +350,22 @@
 	 */
 	public function data()
 	{
-		return array (
-						'file_name'			=> $this->file_name,
-						'file_type'			=> $this->file_type,
-						'file_path'			=> $this->upload_path,
-						'full_path'			=> $this->upload_path.$this->file_name,
-						'raw_name'			=> str_replace($this->file_ext, '', $this->file_name),
-						'orig_name'			=> $this->orig_name,
-						'client_name'		=> $this->client_name,
-						'file_ext'			=> $this->file_ext,
-						'file_size'			=> $this->file_size,
-						'is_image'			=> $this->is_image(),
-						'image_width'		=> $this->image_width,
-						'image_height'		=> $this->image_height,
-						'image_type'		=> $this->image_type,
-						'image_size_str'	=> $this->image_size_str,
-					);
+		return array(
+				'file_name'		=> $this->file_name,
+				'file_type'		=> $this->file_type,
+				'file_path'		=> $this->upload_path,
+				'full_path'		=> $this->upload_path.$this->file_name,
+				'raw_name'		=> str_replace($this->file_ext, '', $this->file_name),
+				'orig_name'		=> $this->orig_name,
+				'client_name'		=> $this->client_name,
+				'file_ext'		=> $this->file_ext,
+				'file_size'		=> $this->file_size,
+				'is_image'		=> $this->is_image(),
+				'image_width'		=> $this->image_width,
+				'image_height'		=> $this->image_height,
+				'image_type'		=> $this->image_type,
+				'image_size_str'	=> $this->image_size_str,
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -442,12 +436,12 @@
 	/**
 	 * Set Maximum File Size
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @return	void
 	 */
 	public function set_max_filesize($n)
 	{
-		$this->max_size = ((int) $n < 0) ? 0: (int) $n;
+		$this->max_size = ((int) $n < 0) ? 0 : (int) $n;
 	}
 
 	// --------------------------------------------------------------------
@@ -455,12 +449,12 @@
 	/**
 	 * Set Maximum File Name Length
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @return	void
 	 */
 	public function set_max_filename($n)
 	{
-		$this->max_filename = ((int) $n < 0) ? 0: (int) $n;
+		$this->max_filename = ((int) $n < 0) ? 0 : (int) $n;
 	}
 
 	// --------------------------------------------------------------------
@@ -468,12 +462,12 @@
 	/**
 	 * Set Maximum Image Width
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @return	void
 	 */
 	public function set_max_width($n)
 	{
-		$this->max_width = ((int) $n < 0) ? 0: (int) $n;
+		$this->max_width = ((int) $n < 0) ? 0 : (int) $n;
 	}
 
 	// --------------------------------------------------------------------
@@ -481,12 +475,12 @@
 	/**
 	 * Set Maximum Image Height
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @return	void
 	 */
 	public function set_max_height($n)
 	{
-		$this->max_height = ((int) $n < 0) ? 0: (int) $n;
+		$this->max_height = ((int) $n < 0) ? 0 : (int) $n;
 	}
 
 	// --------------------------------------------------------------------
@@ -499,7 +493,7 @@
 	 */
 	public function set_allowed_types($types)
 	{
-		if ( ! is_array($types) && $types == '*')
+		if ( ! is_array($types) && $types === '*')
 		{
 			$this->allowed_types = '*';
 			return;
@@ -530,10 +524,10 @@
 			{
 				$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
 
-				$this->image_width		= $D['0'];
-				$this->image_height		= $D['1'];
-				$this->image_type		= ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
-				$this->image_size_str	= $D['3'];  // string containing height and width
+				$this->image_width	= $D[0];
+				$this->image_height	= $D[1];
+				$this->image_type	= isset($types[$D[2]]) ? $types[$D[2]] : 'unknown';
+				$this->image_size_str	= $D[3]; // string containing height and width
 			}
 		}
 	}
@@ -551,7 +545,7 @@
 	 */
 	public function set_xss_clean($flag = FALSE)
 	{
-		$this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;
+		$this->xss_clean = ($flag == TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -573,19 +567,14 @@
 		{
 			$this->file_type = 'image/png';
 		}
-
-		if (in_array($this->file_type, $jpeg_mimes))
+		elseif (in_array($this->file_type, $jpeg_mimes))
 		{
 			$this->file_type = 'image/jpeg';
 		}
 
-		$img_mimes = array(
-							'image/gif',
-							'image/jpeg',
-							'image/png',
-						);
+		$img_mimes = array('image/gif',	'image/jpeg', 'image/png');
 
-		return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;
+		return in_array($this->file_type, $img_mimes, TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -631,16 +620,13 @@
 
 		$mime = $this->mimes_types($ext);
 
-		if (is_array($mime))
+		if (is_array($mime) && in_array($this->file_type, $mime, TRUE))
 		{
-			if (in_array($this->file_type, $mime, TRUE))
-			{
-				return TRUE;
-			}
+			return TRUE;
 		}
 		elseif ($mime === $this->file_type)
 		{
-				return TRUE;
+			return TRUE;
 		}
 
 		return FALSE;
@@ -655,14 +641,7 @@
 	 */
 	public function is_allowed_filesize()
 	{
-		if ($this->max_size != 0  AND  $this->file_size > $this->max_size)
-		{
-			return FALSE;
-		}
-		else
-		{
-			return TRUE;
-		}
+		return ($this->max_size == 0 OR $this->max_size > $this->file_size);
 	}
 
 	// --------------------------------------------------------------------
@@ -683,17 +662,15 @@
 		{
 			$D = @getimagesize($this->file_temp);
 
-			if ($this->max_width > 0 AND $D['0'] > $this->max_width)
+			if ($this->max_width > 0 && $D[0] > $this->max_width)
 			{
 				return FALSE;
 			}
 
-			if ($this->max_height > 0 AND $D['1'] > $this->max_height)
+			if ($this->max_height > 0 && $D[1] > $this->max_height)
 			{
 				return FALSE;
 			}
-
-			return TRUE;
 		}
 
 		return TRUE;
@@ -706,7 +683,6 @@
 	 *
 	 * Verifies that it is a valid upload path with proper permissions.
 	 *
-	 *
 	 * @return	bool
 	 */
 	public function validate_upload_path()
@@ -717,9 +693,9 @@
 			return FALSE;
 		}
 
-		if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)
+		if (function_exists('realpath') && @realpath($this->upload_path) !== FALSE)
 		{
-			$this->upload_path = str_replace("\\", "/", realpath($this->upload_path));
+			$this->upload_path = str_replace('\\', '/', realpath($this->upload_path));
 		}
 
 		if ( ! @is_dir($this->upload_path))
@@ -734,7 +710,7 @@
 			return FALSE;
 		}
 
-		$this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/",  $this->upload_path);
+		$this->upload_path = preg_replace('/(.+?)\/*$/', '\\1/',  $this->upload_path);
 		return TRUE;
 	}
 
@@ -763,37 +739,31 @@
 	public function clean_file_name($filename)
 	{
 		$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'		// =
+			);
 
-		$filename = str_replace($bad, '', $filename);
-
-		return stripslashes($filename);
+		return stripslashes(str_replace($bad, '', $filename));
 	}
 
 	// --------------------------------------------------------------------
@@ -847,7 +817,7 @@
 			$current = ini_get('memory_limit') * 1024 * 1024;
 
 			// There was a bug/behavioural change in PHP 5.2, where numbers over one million get output
-			// into scientific notation.  number_format() ensures this number is an integer
+			// into scientific notation. number_format() ensures this number is an integer
 			// http://bugs.php.net/bug.php?id=43053
 
 			$new_memory = number_format(ceil(filesize($file) + $current), 0, '.', '');
@@ -857,8 +827,8 @@
 
 		// If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but
 		// IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone
-		// using IE who looks at the image.  It does this by inspecting the first 255 bytes of an image.  To get around this
-		// CI will itself look at the first 255 bytes of an image to determine its relative safety.  This can save a lot of
+		// using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this
+		// CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of
 		// processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an
 		// attempted XSS attack.
 
@@ -932,7 +902,7 @@
 	 */
 	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 : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -940,7 +910,7 @@
 	/**
 	 * List of Mime Types
 	 *
-	 * This is a list of mime types.  We use it to validate
+	 * This is a list of mime types. We use it to validate
 	 * the "allowed types" set by the developer
 	 *
 	 * @param	string
@@ -952,7 +922,7 @@
 
 		if (count($this->mimes) == 0)
 		{
-			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');
 			}
@@ -966,10 +936,9 @@
 			}
 
 			$this->mimes = $mimes;
-			unset($mimes);
 		}
 
-		return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];
+		return isset($this->mimes[$mime]) ? $this->mimes[$mime] : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1006,9 +975,7 @@
 			}
 		}
 
-		$filename .= '.'.$ext;
-
-		return $filename;
+		return $filename.'.'.$ext;
 	}
 
 	// --------------------------------------------------------------------
@@ -1129,10 +1096,7 @@
 		$this->file_type = $file['type'];
 	}
 
-	// --------------------------------------------------------------------
-
 }
-// END Upload Class
 
 /* End of file Upload.php */
-/* Location: ./system/libraries/Upload.php */
+/* Location: ./system/libraries/Upload.php */
\ No newline at end of file
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index cd644c0..b8e0d37 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * User Agent Class
  *
@@ -74,15 +72,12 @@
 			$this->agent = trim($_SERVER['HTTP_USER_AGENT']);
 		}
 
-		if ( ! is_null($this->agent))
+		if ( ! is_null($this->agent) && $this->_load_agent_file())
 		{
-			if ($this->_load_agent_file())
-			{
-				$this->_compile_data();
-			}
+			$this->_compile_data();
 		}
 
-		log_message('debug', "User Agent Class Initialized");
+		log_message('debug', 'User Agent Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -94,7 +89,7 @@
 	 */
 	protected function _load_agent_file()
 	{
-		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'))
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php');
 		}
@@ -165,22 +160,24 @@
 	/**
 	 * Set the Platform
 	 *
-	 * @return	mixed
+	 * @return	bool
 	 */
 	protected function _set_platform()
 	{
-		if (is_array($this->platforms) AND count($this->platforms) > 0)
+		if (is_array($this->platforms) && count($this->platforms) > 0)
 		{
 			foreach ($this->platforms as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				if (preg_match('|'.preg_quote($key).'|i', $this->agent))
 				{
 					$this->platform = $val;
 					return TRUE;
 				}
 			}
 		}
+
 		$this->platform = 'Unknown Platform';
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -192,11 +189,11 @@
 	 */
 	protected function _set_browser()
 	{
-		if (is_array($this->browsers) AND count($this->browsers) > 0)
+		if (is_array($this->browsers) && count($this->browsers) > 0)
 		{
 			foreach ($this->browsers as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match))
+				if (preg_match('|'.preg_quote($key).'.*?([0-9\.]+)|i', $this->agent, $match))
 				{
 					$this->is_browser = TRUE;
 					$this->version = $match[1];
@@ -206,6 +203,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -218,11 +216,11 @@
 	 */
 	protected function _set_robot()
 	{
-		if (is_array($this->robots) AND count($this->robots) > 0)
+		if (is_array($this->robots) && count($this->robots) > 0)
 		{
 			foreach ($this->robots as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				if (preg_match('|'.preg_quote($key).'|i', $this->agent))
 				{
 					$this->is_robot = TRUE;
 					$this->robot = $val;
@@ -230,6 +228,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -242,7 +241,7 @@
 	 */
 	protected function _set_mobile()
 	{
-		if (is_array($this->mobiles) AND count($this->mobiles) > 0)
+		if (is_array($this->mobiles) && count($this->mobiles) > 0)
 		{
 			foreach ($this->mobiles as $key => $val)
 			{
@@ -254,6 +253,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -266,7 +266,7 @@
 	 */
 	protected function _set_languages()
 	{
-		if ((count($this->languages) === 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')
+		if ((count($this->languages) === 0) && ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
 		{
 			$this->languages = explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))));
 		}
@@ -286,7 +286,7 @@
 	 */
 	protected function _set_charsets()
 	{
-		if ((count($this->charsets) === 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')
+		if ((count($this->charsets) === 0) && ! empty($_SERVER['HTTP_ACCEPT_CHARSET']))
 		{
 			$this->charsets = explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))));
 		}
@@ -318,7 +318,7 @@
 		}
 
 		// Check for a specific browser
-		return array_key_exists($key, $this->browsers) AND $this->browser === $this->browsers[$key];
+		return (isset($this->browsers[$key]) && $this->browser === $this->browsers[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -342,7 +342,7 @@
 		}
 
 		// Check for a specific robot
-		return array_key_exists($key, $this->robots) AND $this->robot === $this->robots[$key];
+		return (isset($this->robots[$key]) && $this->robot === $this->robots[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -366,7 +366,7 @@
 		}
 
 		// Check for a specific robot
-		return array_key_exists($key, $this->mobiles) AND $this->mobile === $this->mobiles[$key];
+		return (isset($this->mobiles[$key]) && $this->mobile === $this->mobiles[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -378,7 +378,7 @@
 	 */
 	public function is_referral()
 	{
-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
+		return ! empty($_SERVER['HTTP_REFERER']);
 	}
 
 	// --------------------------------------------------------------------
@@ -461,7 +461,7 @@
 	 */
 	public function referrer()
 	{
-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);
+		return empty($_SERVER['HTTP_REFERER']) ? '' : trim($_SERVER['HTTP_REFERER']);
 	}
 
 	// --------------------------------------------------------------------
@@ -507,7 +507,7 @@
 	 */
 	public function accept_lang($lang = 'en')
 	{
-		return (in_array(strtolower($lang), $this->languages(), TRUE));
+		return in_array(strtolower($lang), $this->languages(), TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -519,10 +519,10 @@
 	 */
 	public function accept_charset($charset = 'utf-8')
 	{
-		return (in_array(strtolower($charset), $this->charsets(), TRUE));
+		return in_array(strtolower($charset), $this->charsets(), TRUE);
 	}
 
 }
 
 /* End of file User_agent.php */
-/* Location: ./system/libraries/User_agent.php */
+/* Location: ./system/libraries/User_agent.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 730a0fc..fea560c 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -25,14 +25,6 @@
  * @filesource
  */
 
-if ( ! function_exists('xml_parser_create'))
-{
-	show_error('Your PHP installation does not support XML');
-}
-
-
-// ------------------------------------------------------------------------
-
 /**
  * XML-RPC request handler class
  *
@@ -42,6 +34,14 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
  */
+
+if ( ! function_exists('xml_parser_create'))
+{
+	show_error('Your PHP installation does not support XML');
+}
+
+// ------------------------------------------------------------------------
+
 class CI_Xmlrpc {
 
 	public $debug		= FALSE;	// Debugging on or off
@@ -77,13 +77,17 @@
 
 	public $xss_clean		= TRUE;
 
-	//-------------------------------------
-	//  VALUES THAT MULTIPLE CLASSES NEED
-	//-------------------------------------
 
+	/**
+	 * Constructor
+	 *
+	 * Initializes property default values
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function __construct($config = array())
 	{
-		$this->xmlrpcName	= $this->xmlrpcName;
 		$this->xmlrpc_backslash = chr(92).chr(92);
 
 		// Types for info sent back and forth
@@ -136,14 +140,17 @@
 
 		$this->initialize($config);
 
-		log_message('debug', "XML-RPC Class Initialized");
+		log_message('debug', 'XML-RPC Class Initialized');
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Initialize Prefs
-	//-------------------------------------
-
+	/**
+	 * Initialize
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function initialize($config = array())
 	{
 		if (count($config) > 0)
@@ -157,36 +164,43 @@
 			}
 		}
 	}
-	// END
 
-	//-------------------------------------
-	//  Take URL and parse it
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function server($url, $port=80)
+	/**
+	 * Parse server URL
+	 *
+	 * @param	string	url
+	 * @param	int	port
+	 * @return	void
+	 */
+	public function server($url, $port = 80)
 	{
 		if (strpos($url, 'http') !== 0)
 		{
-			$url = "http://".$url;
+			$url = 'http://'.$url;
 		}
 
 		$parts = parse_url($url);
 
-		$path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
+		$path = isset($parts['path']) ? $parts['path'] : '/';
 
-		if (isset($parts['query']) && $parts['query'] != '')
+		if ( ! empty($parts['query']))
 		{
 			$path .= '?'.$parts['query'];
 		}
 
 		$this->client = new XML_RPC_Client($path, $parts['host'], $port);
 	}
-	// END
 
-	//-------------------------------------
-	//  Set Timeout
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Set Timeout
+	 *
+	 * @param	int	seconds
+	 * @return	void
+	 */
 	public function timeout($seconds = 5)
 	{
 		if ( ! is_null($this->client) && is_int($seconds))
@@ -194,27 +208,34 @@
 			$this->client->timeout = $seconds;
 		}
 	}
-	// END
 
-	//-------------------------------------
-	//  Set Methods
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Set Methods
+	 *
+	 * @param	string	method name
+	 * @return	void
+	 */
 	public function method($function)
 	{
 		$this->method = $function;
 	}
-	// END
 
-	//-------------------------------------
-	//  Take Array of Data and Create Objects
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Take Array of Data and Create Objects
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function request($incoming)
 	{
 		if ( ! is_array($incoming))
 		{
 			// Send Error
+			return;
 		}
 
 		$this->data = array();
@@ -224,27 +245,33 @@
 			$this->data[$key] = $this->values_parsing($value);
 		}
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Set Debug
-	//-------------------------------------
-
+	/**
+	 * Set Debug
+	 *
+	 * @param	bool
+	 * @return	void
+	 */
 	public function set_debug($flag = TRUE)
 	{
 		$this->debug = ($flag == TRUE);
 	}
 
-	//-------------------------------------
-	//  Values Parsing
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function values_parsing($value, $return = FALSE)
+	/**
+	 * Values Parsing
+	 *
+	 * @param	mixed
+	 * @return	object
+	 */
+	public function values_parsing($value)
 	{
 		if (is_array($value) && array_key_exists(0, $value))
 		{
-			if ( ! isset($value[1]) OR ( ! isset($this->xmlrpcTypes[$value[1]])))
+			if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]]))
 			{
 				$temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
 			}
@@ -268,16 +295,17 @@
 
 		return $temp;
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Sends XML-RPC Request
-	//-------------------------------------
-
+	/**
+	 * Sends XML-RPC Request
+	 *
+	 * @return	bool
+	 */
 	public function send_request()
 	{
-		$this->message = new XML_RPC_Message($this->method,$this->data);
+		$this->message = new XML_RPC_Message($this->method, $this->data);
 		$this->message->debug = $this->debug;
 
 		if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
@@ -289,55 +317,62 @@
 		$this->response = $this->result->decode();
 		return TRUE;
 	}
-	// END
 
-	//-------------------------------------
-	//  Returns Error
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Returns Error
+	 *
+	 * @return	string
+	 */
 	public function display_error()
 	{
 		return $this->error;
 	}
-	// END
 
-	//-------------------------------------
-	//  Returns Remote Server Response
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Returns Remote Server Response
+	 *
+	 * @return	string
+	 */
 	public function display_response()
 	{
 		return $this->response;
 	}
-	// END
 
-	//-------------------------------------
-	//  Sends an Error Message for Server Request
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Sends an Error Message for Server Request
+	 *
+	 * @param	int
+	 * @param	string
+	 * @return	object
+	 */
 	public function send_error_message($number, $message)
 	{
 		return new XML_RPC_Response(0, $number, $message);
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Send Response for Server Request
-	//-------------------------------------
-
+	/**
+	 * Send Response for Server Request
+	 *
+	 * @param	array
+	 * @return	object
+	 */
 	public function send_response($response)
 	{
 		// $response should be array of values, which will be parsed
 		// based on their data and type into a valid group of XML-RPC values
 		return new XML_RPC_Response($this->values_parsing($response));
 	}
-	// END
 
 } // END XML_RPC Class
 
-
-
 /**
  * XML-RPC Client class
  *
@@ -355,7 +390,15 @@
 	public $timeout		= 5;
 	public $no_multicall	= FALSE;
 
-	public function __construct($path, $server, $port=80)
+	/**
+	 * Constructor
+	 *
+	 * @param	string
+	 * @param	object
+	 * @param	int
+	 * @return	void
+	 */
+	public function __construct($path, $server, $port = 80)
 	{
 		parent::__construct();
 
@@ -364,18 +407,33 @@
 		$this->path = $path;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send message
+	 *
+	 * @param	mixed
+	 * @return	object
+	 */
 	public function send($msg)
 	{
 		if (is_array($msg))
 		{
 			// Multi-call disabled
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'], $this->xmlrpcstr['multicall_recursion']);
 		}
 
 		return $this->sendPayload($msg);
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send payload
+	 *
+	 * @param	object
+	 * @return	object
+	 */
 	public function sendPayload($msg)
 	{
 		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
@@ -383,8 +441,7 @@
 		if ( ! is_resource($fp))
 		{
 			error_log($this->xmlrpcstr['http_error']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
 		}
 
 		if (empty($msg->payload))
@@ -394,27 +451,25 @@
 		}
 
 		$r = "\r\n";
-		$op = "POST {$this->path} HTTP/1.0$r"
-			. "Host: {$this->server}$r"
-			. "Content-Type: text/xml$r"
-			. "User-Agent: {$this->xmlrpcName}$r"
-			. "Content-Length: ".strlen($msg->payload)."$r$r"
-			. $msg->payload;
-
+		$op = 'POST '.$this->path.' HTTP/1.0'.$r
+			.'Host: '.$this->server.$r
+			.'Content-Type: text/xml'.$r
+			.'User-Agent: '.$this->xmlrpcName.$r
+			.'Content-Length: '.strlen($msg->payload).$r.$r
+			.$msg->payload;
 
 		if ( ! fputs($fp, $op, strlen($op)))
 		{
 			error_log($this->xmlrpcstr['http_error']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
 		}
+
 		$resp = $msg->parseResponse($fp);
 		fclose($fp);
 		return $resp;
 	}
 
-}
-// end class XML_RPC_Client
+} // END XML_RPC_Client Class
 
 /**
  * XML-RPC Response class
@@ -425,31 +480,34 @@
  */
 class XML_RPC_Response
 {
-	public $val = 0;
-	public $errno = 0;
-	public $errstr = '';
-	public $headers = array();
-	public $xss_clean = TRUE;
+	public $val		= 0;
+	public $errno		= 0;
+	public $errstr		= '';
+	public $headers		= array();
+	public $xss_clean	= TRUE;
 
+	/**
+	 * Constructor
+	 *
+	 * @param	mixed
+	 * @param	int
+	 * @param	string
+	 * @return	void
+	 */
 	public function __construct($val, $code = 0, $fstr = '')
 	{
 		if ($code != 0)
 		{
 			// error
 			$this->errno = $code;
-			if ( ! is_php('5.4'))
-			{
-				$this->errstr = htmlspecialchars($fstr, ENT_NOQUOTES, 'UTF-8');
-			}
-			else
-			{
-				$this->errstr = htmlspecialchars($fstr, ENT_XML1 | ENT_NOQUOTES, 'UTF-8');
-			}
+			$this->errstr = htmlspecialchars($fstr,
+							(is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES),
+							'UTF-8');
 		}
-		else if ( ! is_object($val))
+		elseif ( ! is_object($val))
 		{
 			// programmer error, not an object
-			error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");
+			error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.');
 			$this->val = new XML_RPC_Values();
 		}
 		else
@@ -458,43 +516,79 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fault code
+	 *
+	 * @return	int
+	 */
 	public function faultCode()
 	{
 		return $this->errno;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fault string
+	 *
+	 * @return	string
+	 */
 	public function faultString()
 	{
 		return $this->errstr;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Value
+	 *
+	 * @return	mixed
+	 */
 	public function value()
 	{
 		return $this->val;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Prepare response
+	 *
+	 * @return	string	xml
+	 */
 	public function prepare_response()
 	{
 		return "<methodResponse>\n"
-			. ($this->errno
-			? '<fault>
+			.($this->errno
+				? '<fault>
 	<value>
 		<struct>
 			<member>
 				<name>faultCode</name>
-				<value><int>' . $this->errno . '</int></value>
+				<value><int>'.$this->errno.'</int></value>
 			</member>
 			<member>
 				<name>faultString</name>
-				<value><string>' . $this->errstr . '</string></value>
+				<value><string>'.$this->errstr.'</string></value>
 			</member>
 		</struct>
 	</value>
 </fault>'
-			: "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
-			. "\n</methodResponse>";
+				: "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
+			."\n</methodResponse>";
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Decode
+	 *
+	 * @param	mixed
+	 * @return	array
+	 */
 	public function decode($array = FALSE)
 	{
 		$CI =& get_instance();
@@ -513,31 +607,31 @@
 				}
 			}
 
-			$result = $array;
+			return $array;
+		}
+
+		$result = $this->xmlrpc_decoder($this->val);
+
+		if (is_array($result))
+		{
+			$result = $this->decode($result);
 		}
 		else
 		{
-			$result = $this->xmlrpc_decoder($this->val);
-
-			if (is_array($result))
-			{
-				$result = $this->decode($result);
-			}
-			else
-			{
-				$result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
-			}
+			$result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
 		}
 
 		return $result;
 	}
 
+	// --------------------------------------------------------------------
 
-
-	//-------------------------------------
-	//  XML-RPC Object to PHP Types
-	//-------------------------------------
-
+	/**
+	 * XML-RPC Object to PHP Types
+	 *
+	 * @param	object
+	 * @return	array
+	 */
 	public function xmlrpc_decoder($xmlrpc_val)
 	{
 		$kind = $xmlrpc_val->kindOf();
@@ -571,25 +665,28 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  ISO-8601 time to server or UTC time
-	//-------------------------------------
-
-	public function iso8601_decode($time, $utc = 0)
+	/**
+	 * ISO-8601 time to server or UTC time
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	int	unix timestamp
+	 */
+	public function iso8601_decode($time, $utc = FALSE)
 	{
-		// return a timet in the localtime, or UTC
+		// return a time in the localtime, or UTC
 		$t = 0;
 		if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
 		{
-			$fnc = ($utc == 1) ? 'gmmktime' : 'mktime';
+			$fnc = ($utc == TRUE) ? 'gmmktime' : 'mktime';
 			$t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 		}
 		return $t;
 	}
 
-}
-// End Response Class
+} // END XML_RPC_Response Class
 
 /**
  * XML-RPC Message class
@@ -602,10 +699,17 @@
 {
 	public $payload;
 	public $method_name;
-	public $params			= array();
-	public $xh				= array();
+	public $params		= array();
+	public $xh		= array();
 
-	public function __construct($method, $pars=0)
+	/**
+	 * Constructor
+	 *
+	 * @param	string	method name
+	 * @param	array
+	 * @return	void
+	 */
+	public function __construct($method, $pars = FALSE)
 	{
 		parent::__construct();
 
@@ -620,15 +724,18 @@
 		}
 	}
 
-	//-------------------------------------
-	//  Create Payload to Send
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Create Payload to Send
+	 *
+	 * @return	void
+	 */
 	public function createPayload()
 	{
-		$this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n"
-				. '<methodName>'.$this->method_name."</methodName>\r\n"
-				. "<params>\r\n";
+		$this->payload = '<?xml version="1.0"?'.">\r\n<methodCall>\r\n"
+				.'<methodName>'.$this->method_name."</methodName>\r\n"
+				."<params>\r\n";
 
 		for ($i = 0, $c = count($this->params); $i < $c; $i++)
 		{
@@ -640,10 +747,14 @@
 		$this->payload .= "</params>\r\n</methodCall>\r\n";
 	}
 
-	//-------------------------------------
-	//  Parse External XML-RPC Server's Response
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Parse External XML-RPC Server's Response
+	 *
+	 * @param	resource
+	 * @return	object
+	 */
 	public function parseResponse($fp)
 	{
 		$data = '';
@@ -653,36 +764,24 @@
 			$data .= $datum;
 		}
 
-		//-------------------------------------
-		//  DISPLAY HTTP CONTENT for DEBUGGING
-		//-------------------------------------
-
+		// Display HTTP content for debugging
 		if ($this->debug === TRUE)
 		{
 			echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
 		}
 
-		//-------------------------------------
-		//  Check for data
-		//-------------------------------------
-
+		// Check for data
 		if ($data === '')
 		{
 			error_log($this->xmlrpcstr['no_data']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
 		}
 
-
-		//-------------------------------------
-		//  Check for HTTP 200 Response
-		//-------------------------------------
-
+		// Check for HTTP 200 Response
 		if (strncmp($data, 'HTTP', 4) === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
 		{
-			$errstr= substr($data, 0, strpos($data, "\n")-1);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
-			return $r;
+			$errstr = substr($data, 0, strpos($data, "\n")-1);
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' ('.$errstr.')');
 		}
 
 		//-------------------------------------
@@ -692,25 +791,21 @@
 		$parser = xml_parser_create($this->xmlrpc_defencoding);
 
 		$this->xh[$parser] = array(
-						'isf' =>	0,
-						'ac' =>		'',
-						'headers' =>	array(),
-						'stack' =>	array(),
-						'valuestack' =>	array(),
-						'isf_reason' =>	0
+						'isf'		=> 0,
+						'ac'		=> '',
+						'headers'	=> array(),
+						'stack'		=> array(),
+						'valuestack'	=> array(),
+						'isf_reason'	=> 0
 					);
 
 		xml_set_object($parser, $this);
-		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
 		xml_set_element_handler($parser, 'open_tag', 'closing_tag');
 		xml_set_character_data_handler($parser, 'character_data');
 		//xml_set_default_handler($parser, 'default_handler');
 
-
-		//-------------------------------------
-		//  GET HEADERS
-		//-------------------------------------
-
+		// Get headers
 		$lines = explode("\r\n", $data);
 		while (($line = array_shift($lines)))
 		{
@@ -722,16 +817,12 @@
 		}
 		$data = implode("\r\n", $lines);
 
-
-		//-------------------------------------
-		//  PARSE XML DATA
-		//-------------------------------------
-
+		// Parse XML data
 		if ( ! xml_parse($parser, $data, count($data)))
 		{
 			$errstr = sprintf('XML error: %s at line %d',
-					xml_error_string(xml_get_error_code($parser)),
-					xml_get_current_line_number($parser));
+						xml_error_string(xml_get_error_code($parser)),
+						xml_get_current_line_number($parser));
 			//error_log($errstr);
 			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
 			xml_parser_free($parser);
@@ -739,10 +830,7 @@
 		}
 		xml_parser_free($parser);
 
-		// ---------------------------------------
-		//  Got Ourselves Some Badness, It Seems
-		// ---------------------------------------
-
+		// Got ourselves some badness, it seems
 		if ($this->xh[$parser]['isf'] > 1)
 		{
 			if ($this->debug === TRUE)
@@ -750,29 +838,24 @@
 				echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
 			}
 
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 		}
 		elseif ( ! is_object($this->xh[$parser]['value']))
 		{
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 		}
 
-		//-------------------------------------
-		//  DISPLAY XML CONTENT for DEBUGGING
-		//-------------------------------------
-
+		// Display XML content for debugging
 		if ($this->debug === TRUE)
 		{
-			echo "<pre>";
+			echo '<pre>';
 
 			if (count($this->xh[$parser]['headers'] > 0))
 			{
 				echo "---HEADERS---\n";
 				foreach ($this->xh[$parser]['headers'] as $header)
 				{
-					echo "$header\n";
+					echo $header."\n";
 				}
 				echo "---END HEADERS---\n\n";
 			}
@@ -782,10 +865,7 @@
 			echo "\n---END PARSED---</pre>";
 		}
 
-		//-------------------------------------
-		//  SEND RESPONSE
-		//-------------------------------------
-
+		// Send response
 		$v = $this->xh[$parser]['value'];
 		if ($this->xh[$parser]['isf'])
 		{
@@ -810,6 +890,8 @@
 		return $r;
 	}
 
+	// --------------------------------------------------------------------
+
 	// ------------------------------------
 	//  Begin Return Message Parsing section
 	// ------------------------------------
@@ -824,17 +906,21 @@
 	//	 stack - array with parent tree of the xml element,
 	//			 used to validate the nesting of elements
 
-	//-------------------------------------
-	//  Start Element Handler
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function open_tag($the_parser, $name, $attrs)
+	/**
+	 * Start Element Handler
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	public function open_tag($the_parser, $name)
 	{
 		// If invalid nesting, then return
 		if ($this->xh[$the_parser]['isf'] > 1) return;
 
 		// Evaluate and check for correct nesting of XML elements
-
 		if (count($this->xh[$the_parser]['stack']) == 0)
 		{
 			if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
@@ -844,43 +930,37 @@
 				return;
 			}
 		}
-		else
+		// not top level element: see if parent is OK
+		elseif ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
 		{
-			// not top level element: see if parent is OK
-			if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
-			{
-				$this->xh[$the_parser]['isf'] = 2;
-				$this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
-				return;
-			}
+			$this->xh[$the_parser]['isf'] = 2;
+			$this->xh[$the_parser]['isf_reason'] = 'XML-RPC element $name cannot be child of '.$this->xh[$the_parser]['stack'][0];
+			return;
 		}
 
-		switch($name)
+		switch ($name)
 		{
 			case 'STRUCT':
 			case 'ARRAY':
 				// Creates array for child elements
-
-				$cur_val = array('value' => array(),
-								 'type'	 => $name);
-
+				$cur_val = array('value' => array(), 'type' => $name);
 				array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
-			break;
+				break;
 			case 'METHODNAME':
 			case 'NAME':
 				$this->xh[$the_parser]['ac'] = '';
-			break;
+				break;
 			case 'FAULT':
 				$this->xh[$the_parser]['isf'] = 1;
-			break;
+				break;
 			case 'PARAM':
 				$this->xh[$the_parser]['value'] = NULL;
-			break;
+				break;
 			case 'VALUE':
 				$this->xh[$the_parser]['vt'] = 'value';
 				$this->xh[$the_parser]['ac'] = '';
 				$this->xh[$the_parser]['lv'] = 1;
-			break;
+				break;
 			case 'I4':
 			case 'INT':
 			case 'STRING':
@@ -892,66 +972,70 @@
 				{
 					//two data elements inside a value: an error occurred!
 					$this->xh[$the_parser]['isf'] = 2;
-					$this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
+					$this->xh[$the_parser]['isf_reason'] = "'Twas a ".$name.' element following a '
+										.$this->xh[$the_parser]['vt'].' element inside a single value';
 					return;
 				}
 
 				$this->xh[$the_parser]['ac'] = '';
-			break;
+				break;
 			case 'MEMBER':
 				// Set name of <member> to nothing to prevent errors later if no <name> is found
 				$this->xh[$the_parser]['valuestack'][0]['name'] = '';
 
 				// Set NULL value to check to see if value passed for this param/member
 				$this->xh[$the_parser]['value'] = NULL;
-			break;
+				break;
 			case 'DATA':
 			case 'METHODCALL':
 			case 'METHODRESPONSE':
 			case 'PARAMS':
 				// valid elements that add little to processing
-			break;
+				break;
 			default:
 				/// An Invalid Element is Found, so we have trouble
 				$this->xh[$the_parser]['isf'] = 2;
-				$this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
-			break;
+				$this->xh[$the_parser]['isf_reason'] = 'Invalid XML-RPC element found: '.$name;
+				break;
 		}
 
 		// Add current element name to stack, to allow validation of nesting
 		array_unshift($this->xh[$the_parser]['stack'], $name);
 
-		if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
+		$name == 'VALUE' OR $this->xh[$the_parser]['lv'] = 0;
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  End Element Handler
-	//-------------------------------------
-
+	/**
+	 * End Element Handler
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
 	public function closing_tag($the_parser, $name)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return;
 
 		// Remove current element from stack and set variable
 		// NOTE: If the XML validates, then we do not have to worry about
-		// the opening and closing of elements.  Nesting is checked on the opening
+		// the opening and closing of elements. Nesting is checked on the opening
 		// tag so we be safe there as well.
 
 		$curr_elem = array_shift($this->xh[$the_parser]['stack']);
 
-		switch($name)
+		switch ($name)
 		{
 			case 'STRUCT':
 			case 'ARRAY':
 				$cur_val = array_shift($this->xh[$the_parser]['valuestack']);
-				$this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
+				$this->xh[$the_parser]['value'] = isset($cur_val['values']) ? $cur_val['values'] : array();
 				$this->xh[$the_parser]['vt']	= strtolower($name);
-			break;
+				break;
 			case 'NAME':
 				$this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
-			break;
+				break;
 			case 'BOOLEAN':
 			case 'I4':
 			case 'INT':
@@ -965,56 +1049,39 @@
 				{
 					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 				}
-				elseif ($name=='DATETIME.ISO8601')
+				elseif ($name == 'DATETIME.ISO8601')
 				{
 					$this->xh[$the_parser]['vt']	= $this->xmlrpcDateTime;
 					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 				}
-				elseif ($name=='BASE64')
+				elseif ($name == 'BASE64')
 				{
 					$this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
 				}
-				elseif ($name=='BOOLEAN')
+				elseif ($name == 'BOOLEAN')
 				{
 					// Translated BOOLEAN values to TRUE AND FALSE
-					if ($this->xh[$the_parser]['ac'] == '1')
-					{
-						$this->xh[$the_parser]['value'] = TRUE;
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = FALSE;
-					}
+					$this->xh[$the_parser]['value'] = (bool) $this->xh[$the_parser]['ac'];
 				}
 				elseif ($name=='DOUBLE')
 				{
 					// we have a DOUBLE
 					// we must check that only 0123456789-.<space> are characters here
-					if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
-					{
-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
-					}
+					$this->xh[$the_parser]['value'] = preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])
+										? (float) $this->xh[$the_parser]['ac']
+										: 'ERROR_NON_NUMERIC_FOUND';
 				}
 				else
 				{
 					// we have an I4/INT
 					// we must check that only 0123456789-<space> are characters here
-					if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
-					{
-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
-					}
+					$this->xh[$the_parser]['value'] = preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])
+										? (int) $this->xh[$the_parset]['ac']
+										: 'ERROR_NON_NUMERIC_FOUND';
 				}
 				$this->xh[$the_parser]['ac'] = '';
 				$this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
-			break;
+				break;
 			case 'VALUE':
 				// This if() detects if no scalar was inside <VALUE></VALUE>
 				if ($this->xh[$the_parser]['vt']=='value')
@@ -1036,44 +1103,49 @@
 					// Struct
 					$this->xh[$the_parser]['value'] = $temp;
 				}
-			break;
+				break;
 			case 'MEMBER':
-				$this->xh[$the_parser]['ac']='';
+				$this->xh[$the_parser]['ac'] = '';
 
 				// If value add to array in the stack for the last element built
 				if ($this->xh[$the_parser]['value'])
 				{
 					$this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
 				}
-			break;
+				break;
 			case 'DATA':
-				$this->xh[$the_parser]['ac']='';
-			break;
+				$this->xh[$the_parser]['ac'] = '';
+				break;
 			case 'PARAM':
 				if ($this->xh[$the_parser]['value'])
 				{
 					$this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
 				}
-			break;
+				break;
 			case 'METHODNAME':
 				$this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
-			break;
+				break;
 			case 'PARAMS':
 			case 'FAULT':
 			case 'METHODCALL':
 			case 'METHORESPONSE':
 				// We're all good kids with nuthin' to do
-			break;
+				break;
 			default:
-				// End of an Invalid Element.  Taken care of during the opening tag though
-			break;
+				// End of an Invalid Element. Taken care of during the opening tag though
+				break;
 		}
 	}
 
-	//-------------------------------------
-	//  Parses Character Data
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Parse character data
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
 	public function character_data($the_parser, $data)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
@@ -1086,7 +1158,7 @@
 				$this->xh[$the_parser]['lv'] = 2; // Found a value
 			}
 
-			if ( ! @isset($this->xh[$the_parser]['ac']))
+			if ( ! isset($this->xh[$the_parser]['ac']))
 			{
 				$this->xh[$the_parser]['ac'] = '';
 			}
@@ -1095,12 +1167,27 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
+	/**
+	 * Add parameter
+	 *
+	 * @param	mixed
+	 * @return	void
+	 */
 	public function addParam($par)
 	{
 		$this->params[] = $par;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Output parameters
+	 *
+	 * @param	array
+	 * @return	array
+	 */
 	public function output_parameters($array = FALSE)
 	{
 		$CI =& get_instance();
@@ -1121,31 +1208,36 @@
 				}
 			}
 
-			$parameters = $array;
+			return $array;
 		}
-		else
+
+		$parameters = array();
+
+		for ($i = 0, $c = count($this->params); $i < $c; $i++)
 		{
-			$parameters = array();
+			$a_param = $this->decode_message($this->params[$i]);
 
-			for ($i = 0, $c = count($this->params); $i < $c; $i++)
+			if (is_array($a_param))
 			{
-				$a_param = $this->decode_message($this->params[$i]);
-
-				if (is_array($a_param))
-				{
-					$parameters[] = $this->output_parameters($a_param);
-				}
-				else
-				{
-					$parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
-				}
+				$parameters[] = $this->output_parameters($a_param);
+			}
+			else
+			{
+				$parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
 			}
 		}
 
 		return $parameters;
 	}
 
+	// --------------------------------------------------------------------
 
+	/**
+	 * Decode message
+	 *
+	 * @param	object
+	 * @return	mixed
+	 */
 	public function decode_message($param)
 	{
 		$kind = $param->kindOf();
@@ -1160,7 +1252,7 @@
 			$b = current($param->me);
 			$arr = array();
 
-			for($i = 0, $c = count($b); $i < $c; $i++)
+			for ($i = 0, $c = count($b); $i < $c; $i++)
 			{
 				$arr[] = $this->decode_message($param->me['array'][$i]);
 			}
@@ -1181,8 +1273,7 @@
 		}
 	}
 
-}
-// End XML_RPC_Messages class
+} // END XML_RPC_Message Class
 
 /**
  * XML-RPC Values class
@@ -1196,6 +1287,13 @@
 	public $me	= array();
 	public $mytype	= 0;
 
+	/**
+	 * Constructor
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
 	public function __construct($val = -1, $type = '')
 	{
 		parent::__construct();
@@ -1219,11 +1317,20 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add scalar value
+	 *
+	 * @param	scalar
+	 * @param	string
+	 * @return	int
+	 */
 	public function addScalar($val, $type = 'string')
 	{
 		$typeof = $this->xmlrpcTypes[$type];
 
-		if ($this->mytype==1)
+		if ($this->mytype == 1)
 		{
 			echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
 			return 0;
@@ -1237,7 +1344,7 @@
 
 		if ($type == $this->xmlrpcBoolean)
 		{
-			$val = (strcasecmp($val,'true') === 0 OR $val == 1 OR ($val == true && strcasecmp($val, 'false'))) ? 1 : 0;
+			$val = (int) (strcasecmp($val,'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
 		}
 
 		if ($this->mytype == 2)
@@ -1253,9 +1360,18 @@
 			$this->me[$type] = $val;
 			$this->mytype = $typeof;
 		}
+
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add array value
+	 *
+	 * @param	array
+	 * @return	int
+	 */
 	public function addArray($vals)
 	{
 		if ($this->mytype != 0)
@@ -1269,6 +1385,14 @@
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add struct value
+	 *
+	 * @param	object
+	 * @return	int
+	 */
 	public function addStruct($vals)
 	{
 		if ($this->mytype != 0)
@@ -1281,29 +1405,37 @@
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get value type
+	 *
+	 * @return	string
+	 */
 	public function kindOf()
 	{
-		switch($this->mytype)
+		switch ($this->mytype)
 		{
-			case 3:
-				return 'struct';
-				break;
-			case 2:
-				return 'array';
-				break;
-			case 1:
-				return 'scalar';
-				break;
-			default:
-				return 'undef';
+			case 3: return 'struct';
+			case 2: return 'array';
+			case 1: return 'scalar';
+			default: return 'undef';
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize data
+	 *
+	 * @param	string
+	 * @param	mixed
+	 */
 	public function serializedata($typ, $val)
 	{
 		$rs = '';
 
-		switch($this->xmlrpcTypes[$typ])
+		switch ($this->xmlrpcTypes[$typ])
 		{
 			case 3:
 				// struct
@@ -1314,11 +1446,11 @@
 					$rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
 				}
 				$rs .= '</struct>';
-			break;
+				break;
 			case 2:
 				// array
 				$rs .= "<array>\n<data>\n";
-				for($i = 0, $c = count($val); $i < $c; $i++)
+				for ($i = 0, $c = count($val); $i < $c; $i++)
 				{
 					$rs .= $this->serializeval($val[$i]);
 				}
@@ -1329,29 +1461,45 @@
 				switch ($typ)
 				{
 					case $this->xmlrpcBase64:
-						$rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.base64_encode( (string) $val).'</'.$typ.">\n";
+						break;
 					case $this->xmlrpcBoolean:
-						$rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.( (bool) $val ? '1' : '0').'</'.$typ.">\n";
+						break;
 					case $this->xmlrpcString:
-						$rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.htmlspecialchars( (string) $val).'</'.$typ.">\n";
+						break;
 					default:
-						$rs .= "<{$typ}>{$val}</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.$val.'</'.$typ.">\n";
+						break;
 				}
 			default:
-			break;
+				break;
 		}
+
 		return $rs;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize class
+	 *
+	 * @return	string
+	 */
 	public function serialize_class()
 	{
 		return $this->serializeval($this);
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize value
+	 *
+	 * @param	object
+	 * @return	string
+	 */
 	public function serializeval($o)
 	{
 		$ar = $o->me;
@@ -1361,26 +1509,35 @@
 		return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Scalar value
+	 *
+	 * @return	mixed
+	 */
 	public function scalarval()
 	{
 		reset($this->me);
 		return current($this->me);
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	// Encode time in ISO-8601 form.
-	//-------------------------------------
-
-	// Useful for sending time in XML-RPC
-
-	public function iso8601_encode($time, $utc = 0)
+	/**
+	 * Encode time in ISO-8601 form.
+	 * Useful for sending time in XML-RPC
+	 *
+	 * @param	int	unix timestamp
+	 * @param	bool
+	 * @return	string
+	*/
+	public function iso8601_encode($time, $utc = FALSE)
 	{
 		return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time);
 	}
 
-}
-// END XML_RPC_Values Class
+} // END XML_RPC_Values Class
 
 /* End of file Xmlrpc.php */
-/* Location: ./system/libraries/Xmlrpc.php */
+/* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 355d43f..6d270c2 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
@@ -54,10 +54,7 @@
 	public $controller_obj;
 	public $object		= FALSE;
 
-	/**
-	 * Constructor
-	 */
-	public function __construct($config=array())
+	public function __construct($config = array())
 	{
 		parent::__construct();
 		$this->set_system_methods();
@@ -67,7 +64,7 @@
 			$this->methods = array_merge($this->methods, $config['functions']);
 		}
 
-		log_message('debug', "XML-RPC Server Class Initialized");
+		log_message('debug', 'XML-RPC Server Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -75,7 +72,6 @@
 	/**
 	 * Initialize Prefs and Serve
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	void
 	 */
@@ -107,7 +103,6 @@
 	/**
 	 * Setting of System Methods
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function set_system_methods()
@@ -137,7 +132,6 @@
 	/**
 	 * Main Server Function
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function serve()
@@ -145,8 +139,8 @@
 		$r = $this->parseRequest();
 		$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));
+		header('Content-Type: text/xml');
+		header('Content-Length: '.strlen($payload));
 		exit($payload);
 	}
 
@@ -155,7 +149,6 @@
 	/**
 	 * Add Method to Class
 	 *
-	 * @access	public
 	 * @param	string	method name
 	 * @param	string	function
 	 * @param	string	signature
@@ -176,7 +169,6 @@
 	/**
 	 * Parse Server Request
 	 *
-	 * @access	public
 	 * @param	string	data
 	 * @return	object	xmlrpc response
 	 */
@@ -198,7 +190,7 @@
 		//-------------------------------------
 
 		$parser = xml_parser_create($this->xmlrpc_defencoding);
-		$parser_object = new XML_RPC_Message("filler");
+		$parser_object = new XML_RPC_Message('filler');
 
 		$parser_object->xh[$parser] = array(
 							'isf' =>	0,
@@ -215,7 +207,6 @@
 		xml_set_character_data_handler($parser, 'character_data');
 		//xml_set_default_handler($parser, 'default_handler');
 
-
 		//-------------------------------------
 		//  PARSE + PROCESS XML DATA
 		//-------------------------------------
@@ -245,7 +236,7 @@
 			{
 				if ($this->debug === TRUE)
 				{
-					$plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
+					$plist .= $i.' - '.print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE).";\n";
 				}
 
 				$m->addParam($parser_object->xh[$parser]['params'][$i]);
@@ -276,7 +267,6 @@
 	/**
 	 * Executes the Method
 	 *
-	 * @access	protected
 	 * @param	object
 	 * @return	mixed
 	 */
@@ -305,7 +295,7 @@
 		//  Check for Method (and Object)
 		//-------------------------------------
 
-		$method_parts = explode(".", $this->methods[$methName]['function']);
+		$method_parts = explode('.', $this->methods[$methName]['function']);
 		$objectCall = (isset($method_parts[1]) && $method_parts[1] != '');
 
 		if ($system_call === TRUE)
@@ -315,14 +305,11 @@
 				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
 			}
 		}
-		else
+		elseif (($objectCall && ! is_callable(array($method_parts[0], $method_parts[1])))
+			OR ( ! $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']);
-			}
+			return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
 		}
 
 		//-------------------------------------
@@ -351,7 +338,7 @@
 							return new XML_RPC_Response(0,
 								$this->xmlrpcerr['incorrect_params'],
 								$this->xmlrpcstr['incorrect_params'] .
-								": Wanted {$wanted}, got {$pt} at param {$pno})");
+								': Wanted '.$wanted.', got '.$pt.' at param '.$pno.')');
 						}
 					}
 				}
@@ -393,7 +380,6 @@
 	/**
 	 * Server Function:  List Methods
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -409,7 +395,7 @@
 
 		foreach ($this->system_methods as $key => $value)
 		{
-			$output[]= new XML_RPC_Values($key, 'string');
+			$output[] = new XML_RPC_Values($key, 'string');
 		}
 
 		$v->addArray($output);
@@ -421,7 +407,6 @@
 	/**
 	 * Server Function:  Return Signature for Method
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -447,18 +432,14 @@
 					}
 					$sigs[] = new XML_RPC_Values($cursig, 'array');
 				}
-				$r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
+
+				return new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
 			}
-			else
-			{
-				$r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
-			}
+
+			return new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
 		}
-		else
-		{
-			$r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
-		}
-		return $r;
+
+		return new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
 	}
 
 	// --------------------------------------------------------------------
@@ -466,7 +447,6 @@
 	/**
 	 * Server Function:  Doc String for Method
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -492,7 +472,6 @@
 	/**
 	 * Server Function:  Multi-call
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -536,7 +515,6 @@
 	/**
 	 *  Multi-call Function:  Error Handling
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -556,7 +534,6 @@
 	/**
 	 *  Multi-call Function:  Processes method
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	object
 	 */
@@ -610,7 +587,6 @@
 	}
 
 }
-// END XML_RPC_Server class
 
 /* End of file Xmlrpcs.php */
-/* Location: ./system/libraries/Xmlrpcs.php */
+/* Location: ./system/libraries/Xmlrpcs.php */
\ No newline at end of file
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 50e8492..8043854 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.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
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Zip Compression Class
  *
@@ -44,21 +42,17 @@
  */
 class CI_Zip  {
 
-	var $zipdata	= '';
-	var $directory	= '';
-	var $entries	= 0;
-	var $file_num	= 0;
-	var $offset		= 0;
-	var $now;
+	public $zipdata		= '';
+	public $directory	= '';
+	public $entries		= 0;
+	public $file_num	= 0;
+	public $offset		= 0;
+	public $now;
 
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
-		log_message('debug', "Zip Compression Class Initialized");
-
 		$this->now = time();
+		log_message('debug', 'Zip Compression Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -68,21 +62,19 @@
 	 *
 	 * Lets you add a virtual directory into which you can place files.
 	 *
-	 * @access	public
 	 * @param	mixed	the directory name. Can be string or array
 	 * @return	void
 	 */
-	function add_dir($directory)
+	public function add_dir($directory)
 	{
-		foreach ((array)$directory as $dir)
+		foreach ( (array) $directory as $dir)
 		{
-			if ( ! preg_match("|.+/$|", $dir))
+			if ( ! preg_match('|.+/$|', $dir))
 			{
 				$dir .= '/';
 			}
 
 			$dir_time = $this->_get_mod_time($dir);
-
 			$this->_add_dir($dir, $dir_time['file_mtime'], $dir_time['file_mdate']);
 		}
 	}
@@ -90,22 +82,22 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 *	Get file/directory modification time
+	 * Get file/directory modification time
 	 *
-	 *	If this is a newly created file/dir, we will set the time to 'now'
+	 * If this is a newly created file/dir, we will set the time to 'now'
 	 *
-	 *	@param string	path to file
-	 *	@return array	filemtime/filemdate
+	 * @param	string	path to file
+	 * @return	array	filemtime/filemdate
 	 */
-	function _get_mod_time($dir)
+	protected function _get_mod_time($dir)
 	{
 		// filemtime() may return false, but raises an error for non-existing files
-		$date = (file_exists($dir)) ? filemtime($dir): getdate($this->now);
-		
-		$time['file_mtime'] = ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2;
-		$time['file_mdate'] = (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday'];
+		$date = file_exists($dir) ? filemtime($dir) : getdate($this->now);
 
-		return $time;
+		return array(
+				'file_mtime' => ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2,
+				'file_mdate' => (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday']
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -113,13 +105,14 @@
 	/**
 	 * Add Directory
 	 *
-	 * @access	private
 	 * @param	string	the directory name
+	 * @param	int
+	 * @param	int
 	 * @return	void
 	 */
-	function _add_dir($dir, $file_mtime, $file_mdate)
+	protected function _add_dir($dir, $file_mtime, $file_mdate)
 	{
-		$dir = str_replace("\\", "/", $dir);
+		$dir = str_replace('\\', '/', $dir);
 
 		$this->zipdata .=
 			"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00"
@@ -162,29 +155,26 @@
 	 * Add Data to Zip
 	 *
 	 * Lets you add files to the archive. If the path is included
-	 * in the filename it will be placed within a directory.  Make
+	 * in the filename it will be placed within a directory. Make
 	 * sure you use add_dir() first to create the folder.
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @param	string
 	 * @return	void
 	 */
-	function add_data($filepath, $data = NULL)
+	public function add_data($filepath, $data = NULL)
 	{
 		if (is_array($filepath))
 		{
 			foreach ($filepath as $path => $data)
 			{
 				$file_data = $this->_get_mod_time($path);
-
 				$this->_add_data($path, $data, $file_data['file_mtime'], $file_data['file_mdate']);
 			}
 		}
 		else
 		{
 			$file_data = $this->_get_mod_time($filepath);
-
 			$this->_add_data($filepath, $data, $file_data['file_mtime'], $file_data['file_mdate']);
 		}
 	}
@@ -194,20 +184,19 @@
 	/**
 	 * Add Data to Zip
 	 *
-	 * @access	private
 	 * @param	string	the file name/path
 	 * @param	string	the data to be encoded
+	 * @param	int
+	 * @param	int
 	 * @return	void
 	 */
-	function _add_data($filepath, $data, $file_mtime, $file_mdate)
+	protected function _add_data($filepath, $data, $file_mtime, $file_mdate)
 	{
-		$filepath = str_replace("\\", "/", $filepath);
+		$filepath = str_replace('\\', '/', $filepath);
 
 		$uncompressed_size = strlen($data);
 		$crc32  = crc32($data);
-
-		$gzdata = gzcompress($data);
-		$gzdata = substr($gzdata, 2, -4);
+		$gzdata = substr(gzcompress($data), 2, -4);
 		$compressed_size = strlen($gzdata);
 
 		$this->zipdata .=
@@ -248,10 +237,11 @@
 	/**
 	 * Read the contents of a file and add it to the zip
 	 *
-	 * @access	public
+	 * @param	string
+	 * @param	bool
 	 * @return	bool
 	 */
-	function read_file($path, $preserve_filepath = FALSE)
+	public function read_file($path, $preserve_filepath = FALSE)
 	{
 		if ( ! file_exists($path))
 		{
@@ -260,16 +250,16 @@
 
 		if (FALSE !== ($data = file_get_contents($path)))
 		{
-			$name = str_replace("\\", "/", $path);
-
+			$name = str_replace('\\', '/', $path);
 			if ($preserve_filepath === FALSE)
 			{
-				$name = preg_replace("|.*/(.+)|", "\\1", $name);
+				$name = preg_replace('|.*/(.+)|', '\\1', $name);
 			}
 
 			$this->add_data($name, $data);
 			return TRUE;
 		}
+
 		return FALSE;
 	}
 
@@ -279,15 +269,17 @@
 	 * Read a directory and add it to the zip.
 	 *
 	 * This function recursively reads a folder and everything it contains (including
-	 * sub-folders) and creates a zip based on it.  Whatever directory structure
+	 * sub-folders) and creates a zip based on it. Whatever directory structure
 	 * is in the original file path will be recreated in the zip file.
 	 *
-	 * @access	public
 	 * @param	string	path to source
+	 * @param	bool
+	 * @param	bool
 	 * @return	bool
 	 */
-	function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
+	public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
 	{
+		$path = rtrim($path, '/\\').DIRECTORY_SEPARATOR;
 		if ( ! $fp = @opendir($path))
 		{
 			return FALSE;
@@ -296,36 +288,32 @@
 		// Set the original directory root for child dir's to use as relative
 		if ($root_path === NULL)
 		{
-			$root_path = dirname($path).'/';
+			$root_path = dirname($path).DIRECTORY_SEPARATOR;
 		}
 
 		while (FALSE !== ($file = readdir($fp)))
 		{
-			if (substr($file, 0, 1) == '.')
+			if ($file[0] === '.')
 			{
 				continue;
 			}
 
 			if (@is_dir($path.$file))
 			{
-				$this->read_dir($path.$file."/", $preserve_filepath, $root_path);
+				$this->read_dir($path.$file.DIRECTORY_SEPARATOR, $preserve_filepath, $root_path);
 			}
-			else
+			elseif (FALSE !== ($data = file_get_contents($path.$file)))
 			{
-				if (FALSE !== ($data = file_get_contents($path.$file)))
+				$name = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $path);
+				if ($preserve_filepath === FALSE)
 				{
-					$name = str_replace("\\", "/", $path);
-
-					if ($preserve_filepath === FALSE)
-					{
-						$name = str_replace($root_path, '', $name);
-					}
-
-					$this->add_data($name.$file, $data);
+					$name = str_replace($root_path, '', $name);
 				}
+				$this->add_data($name.$file, $data);
 			}
 		}
 
+		closedir($fp);
 		return TRUE;
 	}
 
@@ -334,26 +322,23 @@
 	/**
 	 * Get the Zip file
 	 *
-	 * @access	public
-	 * @return	binary string
+	 * @return	string	(binary encoded)
 	 */
-	function get_zip()
+	public function get_zip()
 	{
 		// Is there any data to return?
-		if ($this->entries == 0)
+		if ($this->entries === 0)
 		{
 			return FALSE;
 		}
 
-		$zip_data = $this->zipdata;
-		$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";
-		$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"
-		$zip_data .= pack('v', $this->entries); // total # of entries overall
-		$zip_data .= pack('V', strlen($this->directory)); // size of central dir
-		$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir
-		$zip_data .= "\x00\x00"; // .zip file comment length
-
-		return $zip_data;
+		return $this->zipdata
+			.$this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00"
+			.pack('v', $this->entries) // total # of entries "on this disk"
+			.pack('v', $this->entries) // total # of entries overall
+			.pack('V', strlen($this->directory)) // size of central dir
+			.pack('V', strlen($this->zipdata)) // offset to start of central dir
+			."\x00\x00"; // .zip file comment length
 	}
 
 	// --------------------------------------------------------------------
@@ -363,11 +348,10 @@
 	 *
 	 * Lets you write a file
 	 *
-	 * @access	public
 	 * @param	string	the file name
 	 * @return	bool
 	 */
-	function archive($filepath)
+	public function archive($filepath)
 	{
 		if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))
 		{
@@ -387,23 +371,19 @@
 	/**
 	 * Download
 	 *
-	 * @access	public
 	 * @param	string	the file name
-	 * @param	string	the data to be encoded
-	 * @return	bool
+	 * @return	void
 	 */
-	function download($filename = 'backup.zip')
+	public function download($filename = 'backup.zip')
 	{
-		if ( ! preg_match("|.+?\.zip$|", $filename))
+		if ( ! preg_match('|.+?\.zip$|', $filename))
 		{
 			$filename .= '.zip';
 		}
 
 		$CI =& get_instance();
 		$CI->load->helper('download');
-
 		$get_zip = $this->get_zip();
-
 		$zip_content =& $get_zip;
 
 		force_download($filename, $zip_content);
@@ -414,19 +394,19 @@
 	/**
 	 * Initialize Data
 	 *
-	 * Lets you clear current zip data.  Useful if you need to create
+	 * Lets you clear current zip data. Useful if you need to create
 	 * multiple zips with different data.
 	 *
-	 * @access	public
-	 * @return	void
+	 * @return	object
 	 */
-	function clear_data()
+	public function clear_data()
 	{
 		$this->zipdata		= '';
 		$this->directory	= '';
 		$this->entries		= 0;
 		$this->file_num		= 0;
 		$this->offset		= 0;
+		return $this;
 	}
 
 }
diff --git a/system/libraries/javascript/Jquery.php b/system/libraries/javascript/Jquery.php
index 03574c6..f30d7c6 100644
--- a/system/libraries/javascript/Jquery.php
+++ b/system/libraries/javascript/Jquery.php
@@ -2,7 +2,7 @@
 /**
  * CodeIgniter
  *
- * An open source application development framework for PHP 5.1.6 or newer
+ * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
  *
diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php
new file mode 100644
index 0000000..9f89d1b
--- /dev/null
+++ b/tests/Bootstrap.php
@@ -0,0 +1,21 @@
+<?php
+
+// Errors on full!
+ini_set('display_errors', 1);
+error_reporting(E_ALL | E_STRICT);
+
+$dir = realpath(dirname(__FILE__));
+
+// Path constants
+define('PROJECT_BASE',	realpath($dir.'/../').'/');
+define('BASEPATH',		PROJECT_BASE.'system/');
+define('APPPATH',		PROJECT_BASE.'application/');
+define('VIEWPATH',		PROJECT_BASE.'');
+
+// Prep our test environment
+require_once 'vfsStream/vfsStream.php';
+include_once $dir.'/mocks/core/common.php';
+include_once $dir.'/mocks/autoloader.php';
+spl_autoload_register('autoload');
+
+unset($dir);
\ No newline at end of file
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..6d83c34
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,164 @@
+# CodeIgniter Unit Tests #
+
+Status : [![Build Status](https://secure.travis-ci.org/EllisLab/CodeIgniter.png?branch=feature/unit-tests)](http://travis-ci.org/EllisLab/CodeIgniter)
+
+*Do not merge to default until these issues have been addressed*
+
+- Clean up naming conventions
+- Figure out config stuff
+- Figure out database testing
+
+### Introduction:
+
+This is the preliminary CodeIgniter testing documentation. It
+will cover both internal as well as external APIs and the reasoning
+behind their implemenation, where appropriate. As with all CodeIgniter
+documentation, this file should maintain a mostly human readable
+format to facilitate clean api design. [see http://arrenbrecht.ch/testing/]
+
+*First public draft: everything is subject to change*
+
+### Requirements
+
+PHP Unit >= 3.5.6
+
+	pear channel-discover pear.phpunit.de
+	pear install phpunit/PHPUnit
+
+vfsStream
+
+	pear channel-discover pear.php-tools.net
+	pear install pat/vfsStream-alpha
+
+#### Installation of PEAR and PHPUnit on Ubuntu
+
+  Installation on Ubuntu requires a few steps. Depending on your setup you may
+  need to use 'sudo' to install these. Mileage may vary but these steps are a
+  good start.
+
+	# Install the PEAR package
+	sudo apt-get install php-pear
+
+	# Add a few sources to PEAR
+	pear channel-discover pear.phpunit.de
+	pear channel-discover pear.symfony-project.com
+	pear channel-discover components.ez.no
+	pear channel-discover pear.php-tools.net 
+
+	# Finally install PHPUnit and vfsStream (including dependencies)
+	pear install --alldeps phpunit/PHPUnit
+	pear install --alldeps pat/vfsStream-alpha
+
+	# Finally, run 'phpunit' from within the ./tests directory
+	# and you should be on your way!
+
+## Test Suites:
+
+CodeIgniter bootstraps a request very directly, with very flat class
+hierarchy. As a result, there is no main CodeIgniter class until the
+controller is instantiated.
+
+This has forced the core classes to be relatively decoupled, which is
+a good thing. However, it makes that portion of code relatively hard
+to test.
+
+Right now that means we'll probably have two core test suites, along
+with a base for application and package tests. That gives us:
+
+1. Bootstrap Test	- test common.php and sanity check codeigniter.php [in planning]
+2. System Test		- test core components in relative isolation [in development]
+3. Application Test	- bootstrapping for application/tests [not started]
+4. Package Test		- bootstrapping for <package>/tests [not started]
+
+### CI_TestCase Documentation
+
+Test cases should extend CI_TestCase. This internally extends
+PHPUnit\_Framework\_TestCase, so you have access to all of your
+usual PHPUnit methods.
+
+We need to provide a simple way to modify the globals and the
+common function output. We also need to be able to mock up
+the super object as we please.
+
+Current API is *not stable*. Names and implementations will change.
+
+    $this->ci_set_config($key, $val)
+
+Set the global config variables. If key is an array, it will
+replace the entire config array. They are _not_ merged.
+
+    $this->ci_instance($obj)
+
+Set the object to use as the "super object", in a lot
+of cases this will be a simple stdClass with the attributes
+you need it to have. If no parameter, will return the instance.
+
+	$this->ci_instance_var($name, $val)
+
+Add an attribute to the super object. This is useful if you
+set up a simple instance in setUp and then need to add different
+class mockups to your super object.
+
+	$this->ci_core_class($name)
+
+Get the _class name_ of a core class, so that you can instantiate
+it. The variable is returned by reference and is tied to the correct
+$GLOBALS key. For example:
+    
+	$cfg =& $this->ci_core_class('cfg'); // returns 'CI_Config'
+    $cfg = new $cfg; // instantiates config and overwrites the CFG global
+
+	$this->ci_set_core_class($name, $obj)
+	
+An alternative way to set one of the core globals.
+
+	$this->ci_get_config()  __internal__
+	
+Returns the global config array. Internal as you shouldn't need to
+call this (you're setting it, after all). Used internally to make
+CI's get_config() work.
+
+	CI_TestCase::instance()  __internal__
+
+Returns an instance of the current test case. We force phpunit to
+run with backup-globals enabled, so this will always be the instance
+of the currently running test class.
+
+### Going forward
+
+#### 1. Bootstrap Test
+
+Testing common.php should be pretty simple. Include the file, and test the
+functions. May require some tweaking so that we can grab the statics from all
+methods (see is_loaded()). Testing the actual CodeIgniter.php file will most
+likely be an output test for the default view, with some object checking after
+the file runs. Needs consideration.
+
+#### 2. System Test
+
+Testing the core system relies on being able to isolate the core components
+as much as possible. A few of them access other core classes as globals. These
+should be mocked up and easy to manipulate.
+
+All functions in common.php should be a minimal implementation, or and mapped
+to a method in the test's parent class to gives us full control of their output.
+
+#### 3. Application Test:
+
+Not sure yet, needs to handle:
+
+- Libraries
+- Helpers
+- Models
+- MY_* files
+- Controllers (uh...?)
+- Views? (watir, selenium, cucumber?)
+- Database Testing
+
+#### 4. Package Test:
+
+I don't have a clue how this will work.
+
+Needs to be able to handle packages
+that are used multiple times within the application (i.e. EE/Pyro modules)
+as well as packages that are used by multiple applications (library distributions)
diff --git a/tests/codeigniter/Setup_test.php b/tests/codeigniter/Setup_test.php
new file mode 100644
index 0000000..550245f
--- /dev/null
+++ b/tests/codeigniter/Setup_test.php
@@ -0,0 +1,13 @@
+<?php
+
+class Setup_test extends PHPUnit_Framework_TestCase {
+	
+	function test_nonsense()
+	{
+		$this->markTestIncomplete('not implemented');
+		// ensure that our bootstrapped test environment
+		// is a good representation of an isolated CI install
+		//die('here');
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/core/Common_test.php b/tests/codeigniter/core/Common_test.php
new file mode 100644
index 0000000..dded2e8
--- /dev/null
+++ b/tests/codeigniter/core/Common_test.php
@@ -0,0 +1,13 @@
+<?php
+
+class Common_test extends CI_TestCase {
+	
+	// ------------------------------------------------------------------------
+	
+	public function test_is_php()
+	{
+		$this->assertEquals(TRUE, is_php('1.2.0'));
+		$this->assertEquals(FALSE, is_php('9999.9.9'));
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/core/Config_test.php b/tests/codeigniter/core/Config_test.php
new file mode 100644
index 0000000..30f0cc6
--- /dev/null
+++ b/tests/codeigniter/core/Config_test.php
@@ -0,0 +1,93 @@
+<?php
+
+class Config_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$cls =& $this->ci_core_class('cfg');
+				
+		// set predictable config values
+		$this->ci_set_config(array(
+			'index_page'		=> 'index.php',
+			'base_url'			=> 'http://example.com/',
+			'subclass_prefix'	=> 'MY_'
+		));
+
+		$this->config = new $cls;	
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_item()
+	{
+		$this->assertEquals('http://example.com/', $this->config->item('base_url'));
+
+		// Bad Config value
+		$this->assertFalse($this->config->item('no_good_item'));
+		
+		// Index
+		$this->assertFalse($this->config->item('no_good_item', 'bad_index'));
+		$this->assertFalse($this->config->item('no_good_item', 'default'));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_set_item()
+	{
+		$this->assertFalse($this->config->item('not_yet_set'));
+		
+		$this->config->set_item('not_yet_set', 'is set');
+		
+		$this->assertEquals('is set', $this->config->item('not_yet_set'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_slash_item()
+	{
+		// Bad Config value
+		$this->assertFalse($this->config->slash_item('no_good_item'));
+		
+		$this->assertEquals('http://example.com/', $this->config->slash_item('base_url'));
+
+		$this->assertEquals('MY_/', $this->config->slash_item('subclass_prefix'));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_site_url()
+	{
+		$this->assertEquals('http://example.com/index.php', $this->config->site_url());
+		
+		$base_url = $this->config->item('base_url');
+		
+		$this->config->set_item('base_url', '');
+		
+		$q_string = $this->config->item('enable_query_strings');
+		
+		$this->config->set_item('enable_query_strings', FALSE);
+
+		$this->assertEquals('index.php/test', $this->config->site_url('test'));
+		$this->assertEquals('index.php/test/1', $this->config->site_url(array('test', '1')));
+		
+		$this->config->set_item('enable_query_strings', TRUE);
+
+		$this->assertEquals('index.php?test', $this->config->site_url('test'));
+		$this->assertEquals('index.php?0=test&1=1', $this->config->site_url(array('test', '1')));
+		
+		$this->config->set_item('base_url', $base_url);
+
+		$this->assertEquals('http://example.com/index.php?test', $this->config->site_url('test'));
+		
+		// back to home base
+		$this->config->set_item('enable_query_strings', $q_string);				
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_system_url()
+	{
+		$this->assertEquals('http://example.com/system/', $this->config->system_url());
+	}
+
+}
\ No newline at end of file
diff --git a/tests/codeigniter/core/Lang_test.php b/tests/codeigniter/core/Lang_test.php
new file mode 100644
index 0000000..a414f0a
--- /dev/null
+++ b/tests/codeigniter/core/Lang_test.php
@@ -0,0 +1,31 @@
+<?php
+
+class Lang_test extends CI_TestCase {
+	
+	protected $lang;
+	
+	public function set_up()
+	{
+		$loader_cls = $this->ci_core_class('load');
+		$this->ci_instance_var('load', new $loader_cls);
+
+		$cls = $this->ci_core_class('lang');
+		$this->lang = new $cls;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_load()
+	{
+		$this->assertTrue($this->lang->load('profiler', 'english'));
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_line()
+	{
+		$this->assertTrue($this->lang->load('profiler', 'english'));
+		$this->assertEquals('URI STRING', $this->lang->line('profiler_uri_string'));
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/core/Loader_test.php b/tests/codeigniter/core/Loader_test.php
new file mode 100644
index 0000000..4300865
--- /dev/null
+++ b/tests/codeigniter/core/Loader_test.php
@@ -0,0 +1,235 @@
+<?php
+
+class Loader_test extends CI_TestCase {
+	
+	private $ci_obj;
+	
+	public function set_up()
+	{
+		// Instantiate a new loader
+		$this->load = new Mock_Core_Loader();
+		
+		// mock up a ci instance
+		$this->ci_obj = new StdClass;
+		
+		// Fix get_instance()
+		$this->ci_instance($this->ci_obj);
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_library()
+	{
+		$this->_setup_config_mock();
+		
+		// Test loading as an array.
+		$this->assertNull($this->load->library(array('table')));
+		$this->assertTrue(class_exists('CI_Table'), 'Table class exists');
+		$this->assertAttributeInstanceOf('CI_Table', 'table', $this->ci_obj);
+		
+		// Test no lib given
+		$this->assertEquals(FALSE, $this->load->library());
+		
+		// Test a string given to params
+		$this->assertEquals(NULL, $this->load->library('table', ' '));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_load_library_in_application_dir()
+	{
+		$this->_setup_config_mock();
+		
+		$content = '<?php class Super_test_library {} ';
+		
+		$model = vfsStream::newFile('Super_test_library.php')->withContent($content)
+														->at($this->load->libs_dir);
+		
+		$this->assertNull($this->load->library('super_test_library'));
+		
+		// Was the model class instantiated.
+		$this->assertTrue(class_exists('Super_test_library'));		
+	}
+	
+	// --------------------------------------------------------------------
+	
+	private function _setup_config_mock()
+	{
+		// Mock up a config object until we
+		// figure out how to test the library configs
+		$config = $this->getMock('CI_Config', NULL, array(), '', FALSE);
+		$config->expects($this->any())
+			   ->method('load')
+			   ->will($this->returnValue(TRUE));
+		
+		// Add the mock to our stdClass
+		$this->ci_instance_var('config', $config);
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_non_existent_model()
+	{
+		$this->setExpectedException(
+			'RuntimeException',
+			'CI Error: Unable to locate the model you have specified: ci_test_nonexistent_model.php'
+			);
+			
+		$this->load->model('ci_test_nonexistent_model.php');
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * @coverts CI_Loader::model
+	 */
+	public function test_models()
+	{
+		$this->ci_set_core_class('model', 'CI_Model');
+		
+		$content = '<?php class Unit_test_model extends CI_Model {} ';
+		
+		$model = vfsStream::newFile('unit_test_model.php')->withContent($content)
+														->at($this->load->models_dir);
+		
+		$this->assertNull($this->load->model('unit_test_model'));
+		
+		// Was the model class instantiated.
+		$this->assertTrue(class_exists('Unit_test_model'));
+		
+		// Test no model given
+		$this->assertNull($this->load->model(''));	
+	}
+
+	// --------------------------------------------------------------------
+	
+	// public function testDatabase()
+	// {
+	// 	$this->assertEquals(NULL, $this->load->database());
+	// 	$this->assertEquals(NULL, $this->load->dbutil());		
+	// }
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * @coverts CI_Loader::view
+	 */
+	public function test_load_view()
+	{
+		$this->ci_set_core_class('output', 'CI_Output');
+		
+		$content = 'This is my test page.  <?php echo $hello; ?>';
+		$view = vfsStream::newFile('unit_test_view.php')->withContent($content)
+														->at($this->load->views_dir);
+		
+		// Use the optional return parameter in this test, so the view is not
+		// run through the output class.
+		$this->assertEquals('This is my test page.  World!',
+		$this->load->view('unit_test_view', array('hello' => "World!"), TRUE));
+		
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * @coverts CI_Loader::view
+	 */
+	public function test_non_existent_view()
+	{
+		$this->setExpectedException(
+			'RuntimeException',
+			'CI Error: Unable to load the requested file: ci_test_nonexistent_view.php'
+			);
+			
+		$this->load->view('ci_test_nonexistent_view', array('foo' => 'bar'));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_file()
+	{
+		$content = 'Here is a test file, which we will load now.';
+		$file = vfsStream::newFile('ci_test_mock_file.php')->withContent($content)
+														   ->at($this->load->views_dir);
+		
+		// Just like load->view(), take the output class out of the mix here.
+		$load = $this->load->file(vfsStream::url('application').'/views/ci_test_mock_file.php', 
+								TRUE);
+		
+		$this->assertEquals($content, $load);
+		
+		$this->setExpectedException(
+			'RuntimeException',
+			'CI Error: Unable to load the requested file: ci_test_file_not_exists'
+			);
+		
+		$this->load->file('ci_test_file_not_exists', TRUE);
+		
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_vars()
+	{
+		$vars = array(
+			'foo'	=> 'bar'
+		);
+		
+		$this->assertNull($this->load->vars($vars));
+		$this->assertNull($this->load->vars('foo', 'bar'));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_helper()
+	{
+		$this->assertEquals(NULL, $this->load->helper('array'));
+		
+		$this->setExpectedException(
+			'RuntimeException',
+			'CI Error: Unable to load the requested file: helpers/bad_helper.php'
+			);
+		
+		$this->load->helper('bad');
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_loading_multiple_helpers()
+	{
+		$this->assertEquals(NULL, $this->load->helpers(array('file', 'array', 'string')));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	// public function testLanguage()
+	// {
+	// 	$this->assertEquals(NULL, $this->load->language('test'));
+	// }	
+
+	// --------------------------------------------------------------------
+
+	public function test_load_config()
+	{
+		$this->_setup_config_mock();
+		
+		$this->assertNull($this->load->config('config', FALSE));
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_load_bad_config()
+	{
+		$this->_setup_config_mock();
+		
+		$this->setExpectedException(
+			'RuntimeException',
+			'CI Error: The configuration file foobar.php does not exist.'
+			);
+		
+		$this->load->config('foobar', FALSE);
+	}
+
+	// --------------------------------------------------------------------
+	
+}
diff --git a/tests/codeigniter/core/URI_test.php b/tests/codeigniter/core/URI_test.php
new file mode 100644
index 0000000..e340ddf
--- /dev/null
+++ b/tests/codeigniter/core/URI_test.php
@@ -0,0 +1,313 @@
+<?php
+
+class URI_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->uri = new Mock_Core_URI();
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_set_uri_string()
+	{
+		// Slashes get killed
+		$this->uri->_set_uri_string('/');
+		
+		$a = '';
+		$b =& $this->uri->uri_string;
+		
+		$this->assertEquals($a, $b);
+		
+		$this->uri->_set_uri_string('nice/uri');
+		
+		$a = 'nice/uri';
+		
+		$this->assertEquals($a, $b);
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_fetch_uri_string()
+	{
+		define('SELF', 'index.php');
+
+		// uri_protocol: AUTO
+		$this->uri->config->set_item('uri_protocol', 'AUTO');
+		
+		// Test a variety of request uris
+		$requests = array(
+			'/index.php/controller/method' => 'controller/method',
+			'/index.php?/controller/method' => 'controller/method',
+			'/index.php?/controller/method/?var=foo' => 'controller/method'
+		);
+		
+		foreach($requests as $request => $expected)
+		{
+			$_SERVER['SCRIPT_NAME'] = '/index.php';
+			$_SERVER['REQUEST_URI'] = $request;
+			
+			$this->uri->_fetch_uri_string();
+			$this->assertEquals($expected, $this->uri->uri_string );
+		}
+		
+		// Test a subfolder
+		$_SERVER['SCRIPT_NAME'] = '/subfolder/index.php';
+		$_SERVER['REQUEST_URI'] = '/subfolder/index.php/controller/method';
+		
+		$this->uri->_fetch_uri_string();
+		
+		$a = 'controller/method';
+		$b = $this->uri->uri_string;
+		
+		$this->assertEquals($a, $b);
+		
+		// death to request uri
+		unset($_SERVER['REQUEST_URI']);
+		
+		// life to path info
+		$_SERVER['PATH_INFO'] = '/controller/method/';
+		
+		$this->uri->_fetch_uri_string();
+		
+		$a = '/controller/method/';
+		$b =& $this->uri->uri_string;
+
+		$this->assertEquals($a, $b);
+		
+		// death to path info
+		// At this point your server must be seriously drunk
+		unset($_SERVER['PATH_INFO']);
+		
+		$_SERVER['QUERY_STRING'] = '/controller/method/';
+		
+		$this->uri->_fetch_uri_string();
+
+		$a = '/controller/method/';
+		$b = $this->uri->uri_string;
+		
+		$this->assertEquals($a, $b);
+		
+		// At this point your server is a labotomy victim
+		
+		unset($_SERVER['QUERY_STRING']);
+		
+		$_GET['/controller/method/'] = '';
+		
+		$this->uri->_fetch_uri_string();
+		$this->assertEquals($a, $b);
+
+		// Test coverage implies that these will work
+		// uri_protocol: REQUEST_URI
+		// uri_protocol: CLI
+				
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_explode_segments()
+	{
+		// Lets test the function's ability to clean up this mess
+		$uris = array(
+			'test/uri' => array('test', 'uri'),
+			'/test2/uri2' => array('test2', 'uri2'),
+			'//test3/test3///' => array('test3', 'test3')
+		);
+		
+		foreach($uris as $uri => $a)
+		{
+			$this->uri->segments = array();
+			$this->uri->uri_string = $uri;
+			$this->uri->_explode_segments();
+			
+			$b = $this->uri->segments;
+			
+			$this->assertEquals($a, $b);
+		}
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_filter_uri()
+	{
+		$this->uri->config->set_item('enable_query_strings', FALSE);
+		$this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-');
+		
+		$str_in = 'abc01239~%.:_-';
+		$str = $this->uri->_filter_uri($str_in);
+
+		$this->assertEquals($str, $str_in);
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_filter_uri_escaping()
+	{
+		// ensure escaping even if dodgey characters are permitted
+		
+		$this->uri->config->set_item('enable_query_strings', FALSE);
+		$this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-()$');
+
+		$str = $this->uri->_filter_uri('$destroy_app(foo)');
+		
+		$this->assertEquals($str, '&#36;destroy_app&#40;foo&#41;');
+	}
+
+	// --------------------------------------------------------------------
+
+    public function test_filter_uri_throws_error()
+    {
+		$this->setExpectedException('RuntimeException');
+		
+		$this->uri->config->set_item('enable_query_strings', FALSE);
+		$this->uri->config->set_item('permitted_uri_chars', 'a-z 0-9~%.:_\-');
+		$this->uri->_filter_uri('$this()');
+    }
+
+	// --------------------------------------------------------------------
+
+	public function test_remove_url_suffix()
+	{
+		$this->uri->config->set_item('url_suffix', '.html');
+		
+		$this->uri->uri_string = 'controller/method/index.html';
+		$this->uri->_remove_url_suffix();
+		
+		$this->assertEquals($this->uri->uri_string, 'controller/method/index');
+		
+		$this->uri->uri_string = 'controller/method/index.htmlify.html';
+		$this->uri->_remove_url_suffix();
+		
+		$this->assertEquals($this->uri->uri_string, 'controller/method/index.htmlify');
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_segment()
+	{
+		$this->uri->segments = array(1 => 'controller');
+		$this->assertEquals($this->uri->segment(1), 'controller');
+		$this->assertEquals($this->uri->segment(2, 'default'), 'default');
+	}
+	
+	// --------------------------------------------------------------------
+
+	public function test_rsegment()
+	{
+		$this->uri->rsegments = array(1 => 'method');
+		$this->assertEquals($this->uri->rsegment(1), 'method');
+		$this->assertEquals($this->uri->rsegment(2, 'default'), 'default');
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_uri_to_assoc()
+	{
+		$this->uri->segments = array('a', '1', 'b', '2', 'c', '3');
+		
+		$a = array('a' => '1', 'b' => '2', 'c' => '3');
+		$b = $this->uri->uri_to_assoc(1);
+		$this->assertEquals($a, $b);
+		
+		$a = array('b' => '2', 'c' => '3');
+		$b = $this->uri->uri_to_assoc(3);
+		$this->assertEquals($a, $b);
+		
+		
+		$this->uri->keyval = array(); // reset cache
+				
+		$this->uri->segments = array('a', '1', 'b', '2', 'c');
+		
+		$a = array('a' => '1', 'b' => '2', 'c' => FALSE);
+		$b = $this->uri->uri_to_assoc(1);
+		$this->assertEquals($a, $b);
+		
+		$this->uri->keyval = array(); // reset cache
+		
+		$this->uri->segments = array('a', '1');
+		
+		// test default
+		$a = array('a' => '1', 'b' => FALSE);
+		$b = $this->uri->uri_to_assoc(1, array('a', 'b'));
+		$this->assertEquals($a, $b);
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_ruri_to_assoc()
+	{
+		$this->uri->rsegments = array('x', '1', 'y', '2', 'z', '3');
+		
+		$a = array('x' => '1', 'y' => '2', 'z' => '3');
+		$b = $this->uri->ruri_to_assoc(1);
+		$this->assertEquals($a, $b);
+		
+		$a = array('y' => '2', 'z' => '3');
+		$b = $this->uri->ruri_to_assoc(3);
+		$this->assertEquals($a, $b);
+		
+		
+		$this->uri->keyval = array(); // reset cache
+				
+		$this->uri->rsegments = array('x', '1', 'y', '2', 'z');
+		
+		$a = array('x' => '1', 'y' => '2', 'z' => FALSE);
+		$b = $this->uri->ruri_to_assoc(1);
+		$this->assertEquals($a, $b);
+		
+		$this->uri->keyval = array(); // reset cache
+		
+		$this->uri->rsegments = array('x', '1');
+		
+		// test default
+		$a = array('x' => '1', 'y' => FALSE);
+		$b = $this->uri->ruri_to_assoc(1, array('x', 'y'));
+		$this->assertEquals($a, $b);
+
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_assoc_to_uri()
+	{
+		$this->uri->config->set_item('uri_string_slashes', 'none');
+		
+		$arr = array('a' => 1, 'b' => 2);
+		$a = 'a/1/b/2';
+		$b = $this->uri->assoc_to_uri($arr);
+		$this->assertEquals($a, $b);
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_slash_segment()
+	{
+		$this->uri->segments[1] = 'segment';
+		$this->uri->rsegments[1] = 'segment';
+
+		$a = '/segment/';
+		$b = $this->uri->slash_segment(1, 'both');
+		$this->assertEquals($a, $b);
+		$b = $this->uri->slash_rsegment(1, 'both');
+		$this->assertEquals($a, $b);
+		
+		$a = '/segment';
+		$b = $this->uri->slash_segment(1, 'leading');
+		$this->assertEquals($a, $b);
+		$b = $this->uri->slash_rsegment(1, 'leading');
+		$this->assertEquals($a, $b);
+		
+		$a = 'segment/';
+		$b = $this->uri->slash_segment(1, 'trailing');
+		$this->assertEquals($a, $b);
+		$b = $this->uri->slash_rsegment(1, 'trailing');
+		$this->assertEquals($a, $b);
+	}
+
+
+}
+// END URI_test Class
+
+/* End of file URI_test.php */
+/* Location: ./tests/core/URI_test.php */
diff --git a/tests/codeigniter/database/DB_test.php b/tests/codeigniter/database/DB_test.php
new file mode 100644
index 0000000..9b93e22
--- /dev/null
+++ b/tests/codeigniter/database/DB_test.php
@@ -0,0 +1,49 @@
+<?php
+
+class DB_test extends CI_TestCase {
+
+	// ------------------------------------------------------------------------
+
+	public function test_db_invalid()
+	{
+		$connection = new Mock_Database_DB(array(
+			'undefined' => array(
+				'dsn' => '',
+				'hostname' => 'undefined',
+				'username' => 'undefined',
+				'password' => 'undefined',
+				'database' => 'undefined',
+				'dbdriver' => 'undefined',
+			),
+		));
+
+		$this->setExpectedException('InvalidArgumentException', 'CI Error: Invalid DB driver');
+
+		Mock_Database_DB::DB($connection->set_dsn('undefined'), TRUE);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_db_valid()
+	{
+		$config = Mock_Database_DB::config(DB_DRIVER);
+		$connection = new Mock_Database_DB($config);
+		$db = Mock_Database_DB::DB($connection->set_dsn(DB_DRIVER), TRUE);
+
+		$this->assertTrue($db instanceof CI_DB);
+		$this->assertTrue($db instanceof CI_DB_Driver);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_db_failover()
+	{
+		$config = Mock_Database_DB::config(DB_DRIVER);
+		$connection = new Mock_Database_DB($config);
+		$db = Mock_Database_DB::DB($connection->set_dsn(DB_DRIVER.'_failover'), TRUE);
+
+		$this->assertTrue($db instanceof CI_DB);
+		$this->assertTrue($db instanceof CI_DB_Driver);
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/database/query_builder/.gitkeep b/tests/codeigniter/database/query_builder/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/codeigniter/database/query_builder/.gitkeep
diff --git a/tests/codeigniter/helpers/array_helper_test.php b/tests/codeigniter/helpers/array_helper_test.php
new file mode 100644
index 0000000..9cd1596
--- /dev/null
+++ b/tests/codeigniter/helpers/array_helper_test.php
@@ -0,0 +1,47 @@
+<?php
+
+class Array_helper_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->helper('array');
+
+		$this->my_array = array(
+			'foo'		=> 'bar',
+			'sally'		=> 'jim',
+			'maggie'	=> 'bessie',
+			'herb'		=> 'cook'
+		);
+	}
+	
+	// ------------------------------------------------------------------------
+	
+	public function test_element_with_existing_item()
+	{	
+		$this->assertEquals(FALSE, element('testing', $this->my_array));
+		
+		$this->assertEquals('not set', element('testing', $this->my_array, 'not set'));
+		
+		$this->assertEquals('bar', element('foo', $this->my_array));
+	}
+	
+	// ------------------------------------------------------------------------	
+
+	public function test_random_element()
+	{
+		// Send a string, not an array to random_element
+		$this->assertEquals('my string', random_element('my string'));
+		
+		// Test sending an array
+		$this->assertEquals(TRUE, in_array(random_element($this->my_array), $this->my_array));
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	public function test_elements()
+	{
+		$this->assertEquals(TRUE, is_array(elements('test', $this->my_array)));
+		$this->assertEquals(TRUE, is_array(elements('foo', $this->my_array)));
+	}
+
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/date_helper_test.php b/tests/codeigniter/helpers/date_helper_test.php
new file mode 100644
index 0000000..17d1ef2
--- /dev/null
+++ b/tests/codeigniter/helpers/date_helper_test.php
@@ -0,0 +1,288 @@
+<?php
+
+class Date_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('date');
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_now_local()
+	{
+		// This stub job, is simply to cater $config['time_reference']
+		$config = $this->getMock('CI_Config');
+		$config->expects($this->any())
+			   ->method('item')
+			   ->will($this->returnValue('local'));
+		
+		// Add the stub to our test instance
+		$this->ci_instance_var('config', $config);
+
+		$expected = time();
+		$test = now();
+		$this->assertEquals($expected, $test);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_now_gmt()
+	{
+		// This stub job, is simply to cater $config['time_reference']
+		$config = $this->getMock('CI_Config');
+		$config->expects($this->any())
+			   ->method('item')
+			   ->will($this->returnValue('gmt'));
+		
+		// Add the stub to our stdClass
+		$this->ci_instance_var('config', $config);
+
+		$t = time();
+		$expected = mktime(gmdate("H", $t), gmdate("i", $t), gmdate("s", $t), gmdate("m", $t), gmdate("d", $t), gmdate("Y", $t));
+		$test = now();
+		$this->assertEquals($expected, $test);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_mdate()
+	{
+		$time = time();
+		$expected = date("Y-m-d - h:i a", $time);
+		$test = mdate("%Y-%m-%d - %h:%i %a", $time);
+		$this->assertEquals($expected, $test);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rfc822()
+	{
+		$time = time();
+		$format = 'DATE_RFC822';
+		$expected = date("D, d M y H:i:s O", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_atom()
+	{
+		$time = time();
+		$format = 'DATE_ATOM';
+		$expected = date("Y-m-d\TH:i:sO", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_cookie()
+	{
+		$time = time();
+		$format = 'DATE_COOKIE';
+		$expected = date("l, d-M-y H:i:s \U\T\C", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_iso8601()
+	{
+		$time = time();
+		$format = 'DATE_ISO8601';
+		$expected = date("Y-m-d\TH:i:sO", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rfc850()
+	{
+		$time = time();
+		$format = 'DATE_RFC850';
+		$expected = date("l, d-M-y H:i:s \U\T\C", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rfc1036()
+	{
+		$time = time();
+		$format = 'DATE_RFC1036';
+		$expected = date("D, d M y H:i:s O", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rfc1123()
+	{
+		$time = time();
+		$format = 'DATE_RFC1123';
+		$expected = date("D, d M Y H:i:s O", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rfc2822()
+	{
+		$time = time();
+		$format = 'DATE_RFC2822';
+		$expected = date("D, d M Y H:i:s O", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_rss()
+	{
+		$time = time();
+		$format = 'DATE_RSS';
+		$expected = date("D, d M Y H:i:s O", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_standard_date_w3c()
+	{
+		$time = time();
+		$format = 'DATE_W3C';
+		$expected = date("Y-m-d\TH:i:sO", $time);
+		$this->assertEquals($expected, standard_date($format, $time));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_timespan()
+	{
+		$loader_cls = $this->ci_core_class('load');
+		$this->ci_instance_var('load', new $loader_cls);
+
+		$lang_cls = $this->ci_core_class('lang');
+		$this->ci_instance_var('lang', new $lang_cls);
+
+		$this->assertEquals('1 Second', timespan(time(), time()+1));
+		$this->assertEquals('1 Minute', timespan(time(), time()+60));
+		$this->assertEquals('1 Hour', timespan(time(), time()+3600));
+		$this->assertEquals('2 Hours', timespan(time(), time()+7200));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_days_in_month()
+	{
+		$this->assertEquals(30, days_in_month(06, 2005));
+		$this->assertEquals(28, days_in_month(02, 2011));
+		$this->assertEquals(29, days_in_month(02, 2012));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_local_to_gmt()
+	{
+		$t = time();
+		$expected = mktime(gmdate("H", $t), gmdate("i", $t), gmdate("s", $t), gmdate("m", $t), gmdate("d", $t), gmdate("Y", $t));
+		$this->assertEquals($expected, local_to_gmt($t));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_gmt_to_local()
+	{
+		$timestamp = '1140153693';
+		$timezone = 'UM8';
+		$daylight_saving = TRUE;
+
+		$this->assertEquals(1140128493, gmt_to_local($timestamp, $timezone, $daylight_saving));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_mysql_to_unix()
+	{
+		$time = time();
+		$this->assertEquals($time, 
+				mysql_to_unix(date("Y-m-d H:i:s", $time)));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_unix_to_human()
+	{
+		$time = time();
+		$this->assertEquals(date("Y-m-d h:i A", $time), unix_to_human($time));
+		$this->assertEquals(date("Y-m-d h:i:s A", $time), unix_to_human($time, TRUE, 'us'));
+		$this->assertEquals(date("Y-m-d H:i:s", $time), unix_to_human($time, TRUE, 'eu'));
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_human_to_unix()
+	{
+		$date = '2000-12-31 10:00:00 PM';
+		$expected = strtotime($date);
+		$this->assertEquals($expected, human_to_unix($date));
+		$this->assertFalse(human_to_unix());
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_timezones()
+	{
+		$zones = array(
+			'UM12'		=> -12,
+			'UM11'		=> -11,
+			'UM10'		=> -10,
+			'UM95'		=> -9.5,
+			'UM9'		=> -9,
+			'UM8'		=> -8,
+			'UM7'		=> -7,
+			'UM6'		=> -6,
+			'UM5'		=> -5,
+			'UM45'		=> -4.5,
+			'UM4'		=> -4,
+			'UM35'		=> -3.5,
+			'UM3'		=> -3,
+			'UM2'		=> -2,
+			'UM1'		=> -1,
+			'UTC'		=> 0,
+			'UP1'		=> +1,
+			'UP2'		=> +2,
+			'UP3'		=> +3,
+			'UP35'		=> +3.5,
+			'UP4'		=> +4,
+			'UP45'		=> +4.5,
+			'UP5'		=> +5,
+			'UP55'		=> +5.5,
+			'UP575'		=> +5.75,
+			'UP6'		=> +6,
+			'UP65'		=> +6.5,
+			'UP7'		=> +7,
+			'UP8'		=> +8,
+			'UP875'		=> +8.75,
+			'UP9'		=> +9,
+			'UP95'		=> +9.5,
+			'UP10'		=> +10,
+			'UP105'		=> +10.5,
+			'UP11'		=> +11,
+			'UP115'		=> +11.5,
+			'UP12'		=> +12,
+			'UP1275'	=> +12.75,
+			'UP13'		=> +13,
+			'UP14'		=> +14
+		);
+
+		foreach ($zones AS $test => $expected)
+		{
+			$this->assertEquals($expected, timezones($test));
+		}
+
+		$this->assertArrayHasKey('UP3', timezones());
+		$this->assertEquals(0, timezones('non_existant'));
+	}
+}
+
+/* End of file date_helper_test.php */
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/directory_helper_test.php b/tests/codeigniter/helpers/directory_helper_test.php
new file mode 100644
index 0000000..3937d29
--- /dev/null
+++ b/tests/codeigniter/helpers/directory_helper_test.php
@@ -0,0 +1,41 @@
+<?php
+
+class Directory_helper_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->helper('directory');
+
+		vfsStreamWrapper::register();
+		vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir'));
+		
+		$this->_test_dir = vfsStreamWrapper::getRoot();
+	}	
+	
+	public function test_directory_map()
+	{
+		$structure = array('libraries' => array('benchmark.html' => '', 'database' =>
+			array('active_record.html' => '', 'binds.html' => ''), 'email.html' => '', '.hiddenfile.txt' => ''));
+		
+		vfsStream::create($structure, $this->_test_dir);
+
+		// test default recursive behavior
+		$expected = array('libraries' => array('benchmark.html', 'database' =>
+			array('active_record.html', 'binds.html'), 'email.html'));
+			
+		$this->assertEquals($expected, directory_map(vfsStream::url('testDir')));
+
+		// test recursion depth behavior
+		$expected = array('libraries');
+			
+		$this->assertEquals($expected, directory_map(vfsStream::url('testDir'), 1));
+
+		// test detection of hidden files
+		$expected = array('libraries' => array('benchmark.html', 'database' =>
+			array('active_record.html', 'binds.html'), 'email.html', '.hiddenfile.txt'));
+			
+		$this->assertEquals($expected, directory_map(vfsStream::url('testDir'), FALSE, TRUE));
+  }  
+}
+
+/* End of file directory_helper_test.php */
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/email_helper_test.php b/tests/codeigniter/helpers/email_helper_test.php
new file mode 100644
index 0000000..a01f3d5
--- /dev/null
+++ b/tests/codeigniter/helpers/email_helper_test.php
@@ -0,0 +1,18 @@
+<?php
+
+class Email_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('email');
+	}
+
+	public function test_valid_email()
+	{
+		$this->assertEquals(FALSE, valid_email('test'));
+		$this->assertEquals(FALSE, valid_email('test@test@test.com'));
+		$this->assertEquals(TRUE, valid_email('test@test.com'));
+		$this->assertEquals(TRUE, valid_email('my.test@test.com'));
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/file_helper_test.php b/tests/codeigniter/helpers/file_helper_test.php
new file mode 100644
index 0000000..4b9c294
--- /dev/null
+++ b/tests/codeigniter/helpers/file_helper_test.php
@@ -0,0 +1,156 @@
+<?php
+
+class File_helper_Test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('file');
+		
+		vfsStreamWrapper::register();
+		vfsStreamWrapper::setRoot(new vfsStreamDirectory('testDir'));
+		
+		$this->_test_dir = vfsStreamWrapper::getRoot();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_read_file()
+	{
+		$this->assertFalse(read_file('does_not_exist'));
+		
+		$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+		
+		$file = vfsStream::newFile('my_file.txt')->withContent($content)
+												 ->at($this->_test_dir);
+		
+		$this->assertEquals($content, read_file(vfsStream::url('my_file.txt')));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_octal_permissions()
+	{
+		$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+		
+		$file = vfsStream::newFile('my_file.txt', 0777)->withContent($content)
+												 ->lastModified(time() - 86400)
+												 ->at($this->_test_dir);
+		
+		$this->assertEquals('777', octal_permissions($file->getPermissions()));		
+	}
+
+	// --------------------------------------------------------------------	
+	
+	/**
+	 * More tests should happen here, since I'm not hitting the whole function.
+	 */
+	public function test_symbolic_permissions()
+	{
+		$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+		
+		$file = vfsStream::newFile('my_file.txt', 0777)->withContent($content)
+												 ->lastModified(time() - 86400)
+												 ->at($this->_test_dir);
+												
+		$this->assertEquals('urwxrwxrwx', symbolic_permissions($file->getPermissions()));		
+	}
+
+	// --------------------------------------------------------------------	
+	
+	public function test_get_mime_by_extension()
+	{
+		$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+		
+		$file = vfsStream::newFile('my_file.txt', 0777)->withContent($content)
+												 ->lastModified(time() - 86400)
+												 ->at($this->_test_dir);
+												
+		$this->assertEquals('text/plain', 
+						get_mime_by_extension(vfsStream::url('my_file.txt')));
+						
+		// Test a mime with an array, such as png		
+		$file = vfsStream::newFile('foo.png')->at($this->_test_dir);
+		
+		$this->assertEquals('image/png', get_mime_by_extension(vfsStream::url('foo.png')));			
+			
+		// Test a file not in the mimes array
+		$file = vfsStream::newFile('foo.blarfengar')->at($this->_test_dir);
+		
+		$this->assertFalse(get_mime_by_extension(vfsStream::url('foo.blarfengar')));
+	}
+
+	// --------------------------------------------------------------------	
+
+	public function test_get_file_info()
+	{
+		// Test Bad File
+		$this->assertFalse(get_file_info('i_am_bad_boo'));
+		
+		// Test the rest
+		
+		// First pass in an array
+		$vals = array(
+			'name', 'server_path', 'size', 'date',
+			'readable', 'writable', 'executable',  'fileperms'
+		);
+		
+		$this->_test_get_file_info($vals);
+
+		// Test passing in vals as a string.
+		$vals = 'name, server_path, size, date, readable, writable, executable, fileperms';
+		$this->_test_get_file_info($vals);
+	}
+	
+	private function _test_get_file_info($vals)
+	{
+		$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+		$last_modified = time() - 86400;
+		
+		$file = vfsStream::newFile('my_file.txt', 0777)->withContent($content)
+												 ->lastModified($last_modified)
+												 ->at($this->_test_dir);
+		
+		$ret_values = array(
+			'name'			=> 'my_file.txt', 
+			'server_path'	=> 'vfs://my_file.txt', 
+			'size'			=> 57, 
+			'date'			=> $last_modified, 
+			'readable'		=> TRUE,
+			'writable'		=> TRUE, 
+			'executable'	=> TRUE, 
+			'fileperms'		=> 33279
+		);
+		
+		$info = get_file_info(vfsStream::url('my_file.txt'), $vals);
+		
+		foreach ($info as $k => $v)
+		{
+			$this->assertEquals($ret_values[$k], $v);
+		}
+	}
+	
+	// --------------------------------------------------------------------	
+
+	// Skipping for now, as it's not implemented in vfsStreamWrapper
+	// flock(): vfsStreamWrapper::stream_lock is not implemented!
+	
+	// public function test_write_file()
+	// {
+	// 	if ( ! defined('FOPEN_WRITE_CREATE_DESTRUCTIVE'))
+	// 	{
+	// 		define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb');
+	// 	}
+	// 	
+	// 	$content = 'Jack and Jill went up the mountain to fight a billy goat.';
+	// 	
+	// 	$file = vfsStream::newFile('write.txt', 0777)->withContent('')
+	// 											 	 ->lastModified(time() - 86400)
+	// 											 	 ->at($this->_test_dir);
+	// 	
+	// 	$this->assertTrue(write_file(vfsStream::url('write.txt'), $content));
+	// 		
+	// }
+
+	// --------------------------------------------------------------------		
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/form_helper_test.php b/tests/codeigniter/helpers/form_helper_test.php
new file mode 100644
index 0000000..80bace9
--- /dev/null
+++ b/tests/codeigniter/helpers/form_helper_test.php
@@ -0,0 +1,252 @@
+<?php
+
+require BASEPATH . 'core/Common.php';
+require BASEPATH . 'helpers/form_helper.php';
+
+class Form_helper_test extends CI_TestCase 
+{
+	public function test_form_hidden()
+	{				
+		$expected = <<<EOH
+
+<input type="hidden" name="username" value="johndoe" />
+
+EOH;
+	
+		$this->assertEquals($expected, form_hidden('username', 'johndoe'));
+	}
+	
+	public function test_form_input()
+	{
+		$expected = <<<EOH
+<input type="text" name="username" value="johndoe" id="username" maxlength="100" size="50" style="width:50%"  />
+
+EOH;
+	
+		$data = array(
+			'name'        => 'username',
+			'id'          => 'username',
+			'value'       => 'johndoe',
+			'maxlength'   => '100',
+			'size'        => '50',
+			'style'       => 'width:50%',
+		);
+
+		$this->assertEquals($expected, form_input($data));
+	}
+	
+	public function test_form_password()
+	{				
+		$expected = <<<EOH
+<input type="password" name="password" value=""  />
+
+EOH;
+	
+		$this->assertEquals($expected, form_password('password'));
+	}
+	
+	public function test_form_upload()
+	{				
+		$expected = <<<EOH
+<input type="file" name="attachment" value=""  />
+
+EOH;
+	
+		$this->assertEquals($expected, form_upload('attachment'));
+	}
+	
+	public function test_form_textarea()
+	{				
+		$expected = <<<EOH
+<textarea name="notes" cols="40" rows="10" >Notes</textarea>
+
+EOH;
+	
+		$this->assertEquals($expected, form_textarea('notes', 'Notes'));
+	}
+	
+	public function test_form_dropdown()
+	{
+		$expected = <<<EOH
+<select name="shirts">
+<option value="small">Small Shirt</option>
+<option value="med">Medium Shirt</option>
+<option value="large" selected="selected">Large Shirt</option>
+<option value="xlarge">Extra Large Shirt</option>
+</select>
+
+EOH;
+		
+		$options = array(
+			'small'  => 'Small Shirt',
+			'med'    => 'Medium Shirt',
+			'large'   => 'Large Shirt',
+			'xlarge' => 'Extra Large Shirt',
+		);
+		
+		$this->assertEquals($expected, form_dropdown('shirts', $options, 'large'));
+		
+		$expected = <<<EOH
+<select name="shirts" multiple="multiple">
+<option value="small" selected="selected">Small Shirt</option>
+<option value="med">Medium Shirt</option>
+<option value="large" selected="selected">Large Shirt</option>
+<option value="xlarge">Extra Large Shirt</option>
+</select>
+
+EOH;
+		
+		$shirts_on_sale = array('small', 'large');
+		
+		$this->assertEquals($expected, form_dropdown('shirts', $options, $shirts_on_sale));
+		
+		$options = array(
+			'Swedish Cars' => array(
+				'volvo'  => 'Volvo',
+				'saab'    => 'Saab'
+			),
+			'German Cars' => array(
+				'mercedes'  => 'Mercedes',
+				'audi'    => 'Audi'
+			)
+		);
+		
+		$expected = <<<EOH
+<select name="cars" multiple="multiple">
+<optgroup label="Swedish Cars">
+<option value="volvo" selected="selected">Volvo</option>
+<option value="saab">Saab</option>
+</optgroup>
+<optgroup label="German Cars">
+<option value="mercedes">Mercedes</option>
+<option value="audi" selected="selected">Audi</option>
+</optgroup>
+</select>
+
+EOH;
+		
+		$cars_on_sale = array('volvo', 'audi');
+		
+		$this->assertEquals($expected, form_dropdown('cars', $options, $cars_on_sale));
+		
+	}
+	
+	public function test_form_multiselect()
+	{
+		$expected = <<<EOH
+<select name="shirts[]"  multiple="multiple">
+<option value="small">Small Shirt</option>
+<option value="med" selected="selected">Medium Shirt</option>
+<option value="large" selected="selected">Large Shirt</option>
+<option value="xlarge">Extra Large Shirt</option>
+</select>
+
+EOH;
+		
+		$options = array(
+                  'small'  => 'Small Shirt',
+                  'med'    => 'Medium Shirt',
+                  'large'   => 'Large Shirt',
+                  'xlarge' => 'Extra Large Shirt',
+                );
+		
+		$this->assertEquals($expected, form_multiselect('shirts[]', $options, array('med', 'large')));
+	}
+	
+	public function test_form_fieldset()
+	{
+		$expected = <<<EOH
+<fieldset>
+<legend>Address Information</legend>
+
+EOH;
+		
+		$this->assertEquals($expected, form_fieldset('Address Information'));
+	}
+
+	public function test_form_fieldset_close()
+	{
+		$expected = <<<EOH
+</fieldset></div></div>
+EOH;
+		
+		$this->assertEquals($expected, form_fieldset_close('</div></div>'));
+	}
+	
+	public function test_form_checkbox()
+	{
+		$expected = <<<EOH
+<input type="checkbox" name="newsletter" value="accept" checked="checked"  />
+
+EOH;
+
+		$this->assertEquals($expected, form_checkbox('newsletter', 'accept', TRUE));
+	}
+	
+	public function test_form_radio()
+	{
+		$expected = <<<EOH
+<input type="radio" name="newsletter" value="accept" checked="checked"  />
+
+EOH;
+
+		$this->assertEquals($expected, form_radio('newsletter', 'accept', TRUE));
+	}
+	
+	public function test_form_submit()
+	{
+		$expected = <<<EOH
+<input type="submit" name="mysubmit" value="Submit Post!"  />
+
+EOH;
+
+		$this->assertEquals($expected, form_submit('mysubmit', 'Submit Post!'));
+	}
+	
+	public function test_form_label()
+	{
+		$expected = <<<EOH
+<label for="username">What is your Name</label>
+EOH;
+
+		$this->assertEquals($expected, form_label('What is your Name', 'username'));
+	}
+	
+	public function test_form_reset()
+	{
+		$expected = <<<EOH
+<input type="reset" name="myreset" value="Reset"  />
+
+EOH;
+
+		$this->assertEquals($expected, form_reset('myreset', 'Reset'));
+	}
+	
+	public function test_form_button()
+	{
+		$expected = <<<EOH
+<button name="name" type="button" >content</button>
+
+EOH;
+
+		$this->assertEquals($expected, form_button('name','content'));
+	}
+	
+	public function test_form_close()
+	{
+		$expected = <<<EOH
+</form></div></div>
+EOH;
+
+		$this->assertEquals($expected, form_close('</div></div>'));
+	}
+	
+	public function test_form_prep()
+	{
+		$expected = "Here is a string containing &quot;quoted&quot; text.";
+		
+		$this->assertEquals($expected, form_prep('Here is a string containing "quoted" text.'));
+	}
+}
+
+/* End of file form_helper_test.php */
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/html_helper_test.php b/tests/codeigniter/helpers/html_helper_test.php
new file mode 100644
index 0000000..28974b0
--- /dev/null
+++ b/tests/codeigniter/helpers/html_helper_test.php
@@ -0,0 +1,80 @@
+<?php
+
+class Html_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('html');
+	}
+	
+	// ------------------------------------------------------------------------
+	
+	public function test_br()
+	{
+		$this->assertEquals('<br /><br />', br(2));
+	}
+	
+	// ------------------------------------------------------------------------
+	
+	public function test_heading()
+	{
+		$this->assertEquals('<h1>foobar</h1>', heading('foobar'));
+		$this->assertEquals('<h2 class="bar">foobar</h2>', heading('foobar', 2, 'class="bar"'));
+	}
+
+	// ------------------------------------------------------------------------
+	
+	public function test_Ul()
+	{
+		$expect = <<<EOH
+<ul>
+  <li>foo</li>
+  <li>bar</li>
+</ul>
+
+EOH;
+
+		$expect = ltrim($expect);
+
+		$list = array('foo', 'bar');
+		
+		$this->assertEquals($expect, ul($list));
+
+
+		$expect = <<<EOH
+<ul class="test">
+  <li>foo</li>
+  <li>bar</li>
+</ul>
+
+EOH;
+
+		$expect = ltrim($expect);
+
+		$list = array('foo', 'bar');
+
+		$this->assertEquals($expect, ul($list, 'class="test"'));
+
+		$this->assertEquals($expect, ul($list, array('class' => 'test')));
+	}
+	
+	// ------------------------------------------------------------------------
+
+	public function test_NBS()
+	{
+		$this->assertEquals('&nbsp;&nbsp;&nbsp;', nbs(3));
+	}
+
+	// ------------------------------------------------------------------------
+	
+	public function test_meta()
+	{
+		$this->assertEquals("<meta name=\"test\" content=\"foo\" />\n", meta('test', 'foo'));
+		
+		$expect = "<meta name=\"foo\" content=\"\" />\n";
+		
+		$this->assertEquals($expect, meta(array('name' => 'foo')));
+		
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/inflector_helper_test.php b/tests/codeigniter/helpers/inflector_helper_test.php
new file mode 100644
index 0000000..9e94787
--- /dev/null
+++ b/tests/codeigniter/helpers/inflector_helper_test.php
@@ -0,0 +1,95 @@
+<?php
+
+class Inflector_helper_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->helper('inflector');
+	}
+	
+	public function test_singular()
+	{
+		$strs = array(
+			'tellies'		=> 'telly',
+			'smellies'		=> 'smelly',
+			'abjectnesses'	=> 'abjectness',
+			'smells'		=> 'smell',
+			'equipment'		=> 'equipment'
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, singular($str));
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_plural()
+	{
+		$strs = array(
+			'telly'			=> 'tellies',
+			'smelly'		=> 'smellies',
+			'abjectness'	=> 'abjectnesses', // ref : http://en.wiktionary.org/wiki/abjectnesses
+			'smell'			=> 'smells',
+			'witch'			=> 'witches',
+			'equipment'		=> 'equipment'
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, plural($str));
+		}		
+	}	
+
+	// --------------------------------------------------------------------
+	
+	public function test_camelize()
+	{
+		$strs = array(
+			'this is the string'	=> 'thisIsTheString',
+			'this is another one'	=> 'thisIsAnotherOne',
+			'i-am-playing-a-trick'	=> 'i-am-playing-a-trick',
+			'what_do_you_think-yo?'	=> 'whatDoYouThink-yo?',
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, camelize($str));
+		}
+	}	
+
+	// --------------------------------------------------------------------
+	
+	public function test_underscore()
+	{
+		$strs = array(
+			'this is the string'	=> 'this_is_the_string',
+			'this is another one'	=> 'this_is_another_one',
+			'i-am-playing-a-trick'	=> 'i-am-playing-a-trick',
+			'what_do_you_think-yo?'	=> 'what_do_you_think-yo?',
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, underscore($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_humanize()
+	{
+		$strs = array(
+			'this_is_the_string'	=> 'This Is The String',
+			'this_is_another_one'	=> 'This Is Another One',
+			'i-am-playing-a-trick'	=> 'I-am-playing-a-trick',
+			'what_do_you_think-yo?'	=> 'What Do You Think-yo?',
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, humanize($str));
+		}
+	}
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/number_helper_test.php b/tests/codeigniter/helpers/number_helper_test.php
new file mode 100644
index 0000000..4bb9a91
--- /dev/null
+++ b/tests/codeigniter/helpers/number_helper_test.php
@@ -0,0 +1,77 @@
+<?php
+
+class Number_helper_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->helper('number');
+		
+		// Grab the core lang class
+		$lang_cls = $this->ci_core_class('lang');
+		
+		// Mock away load, too much going on in there,
+		// we'll just check for the expected parameter
+		
+		$lang = $this->getMock($lang_cls, array('load'));
+		$lang->expects($this->once())
+			 ->method('load')
+			 ->with($this->equalTo('number'));
+		
+		// Assign the proper language array
+		
+		$lang->language = $this->_get_lang('number');
+		
+		// We don't have a controller, so just create
+		// a cheap class to act as our super object.
+		// Make sure it has a lang attribute.
+		
+		$obj = new StdClass;
+		$obj->lang = $lang;
+		$this->ci_instance($obj);
+	}
+	
+	// Quick helper to actually grab the language
+	// file. Consider moving this to ci_testcase?
+	public function _get_lang($name)
+	{
+		require BASEPATH.'language/english/'.$name.'_lang.php';
+		return $lang;
+	}
+	
+	public function test_byte_format()
+	{
+		$this->assertEquals('456 Bytes', byte_format(456));
+	}
+	
+	public function test_kb_format()
+	{
+		$this->assertEquals('4.5 KB', byte_format(4567));
+	}
+	
+	public function test_kb_format_medium()
+	{
+		$this->assertEquals('44.6 KB', byte_format(45678));
+	}
+	
+	public function test_kb_format_large()
+	{
+		$this->assertEquals('446.1 KB', byte_format(456789));
+	}
+	
+	public function test_mb_format()
+	{
+		$this->assertEquals('3.3 MB', byte_format(3456789));
+	}
+	
+	public function test_gb_format()
+	{
+		$this->assertEquals('1.8 GB', byte_format(1932735283.2));
+	}
+	
+	public function test_tb_format()
+	{
+		$this->assertEquals('112,283.3 TB', byte_format(123456789123456789));
+	}
+}
+
+// EOF
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/path_helper_test.php b/tests/codeigniter/helpers/path_helper_test.php
new file mode 100644
index 0000000..632f575
--- /dev/null
+++ b/tests/codeigniter/helpers/path_helper_test.php
@@ -0,0 +1,32 @@
+<?php
+
+class Path_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('path');
+	}
+
+	public function test_set_realpath()
+	{				
+		$expected = getcwd() . DIRECTORY_SEPARATOR;
+		$this->assertEquals($expected, set_realpath(getcwd()));		
+	}
+
+	public function test_set_realpath_nonexistent_directory()
+	{
+		$expected = '/path/to/nowhere';
+		$this->assertEquals($expected, set_realpath('/path/to/nowhere', FALSE));
+	}
+
+	public function test_set_realpath_error_trigger()
+	{
+		$this->setExpectedException(
+				'RuntimeException', 'CI Error: Not a valid path: /path/to/nowhere'
+		);
+
+		set_realpath('/path/to/nowhere', TRUE);
+	}
+}
+
+/* End of file path_helper_test.php */
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/string_helper_test.php b/tests/codeigniter/helpers/string_helper_test.php
new file mode 100644
index 0000000..29c3d65
--- /dev/null
+++ b/tests/codeigniter/helpers/string_helper_test.php
@@ -0,0 +1,147 @@
+<?php
+
+class String_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('string');
+	}
+
+	public function test_strip_slashes()
+	{
+		$expected = array(
+			"Is your name O'reilly?", 
+			"No, my name is O'connor."
+		);
+		
+		$str = array(
+			"Is your name O\'reilly?",
+			"No, my name is O\'connor."
+		);
+		
+		$this->assertEquals($expected, strip_slashes($str));
+	}
+	
+	public function test_trim_slashes()
+	{
+		$strs = array(
+			'//Slashes//\/'	=> 'Slashes//\\',
+			'/var/www/html/'	=> 'var/www/html'
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, trim_slashes($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_strip_quotes()
+	{
+		$strs = array(
+			'"me oh my!"'		=> 'me oh my!',
+			"it's a winner!"	=> 'its a winner!',
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, strip_quotes($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_quotes_to_entities()
+	{
+		$strs = array(
+			'"me oh my!"'		=> '&quot;me oh my!&quot;',
+			"it's a winner!"	=> 'it&#39;s a winner!',
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, quotes_to_entities($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_reduce_double_slashes()
+	{
+		$strs = array(
+			'http://codeigniter.com'		=> 'http://codeigniter.com',
+			'//var/www/html/example.com/'	=> '/var/www/html/example.com/',
+			'/var/www/html//index.php'		=> '/var/www/html/index.php'
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, reduce_double_slashes($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_reduce_multiples()
+	{
+		$strs = array(
+			'Fred, Bill,, Joe, Jimmy'	=> 'Fred, Bill, Joe, Jimmy',
+			'Ringo, John, Paul,,'		=> 'Ringo, John, Paul,'
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, reduce_multiples($str));
+		}
+
+		$strs = array(
+			'Fred, Bill,, Joe, Jimmy'	=> 'Fred, Bill, Joe, Jimmy',
+			'Ringo, John, Paul,,'		=> 'Ringo, John, Paul'
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, reduce_multiples($str, ',', TRUE));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_repeater()
+	{
+		$strs = array(
+			'a'			=> 'aaaaaaaaaa',
+			'&nbsp;'	=> '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
+			'<br>'		=> '<br><br><br><br><br><br><br><br><br><br>'
+
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, repeater($str, 10));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_random_string()
+	{
+		$this->assertEquals(16, strlen(random_string('alnum', 16)));
+		$this->assertEquals(32, strlen(random_string('unique', 16)));
+		$this->assertInternalType('string', random_string('numeric', 16));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_increment_string()
+	{
+		$this->assertEquals('my-test_1', increment_string('my-test'));
+		$this->assertEquals('my-test-1', increment_string('my-test', '-'));
+		$this->assertEquals('file_5', increment_string('file_4'));
+		$this->assertEquals('file-5', increment_string('file-4', '-'));
+		$this->assertEquals('file-5', increment_string('file-4', '-'));
+		$this->assertEquals('file-1', increment_string('file', '-', '1'));
+		$this->assertEquals(124, increment_string('123', ''));
+	}
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/text_helper_test.php b/tests/codeigniter/helpers/text_helper_test.php
new file mode 100644
index 0000000..584066b
--- /dev/null
+++ b/tests/codeigniter/helpers/text_helper_test.php
@@ -0,0 +1,159 @@
+<?php
+
+class Text_helper_test extends CI_TestCase {
+
+	private $_long_string;
+	
+	public function set_up()
+	{
+		$this->helper('text');
+		
+		$this->_long_string = 'Once upon a time, a framework had no tests.  It sad.  So some nice people began to write tests.  The more time that went on, the happier it became.  Everyone was happy.';
+	}
+	
+	// ------------------------------------------------------------------------
+	
+	public function test_word_limiter()
+	{
+		$this->assertEquals('Once upon a time,&#8230;', word_limiter($this->_long_string, 4));
+		$this->assertEquals('Once upon a time,&hellip;', word_limiter($this->_long_string, 4, '&hellip;'));
+		$this->assertEquals('', word_limiter('', 4));
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	public function test_character_limiter()
+	{
+		$this->assertEquals('Once upon a time, a&#8230;', character_limiter($this->_long_string, 20));
+		$this->assertEquals('Once upon a time, a&hellip;', character_limiter($this->_long_string, 20, '&hellip;'));
+		$this->assertEquals('Short', character_limiter('Short', 20));
+		$this->assertEquals('Short', character_limiter('Short', 5));
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	public function test_ascii_to_entities()
+	{
+		$strs = array(
+			'“‘ “test”'			=> '&#8220;&#8216; &#8220;test&#8221;',
+			'†¥¨ˆøåß∂ƒ©˙∆˚¬'	=> '&#8224;&#165;&#168;&#710;&#248;&#229;&#223;&#8706;&#402;&#169;&#729;&#8710;&#730;&#172;'
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, ascii_to_entities($str));
+		}
+	}
+
+	// ------------------------------------------------------------------------	
+
+	public function test_entities_to_ascii()
+	{
+		$strs = array(
+			'&#8220;&#8216; &#8220;test&#8221;' => '“‘ “test”',
+			'&#8224;&#165;&#168;&#710;&#248;&#229;&#223;&#8706;&#402;&#169;&#729;&#8710;&#730;&#172;' => '†¥¨ˆøåß∂ƒ©˙∆˚¬'
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, entities_to_ascii($str));
+		}		
+	}
+	
+	// ------------------------------------------------------------------------	
+	
+	function test_convert_accented_characters() 
+	{
+		$this->assertEquals('AAAeEEEIIOOEUUUeY', convert_accented_characters('ÀÂÄÈÊËÎÏÔŒÙÛÜŸ'));
+		$this->assertEquals('a e i o u n ue', convert_accented_characters('á é í ó ú ñ ü'));
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	public function test_censored_words()
+	{
+		$censored = array('boob', 'nerd', 'ass', 'fart');
+		
+		$strs = array(
+			'Ted bobbled the ball' 			=> 'Ted bobbled the ball',
+			'Jake is a nerdo'				=> 'Jake is a nerdo',
+			'The borg will assimilate you'	=> 'The borg will assimilate you',
+			'Did Mary Fart?'				=> 'Did Mary $*#?',
+			'Jake is really a boob'			=> 'Jake is really a $*#'
+		);
+		
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, word_censor($str, $censored, '$*#'));
+		}
+		
+		// test censored words being sent as a string
+		$this->assertEquals('test', word_censor('test', 'test'));
+	}
+
+	// ------------------------------------------------------------------------	
+
+	public function test_highlight_code()
+	{
+		$code = '<?php var_dump($this); ?>';
+		$expect = "<code><span style=\"color: #000000\">\n<span style=\"color: #0000BB\">&lt;?php&nbsp;var_dump</span><span style=\"color: #007700\">(</span><span style=\"color: #0000BB\">\$this</span><span style=\"color: #007700\">);&nbsp;</span><span style=\"color: #0000BB\">?&gt;&nbsp;</span>\n</span>\n</code>";
+
+		$this->assertEquals($expect, highlight_code($code));
+	}
+
+	// ------------------------------------------------------------------------	
+
+	public function test_highlight_phrase()
+	{
+		$strs = array(
+			'this is a phrase'			=> '<strong>this is</strong> a phrase',
+			'this is another'			=> '<strong>this is</strong> another',
+			'Gimme a test, Sally'		=> 'Gimme a test, Sally',
+			'Or tell me what this is'	=> 'Or tell me what <strong>this is</strong>',
+			''							=> ''
+		);
+		
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, highlight_phrase($str, 'this is'));
+		}
+	}
+
+	// ------------------------------------------------------------------------	
+
+	public function test_ellipsizing()
+	{
+		$strs = array(
+			'0'		=> array(
+				'this is my string'				=> '&hellip; my string',
+				"here's another one"			=> '&hellip;nother one',
+				'this one is just a bit longer'	=> '&hellip;bit longer',
+				'short'							=> 'short'
+			),
+			'.5'	=> array(
+				'this is my string'				=> 'this &hellip;tring',
+				"here's another one"			=> "here'&hellip;r one",
+				'this one is just a bit longer'	=> 'this &hellip;onger',
+				'short'							=> 'short'
+			),
+			'1'	=> array(
+				'this is my string'				=> 'this is my&hellip;',
+				"here's another one"			=> "here's ano&hellip;",
+				'this one is just a bit longer'	=> 'this one i&hellip;',
+				'short'							=> 'short'
+			),
+		);
+		
+		foreach ($strs as $pos => $s)
+		{
+			foreach ($s as $str => $expect)
+			{
+				$this->assertEquals($expect, ellipsize($str, 10, $pos));				
+			}
+		}
+	}
+
+	// ------------------------------------------------------------------------	
+
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/url_helper_test.php b/tests/codeigniter/helpers/url_helper_test.php
new file mode 100644
index 0000000..c561809
--- /dev/null
+++ b/tests/codeigniter/helpers/url_helper_test.php
@@ -0,0 +1,75 @@
+<?php
+
+class Url_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('url');
+	}
+
+	public function test_url_title()
+	{
+		$words = array(
+			'foo bar /' 	=> 'foo-bar',
+			'\  testing 12' => 'testing-12'
+		);
+
+		foreach ($words as $in => $out)
+		{
+			$this->assertEquals($out, url_title($in, 'dash', TRUE));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_url_title_extra_dashes()
+	{
+		$words = array(
+			'_foo bar_' 	=> 'foo_bar',
+			'_What\'s wrong with CSS?_' => 'Whats_wrong_with_CSS'
+		);
+
+		foreach ($words as $in => $out)
+		{
+			$this->assertEquals($out, url_title($in, 'underscore'));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_prep_url()
+	{
+		$this->assertEquals('http://codeigniter.com', prep_url('codeigniter.com'));
+		$this->assertEquals('http://www.codeigniter.com', prep_url('www.codeigniter.com'));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_auto_link_url()
+	{
+		$strings = array(
+			'www.codeigniter.com test' => '<a href="http://www.codeigniter.com">http://www.codeigniter.com</a> test',
+			'This is my noreply@codeigniter.com test' => 'This is my noreply@codeigniter.com test',
+			'<br />www.google.com' => '<br /><a href="http://www.google.com">http://www.google.com</a>',
+		);
+
+		foreach ($strings as $in => $out)
+		{
+			$this->assertEquals($out, auto_link($in, 'url'));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_pull_675()
+	{
+		$strings = array(
+			'<br />www.google.com' => '<br /><a href="http://www.google.com">http://www.google.com</a>',
+		);
+
+		foreach ($strings as $in => $out)
+		{
+			$this->assertEquals($out, auto_link($in, 'url'));
+		}
+	}
+}
\ No newline at end of file
diff --git a/tests/codeigniter/helpers/xml_helper_test.php b/tests/codeigniter/helpers/xml_helper_test.php
new file mode 100644
index 0000000..a83fef9
--- /dev/null
+++ b/tests/codeigniter/helpers/xml_helper_test.php
@@ -0,0 +1,15 @@
+<?php
+
+class Xml_helper_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$this->helper('xml');
+	}
+	
+	public function test_xml_convert()
+	{
+		$this->assertEquals('&lt;tag&gt;my &amp; test &#45; &lt;/tag&gt;', xml_convert('<tag>my & test - </tag>'));
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/libraries/Parser_test.php b/tests/codeigniter/libraries/Parser_test.php
new file mode 100644
index 0000000..c3d88fa
--- /dev/null
+++ b/tests/codeigniter/libraries/Parser_test.php
@@ -0,0 +1,110 @@
+<?php
+
+class Parser_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->parser = new Mock_Libraries_Parser();
+		
+		$this->ci_instance($obj);
+		
+		$this->parser = $obj->parser;
+	}
+	// --------------------------------------------------------------------
+	
+	public function test_set_delimiters()
+	{
+		// Make sure default delimiters are there
+		$this->assertEquals('{', $this->parser->l_delim);
+		$this->assertEquals('}', $this->parser->r_delim);
+		
+		// Change them to square brackets
+		$this->parser->set_delimiters('[', ']');
+		
+		// Make sure they changed
+		$this->assertEquals('[', $this->parser->l_delim);
+		$this->assertEquals(']', $this->parser->r_delim);
+		
+		// Reset them
+		$this->parser->set_delimiters();
+		
+		// Make sure default delimiters are there
+		$this->assertEquals('{', $this->parser->l_delim);
+		$this->assertEquals('}', $this->parser->r_delim);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_parse_simple_string()
+	{
+		$data = array(
+			'title' => 'Page Title',
+			'body' => 'Lorem ipsum dolor sit amet.'
+		);
+		
+		$template = "{title}\n{body}";
+		
+		$result = implode("\n", $data);
+		
+		$this->assertEquals($result, $this->parser->parse_string($template, $data, TRUE));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function test_parse()
+	{
+		$this->_parse_no_template();
+		$this->_parse_var_pair();
+		$this->_mismatched_var_pair();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	private function _parse_no_template()
+	{
+		$this->assertFalse($this->parser->parse_string('', '', TRUE));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	private function _parse_var_pair()
+	{
+		$data = array(
+			'title'		=> 'Super Heroes',
+			'powers'	=> array(
+					array(
+						'invisibility'	=> 'yes',
+						'flying'		=> 'no'),
+			)
+		);
+		
+		$template = "{title}\n{powers}{invisibility}\n{flying}{/powers}";
+		
+		$result = "Super Heroes\nyes\nno";
+		
+		$this->assertEquals($result, $this->parser->parse_string($template, $data, TRUE));	
+	}
+	
+	// --------------------------------------------------------------------
+	
+	private function _mismatched_var_pair()
+	{
+		$data = array(
+			'title'		=> 'Super Heroes',
+			'powers'	=> array(
+					array(
+						'invisibility'	=> 'yes',
+						'flying'		=> 'no'),
+			)
+		);
+		
+		$template = "{title}\n{powers}{invisibility}\n{flying}";
+		
+		$result = "Super Heroes\n{powers}{invisibility}\n{flying}";
+		
+		$this->assertEquals($result, $this->parser->parse_string($template, $data, TRUE));			
+	}
+
+	// --------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/tests/codeigniter/libraries/Table_test.php b/tests/codeigniter/libraries/Table_test.php
new file mode 100644
index 0000000..13f338c
--- /dev/null
+++ b/tests/codeigniter/libraries/Table_test.php
@@ -0,0 +1,296 @@
+<?php
+
+class Table_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->table = new Mock_Libraries_Table();
+		
+		$this->ci_instance($obj);
+		
+		$this->table = $obj->table;
+	}
+
+	
+	// Setter Methods
+	// --------------------------------------------------------------------
+	
+	public function test_set_template()
+	{
+		$this->assertFalse($this->table->set_template('not an array'));
+		
+		$template = array(
+			'a' => 'b'
+		);
+		
+		$this->table->set_template($template);
+		$this->assertEquals($template, $this->table->template);
+	}
+	
+	public function test_set_empty()
+	{
+		$this->table->set_empty('nada');
+		$this->assertEquals('nada', $this->table->empty_cells);
+	}
+	
+	public function test_set_caption()
+	{
+		$this->table->set_caption('awesome cap');
+		$this->assertEquals('awesome cap', $this->table->caption);
+	}
+	
+	
+	/*
+	 * @depends testPrepArgs
+	 */
+	public function test_set_heading()
+	{
+		// uses _prep_args internally, so we'll just do a quick
+		// check to verify that func_get_args and prep_args are
+		// being called.
+		
+		$this->table->set_heading('name', 'color', 'size');
+		
+		$this->assertEquals(
+			array(
+				array('data' => 'name'),
+				array('data' => 'color'),
+				array('data' => 'size')
+			),
+			$this->table->heading
+		);
+	}
+	
+	
+	/*
+	 * @depends testPrepArgs
+	 */
+	public function test_add_row()
+	{
+		// uses _prep_args internally, so we'll just do a quick
+		// check to verify that func_get_args and prep_args are
+		// being called.
+		
+		$this->table->add_row('my', 'pony', 'sings');
+		$this->table->add_row('your', 'pony', 'stinks');
+		$this->table->add_row('my pony', '>', 'your pony');
+		
+		$this->assertEquals(count($this->table->rows), 3);
+		
+		$this->assertEquals(
+			array(
+				array('data' => 'your'),
+				array('data' => 'pony'),
+				array('data' => 'stinks')
+			),
+			$this->table->rows[1]
+		);
+	}
+	
+	
+	// Uility Methods
+	// --------------------------------------------------------------------
+	
+	public function test_prep_args()
+	{
+		$expected = array(
+			array('data' => 'name'),
+			array('data' => 'color'),
+			array('data' => 'size')
+		);
+		
+		$this->assertEquals(
+			$expected,
+			$this->table->prep_args(array('name', 'color', 'size'))
+		);
+
+		// with cell attributes
+		// need to add that new argument row to our expected outcome
+		$expected[] = array('data' => 'weight', 'class' => 'awesome');
+
+		$this->assertEquals(
+			$expected,
+			$this->table->prep_args(array('name', 'color', 'size', array('data' => 'weight', 'class' => 'awesome')))
+		);
+	}
+	
+	public function test_default_template_keys()
+	{
+		$keys = array(
+			'table_open',
+			'thead_open', 'thead_close',
+			'heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end',
+			'tbody_open', 'tbody_close',
+			'row_start', 'row_end', 'cell_start', 'cell_end',
+			'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end',
+			'table_close'
+		);
+		
+		foreach ($keys as $key)
+		{
+			$this->assertArrayHasKey($key, $this->table->default_template());
+		}
+	}
+	
+	public function test_compile_template()
+	{
+		$this->assertFalse($this->table->set_template('invalid_junk'));
+		
+		// non default key
+		$this->table->set_template(array('nonsense' => 'foo'));
+		$this->table->compile_template();
+		
+		$this->assertArrayHasKey('nonsense', $this->table->template);
+		$this->assertEquals('foo', $this->table->template['nonsense']);
+		
+		// override default
+		$this->table->set_template(array('table_close' => '</table junk>'));
+		$this->table->compile_template();
+		
+		$this->assertArrayHasKey('table_close', $this->table->template);
+		$this->assertEquals('</table junk>', $this->table->template['table_close']);
+	}
+	
+	public function test_make_columns()
+	{
+		// Test bogus parameters
+		$this->assertFalse($this->table->make_columns('invalid_junk'));
+		$this->assertFalse($this->table->make_columns(array()));
+		$this->assertFalse($this->table->make_columns(array('one', 'two'), '2.5'));
+		
+		
+		// Now on to the actual column creation
+		
+		$five_values = array(
+			'Laura', 'Red', '15',
+			'Katie', 'Blue'
+		);
+		
+		// No column count - no changes to the array
+		$this->assertEquals(
+			$five_values,
+			$this->table->make_columns($five_values)
+		);
+		
+		// Column count of 3 leaves us with one &nbsp;
+		$this->assertEquals(
+			array(
+				array('Laura', 'Red', '15'),
+				array('Katie', 'Blue', '&nbsp;')				
+			),
+			$this->table->make_columns($five_values, 3)
+		);
+	}
+	
+	public function test_clear()
+	{
+		$this->table->set_heading('Name', 'Color', 'Size');
+		
+		// Make columns changes auto_heading
+		$rows = $this->table->make_columns(array(
+			'Laura', 'Red', '15',
+			'Katie', 'Blue'
+		), 3);
+		
+		foreach ($rows as $row)
+		{
+			$this->table->add_row($row);
+		}
+		
+		$this->assertFalse($this->table->auto_heading);
+		$this->assertEquals(count($this->table->heading), 3);
+		$this->assertEquals(count($this->table->rows), 2);
+		
+		$this->table->clear();
+		
+		$this->assertTrue($this->table->auto_heading);
+		$this->assertEmpty($this->table->heading);
+		$this->assertEmpty($this->table->rows);
+	}
+	
+	
+	public function test_set_from_array()
+	{
+		$this->assertFalse($this->table->set_from_array('bogus'));
+		$this->assertFalse($this->table->set_from_array(NULL));
+		
+		$data = array(
+			array('name', 'color', 'number'),
+			array('Laura', 'Red', '22'),
+			array('Katie', 'Blue')				
+		);
+		
+		$this->table->set_from_array($data, FALSE);
+		$this->assertEmpty($this->table->heading);
+		
+		$this->table->clear();
+		
+		$expected_heading = array(
+			array('data' => 'name'),
+			array('data' => 'color'),
+			array('data' => 'number')
+		);
+		
+		$expected_second = array(
+			array('data' => 'Katie'),
+			array('data' => 'Blue'),
+		);
+		
+		$this->table->set_from_array($data);
+		$this->assertEquals(count($this->table->rows), 2);
+		
+		$this->assertEquals(
+			$expected_heading,
+			$this->table->heading
+		);
+		
+		$this->assertEquals(
+			$expected_second,
+			$this->table->rows[1]
+		);
+	}
+	
+	function test_set_from_object()
+	{
+		// Make a stub of query instance
+		$query = new CI_TestCase();
+		$query->list_fields = function(){
+			return array('name', 'email');
+		};
+		$query->result_array = function(){
+			return array(
+					array('name' => 'John Doe', 'email' => 'john@doe.com'),
+					array('name' => 'Foo Bar', 'email' => 'foo@bar.com'),
+				);
+		};
+		$query->num_rows = function(){
+			return 2;
+		};
+
+		$expected_heading = array(
+			array('data' => 'name'),
+			array('data' => 'email')
+		);
+
+		$expected_second = array(
+			'name' => array('data' => 'Foo Bar'),
+			'email' => array('data' => 'foo@bar.com'),
+		);
+
+		$this->table->set_from_object($query);
+
+		$this->assertEquals(
+			$expected_heading,
+			$this->table->heading
+		);
+		
+		$this->assertEquals(
+			$expected_second,
+			$this->table->rows[1]
+		);
+	}
+	
+	// Test main generate method
+	// --------------------------------------------------------------------
+}
\ No newline at end of file
diff --git a/tests/codeigniter/libraries/Typography_test.php b/tests/codeigniter/libraries/Typography_test.php
new file mode 100644
index 0000000..250aefb
--- /dev/null
+++ b/tests/codeigniter/libraries/Typography_test.php
@@ -0,0 +1,188 @@
+<?php
+
+class Typography_test extends CI_TestCase {
+
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->type = new Mock_Libraries_Typography();
+		
+		$this->ci_instance($obj);
+		
+		$this->type = $obj->type;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Tests the format_characters() function.
+	 *
+	 * this can and should grow.
+	 */
+	public function test_format_characters()
+	{
+		$strs = array(
+			'"double quotes"' 				=> '&#8220;double quotes&#8221;',
+			'"testing" in "theory" that is' => '&#8220;testing&#8221; in &#8220;theory&#8221; that is',
+			"Here's what I'm" 				=> 'Here&#8217;s what I&#8217;m',
+			'&' 							=> '&amp;',
+			'&amp;' 						=> '&amp;',
+			'&nbsp;'						=> '&nbsp;',
+			'--'							=> '&#8212;',
+			'foo...'						=> 'foo&#8230;',
+			'foo..'							=> 'foo..',
+			'foo...bar.'					=> 'foo&#8230;bar.',
+			'test.  new'					=> 'test.&nbsp; new',
+		);	
+		
+		foreach ($strs as $str => $expected)
+		{
+			$this->assertEquals($expected, $this->type->format_characters($str));		
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_nl2br_except_pre()
+	{	
+		$str = <<<EOH
+Hello, I'm a happy string with some new lines.  
+
+I like to skip.
+
+Jump
+
+and sing.
+
+<pre>
+I am inside a pre tag.  Please don't mess with me.
+
+k?
+</pre>
+
+That's my story and I'm sticking to it.
+
+The End.
+EOH;
+
+		$expected = <<<EOH
+Hello, I'm a happy string with some new lines.  <br />
+<br />
+I like to skip.<br />
+<br />
+Jump<br />
+<br />
+and sing.<br />
+<br />
+<pre>
+I am inside a pre tag.  Please don't mess with me.
+
+k?
+</pre><br />
+<br />
+That's my story and I'm sticking to it.<br />
+<br />
+The End.
+EOH;
+
+		$this->assertEquals($expected, 
+							$this->type->nl2br_except_pre($str));
+	}
+
+	// --------------------------------------------------------------------
+	
+	public function test_auto_typography()
+	{
+		$this->_blank_string();
+		$this->_standardize_new_lines();
+		$this->_reduce_linebreaks();
+		$this->_remove_comments();
+		$this->_protect_pre();
+		$this->_no_opening_block();
+		$this->_protect_braced_quotes();
+	}
+
+	// --------------------------------------------------------------------
+	
+	private function _blank_string()
+	{
+		// Test blank string
+		$this->assertEquals('', $this->type->auto_typography(''));
+	}
+
+	// --------------------------------------------------------------------
+
+	private function _standardize_new_lines()
+	{
+		$strs = array(
+			"My string\rhas return characters"	=> "<p>My string<br />\nhas return characters</p>",
+			'This one does not!' 				=> '<p>This one does not!</p>'
+		);
+
+		foreach ($strs as $str => $expect)
+		{
+			$this->assertEquals($expect, $this->type->auto_typography($str));
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	private function _reduce_linebreaks()
+	{
+		$str = "This has way too many linebreaks.\n\n\n\nSee?";
+		$expect = "<p>This has way too many linebreaks.</p>\n\n<p>See?</p>";
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str, TRUE));
+	}
+
+	// --------------------------------------------------------------------
+
+	private function _remove_comments()
+	{
+		$str = '<!-- I can haz comments? -->  But no!';
+		$expect = '<p><!-- I can haz comments? -->&nbsp; But no!</p>';
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str));
+	}
+
+	// --------------------------------------------------------------------
+
+	private function _protect_pre()
+	{
+		$str = '<p>My Sentence</p><pre>var_dump($this);</pre>';
+		$expect = '<p>My Sentence</p><pre>var_dump($this);</pre>';
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str));
+	}
+
+	// --------------------------------------------------------------------
+
+	private function _no_opening_block()
+	{
+		$str = 'My Sentence<pre>var_dump($this);</pre>';
+		$expect = '<p>My Sentence</p><pre>var_dump($this);</pre>';
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function _protect_braced_quotes()
+	{
+		$this->type->protect_braced_quotes = TRUE;
+		
+		$str = 'Test {parse="foobar"}';
+		$expect = '<p>Test {parse="foobar"}</p>';
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str));
+
+		$this->type->protect_braced_quotes = FALSE;
+		
+		$str = 'Test {parse="foobar"}';
+		$expect = '<p>Test {parse=&#8220;foobar&#8221;}</p>';
+		
+		$this->assertEquals($expect, $this->type->auto_typography($str));
+
+
+	}
+}
\ No newline at end of file
diff --git a/tests/codeigniter/libraries/Useragent_test.php b/tests/codeigniter/libraries/Useragent_test.php
new file mode 100644
index 0000000..7dad7ac
--- /dev/null
+++ b/tests/codeigniter/libraries/Useragent_test.php
@@ -0,0 +1,87 @@
+<?php
+
+class UserAgent_test extends CI_TestCase {
+	
+	protected $_user_agent = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27';
+	protected $_mobile_ua = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7';
+
+	public function set_up()
+	{
+		// set a baseline user agent
+		$_SERVER['HTTP_USER_AGENT'] = $this->_user_agent;
+
+		$obj = new StdClass;
+		$obj->agent = new Mock_Libraries_UserAgent();
+
+		$this->ci_instance($obj);
+
+		$this->agent = $obj->agent;
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_accept_lang()
+	{
+		$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en';
+		$this->assertTrue($this->agent->accept_lang());
+		unset($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+		$this->assertTrue($this->agent->accept_lang('en'));
+		$this->assertFalse($this->agent->accept_lang('fr'));
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_mobile()
+	{
+		// Mobile Not Set
+		$_SERVER['HTTP_USER_AGENT'] = $this->_mobile_ua;
+		$this->assertEquals('', $this->agent->mobile());
+		unset($_SERVER['HTTP_USER_AGENT']);
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_util_is_functions()
+	{
+		$this->assertTrue($this->agent->is_browser());
+		$this->assertFalse($this->agent->is_robot());
+		$this->assertFalse($this->agent->is_mobile());
+		$this->assertFalse($this->agent->is_referral());
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_agent_string()
+	{
+		$this->assertEquals($this->_user_agent, $this->agent->agent_string());
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_browser_info()
+	{
+		$this->assertEquals('Mac OS X', $this->agent->platform());
+		$this->assertEquals('Safari', $this->agent->browser());
+		$this->assertEquals('533.20.27', $this->agent->version());
+		$this->assertEquals('', $this->agent->robot());
+		$this->assertEquals('', $this->agent->referrer());
+	}
+
+	// --------------------------------------------------------------------
+
+	public function test_charsets()
+	{
+		$_SERVER['HTTP_ACCEPT_CHARSET'] = 'utf8';
+
+		$charsets = $this->agent->charsets();
+
+		$this->assertEquals('utf8', $charsets[0]);
+
+		unset($_SERVER['HTTP_ACCEPT_CHARSET']);
+
+		$this->assertFalse($this->agent->accept_charset());
+	}
+
+	// --------------------------------------------------------------------
+
+}
\ No newline at end of file
diff --git a/tests/mocks/autoloader.php b/tests/mocks/autoloader.php
new file mode 100644
index 0000000..dd59292
--- /dev/null
+++ b/tests/mocks/autoloader.php
@@ -0,0 +1,79 @@
+<?php
+
+// This autoloader provide convinient way to working with mock object
+// make the test looks natural. This autoloader support cascade file loading as well
+// within mocks directory.
+//
+// Prototype :
+//
+// include_once('Mock_Core_Loader') 					// Will load ./mocks/core/loader.php
+// $mock_table = new Mock_Libraries_Table(); 			// Will load ./mocks/libraries/table.php
+// $mock_database_driver = new Mock_Database_Driver();	// Will load ./mocks/database/driver.php 
+// and so on...
+function autoload($class) 
+{
+	$dir = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR;
+
+	$ci_core = array(
+		'Benchmark', 'Config', 'Controller',
+		'Exceptions', 'Hooks', 'Input',
+		'Lang', 'Loader', 'Model',
+		'Output', 'Router', 'Security',
+		'URI', 'Utf8',
+	);
+
+	$ci_libraries = array(
+		'Calendar', 'Cart', 'Driver',
+		'Email', 'Encrypt', 'Form_validation',
+		'Ftp', 'Image_lib', 'Javascript',
+		'Log', 'Migration', 'Pagination',
+		'Parser', 'Profiler', 'Session',
+		'Table', 'Trackback', 'Typography',
+		'Unit_test', 'Upload', 'User_agent',
+		'Xmlrpc', 'Zip',
+	);
+
+	if (strpos($class, 'Mock_') === 0)
+	{
+		$class = str_replace(array('Mock_', '_'), array('', DIRECTORY_SEPARATOR), $class);
+		$class = strtolower($class);
+	}
+	elseif (strpos($class, 'CI_') === 0)
+	{
+		$fragments = explode('_', $class, 2);
+		$subclass = next($fragments);
+
+		if (in_array($subclass, $ci_core))
+		{
+			$dir = BASEPATH.'core'.DIRECTORY_SEPARATOR;
+			$class = $subclass;
+		}
+		elseif (in_array($subclass, $ci_libraries))
+		{
+			$dir = BASEPATH.'libraries'.DIRECTORY_SEPARATOR;
+			$class = $subclass;
+		}
+		else
+		{
+			$class = strtolower($class);
+		}
+	}
+
+	$file = $dir.$class.'.php';
+
+	if ( ! file_exists($file))
+	{
+		$trace = debug_backtrace();
+
+		// If the autoload call came from `class_exists` or `file_exists`, 
+		// we skipped and return FALSE
+		if ($trace[2]['function'] == 'class_exists' OR $trace[2]['function'] == 'file_exists')
+		{
+			return FALSE;
+		}
+
+	    throw new InvalidArgumentException("Unable to load $class.");
+	}
+
+	include_once($file);
+}
\ No newline at end of file
diff --git a/tests/mocks/ci_testcase.php b/tests/mocks/ci_testcase.php
new file mode 100644
index 0000000..f327e6b
--- /dev/null
+++ b/tests/mocks/ci_testcase.php
@@ -0,0 +1,196 @@
+<?php
+
+class CI_TestCase extends PHPUnit_Framework_TestCase {
+	
+	protected $ci_config;
+	protected $ci_instance;
+	protected static $ci_test_instance;
+		
+	private $global_map = array(
+		'benchmark'	=> 'bm',
+		'config'	=> 'cfg',
+		'hooks'		=> 'ext',
+		'utf8'		=> 'uni',
+		'router'	=> 'rtr',
+		'output'	=> 'out',
+		'security'	=> 'sec',
+		'input'		=> 'in',
+		'lang'		=> 'lang',
+		'loader'	=> 'load',
+		'model'		=> 'model'
+	);
+	
+	// --------------------------------------------------------------------
+	
+	public function __construct()
+	{
+		parent::__construct();
+		
+		$this->ci_config = array();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function setUp()
+	{
+		if (method_exists($this, 'set_up'))
+		{
+			$this->set_up();
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public function tearDown() 
+	{
+		if (method_exists($this, 'tear_down'))
+		{
+			$this->tear_down();
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	public static function instance()
+	{
+		return self::$ci_test_instance;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	function ci_set_config($key, $val = '')
+	{
+		if (is_array($key))
+		{
+			$this->ci_config = $key;
+		}
+		else
+		{
+			$this->ci_config[$key] = $val;
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	function ci_get_config()
+	{
+		return $this->ci_config;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	function ci_instance($obj = FALSE)
+	{
+		if ( ! is_object($obj))
+		{
+			return $this->ci_instance;
+		}
+		
+		$this->ci_instance = $obj;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	function ci_instance_var($name, $obj = FALSE)
+	{
+		if ( ! is_object($obj))
+		{
+			return $this->ci_instance->$name;
+		}
+		
+		$this->ci_instance->$name =& $obj;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Grab a core class
+	 *
+	 * Loads the correct core class without extensions
+	 * and returns a reference to the class name in the
+	 * globals array with the correct key. This way the
+	 * test can modify the variable it assigns to and
+	 * still maintain the global.
+	 */
+	function &ci_core_class($name)
+	{
+		$name = strtolower($name);
+		
+		if (isset($this->global_map[$name]))
+		{
+			$class_name = ucfirst($name);
+			$global_name = $this->global_map[$name];
+		}
+		elseif (in_array($name, $this->global_map))
+		{
+			$class_name = ucfirst(array_search($name, $this->global_map));
+			$global_name = $name;
+		}
+		else
+		{
+			throw new Exception('Not a valid core class.');
+		}
+		
+		if ( ! class_exists('CI_'.$class_name))
+		{
+			require_once BASEPATH.'core/'.$class_name.'.php';
+		}
+		
+		$GLOBALS[strtoupper($global_name)] = 'CI_'.$class_name;
+		return $GLOBALS[strtoupper($global_name)];
+	}
+	
+	// --------------------------------------------------------------------
+	
+	// convenience function for global mocks
+	function ci_set_core_class($name, $obj)
+	{
+		$orig =& $this->ci_core_class($name);
+		$orig = $obj;
+	}
+	
+	// --------------------------------------------------------------------
+	// Internals
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Overwrite runBare
+	 *
+	 * PHPUnit instantiates the test classes before
+	 * running them individually. So right before a test
+	 * runs we set our instance. Normally this step would
+	 * happen in setUp, but someone is bound to forget to
+	 * call the parent method and debugging this is no fun.
+	 */
+	public function runBare()
+	{
+		self::$ci_test_instance = $this;
+		parent::runBare();
+	}
+
+	// --------------------------------------------------------------------
+	
+	function helper($name)
+	{
+		require_once(BASEPATH.'helpers/'.$name.'_helper.php');
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * This overload is useful to create a stub, that need to have a specific method.
+	 */
+	function __call($method, $args)
+	{
+		if ($this->{$method} instanceof Closure) 
+		{
+			return call_user_func_array($this->{$method},$args);
+		} 
+		else 
+		{
+			return parent::__call($method, $args);
+		}
+	}
+}
+
+// EOF
\ No newline at end of file
diff --git a/tests/mocks/core/common.php b/tests/mocks/core/common.php
new file mode 100644
index 0000000..fc94d7f
--- /dev/null
+++ b/tests/mocks/core/common.php
@@ -0,0 +1,132 @@
+<?php
+
+// Set up the global CI functions in their most minimal core representation
+
+function &get_instance() 
+{
+	$test = CI_TestCase::instance();
+	$instance = $test->ci_instance();
+	return $instance;
+}
+
+// --------------------------------------------------------------------
+
+function &get_config() {
+	$test = CI_TestCase::instance();
+	$config = $test->ci_get_config();
+		
+	return $config;
+}
+
+function config_item($item)
+{
+	$config =& get_config();
+	
+	if ( ! isset($config[$item]))
+	{
+		return FALSE;
+	}
+	
+	return $config[$item];
+}
+
+// --------------------------------------------------------------------
+
+function load_class($class, $directory = 'libraries', $prefix = 'CI_')
+{
+	if ($directory != 'core' OR $prefix != 'CI_')
+	{
+		throw new Exception('Not Implemented: Non-core load_class()');
+	}
+	
+	$test = CI_TestCase::instance();
+	
+	$obj =& $test->ci_core_class($class);
+	
+	if (is_string($obj))
+	{
+		throw new Exception('Bad Isolation: Use ci_set_core_class to set '.$class.'');
+	}
+	
+	return $obj;
+}
+
+// This is sort of meh. Should probably be mocked up with
+// controllable output, so that we can test some of our
+// security code. The function itself will be tested in the
+// bootstrap testsuite.
+// --------------------------------------------------------------------
+
+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)
+	
+	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
+	{
+		$str = preg_replace($non_displayables, '', $str, -1, $count);
+	}
+	while ($count);
+
+	return $str;
+}
+
+
+// Clean up error messages
+// --------------------------------------------------------------------
+
+function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
+{
+	throw new RuntimeException('CI Error: '.$message);
+}
+
+function show_404($page = '', $log_error = TRUE)
+{
+	throw new RuntimeException('CI Error: 404');
+}
+
+function _exception_handler($severity, $message, $filepath, $line)
+{
+	throw new RuntimeException('CI Exception: '.$message.' | '.$filepath.' | '.$line);
+}
+
+
+// We assume a few things about our environment ...
+// --------------------------------------------------------------------
+
+function is_php($version = '5.0.0')
+{
+	return ! (version_compare(PHP_VERSION, $version) < 0);
+}
+
+function is_really_writable($file)
+{
+	return is_writable($file);
+}
+
+function is_loaded()
+{
+	throw new Exception('Bad Isolation: mock up environment');
+}
+
+function log_message($level = 'error', $message, $php_error = FALSE)
+{
+	return TRUE;
+}
+
+function set_status_header($code = 200, $text = '')
+{
+	return TRUE;
+}
+
+// EOF
\ No newline at end of file
diff --git a/tests/mocks/core/loader.php b/tests/mocks/core/loader.php
new file mode 100644
index 0000000..d4b29bb
--- /dev/null
+++ b/tests/mocks/core/loader.php
@@ -0,0 +1,30 @@
+<?php
+
+class Mock_Core_Loader extends CI_Loader {
+	
+	/**
+	 * Since we use paths to load up models, views, etc, we need the ability to
+	 * mock up the file system so when core tests are run, we aren't mucking
+	 * in the application directory.  this will give finer grained control over
+	 * these tests.  So yeah, while this looks odd, I need to overwrite protected
+	 * class vars in the loader.  So here we go...
+	 *
+	 * @covers CI_Loader::__construct()
+	 */
+	public function __construct()
+	{
+		vfsStreamWrapper::register();
+		vfsStreamWrapper::setRoot(new vfsStreamDirectory('application'));
+		
+		$this->models_dir 	= vfsStream::newDirectory('models')->at(vfsStreamWrapper::getRoot());
+		$this->libs_dir 	= vfsStream::newDirectory('libraries')->at(vfsStreamWrapper::getRoot());
+		$this->helpers_dir 	= vfsStream::newDirectory('helpers')->at(vfsStreamWrapper::getRoot());
+		$this->views_dir 	= vfsStream::newDirectory('views')->at(vfsStreamWrapper::getRoot());
+		
+		$this->_ci_ob_level  		= ob_get_level();
+		$this->_ci_library_paths	= array(vfsStream::url('application').'/', BASEPATH);
+		$this->_ci_helper_paths 	= array(vfsStream::url('application').'/', BASEPATH);
+		$this->_ci_model_paths 		= array(vfsStream::url('application').'/');
+		$this->_ci_view_paths 		= array(vfsStream::url('application').'/views/' => TRUE);
+	}
+}
\ No newline at end of file
diff --git a/tests/mocks/core/uri.php b/tests/mocks/core/uri.php
new file mode 100644
index 0000000..b694609
--- /dev/null
+++ b/tests/mocks/core/uri.php
@@ -0,0 +1,25 @@
+<?php
+
+class Mock_Core_URI extends CI_URI {
+	
+	public function __construct()
+	{
+		$test = CI_TestCase::instance();
+		$cls =& $test->ci_core_class('cfg');
+		
+		// set predictable config values
+		$test->ci_set_config(array(
+			'index_page'		=> 'index.php',
+			'base_url'			=> 'http://example.com/',
+			'subclass_prefix'	=> 'MY_'
+		));
+
+		$this->config = new $cls;	
+
+	}
+	
+	protected function _is_cli_request()
+	{
+		return FALSE;
+	}
+}
\ No newline at end of file
diff --git a/tests/mocks/database/ci_test.sqlite b/tests/mocks/database/ci_test.sqlite
new file mode 100755
index 0000000..37ce4f8
--- /dev/null
+++ b/tests/mocks/database/ci_test.sqlite
Binary files differ
diff --git a/tests/mocks/database/config/mysql.php b/tests/mocks/database/config/mysql.php
new file mode 100644
index 0000000..ace0a31
--- /dev/null
+++ b/tests/mocks/database/config/mysql.php
@@ -0,0 +1,34 @@
+<?php
+
+return array(
+	
+	// Typical Database configuration
+	'mysql' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'travis',
+		'password' => '',
+		'database' => 'ci_test',
+		'dbdriver' => 'mysql',
+	),
+
+	// Database configuration with failover
+	'mysql_failover' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'not_travis',
+		'password' => 'wrong password',
+		'database' => 'not_ci_test',
+		'dbdriver' => 'mysql',
+		'failover' => array(
+			array(
+				'dsn' => '',
+				'hostname' => 'localhost',
+				'username' => 'travis',
+				'password' => '',
+				'database' => 'ci_test',
+				'dbdriver' => 'mysql',
+			),
+		),
+	),
+);
\ No newline at end of file
diff --git a/tests/mocks/database/config/pgsql.php b/tests/mocks/database/config/pgsql.php
new file mode 100644
index 0000000..c06af8c
--- /dev/null
+++ b/tests/mocks/database/config/pgsql.php
@@ -0,0 +1,34 @@
+<?php
+
+return array(
+	
+	// Typical Database configuration
+	'pgsql' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'postgres',
+		'password' => '',
+		'database' => 'ci_test',
+		'dbdriver' => 'postgre',
+	),
+
+	// Database configuration with failover
+	'pgsql_failover' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'not_travis',
+		'password' => 'wrong password',
+		'database' => 'not_ci_test',
+		'dbdriver' => 'postgre',
+		'failover' => array(
+			array(
+				'dsn' => '',
+				'hostname' => 'localhost',
+				'username' => 'postgres',
+				'password' => '',
+				'database' => 'ci_test',
+				'dbdriver' => 'postgre',
+			),
+		),
+	),
+);
\ No newline at end of file
diff --git a/tests/mocks/database/config/sqlite.php b/tests/mocks/database/config/sqlite.php
new file mode 100644
index 0000000..8665e20
--- /dev/null
+++ b/tests/mocks/database/config/sqlite.php
@@ -0,0 +1,35 @@
+<?php
+$dbdriver = is_php('5.4') ? 'sqlite3' : 'sqlite';
+
+return array(
+
+	// Typical Database configuration
+	'sqlite' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'sqlite',
+		'password' => 'sqlite',
+		'database' => realpath(__DIR__.'/..').'/ci_test.sqlite',
+		'dbdriver' => $dbdriver,
+	),
+
+	// Database configuration with failover
+	'sqlite_failover' => array(
+		'dsn' => '',
+		'hostname' => 'localhost',
+		'username' => 'sqlite',
+		'password' => 'sqlite',
+		'database' => '../not_exists.sqlite',
+		'dbdriver' => $dbdriver,
+		'failover' => array(
+			array(
+				'dsn' => '',
+				'hostname' => 'localhost',
+				'username' => 'sqlite',
+				'password' => 'sqlite',
+				'database' => realpath(__DIR__.'/..').'/ci_testf.sqlite',
+				'dbdriver' => $dbdriver,
+			),
+		),
+	),
+);
\ No newline at end of file
diff --git a/tests/mocks/database/db.php b/tests/mocks/database/db.php
new file mode 100644
index 0000000..43a0d39
--- /dev/null
+++ b/tests/mocks/database/db.php
@@ -0,0 +1,101 @@
+<?php
+
+class Mock_Database_DB {
+
+	/**
+	 * @var array DB configuration
+	 */
+	private $config = array();
+	
+	/**
+	 * Prepare database configuration skeleton
+	 *
+	 * @param  array 	DB configuration to set
+	 * @return void
+	 */
+	public function __construct($config = array())
+	{
+		$this->config = $config;
+	}
+
+	/**
+	 * Build DSN connection string for DB driver instantiate process
+	 *
+	 * @param 	string 	Group name 		
+	 * @return 	string 	DSN Connection string
+	 */
+	public function set_dsn($group = 'default')
+	{
+		if ( ! isset($this->config[$group]))
+		{
+			throw new InvalidArgumentException('Group '.$group.' not exists');
+		}
+
+		$params = array(
+			'dbprefix' => '',
+			'pconnect' => FALSE,
+			'db_debug' => FALSE,
+			'cache_on' => FALSE,
+			'cachedir' => '',
+			'char_set' => 'utf8',
+			'dbcollat' => 'utf8_general_ci',
+			'swap_pre' => '',
+			'autoinit' => TRUE,
+			'stricton' => FALSE,
+		);
+
+		$config = array_merge($this->config[$group], $params);
+
+		if ( ! empty($config['dsn']))
+		{
+			$dsn = $config['dsn'];
+		}
+		else
+		{
+			$dsn = $config['dbdriver'].'://'.$config['username'].':'.$config['password']
+			       .'@'.$config['hostname'].'/'.$config['database'];
+
+		}
+
+		$other_params = array_slice($config, 6);
+
+		return $dsn.'?'.http_build_query($other_params);
+	}
+
+	/**
+	 * Return a database config array
+	 *
+	 * @see 	./config
+	 * @param 	string 		Driver based configuration
+	 * @return 	array 		
+	 */
+	public static function config($driver)
+	{
+		$dir = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR;
+
+		return include($dir.'config'.DIRECTORY_SEPARATOR.$driver.'.php');
+	}
+
+	/**
+	 * Main DB method wrapper
+	 *
+	 * @param 	string 		Group or DSN string
+	 * @param 	bool 		
+	 * @return 	object 		
+	 */
+	public static function DB($group, $query_builder = FALSE)
+	{
+		include_once(BASEPATH.'database/DB.php');
+
+		try 
+		{
+			$db = DB($group, $query_builder);
+		}
+		catch (Exception $e)
+		{
+			throw new InvalidArgumentException($e->getMessage());
+		}
+
+		return $db;
+	}
+}
\ No newline at end of file
diff --git a/tests/mocks/database/schema/.gitkeep b/tests/mocks/database/schema/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/mocks/database/schema/.gitkeep
diff --git a/tests/mocks/libraries/parser.php b/tests/mocks/libraries/parser.php
new file mode 100644
index 0000000..81dcfb3
--- /dev/null
+++ b/tests/mocks/libraries/parser.php
@@ -0,0 +1,3 @@
+<?php
+
+class Mock_Libraries_Parser extends CI_Parser {}
\ No newline at end of file
diff --git a/tests/mocks/libraries/table.php b/tests/mocks/libraries/table.php
new file mode 100644
index 0000000..1a6ff8d
--- /dev/null
+++ b/tests/mocks/libraries/table.php
@@ -0,0 +1,15 @@
+<?php
+
+class Mock_Libraries_Table extends CI_Table {
+	
+	// Overide inaccesible private or protected method
+	public function __call($method, $params)
+	{
+		if (is_callable(array($this, '_'.$method)))
+		{
+			return call_user_func_array(array($this, '_'.$method), $params);
+		}
+
+		throw new BadMethodCallException('Method '.$method.' was not found');
+	}
+}
\ No newline at end of file
diff --git a/tests/mocks/libraries/typography.php b/tests/mocks/libraries/typography.php
new file mode 100644
index 0000000..0f76c57
--- /dev/null
+++ b/tests/mocks/libraries/typography.php
@@ -0,0 +1,3 @@
+<?php
+
+class Mock_Libraries_Typography extends CI_Typography {}
\ No newline at end of file
diff --git a/tests/mocks/libraries/useragent.php b/tests/mocks/libraries/useragent.php
new file mode 100644
index 0000000..c957cde
--- /dev/null
+++ b/tests/mocks/libraries/useragent.php
@@ -0,0 +1,3 @@
+<?php
+
+class Mock_Libraries_UserAgent extends CI_User_agent {}
\ No newline at end of file
diff --git a/tests/travis/mysql.phpunit.xml b/tests/travis/mysql.phpunit.xml
new file mode 100644
index 0000000..44d6d6e
--- /dev/null
+++ b/tests/travis/mysql.phpunit.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit 
+	bootstrap="../Bootstrap.php"
+	colors="true"
+	convertNoticesToExceptions="true"
+	convertWarningsToExceptions="true"
+	stopOnError="false"
+	stopOnFailure="false"
+	stopOnIncomplete="false"
+	stopOnSkipped="false">
+	<php>
+        <const name="DB_DRIVER" value="mysql"/>
+    </php>
+	<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>
+			<directory suffix="test.php">../codeigniter/database</directory>
+		</testsuite>
+	</testsuites>
+	<filters>
+		<blacklist>
+			<directory suffix=".php">PEAR_INSTALL_DIR</directory>
+			<directory suffix=".php">PHP_LIBDIR</directory>
+			<directory suffix=".php">PROJECT_BASE.'tests'</directory>
+			<directory suffix=".php">'../../system/core/CodeIgniter.php'</directory>
+		</blacklist>
+		<whitelist>
+			<!--
+			<directory suffix=".php">'../system/core'</directory>
+			-->
+		</whitelist>
+	</filters>
+</phpunit>
\ No newline at end of file
diff --git a/tests/travis/pgsql.phpunit.xml b/tests/travis/pgsql.phpunit.xml
new file mode 100644
index 0000000..9f52b40
--- /dev/null
+++ b/tests/travis/pgsql.phpunit.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit 
+	bootstrap="../Bootstrap.php"
+	colors="true"
+	convertNoticesToExceptions="true"
+	convertWarningsToExceptions="true"
+	stopOnError="false"
+	stopOnFailure="false"
+	stopOnIncomplete="false"
+	stopOnSkipped="false">
+	<php>
+        <const name="DB_DRIVER" value="pgsql"/>
+    </php>
+	<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>
+			<directory suffix="test.php">../codeigniter/database</directory>
+		</testsuite>
+	</testsuites>
+	<filters>
+		<blacklist>
+			<directory suffix=".php">PEAR_INSTALL_DIR</directory>
+			<directory suffix=".php">PHP_LIBDIR</directory>
+			<directory suffix=".php">PROJECT_BASE.'tests'</directory>
+			<directory suffix=".php">'../../system/core/CodeIgniter.php'</directory>
+		</blacklist>
+		<whitelist>
+			<!--
+			<directory suffix=".php">'../system/core'</directory>
+			-->
+		</whitelist>
+	</filters>
+</phpunit>
\ No newline at end of file
diff --git a/tests/travis/sqlite.phpunit.xml b/tests/travis/sqlite.phpunit.xml
new file mode 100644
index 0000000..74ebb48
--- /dev/null
+++ b/tests/travis/sqlite.phpunit.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit 
+	bootstrap="../Bootstrap.php"
+	colors="true"
+	convertNoticesToExceptions="true"
+	convertWarningsToExceptions="true"
+	stopOnError="false"
+	stopOnFailure="false"
+	stopOnIncomplete="false"
+	stopOnSkipped="false">
+	<php>
+        <const name="DB_DRIVER" value="sqlite"/>
+    </php>
+	<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>
+			<directory suffix="test.php">../codeigniter/database</directory>
+		</testsuite>
+	</testsuites>
+	<filters>
+		<blacklist>
+			<directory suffix=".php">PEAR_INSTALL_DIR</directory>
+			<directory suffix=".php">PHP_LIBDIR</directory>
+			<directory suffix=".php">PROJECT_BASE.'tests'</directory>
+			<directory suffix=".php">'../../system/core/CodeIgniter.php'</directory>
+		</blacklist>
+		<whitelist>
+			<!--
+			<directory suffix=".php">'../system/core'</directory>
+			-->
+		</whitelist>
+	</filters>
+</phpunit>
\ No newline at end of file
diff --git a/user_guide_src/cilexer/cilexer/cilexer.py b/user_guide_src/cilexer/cilexer/cilexer.py
index 713268e..1c41f2a 100644
--- a/user_guide_src/cilexer/cilexer/cilexer.py
+++ b/user_guide_src/cilexer/cilexer/cilexer.py
@@ -1,7 +1,7 @@
 # CodeIgniter
 # http://codeigniter.com
 # 
-# An open source application development framework for PHP 5.1.6 or newer
+# An open source application development framework for PHP 5.2.4 or newer
 # 
 # NOTICE OF LICENSE
 # 
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 b9e28ae..66768ba 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
@@ -2,7 +2,7 @@
 CodeIgniter
 http://codeigniter.com
 
-An open source application development framework for PHP 5.1.6 or newer
+An open source application development framework for PHP 5.2.4 or newer
 
 NOTICE OF LICENSE
 
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 7f8f9bd..3a02d27 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -19,6 +19,7 @@
 
 -  General Changes
 
+   -  PHP 5.1.6 is no longer supported. CodeIgniter now requires PHP 5.2.4.
    -  Added an optional backtrace to php-error template.
    -  Added Android to the list of user agents.
    -  Added Windows 7 to the list of user platforms.
@@ -28,12 +29,15 @@
    -  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.
+   -  Added Romanian and Greek characters in foreign_characters.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.
+   -  Added some more doctypes.
+   -  Updated all classes to be written in PHP 5 style, with visibility declarations and no ``var`` usage for properties.
 
 -  Helpers
 
@@ -42,19 +46,28 @@
    -  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).
+   -  Added an optional third parameter to ``timespan()`` that constrains the number of time units displayed.
+   -  Added a work-around in force_download() for a bug Android <= 2.1, where the filename extension needs to be in uppercase.
+   -  form_dropdown() will now also take an array for unity with other form helpers.
+   -  set_realpath() can now also handle file paths as opposed to just directories.
+   -  do_hash() now uses PHP's native hash() function, supporting more algorithms.
+   -  Added an optional paramater to ``delete_files()`` to enable it to skip deleting files such as .htaccess and index.html.
 
 -  Database
 
    -  Renamed the Active Record class to Query Builder to remove confusion with 
       the Active Record design pattern
    -  Added new :doc:`Query Builder <database/query_builder>` methods that return
+   -  Added the ability to insert objects with insert_batch() in :doc:`Query Builder <database/query_builder>`.
+   -  Added new :doc:`Query Builder <database/query_builder>` methods that return
       the SQL string of queries without executing them: get_compiled_select(),
       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 support for the MySQLi driver, including:
+	 -  OOP style of the PHP extension is now used, instead of the procedural aliases.
+	 -  Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query.
+	 -  Added persistent connections support for PHP >= 5.3.
+   -  Added 'dsn' configuration setting for drivers that support DSN strings (PDO, PostgreSQL, Oracle, ODBC, CUBRID).
    -  Improved PDO database support.
    -  Added Interbase/Firebird database support via the "interbase" driver
    -  Added an optional database name parameter to db_select().
@@ -66,19 +79,39 @@
 	 -  Added _optimize_table() support for the :doc:`Database Utility Class <database/utilities>` (rebuilds table indexes).
    -  Added a constructor to the DB_result class and moved all driver-specific properties and logic out of the base DB_driver class to allow better abstraction.
    -  Removed limit() and order_by() support for UPDATE and DELETE queries in PostgreSQL driver. Postgres does not support those features.
-   -  Removed protect_identifiers() and renamed _protect_identifiers() to it instead - it was just an alias.
+   -  Removed protect_identifiers() and renamed internal method _protect_identifiers() to it instead - it was just an alias.
+   -  MySQL and MySQLi drivers now require at least MySQL version 5.1.
+   -  db_set_charset() now only requires one parameter (collation was only needed due to legacy support for MySQL versions prior to 5.1).
+   -  Added DSN string support for CUBRID.
+   -  Added persistent connections support for CUBRID.
+   -  Added random ordering support for MSSQL, SQLSRV.
+   -  Added support for SQLite3 database driver.
+   -  Improved support of the Oracle (OCI8) driver, including:
+	 -  Added DSN string support (Easy Connect and TNS).
+	 -  Added support for dropping tables to :doc:`Database Forge <database/forge>`.
+	 -  Added support for listing database schemas to :doc:`Database Utilities <database/utilities>`.
+	 -  Generally improved for speed and cleaned up all of its components.
+	 -  *Row* result methods now really only fetch only the needed number of rows, instead of depending entirely on result().
+	 -  num_rows() is now only called explicitly by the developer and no longer re-executes statements.
+   -  Added replace() support for SQLite.
+   -  Renamed internal method _escape_identifiers() to escape_identifiers().
+   -  Added SQLite support for drop_table() in :doc:`Database Forge <database/forge>`.
+   -  Added ODBC support for create_database(), drop_database() and drop_table() in :doc:`Database Forge <database/forge>`.
+   -  Added PDO support for create_database(), drop_database and drop_table() in :doc:`Database Forge <database/forge>`.
+   -  Added MSSQL, SQLSRV support for optimize_table() in :doc:`Database Utility <database/utilities>`.
+   -  Improved CUBRID support for list_databases() in :doc:`Database Utility <database/utilities>` (until now only the currently used database was returned).
 
 -  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).
+   -  Added possibility to send attachment as buffer string in Email::attach() as $this->email->attach($buffer, $disposition, $newname, $mime).
    -  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:
+   -  :doc:`Image Manipulation library <libraries/image_lib>` 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
@@ -87,10 +120,19 @@
    -  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.
-   -  Added function reset_validation() to form validation library, which resets internal validation variables in case of multiple validation routines.
-   -  Changed the Session library to select only one row when using database sessions.
+   -  :doc:`Form Validation library <libraries/form_validation>` changes include:
+	 -  Added method error_array() to return all error messages as an array.
+	 -  Added method set_data() to set an alternative data array to be validated instead of the default $_POST.
+	 -  Added method reset_validation(), which resets internal validation variables in case of multiple validation routines.
+	 -  Added support for setting error delimiters in the config file via $config['error_prefix'] and $config['error_suffix'].
+	 -  _execute() now considers input data to be invalid if a specified rule is not found.
+	 -  Removed method is_numeric() as it exists as a native PHP function and _execute() will find and use that (the 'is_numeric' rule itself is deprecated since 1.6.1).
+	 -  Native PHP functions used as rules can now accept an additional parameter, other than the data itself.
+   -  Changed the :doc:`Session Library <libraries/sessions>` to select only one row when using database sessions.
+   -  Added all_flashdata() method to session class. Returns an associative array of only flashdata.
+   -  Allowed for setting table class defaults in a config file.
+   -  Added a Wincache driver to the :doc:`Caching Library <libraries/caching>`.
+   -  Added dsn (delivery status notification) option to the :doc:`Email Library <libraries/email>`.
 
 -  Core
 
@@ -100,6 +142,10 @@
    -  is_loaded() function from system/core/Commons.php now returns a reference.
    -  $config['rewrite_short_tags'] now has no effect when using PHP 5.4 as *<?=* will always be available.
    -  Added method() to CI_Input to retrieve $_SERVER['REQUEST_METHOD'].
+   -  Modified valid_ip() to use PHP's filter_var() in the :doc:`Input Library <libraries/input>`.
+   -  Added support for HTTP-Only cookies with new config option ``cookie_httponly`` (default FALSE).
+   -  Renamed method _call_hook() to call_hook() in the :doc:`Hooks Library <general/hooks>`.
+   -  Added get_content_type() method to the :doc:`Output Library <libraries/output>`.
 
 Bug fixes for 3.0
 ------------------
@@ -138,7 +184,7 @@
 -  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 (#638) - db_set_charset() ignored its arguments and always used the configured charset 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.
@@ -151,6 +197,21 @@
 -  Fixed a bug in the :doc:`Session Library <libraries/sessions>` where a PHP E_NOTICE error was triggered by _unserialize() due to results from databases such as MSSQL and Oracle being space-padded on the right.
 -  Fixed a bug (#501) - set_rules() to check if the request method is not 'POST' before aborting, instead of depending on count($_POST) in the :doc:`Form Validation Library <libraries/form_validation>`.
 -  Fixed a bug (#940) - csrf_verify() used to set the CSRF cookie while processing a POST request with no actual POST data, which resulted in validating a request that should be considered invalid.
+-  Fixed a bug in PostgreSQL's escape_str() where it didn't properly escape LIKE wild characters.
+-  Fixed a bug in the library loader where some PHP versions wouldn't execute the class constructor.
+-  Fixed a bug (#88) - An unexisting property was used for configuration of the Memcache cache driver.
+-  Fixed a bug (#14) - create_database() method in the :doc:`Database Forge Library <database/forge>` didn't utilize the configured database character set.
+-  Fixed a bug (#23, #1238) - delete_all() in the `Database Caching Library <database/caching>` used to delete .htaccess and index.html files, which is a potential security risk.
+-  Fixed a bug in :doc:`Trackback Library <libraries/trackback>` method validate_url() where it didn't actually do anything, due to input not being passed by reference.
+-  Fixed a bug (#11, #183, #863) - CI_Form_validation::_execute() silently continued to the next rule, if a rule method/function is not found.
+-  Fixed a bug (#1242) - read_dir() in the :doc:`Zip Library <libraries/zip>` wasn't compatible with Windows.
+-  Fixed a bug (#306) - ODBC driver didn't have an _insert_batch() method, which resulted in fatal error being triggered when insert_batch() is used with it.
+-  Fixed a bug in MSSQL and SQLSrv's _truncate() where the TABLE keyword was missing.
+-  Fixed a bug in PDO's trans_commit() method where it failed due to an erroneous property name.
+-  Fixed a bug (#798) - update() used to ignore LIKE conditions that were set with like().
+-  Fixed a bug in Oracle's and MSSQL's delete() methods where an erroneous SQL statement was generated when used with limit().
+-  Fixed a bug in SQLSRV's delete() method where like() and limit() conditions were ignored.
+-  Fixed a bug (#1265) - Database connections were always closed, regardless of the 'pconnect' option value.
 
 Version 2.1.1
 =============
@@ -236,11 +297,9 @@
       override them.
    -  Removed CI_CORE boolean constant from CodeIgniter.php (no longer Reactor and Core versions).
 
-
 Bug fixes for 2.1.0
 -------------------
 
-
 -  Fixed #378 Robots identified as regular browsers by the User Agent
    class.
 -  If a config class was loaded first then a library with the same name
@@ -1239,7 +1298,7 @@
 
 -  Added a language key for valid_emails in validation_lang.php.
 -  Amended fixes for bug (#3419) with parsing DSN database connections.
--  Moved the _has_operators() function (#4535) into DB_driver from
+-  Moved the _has_operator() function (#4535) into DB_driver from
    DB_active_rec.
 -  Fixed a syntax error in upload_lang.php.
 -  Fixed a bug (#4542) with a regular expression in the Image library.
diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py
index 593ceaf..e972a38 100644
--- a/user_guide_src/source/conf.py
+++ b/user_guide_src/source/conf.py
@@ -121,7 +121,7 @@
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+#html_static_path = ['_static']
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst
index 953bbfb..7a19c84 100644
--- a/user_guide_src/source/database/configuration.rst
+++ b/user_guide_src/source/database/configuration.rst
@@ -132,7 +132,7 @@
 **username**		The username used to connect to the database.
 **password**		The password used to connect to the database.
 **database**		The name of the database you want to connect to.
-**dbdriver**		The database type. ie: mysql, postgres, odbc, etc. Must be specified in lower case.
+**dbdriver**		The database type. ie: mysql, postgre, odbc, etc. Must be specified in lower case.
 **dbprefix**		An optional table prefix which will added to the table name when running :doc:
 			`Query Builder <query_builder>` queries. This permits multiple CodeIgniter installations
 			to share one database.
@@ -166,8 +166,8 @@
 				$db['default']['port'] =  5432;
 ======================  ==================================================================================================
 
-.. note:: Depending on what database platform you are using (MySQL,
-	Postgres, etc.) not all values will be needed. For example, when using
-	SQLite you will not need to supply a username or password, and the
-	database name will be the path to your database file. The information
-	above assumes you are using MySQL.
+.. note:: Depending on what database platform you are using (MySQL, PostgreSQL,
+	etc.) not all values will be needed. For example, when using SQLite you
+	will not need to supply a username or password, and the database name
+	will be the path to your database file. The information above assumes
+	you are using MySQL.
diff --git a/user_guide_src/source/database/query_builder.rst b/user_guide_src/source/database/query_builder.rst
index f55d8e2..54e8df6 100644
--- a/user_guide_src/source/database/query_builder.rst
+++ b/user_guide_src/source/database/query_builder.rst
@@ -533,7 +533,7 @@
 **************
 
 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:
+you to create queries with complex WHERE clauses. Nested groups are supported. Example::
 
 	$this->db->select('*')->from('my_table')
 		->group_start()
@@ -921,9 +921,9 @@
 multiple functions. Consider this example::
 
 	$query = $this->db->select('title')
-				->where('id', $id)
-				->limit(10, 20)
-				->get('mytable');
+			->where('id', $id)
+			->limit(10, 20)
+			->get('mytable');
 
 .. _ar-caching:
 
diff --git a/user_guide_src/source/database/utilities.rst b/user_guide_src/source/database/utilities.rst
index 3805ffb..4e83929 100644
--- a/user_guide_src/source/database/utilities.rst
+++ b/user_guide_src/source/database/utilities.rst
@@ -117,7 +117,7 @@
 	echo $this->dbutil->csv_from_result($query);
 
 The second, third, and fourth parameters allow you to set the delimiter
-newline, and enclosure characters respectively. By default tabs are
+newline, and enclosure characters respectively. By default commas are
 used as the delimiter, "\n" is used as a new line, and a double-quote
 is used as the enclosure. Example::
 
diff --git a/user_guide_src/source/general/requirements.rst b/user_guide_src/source/general/requirements.rst
index 3862355..d97b7b4 100644
--- a/user_guide_src/source/general/requirements.rst
+++ b/user_guide_src/source/general/requirements.rst
@@ -2,7 +2,7 @@
 Server Requirements
 ###################
 
--  `PHP <http://www.php.net/>`_ version 5.1.6 or newer.
+-  `PHP <http://www.php.net/>`_ version 5.2.4 or newer.
 -  A Database is required for most web application programming. Current
-   supported databases are MySQL (4.1+), MySQLi, MS SQL, Postgres, Oracle,
-   SQLite, ODBC and CUBRID.
\ No newline at end of file
+   supported databases are MySQL (5.1+), MySQLi, MS SQL, SQLSRV, Oracle,
+   PostgreSQL, SQLite, SQLite3, CUBRID, Interbase, ODBC and PDO.
diff --git a/user_guide_src/source/general/styleguide.rst b/user_guide_src/source/general/styleguide.rst
index d8bdd05..2b91d1c 100644
--- a/user_guide_src/source/general/styleguide.rst
+++ b/user_guide_src/source/general/styleguide.rst
@@ -94,7 +94,7 @@
 
 	class Super_class {
 
-		function __construct()
+		public function __construct()
 		{
 
 		}
@@ -168,7 +168,6 @@
 	/**
 	 * Encodes string for use in XML
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
diff --git a/user_guide_src/source/general/views.rst b/user_guide_src/source/general/views.rst
index dc65f6c..9b7c9da 100644
--- a/user_guide_src/source/general/views.rst
+++ b/user_guide_src/source/general/views.rst
@@ -49,7 +49,7 @@
 	<?php
 	class Blog extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$this->load->view('blogview');
 		}
@@ -74,14 +74,14 @@
 
 	class Page extends CI_Controller {
 
-	   function index()
-	   {
-	      $data['page_title'] = 'Your title';
-	      $this->load->view('header');
-	      $this->load->view('menu');
-	      $this->load->view('content', $data);
-	      $this->load->view('footer');
-	   }
+		public function index()
+		{
+			$data['page_title'] = 'Your title';
+			$this->load->view('header');
+			$this->load->view('menu');
+			$this->load->view('content', $data);
+			$this->load->view('footer');
+		}
 
 	}
 	?>
@@ -126,7 +126,7 @@
 	<?php
 	class Blog extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$data['title'] = "My Real Title";
 			$data['heading'] = "My Real Heading";
@@ -164,7 +164,7 @@
 	<?php
 	class Blog extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$data['todo_list'] = array('Clean House', 'Call Mom', 'Run Errands');
 
diff --git a/user_guide_src/source/helpers/date_helper.rst b/user_guide_src/source/helpers/date_helper.rst
index ad06dd6..b21d147 100644
--- a/user_guide_src/source/helpers/date_helper.rst
+++ b/user_guide_src/source/helpers/date_helper.rst
@@ -255,14 +255,16 @@
 
 The first parameter must contain a Unix timestamp. The second parameter
 must contain a timestamp that is greater that the first timestamp. If
-the second parameter empty, the current time will be used. The most
-common purpose for this function is to show how much time has elapsed
-from some point in time in the past to now. 
+the second parameter empty, the current time will be used. The third 
+parameter is optional and limits the number of time units to display. 
+The most common purpose for this function is to show how much time has 
+elapsed from some point in time in the past to now. 
 
-.. php:method:: timespan($seconds = 1, $time = '')
+.. php:method:: timespan($seconds = 1, $time = '', $units = '')
 
 	:param integer 	$seconds: a number of seconds
 	:param string 	$time: Unix timestamp
+	:param integer 	$units: a number of time units to display
 	:returns: string
 
 Example
@@ -271,7 +273,8 @@
 
 	$post_date = '1079621429';
 	$now = time();
-	echo timespan($post_date, $now);
+	$units = 2;
+	echo timespan($post_date, $now, $units);
 
 .. note:: The text generated by this function is found in the following language
 	file: language/<your_lang>/date_lang.php
diff --git a/user_guide_src/source/helpers/form_helper.rst b/user_guide_src/source/helpers/form_helper.rst
index 3794e08..a110f3c 100644
--- a/user_guide_src/source/helpers/form_helper.rst
+++ b/user_guide_src/source/helpers/form_helper.rst
@@ -45,7 +45,7 @@
 
 ::
 
-	$attributes = array('class' => 'email', 'id' => 'myform');  
+	$attributes = array('class' => 'email', 'id' => 'myform');
 	echo form_open('email/send', $attributes);
 
 The above example would create a form similar to this
@@ -61,15 +61,15 @@
 
 ::
 
-	 $hidden = array('username' => 'Joe', 'member_id' => '234');  
+	 $hidden = array('username' => 'Joe', 'member_id' => '234');
 	echo form_open('email/send', '', $hidden);
 
 The above example would create a form similar to this
 
 ::
 
-	<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send"> 
-		<input type="hidden" name="username" value="Joe" /> 
+	<form method="post" accept-charset="utf-8" action="http://example.com/index.php/email/send">
+		<input type="hidden" name="username" value="Joe" />
 		<input type="hidden" name="member_id" value="234" />
 
 form_open_multipart()
@@ -87,28 +87,67 @@
 
 ::
 
-	form_hidden('username', 'johndoe');  
+	form_hidden('username', 'johndoe');
 	// Would produce: <input type="hidden" name="username" value="johndoe" />
 
 Or you can submit an associative array to create multiple fields
 
 ::
 
-	$data = array(               
-		'name'  => 'John Doe',               
-		'email' => 'john@example.com',               
-		'url'   => 'http://example.com'             
-	);  
-	
-	echo form_hidden($data);  
-	
+	$data = array(
+		'name'  => 'John Doe',
+		'email' => 'john@example.com',
+		'url'   => 'http://example.com'
+	);
+
+	echo form_hidden($data);
+
 	/*
-		Would produce: 
-		<input type="hidden" name="name" value="John Doe" /> 
-		<input type="hidden" name="email" value="john@example.com" /> 
+		Would produce:
+		<input type="hidden" name="name" value="John Doe" />
+		<input type="hidden" name="email" value="john@example.com" />
 		<input type="hidden" name="url" value="http://example.com" />
 	*/
 
+Or pass an associative array to the value field.
+
+::
+
+	$data = array(
+		'name'  => 'John Doe',
+		'email' => 'john@example.com',
+		'url'   => 'http://example.com'
+	);
+
+	echo form_hidden('my_array', $data);
+
+	/*
+		Would produce:
+		<input type="hidden" name="my_array[name]" value="John Doe" />
+		<input type="hidden" name="my_array[email]" value="john@example.com" />
+		<input type="hidden" name="my_array[url]" value="http://example.com" />
+	*/
+
+If you want to create hidden input fields with extra attributes
+
+::
+
+	$data = array(
+		'type'        => 'hidden',
+		'name'        => 'email',
+		'id'          => 'hiddenemail',
+		'value'       => 'john@example.com',
+		'class'       => 'hiddenemail'
+	);
+
+	echo form_input($data);
+
+	/*
+		Would produce:
+
+		<input type="hidden" name="email" value="john@example.com" id="hiddenemail" class="hiddenemail" />
+	*/
+
 form_input()
 ============
 
@@ -124,21 +163,21 @@
 
 ::
 
-	$data = array(               
-		'name'        => 'username',               
-		'id'          => 'username',               
-		'value'       => 'johndoe',               
-		'maxlength'   => '100',               
-		'size'        => '50',               
-		'style'       => 'width:50%',             
-	);  
-	
+	$data = array(
+		'name'        => 'username',
+		'id'          => 'username',
+		'value'       => 'johndoe',
+		'maxlength'   => '100',
+		'size'        => '50',
+		'style'       => 'width:50%'
+	);
+
 	echo form_input($data);
-	
+
 	/*
 		Would produce:
-		
-		<input type="text" name="username" id="username" value="johndoe" maxlength="100" size="50" style="width:50%" />
+
+		<input type="text" name="username" value="johndoe" id="username" maxlength="100" size="50" style="width:50%"  />
 	*/
 
 If you would like your form to contain some additional data, like
@@ -146,7 +185,7 @@
 
 ::
 
-	$js = 'onClick="some_function()"';  
+	$js = 'onClick="some_function()"';
 	echo form_input('username', 'johndoe', $js);
 
 form_password()
@@ -176,37 +215,37 @@
 
 ::
 
-	$options = array(                   
-		'small'  => 'Small Shirt',                   
-		'med'    => 'Medium Shirt',                   
-		'large'   => 'Large Shirt',                   
-		'xlarge' => 'Extra Large Shirt',                 
-	);  
-	
-	$shirts_on_sale = array('small', 'large');  
-	echo form_dropdown('shirts', $options, 'large');  
-	
+	$options = array(
+		'small'  => 'Small Shirt',
+		'med'    => 'Medium Shirt',
+		'large'   => 'Large Shirt',
+		'xlarge' => 'Extra Large Shirt',
+	);
+
+	$shirts_on_sale = array('small', 'large');
+	echo form_dropdown('shirts', $options, 'large');
+
 	/*
-		Would produce:  
-		
-		<select name="shirts"> 
-			<option value="small">Small Shirt</option> 
-			<option value="med">Medium  Shirt</option> 
-			<option value="large" selected="selected">Large Shirt</option> 
-			<option value="xlarge">Extra Large Shirt</option> 
+		Would produce:
+
+		<select name="shirts">
+			<option value="small">Small Shirt</option>
+			<option value="med">Medium  Shirt</option>
+			<option value="large" selected="selected">Large Shirt</option>
+			<option value="xlarge">Extra Large Shirt</option>
 		</select>
 	*/
-	
+
 	echo form_dropdown('shirts', $options, $shirts_on_sale);
-	
+
 	/*
-		Would produce:  
-	
-		<select name="shirts" multiple="multiple"> 
-			<option value="small" selected="selected">Small Shirt</option> 
-			<option value="med">Medium  Shirt</option> 
-			<option value="large" selected="selected">Large Shirt</option> 	
-			<option value="xlarge">Extra Large Shirt</option> 
+		Would produce:
+
+		<select name="shirts" multiple="multiple">
+			<option value="small" selected="selected">Small Shirt</option>
+			<option value="med">Medium  Shirt</option>
+			<option value="large" selected="selected">Large Shirt</option>
+			<option value="xlarge">Extra Large Shirt</option>
 		</select>
 	*/
 
@@ -216,7 +255,7 @@
 
 ::
 
-	$js = 'id="shirts" onChange="some_function();"';  
+	$js = 'id="shirts" onChange="some_function();"';
 	echo form_dropdown('shirts', $options, 'large', $js);
 
 If the array passed as $options is a multidimensional array,
@@ -240,38 +279,38 @@
 
 ::
 
-	echo form_fieldset('Address Information'); 
-	echo "<p>fieldset content here</p>\n"; 
+	echo form_fieldset('Address Information');
+	echo "<p>fieldset content here</p>\n";
 	echo form_fieldset_close();
-	
+
 	/*
 		Produces:
-			<fieldset>  
-				<legend>Address Information</legend>  
-					<p>form content here</p>  
+			<fieldset>
+				<legend>Address Information</legend>
+					<p>form content here</p>
 			</fieldset>
 	*/
-	
+
 Similar to other functions, you can submit an associative array in the
 second parameter if you prefer to set additional attributes.
 
 ::
 
 	$attributes = array(
-		'id' => 'address_info', 
+		'id' => 'address_info',
 		'class' => 'address_info'
-	);     
-	
-	echo form_fieldset('Address Information', $attributes); 
-	echo "<p>fieldset content here</p>\n"; 
-	echo form_fieldset_close();   
-	
+	);
+
+	echo form_fieldset('Address Information', $attributes);
+	echo "<p>fieldset content here</p>\n";
+	echo form_fieldset_close();
+
 	/*
-		Produces: 
-		
-		<fieldset id="address_info" class="address_info">  
-			<legend>Address Information</legend>  
-			<p>form content here</p>  
+		Produces:
+
+		<fieldset id="address_info" class="address_info">
+			<legend>Address Information</legend>
+			<p>form content here</p>
 		</fieldset>
 	*/
 
@@ -284,9 +323,9 @@
 
 ::
 
-	$string = "</div></div>";  
-	echo form_fieldset_close($string);  
-	// Would produce: </fieldset> </div></div>
+	$string = "</div></div>";
+	echo form_fieldset_close($string);
+	// Would produce: </fieldset></div></div>
 
 form_checkbox()
 ===============
@@ -295,7 +334,7 @@
 
 ::
 
-	echo form_checkbox('newsletter', 'accept', TRUE);  
+	echo form_checkbox('newsletter', 'accept', TRUE);
 	// Would produce:  <input type="checkbox" name="newsletter" value="accept" checked="checked" />
 
 The third parameter contains a boolean TRUE/FALSE to determine whether
@@ -306,15 +345,15 @@
 
 ::
 
-	$data = array(     
-		'name'        => 'newsletter',     
-		'id'          => 'newsletter',     
-		'value'       => 'accept',     
-		'checked'     => TRUE,     
-		'style'       => 'margin:10px',     
-	);  
-	
-	echo form_checkbox($data);  
+	$data = array(
+		'name'        => 'newsletter',
+		'id'          => 'newsletter',
+		'value'       => 'accept',
+		'checked'     => TRUE,
+		'style'       => 'margin:10px',
+	);
+
+	echo form_checkbox($data);
 	// Would produce: <input type="checkbox" name="newsletter" id="newsletter" value="accept" checked="checked" style="margin:10px" />
 
 As with other functions, if you would like the tag to contain additional
@@ -323,7 +362,7 @@
 
 ::
 
-	$js = 'onClick="some_function()"';   
+	$js = 'onClick="some_function()"';
 	echo form_checkbox('newsletter', 'accept', TRUE, $js)
 
 form_radio()
@@ -339,7 +378,7 @@
 
 ::
 
-	echo form_submit('mysubmit', 'Submit Post!');  
+	echo form_submit('mysubmit', 'Submit Post!');
 	// Would produce:  <input type="submit" name="mysubmit" value="Submit Post!" />
 
 Similar to other functions, you can submit an associative array in the
@@ -353,7 +392,7 @@
 
 ::
 
-	echo form_label('What is your Name', 'username');  
+	echo form_label('What is your Name', 'username');
 	// Would produce:  <label for="username">What is your Name</label>
 
 Similar to other functions, you can submit an associative array in the
@@ -361,12 +400,12 @@
 
 ::
 
-	$attributes = array(     
-		'class' => 'mycustomclass',     
+	$attributes = array(
+		'class' => 'mycustomclass',
 		'style' => 'color: #000;'
-	);     
-	
-	echo form_label('What is your Name', 'username', $attributes);          
+	);
+
+	echo form_label('What is your Name', 'username', $attributes);
 	// Would produce:  <label for="username" class="mycustomclass" style="color: #000;">What is your Name</label>
 
 
@@ -384,7 +423,7 @@
 
 ::
 
-	 echo form_button('name','content');  
+	 echo form_button('name','content');
 	// Would produce <button name="name" type="button">Content</button>
 
 Or you can pass an associative array containing any data you wish your
@@ -392,15 +431,15 @@
 
 ::
 
-	$data = array(     
-		'name' 		=> 'button',     
-		'id' 		=> 'button',     
-		'value' 	=> 'true',     
-		'type' 		=> 'reset',     
-		'content' 	=> 'Reset' 
-	);  
-	
-	echo form_button($data);  
+	$data = array(
+		'name' 		=> 'button',
+		'id' 		=> 'button',
+		'value' 	=> 'true',
+		'type' 		=> 'reset',
+		'content' 	=> 'Reset'
+	);
+
+	echo form_button($data);
 	// Would produce: <button name="button" id="button" value="true" type="reset">Reset</button>
 
 If you would like your form to contain some additional data, like
@@ -408,7 +447,7 @@
 
 ::
 
-	 $js = 'onClick="some_function()"'; 
+	 $js = 'onClick="some_function()"';
 	echo form_button('mybutton', 'Click Me', $js);
 
 form_close()
@@ -420,8 +459,8 @@
 
 ::
 
-	$string = "</div></div>";  
-	echo form_close($string);  
+	$string = "</div></div>";
+	echo form_close($string);
 	// Would produce:  </form> </div></div>
 
 form_prep()
@@ -432,7 +471,7 @@
 
 ::
 
-	$string = 'Here is a string containing "quoted" text.';  
+	$string = 'Here is a string containing "quoted" text.';
 	<input type="text" name="myform" value="$string" />
 
 Since the above string contains a set of quotes it will cause the form
@@ -475,9 +514,9 @@
 ::
 
 	<select name="myselect">
-		<option value="one" <?php echo  set_select('myselect', 'one', TRUE); ?> >One</option> 
-		<option value="two" <?php echo  set_select('myselect', 'two'); ?> >Two</option> 
-		<option value="three" <?php echo  set_select('myselect', 'three'); ?> >Three</option> 
+		<option value="one" <?php echo  set_select('myselect', 'one', TRUE); ?> >One</option>
+		<option value="two" <?php echo  set_select('myselect', 'two'); ?> >Two</option>
+		<option value="three" <?php echo  set_select('myselect', 'three'); ?> >Three</option>
 	</select>
 
 set_checkbox()
@@ -490,7 +529,7 @@
 
 ::
 
-	<input type="checkbox" name="mycheck" value="1" <?php echo set_checkbox('mycheck', '1'); ?> /> 
+	<input type="checkbox" name="mycheck" value="1" <?php echo set_checkbox('mycheck', '1'); ?> />
 	<input type="checkbox" name="mycheck" value="2" <?php echo set_checkbox('mycheck', '2'); ?> />
 
 set_radio()
@@ -501,6 +540,6 @@
 
 ::
 
-	<input type="radio" name="myradio" value="1" <?php echo  set_radio('myradio', '1', TRUE); ?> /> 
+	<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'); ?> />
 
diff --git a/user_guide_src/source/helpers/html_helper.rst b/user_guide_src/source/helpers/html_helper.rst
index 2e21789..17c28cd 100644
--- a/user_guide_src/source/helpers/html_helper.rst
+++ b/user_guide_src/source/helpers/html_helper.rst
@@ -325,24 +325,44 @@
 The following is a list of doctype choices. These are configurable, and
 pulled from application/config/doctypes.php
 
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| Doctype                | Option                   | Result                                                                                                                    |
-+========================+==========================+===========================================================================================================================+
-| XHTML 1.1              | doctype('xhtml11')       | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">                         |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| XHTML 1.0 Strict       | doctype('xhtml1-strict') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">             |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| XHTML 1.0 Transitional | doctype('xhtml1-trans')  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| XHTML 1.0 Frameset     | doctype('xhtml1-frame')  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">         |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| XHTML Basic 1.1        | doctype('xhtml-basic11') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">             |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| HTML 5                 | doctype('html5')         | <!DOCTYPE html>                                                                                                           |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| HTML 4 Strict          | doctype('html4-strict')  | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">                                |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| HTML 4 Transitional    | doctype('html4-trans')   | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">                    |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
-| HTML 4 Frameset        | doctype('html4-frame')   | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">                     |
-+------------------------+--------------------------+---------------------------------------------------------------------------------------------------------------------------+
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| Doctype                       | Option                       | Result                                                                                                                                           |
++===============================+==============================+==================================================================================================================================================+
+| XHTML 1.1                     | doctype('xhtml11')           | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">                                                |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML 1.0 Strict              | doctype('xhtml1-strict')     | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">                                    |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML 1.0 Transitional        | doctype('xhtml1-trans')      | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">                        |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML 1.0 Frameset            | doctype('xhtml1-frame')      | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">                                |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML Basic 1.1               | doctype('xhtml-basic11')     | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">                                    |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| HTML 5                        | doctype('html5')             | <!DOCTYPE html>                                                                                                                                  |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| HTML 4 Strict                 | doctype('html4-strict')      | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">                                                       |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| HTML 4 Transitional           | doctype('html4-trans')       | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">                                           |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| HTML 4 Frameset               | doctype('html4-frame')       | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">                                            |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| MathML 1.01                   | doctype('mathml1')	       | <!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">                                                                           |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| MathML 2.0                    | doctype('mathml2')           | <!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">                                             |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| SVG 1.0                       | doctype('svg10')             | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">                                       |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| SVG 1.1 Full                  | doctype('svg11')             | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">                                               |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| SVG 1.1 Basic                 | doctype('svg11-basic')       | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">                                   |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| SVG 1.1 Tiny                  | doctype('svg11-tiny')        | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">                                     |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML+MathML+SVG (XHTML host) | doctype('xhtml-math-svg-xh') | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">    |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML+MathML+SVG (SVG host)   | doctype('xhtml-math-svg-sh') | <!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML+RDFa 1.0                | doctype('xhtml-rdfa-1')      | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">                                          |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
+| XHTML+RDFa 1.1                | doctype('xhtml-rdfa-2')      | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">                                          |
++-------------------------------+------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
\ No newline at end of file
diff --git a/user_guide_src/source/helpers/path_helper.rst b/user_guide_src/source/helpers/path_helper.rst
index 1a70af4..847f5a0 100644
--- a/user_guide_src/source/helpers/path_helper.rst
+++ b/user_guide_src/source/helpers/path_helper.rst
@@ -28,10 +28,16 @@
 
 ::
 
-	$directory = '/etc/passwd'; 
-	echo set_realpath($directory); // returns "/etc/passwd"  
-	$non_existent_directory = '/path/to/nowhere'; 
-	echo set_realpath($non_existent_directory, TRUE); // returns an error, as the path could not be resolved  
-	echo set_realpath($non_existent_directory, FALSE); // returns "/path/to/nowhere"   
+	$file = '/etc/php5/apache2/php.ini';
+	echo set_realpath($file); // returns "/etc/php5/apache2/php.ini"
 
+	$non_existent_file = '/path/to/non-exist-file.txt';
+	echo set_realpath($non_existent_file, TRUE);	// shows an error, as the path cannot be resolved
+	echo set_realpath($non_existent_file, FALSE);	// returns "/path/to/non-exist-file.txt"
 
+	$directory = '/etc/php5';
+	echo set_realpath($directory);	// returns "/etc/php5/"
+	
+	$non_existent_directory = '/path/to/nowhere';
+	echo set_realpath($non_existent_directory, TRUE);	// shows an error, as the path cannot be resolved
+	echo set_realpath($non_existent_directory, FALSE);	// returns "/path/to/nowhere"
diff --git a/user_guide_src/source/helpers/security_helper.rst b/user_guide_src/source/helpers/security_helper.rst
index 01018c6..b1bcf2b 100644
--- a/user_guide_src/source/helpers/security_helper.rst
+++ b/user_guide_src/source/helpers/security_helper.rst
@@ -34,8 +34,9 @@
 do_hash()
 =========
 
-Permits you to create SHA1 or MD5 one way hashes suitable for encrypting
-passwords. Will create SHA1 by default. Examples
+Permits you to create one way hashes suitable for encrypting
+passwords. Will create SHA1 by default. See `hash_algos() <http://php.net/function.hash_algos>`_
+for a full list of supported algorithms.
 
 ::
 
@@ -43,7 +44,7 @@
 	$str = do_hash($str, 'md5'); // MD5
 
 .. note:: This function was formerly named dohash(), which has been
-	deprecated in favor of `do_hash()`.
+	removed in favor of `do_hash()`.
 
 strip_image_tags()
 ==================
diff --git a/user_guide_src/source/helpers/string_helper.rst b/user_guide_src/source/helpers/string_helper.rst
index dc70e46..2d23fb0 100644
--- a/user_guide_src/source/helpers/string_helper.rst
+++ b/user_guide_src/source/helpers/string_helper.rst
@@ -108,6 +108,36 @@
 	$string = "http://example.com//index.php";
 	echo reduce_double_slashes($string); // results in "http://example.com/index.php"
 
+strip_slashes()
+===============
+
+Removes any slashes from a string. Example
+
+::
+
+	$str = "Is your name O\'reilly?";
+	echo strip_slashes($str); // results in Is your name O'reilly?
+
+You can also use an array. Example
+
+::
+	
+	$str = array(
+		'question'  => 'Is your name O\'reilly?',
+		'answer' => 'No, my name is O\'connor.'
+	);
+	
+	$str = strip_slashes($str);
+	
+The above will return the following array:
+
+::
+
+	array(
+		'question'  => "Is your name O'reilly?",
+		'answer' => "No, my name is O'connor."
+	);
+
 trim_slashes()
 ==============
 
diff --git a/user_guide_src/source/installation/upgrade_200.rst b/user_guide_src/source/installation/upgrade_200.rst
index 0bcbd5c..b39f4fd 100644
--- a/user_guide_src/source/installation/upgrade_200.rst
+++ b/user_guide_src/source/installation/upgrade_200.rst
@@ -102,7 +102,7 @@
 details, but here are some of the larger changes that are more likely to
 impact your code:
 
-- CodeIgniter now requires PHP 5.1.6.
+- CodeIgniter now requires PHP 5.2.4.
 - Scaffolding has been removed.
 - The CAPTCHA plugin in now a :doc:`helper </helpers/captcha_helper>`.
 - The JavaScript calendar plugin was removed.
diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst
index 27b704d..daf0009 100644
--- a/user_guide_src/source/libraries/email.rst
+++ b/user_guide_src/source/libraries/email.rst
@@ -104,6 +104,7 @@
 **newline**         \\n                    "\\r\\n" or "\\n" or "\\r"   Newline character. (Use "\\r\\n" to comply with RFC 822).
 **bcc_batch_mode**  FALSE                  TRUE or FALSE (boolean)      Enable BCC Batch Mode.
 **bcc_batch_size**  200                    None                         Number of emails in each BCC batch.
+**dsn**             FALSE                  TRUE or FALSE (boolean)      Enable notify message from server
 =================== ====================== ============================ =======================================================================
 
 Email Function Reference
@@ -228,11 +229,20 @@
 	$this->email->attach('/path/to/photo2.jpg');
 	$this->email->attach('/path/to/photo3.jpg');
 
-If you'd like to change the disposition or add a custom file name, you can use the second and third paramaters. To use the default disposition (attachment), leave the second parameter blank. Here's an example::
-  
-	$this->email->attach('/path/to/photo1.jpg', 'inline');
-	$this->email->attach('/path/to/photo1.jpg', '', 'birthday.jpg');
-	
+To use the default disposition (attachment), leave the second parameter blank,
+otherwise use a custom disposition::
+
+	$this->email->attach('image.jpg', 'inline');
+
+If you'd like to use a custom file name, you can use the third paramater::
+
+	$this->email->attach('filename.pdf', 'attachment', 'report.pdf');
+
+If you need to use a buffer string instead of a real - physical - file you can
+use the first parameter as buffer, the third parameter as file name and the fourth
+parameter as mime-type::
+
+	$this->email->attach($buffer, 'attachment', 'report.pdf', 'application/pdf');
 
 $this->email->print_debugger()
 -------------------------------
diff --git a/user_guide_src/source/libraries/file_uploading.rst b/user_guide_src/source/libraries/file_uploading.rst
index 90efca9..d573fc7 100644
--- a/user_guide_src/source/libraries/file_uploading.rst
+++ b/user_guide_src/source/libraries/file_uploading.rst
@@ -90,24 +90,24 @@
 
 	class Upload extends CI_Controller {
 
-		function __construct()
+		public function __construct()
 		{
 			parent::__construct();
 			$this->load->helper(array('form', 'url'));
 		}
 
-		function index()
+		public function index()
 		{
 			$this->load->view('upload_form', array('error' => ' ' ));
 		}
 
-		function do_upload()
+		public function do_upload()
 		{
-			$config['upload_path'] = './uploads/';
-			$config['allowed_types'] = 'gif|jpg|png';
-			$config['max_size']	= '100';
-			$config['max_width']  = '1024';
-			$config['max_height']  = '768';
+			$config['upload_path']		= './uploads/';
+			$config['allowed_types']	= 'gif|jpg|png';
+			$config['max_size']		= 100;
+			$config['max_width']		= 1024;
+			$config['max_height']		= 768;
 
 			$this->load->library('upload', $config);
 
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 5aa64d0..028b61c 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -123,7 +123,7 @@
 
 	class Form extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$this->load->helper(array('form', 'url'));
 
@@ -219,7 +219,7 @@
 
 	class Form extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$this->load->helper(array('form', 'url'));
 
@@ -321,7 +321,7 @@
 function, which removes malicious data.
 
 **Any native PHP function that accepts one parameter can be used as a
-rule, like htmlspecialchars, trim, MD5, etc.**
+rule, like htmlspecialchars, trim, md5, etc.**
 
 .. note:: You will generally want to use the prepping functions
 	**after** the validation rules so if there is an error, the original
@@ -523,7 +523,7 @@
 
 By default, the Form Validation class adds a paragraph tag (<p>) around
 each error message shown. You can either change these delimiters
-globally or individually.
+globally, individually, or change the defaults in a config file.
 
 #. **Changing delimiters Globally**
    To globally change the error delimiters, in your controller function,
@@ -543,6 +543,12 @@
 
       <?php echo validation_errors('<div class="error">', '</div>'); ?>
 
+#. **Set delimiters in a config file**
+   You can add your error delimiters in application/config/form_validation.php as follows::
+   
+      $config['error_prefix'] = '<div class="error_prefix">';
+      $config['error_suffix'] = '</div>';
+
 
 Showing Errors Individually
 ===========================
@@ -602,7 +608,7 @@
 
 For more info please see the :ref:`function-reference` section below.
 
--.. _saving-groups:
+.. _saving-groups:
 
 ************************************************
 Saving Sets of Validation Rules to a Config File
@@ -869,7 +875,7 @@
                                      underscores or dashes.                                                                                               
 **numeric**               No         Returns FALSE if the form element contains anything other than numeric characters.                                   
 **integer**               No         Returns FALSE if the form element contains anything other than an integer.                                           
-**decimal**               Yes        Returns FALSE if the form element is not exactly the parameter value.                                                
+**decimal**               No         Returns FALSE if the form element contains anything other than a decimal number.                                     
 **is_natural**            No         Returns FALSE if the form element contains anything other than a natural number:
                                      0, 1, 2, 3, etc.
 **is_natural_no_zero**    No         Returns FALSE if the form element contains anything other than a natural
@@ -886,8 +892,9 @@
 
 		$this->form_validation->required($string);
 
-.. note:: You can also use any native PHP functions that permit one
-	parameter.
+.. note:: You can also use any native PHP functions that permit up
+	to two parameters, where at least one is required (to pass
+	the field data).
 
 ******************
 Prepping Reference
@@ -970,7 +977,7 @@
 		$_POST array.
 
 $this->form_validation->reset_validation();
-========================================
+===========================================
 
  .. php:method:: reset_validation ()
 
diff --git a/user_guide_src/source/libraries/javascript.rst b/user_guide_src/source/libraries/javascript.rst
index 5e80fb9..d5e09c3 100644
--- a/user_guide_src/source/libraries/javascript.rst
+++ b/user_guide_src/source/libraries/javascript.rst
@@ -86,14 +86,14 @@
 To initialize the jQuery class manually in your controller constructor,
 use the $this->load->library function::
 
-	$this->load->library('jquery');
+	$this->load->library('javascript/jquery');
 
 You may send an optional parameter to determine whether or not a script
 tag for the main jQuery file will be automatically included when loading
 the library. It will be created by default. To prevent this, load the
 library as follows::
 
-	$this->load->library('jquery', FALSE);
+	$this->load->library('javascript/jquery', FALSE);
 
 Once loaded, the jQuery library object will be available using:
 $this->jquery
diff --git a/user_guide_src/source/libraries/output.rst b/user_guide_src/source/libraries/output.rst
index 2cf7c08..baceaae 100644
--- a/user_guide_src/source/libraries/output.rst
+++ b/user_guide_src/source/libraries/output.rst
@@ -49,6 +49,15 @@
 .. important:: Make sure any non-mime string you pass to this method
 	exists in config/mimes.php or it will have no effect.
 
+$this->output->get_content_type();
+==========================================
+
+Returns the Content-Type HTTP header that's currently in use.
+
+	$mime = $this->output->get_content_type();
+
+.. note:: If not set, the default return value is 'text/html'.
+
 $this->output->get_output();
 =============================
 
diff --git a/user_guide_src/source/libraries/sessions.rst b/user_guide_src/source/libraries/sessions.rst
index ef32f5d..e8332ee 100644
--- a/user_guide_src/source/libraries/sessions.rst
+++ b/user_guide_src/source/libraries/sessions.rst
@@ -209,6 +209,10 @@
 To read a flashdata variable::
 
 	$this->session->flashdata('item');
+	
+An array of all flashdata can be retrieved as follows::
+
+	$this->session->all_flashdata();
 
 
 If you find that you need to preserve a flashdata variable through an
diff --git a/user_guide_src/source/libraries/table.rst b/user_guide_src/source/libraries/table.rst
index 9bc3f34..6a808ab 100644
--- a/user_guide_src/source/libraries/table.rst
+++ b/user_guide_src/source/libraries/table.rst
@@ -116,6 +116,8 @@
 	$tmpl = array ( 'table_open'  => '<table border="1" cellpadding="2" cellspacing="1" class="mytable">' );
 
 	$this->table->set_template($tmpl);
+	
+You can also set defaults for these in a config file.
 
 ******************
 Function Reference
diff --git a/user_guide_src/source/libraries/xmlrpc.rst b/user_guide_src/source/libraries/xmlrpc.rst
index 3b94576..dfb8811 100644
--- a/user_guide_src/source/libraries/xmlrpc.rst
+++ b/user_guide_src/source/libraries/xmlrpc.rst
@@ -184,10 +184,10 @@
 
 	class My_blog extends CI_Controller {
 
-	    function new_post($request)
-	    {
+		public function new_post($request)
+		{
 
-	    }
+		}
 	}
 
 The $request variable is an object compiled by the Server, which
@@ -304,7 +304,7 @@
 
 	class Xmlrpc_client extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$this->load->helper('url');
 			$server_url = site_url('xmlrpc_server');
@@ -345,7 +345,7 @@
 
 	class Xmlrpc_server extends CI_Controller {
 
-		function index()
+		public function index()
 		{
 			$this->load->library('xmlrpc');
 			$this->load->library('xmlrpcs');
@@ -357,15 +357,17 @@
 		}
 
 
-		function process($request)
+		public function process($request)
 		{
 			$parameters = $request->output_parameters();
 
 			$response = array(
-								array(
-										'you_said'  => $parameters['0'],
-										'i_respond' => 'Not bad at all.'),
-								'struct');
+						array(
+							'you_said'  => $parameters[0],
+							'i_respond' => 'Not bad at all.'
+						),
+						'struct'
+					);
 
 			return $this->xmlrpc->send_response($response);
 		}
@@ -419,9 +421,9 @@
 ::
 
 	$parameters = $request->output_parameters();
-	$name = $parameters['0']['name'];
-	$size = $parameters['1']['size'];
-	$size = $parameters['1']['shape'];
+	$name = $parameters[0]['name'];
+	$size = $parameters[1]['size'];
+	$size = $parameters[1]['shape'];
 
 **************************
 XML-RPC Function Reference