Merge upstream branch
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..032bf9d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: php
+
+phps:
+  - 5.2
+  - 5.3
+  - 5.4
+
+before_script:
+  - pyrus channel-discover pear.php-tools.net
+  - pyrus install http://pear.php-tools.net/get/vfsStream-0.11.2.tgz
+  - phpenv rehash
+
+script: phpunit --configuration tests/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..e8c9993 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.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/config.php b/application/config/config.php
index 17b854b..2ffbb66 100644
--- a/application/config/config.php
+++ b/application/config/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
  * 
@@ -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..fce1013 100644
--- a/application/config/constants.php
+++ b/application/config/constants.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/database.php b/application/config/database.php
index bd68db1..154638d 100644
--- a/application/config/database.php
+++ b/application/config/database.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/doctypes.php b/application/config/doctypes.php
index 984da59..e5e70da 100644
--- a/application/config/doctypes.php
+++ b/application/config/doctypes.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/foreign_chars.php b/application/config/foreign_chars.php
index 1ae0cef..d3713fe 100644
--- a/application/config/foreign_chars.php
+++ b/application/config/foreign_chars.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/hooks.php b/application/config/hooks.php
index 80269df..1b10fc2 100644
--- a/application/config/hooks.php
+++ b/application/config/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
  * 
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..e1ce1ae 100644
--- a/application/config/migration.php
+++ b/application/config/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
  *
diff --git a/application/config/mimes.php b/application/config/mimes.php
index d69497a..7ec782b 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
  *
diff --git a/application/config/profiler.php b/application/config/profiler.php
index f956142..5339189 100644
--- a/application/config/profiler.php
+++ b/application/config/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
  * 
diff --git a/application/config/routes.php b/application/config/routes.php
index 53fc7e7..686573d 100644
--- a/application/config/routes.php
+++ b/application/config/routes.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/smileys.php b/application/config/smileys.php
index 4132aed..8e3844a 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.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/user_agents.php b/application/config/user_agents.php
index e7a6894..0baa252 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.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/controllers/welcome.php b/application/controllers/welcome.php
index 5eb0e96..2451d97 100644
--- a/application/controllers/welcome.php
+++ b/application/controllers/welcome.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/errors/error_404.php b/application/errors/error_404.php
index 4dd8fc4..9af9e39 100644
--- a/application/errors/error_404.php
+++ b/application/errors/error_404.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/errors/error_db.php b/application/errors/error_db.php
index 130ffc1..81ff02a 100644
--- a/application/errors/error_db.php
+++ b/application/errors/error_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
  * 
diff --git a/application/errors/error_general.php b/application/errors/error_general.php
index 2a844a8..8efcfd9 100644
--- a/application/errors/error_general.php
+++ b/application/errors/error_general.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/errors/error_php.php b/application/errors/error_php.php
index 8e293cd..42e5f5a 100644
--- a/application/errors/error_php.php
+++ b/application/errors/error_php.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/views/welcome_message.php b/application/views/welcome_message.php
index acc36b6..0dd8924 100644
--- a/application/views/welcome_message.php
+++ b/application/views/welcome_message.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/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..f6b634d 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
  *
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 7af3c48..a79a695 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
  *
diff --git a/system/core/Common.php b/system/core/Common.php
index 4919793..f20acaf 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
  *
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..d7282b1 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
  *
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index e1ac58e..493822f 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
  *
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 20cf7ef..9b9cc2f 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
  *
@@ -615,13 +615,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
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..faebbbe 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
  *
diff --git a/system/core/Router.php b/system/core/Router.php
index d213195..b251abb 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
  *
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 d06ffb4..116116b 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
  *
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index de8cfc1..fe591dd 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.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_active_record extends CI_DB_driver {
+abstract class CI_DB_active_record extends CI_DB_driver {
 
 	protected $return_delete_sql		= FALSE;
 	protected $reset_delete_data		= FALSE;
@@ -214,6 +214,7 @@
 
 		$sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->protect_identifiers(trim($alias));
 		$this->ar_select[] = $sql;
+		$this->ar_no_escape[] = NULL;
 
 		if ($this->ar_caching === TRUE)
 		{
@@ -2196,19 +2197,19 @@
 	protected function _reset_write()
 	{
 		$this->_reset_run(array(
-					'ar_set'	=> array(),
-					'ar_from'	=> array(),
-					'ar_where'	=> array(),
-					'ar_like'	=> array(),
-					'ar_orderby'	=> array(),
-					'ar_keys'	=> array(),
-					'ar_limit'	=> FALSE,
-					'ar_order'	=> FALSE
-					)
-				);
+			'ar_set'	=> array(),
+			'ar_from'	=> array(),
+			'ar_where'	=> array(),
+			'ar_like'	=> array(),
+			'ar_orderby'	=> array(),
+			'ar_keys'	=> array(),
+			'ar_limit'	=> FALSE,
+			'ar_order'	=> FALSE
+			)
+		);
 	}
 
 }
 
 /* End of file DB_active_rec.php */
-/* Location: ./system/database/DB_active_rec.php */
+/* Location: ./system/database/DB_active_rec.php */
\ No newline at end of file
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 79651fc..58e6968 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
  *
