Merge branch 'develop' of github.com:/EllisLab/CodeIgniter into load_config_units
diff --git a/application/config/database.php b/application/config/database.php
index 4c5cad0..3234026 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -43,7 +43,7 @@
 |	['password'] The password used to connect to the database
 |	['database'] The name of the database you want to connect to
 |	['dbdriver'] The database driver. e.g.: mysqli.
-			Currently supported:
+|			Currently supported:
 |				 cubrid, ibase, mssql, mysql, mysqli, oci8,
 |				 odbc, pdo, postgre, sqlite, sqlite3, sqlsrv
 |	['dbprefix'] You can add an optional prefix, which will be added
@@ -63,7 +63,8 @@
 | 				 Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
 |	['swap_pre'] A default table prefix that should be swapped with the dbprefix
 |	['autoinit'] Whether or not to automatically initialize the database.
-|	['compress'] Whether or not to use client compression (only MySQL and MySQLi)
+|	['encrypt']  Whether or not to use an encrypted connection.
+|	['compress'] Whether or not to use client compression (MySQL only)
 |	['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
 |							- good for ensuring strict SQL while developing
 |	['failover'] array - A array with 0 or more data for connections if the main should fail.
@@ -72,7 +73,7 @@
 | make active.  By default there is only one group (the 'default' group).
 |
 | The $query_builder variables lets you determine whether or not to load
-| the query builder class
+| the query builder class.
 */
 
 $active_group = 'default';
@@ -94,7 +95,8 @@
 	'dbcollat' => 'utf8_general_ci',
 	'swap_pre' => '',
 	'autoinit' => TRUE,
-	'compress' => TRUE,
+	'encrypt' => FALSE,
+	'compress' => FALSE,
 	'stricton' => FALSE,
 	'failover' => array()
 );
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 8159b19..f3592ea 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -50,7 +50,7 @@
  *  Load the global functions
  * ------------------------------------------------------
  */
-	require(BASEPATH.'core/Common.php');
+	require_once(BASEPATH.'core/Common.php');
 
 /*
  * ------------------------------------------------------
diff --git a/system/core/Common.php b/system/core/Common.php
index 981af45..341402c 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -150,7 +150,7 @@
 
 				if (class_exists($name) === FALSE)
 				{
-					require($path.$directory.'/'.$class.'.php');
+					require_once($path.$directory.'/'.$class.'.php');
 				}
 
 				break;
@@ -164,7 +164,7 @@
 
 			if (class_exists($name) === FALSE)
 			{
-				require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
+				require_once(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
 			}
 		}
 
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 0a7ec50..1ff0298 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -49,30 +49,31 @@
 	{
 		log_message('debug', 'Utf8 Class Initialized');
 
-		global $CFG;
+		$charset = strtoupper(config_item('charset'));
+
+		// set internal encoding for multibyte string functions if necessary
+		// and set a flag so we don't have to repeatedly use extension_loaded()
+		// or function_exists()
+		if (extension_loaded('mbstring'))
+		{
+			define('MB_ENABLED', TRUE);
+			mb_internal_encoding($charset);
+		}
+		else
+		{
+			define('MB_ENABLED', FALSE);
+		}
+
 
 		if (
-			@preg_match('/./u', 'é') === 1		// PCRE must support UTF-8
-			&& function_exists('iconv')			// iconv must be installed
-			&& (bool) @ini_get('mbstring.func_overload') !== TRUE	// Multibyte string function overloading cannot be enabled
-			&& $CFG->item('charset') === 'UTF-8'		// Application charset must be UTF-8
+			@preg_match('/./u', 'é') === 1	// PCRE must support UTF-8
+			&& function_exists('iconv')	// iconv must be installed
+			&& MB_ENABLED === TRUE		// mbstring must be enabled
+			&& $charset === 'UTF-8'		// Application charset must be UTF-8
 			)
 		{
 			define('UTF8_ENABLED', TRUE);
 			log_message('debug', 'UTF-8 Support Enabled');
-
-			// set internal encoding for multibyte string functions if necessary
-			// and set a flag so we don't have to repeatedly use extension_loaded()
-			// or function_exists()
-			if (extension_loaded('mbstring'))
-			{
-				define('MB_ENABLED', TRUE);
-				mb_internal_encoding('UTF-8');
-			}
-			else
-			{
-				define('MB_ENABLED', FALSE);
-			}
 		}
 		else
 		{
@@ -135,7 +136,7 @@
 		{
 			return @iconv($encoding, 'UTF-8', $str);
 		}
-		elseif (function_exists('mb_convert_encoding'))
+		elseif (MB_ENABLED === TRUE)
 		{
 			return @mb_convert_encoding($str, 'UTF-8', $encoding);
 		}
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index ea2a53e..fef388b 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -51,7 +51,7 @@
 	public $char_set		= 'utf8';
 	public $dbcollat		= 'utf8_general_ci';
 	public $autoinit		= TRUE; // Whether to automatically initialize the DB
-	public $compress		= TRUE;
+	public $encrypt			= FALSE;
 	public $swap_pre		= '';
 	public $port			= '';
 	public $pconnect		= FALSE;
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index a62ea94..a5ace02 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -465,7 +465,7 @@
 			$orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
 
 			// We have to strip the ORDER BY clause
-			$sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+			$sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
 
 			return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
 				.preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 7262591..99bf559 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -41,6 +41,7 @@
 class CI_DB_mysql_driver extends CI_DB {
 
 	public $dbdriver = 'mysql';
+	public $compress = FALSE;
 
 	// The character used for escaping
 	protected $_escape_char = '`';
@@ -75,18 +76,21 @@
 	/**
 	 * Non-persistent database connection
 	 *
+	 * @param	bool
 	 * @return	resource
 	 */