@@ -183,4 +183,4 @@
 }
 
 /* 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 025441f..42b1b35 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;
@@ -165,7 +165,7 @@
 		}
 
 		// 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);
 	}
 
 	// --------------------------------------------------------------------
@@ -177,9 +177,9 @@
 	 * @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);
 
@@ -670,7 +670,7 @@
 	 */
 	public function escape($str)
 	{
-		if (is_string($str))
+		if (is_string($str) OR method_exists($str, '__toString'))
 		{
 			$str = "'".$this->escape_str($str)."'";
 		}
@@ -1357,11 +1357,9 @@
 	 *
 	 * @return	void
 	 */
-	protected function _reset_select()
-	{
-	}
+	abstract protected function _reset_select();
 
 }
 
 /* End of file DB_driver.php */
-/* Location: ./system/database/DB_driver.php */
+/* Location: ./system/database/DB_driver.php */
\ No newline at end of file
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 336e949..34c502a 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
  *
@@ -34,7 +34,7 @@
  * @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();
@@ -346,4 +346,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_result.php b/system/database/DB_result.php
index 61aa561..37c50e5 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
  *
@@ -36,7 +36,7 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-class CI_DB_result {
+abstract class CI_DB_result {
 
 	public $conn_id				= NULL;
 	public $result_id			= NULL;
@@ -392,4 +392,4 @@
 }
 
 /* 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..642a004 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,7 +32,7 @@
  * @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();
@@ -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 3c0850a..f39c2ad 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,39 +40,35 @@
  */
 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
 
 	/**
 	 * 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;
+			// Default CUBRID Broker port
+			$this->port = 33000;
 		}
 
 		$conn = cubrid_connect($this->hostname, $this->port, $this->database, $this->username, $this->password);
@@ -101,6 +95,7 @@
 
 	/**
 	 * 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
@@ -109,10 +104,9 @@
 	 * @cubrid_connect function will establish persisten connection
 	 * considering that the CCI_PCONNECT is ON.
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
 		return $this->db_connect();
 	}
@@ -125,10 +119,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)
 		{
@@ -141,10 +134,9 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_select()
+	public function db_select()
 	{
 		// In CUBRID there is no need to select a database as the database
 		// is chosen at the connection time.
@@ -172,42 +164,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 +210,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -269,10 +240,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -300,12 +270,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 +321,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 +336,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 +364,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 +386,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 +401,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";
 	}
@@ -465,11 +429,10 @@
 	 *
 	 * This function escapes column and table names
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _escape_identifiers($item)
+	public function _escape_identifiers($item)
 	{
 		if ($this->_escape_char == '')
 		{
@@ -508,11 +471,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))
 		{
@@ -529,13 +491,12 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _insert($table, $keys, $values)
 	{
 		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
 	}
@@ -548,13 +509,12 @@
 	 *
 	 * Generates a platform-specific replace string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _replace($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
 		return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
 	}
@@ -566,13 +526,12 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert_batch($table, $keys, $values)
+	protected function _insert_batch($table, $keys, $values)
 	{
 		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
 	}
@@ -585,7 +544,6 @@
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
@@ -593,7 +551,7 @@
 	 * @param	array	the limit clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
 		foreach ($values as $key => $val)
 		{
@@ -621,13 +579,12 @@
 	 *
 	 * 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 ' : '';
@@ -668,7 +625,6 @@
 
 	// --------------------------------------------------------------------
 
-
 	/**
 	 * Truncate statement
 	 *
@@ -676,11 +632,10 @@
 	 * If the database does not support the truncate() command
 	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
 		return "TRUNCATE ".$table;
 	}
@@ -692,13 +647,12 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
 		$conditions = '';
 
@@ -726,13 +680,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)
 		{
@@ -751,17 +704,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 */
+/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index 76002cb..bbda484 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
  *
@@ -39,11 +37,10 @@
 	/**
 	 * Create database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _create_database($name)
+	public function _create_database($name)
 	{
 		// CUBRID does not allow to create a database in SQL. The GUI tools
 		// have to be used for this purpose.
@@ -55,11 +52,10 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _drop_database($name)
+	public function _drop_database($name)
 	{
 		// CUBRID does not allow to drop a database in SQL. The GUI tools
 		// have to be used for this purpose.
@@ -71,16 +67,15 @@
 	/**
 	 * 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 +167,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	mixed	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -232,10 +226,9 @@
 	/**
 	 * Drop Table
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _drop_table($table)
+	public function _drop_table($table)
 	{
 		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
 	}
@@ -248,14 +241,13 @@
 	 * Generates a platform-specific query so that a table can be altered
 	 * Called by add_column(), drop_column(), and column_alter(),
 	 *
-	 * @access	private
 	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
 	 * @param	string	the column name
 	 * @param	array	fields
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	public function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -282,12 +274,11 @@
 	 *
 	 * Generates a platform-specific query so that a table can be renamed
 	 *
-	 * @access	private
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	string
 	 */
-	function _rename_table($table_name, $new_table_name)
+	public function _rename_table($table_name, $new_table_name)
 	{
 		return 'RENAME TABLE '.$this->db->protect_identifiers($table_name).' AS '.$this->db->protect_identifiers($new_table_name);
 	}
@@ -295,4 +286,4 @@
 }
 
 /* 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..6a61a21 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
 	 */
-	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..dafd661 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,10 +37,9 @@
 	/**
 	 * 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
@@ -66,12 +63,11 @@
 	 *
 	 * Generates a platform-specific query so that a table can be optimized
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 * @link 	http://www.cubrid.org/manual/840/en/Optimize%20Database
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
 		// No SQL based support in CUBRID as of version 8.4.0. Database or
 		// table optimization can be performed using CUBRID Manager
@@ -86,12 +82,11 @@
 	 *
 	 * Generates a platform-specific query so that a table can be repaired
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 * @link 	http://www.cubrid.org/manual/840/en/Checking%20Database%20Consistency
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
 		// Not supported in CUBRID as of version 8.4.0. Database or
 		// table consistency can be checked using CUBRID Manager
@@ -103,11 +98,10 @@
 	/**
 	 * CUBRID Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	public 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..9fa03ad 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
  *
@@ -148,28 +148,12 @@
 	 */
 	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
@@ -623,4 +607,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..f460435 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
  *
diff --git a/system/database/drivers/interbase/interbase_result.php b/system/database/drivers/interbase/interbase_result.php
index 4b15eee..5bf0c90 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
  *
diff --git a/system/database/drivers/interbase/interbase_utility.php b/system/database/drivers/interbase/interbase_utility.php
index 76a0497..a88055e 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
  *
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 39b84f9..ccbc3c4 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_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
  * 
@@ -146,29 +146,12 @@
 	 */
 	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
@@ -656,7 +639,5 @@
 
 }
 
-
-
 /* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
+/* Location: ./system/database/drivers/mssql/mssql_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php
index ec97805..ee8b8f5 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_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
  * 
@@ -256,4 +256,4 @@
 }
 
 /* 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..c77c5a7 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_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
  * 
@@ -176,6 +176,5 @@
 
 }
 
-
 /* 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..28f34b9 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_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
  * 
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index cd17637..bef4111 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)
@@ -715,4 +701,4 @@
 }
 
 /* End of file mysql_driver.php */
-/* Location: ./system/database/drivers/mysql/mysql_driver.php */
+/* Location: ./system/database/drivers/mysql/mysql_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index a907b20..11172b4 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
  *
@@ -66,7 +66,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	private function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -237,4 +237,4 @@
 }
 
 /* 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..f76076f 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
  *
@@ -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..2d89cb9 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
  *
@@ -204,4 +204,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 d06119a..4c5d521 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
  *
@@ -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 @mysqli_set_charset($this->conn_id, $charset);
 	}
 
 	// --------------------------------------------------------------------
@@ -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) ? mysqli_real_escape_string($this->conn_id, $str) : addslashes($str);
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
@@ -711,4 +697,4 @@
 }
 
 /* End of file mysqli_driver.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
+/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index 744525f..8cf0ae1 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
  *
@@ -66,7 +66,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	public function _process_fields($fields)
+	protected function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
@@ -86,9 +86,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' : '');
@@ -214,4 +237,4 @@
 }
 
 /* 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..83d88aa 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
  *
@@ -167,4 +167,4 @@
 }
 
 /* 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..4d7002e 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
  *
@@ -90,4 +90,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 8db6c12..e3846bc 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_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
  * 
@@ -180,26 +180,10 @@
 	{
 		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
-	 *
-	 * 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;
-	}
-
+	
 	// --------------------------------------------------------------------
 
 	/**
@@ -797,7 +781,5 @@
 
 }
 
-
-
 /* End of file oci8_driver.php */
-/* Location: ./system/database/drivers/oci8/oci8_driver.php */
+/* Location: ./system/database/drivers/oci8/oci8_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index 48f98d0..0a25199 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_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
  * 
@@ -225,4 +225,4 @@
 }
 
 /* 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..a14e32e 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_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
  * 
@@ -235,6 +235,5 @@
 
 }
 
-
 /* 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..62dfb2f 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_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
  * 
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 2575f43..6704264 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,25 +40,25 @@
  */
 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);
 
@@ -70,10 +68,9 @@
 	/**
 	 * 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);
 	}
@@ -83,10 +80,9 @@
 	/**
 	 * 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);
 	}
@@ -99,10 +95,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()
 	{
 		// not implemented in odbc
 	}
@@ -112,10 +107,9 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_select()
+	public function db_select()
 	{
 		// Not needed for ODBC
 		return TRUE;
@@ -126,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 @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 +161,9 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	public function trans_commit()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -212,10 +186,9 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	public function trans_rollback()
 	{
 		if ( ! $this->trans_enabled)
 		{
@@ -238,12 +211,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 +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;
@@ -274,10 +246,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 +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 == '')
 		{
@@ -332,11 +302,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 +325,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 +340,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;
 	}
@@ -403,11 +370,10 @@
 	 *
 	 * This function escapes column and table names
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _escape_identifiers($item)
+	public function _escape_identifiers($item)
 	{
 		if ($this->_escape_char == '')
 		{
@@ -446,11 +412,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))
 		{
@@ -467,13 +432,12 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _insert($table, $keys, $values)
 	{
 		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
 	}
@@ -485,7 +449,6 @@
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
@@ -493,7 +456,7 @@
 	 * @param	array	the limit clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
 		foreach ($values as $key => $val)
 		{
@@ -523,11 +486,10 @@
 	 * If the database does not support the truncate() command
 	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
 		return $this->_delete($table);
 	}
@@ -539,13 +501,12 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
 		$conditions = '';
 
@@ -573,13 +534,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 +550,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 */
+/* Location: ./system/database/drivers/odbc/odbc_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php
index 51addf0..486a8dd 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
  *
@@ -39,11 +37,10 @@
 	/**
 	 * Create database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _create_database()
+	public function _create_database()
 	{
 		// ODBC has no "create database" command since it's
 		// designed to connect to an existing database
@@ -59,11 +56,10 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _drop_database($name)
+	public function _drop_database($name)
 	{
 		// ODBC has no "drop database" command since it's
 		// designed to connect to an existing database
@@ -79,15 +75,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	array	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -99,7 +94,7 @@
 		$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
@@ -186,10 +181,9 @@
 	/**
 	 * Drop Table
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	function _drop_table($table)
+	public function _drop_table($table)
 	{
 		// Not a supported ODBC feature
 		if ($this->db->db_debug)
@@ -207,17 +201,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 = '')
+	public 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);
 
@@ -260,12 +253,11 @@
 	 *
 	 * Generates a platform-specific query so that a table can be renamed
 	 *
-	 * @access	private
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	string
 	 */