-	public function db_connect()
+	public function db_connect($persistent = FALSE)
 	{
-		if ($this->compress === TRUE)
+		$client_flags = ($this->compress === FALSE) ? 0 : MYSQL_CLIENT_COMPRESS;
+
+		if ($this->encrypt === TRUE)
 		{
-			return @mysql_connect($this->hostname, $this->username, $this->password, TRUE, MYSQL_CLIENT_COMPRESS);
+			$client_flags = $client_flags | MYSQL_CLIENT_SSL;
 		}
-		else
-		{
-			return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);
-		}
+
+		return ($persistent === TRUE)
+			? @mysql_pconnect($this->hostname, $this->username, $this->password, $client_flags)
+			: @mysql_connect($this->hostname, $this->username, $this->password, TRUE, $client_flags);
 	}
 
 	// --------------------------------------------------------------------
@@ -98,14 +102,7 @@
 	 */
 	public function db_pconnect()
 	{
-		if ($this->compress === TRUE)
-		{
-			return @mysql_pconnect($this->hostname, $this->username, $this->password, MYSQL_CLIENT_COMPRESS);
-		}
-		else
-		{
-			return @mysql_pconnect($this->hostname, $this->username, $this->password);
-		}
+		return $this->db_connect(TRUE);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index b5a1e26..f77176c 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -41,6 +41,7 @@
 class CI_DB_mysqli_driver extends CI_DB {
 
 	public $dbdriver = 'mysqli';
+	public $compress = FALSE;
 
 	// The character used for escaping
 	protected $_escape_char = '`';
@@ -57,24 +58,21 @@
 	/**
 	 * Non-persistent database connection
 	 *
+	 * @param	bool
 	 * @return	object
+	 * @todo	SSL support
 	 */
-	public function db_connect()
+	public function db_connect($persistent = FALSE)
 	{
-		// Use MySQL client compression?
-		if ($this->compress === TRUE)
-		{
-			$port = empty($this->port) ? NULL : $this->port;
+		// Persistent connection support was added in PHP 5.3.0
+		$hostname = ($persistent === TRUE && is_php('5.3'))
+			? 'p:'.$this->hostname : $this->hostname;
+		$port = empty($this->port) ? NULL : $this->port;
+		$client_flags = ($this->compress === TRUE) ? MYSQLI_CLIENT_COMPRESS : 0;
+		$mysqli = new mysqli();
 
-			$mysqli = new mysqli();
-			@$mysqli->real_connect($this->hostname, $this->username, $this->password, $this->database, $port, NULL, MYSQLI_CLIENT_COMPRESS);
-
-			return $mysqli;
-		}
-
-		return empty($this->port)
-			? @new mysqli($this->hostname, $this->username, $this->password, $this->database)
-			: @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port);
+		return @$mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, NULL, $client_flags)
+			? $mysqli : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -86,26 +84,7 @@
 	 */
 	public function db_pconnect()
 	{
-		// Persistent connection support was added in PHP 5.3.0
-		if ( ! is_php('5.3'))
-		{
-			return $this->db_connect();
-		}
-
-		// Use MySQL client compression?
-		if ($this->compress === TRUE)
-		{
-			$port = empty($this->port) ? NULL : $this->port;
-
-			$mysqli = mysqli_init();
-			$mysqli->real_connect('p:'.$this->hostname, $this->username, $this->password, $this->database, $port, NULL, MYSQLI_CLIENT_COMPRESS);
-
-			return $mysqli;
-		}
-
-		return empty($this->port)
-			? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database)
-			: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port);
+		return $this->db_connect(TRUE);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
index 2346e68..7c4b008 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
@@ -232,7 +232,7 @@
 			$orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
 
 			// We have to strip the ORDER BY clause