-	function _rename_table($table_name, $new_table_name)
+	public function _rename_table($table_name, $new_table_name)
 	{
 		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
 	}
@@ -273,4 +265,4 @@
 }
 
 /* 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..30cc979 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))
 		{
@@ -148,10 +146,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 FALSE;
 	}
@@ -163,12 +160,11 @@
 	 *
 	 * 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 +181,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 +195,7 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
 	/**
 	 * Result - object
@@ -207,21 +203,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 +228,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 +319,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..65445e9 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
  *
@@ -39,10 +37,9 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	function _list_databases()
+	public function _list_databases()
 	{
 		// Not sure if ODBC lets you list all databases...
 		if ($this->db->db_debug)
@@ -59,11 +56,10 @@
 	 *
 	 * Generates a platform-specific query so that a table can be optimized
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
 		// Not a supported ODBC feature
 		if ($this->db->db_debug)
@@ -80,11 +76,10 @@
 	 *
 	 * Generates a platform-specific query so that a table can be repaired
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
 		// Not a supported ODBC feature
 		if ($this->db->db_debug)
@@ -99,11 +94,10 @@
 	/**
 	 * ODBC Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	public function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index c8732ac..9b44e7c 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_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
  * 
@@ -561,6 +561,11 @@
 			// 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."`";
@@ -603,6 +608,22 @@
 	 */
 	function _field_data($table)
 	{
+		if ($this->pdodriver == 'mysql' or $this->pdodriver == 'pgsql')
+		{
+			// Analog function for mysql and postgre
+			return 'SELECT * FROM '.$this->_from_tables($table).' LIMIT 1';
+		}
+		elseif ($this->pdodriver == 'oci')
+		{
+			// Analog function for oci
+			return 'SELECT * FROM '.$this->_from_tables($table).' WHERE ROWNUM <= 1';
+		}
+		elseif ($this->pdodriver == 'sqlite')
+		{
+			// Analog function for sqlite
+			return 'PRAGMA table_info('.$this->_from_tables($table).')';
+		}
+		
 		return 'SELECT TOP 1 FROM '.$this->_from_tables($table);
 	}
 
@@ -921,4 +942,4 @@
 }
 
 /* End of file pdo_driver.php */
-/* Location: ./system/database/drivers/pdo/pdo_driver.php */
+/* Location: ./system/database/drivers/pdo/pdo_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index b4ddca5..2e5c81d 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_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
  * 
@@ -278,4 +278,4 @@
 }
 
 /* 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..384b753 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_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
  * 
@@ -160,9 +160,48 @@
 	
 		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;
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index 971ec88..c278c51 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_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
  * 
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 6feec73..3bfccad 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,29 +40,28 @@
  */
 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
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _connect_string()
+	protected function _connect_string()
 	{
 		$components = array(
 								'hostname'	=> 'host',
@@ -90,10 +87,9 @@
 	/**
 	 * 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());
 	}
@@ -103,10 +99,9 @@
 	/**
 	 * 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());
 	}
@@ -119,10 +114,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)
 		{
@@ -135,10 +129,9 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_select()
+	public function db_select()
 	{
 		// Not needed for Postgre so we'll return TRUE
 		return TRUE;
@@ -191,35 +184,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 +256,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 +277,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 +290,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 +302,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	string
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		$v = $this->version();
 
@@ -372,11 +344,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 +372,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 +394,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 +409,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";
 	}
@@ -471,11 +439,10 @@
 	 *
 	 * This function escapes column and table names
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _escape_identifiers($item)
+	public function _escape_identifiers($item)
 	{
 		if ($this->_escape_char == '')
 		{
@@ -514,11 +481,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))
 		{
@@ -535,13 +501,12 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _insert($table, $keys, $values)
 	{
 		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
 	}
@@ -553,13 +518,12 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access  public
 	 * @param   string  the table name
 	 * @param   array   the insert keys
 	 * @param   array   the insert values
 	 * @return  string
 	 */
-	function _insert_batch($table, $keys, $values)
+	protected function _insert_batch($table, $keys, $values)
 	{
 		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
 	}
@@ -571,7 +535,6 @@
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
@@ -579,7 +542,7 @@
 	 * @param	array	the limit clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
 		foreach ($values as $key => $val)
 		{
@@ -602,11 +565,10 @@
 	 * If the database does not support the truncate() command
 	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
 		return "TRUNCATE ".$table;
 	}
@@ -618,13 +580,12 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
 		$conditions = '';
 
@@ -649,13 +610,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 +632,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 */
+/* Location: ./system/database/drivers/postgre/postgre_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php
index 4a7348a..a724498 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
  *
@@ -39,11 +37,10 @@
 	/**
 	 * Create database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _create_database($name)
+	public function _create_database($name)
 	{
 		return "CREATE DATABASE ".$name;
 	}
@@ -53,29 +50,28 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function _drop_database($name)
+	public 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 +164,7 @@
 				$sql .= ',';
 			}
 		}
-		
+
 		return $sql;
 	}
 
@@ -177,15 +173,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	array	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -241,8 +236,10 @@
 
 	/**
 	 * Drop Table
+	 *
+	 * @return	string
 	 */
-	function _drop_table($table)
+	public function _drop_table($table)
 	{
 		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table)." CASCADE";
 	}
@@ -255,7 +252,6 @@
 	 * 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 +259,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 = '')
+	public function _alter_table($alter_type, $table, $fields, $after_field = '')
  	{
  		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
 
@@ -292,16 +288,15 @@
 	 *
 	 * Generates a platform-specific query so that a table can be renamed
 	 *
-	 * @access	private
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	string
 	 */
-	function _rename_table($table_name, $new_table_name)
+	public function _rename_table($table_name, $new_table_name)
 	{
 		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..8b22564 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,10 +65,9 @@
 	 *
 	 * 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++)
@@ -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();
 		for ($i = 0; $i < $this->num_fields(); $i++)
@@ -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
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return pg_result_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 pg_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 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..c6b71b4 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
  *
@@ -86,4 +86,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 91598ab..de72b54 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_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
  * 
@@ -27,8 +27,6 @@
 
 // ------------------------------------------------------------------------
 
-
-
 /**
  * SQLite Database Adapter Class
  *
@@ -163,29 +161,12 @@
 	 */
 	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
@@ -642,4 +623,4 @@
 
 
 /* End of file sqlite_driver.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
+/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 4f379d9..26d0d94 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_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
  * 
@@ -274,4 +274,4 @@
 }
 
 /* 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..ac2235c 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_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
  * 
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index 8fefcd9..c07004c 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
  *
@@ -94,4 +94,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/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 5c90cb4..0239e8f 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
  * 
@@ -152,7 +152,6 @@
 	 */
 	function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
 		return sqlsrv_query($this->conn_id, $sql, null, array(
 			'Scrollable'				=> SQLSRV_CURSOR_STATIC,
 			'SendStreamParamsAtExec'	=> true
@@ -162,22 +161,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * 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
@@ -618,7 +601,5 @@
 
 }
 
-
-
 /* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
+/* Location: ./system/database/drivers/mssql/mssql_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index 1521922..0a276e1 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
  * 
@@ -256,4 +256,4 @@
 }
 
 /* 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..d980f98 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
  * 
@@ -176,6 +176,5 @@
 
 }
 
-
 /* 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/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index e96df96..44e6faf 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_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
  * 
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index c46c4d1..464d1d1 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;
@@ -128,4 +103,4 @@
 }
 
 /* End of file array_helper.php */
-/* Location: ./system/helpers/array_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/array_helper.php */
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 4a48df2..5787965 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_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
  *
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 7b439c4..ec8aa32 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
+/* Location: ./system/helpers/cookie_helper.php */
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 9e58d86..d545532 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_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
  *
@@ -128,15 +128,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]))
@@ -159,11 +160,12 @@
  * @access	public
  * @param	integer	a number of seconds
  * @param	integer	Unix timestamp
- * @return	integer
+ * @param	integer	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 +180,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 +210,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 +222,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 +234,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 +246,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);
 	}
 }
 
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index be65b38..d7ca13e 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
+/* Location: ./system/helpers/directory_helper.php */
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index a8c59c2..96ff29d 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
  *
@@ -60,19 +60,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 +90,20 @@
 			}
 		}
 
+		/* 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);
+		}
+
 		// 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');
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index f184031..b87bce6 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
  *
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 2d4b10e..3fd6b82 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
  *
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 6efef23..37337d9 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
  *
@@ -314,6 +314,28 @@
 {
 	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']))
+    {
+      
+      if ( ! isset($name['options'])) 
+      {
+        $name['options'] = array();
+      }
+      
+      if ( ! isset($name['selected'])) 
+      {
+        $name['selected'] = array();
+      }
+      
+      if ( ! isset($name['extra'])) 
+      {
+        $name['extra'] = '';
+      }
+      
+      return form_dropdown($name['name'], $name['options'], $name['selected'], $name['extra']);
+    }
+    
 		if ( ! is_array($selected))
 		{
 			$selected = array($selected);
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index 72970d9..b8c4f36 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
  *
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index 02c425b..485806b 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);
 	}
 }
 
@@ -232,4 +229,4 @@
 }
 
 /* End of file inflector_helper.php */
-/* Location: ./system/helpers/inflector_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/inflector_helper.php */
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index a83580a..1d66df5 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
  *
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 331b468..b6c823d 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
  *
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index cd87a73..c31f0bd 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
  *
@@ -51,28 +49,24 @@
 {
 	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;
 	}
 }
 
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index 99fda56..8c7adea 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
  */
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 700f448..cc903bc 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_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
  * 
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 04d51c2..607a12b 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_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
  * 
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index 6e9ea57..7591bac 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_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
  * 
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index c49348e..9b19c7c 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
  *
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 3f0fef5..2ae1fd3 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
  *
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 5242193..f3ff576 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
  *
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..7642a52 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
  *