-			$sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+			$sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
 
 			return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
 				.preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
diff --git a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
index 4244688..a543117 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_mysql_driver.php
@@ -41,6 +41,7 @@
 class CI_DB_pdo_mysql_driver extends CI_DB_pdo_driver {
 
 	public $subdriver = 'mysql';
+	public $compress = FALSE;
 
 	protected $_escape_char = '`';
 
@@ -79,6 +80,7 @@
 	 *
 	 * @param	bool
 	 * @return	object
+	 * @todo	SSL support
 	 */
 	public function db_connect($persistent = FALSE)
 	{
@@ -93,6 +95,11 @@
 				.(empty($this->dbcollat) ? '' : ' COLLATE '.$this->dbcollat);
 		}
 
+		if ($this->compress === TRUE)
+		{
+			$this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE;
+		}
+
 		return parent::db_connect($persistent);
 	}
 
diff --git a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
index ee7c1d1..3154fdd 100644
--- a/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
+++ b/system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
@@ -78,9 +78,9 @@
 				$this->dsn .= ';ConnectionPooling='.$this->ConnectionPooling;
 			}
 
-			if (isset($this->Encrypt))
+			if ($this->encrypt === TRUE)
 			{
-				$this->dsn .= ';Encrypt='.$this->Encrypt;
+				$this->dsn .= ';Encrypt=1';
 			}
 
 			if (isset($this->TraceOn))
@@ -266,7 +266,7 @@
 			$orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
 
 			// We have to strip the ORDER BY clause
-			$sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+			$sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
 
 			return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
 				.preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index a6739d1..be321ff 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -57,15 +57,16 @@
 	 */
 	public function db_connect($pooling = FALSE)
 	{
-		// Check for a UTF-8 charset being passed as CI's default 'utf8'.
-		$character_set = (0 === strcasecmp('utf8', $this->char_set)) ? 'UTF-8' : $this->char_set;
+		$charset = in_array(strtolower($this->char_set), array('utf-8', 'utf8'), TRUE)
+			? 'UTF-8' : SQLSRV_ENC_CHAR;
 
 		$connection = array(
 			'UID'			=> empty($this->username) ? '' : $this->username,
 			'PWD'			=> empty($this->password) ? '' : $this->password,
 			'Database'		=> $this->database,
-			'ConnectionPooling'	=> $pooling ? 1 : 0,
-			'CharacterSet'		=> $character_set,
+			'ConnectionPooling'	=> ($pooling === TRUE) ? 1 : 0,
+			'CharacterSet'		=> $charset,
+			'Encrypt'		=> ($this->encrypt === TRUE) ? 1 : 0,
 			'ReturnDatesAsStrings'	=> 1
 		);
 
@@ -460,7 +461,7 @@
 			$orderby = 'ORDER BY '.implode(', ', $this->qb_orderby);
 
 			// We have to strip the ORDER BY clause
-			$sql = trim(substr($sql, 0, strrpos($sql, 'ORDER BY '.$orderby)));
+			$sql = trim(substr($sql, 0, strrpos($sql, $orderby)));
 
 			return 'SELECT '.(count($this->qb_select) === 0 ? '*' : implode(', ', $this->qb_select))." FROM (\n"
 				.preg_replace('/^(SELECT( DISTINCT)?)/i', '\\1 ROW_NUMBER() OVER('.$orderby.') AS '.$this->escape_identifiers('CI_rownum').', ', $sql)
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 955d745..51b2b76 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -669,7 +669,7 @@
 	 * @param	int	unix_start	UNIX timestamp of period start date
 	 * @param	int	unix_end|days	UNIX timestamp of period end date
 	 *					or interval in days.
-	 * @param	mixed	is_unix		Specifies wether the second parameter
+	 * @param	mixed	is_unix		Specifies whether the second parameter
 	 *					is a UNIX timestamp or a day interval
 	 *					 - TRUE or 'unix' for a timestamp
 	 *					 - FALSE or 'days' for an interval
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index cf1b3b5..6ff0cc2 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -42,6 +42,7 @@
 $lang['integer']				= 'The %s field must contain an integer.';
 $lang['regex_match']			= 'The %s field is not in the correct format.';
 $lang['matches']				= 'The %s field does not match the %s field.';
+$lang['differs']        		= 'The %s field must differ from the %s field.';
 $lang['is_unique'] 				= 'The %s field must contain a unique value.';
 $lang['is_natural']				= 'The %s field must only contain digits.';
 $lang['is_natural_no_zero']		= 'The %s field must only contain digits and must be greater than zero.';
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 1b457ae..fa1d5e9 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -98,6 +98,8 @@
 	 */
 	public function __construct($config = array())
 	{
+		$this->charset = strtoupper(config_item('charset'));
+
 		if (count($config) > 0)
 		{
 			$this->initialize($config);
@@ -1107,9 +1109,16 @@
 		// However, many developers choose to override that and violate
 		// the RFC rules due to (apparently) a bug in MS Exchange,
 		// which only works with "\n".
-		if ($this->crlf === "\r\n" && is_php('5.3'))
+		if ($this->crlf === "\r\n")
 		{
-			return quoted_printable_encode($str);
+			if (is_php('5.3'))
+			{
+				return quoted_printable_encode($str);
+			}
+			elseif (function_exists('imap_8bit'))
+			{
+				return imap_8bit($str);
+			}
 		}
 
 		// Reduce multiple spaces & remove nulls
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 6796092..73ab8ca 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -165,7 +165,7 @@
 	 */
 	public function decode($string, $key = '')
 	{
-		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
+		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string) OR base64_encode(base64_decode($string)) !== $string)
 		{
 			return FALSE;
 		}
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index b490a34..91f46b6 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -134,12 +134,6 @@
 		// Automatically load the form helper
 		$this->CI->load->helper('form');
 
-		// Set the character encoding in MB.
-		if (MB_ENABLED === TRUE)
-		{
-			mb_internal_encoding($this->CI->config->item('charset'));
-		}
-
 		log_message('debug', 'Form Validation Class Initialized');
 	}
 
@@ -977,6 +971,20 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Differs from another field
+	 *
+	 * @param	string
+	 * @param	string	field
+	 * @return	bool
+	 */
+	public function differs($str, $field)
+	{
+		return ! (isset($this->_field_data[$field]) && $this->_field_data[$field]['postdata'] === $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Is Unique
 	 *
 	 * Check if the input value doesn't already exist
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index ba2036d..145853a 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -87,65 +87,66 @@
 
    -  :doc:`Query Builder <database/query_builder>` changes include:
 	 - Renamed the Active Record class to Query Builder to remove confusion with the Active Record design pattern.
-	 - Added the ability to insert objects with insert_batch().
-	 - Added new methods that return the SQL string of queries without executing them: get_compiled_select(), get_compiled_insert(), get_compiled_update(), get_compiled_delete().
-	 - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods join(), order_by(), where_in(), or_where_in(), where_not_in(), or_where_not_in().
-	 - Added support for join() with multiple conditions.
-	 - Added support for USING in join().
-	 - Changed limit() to ignore NULL values instead of always casting to integer.
-	 - Changed offset() to ignore empty values instead of always casting to integer.
+	 - Added the ability to insert objects with ``insert_batch()``.
+	 - Added new methods that return the SQL string of queries without executing them: ``get_compiled_select()``, ``get_compiled_insert()``, ``get_compiled_update()``, ``get_compiled_delete()``.
+	 - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods ``join()``, ``order_by()``, ``where_in()``, ``or_where_in()``, ``where_not_in()``, ``or_where_not_in()``.
+	 - Added support for ``join()`` with multiple conditions.
+	 - Added support for *USING* in ``join()``.
+	 - Changed ``limit()`` to ignore NULL values instead of always casting to integer.
+	 - Changed ``offset()`` to ignore empty values instead of always casting to integer.
    -  Improved support for the MySQLi driver, including:
 	 - OOP style of the PHP extension is now used, instead of the procedural aliases.
 	 - Server version checking is now done via ``mysqli::$server_info`` instead of running an SQL query.
 	 - Added persistent connections support for PHP >= 5.3.
-	 - Added support for backup() in :doc:`Database Utilities <database/utilities>`.
-   -  Added 'dsn' configuration setting for drivers that support DSN strings (PDO, PostgreSQL, Oracle, ODBC, CUBRID).
+	 - Added support for ``backup()`` in :doc:`Database Utilities <database/utilities>`.
+   -  Added *dsn* configuration setting for drivers that support DSN strings (PDO, PostgreSQL, Oracle, ODBC, CUBRID).
    -  Improved PDO database support.
-   -  Added Interbase/Firebird database support via the 'ibase' driver.
-   -  Added an optional database name parameter to db_select().
-   -  Replaced the _error_message() and _error_number() methods with error(), that returns an array containing the last database error code and message.
-   -  Improved version() implementation so that drivers that have a native function to get the version number don't have to be defined in the core DB_driver class.
+   -  Added Interbase/Firebird database support via the *ibase* driver.
+   -  Added an optional database name parameter to ``db_select()``.
+   -  Replaced the ``_error_message()`` and ``_error_number()`` methods with ``error()``, which returns an array containing the last database error code and message.
+   -  Improved ``version()`` implementation so that drivers that have a native function to get the version number don't have to be defined in the core ``DB_driver`` class.
    -  Improved support of the PostgreSQL driver, including:
 	 - ``pg_version()`` is now used to get the database version number, when possible.
 	 - Added ``db_set_charset()`` support.
 	 - Added support for ``optimize_table()`` in :doc:`Database Utilities <database/utilities>` (rebuilds table indexes).
 	 - Added boolean data type support in ``escape()``.
 	 - Added ``update_batch()`` support.
-	 - Removed ``limit()`` and ``order_by()`` support for UPDATE and DELETE queries as PostgreSQL does not support those features.
+	 - Removed ``limit()`` and ``order_by()`` support for *UPDATE* and *DELETE* queries as PostgreSQL does not support those features.
 	 - Added a work-around for dead persistent connections to be re-created after a database restart.
-   -  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 protect_identifiers() and renamed internal method _protect_identifiers() to it instead - it was just an alias.
-   -  Renamed internal method _escape_identifiers() to escape_identifiers().
-   -  Updated escape_identifiers() to accept an array of fields as well as strings.
+   -  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 ``protect_identifiers()`` and renamed internal method ``_protect_identifiers()`` to it instead - it was just an alias.
+   -  Renamed internal method ``_escape_identifiers()`` to ``escape_identifiers()``.
+   -  Updated ``escape_identifiers()`` to accept an array of fields as well as strings.
    -  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).
+   -  ``db_set_charset()`` now only requires one parameter (collation was only needed due to legacy support for MySQL versions prior to 5.1).
    -  Added support for SQLite3 database driver.
    -  Improved support of the CUBRID driver, including:
 	 - Added DSN string support.
 	 - Added persistent connections support.
-	 - Improved list_databases() in :doc:`Database Utility <database/utilities>` (until now only the currently used database was returned).
+	 - Improved ``list_databases()`` in :doc:`Database Utility <database/utilities>` (until now only the currently used database was returned).
    -  Improved support of the MSSQL and SQLSRV drivers, including:
 	 - Added random ordering support.
-	 - Added support for optimize_table() in :doc:`Database Utility <database/utilities>`.
-	 - Added escaping with QUOTE_IDENTIFIER setting detection.
+	 - Added support for ``optimize_table()`` in :doc:`Database Utility <database/utilities>`.
+	 - Added escaping with *QUOTE_IDENTIFIER* setting detection.
 	 - Added port handling support for UNIX-based systems (MSSQL driver).
-	 - Added OFFSET support for SQL Server 2005 and above.
+	 - Added *OFFSET* support for SQL Server 2005 and above.
    -  Improved support of the Oracle (OCI8) driver, including:
 	 - Added DSN string support (Easy Connect and TNS).
-	 - Added support for drop_table() in :doc:`Database Forge <database/forge>`.
-	 - Added support for list_databases() in :doc:`Database Utilities <database/utilities>`.
+	 - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+	 - Added support for ``list_databases()`` in :doc:`Database Utilities <database/utilities>`.
 	 - Generally improved for speed and cleaned up all of its components.
-	 - num_rows() is now only called explicitly by the developer and no longer re-executes statements.
+	 - ``num_rows()`` is now only called explicitly by the developer and no longer re-executes statements.
    -  Improved support of the SQLite driver, including:
-	 - Added support for replace() in :doc:`Query Builder <database/query_builder>`.
-	 - Added support for drop_table() in :doc:`Database Forge <database/forge>`.
-   -  Added ODBC support for create_database(), drop_database() and drop_table() in :doc:`Database Forge <database/forge>`.
-   -  Added PDO support for create_database(), drop_database and drop_table() in :doc:`Database Forge <database/forge>`.
-   -  Added unbuffered_row() method for getting a row without prefetching whole result (consume less memory).
+	 - Added support for ``replace()`` in :doc:`Query Builder <database/query_builder>`.
+	 - Added support for ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+   -  Added ODBC support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+   -  Added PDO support for ``create_database()``, ``drop_database()`` and ``drop_table()`` in :doc:`Database Forge <database/forge>`.
+   -  Added ``unbuffered_row()`` method for getting a row without prefetching whole result (consume less memory).
    -  Added PDO support for ``list_fields()`` in :doc:`Database Results <database/results>`.
-   -  Added capability for packages to hold database.php config files
+   -  Added capability for packages to hold *database.php* config files
    -  Added subdrivers support (currently only used by PDO).
-   -  Added client compression support for MySQL and MySQLi.
+   -  Added MySQL client compression support.
+   -  Added encrypted connections support (for *mysql*, *sqlsrv* and PDO with *sqlsrv*).
    -  Removed :doc:`Loader Class <libraries/loader>` from Database error tracing to better find the likely culprit.
 
 -  Libraries
@@ -179,15 +180,16 @@
 	 -  Property *maintain_ratio* is now taken into account when resizing images using ImageMagick library.
 	 -  Added support for maintaining transparency for PNG images in method ``text_watermark()``.
    -  :doc:`Form Validation library <libraries/form_validation>` changes include:
-	 -  Added method error_array() to return all error messages as an array.
-	 -  Added method set_data() to set an alternative data array to be validated instead of the default $_POST.
-	 -  Added method reset_validation(), which resets internal validation variables in case of multiple validation routines.
-	 -  Added support for setting error delimiters in the config file via $config['error_prefix'] and $config['error_suffix'].
-	 -  _execute() now considers input data to be invalid if a specified rule is not found.
-	 -  Removed method is_numeric() as it exists as a native PHP function and _execute() will find and use that (the 'is_numeric' rule itself is deprecated since 1.6.1).
+	 -  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.
-	 -  Updated set_rules() to accept an array of rules as well as a string.
+	 -  Updated ``set_rules()`` to accept an array of rules as well as a string.
 	 -  Fields that have empty rules set no longer run through validation (and therefore are not considered erroneous).
+	 -  Added rule *differs* to check if the value of a field differs from the value of another field.
    -  Added support for setting :doc:`Table <libraries/table>` class defaults in a config file.
    -  Added a Wincache driver to the :doc:`Caching Library <libraries/caching>`.
    -  Added a Redis driver to the :doc:`Caching Library <libraries/caching>`.
@@ -199,7 +201,8 @@
 	 -  Successfully sent emails will automatically clear the parameters.
 	 -  Added a *return_path* parameter to the ``from()`` method.
 	 -  Removed the second parameter (character limit) from internal method ``_prep_quoted_printable()`` as it is never used.
-	 -  Internal method ``_prep_quoted_printable()`` will now utilize the native ``quoted_printable_encode()`` function on PHP 5.3+ if CRLF is set to "\r\n".
+	 -  Internal method ``_prep_quoted_printable()`` will now utilize the native ``quoted_printable_encode()``, ``imap_8bit()`` functions (if available) when CRLF is set to "\r\n".
+	 -  Default charset now relies on the global ``$config['charset']`` setting.
    -  :doc:`Pagination Library <libraries/pagination>` changes include:
 	 -  Added support for the anchor "rel" attribute.
 	 -  Added support for setting custom attributes.
@@ -335,8 +338,8 @@
 -  Fixed a bug (#520) - :doc:`Date Helper <helpers/date_helper>` function nice_date() failed when the optional second parameter is not passed.
 -  Fixed a bug (#167) - ``$config['permitted_uri_chars']`` didn't affect URL-encoded characters.
 -  Fixed a bug (#318) - :doc:`Profiling <general/profiling>` setting *query_toggle_count* was not settable as described in the manual.
--  Fixed a bug (#938) - :doc:`Config Library <libraries/config>` method site_url() added a question mark to the URL string when query strings are enabled even if it already existed.
--  Fixed a bug (#999) - :doc:`Config Library <libraries/config>` method site_url() always appended ``$config['url_suffix']`` to the end of the URL string, regardless of wether a query string exists in it.
+-  Fixed a bug (#938) - :doc:`Config Library <libraries/config>` method ``site_url()`` added a question mark to the URL string when query strings are enabled even if it already existed.
+-  Fixed a bug (#999) - :doc:`Config Library <libraries/config>` method ``site_url()`` always appended ``$config['url_suffix']`` to the end of the URL string, regardless of whether a query string exists in it.
 -  Fixed a bug where :doc:`URL Helper <helpers/url_helper>` function anchor_popup() ignored the attributes argument if it is not an array.
 -  Fixed a bug (#1328) - :doc:`Form Validation Library <libraries/form_validation>` didn't properly check the type of the form fields before processing them.
 -  Fixed a bug (#79) - :doc:`Form Validation Library <libraries/form_validation>` didn't properly validate array fields that use associative keys or have custom indexes.
@@ -357,6 +360,7 @@
 -  Fixed a bug (#1765) - :doc:`Database Library <database/index>` didn't properly detect connection errors for MySQLi.
 -  Fixed a bug (#1257) - :doc:`Query Builder <database/query_builder>` used to (unnecessarily) group FROM clause contents, which breaks certain queries and is invalid for some databases.
 -  Fixed a bug (#1709) - :doc:`Email <libraries/email>` headers were broken when using long email subjects and \r\n as CRLF.
+-  Fixed a bug where MB_ENABLED was only declared if UTF8_ENABLED was set to TRUE.
 
 Version 2.1.3
 =============
diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst
index 636b5b5..6684963 100644
--- a/user_guide_src/source/database/configuration.rst
+++ b/user_guide_src/source/database/configuration.rst
@@ -28,7 +28,8 @@
 		'dbcollat' => 'utf8_general_ci',
 		'swap_pre' => '',
 		'autoinit' => TRUE,
-		'compress' => TRUE,
+		'encrypt' => FALSE,
+		'compress' => FALSE,
 		'stricton' => FALSE,
 		'failover' => array()
 	);
@@ -70,7 +71,8 @@
 				'dbcollat' => 'utf8_general_ci',
 				'swap_pre' => '',
 				'autoinit' => TRUE,
-				'compress' => TRUE,
+				'encrypt' => FALSE,
+				'compress' => FALSE,
 				'stricton' => FALSE
 			),
 			array(
@@ -88,7 +90,8 @@
 				'dbcollat' => 'utf8_general_ci',
 				'swap_pre' => '',
 				'autoinit' => TRUE,
-				'compress' => TRUE,
+				'encrypt' => FALSE,
+				'compress' => FALSE,
 				'stricton' => FALSE
 			)
 		);
@@ -118,7 +121,8 @@
 		'dbcollat' => 'utf8_general_ci',
 		'swap_pre' => '',
 		'autoinit' => TRUE,
-		'compress' => TRUE,
+		'compress' => FALSE,
+		'encrypt' => FALSE,
 		'stricton' => FALSE,
 		'failover' => array()
 	);
@@ -178,7 +182,8 @@
 			customizable by the end user.
 **autoinit**		Whether or not to automatically connect to the database when the library loads. If set to false,
 			the connection will take place prior to executing the first query.
-**compress**		Whether or not to use client compression for MySQL or MySQLi.
+**encrypt**		Whether or not to use an encrypted connection.
+**compress**		Whether or not to use client compression (MySQL only).
 **stricton**		TRUE/FALSE (boolean) - Whether to force "Strict Mode" connections, good for ensuring strict SQL
 			while developing an application.
 **port**		The database port number. To use this value you have to add a line to the database config array.
diff --git a/user_guide_src/source/general/autoloader.rst b/user_guide_src/source/general/autoloader.rst
index 259a498..8ecc13c 100644
--- a/user_guide_src/source/general/autoloader.rst
+++ b/user_guide_src/source/general/autoloader.rst
@@ -9,7 +9,7 @@
 
 The following items can be loaded automatically:
 
--  Core classes found in the "libraries" folder
+-  Classes found in the "libraries" folder
 -  Helper files found in the "helpers" folder
 -  Custom config files found in the "config" folder
 -  Language files found in the "system/language" folder
diff --git a/user_guide_src/source/libraries/email.rst b/user_guide_src/source/libraries/email.rst
index e7ed9f7..da3bf26 100644
--- a/user_guide_src/source/libraries/email.rst
+++ b/user_guide_src/source/libraries/email.rst
@@ -97,7 +97,7 @@
 **mailtype**        text                   text or html                 Type of mail. If you send HTML email you must send it as a complete web
                                                                         page. Make sure you don't have any relative links or relative image
                                                                         paths otherwise they will not work.
-**charset**         utf-8                                               Character set (utf-8, iso-8859-1, etc.).
+**charset**         ``$config['charset']``                              Character set (utf-8, iso-8859-1, etc.).
 **validate**        FALSE                  TRUE or FALSE (boolean)      Whether to validate the email address.
 **priority**        3                      1, 2, 3, 4, 5                Email Priority. 1 = highest. 5 = lowest. 3 = normal.
 **crlf**            \\n                    "\\r\\n" or "\\n" or "\\r"   Newline character. (Use "\\r\\n" to comply with RFC 822).
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index 22272dc..6c6743d 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -872,6 +872,7 @@
 ========================= ========== ============================================================================================= =======================
 **required**              No         Returns FALSE if the form element is empty.                                                                          
 **matches**               Yes        Returns FALSE if the form element does not match the one in the parameter.                    matches[form_item]     
+**differs**               Yes        Returns FALSE if the form element does not differ from the one in the parameter.              differs[form_item]     
 **is_unique**             Yes        Returns FALSE if the form element is not unique to the table and field name in the            is_unique[table.field] 
                                      parameter. Note: This rule requires :doc:`Query Builder <../database/query_builder>` to be                             
                                      enabled in order to work.