@@ -39,20 +39,17 @@
 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))
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index a3dd469..c387a30 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
  *
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index fcd55da..c9767e4 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
  *
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index a960730..c0be0de 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
  *
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index ffe6f2f..b8f2d7e 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
  *
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
new file mode 100644
index 0000000..df619d4
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -0,0 +1,165 @@
+<?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 */
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index a05a7ba..6c04de8 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
  *
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
index 10b5362..60a1e52 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
  *
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index 4e89443..9a073b3 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
  *
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 8d839d0..f30fe40 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
  *
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 0b06189..b29eb47 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
  *
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 8a5d8ea..8a27935 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
  *
@@ -51,6 +51,18 @@
 	{
 		$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;
 
@@ -58,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'));
 		}
@@ -87,7 +99,7 @@
 			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))
 		{
@@ -925,7 +937,7 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
+		if (MB_ENABLED === TRUE)
 		{
 			return ! (mb_strlen($str) < $val);
 		}
@@ -949,7 +961,7 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
+		if (MB_ENABLED === TRUE)
 		{
 			return ! (mb_strlen($str) > $val);
 		}
@@ -973,7 +985,7 @@
 			return FALSE;
 		}
 
-		if (function_exists('mb_strlen'))
+		if (MB_ENABLED === TRUE)
 		{
 			return (mb_strlen($str) == $val);
 		}
@@ -1337,4 +1349,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..4d96c00 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
  *
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 9826eab..86b77bf 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
  *
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 33df600..9ba9300 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
  *
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 944173f..955277a 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
  *
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index d070972..c045ac0 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
  *
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 35ac541..86b8d79 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
  *
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index 3212482..290e17f 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
  *
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 04216be..d84e5d3 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
  *
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 104b888..3a80c16 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);
 		}
@@ -468,6 +469,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
+		);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index fb154e5..11a4858 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
  *
@@ -49,9 +47,21 @@
 	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");
+		log_message('debug', 'Table Class Initialized');
+
+		// initialize config
+		foreach ($config as $key => $val)
+		{
+			$this->template[$key] = $val;
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -102,7 +112,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;
 		}
@@ -395,7 +405,7 @@
 		// 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;
 			}
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 79a0091..be1de6f 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
  *
@@ -141,7 +141,7 @@
 
 			$this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));
 
-			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']);
 			}
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index 46c73ef..65e30b0 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
  *
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 38d767c..2eb8df3 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
  *
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 89575c8..42664a5 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
  *
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index cd644c0..9109edd 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
  *
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 730a0fc..32e2e52 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
  *
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 355d43f..fc41444 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
  *
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 50e8492..e33eb4e 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.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/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..39c24b2
--- /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 $dir.'/lib/common.php';
+require_once $dir.'/lib/ci_testcase.php';
+
+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..cec1298
--- /dev/null
+++ b/tests/codeigniter/core/Common_test.php
@@ -0,0 +1,16 @@
+<?php
+
+require_once(BASEPATH.'helpers/email_helper.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..b86fd34
--- /dev/null
+++ b/tests/codeigniter/core/Loader_test.php
@@ -0,0 +1,271 @@
+<?php
+
+require_once 'vfsStream/vfsStream.php';
+require_once BASEPATH.'/core/Loader.php';
+
+class Extended_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);
+	}
+}
+
+
+class Loader_test extends CI_TestCase {
+	
+	private $ci_obj;
+	
+	public function set_up()
+	{
+		// Instantiate a new loader
+		$this->load = new Extended_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..40252aa
--- /dev/null
+++ b/tests/codeigniter/core/URI_test.php
@@ -0,0 +1,344 @@
+<?php
+
+require BASEPATH.'core/URI.php';
+
+/**
+ * Extend the URI class
+ *  - override contructor
+ *  - override CLI detection
+ */
+class URI_extended 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;
+	}
+}
+
+class URI_test extends CI_TestCase {
+	
+	public function set_up()
+	{
+		$this->uri = new URI_extended();
+	}
+
+	// --------------------------------------------------------------------
+
+	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/helpers/array_helper_test.php b/tests/codeigniter/helpers/array_helper_test.php
new file mode 100644
index 0000000..62559de
--- /dev/null
+++ b/tests/codeigniter/helpers/array_helper_test.php
@@ -0,0 +1,49 @@
+<?php
+
+// OLD TEST FORMAT: DO NOT COPY
+
+require_once(BASEPATH.'helpers/array_helper.php');
+
+class Array_helper_test extends CI_TestCase
+{
+	public function set_up()
+	{
+		$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..662d164
--- /dev/null
+++ b/tests/codeigniter/helpers/date_helper_test.php
@@ -0,0 +1,284 @@
+<?php
+require_once BASEPATH.'helpers/date_helper.php';
+
+class Date_helper_test extends CI_TestCase
+{
+	// ------------------------------------------------------------------------
+
+	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..3fae81b
--- /dev/null
+++ b/tests/codeigniter/helpers/directory_helper_test.php
@@ -0,0 +1,42 @@
+<?php
+
+require_once 'vfsStream/vfsStream.php';
+require BASEPATH.'helpers/directory_helper.php';
+
+class Directory_helper_test extends CI_TestCase
+{
+	public function set_up()
+	{
+		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..7324e81
--- /dev/null
+++ b/tests/codeigniter/helpers/email_helper_test.php
@@ -0,0 +1,16 @@
+<?php
+
+require_once(BASEPATH.'helpers/email_helper.php');
+
+class Email_helper_test extends CI_TestCase
+{
+	
+	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..a596a03
--- /dev/null
+++ b/tests/codeigniter/helpers/file_helper_test.php
@@ -0,0 +1,157 @@
+<?php
+
+require_once 'vfsStream/vfsStream.php';
+require BASEPATH.'helpers/file_helper.php';
+
+class File_helper_Test extends CI_TestCase
+{
+	public function set_up()
+	{
+		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/html_helper_test.php b/tests/codeigniter/helpers/html_helper_test.php
new file mode 100644
index 0000000..553fc2b
--- /dev/null
+++ b/tests/codeigniter/helpers/html_helper_test.php
@@ -0,0 +1,78 @@
+<?php
+
+require_once(BASEPATH.'helpers/html_helper.php');
+
+class Html_helper_test extends CI_TestCase
+{
+	
+	// ------------------------------------------------------------------------
+	
+	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..472e28a
--- /dev/null
+++ b/tests/codeigniter/helpers/inflector_helper_test.php
@@ -0,0 +1,93 @@
+<?php
+
+require_once(BASEPATH.'helpers/inflector_helper.php');
+
+class Inflector_helper_test extends CI_TestCase {
+	
+	
+	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..3322b24
--- /dev/null
+++ b/tests/codeigniter/helpers/number_helper_test.php
@@ -0,0 +1,78 @@
+<?php
+
+require_once BASEPATH.'helpers/number_helper.php';
+
+class Number_helper_test extends CI_TestCase
+{
+	
+	public function set_up()
+	{
+		// 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..2e6cc63
--- /dev/null
+++ b/tests/codeigniter/helpers/path_helper_test.php
@@ -0,0 +1,29 @@
+<?php
+
+require BASEPATH . 'helpers/path_helper.php';
+
+class Path_helper_test extends CI_TestCase 
+{
+	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..a884d62
--- /dev/null
+++ b/tests/codeigniter/helpers/string_helper_test.php
@@ -0,0 +1,144 @@
+<?php
+
+require_once(BASEPATH.'helpers/string_helper.php');
+
+class String_helper_test extends CI_TestCase
+{
+	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..a0866e6
--- /dev/null
+++ b/tests/codeigniter/helpers/text_helper_test.php
@@ -0,0 +1,159 @@
+<?php
+
+require_once(BASEPATH.'helpers/text_helper.php');
+
+class Text_helper_test extends CI_TestCase
+{
+	private $_long_string;
+	
+	public function set_up()
+	{
+		$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..51a8cc7
--- /dev/null
+++ b/tests/codeigniter/helpers/url_helper_test.php
@@ -0,0 +1,72 @@
+<?php
+
+require_once(BASEPATH.'helpers/url_helper.php');
+
+class Url_helper_test extends CI_TestCase
+{
+	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..49f49e1
--- /dev/null
+++ b/tests/codeigniter/helpers/xml_helper_test.php
@@ -0,0 +1,13 @@
+<?php
+
+require_once(BASEPATH.'helpers/xml_helper.php');
+
+class Xml_helper_test extends CI_TestCase
+{
+	
+	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..b4580a4
--- /dev/null
+++ b/tests/codeigniter/libraries/Parser_test.php
@@ -0,0 +1,113 @@
+<?php
+
+require BASEPATH.'libraries/Parser.php';
+
+class Parser_test extends CI_TestCase
+{
+	
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->parser = new CI_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..0208a46
--- /dev/null
+++ b/tests/codeigniter/libraries/Table_test.php
@@ -0,0 +1,344 @@
+<?php
+
+require BASEPATH.'libraries/Table.php';
+
+class Table_test extends CI_TestCase
+{
+
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->table = new CI_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')
+		);
+		
+		// test what would be discreet args,
+		// basically means a single array as the calling method
+		// will use func_get_args()
+		
+		$reflectionOfTable = new ReflectionClass($this->table);
+		$method = $reflectionOfTable->getMethod('_prep_args');
+		
+		$method->setAccessible(true);
+			
+		$this->assertEquals(
+			$expected,
+			$method->invokeArgs(
+				$this->table, array(array('name', 'color', 'size'), 'discreet')
+			)
+		);
+		
+		// test what would be a single array argument. Again, nested
+		// due to func_get_args on calling methods
+		$this->assertEquals(
+			$expected,
+			$method->invokeArgs(
+				$this->table, array(array('name', 'color', 'size'), 'array')
+			)
+		);
+		
+		
+		// with cell attributes
+		
+		// need to add that new argument row to our expected outcome
+		$expected[] = array('data' => 'weight', 'class' => 'awesome');
+
+		$this->assertEquals(
+			$expected,
+			$method->invokeArgs(
+				$this->table, array(array('name', 'color', 'size', array('data' => 'weight', 'class' => 'awesome')), 'attributes')
+			)
+		);
+	}
+	
+	public function test_default_template_keys()
+	{
+		$reflectionOfTable = new ReflectionClass($this->table);
+		$method = $reflectionOfTable->getMethod('_default_template');
+		
+		$method->setAccessible(true);
+		
+		$deft_template = $method->invoke($this->table);
+		$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, $deft_template);
+		}
+	}
+	
+	public function test_compile_template()
+	{
+		$reflectionOfTable = new ReflectionClass($this->table);
+		$method = $reflectionOfTable->getMethod('_compile_template');
+		
+		$method->setAccessible(true);
+		
+		$this->assertFalse($this->table->set_template('invalid_junk'));
+		
+		// non default key
+		$this->table->set_template(array('nonsense' => 'foo'));
+		$method->invoke($this->table);
+		
+		$this->assertArrayHasKey('nonsense', $this->table->template);
+		$this->assertEquals('foo', $this->table->template['nonsense']);
+		
+		// override default
+		$this->table->set_template(array('table_close' => '</table junk>'));
+		$method->invoke($this->table);
+		
+		$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()
+	{
+		$reflectionOfTable = new ReflectionClass($this->table);
+		$method = $reflectionOfTable->getMethod('_set_from_array');
+		
+		$method->setAccessible(true);
+				
+		$this->assertFalse($method->invokeArgs($this->table, array('bogus')));
+		$this->assertFalse($method->invoke($this->table, array()));
+		
+		$data = array(
+			array('name', 'color', 'number'),
+			array('Laura', 'Red', '22'),
+			array('Katie', 'Blue')				
+		);
+		
+		$method->invokeArgs($this->table, 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'),
+		);
+		
+		$method->invokeArgs($this->table, 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()
+	{
+		$reflectionOfTable = new ReflectionClass($this->table);
+		$method = $reflectionOfTable->getMethod('_set_from_object');
+		
+		$method->setAccessible(true);
+
+		// 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'),
+		);
+
+		$method->invokeArgs($this->table, array($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..a0533ba
--- /dev/null
+++ b/tests/codeigniter/libraries/Typography_test.php
@@ -0,0 +1,191 @@
+<?php
+
+require BASEPATH.'libraries/Typography.php';
+
+class Typography_test extends CI_TestCase
+{
+
+	public function set_up()
+	{
+		$obj = new StdClass;
+		$obj->type = new CI_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/User_agent_test.php b/tests/codeigniter/libraries/User_agent_test.php
new file mode 100644
index 0000000..6f9e871
--- /dev/null
+++ b/tests/codeigniter/libraries/User_agent_test.php
@@ -0,0 +1,91 @@
+<?php
+
+require BASEPATH.'libraries/User_agent.php';
+
+// This class needs some work...
+
+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 CI_User_agent();
+
+		$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/lib/ci_testcase.php b/tests/lib/ci_testcase.php
new file mode 100644
index 0000000..afccee0
--- /dev/null
+++ b/tests/lib/ci_testcase.php
@@ -0,0 +1,194 @@
+<?php
+
+
+// Need a way to change dependencies (core libs and laoded libs)
+// Need a way to set the CI class
+
+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',
+		// @todo the loader is an edge case
+		'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();
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	function ci_set_config($key, $val = '')
+	{
+		if (is_array($key))
+		{
+			$this->ci_config = $key;
+		}
+		else
+		{
+			$this->ci_config[$key] = $val;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	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();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	public static function instance()
+	{
+		return self::$ci_test_instance;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	function ci_get_config()
+	{
+		return $this->ci_config;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * 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/lib/common.php b/tests/lib/common.php
new file mode 100644
index 0000000..4a83258
--- /dev/null
+++ b/tests/lib/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
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
new file mode 100644
index 0000000..abb9881
--- /dev/null
+++ b/tests/phpunit.xml
@@ -0,0 +1,38 @@
+<?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">
+	<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>
+			<!-- We'll worry about these later ...
+			<directory suffix="test.php">codeigniter/libraries</directory>
+			<directory suffix="test.php">codeigniter/helpers</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 d71fc8b..881c69c 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.
@@ -42,6 +43,11 @@
    -  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.
 
 -  Database
 
@@ -65,13 +71,13 @@
    -  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.
+   -  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).
 
 -  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:`Input library <libraries/input>` (also used by :doc:`Form Validation library <libraries/form_validation>`).
-   -  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)
    -  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.
@@ -90,10 +96,14 @@
 	 -  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 `Caching Library <libraries/caching>`.
 
 -  Core
 
@@ -103,6 +113,8 @@
    -  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).
 
 Bug fixes for 3.0
 ------------------
@@ -141,7 +153,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.
@@ -154,6 +166,7 @@
 -  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 (#11, #183, #863) - CI_Form_validation::_execute() silently continued to the next rule, if a rule method/function is not found.
 
 Version 2.1.1
diff --git a/user_guide_src/source/database/active_record.rst b/user_guide_src/source/database/active_record.rst
index c04e67d..e328c11 100644
--- a/user_guide_src/source/database/active_record.rst
+++ b/user_guide_src/source/database/active_record.rst
@@ -68,7 +68,7 @@
 	// Produces string: SELECT * FROM mytable
 
 The second parameter enables you to set whether or not the active record query
-will be reset (by default it will be&mdash;just like `$this->db->get()`)::
+will be reset (by default it will be just like `$this->db->get()`)::
 
 	echo $this->db->limit(10,20)->get_compiled_select('mytable', FALSE);
 	// Produces string: SELECT * FROM mytable LIMIT 20, 10
@@ -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/general/requirements.rst b/user_guide_src/source/general/requirements.rst
index 3862355..05e8796 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, CUBRID, Interbase, ODBC and PDO.
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/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/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 438e4c1..e819a9d 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -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
 ===========================
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