Changing EOL style to LF
diff --git a/system/application/config/autoload.php b/system/application/config/autoload.php
index 8e896d0..1745d5c 100644
--- a/system/application/config/autoload.php
+++ b/system/application/config/autoload.php
@@ -1,116 +1,116 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------

-| AUTO-LOADER

-| -------------------------------------------------------------------

-| This file specifies which systems should be loaded by default.

-|

-| In order to keep the framework as light-weight as possible only the

-| absolute minimal resources are loaded by default. For example,

-| the database is not connected to automatically since no assumption

-| is made regarding whether you intend to use it.  This file lets

-| you globally define which systems you would like loaded with every

-| request.

-|

-| -------------------------------------------------------------------

-| Instructions

-| -------------------------------------------------------------------

-|

-| These are the things you can load automatically:

-|

-| 1. Libraries

-| 2. Helper files

-| 3. Plugins

-| 4. Custom config files

-| 5. Language files

-| 6. Models

-|

-*/

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Libraries

-| -------------------------------------------------------------------

-| These are the classes located in the system/libraries folder

-| or in your system/application/libraries folder.

-|

-| Prototype:

-|

-|	$autoload['libraries'] = array('database', 'session', 'xmlrpc');

-*/

-

-$autoload['libraries'] = array();

-

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Helper Files

-| -------------------------------------------------------------------

-| Prototype:

-|

-|	$autoload['helper'] = array('url', 'file');

-*/

-

-$autoload['helper'] = array();

-

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Plugins

-| -------------------------------------------------------------------

-| Prototype:

-|

-|	$autoload['plugin'] = array('captcha', 'js_calendar');

-*/

-

-$autoload['plugin'] = array();

-

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Config files

-| -------------------------------------------------------------------

-| Prototype:

-|

-|	$autoload['config'] = array('config1', 'config2');

-|

-| NOTE: This item is intended for use ONLY if you have created custom

-| config files.  Otherwise, leave it blank.

-|

-*/

-

-$autoload['config'] = array();

-

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Language files

-| -------------------------------------------------------------------

-| Prototype:

-|

-|	$autoload['language'] = array('lang1', 'lang2');

-|

-| NOTE: Do not include the "_lang" part of your file.  For example 

-| "codeigniter_lang.php" would be referenced as array('codeigniter');

-|

-*/

-

-$autoload['language'] = array();

-

-

-/*

-| -------------------------------------------------------------------

-|  Auto-load Models

-| -------------------------------------------------------------------

-| Prototype:

-|

-|	$autoload['model'] = array('model1', 'model2');

-|

-*/

-

-$autoload['model'] = array();

-

-

-

-/* End of file autoload.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| AUTO-LOADER
+| -------------------------------------------------------------------
+| This file specifies which systems should be loaded by default.
+|
+| In order to keep the framework as light-weight as possible only the
+| absolute minimal resources are loaded by default. For example,
+| the database is not connected to automatically since no assumption
+| is made regarding whether you intend to use it.  This file lets
+| you globally define which systems you would like loaded with every
+| request.
+|
+| -------------------------------------------------------------------
+| Instructions
+| -------------------------------------------------------------------
+|
+| These are the things you can load automatically:
+|
+| 1. Libraries
+| 2. Helper files
+| 3. Plugins
+| 4. Custom config files
+| 5. Language files
+| 6. Models
+|
+*/
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Libraries
+| -------------------------------------------------------------------
+| These are the classes located in the system/libraries folder
+| or in your system/application/libraries folder.
+|
+| Prototype:
+|
+|	$autoload['libraries'] = array('database', 'session', 'xmlrpc');
+*/
+
+$autoload['libraries'] = array();
+
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Helper Files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['helper'] = array('url', 'file');
+*/
+
+$autoload['helper'] = array();
+
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Plugins
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['plugin'] = array('captcha', 'js_calendar');
+*/
+
+$autoload['plugin'] = array();
+
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Config files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['config'] = array('config1', 'config2');
+|
+| NOTE: This item is intended for use ONLY if you have created custom
+| config files.  Otherwise, leave it blank.
+|
+*/
+
+$autoload['config'] = array();
+
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Language files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['language'] = array('lang1', 'lang2');
+|
+| NOTE: Do not include the "_lang" part of your file.  For example 
+| "codeigniter_lang.php" would be referenced as array('codeigniter');
+|
+*/
+
+$autoload['language'] = array();
+
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Models
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['model'] = array('model1', 'model2');
+|
+*/
+
+$autoload['model'] = array();
+
+
+
+/* End of file autoload.php */
 /* Location: ./system/application/config/autoload.php */
\ No newline at end of file
diff --git a/system/application/config/config.php b/system/application/config/config.php
index 13a4f7d..58309d8 100644
--- a/system/application/config/config.php
+++ b/system/application/config/config.php
@@ -1,316 +1,316 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-

-/*

-|--------------------------------------------------------------------------

-| Base Site URL

-|--------------------------------------------------------------------------

-|

-| URL to your CodeIgniter root. Typically this will be your base URL,

-| WITH a trailing slash:

-|

-|	http://example.com/

-|

-*/

-$config['base_url']	= "http://your-site.com/";

-

-/*

-|--------------------------------------------------------------------------

-| Index File

-|--------------------------------------------------------------------------

-|

-| Typically this will be your index.php file, unless you've renamed it to

-| something else. If you are using mod_rewrite to remove the page set this

-| variable so that it is blank.

-|

-*/

-$config['index_page'] = "index.php";

-

-/*

-|--------------------------------------------------------------------------

-| URI PROTOCOL

-|--------------------------------------------------------------------------

-|

-| This item determines which server global should be used to retrieve the

-| URI string.  The default setting of "AUTO" works for most servers.

-| If your links do not seem to work, try one of the other delicious flavors:

-|

-| 'AUTO'			Default - auto detects

-| 'PATH_INFO'		Uses the PATH_INFO

-| 'QUERY_STRING'	Uses the QUERY_STRING

-| 'REQUEST_URI'		Uses the REQUEST_URI

-| 'ORIG_PATH_INFO'	Uses the ORIG_PATH_INFO

-|

-*/

-$config['uri_protocol']	= "AUTO";

-

-/*

-|--------------------------------------------------------------------------

-| URL suffix

-|--------------------------------------------------------------------------

-|

-| This option allows you to add a suffix to all URLs generated by CodeIgniter.

-| For more information please see the user guide:

-|

-| http://codeigniter.com/user_guide/general/urls.html

-*/

-

-$config['url_suffix'] = "";

-

-/*

-|--------------------------------------------------------------------------

-| Default Language

-|--------------------------------------------------------------------------

-|

-| This determines which set of language files should be used. Make sure

-| there is an available translation if you intend to use something other

-| than english.

-|

-*/

-$config['language']	= "english";

-

-/*

-|--------------------------------------------------------------------------

-| Default Character Set

-|--------------------------------------------------------------------------

-|

-| This determines which character set is used by default in various methods

-| that require a character set to be provided.

-|

-*/

-$config['charset'] = "UTF-8";

-

-/*

-|--------------------------------------------------------------------------

-| Enable/Disable System Hooks

-|--------------------------------------------------------------------------

-|

-| If you would like to use the "hooks" feature you must enable it by

-| setting this variable to TRUE (boolean).  See the user guide for details.

-|

-*/

-$config['enable_hooks'] = FALSE;

-

-

-/*

-|--------------------------------------------------------------------------

-| Class Extension Prefix

-|--------------------------------------------------------------------------

-|

-| This item allows you to set the filename/classname prefix when extending

-| native libraries.  For more information please see the user guide:

-|

-| http://codeigniter.com/user_guide/general/core_classes.html

-| http://codeigniter.com/user_guide/general/creating_libraries.html

-|

-*/

-$config['subclass_prefix'] = 'MY_';

-

-

-/*

-|--------------------------------------------------------------------------

-| Allowed URL Characters

-|--------------------------------------------------------------------------

-|

-| This lets you specify with a regular expression which characters are permitted

-| within your URLs.  When someone tries to submit a URL with disallowed

-| characters they will get a warning message.

-|

-| As a security measure you are STRONGLY encouraged to restrict URLs to

-| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-

-|

-| Leave blank to allow all characters -- but only if you are insane.

-|

-| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!

-|

-*/

-$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';

-

-

-/*

-|--------------------------------------------------------------------------

-| Enable Query Strings

-|--------------------------------------------------------------------------

-|

-| By default CodeIgniter uses search-engine friendly segment based URLs:

-| example.com/who/what/where/

-|

-| You can optionally enable standard query string based URLs:

-| example.com?who=me&what=something&where=here

-|

-| Options are: TRUE or FALSE (boolean)

-|

-| The other items let you set the query string "words" that will

-| invoke your controllers and its functions:

-| example.com/index.php?c=controller&m=function

-|

-| Please note that some of the helpers won't work as expected when

-| this feature is enabled, since CodeIgniter is designed primarily to

-| use segment based URLs.

-|

-*/

-$config['enable_query_strings'] = FALSE;

-$config['controller_trigger'] 	= 'c';

-$config['function_trigger'] 	= 'm';

-$config['directory_trigger'] 	= 'd'; // experimental not currently in use

-

-/*

-|--------------------------------------------------------------------------

-| Error Logging Threshold

-|--------------------------------------------------------------------------

-|

-| If you have enabled error logging, you can set an error threshold to 

-| determine what gets logged. Threshold options are:

-| You can enable error logging by setting a threshold over zero. The

-| threshold determines what gets logged. Threshold options are:

-|

-|	0 = Disables logging, Error logging TURNED OFF

-|	1 = Error Messages (including PHP errors)

-|	2 = Debug Messages

-|	3 = Informational Messages

-|	4 = All Messages

-|

-| For a live site you'll usually only enable Errors (1) to be logged otherwise

-| your log files will fill up very fast.

-|

-*/

-$config['log_threshold'] = 0;

-

-/*

-|--------------------------------------------------------------------------

-| Error Logging Directory Path

-|--------------------------------------------------------------------------

-|

-| Leave this BLANK unless you would like to set something other than the default

-| system/logs/ folder.  Use a full server path with trailing slash.

-|

-*/

-$config['log_path'] = '';

-

-/*

-|--------------------------------------------------------------------------

-| Date Format for Logs

-|--------------------------------------------------------------------------

-|

-| Each item that is logged has an associated date. You can use PHP date

-| codes to set your own date formatting

-|

-*/

-$config['log_date_format'] = 'Y-m-d H:i:s';

-

-/*

-|--------------------------------------------------------------------------

-| Cache Directory Path

-|--------------------------------------------------------------------------

-|

-| Leave this BLANK unless you would like to set something other than the default

-| system/cache/ folder.  Use a full server path with trailing slash.

-|

-*/

-$config['cache_path'] = '';

-

-/*

-|--------------------------------------------------------------------------

-| Encryption Key

-|--------------------------------------------------------------------------

-|

-| If you use the Encryption class or the Sessions class with encryption

-| enabled you MUST set an encryption key.  See the user guide for info.

-|

-*/

-$config['encryption_key'] = "";

-

-/*

-|--------------------------------------------------------------------------

-| Session Variables

-|--------------------------------------------------------------------------

-|

-| 'session_cookie_name' = the name you want for the cookie

-| 'encrypt_sess_cookie' = TRUE/FALSE (boolean).  Whether to encrypt the cookie

-| 'session_expiration'  = the number of SECONDS you want the session to last.

-|  by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.

-| 'time_to_update'		= how many seconds between CI refreshing Session Information

-|

-*/

-$config['sess_cookie_name']		= 'ci_session';

-$config['sess_expiration']		= 7200;

-$config['sess_encrypt_cookie']	= FALSE;

-$config['sess_use_database']	= FALSE;

-$config['sess_table_name']		= 'ci_sessions';

-$config['sess_match_ip']		= FALSE;

-$config['sess_match_useragent']	= TRUE;

-$config['sess_time_to_update'] 	= 300;

-

-/*

-|--------------------------------------------------------------------------

-| Cookie Related Variables

-|--------------------------------------------------------------------------

-|

-| 'cookie_prefix' = Set a prefix if you need to avoid collisions

-| 'cookie_domain' = Set to .your-domain.com for site-wide cookies

-| 'cookie_path'   =  Typically will be a forward slash

-|

-*/

-$config['cookie_prefix']	= "";

-$config['cookie_domain']	= "";

-$config['cookie_path']		= "/";

-

-/*

-|--------------------------------------------------------------------------

-| Global XSS Filtering

-|--------------------------------------------------------------------------

-|

-| Determines whether the XSS filter is always active when GET, POST or

-| COOKIE data is encountered

-|

-*/

-$config['global_xss_filtering'] = FALSE;

-

-/*

-|--------------------------------------------------------------------------

-| Output Compression

-|--------------------------------------------------------------------------

-|

-| Enables Gzip output compression for faster page loads.  When enabled,

-| the output class will test whether your server supports Gzip.

-| Even if it does, however, not all browsers support compression

-| so enable only if you are reasonably sure your visitors can handle it.

-|

-| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it

-| means you are prematurely outputting something to your browser. It could

-| even be a line of whitespace at the end of one of your scripts.  For

-| compression to work, nothing can be sent before the output buffer is called

-| by the output class.  Do not "echo" any values with compression enabled.

-|

-*/

-$config['compress_output'] = FALSE;

-

-/*

-|--------------------------------------------------------------------------

-| Master Time Reference

-|--------------------------------------------------------------------------

-|

-| Options are "local" or "gmt".  This pref tells the system whether to use

-| your server's local time as the master "now" reference, or convert it to

-| GMT.  See the "date helper" page of the user guide for information

-| regarding date handling.

-|

-*/

-$config['time_reference'] = 'local';

-

-

-/*

-|--------------------------------------------------------------------------

-| Rewrite PHP Short Tags

-|--------------------------------------------------------------------------

-|

-| If your PHP installation does not have short tag support enabled CI

-| can rewrite the tags on-the-fly, enabling you to utilize that syntax

-| in your view files.  Options are TRUE or FALSE (boolean)

-|

-*/

-$config['rewrite_short_tags'] = FALSE;

-

-

-

-/* End of file config.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Base Site URL
+|--------------------------------------------------------------------------
+|
+| URL to your CodeIgniter root. Typically this will be your base URL,
+| WITH a trailing slash:
+|
+|	http://example.com/
+|
+*/
+$config['base_url']	= "http://your-site.com/";
+
+/*
+|--------------------------------------------------------------------------
+| Index File
+|--------------------------------------------------------------------------
+|
+| Typically this will be your index.php file, unless you've renamed it to
+| something else. If you are using mod_rewrite to remove the page set this
+| variable so that it is blank.
+|
+*/
+$config['index_page'] = "index.php";
+
+/*
+|--------------------------------------------------------------------------
+| URI PROTOCOL
+|--------------------------------------------------------------------------
+|
+| This item determines which server global should be used to retrieve the
+| URI string.  The default setting of "AUTO" works for most servers.
+| If your links do not seem to work, try one of the other delicious flavors:
+|
+| 'AUTO'			Default - auto detects
+| 'PATH_INFO'		Uses the PATH_INFO
+| 'QUERY_STRING'	Uses the QUERY_STRING
+| 'REQUEST_URI'		Uses the REQUEST_URI
+| 'ORIG_PATH_INFO'	Uses the ORIG_PATH_INFO
+|
+*/
+$config['uri_protocol']	= "AUTO";
+
+/*
+|--------------------------------------------------------------------------
+| URL suffix
+|--------------------------------------------------------------------------
+|
+| This option allows you to add a suffix to all URLs generated by CodeIgniter.
+| For more information please see the user guide:
+|
+| http://codeigniter.com/user_guide/general/urls.html
+*/
+
+$config['url_suffix'] = "";
+
+/*
+|--------------------------------------------------------------------------
+| Default Language
+|--------------------------------------------------------------------------
+|
+| This determines which set of language files should be used. Make sure
+| there is an available translation if you intend to use something other
+| than english.
+|
+*/
+$config['language']	= "english";
+
+/*
+|--------------------------------------------------------------------------
+| Default Character Set
+|--------------------------------------------------------------------------
+|
+| This determines which character set is used by default in various methods
+| that require a character set to be provided.
+|
+*/
+$config['charset'] = "UTF-8";
+
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable System Hooks
+|--------------------------------------------------------------------------
+|
+| If you would like to use the "hooks" feature you must enable it by
+| setting this variable to TRUE (boolean).  See the user guide for details.
+|
+*/
+$config['enable_hooks'] = FALSE;
+
+
+/*
+|--------------------------------------------------------------------------
+| Class Extension Prefix
+|--------------------------------------------------------------------------
+|
+| This item allows you to set the filename/classname prefix when extending
+| native libraries.  For more information please see the user guide:
+|
+| http://codeigniter.com/user_guide/general/core_classes.html
+| http://codeigniter.com/user_guide/general/creating_libraries.html
+|
+*/
+$config['subclass_prefix'] = 'MY_';
+
+
+/*
+|--------------------------------------------------------------------------
+| Allowed URL Characters
+|--------------------------------------------------------------------------
+|
+| This lets you specify with a regular expression which characters are permitted
+| within your URLs.  When someone tries to submit a URL with disallowed
+| characters they will get a warning message.
+|
+| As a security measure you are STRONGLY encouraged to restrict URLs to
+| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-
+|
+| Leave blank to allow all characters -- but only if you are insane.
+|
+| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
+|
+*/
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
+
+
+/*
+|--------------------------------------------------------------------------
+| Enable Query Strings
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter uses search-engine friendly segment based URLs:
+| example.com/who/what/where/
+|
+| You can optionally enable standard query string based URLs:
+| example.com?who=me&what=something&where=here
+|
+| Options are: TRUE or FALSE (boolean)
+|
+| The other items let you set the query string "words" that will
+| invoke your controllers and its functions:
+| example.com/index.php?c=controller&m=function
+|
+| Please note that some of the helpers won't work as expected when
+| this feature is enabled, since CodeIgniter is designed primarily to
+| use segment based URLs.
+|
+*/
+$config['enable_query_strings'] = FALSE;
+$config['controller_trigger'] 	= 'c';
+$config['function_trigger'] 	= 'm';
+$config['directory_trigger'] 	= 'd'; // experimental not currently in use
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Threshold
+|--------------------------------------------------------------------------
+|
+| If you have enabled error logging, you can set an error threshold to 
+| determine what gets logged. Threshold options are:
+| You can enable error logging by setting a threshold over zero. The
+| threshold determines what gets logged. Threshold options are:
+|
+|	0 = Disables logging, Error logging TURNED OFF
+|	1 = Error Messages (including PHP errors)
+|	2 = Debug Messages
+|	3 = Informational Messages
+|	4 = All Messages
+|
+| For a live site you'll usually only enable Errors (1) to be logged otherwise
+| your log files will fill up very fast.
+|
+*/
+$config['log_threshold'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| system/logs/ folder.  Use a full server path with trailing slash.
+|
+*/
+$config['log_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Date Format for Logs
+|--------------------------------------------------------------------------
+|
+| Each item that is logged has an associated date. You can use PHP date
+| codes to set your own date formatting
+|
+*/
+$config['log_date_format'] = 'Y-m-d H:i:s';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| system/cache/ folder.  Use a full server path with trailing slash.
+|
+*/
+$config['cache_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Encryption Key
+|--------------------------------------------------------------------------
+|
+| If you use the Encryption class or the Sessions class with encryption
+| enabled you MUST set an encryption key.  See the user guide for info.
+|
+*/
+$config['encryption_key'] = "";
+
+/*
+|--------------------------------------------------------------------------
+| Session Variables
+|--------------------------------------------------------------------------
+|
+| 'session_cookie_name' = the name you want for the cookie
+| 'encrypt_sess_cookie' = TRUE/FALSE (boolean).  Whether to encrypt the cookie
+| 'session_expiration'  = the number of SECONDS you want the session to last.
+|  by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.
+| 'time_to_update'		= how many seconds between CI refreshing Session Information
+|
+*/
+$config['sess_cookie_name']		= 'ci_session';
+$config['sess_expiration']		= 7200;
+$config['sess_encrypt_cookie']	= FALSE;
+$config['sess_use_database']	= FALSE;
+$config['sess_table_name']		= 'ci_sessions';
+$config['sess_match_ip']		= FALSE;
+$config['sess_match_useragent']	= TRUE;
+$config['sess_time_to_update'] 	= 300;
+
+/*
+|--------------------------------------------------------------------------
+| Cookie Related Variables
+|--------------------------------------------------------------------------
+|
+| 'cookie_prefix' = Set a prefix if you need to avoid collisions
+| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
+| 'cookie_path'   =  Typically will be a forward slash
+|
+*/
+$config['cookie_prefix']	= "";
+$config['cookie_domain']	= "";
+$config['cookie_path']		= "/";
+
+/*
+|--------------------------------------------------------------------------
+| Global XSS Filtering
+|--------------------------------------------------------------------------
+|
+| Determines whether the XSS filter is always active when GET, POST or
+| COOKIE data is encountered
+|
+*/
+$config['global_xss_filtering'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Output Compression
+|--------------------------------------------------------------------------
+|
+| Enables Gzip output compression for faster page loads.  When enabled,
+| the output class will test whether your server supports Gzip.
+| Even if it does, however, not all browsers support compression
+| so enable only if you are reasonably sure your visitors can handle it.
+|
+| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it
+| means you are prematurely outputting something to your browser. It could
+| even be a line of whitespace at the end of one of your scripts.  For
+| compression to work, nothing can be sent before the output buffer is called
+| by the output class.  Do not "echo" any values with compression enabled.
+|
+*/
+$config['compress_output'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Master Time Reference
+|--------------------------------------------------------------------------
+|
+| Options are "local" or "gmt".  This pref tells the system whether to use
+| your server's local time as the master "now" reference, or convert it to
+| GMT.  See the "date helper" page of the user guide for information
+| regarding date handling.
+|
+*/
+$config['time_reference'] = 'local';
+
+
+/*
+|--------------------------------------------------------------------------
+| Rewrite PHP Short Tags
+|--------------------------------------------------------------------------
+|
+| If your PHP installation does not have short tag support enabled CI
+| can rewrite the tags on-the-fly, enabling you to utilize that syntax
+| in your view files.  Options are TRUE or FALSE (boolean)
+|
+*/
+$config['rewrite_short_tags'] = FALSE;
+
+
+
+/* End of file config.php */
 /* Location: ./system/application/config/config.php */
\ No newline at end of file
diff --git a/system/application/config/constants.php b/system/application/config/constants.php
index 3d317f5..86ebdbb 100644
--- a/system/application/config/constants.php
+++ b/system/application/config/constants.php
@@ -1,41 +1,41 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-

-/*

-|--------------------------------------------------------------------------

-| File and Directory Modes

-|--------------------------------------------------------------------------

-|

-| These prefs are used when checking and setting modes when working

-| with the file system.  The defaults are fine on servers with proper

-| security, but you may wish (or even need) to change the values in

-| certain environments (Apache running a separate process for each

-| user, PHP under CGI with Apache suEXEC, etc.).  Octal values should

-| always be used to set the mode correctly.

-|

-*/

-define('FILE_READ_MODE', 0644);

-define('FILE_WRITE_MODE', 0666);

-define('DIR_READ_MODE', 0755);

-define('DIR_WRITE_MODE', 0777);

-

-/*

-|--------------------------------------------------------------------------

-| File Stream Modes

-|--------------------------------------------------------------------------

-|

-| These modes are used when working with fopen()/popen()

-|

-*/

-

-define('FOPEN_READ', 							'rb');

-define('FOPEN_READ_WRITE',						'r+b');

-define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 		'wb'); // truncates existing file data, use with care

-define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 	'w+b'); // truncates existing file data, use with care

-define('FOPEN_WRITE_CREATE', 					'ab');

-define('FOPEN_READ_WRITE_CREATE', 				'a+b');

-define('FOPEN_WRITE_CREATE_STRICT', 			'xb');

-define('FOPEN_READ_WRITE_CREATE_STRICT',		'x+b');

-

-

-/* End of file constants.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| File and Directory Modes
+|--------------------------------------------------------------------------
+|
+| These prefs are used when checking and setting modes when working
+| with the file system.  The defaults are fine on servers with proper
+| security, but you may wish (or even need) to change the values in
+| certain environments (Apache running a separate process for each
+| user, PHP under CGI with Apache suEXEC, etc.).  Octal values should
+| always be used to set the mode correctly.
+|
+*/
+define('FILE_READ_MODE', 0644);
+define('FILE_WRITE_MODE', 0666);
+define('DIR_READ_MODE', 0755);
+define('DIR_WRITE_MODE', 0777);
+
+/*
+|--------------------------------------------------------------------------
+| File Stream Modes
+|--------------------------------------------------------------------------
+|
+| These modes are used when working with fopen()/popen()
+|
+*/
+
+define('FOPEN_READ', 							'rb');
+define('FOPEN_READ_WRITE',						'r+b');
+define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 		'wb'); // truncates existing file data, use with care
+define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 	'w+b'); // truncates existing file data, use with care
+define('FOPEN_WRITE_CREATE', 					'ab');
+define('FOPEN_READ_WRITE_CREATE', 				'a+b');
+define('FOPEN_WRITE_CREATE_STRICT', 			'xb');
+define('FOPEN_READ_WRITE_CREATE_STRICT',		'x+b');
+
+
+/* End of file constants.php */
 /* Location: ./system/application/config/constants.php */
\ No newline at end of file
diff --git a/system/application/config/database.php b/system/application/config/database.php
index 24789f4..ee11c8a 100644
--- a/system/application/config/database.php
+++ b/system/application/config/database.php
@@ -1,55 +1,55 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------

-| DATABASE CONNECTIVITY SETTINGS

-| -------------------------------------------------------------------

-| This file will contain the settings needed to access your database.

-|

-| For complete instructions please consult the "Database Connection"

-| page of the User Guide.

-|

-| -------------------------------------------------------------------

-| EXPLANATION OF VARIABLES

-| -------------------------------------------------------------------

-|

-|	['hostname'] The hostname of your database server.

-|	['username'] The username used to connect to the database

-|	['password'] The password used to connect to the database

-|	['database'] The name of the database you want to connect to

-|	['dbdriver'] The database type. ie: mysql.  Currently supported:

-				 mysql, mysqli, postgre, odbc, mssql, sqlite, oci8

-|	['dbprefix'] You can add an optional prefix, which will be added

-|				 to the table name when using the  Active Record class

-|	['pconnect'] TRUE/FALSE - Whether to use a persistent connection

-|	['db_debug'] TRUE/FALSE - Whether database errors should be displayed.

-|	['cache_on'] TRUE/FALSE - Enables/disables query caching

-|	['cachedir'] The path to the folder where cache files should be stored

-|	['char_set'] The character set used in communicating with the database

-|	['dbcollat'] The character collation used in communicating with the database

-|

-| The $active_group variable lets you choose which connection group to

-| make active.  By default there is only one group (the "default" group).

-|

-| The $active_record variables lets you determine whether or not to load

-| the active record class

-*/

-

-$active_group = "default";

-$active_record = TRUE;

-

-$db['default']['hostname'] = "localhost";

-$db['default']['username'] = "";

-$db['default']['password'] = "";

-$db['default']['database'] = "";

-$db['default']['dbdriver'] = "mysql";

-$db['default']['dbprefix'] = "";

-$db['default']['pconnect'] = TRUE;

-$db['default']['db_debug'] = TRUE;

-$db['default']['cache_on'] = FALSE;

-$db['default']['cachedir'] = "";

-$db['default']['char_set'] = "utf8";

-$db['default']['dbcollat'] = "utf8_general_ci";

-

-

-/* End of file database.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| DATABASE CONNECTIVITY SETTINGS
+| -------------------------------------------------------------------
+| This file will contain the settings needed to access your database.
+|
+| For complete instructions please consult the "Database Connection"
+| page of the User Guide.
+|
+| -------------------------------------------------------------------
+| EXPLANATION OF VARIABLES
+| -------------------------------------------------------------------
+|
+|	['hostname'] The hostname of your database server.
+|	['username'] The username used to connect to the database
+|	['password'] The password used to connect to the database
+|	['database'] The name of the database you want to connect to
+|	['dbdriver'] The database type. ie: mysql.  Currently supported:
+				 mysql, mysqli, postgre, odbc, mssql, sqlite, oci8
+|	['dbprefix'] You can add an optional prefix, which will be added
+|				 to the table name when using the  Active Record class
+|	['pconnect'] TRUE/FALSE - Whether to use a persistent connection
+|	['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
+|	['cache_on'] TRUE/FALSE - Enables/disables query caching
+|	['cachedir'] The path to the folder where cache files should be stored
+|	['char_set'] The character set used in communicating with the database
+|	['dbcollat'] The character collation used in communicating with the database
+|
+| The $active_group variable lets you choose which connection group to
+| make active.  By default there is only one group (the "default" group).
+|
+| The $active_record variables lets you determine whether or not to load
+| the active record class
+*/
+
+$active_group = "default";
+$active_record = TRUE;
+
+$db['default']['hostname'] = "localhost";
+$db['default']['username'] = "";
+$db['default']['password'] = "";
+$db['default']['database'] = "";
+$db['default']['dbdriver'] = "mysql";
+$db['default']['dbprefix'] = "";
+$db['default']['pconnect'] = TRUE;
+$db['default']['db_debug'] = TRUE;
+$db['default']['cache_on'] = FALSE;
+$db['default']['cachedir'] = "";
+$db['default']['char_set'] = "utf8";
+$db['default']['dbcollat'] = "utf8_general_ci";
+
+
+/* End of file database.php */
 /* Location: ./system/application/config/database.php */
\ No newline at end of file
diff --git a/system/application/config/doctypes.php b/system/application/config/doctypes.php
index 2e6ac7d..9d510ab 100644
--- a/system/application/config/doctypes.php
+++ b/system/application/config/doctypes.php
@@ -1,15 +1,15 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-

-$_doctypes = array(

-					'xhtml11'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',

-					'xhtml1-strict'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',

-					'xhtml1-trans'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',

-					'xhtml1-frame'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',

-					'html5'			=> '<!DOCTYPE html>',

-					'html4-strict'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',

-					'html4-trans'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',

-					'html4-frame'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'

-					);

-

-/* End of file doctypes.php */

+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+$_doctypes = array(
+					'xhtml11'		=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+					'xhtml1-strict'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+					'xhtml1-trans'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+					'xhtml1-frame'	=> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+					'html5'			=> '<!DOCTYPE html>',
+					'html4-strict'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+					'html4-trans'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+					'html4-frame'	=> '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
+					);
+
+/* End of file doctypes.php */
 /* Location: application/config/doctypes.php */
\ No newline at end of file
diff --git a/system/application/config/hooks.php b/system/application/config/hooks.php
index b94edb9..5e98a9b 100644
--- a/system/application/config/hooks.php
+++ b/system/application/config/hooks.php
@@ -1,16 +1,16 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------------

-| Hooks

-| -------------------------------------------------------------------------

-| This file lets you define "hooks" to extend CI without hacking the core

-| files.  Please see the user guide for info:

-|

-|	http://codeigniter.com/user_guide/general/hooks.html

-|

-*/

-

-

-

-/* End of file hooks.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------------
+| Hooks
+| -------------------------------------------------------------------------
+| This file lets you define "hooks" to extend CI without hacking the core
+| files.  Please see the user guide for info:
+|
+|	http://codeigniter.com/user_guide/general/hooks.html
+|
+*/
+
+
+
+/* End of file hooks.php */
 /* Location: ./system/application/config/hooks.php */
\ No newline at end of file
diff --git a/system/application/config/index.html b/system/application/config/index.html
index 065d2da..c942a79 100644
--- a/system/application/config/index.html
+++ b/system/application/config/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/config/mimes.php b/system/application/config/mimes.php
index 51e444e..10acfad 100644
--- a/system/application/config/mimes.php
+++ b/system/application/config/mimes.php
@@ -1,105 +1,105 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------

-| MIME TYPES

-| -------------------------------------------------------------------

-| This file contains an array of mime types.  It is used by the

-| Upload class to help identify allowed file types.

-|

-*/

-

-$mimes = array(	'hqx'	=>	'application/mac-binhex40',

-				'cpt'	=>	'application/mac-compactpro',

-				'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),

-				'bin'	=>	'application/macbinary',

-				'dms'	=>	'application/octet-stream',

-				'lha'	=>	'application/octet-stream',

-				'lzh'	=>	'application/octet-stream',

-				'exe'	=>	'application/octet-stream',

-				'class'	=>	'application/octet-stream',

-				'psd'	=>	'application/x-photoshop',

-				'so'	=>	'application/octet-stream',

-				'sea'	=>	'application/octet-stream',

-				'dll'	=>	'application/octet-stream',

-				'oda'	=>	'application/oda',

-				'pdf'	=>	array('application/pdf', 'application/x-download'),

-				'ai'	=>	'application/postscript',

-				'eps'	=>	'application/postscript',

-				'ps'	=>	'application/postscript',

-				'smi'	=>	'application/smil',

-				'smil'	=>	'application/smil',

-				'mif'	=>	'application/vnd.mif',

-				'xls'	=>	array('application/excel', 'application/vnd.ms-excel'),

-				'ppt'	=>	array('application/powerpoint', 'application/vnd.ms-powerpoint'),

-				'wbxml'	=>	'application/wbxml',

-				'wmlc'	=>	'application/wmlc',

-				'dcr'	=>	'application/x-director',

-				'dir'	=>	'application/x-director',

-				'dxr'	=>	'application/x-director',

-				'dvi'	=>	'application/x-dvi',

-				'gtar'	=>	'application/x-gtar',

-				'gz'	=>	'application/x-gzip',

-				'php'	=>	'application/x-httpd-php',

-				'php4'	=>	'application/x-httpd-php',

-				'php3'	=>	'application/x-httpd-php',

-				'phtml'	=>	'application/x-httpd-php',

-				'phps'	=>	'application/x-httpd-php-source',

-				'js'	=>	'application/x-javascript',

-				'swf'	=>	'application/x-shockwave-flash',

-				'sit'	=>	'application/x-stuffit',

-				'tar'	=>	'application/x-tar',

-				'tgz'	=>	'application/x-tar',

-				'xhtml'	=>	'application/xhtml+xml',

-				'xht'	=>	'application/xhtml+xml',

-				'zip'	=>  array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),

-				'mid'	=>	'audio/midi',

-				'midi'	=>	'audio/midi',

-				'mpga'	=>	'audio/mpeg',

-				'mp2'	=>	'audio/mpeg',

-				'mp3'	=>	array('audio/mpeg', 'audio/mpg'),

-				'aif'	=>	'audio/x-aiff',

-				'aiff'	=>	'audio/x-aiff',

-				'aifc'	=>	'audio/x-aiff',

-				'ram'	=>	'audio/x-pn-realaudio',

-				'rm'	=>	'audio/x-pn-realaudio',

-				'rpm'	=>	'audio/x-pn-realaudio-plugin',

-				'ra'	=>	'audio/x-realaudio',

-				'rv'	=>	'video/vnd.rn-realvideo',

-				'wav'	=>	'audio/x-wav',

-				'bmp'	=>	'image/bmp',

-				'gif'	=>	'image/gif',

-				'jpeg'	=>	array('image/jpeg', 'image/pjpeg'),

-				'jpg'	=>	array('image/jpeg', 'image/pjpeg'),

-				'jpe'	=>	array('image/jpeg', 'image/pjpeg'),

-				'png'	=>	array('image/png',  'image/x-png'),

-				'tiff'	=>	'image/tiff',

-				'tif'	=>	'image/tiff',

-				'css'	=>	'text/css',

-				'html'	=>	'text/html',

-				'htm'	=>	'text/html',

-				'shtml'	=>	'text/html',

-				'txt'	=>	'text/plain',

-				'text'	=>	'text/plain',

-				'log'	=>	array('text/plain', 'text/x-log'),

-				'rtx'	=>	'text/richtext',

-				'rtf'	=>	'text/rtf',

-				'xml'	=>	'text/xml',

-				'xsl'	=>	'text/xml',

-				'mpeg'	=>	'video/mpeg',

-				'mpg'	=>	'video/mpeg',

-				'mpe'	=>	'video/mpeg',

-				'qt'	=>	'video/quicktime',

-				'mov'	=>	'video/quicktime',

-				'avi'	=>	'video/x-msvideo',

-				'movie'	=>	'video/x-sgi-movie',

-				'doc'	=>	'application/msword',

-				'docx'	=>	'application/vnd.openxmlformats-officedocument.wordprocessingml.document',

-				'xlsx'	=>	'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',

-				'word'	=>	array('application/msword', 'application/octet-stream'),

-				'xl'	=>	'application/excel',

-				'eml'	=>	'message/rfc822'

-			);

-

-

-/* End of file mimes.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| MIME TYPES
+| -------------------------------------------------------------------
+| This file contains an array of mime types.  It is used by the
+| Upload class to help identify allowed file types.
+|
+*/
+
+$mimes = array(	'hqx'	=>	'application/mac-binhex40',
+				'cpt'	=>	'application/mac-compactpro',
+				'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
+				'bin'	=>	'application/macbinary',
+				'dms'	=>	'application/octet-stream',
+				'lha'	=>	'application/octet-stream',
+				'lzh'	=>	'application/octet-stream',
+				'exe'	=>	'application/octet-stream',
+				'class'	=>	'application/octet-stream',
+				'psd'	=>	'application/x-photoshop',
+				'so'	=>	'application/octet-stream',
+				'sea'	=>	'application/octet-stream',
+				'dll'	=>	'application/octet-stream',
+				'oda'	=>	'application/oda',
+				'pdf'	=>	array('application/pdf', 'application/x-download'),
+				'ai'	=>	'application/postscript',
+				'eps'	=>	'application/postscript',
+				'ps'	=>	'application/postscript',
+				'smi'	=>	'application/smil',
+				'smil'	=>	'application/smil',
+				'mif'	=>	'application/vnd.mif',
+				'xls'	=>	array('application/excel', 'application/vnd.ms-excel'),
+				'ppt'	=>	array('application/powerpoint', 'application/vnd.ms-powerpoint'),
+				'wbxml'	=>	'application/wbxml',
+				'wmlc'	=>	'application/wmlc',
+				'dcr'	=>	'application/x-director',
+				'dir'	=>	'application/x-director',
+				'dxr'	=>	'application/x-director',
+				'dvi'	=>	'application/x-dvi',
+				'gtar'	=>	'application/x-gtar',
+				'gz'	=>	'application/x-gzip',
+				'php'	=>	'application/x-httpd-php',
+				'php4'	=>	'application/x-httpd-php',
+				'php3'	=>	'application/x-httpd-php',
+				'phtml'	=>	'application/x-httpd-php',
+				'phps'	=>	'application/x-httpd-php-source',
+				'js'	=>	'application/x-javascript',
+				'swf'	=>	'application/x-shockwave-flash',
+				'sit'	=>	'application/x-stuffit',
+				'tar'	=>	'application/x-tar',
+				'tgz'	=>	'application/x-tar',
+				'xhtml'	=>	'application/xhtml+xml',
+				'xht'	=>	'application/xhtml+xml',
+				'zip'	=>  array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
+				'mid'	=>	'audio/midi',
+				'midi'	=>	'audio/midi',
+				'mpga'	=>	'audio/mpeg',
+				'mp2'	=>	'audio/mpeg',
+				'mp3'	=>	array('audio/mpeg', 'audio/mpg'),
+				'aif'	=>	'audio/x-aiff',
+				'aiff'	=>	'audio/x-aiff',
+				'aifc'	=>	'audio/x-aiff',
+				'ram'	=>	'audio/x-pn-realaudio',
+				'rm'	=>	'audio/x-pn-realaudio',
+				'rpm'	=>	'audio/x-pn-realaudio-plugin',
+				'ra'	=>	'audio/x-realaudio',
+				'rv'	=>	'video/vnd.rn-realvideo',
+				'wav'	=>	'audio/x-wav',
+				'bmp'	=>	'image/bmp',
+				'gif'	=>	'image/gif',
+				'jpeg'	=>	array('image/jpeg', 'image/pjpeg'),
+				'jpg'	=>	array('image/jpeg', 'image/pjpeg'),
+				'jpe'	=>	array('image/jpeg', 'image/pjpeg'),
+				'png'	=>	array('image/png',  'image/x-png'),
+				'tiff'	=>	'image/tiff',
+				'tif'	=>	'image/tiff',
+				'css'	=>	'text/css',
+				'html'	=>	'text/html',
+				'htm'	=>	'text/html',
+				'shtml'	=>	'text/html',
+				'txt'	=>	'text/plain',
+				'text'	=>	'text/plain',
+				'log'	=>	array('text/plain', 'text/x-log'),
+				'rtx'	=>	'text/richtext',
+				'rtf'	=>	'text/rtf',
+				'xml'	=>	'text/xml',
+				'xsl'	=>	'text/xml',
+				'mpeg'	=>	'video/mpeg',
+				'mpg'	=>	'video/mpeg',
+				'mpe'	=>	'video/mpeg',
+				'qt'	=>	'video/quicktime',
+				'mov'	=>	'video/quicktime',
+				'avi'	=>	'video/x-msvideo',
+				'movie'	=>	'video/x-sgi-movie',
+				'doc'	=>	'application/msword',
+				'docx'	=>	'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+				'xlsx'	=>	'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+				'word'	=>	array('application/msword', 'application/octet-stream'),
+				'xl'	=>	'application/excel',
+				'eml'	=>	'message/rfc822'
+			);
+
+
+/* End of file mimes.php */
 /* Location: ./system/application/config/mimes.php */
\ No newline at end of file
diff --git a/system/application/config/routes.php b/system/application/config/routes.php
index c959248..c2f1e99 100644
--- a/system/application/config/routes.php
+++ b/system/application/config/routes.php
@@ -1,48 +1,48 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------------

-| URI ROUTING

-| -------------------------------------------------------------------------

-| This file lets you re-map URI requests to specific controller functions.

-|

-| Typically there is a one-to-one relationship between a URL string

-| and its corresponding controller class/method. The segments in a

-| URL normally follow this pattern:

-|

-| 	example.com/class/method/id/

-|

-| In some instances, however, you may want to remap this relationship

-| so that a different class/function is called than the one

-| corresponding to the URL.

-|

-| Please see the user guide for complete details:

-|

-|	http://codeigniter.com/user_guide/general/routing.html

-|

-| -------------------------------------------------------------------------

-| RESERVED ROUTES

-| -------------------------------------------------------------------------

-|

-| There are two reserved routes:

-|

-|	$route['default_controller'] = 'welcome';

-|

-| This route indicates which controller class should be loaded if the

-| URI contains no data. In the above example, the "welcome" class

-| would be loaded.

-|

-|	$route['scaffolding_trigger'] = 'scaffolding';

-|

-| This route lets you set a "secret" word that will trigger the

-| scaffolding feature for added security. Note: Scaffolding must be

-| enabled in the controller in which you intend to use it.   The reserved 

-| routes must come before any wildcard or regular expression routes.

-|

-*/

-

-$route['default_controller'] = "welcome";

-$route['scaffolding_trigger'] = "";

-

-

-/* End of file routes.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------------
+| URI ROUTING
+| -------------------------------------------------------------------------
+| This file lets you re-map URI requests to specific controller functions.
+|
+| Typically there is a one-to-one relationship between a URL string
+| and its corresponding controller class/method. The segments in a
+| URL normally follow this pattern:
+|
+| 	example.com/class/method/id/
+|
+| In some instances, however, you may want to remap this relationship
+| so that a different class/function is called than the one
+| corresponding to the URL.
+|
+| Please see the user guide for complete details:
+|
+|	http://codeigniter.com/user_guide/general/routing.html
+|
+| -------------------------------------------------------------------------
+| RESERVED ROUTES
+| -------------------------------------------------------------------------
+|
+| There are two reserved routes:
+|
+|	$route['default_controller'] = 'welcome';
+|
+| This route indicates which controller class should be loaded if the
+| URI contains no data. In the above example, the "welcome" class
+| would be loaded.
+|
+|	$route['scaffolding_trigger'] = 'scaffolding';
+|
+| This route lets you set a "secret" word that will trigger the
+| scaffolding feature for added security. Note: Scaffolding must be
+| enabled in the controller in which you intend to use it.   The reserved 
+| routes must come before any wildcard or regular expression routes.
+|
+*/
+
+$route['default_controller'] = "welcome";
+$route['scaffolding_trigger'] = "";
+
+
+/* End of file routes.php */
 /* Location: ./system/application/config/routes.php */
\ No newline at end of file
diff --git a/system/application/config/smileys.php b/system/application/config/smileys.php
index 8ef424f..7f3aba5 100644
--- a/system/application/config/smileys.php
+++ b/system/application/config/smileys.php
@@ -1,66 +1,66 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------

-| SMILEYS

-| -------------------------------------------------------------------

-| This file contains an array of smileys for use with the emoticon helper.

-| Individual images can be used to replace multiple simileys.  For example:

-| :-) and :) use the same image replacement.

-|

-| Please see user guide for more info: 

-| http://codeigniter.com/user_guide/helpers/smiley_helper.html

-|

-*/

-

-$smileys = array(

-

-//	smiley			image name						width	height	alt

-

-	':-)'			=>	array('grin.gif',			'19',	'19',	'grin'),

-	':lol:'			=>	array('lol.gif',			'19',	'19',	'LOL'),

-	':cheese:'		=>	array('cheese.gif',			'19',	'19',	'cheese'),

-	':)'			=>	array('smile.gif',			'19',	'19',	'smile'),

-	';-)'			=>	array('wink.gif',			'19',	'19',	'wink'),

-	';)'			=>	array('wink.gif',			'19',	'19',	'wink'),

-	':smirk:'		=>	array('smirk.gif',			'19',	'19',	'smirk'),

-	':roll:'		=>	array('rolleyes.gif',		'19',	'19',	'rolleyes'),

-	':-S'			=>	array('confused.gif',		'19',	'19',	'confused'),

-	':wow:'			=>	array('surprise.gif',		'19',	'19',	'surprised'),

-	':bug:'			=>	array('bigsurprise.gif',	'19',	'19',	'big surprise'),

-	':-P'			=>	array('tongue_laugh.gif',	'19',	'19',	'tongue laugh'),

-	'%-P'			=>	array('tongue_rolleye.gif',	'19',	'19',	'tongue rolleye'),

-	';-P'			=>	array('tongue_wink.gif',	'19',	'19',	'tongue wink'),

-	':P'			=>	array('raspberry.gif',		'19',	'19',	'raspberry'),

-	':blank:'		=>	array('blank.gif',			'19',	'19',	'blank stare'),

-	':long:'		=>	array('longface.gif',		'19',	'19',	'long face'),

-	':ohh:'			=>	array('ohh.gif',			'19',	'19',	'ohh'),

-	':grrr:'		=>	array('grrr.gif',			'19',	'19',	'grrr'),

-	':gulp:'		=>	array('gulp.gif',			'19',	'19',	'gulp'),

-	'8-/'			=>	array('ohoh.gif',			'19',	'19',	'oh oh'),

-	':down:'		=>	array('downer.gif',			'19',	'19',	'downer'),

-	':red:'			=>	array('embarrassed.gif',	'19',	'19',	'red face'),

-	':sick:'		=>	array('sick.gif',			'19',	'19',	'sick'),

-	':shut:'		=>	array('shuteye.gif',		'19',	'19',	'shut eye'),

-	':-/'			=>	array('hmm.gif',			'19',	'19',	'hmmm'),

-	'>:('			=>	array('mad.gif',			'19',	'19',	'mad'),

-	':mad:'			=>	array('mad.gif',			'19',	'19',	'mad'),

-	'>:-('			=>	array('angry.gif',			'19',	'19',	'angry'),

-	':angry:'		=>	array('angry.gif',			'19',	'19',	'angry'),

-	':zip:'			=>	array('zip.gif',			'19',	'19',	'zipper'),

-	':kiss:'		=>	array('kiss.gif',			'19',	'19',	'kiss'),

-	':ahhh:'		=>	array('shock.gif',			'19',	'19',	'shock'),

-	':coolsmile:'	=>	array('shade_smile.gif',	'19',	'19',	'cool smile'),

-	':coolsmirk:'	=>	array('shade_smirk.gif',	'19',	'19',	'cool smirk'),

-	':coolgrin:'	=>	array('shade_grin.gif',		'19',	'19',	'cool grin'),

-	':coolhmm:'		=>	array('shade_hmm.gif',		'19',	'19',	'cool hmm'),

-	':coolmad:'		=>	array('shade_mad.gif',		'19',	'19',	'cool mad'),

-	':coolcheese:'	=>	array('shade_cheese.gif',	'19',	'19',	'cool cheese'),

-	':vampire:'		=>	array('vampire.gif',		'19',	'19',	'vampire'),

-	':snake:'		=>	array('snake.gif',			'19',	'19',	'snake'),

-	':exclaim:'		=>	array('exclaim.gif',		'19',	'19',	'excaim'),

-	':question:'	=>	array('question.gif',		'19',	'19',	'question') // no comma after last item

-

-		);

-

-/* End of file smileys.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| SMILEYS
+| -------------------------------------------------------------------
+| This file contains an array of smileys for use with the emoticon helper.
+| Individual images can be used to replace multiple simileys.  For example:
+| :-) and :) use the same image replacement.
+|
+| Please see user guide for more info: 
+| http://codeigniter.com/user_guide/helpers/smiley_helper.html
+|
+*/
+
+$smileys = array(
+
+//	smiley			image name						width	height	alt
+
+	':-)'			=>	array('grin.gif',			'19',	'19',	'grin'),
+	':lol:'			=>	array('lol.gif',			'19',	'19',	'LOL'),
+	':cheese:'		=>	array('cheese.gif',			'19',	'19',	'cheese'),
+	':)'			=>	array('smile.gif',			'19',	'19',	'smile'),
+	';-)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	';)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	':smirk:'		=>	array('smirk.gif',			'19',	'19',	'smirk'),
+	':roll:'		=>	array('rolleyes.gif',		'19',	'19',	'rolleyes'),
+	':-S'			=>	array('confused.gif',		'19',	'19',	'confused'),
+	':wow:'			=>	array('surprise.gif',		'19',	'19',	'surprised'),
+	':bug:'			=>	array('bigsurprise.gif',	'19',	'19',	'big surprise'),
+	':-P'			=>	array('tongue_laugh.gif',	'19',	'19',	'tongue laugh'),
+	'%-P'			=>	array('tongue_rolleye.gif',	'19',	'19',	'tongue rolleye'),
+	';-P'			=>	array('tongue_wink.gif',	'19',	'19',	'tongue wink'),
+	':P'			=>	array('raspberry.gif',		'19',	'19',	'raspberry'),
+	':blank:'		=>	array('blank.gif',			'19',	'19',	'blank stare'),
+	':long:'		=>	array('longface.gif',		'19',	'19',	'long face'),
+	':ohh:'			=>	array('ohh.gif',			'19',	'19',	'ohh'),
+	':grrr:'		=>	array('grrr.gif',			'19',	'19',	'grrr'),
+	':gulp:'		=>	array('gulp.gif',			'19',	'19',	'gulp'),
+	'8-/'			=>	array('ohoh.gif',			'19',	'19',	'oh oh'),
+	':down:'		=>	array('downer.gif',			'19',	'19',	'downer'),
+	':red:'			=>	array('embarrassed.gif',	'19',	'19',	'red face'),
+	':sick:'		=>	array('sick.gif',			'19',	'19',	'sick'),
+	':shut:'		=>	array('shuteye.gif',		'19',	'19',	'shut eye'),
+	':-/'			=>	array('hmm.gif',			'19',	'19',	'hmmm'),
+	'>:('			=>	array('mad.gif',			'19',	'19',	'mad'),
+	':mad:'			=>	array('mad.gif',			'19',	'19',	'mad'),
+	'>:-('			=>	array('angry.gif',			'19',	'19',	'angry'),
+	':angry:'		=>	array('angry.gif',			'19',	'19',	'angry'),
+	':zip:'			=>	array('zip.gif',			'19',	'19',	'zipper'),
+	':kiss:'		=>	array('kiss.gif',			'19',	'19',	'kiss'),
+	':ahhh:'		=>	array('shock.gif',			'19',	'19',	'shock'),
+	':coolsmile:'	=>	array('shade_smile.gif',	'19',	'19',	'cool smile'),
+	':coolsmirk:'	=>	array('shade_smirk.gif',	'19',	'19',	'cool smirk'),
+	':coolgrin:'	=>	array('shade_grin.gif',		'19',	'19',	'cool grin'),
+	':coolhmm:'		=>	array('shade_hmm.gif',		'19',	'19',	'cool hmm'),
+	':coolmad:'		=>	array('shade_mad.gif',		'19',	'19',	'cool mad'),
+	':coolcheese:'	=>	array('shade_cheese.gif',	'19',	'19',	'cool cheese'),
+	':vampire:'		=>	array('vampire.gif',		'19',	'19',	'vampire'),
+	':snake:'		=>	array('snake.gif',			'19',	'19',	'snake'),
+	':exclaim:'		=>	array('exclaim.gif',		'19',	'19',	'excaim'),
+	':question:'	=>	array('question.gif',		'19',	'19',	'question') // no comma after last item
+
+		);
+
+/* End of file smileys.php */
 /* Location: ./system/application/config/smileys.php */
\ No newline at end of file
diff --git a/system/application/config/user_agents.php b/system/application/config/user_agents.php
index eabd762..c01b276 100644
--- a/system/application/config/user_agents.php
+++ b/system/application/config/user_agents.php
@@ -1,175 +1,175 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/*

-| -------------------------------------------------------------------

-| USER AGENT TYPES

-| -------------------------------------------------------------------

-| This file contains four arrays of user agent data.  It is used by the

-| User Agent Class to help identify browser, platform, robot, and

-| mobile device data.  The array keys are used to identify the device

-| and the array values are used to set the actual name of the item.

-|

-*/

-

-$platforms = array (

-					'windows nt 6.0'	=> 'Windows Longhorn',

-					'windows nt 5.2'	=> 'Windows 2003',

-					'windows nt 5.0'	=> 'Windows 2000',

-					'windows nt 5.1'	=> 'Windows XP',

-					'windows nt 4.0'	=> 'Windows NT 4.0',

-					'winnt4.0'			=> 'Windows NT 4.0',

-					'winnt 4.0'			=> 'Windows NT',

-					'winnt'				=> 'Windows NT',

-					'windows 98'		=> 'Windows 98',

-					'win98'				=> 'Windows 98',

-					'windows 95'		=> 'Windows 95',

-					'win95'				=> 'Windows 95',

-					'windows'			=> 'Unknown Windows OS',

-					'os x'				=> 'Mac OS X',

-					'ppc mac'			=> 'Power PC Mac',

-					'freebsd'			=> 'FreeBSD',

-					'ppc'				=> 'Macintosh',

-					'linux'				=> 'Linux',

-					'debian'			=> 'Debian',

-					'sunos'				=> 'Sun Solaris',

-					'beos'				=> 'BeOS',

-					'apachebench'		=> 'ApacheBench',

-					'aix'				=> 'AIX',

-					'irix'				=> 'Irix',

-					'osf'				=> 'DEC OSF',

-					'hp-ux'				=> 'HP-UX',

-					'netbsd'			=> 'NetBSD',

-					'bsdi'				=> 'BSDi',

-					'openbsd'			=> 'OpenBSD',

-					'gnu'				=> 'GNU/Linux',

-					'unix'				=> 'Unknown Unix OS'

-				);

-

-

-// The order of this array should NOT be changed. Many browsers return

-// multiple browser types so we want to identify the sub-type first.

-$browsers = array(

-					'Opera'				=> 'Opera',

-					'MSIE'				=> 'Internet Explorer',

-					'Internet Explorer'	=> 'Internet Explorer',

-					'Shiira'			=> 'Shiira',

-					'Firefox'			=> 'Firefox',

-					'Chimera'			=> 'Chimera',

-					'Phoenix'			=> 'Phoenix',

-					'Firebird'			=> 'Firebird',

-					'Camino'			=> 'Camino',

-					'Netscape'			=> 'Netscape',

-					'OmniWeb'			=> 'OmniWeb',

-					'Mozilla'			=> 'Mozilla',

-					'Safari'			=> 'Safari',

-					'Konqueror'			=> 'Konqueror',

-					'icab'				=> 'iCab',

-					'Lynx'				=> 'Lynx',

-					'Links'				=> 'Links',

-					'hotjava'			=> 'HotJava',

-					'amaya'				=> 'Amaya',

-					'IBrowse'			=> 'IBrowse'

-				);

-

-$mobiles = array(

-					// legacy array, old values commented out

-					'mobileexplorer'	=> 'Mobile Explorer',

-//					'openwave'			=> 'Open Wave',

-//					'opera mini'		=> 'Opera Mini',

-//					'operamini'			=> 'Opera Mini',

-//					'elaine'			=> 'Palm',

-					'palmsource'		=> 'Palm',

-//					'digital paths'		=> 'Palm',

-//					'avantgo'			=> 'Avantgo',

-//					'xiino'				=> 'Xiino',

-					'palmscape'			=> 'Palmscape',

-//					'nokia'				=> 'Nokia',

-//					'ericsson'			=> 'Ericsson',

-//					'blackberry'		=> 'BlackBerry',

-//					'motorola'			=> 'Motorola'

-

-					// Phones and Manufacturers

-					'motorola'			=> "Motorola",

-					'nokia'				=> "Nokia",

-					'palm'				=> "Palm",

-					'iphone'			=> "Apple iPhone",

-					'ipod'				=> "Apple iPod Touch",

-					'sony'				=> "Sony Ericsson",

-					'ericsson'			=> "Sony Ericsson",

-					'blackberry'		=> "BlackBerry",

-					'cocoon'			=> "O2 Cocoon",

-					'blazer'			=> "Treo",

-					'lg'				=> "LG",

-					'amoi'				=> "Amoi",

-					'xda'				=> "XDA",

-					'mda'				=> "MDA",

-					'vario'				=> "Vario",

-					'htc'				=> "HTC",

-					'samsung'			=> "Samsung",

-					'sharp'				=> "Sharp",

-					'sie-'				=> "Siemens",

-					'alcatel'			=> "Alcatel",

-					'benq'				=> "BenQ",

-					'ipaq'				=> "HP iPaq",

-					'mot-'				=> "Motorola",

-					'playstation portable' 	=> "PlayStation Portable",

-					'hiptop'			=> "Danger Hiptop",

-					'nec-'				=> "NEC",

-					'panasonic'			=> "Panasonic",

-					'philips'			=> "Philips",

-					'sagem'				=> "Sagem",

-					'sanyo'				=> "Sanyo",

-					'spv'				=> "SPV",

-					'zte'				=> "ZTE",

-					'sendo'				=> "Sendo",

-

-					// Operating Systems

-					'symbian'				=> "Symbian",

-					'SymbianOS'				=> "SymbianOS", 

-					'elaine'				=> "Palm",

-					'palm'					=> "Palm",

-					'series60'				=> "Symbian S60",

-					'windows ce'			=> "Windows CE",

-

-					// Browsers

-					'obigo'					=> "Obigo",

-					'netfront'				=> "Netfront Browser",

-					'openwave'				=> "Openwave Browser",

-					'mobilexplorer'			=> "Mobile Explorer",

-					'operamini'				=> "Opera Mini",

-					'opera mini'			=> "Opera Mini",

-

-					// Other

-					'digital paths'			=> "Digital Paths",

-					'avantgo'				=> "AvantGo",

-					'xiino'					=> "Xiino",

-					'novarra'				=> "Novarra Transcoder",

-					'vodafone'				=> "Vodafone",

-					'docomo'				=> "NTT DoCoMo",

-					'o2'					=> "O2",

-

-					// Fallback

-					'mobile'				=> "Generic Mobile",

-					'wireless' 				=> "Generic Mobile",

-					'j2me'					=> "Generic Mobile",

-					'midp'					=> "Generic Mobile",

-					'cldc'					=> "Generic Mobile",

-					'up.link'				=> "Generic Mobile",

-					'up.browser'			=> "Generic Mobile",

-					'smartphone'			=> "Generic Mobile",

-					'cellphone'				=> "Generic Mobile"

-				);

-

-// There are hundreds of bots but these are the most common.

-$robots = array(

-					'googlebot'			=> 'Googlebot',

-					'msnbot'			=> 'MSNBot',

-					'slurp'				=> 'Inktomi Slurp',

-					'yahoo'				=> 'Yahoo',

-					'askjeeves'			=> 'AskJeeves',

-					'fastcrawler'		=> 'FastCrawler',

-					'infoseek'			=> 'InfoSeek Robot 1.0',

-					'lycos'				=> 'Lycos'

-				);

-

-/* End of file user_agents.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| USER AGENT TYPES
+| -------------------------------------------------------------------
+| This file contains four arrays of user agent data.  It is used by the
+| User Agent Class to help identify browser, platform, robot, and
+| mobile device data.  The array keys are used to identify the device
+| and the array values are used to set the actual name of the item.
+|
+*/
+
+$platforms = array (
+					'windows nt 6.0'	=> 'Windows Longhorn',
+					'windows nt 5.2'	=> 'Windows 2003',
+					'windows nt 5.0'	=> 'Windows 2000',
+					'windows nt 5.1'	=> 'Windows XP',
+					'windows nt 4.0'	=> 'Windows NT 4.0',
+					'winnt4.0'			=> 'Windows NT 4.0',
+					'winnt 4.0'			=> 'Windows NT',
+					'winnt'				=> 'Windows NT',
+					'windows 98'		=> 'Windows 98',
+					'win98'				=> 'Windows 98',
+					'windows 95'		=> 'Windows 95',
+					'win95'				=> 'Windows 95',
+					'windows'			=> 'Unknown Windows OS',
+					'os x'				=> 'Mac OS X',
+					'ppc mac'			=> 'Power PC Mac',
+					'freebsd'			=> 'FreeBSD',
+					'ppc'				=> 'Macintosh',
+					'linux'				=> 'Linux',
+					'debian'			=> 'Debian',
+					'sunos'				=> 'Sun Solaris',
+					'beos'				=> 'BeOS',
+					'apachebench'		=> 'ApacheBench',
+					'aix'				=> 'AIX',
+					'irix'				=> 'Irix',
+					'osf'				=> 'DEC OSF',
+					'hp-ux'				=> 'HP-UX',
+					'netbsd'			=> 'NetBSD',
+					'bsdi'				=> 'BSDi',
+					'openbsd'			=> 'OpenBSD',
+					'gnu'				=> 'GNU/Linux',
+					'unix'				=> 'Unknown Unix OS'
+				);
+
+
+// The order of this array should NOT be changed. Many browsers return
+// multiple browser types so we want to identify the sub-type first.
+$browsers = array(
+					'Opera'				=> 'Opera',
+					'MSIE'				=> 'Internet Explorer',
+					'Internet Explorer'	=> 'Internet Explorer',
+					'Shiira'			=> 'Shiira',
+					'Firefox'			=> 'Firefox',
+					'Chimera'			=> 'Chimera',
+					'Phoenix'			=> 'Phoenix',
+					'Firebird'			=> 'Firebird',
+					'Camino'			=> 'Camino',
+					'Netscape'			=> 'Netscape',
+					'OmniWeb'			=> 'OmniWeb',
+					'Mozilla'			=> 'Mozilla',
+					'Safari'			=> 'Safari',
+					'Konqueror'			=> 'Konqueror',
+					'icab'				=> 'iCab',
+					'Lynx'				=> 'Lynx',
+					'Links'				=> 'Links',
+					'hotjava'			=> 'HotJava',
+					'amaya'				=> 'Amaya',
+					'IBrowse'			=> 'IBrowse'
+				);
+
+$mobiles = array(
+					// legacy array, old values commented out
+					'mobileexplorer'	=> 'Mobile Explorer',
+//					'openwave'			=> 'Open Wave',
+//					'opera mini'		=> 'Opera Mini',
+//					'operamini'			=> 'Opera Mini',
+//					'elaine'			=> 'Palm',
+					'palmsource'		=> 'Palm',
+//					'digital paths'		=> 'Palm',
+//					'avantgo'			=> 'Avantgo',
+//					'xiino'				=> 'Xiino',
+					'palmscape'			=> 'Palmscape',
+//					'nokia'				=> 'Nokia',
+//					'ericsson'			=> 'Ericsson',
+//					'blackberry'		=> 'BlackBerry',
+//					'motorola'			=> 'Motorola'
+
+					// Phones and Manufacturers
+					'motorola'			=> "Motorola",
+					'nokia'				=> "Nokia",
+					'palm'				=> "Palm",
+					'iphone'			=> "Apple iPhone",
+					'ipod'				=> "Apple iPod Touch",
+					'sony'				=> "Sony Ericsson",
+					'ericsson'			=> "Sony Ericsson",
+					'blackberry'		=> "BlackBerry",
+					'cocoon'			=> "O2 Cocoon",
+					'blazer'			=> "Treo",
+					'lg'				=> "LG",
+					'amoi'				=> "Amoi",
+					'xda'				=> "XDA",
+					'mda'				=> "MDA",
+					'vario'				=> "Vario",
+					'htc'				=> "HTC",
+					'samsung'			=> "Samsung",
+					'sharp'				=> "Sharp",
+					'sie-'				=> "Siemens",
+					'alcatel'			=> "Alcatel",
+					'benq'				=> "BenQ",
+					'ipaq'				=> "HP iPaq",
+					'mot-'				=> "Motorola",
+					'playstation portable' 	=> "PlayStation Portable",
+					'hiptop'			=> "Danger Hiptop",
+					'nec-'				=> "NEC",
+					'panasonic'			=> "Panasonic",
+					'philips'			=> "Philips",
+					'sagem'				=> "Sagem",
+					'sanyo'				=> "Sanyo",
+					'spv'				=> "SPV",
+					'zte'				=> "ZTE",
+					'sendo'				=> "Sendo",
+
+					// Operating Systems
+					'symbian'				=> "Symbian",
+					'SymbianOS'				=> "SymbianOS", 
+					'elaine'				=> "Palm",
+					'palm'					=> "Palm",
+					'series60'				=> "Symbian S60",
+					'windows ce'			=> "Windows CE",
+
+					// Browsers
+					'obigo'					=> "Obigo",
+					'netfront'				=> "Netfront Browser",
+					'openwave'				=> "Openwave Browser",
+					'mobilexplorer'			=> "Mobile Explorer",
+					'operamini'				=> "Opera Mini",
+					'opera mini'			=> "Opera Mini",
+
+					// Other
+					'digital paths'			=> "Digital Paths",
+					'avantgo'				=> "AvantGo",
+					'xiino'					=> "Xiino",
+					'novarra'				=> "Novarra Transcoder",
+					'vodafone'				=> "Vodafone",
+					'docomo'				=> "NTT DoCoMo",
+					'o2'					=> "O2",
+
+					// Fallback
+					'mobile'				=> "Generic Mobile",
+					'wireless' 				=> "Generic Mobile",
+					'j2me'					=> "Generic Mobile",
+					'midp'					=> "Generic Mobile",
+					'cldc'					=> "Generic Mobile",
+					'up.link'				=> "Generic Mobile",
+					'up.browser'			=> "Generic Mobile",
+					'smartphone'			=> "Generic Mobile",
+					'cellphone'				=> "Generic Mobile"
+				);
+
+// There are hundreds of bots but these are the most common.
+$robots = array(
+					'googlebot'			=> 'Googlebot',
+					'msnbot'			=> 'MSNBot',
+					'slurp'				=> 'Inktomi Slurp',
+					'yahoo'				=> 'Yahoo',
+					'askjeeves'			=> 'AskJeeves',
+					'fastcrawler'		=> 'FastCrawler',
+					'infoseek'			=> 'InfoSeek Robot 1.0',
+					'lycos'				=> 'Lycos'
+				);
+
+/* End of file user_agents.php */
 /* Location: ./system/application/config/user_agents.php */
\ No newline at end of file
diff --git a/system/application/controllers/index.html b/system/application/controllers/index.html
index 065d2da..c942a79 100644
--- a/system/application/controllers/index.html
+++ b/system/application/controllers/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/controllers/welcome.php b/system/application/controllers/welcome.php
index ec16000..20d4885 100644
--- a/system/application/controllers/welcome.php
+++ b/system/application/controllers/welcome.php
@@ -1,17 +1,17 @@
-<?php

-

-class Welcome extends Controller {

-

-	function Welcome()

-	{

-		parent::Controller();	

-	}

-	

-	function index()

-	{

-		$this->load->view('welcome_message');

-	}

-}

-

-/* End of file welcome.php */

+<?php
+
+class Welcome extends Controller {
+
+	function Welcome()
+	{
+		parent::Controller();	
+	}
+	
+	function index()
+	{
+		$this->load->view('welcome_message');
+	}
+}
+
+/* End of file welcome.php */
 /* Location: ./system/application/controllers/welcome.php */
\ No newline at end of file
diff --git a/system/application/errors/error_404.php b/system/application/errors/error_404.php
index cad7375..bfe9444 100644
--- a/system/application/errors/error_404.php
+++ b/system/application/errors/error_404.php
@@ -1,35 +1,35 @@
-<?php header("HTTP/1.1 404 Not Found"); ?>

-<html>

-<head>

-<title>404 Page Not Found</title>

-<style type="text/css">

-

-body {

-background-color:	#fff;

-margin:				40px;

-font-family:		Lucida Grande, Verdana, Sans-serif;

-font-size:			12px;

-color:				#000;

-}

-

-#content  {

-border:				#999 1px solid;

-background-color:	#fff;

-padding:			20px 20px 12px 20px;

-}

-

-h1 {

-font-weight:		normal;

-font-size:			14px;

-color:				#990000;

-margin: 			0 0 4px 0;

-}

-</style>

-</head>

-<body>

-	<div id="content">

-		<h1><?php echo $heading; ?></h1>

-		<?php echo $message; ?>

-	</div>

-</body>

+<?php header("HTTP/1.1 404 Not Found"); ?>
+<html>
+<head>
+<title>404 Page Not Found</title>
+<style type="text/css">
+
+body {
+background-color:	#fff;
+margin:				40px;
+font-family:		Lucida Grande, Verdana, Sans-serif;
+font-size:			12px;
+color:				#000;
+}
+
+#content  {
+border:				#999 1px solid;
+background-color:	#fff;
+padding:			20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:		normal;
+font-size:			14px;
+color:				#990000;
+margin: 			0 0 4px 0;
+}
+</style>
+</head>
+<body>
+	<div id="content">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/errors/error_db.php b/system/application/errors/error_db.php
index 71a4b98..1ce52df 100644
--- a/system/application/errors/error_db.php
+++ b/system/application/errors/error_db.php
@@ -1,34 +1,34 @@
-<html>

-<head>

-<title>Database Error</title>

-<style type="text/css">

-

-body {

-background-color:	#fff;

-margin:				40px;

-font-family:		Lucida Grande, Verdana, Sans-serif;

-font-size:			12px;

-color:				#000;

-}

-

-#content  {

-border:				#999 1px solid;

-background-color:	#fff;

-padding:			20px 20px 12px 20px;

-}

-

-h1 {

-font-weight:		normal;

-font-size:			14px;

-color:				#990000;

-margin: 			0 0 4px 0;

-}

-</style>

-</head>

-<body>

-	<div id="content">

-		<h1><?php echo $heading; ?></h1>

-		<?php echo $message; ?>

-	</div>

-</body>

+<html>
+<head>
+<title>Database Error</title>
+<style type="text/css">
+
+body {
+background-color:	#fff;
+margin:				40px;
+font-family:		Lucida Grande, Verdana, Sans-serif;
+font-size:			12px;
+color:				#000;
+}
+
+#content  {
+border:				#999 1px solid;
+background-color:	#fff;
+padding:			20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:		normal;
+font-size:			14px;
+color:				#990000;
+margin: 			0 0 4px 0;
+}
+</style>
+</head>
+<body>
+	<div id="content">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/errors/error_general.php b/system/application/errors/error_general.php
index 8545286..d861070 100644
--- a/system/application/errors/error_general.php
+++ b/system/application/errors/error_general.php
@@ -1,34 +1,34 @@
-<html>

-<head>

-<title>Error</title>

-<style type="text/css">

-

-body {

-background-color:	#fff;

-margin:				40px;

-font-family:		Lucida Grande, Verdana, Sans-serif;

-font-size:			12px;

-color:				#000;

-}

-

-#content  {

-border:				#999 1px solid;

-background-color:	#fff;

-padding:			20px 20px 12px 20px;

-}

-

-h1 {

-font-weight:		normal;

-font-size:			14px;

-color:				#990000;

-margin: 			0 0 4px 0;

-}

-</style>

-</head>

-<body>

-	<div id="content">

-		<h1><?php echo $heading; ?></h1>

-		<?php echo $message; ?>

-	</div>

-</body>

+<html>
+<head>
+<title>Error</title>
+<style type="text/css">
+
+body {
+background-color:	#fff;
+margin:				40px;
+font-family:		Lucida Grande, Verdana, Sans-serif;
+font-size:			12px;
+color:				#000;
+}
+
+#content  {
+border:				#999 1px solid;
+background-color:	#fff;
+padding:			20px 20px 12px 20px;
+}
+
+h1 {
+font-weight:		normal;
+font-size:			14px;
+color:				#990000;
+margin: 			0 0 4px 0;
+}
+</style>
+</head>
+<body>
+	<div id="content">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/errors/error_php.php b/system/application/errors/error_php.php
index f5941c9..f085c20 100644
--- a/system/application/errors/error_php.php
+++ b/system/application/errors/error_php.php
@@ -1,10 +1,10 @@
-<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">

-

-<h4>A PHP Error was encountered</h4>

-

-<p>Severity: <?php echo $severity; ?></p>

-<p>Message:  <?php echo $message; ?></p>

-<p>Filename: <?php echo $filepath; ?></p>

-<p>Line Number: <?php echo $line; ?></p>

-

+<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
+
+<h4>A PHP Error was encountered</h4>
+
+<p>Severity: <?php echo $severity; ?></p>
+<p>Message:  <?php echo $message; ?></p>
+<p>Filename: <?php echo $filepath; ?></p>
+<p>Line Number: <?php echo $line; ?></p>
+
 </div>
\ No newline at end of file
diff --git a/system/application/errors/index.html b/system/application/errors/index.html
index 065d2da..c942a79 100644
--- a/system/application/errors/index.html
+++ b/system/application/errors/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/helpers/index.html b/system/application/helpers/index.html
index 065d2da..c942a79 100644
--- a/system/application/helpers/index.html
+++ b/system/application/helpers/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/hooks/index.html b/system/application/hooks/index.html
index 065d2da..c942a79 100644
--- a/system/application/hooks/index.html
+++ b/system/application/hooks/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/index.html b/system/application/index.html
index 065d2da..c942a79 100644
--- a/system/application/index.html
+++ b/system/application/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/language/english/index.html b/system/application/language/english/index.html
index 065d2da..c942a79 100644
--- a/system/application/language/english/index.html
+++ b/system/application/language/english/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/libraries/index.html b/system/application/libraries/index.html
index 065d2da..c942a79 100644
--- a/system/application/libraries/index.html
+++ b/system/application/libraries/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/models/index.html b/system/application/models/index.html
index 065d2da..c942a79 100644
--- a/system/application/models/index.html
+++ b/system/application/models/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/views/index.html b/system/application/views/index.html
index 065d2da..c942a79 100644
--- a/system/application/views/index.html
+++ b/system/application/views/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/application/views/welcome_message.php b/system/application/views/welcome_message.php
index 8313059..653b62c 100644
--- a/system/application/views/welcome_message.php
+++ b/system/application/views/welcome_message.php
@@ -1,62 +1,62 @@
-<html>

-<head>

-<title>Welcome to CodeIgniter</title>

-

-<style type="text/css">

-

-body {

- background-color: #fff;

- margin: 40px;

- font-family: Lucida Grande, Verdana, Sans-serif;

- font-size: 14px;

- color: #4F5155;

-}

-

-a {

- color: #003399;

- background-color: transparent;

- font-weight: normal;

-}

-

-h1 {

- color: #444;

- background-color: transparent;

- border-bottom: 1px solid #D0D0D0;

- font-size: 16px;

- font-weight: bold;

- margin: 24px 0 2px 0;

- padding: 5px 0 6px 0;

-}

-

-code {

- font-family: Monaco, Verdana, Sans-serif;

- font-size: 12px;

- background-color: #f9f9f9;

- border: 1px solid #D0D0D0;

- color: #002166;

- display: block;

- margin: 14px 0 14px 0;

- padding: 12px 10px 12px 10px;

-}

-

-</style>

-</head>

-<body>

-

-<h1>Welcome to CodeIgniter!</h1>

-

-<p>The page you are looking at is being generated dynamically by CodeIgniter.</p>

-

-<p>If you would like to edit this page you'll find it located at:</p>

-<code>system/application/views/welcome_message.php</code>

-

-<p>The corresponding controller for this page is found at:</p>

-<code>system/application/controllers/welcome.php</code>

-

-<p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>

-

-

-<p><br />Page rendered in {elapsed_time} seconds</p>

-

-</body>

+<html>
+<head>
+<title>Welcome to CodeIgniter</title>
+
+<style type="text/css">
+
+body {
+ background-color: #fff;
+ margin: 40px;
+ font-family: Lucida Grande, Verdana, Sans-serif;
+ font-size: 14px;
+ color: #4F5155;
+}
+
+a {
+ color: #003399;
+ background-color: transparent;
+ font-weight: normal;
+}
+
+h1 {
+ color: #444;
+ background-color: transparent;
+ border-bottom: 1px solid #D0D0D0;
+ font-size: 16px;
+ font-weight: bold;
+ margin: 24px 0 2px 0;
+ padding: 5px 0 6px 0;
+}
+
+code {
+ font-family: Monaco, Verdana, Sans-serif;
+ font-size: 12px;
+ background-color: #f9f9f9;
+ border: 1px solid #D0D0D0;
+ color: #002166;
+ display: block;
+ margin: 14px 0 14px 0;
+ padding: 12px 10px 12px 10px;
+}
+
+</style>
+</head>
+<body>
+
+<h1>Welcome to CodeIgniter!</h1>
+
+<p>The page you are looking at is being generated dynamically by CodeIgniter.</p>
+
+<p>If you would like to edit this page you'll find it located at:</p>
+<code>system/application/views/welcome_message.php</code>
+
+<p>The corresponding controller for this page is found at:</p>
+<code>system/application/controllers/welcome.php</code>
+
+<p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>
+
+
+<p><br />Page rendered in {elapsed_time} seconds</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/cache/index.html b/system/cache/index.html
index 065d2da..c942a79 100644
--- a/system/cache/index.html
+++ b/system/cache/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/codeigniter/Base4.php b/system/codeigniter/Base4.php
index b242c00..a95c281 100644
--- a/system/codeigniter/Base4.php
+++ b/system/codeigniter/Base4.php
@@ -1,69 +1,69 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.3

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CI_BASE - For PHP 4

- *

- * This file is used only when CodeIgniter is being run under PHP 4.

- *

- * In order to allow CI to work under PHP 4 we had to make the Loader class

- * the parent of the Controller Base class.  It's the only way we can

- * enable functions like $this->load->library('email') to instantiate

- * classes that can then be used within controllers as $this->email->send()

- *

- * PHP 4 also has trouble referencing the CI super object within application

- * constructors since objects do not exist until the class is fully

- * instantiated.  Basically PHP 4 sucks...

- *

- * Since PHP 5 doesn't suffer from this problem so we load one of

- * two files based on the version of PHP being run.

- *

- * @package		CodeIgniter

- * @subpackage	codeigniter

- * @category	front-controller

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/

- */

- class CI_Base extends CI_Loader {

-

-	function CI_Base()

-	{

-		// This allows syntax like $this->load->foo() to work

-		parent::CI_Loader();

-		$this->load =& $this;

-		

-		// This allows resources used within controller constructors to work

-		global $OBJ;

-		$OBJ = $this->load; // Do NOT use a reference.

-	}

-}

-

-function &get_instance()

-{

-	global $CI, $OBJ;

-	

-	if (is_object($CI))

-	{

-		return $CI;

-	}

-	

-	return $OBJ->load;

-}

-

-

-/* End of file Base4.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.3
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CI_BASE - For PHP 4
+ *
+ * This file is used only when CodeIgniter is being run under PHP 4.
+ *
+ * In order to allow CI to work under PHP 4 we had to make the Loader class
+ * the parent of the Controller Base class.  It's the only way we can
+ * enable functions like $this->load->library('email') to instantiate
+ * classes that can then be used within controllers as $this->email->send()
+ *
+ * PHP 4 also has trouble referencing the CI super object within application
+ * constructors since objects do not exist until the class is fully
+ * instantiated.  Basically PHP 4 sucks...
+ *
+ * Since PHP 5 doesn't suffer from this problem so we load one of
+ * two files based on the version of PHP being run.
+ *
+ * @package		CodeIgniter
+ * @subpackage	codeigniter
+ * @category	front-controller
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/
+ */
+ class CI_Base extends CI_Loader {
+
+	function CI_Base()
+	{
+		// This allows syntax like $this->load->foo() to work
+		parent::CI_Loader();
+		$this->load =& $this;
+		
+		// This allows resources used within controller constructors to work
+		global $OBJ;
+		$OBJ = $this->load; // Do NOT use a reference.
+	}
+}
+
+function &get_instance()
+{
+	global $CI, $OBJ;
+	
+	if (is_object($CI))
+	{
+		return $CI;
+	}
+	
+	return $OBJ->load;
+}
+
+
+/* End of file Base4.php */
 /* Location: ./system/codeigniter/Base4.php */
\ No newline at end of file
diff --git a/system/codeigniter/Base5.php b/system/codeigniter/Base5.php
index 8dd3ad0..aa90355 100644
--- a/system/codeigniter/Base5.php
+++ b/system/codeigniter/Base5.php
@@ -1,56 +1,56 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.3

- * @filesource

- */

-

-

-// ------------------------------------------------------------------------

-

-/**

- * CI_BASE - For PHP 5

- *

- * This file contains some code used only when CodeIgniter is being

- * run under PHP 5.  It allows us to manage the CI super object more

- * gracefully than what is possible with PHP 4.

- *

- * @package		CodeIgniter

- * @subpackage	codeigniter

- * @category	front-controller

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/

- */

-

-class CI_Base {

-

-	private static $instance;

-

-	public function CI_Base()

-	{

-		self::$instance =& $this;

-	}

-

-	public static function &get_instance()

-	{

-		return self::$instance;

-	}

-}

-

-function &get_instance()

-{

-	return CI_Base::get_instance();

-}

-

-

-

-/* End of file Base5.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.3
+ * @filesource
+ */
+
+
+// ------------------------------------------------------------------------
+
+/**
+ * CI_BASE - For PHP 5
+ *
+ * This file contains some code used only when CodeIgniter is being
+ * run under PHP 5.  It allows us to manage the CI super object more
+ * gracefully than what is possible with PHP 4.
+ *
+ * @package		CodeIgniter
+ * @subpackage	codeigniter
+ * @category	front-controller
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/
+ */
+
+class CI_Base {
+
+	private static $instance;
+
+	public function CI_Base()
+	{
+		self::$instance =& $this;
+	}
+
+	public static function &get_instance()
+	{
+		return self::$instance;
+	}
+}
+
+function &get_instance()
+{
+	return CI_Base::get_instance();
+}
+
+
+
+/* End of file Base5.php */
 /* Location: ./system/codeigniter/Base5.php */
\ No newline at end of file
diff --git a/system/codeigniter/CodeIgniter.php b/system/codeigniter/CodeIgniter.php
index 27094d2..fa4bf77 100644
--- a/system/codeigniter/CodeIgniter.php
+++ b/system/codeigniter/CodeIgniter.php
@@ -1,276 +1,276 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * System Front Controller

- *

- * Loads the base classes and executes the request.

- *

- * @package		CodeIgniter

- * @subpackage	codeigniter

- * @category	Front-controller

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/

- */

-

-// CI Version

-define('CI_VERSION',	'1.7.0');

-

-/*

- * ------------------------------------------------------

- *  Load the global functions

- * ------------------------------------------------------

- */

-require(BASEPATH.'codeigniter/Common'.EXT);

-

-/*

- * ------------------------------------------------------

- *  Load the compatibility override functions

- * ------------------------------------------------------

- */

-require(BASEPATH.'codeigniter/Compat'.EXT);

-

-/*

- * ------------------------------------------------------

- *  Load the framework constants

- * ------------------------------------------------------

- */

-require(APPPATH.'config/constants'.EXT);

-

-/*

- * ------------------------------------------------------

- *  Define a custom error handler so we can log PHP errors

- * ------------------------------------------------------

- */

-set_error_handler('_exception_handler');

-set_magic_quotes_runtime(0); // Kill magic quotes

-

-/*

- * ------------------------------------------------------

- *  Start the timer... tick tock tick tock...

- * ------------------------------------------------------

- */

-

-$BM =& load_class('Benchmark');

-$BM->mark('total_execution_time_start');

-$BM->mark('loading_time_base_classes_start');

-

-/*

- * ------------------------------------------------------

- *  Instantiate the hooks class

- * ------------------------------------------------------

- */

-

-$EXT =& load_class('Hooks');

-

-/*

- * ------------------------------------------------------

- *  Is there a "pre_system" hook?

- * ------------------------------------------------------

- */

-$EXT->_call_hook('pre_system');

-

-/*

- * ------------------------------------------------------

- *  Instantiate the base classes

- * ------------------------------------------------------

- */

-

-$CFG =& load_class('Config');

-$URI =& load_class('URI');

-$RTR =& load_class('Router');

-$OUT =& load_class('Output');

-

-/*

- * ------------------------------------------------------

- *	Is there a valid cache file?  If so, we're done...

- * ------------------------------------------------------

- */

-

-if ($EXT->_call_hook('cache_override') === FALSE)

-{

-	if ($OUT->_display_cache($CFG, $URI) == TRUE)

-	{

-		exit;

-	}

-}

-

-/*

- * ------------------------------------------------------

- *  Load the remaining base classes

- * ------------------------------------------------------

- */

-

-$IN		=& load_class('Input');

-$LANG	=& load_class('Language');

-

-/*

- * ------------------------------------------------------

- *  Load the app controller and local controller

- * ------------------------------------------------------

- *

- *  Note: Due to the poor object handling in PHP 4 we'll

- *  conditionally load different versions of the base

- *  class.  Retaining PHP 4 compatibility requires a bit of a hack.

- *

- *  Note: The Loader class needs to be included first

- *

- */

-if (floor(phpversion()) < 5)

-{

-	load_class('Loader', FALSE);

-	require(BASEPATH.'codeigniter/Base4'.EXT);

-}

-else

-{

-	require(BASEPATH.'codeigniter/Base5'.EXT);

-}

-

-// Load the base controller class

-load_class('Controller', FALSE);

-

-// Load the local application controller

-// Note: The Router class automatically validates the controller path.  If this include fails it 

-// means that the default controller in the Routes.php file is not resolving to something valid.

-if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))

-{

-	show_error('Unable to load your default controller.  Please make sure the controller specified in your Routes.php file is valid.');

-}

-

-include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);

-

-// Set a mark point for benchmarking

-$BM->mark('loading_time_base_classes_end');

-

-

-/*

- * ------------------------------------------------------

- *  Security check

- * ------------------------------------------------------

- *

- *  None of the functions in the app controller or the

- *  loader class can be called via the URI, nor can

- *  controller functions that begin with an underscore

- */

-$class  = $RTR->fetch_class();

-$method = $RTR->fetch_method();

-

-if ( ! class_exists($class)

-	OR $method == 'controller'

-	OR strncmp($method, '_', 1) == 0

-	OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))

-	)

-{

-	show_404("{$class}/{$method}");

-}

-

-/*

- * ------------------------------------------------------

- *  Is there a "pre_controller" hook?

- * ------------------------------------------------------

- */

-$EXT->_call_hook('pre_controller');

-

-/*

- * ------------------------------------------------------

- *  Instantiate the controller and call requested method

- * ------------------------------------------------------

- */

-

-// Mark a start point so we can benchmark the controller

-$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');

-

-$CI = new $class();

-

-// Is this a scaffolding request?

-if ($RTR->scaffolding_request === TRUE)

-{

-	if ($EXT->_call_hook('scaffolding_override') === FALSE)

-	{

-		$CI->_ci_scaffolding();

-	}

-}

-else

-{

-	/*

-	 * ------------------------------------------------------

-	 *  Is there a "post_controller_constructor" hook?

-	 * ------------------------------------------------------

-	 */

-	$EXT->_call_hook('post_controller_constructor');

-	

-	// Is there a "remap" function?

-	if (method_exists($CI, '_remap'))

-	{

-		$CI->_remap($method);

-	}

-	else

-	{

-		// is_callable() returns TRUE on some versions of PHP 5 for private and protected

-		// methods, so we'll use this workaround for consistent behavior

-		if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))

-		{

-			show_404("{$class}/{$method}");

-		}

-

-		// Call the requested method.

-		// Any URI segments present (besides the class/function) will be passed to the method for convenience

-		call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));

-	}

-}

-

-// Mark a benchmark end point

-$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');

-

-/*

- * ------------------------------------------------------

- *  Is there a "post_controller" hook?

- * ------------------------------------------------------

- */

-$EXT->_call_hook('post_controller');

-

-/*

- * ------------------------------------------------------

- *  Send the final rendered output to the browser

- * ------------------------------------------------------

- */

-

-if ($EXT->_call_hook('display_override') === FALSE)

-{

-	$OUT->_display();

-}

-

-/*

- * ------------------------------------------------------

- *  Is there a "post_system" hook?

- * ------------------------------------------------------

- */

-$EXT->_call_hook('post_system');

-

-/*

- * ------------------------------------------------------

- *  Close the DB connection if one exists

- * ------------------------------------------------------

- */

-if (class_exists('CI_DB') AND isset($CI->db))

-{

-	$CI->db->close();

-}

-

-

-/* End of file CodeIgniter.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * System Front Controller
+ *
+ * Loads the base classes and executes the request.
+ *
+ * @package		CodeIgniter
+ * @subpackage	codeigniter
+ * @category	Front-controller
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/
+ */
+
+// CI Version
+define('CI_VERSION',	'1.7.0');
+
+/*
+ * ------------------------------------------------------
+ *  Load the global functions
+ * ------------------------------------------------------
+ */
+require(BASEPATH.'codeigniter/Common'.EXT);
+
+/*
+ * ------------------------------------------------------
+ *  Load the compatibility override functions
+ * ------------------------------------------------------
+ */
+require(BASEPATH.'codeigniter/Compat'.EXT);
+
+/*
+ * ------------------------------------------------------
+ *  Load the framework constants
+ * ------------------------------------------------------
+ */
+require(APPPATH.'config/constants'.EXT);
+
+/*
+ * ------------------------------------------------------
+ *  Define a custom error handler so we can log PHP errors
+ * ------------------------------------------------------
+ */
+set_error_handler('_exception_handler');
+set_magic_quotes_runtime(0); // Kill magic quotes
+
+/*
+ * ------------------------------------------------------
+ *  Start the timer... tick tock tick tock...
+ * ------------------------------------------------------
+ */
+
+$BM =& load_class('Benchmark');
+$BM->mark('total_execution_time_start');
+$BM->mark('loading_time_base_classes_start');
+
+/*
+ * ------------------------------------------------------
+ *  Instantiate the hooks class
+ * ------------------------------------------------------
+ */
+
+$EXT =& load_class('Hooks');
+
+/*
+ * ------------------------------------------------------
+ *  Is there a "pre_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_system');
+
+/*
+ * ------------------------------------------------------
+ *  Instantiate the base classes
+ * ------------------------------------------------------
+ */
+
+$CFG =& load_class('Config');
+$URI =& load_class('URI');
+$RTR =& load_class('Router');
+$OUT =& load_class('Output');
+
+/*
+ * ------------------------------------------------------
+ *	Is there a valid cache file?  If so, we're done...
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('cache_override') === FALSE)
+{
+	if ($OUT->_display_cache($CFG, $URI) == TRUE)
+	{
+		exit;
+	}
+}
+
+/*
+ * ------------------------------------------------------
+ *  Load the remaining base classes
+ * ------------------------------------------------------
+ */
+
+$IN		=& load_class('Input');
+$LANG	=& load_class('Language');
+
+/*
+ * ------------------------------------------------------
+ *  Load the app controller and local controller
+ * ------------------------------------------------------
+ *
+ *  Note: Due to the poor object handling in PHP 4 we'll
+ *  conditionally load different versions of the base
+ *  class.  Retaining PHP 4 compatibility requires a bit of a hack.
+ *
+ *  Note: The Loader class needs to be included first
+ *
+ */
+if (floor(phpversion()) < 5)
+{
+	load_class('Loader', FALSE);
+	require(BASEPATH.'codeigniter/Base4'.EXT);
+}
+else
+{
+	require(BASEPATH.'codeigniter/Base5'.EXT);
+}
+
+// Load the base controller class
+load_class('Controller', FALSE);
+
+// Load the local application controller
+// Note: The Router class automatically validates the controller path.  If this include fails it 
+// means that the default controller in the Routes.php file is not resolving to something valid.
+if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))
+{
+	show_error('Unable to load your default controller.  Please make sure the controller specified in your Routes.php file is valid.');
+}
+
+include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);
+
+// Set a mark point for benchmarking
+$BM->mark('loading_time_base_classes_end');
+
+
+/*
+ * ------------------------------------------------------
+ *  Security check
+ * ------------------------------------------------------
+ *
+ *  None of the functions in the app controller or the
+ *  loader class can be called via the URI, nor can
+ *  controller functions that begin with an underscore
+ */
+$class  = $RTR->fetch_class();
+$method = $RTR->fetch_method();
+
+if ( ! class_exists($class)
+	OR $method == 'controller'
+	OR strncmp($method, '_', 1) == 0
+	OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))
+	)
+{
+	show_404("{$class}/{$method}");
+}
+
+/*
+ * ------------------------------------------------------
+ *  Is there a "pre_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('pre_controller');
+
+/*
+ * ------------------------------------------------------
+ *  Instantiate the controller and call requested method
+ * ------------------------------------------------------
+ */
+
+// Mark a start point so we can benchmark the controller
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
+
+$CI = new $class();
+
+// Is this a scaffolding request?
+if ($RTR->scaffolding_request === TRUE)
+{
+	if ($EXT->_call_hook('scaffolding_override') === FALSE)
+	{
+		$CI->_ci_scaffolding();
+	}
+}
+else
+{
+	/*
+	 * ------------------------------------------------------
+	 *  Is there a "post_controller_constructor" hook?
+	 * ------------------------------------------------------
+	 */
+	$EXT->_call_hook('post_controller_constructor');
+	
+	// Is there a "remap" function?
+	if (method_exists($CI, '_remap'))
+	{
+		$CI->_remap($method);
+	}
+	else
+	{
+		// is_callable() returns TRUE on some versions of PHP 5 for private and protected
+		// methods, so we'll use this workaround for consistent behavior
+		if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
+		{
+			show_404("{$class}/{$method}");
+		}
+
+		// Call the requested method.
+		// Any URI segments present (besides the class/function) will be passed to the method for convenience
+		call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
+	}
+}
+
+// Mark a benchmark end point
+$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
+
+/*
+ * ------------------------------------------------------
+ *  Is there a "post_controller" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_controller');
+
+/*
+ * ------------------------------------------------------
+ *  Send the final rendered output to the browser
+ * ------------------------------------------------------
+ */
+
+if ($EXT->_call_hook('display_override') === FALSE)
+{
+	$OUT->_display();
+}
+
+/*
+ * ------------------------------------------------------
+ *  Is there a "post_system" hook?
+ * ------------------------------------------------------
+ */
+$EXT->_call_hook('post_system');
+
+/*
+ * ------------------------------------------------------
+ *  Close the DB connection if one exists
+ * ------------------------------------------------------
+ */
+if (class_exists('CI_DB') AND isset($CI->db))
+{
+	$CI->db->close();
+}
+
+
+/* End of file CodeIgniter.php */
 /* Location: ./system/codeigniter/CodeIgniter.php */
\ No newline at end of file
diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php
index 9212f07..3c75f5e 100644
--- a/system/codeigniter/Common.php
+++ b/system/codeigniter/Common.php
@@ -1,307 +1,307 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Common Functions

- *

- * Loads the base classes and executes the request.

- *

- * @package		CodeIgniter

- * @subpackage	codeigniter

- * @category	Common Functions

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Tests for file writability

- *

- * is_writable() returns TRUE on Windows servers when you really can't write to 

- * the file, based on the read-only attribute.  is_writable() is also unreliable

- * on Unix servers if safe_mode is on. 

- *

- * @access	private

- * @return	void

- */

-function is_really_writable($file)

-{	

-	// If we're on a Unix server with safe_mode off we call is_writable

-	if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)

-	{

-		return is_writable($file);

-	}

-

-	// For windows servers and safe_mode "on" installations we'll actually

-	// write a file then read it.  Bah...

-	if (is_dir($file))

-	{

-		$file = rtrim($file, '/').'/'.md5(rand(1,100));

-

-		if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)

-		{

-			return FALSE;

-		}

-

-		fclose($fp);

-		@chmod($file, DIR_WRITE_MODE);

-		@unlink($file);

-		return TRUE;

-	}

-	elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)

-	{

-		return FALSE;

-	}

-

-	fclose($fp);

-	return TRUE;

-}

-

-// ------------------------------------------------------------------------

-

-/**

-* Class registry

-*

-* This function acts as a singleton.  If the requested class does not

-* exist it is instantiated and set to a static variable.  If it has

-* previously been instantiated the variable is returned.

-*

-* @access	public

-* @param	string	the class name being requested

-* @param	bool	optional flag that lets classes get loaded but not instantiated

-* @return	object

-*/

-function &load_class($class, $instantiate = TRUE)

-{

-	static $objects = array();

-

-	// Does the class exist?  If so, we're done...

-	if (isset($objects[$class]))

-	{

-		return $objects[$class];

-	}

-

-	// If the requested class does not exist in the application/libraries

-	// folder we'll load the native class from the system/libraries folder.	

-	if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT))

-	{

-		require(BASEPATH.'libraries/'.$class.EXT);

-		require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT);

-		$is_subclass = TRUE;

-	}

-	else

-	{

-		if (file_exists(APPPATH.'libraries/'.$class.EXT))

-		{

-			require(APPPATH.'libraries/'.$class.EXT);

-			$is_subclass = FALSE;

-		}

-		else

-		{

-			require(BASEPATH.'libraries/'.$class.EXT);

-			$is_subclass = FALSE;

-		}

-	}

-

-	if ($instantiate == FALSE)

-	{

-		$objects[$class] = TRUE;

-		return $objects[$class];

-	}

-

-	if ($is_subclass == TRUE)

-	{

-		$name = config_item('subclass_prefix').$class;

-		$objects[$class] =& new $name();

-		return $objects[$class];

-	}

-

-	$name = ($class != 'Controller') ? 'CI_'.$class : $class;

-	

-	$objects[$class] =& new $name();

-	return $objects[$class];

-}

-

-/**

-* Loads the main config.php file

-*

-* @access	private

-* @return	array

-*/

-function &get_config()

-{

-	static $main_conf;

-

-	if ( ! isset($main_conf))

-	{

-		if ( ! file_exists(APPPATH.'config/config'.EXT))

-		{

-			exit('The configuration file config'.EXT.' does not exist.');

-		}

-

-		require(APPPATH.'config/config'.EXT);

-

-		if ( ! isset($config) OR ! is_array($config))

-		{

-			exit('Your config file does not appear to be formatted correctly.');

-		}

-

-		$main_conf[0] =& $config;

-	}

-	return $main_conf[0];

-}

-

-/**

-* Gets a config item

-*

-* @access	public

-* @return	mixed

-*/

-function config_item($item)

-{

-	static $config_item = array();

-

-	if ( ! isset($config_item[$item]))

-	{

-		$config =& get_config();

-

-		if ( ! isset($config[$item]))

-		{

-			return FALSE;

-		}

-		$config_item[$item] = $config[$item];

-	}

-

-	return $config_item[$item];

-}

-

-

-/**

-* Error Handler

-*

-* This function lets us invoke the exception class and

-* display errors using the standard error template located

-* in application/errors/errors.php

-* This function will send the error page directly to the

-* browser and exit.

-*

-* @access	public

-* @return	void

-*/

-function show_error($message)

-{

-	$error =& load_class('Exceptions');

-	echo $error->show_error('An Error Was Encountered', $message);

-	exit;

-}

-

-

-/**

-* 404 Page Handler

-*

-* This function is similar to the show_error() function above

-* However, instead of the standard error template it displays

-* 404 errors.

-*

-* @access	public

-* @return	void

-*/

-function show_404($page = '')

-{

-	$error =& load_class('Exceptions');

-	$error->show_404($page);

-	exit;

-}

-

-

-/**

-* Error Logging Interface

-*

-* We use this as a simple mechanism to access the logging

-* class and send messages to be logged.

-*

-* @access	public

-* @return	void

-*/

-function log_message($level = 'error', $message, $php_error = FALSE)

-{

-	static $LOG;

-	

-	$config =& get_config();

-	if ($config['log_threshold'] == 0)

-	{

-		return;

-	}

-

-	$LOG =& load_class('Log');

-	$LOG->write_log($level, $message, $php_error);

-}

-

-/**

-* Exception Handler

-*

-* This is the custom exception handler that is declaired at the top

-* of Codeigniter.php.  The main reason we use this is permit

-* PHP errors to be logged in our own log files since we may

-* not have access to server logs. Since this function

-* effectively intercepts PHP errors, however, we also need

-* to display errors based on the current error_reporting level.

-* We do that with the use of a PHP error template.

-*

-* @access	private

-* @return	void

-*/

-function _exception_handler($severity, $message, $filepath, $line)

-{	

-	 // We don't bother with "strict" notices since they will fill up

-	 // the log file with information that isn't normally very

-	 // helpful.  For example, if you are running PHP 5 and you

-	 // use version 4 style class functions (without prefixes

-	 // like "public", "private", etc.) you'll get notices telling

-	 // you that these have been deprecated.

-	

-	if ($severity == E_STRICT)

-	{

-		return;

-	}

-

-	$error =& load_class('Exceptions');

-

-	// Should we display the error?

-	// We'll get the current error_reporting level and add its bits

-	// with the severity bits to find out.

-	

-	if (($severity & error_reporting()) == $severity)

-	{

-		$error->show_php_error($severity, $message, $filepath, $line);

-	}

-	

-	// Should we log the error?  No?  We're done...

-	$config =& get_config();

-	if ($config['log_threshold'] == 0)

-	{

-		return;

-	}

-

-	$error->log_exception($severity, $message, $filepath, $line);

-}

-

-

-

-/* End of file Common.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Common Functions
+ *
+ * Loads the base classes and executes the request.
+ *
+ * @package		CodeIgniter
+ * @subpackage	codeigniter
+ * @category	Common Functions
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Tests for file writability
+ *
+ * is_writable() returns TRUE on Windows servers when you really can't write to 
+ * the file, based on the read-only attribute.  is_writable() is also unreliable
+ * on Unix servers if safe_mode is on. 
+ *
+ * @access	private
+ * @return	void
+ */
+function is_really_writable($file)
+{	
+	// If we're on a Unix server with safe_mode off we call is_writable
+	if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
+	{
+		return is_writable($file);
+	}
+
+	// For windows servers and safe_mode "on" installations we'll actually
+	// write a file then read it.  Bah...
+	if (is_dir($file))
+	{
+		$file = rtrim($file, '/').'/'.md5(rand(1,100));
+
+		if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
+		{
+			return FALSE;
+		}
+
+		fclose($fp);
+		@chmod($file, DIR_WRITE_MODE);
+		@unlink($file);
+		return TRUE;
+	}
+	elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
+	{
+		return FALSE;
+	}
+
+	fclose($fp);
+	return TRUE;
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Class registry
+*
+* This function acts as a singleton.  If the requested class does not
+* exist it is instantiated and set to a static variable.  If it has
+* previously been instantiated the variable is returned.
+*
+* @access	public
+* @param	string	the class name being requested
+* @param	bool	optional flag that lets classes get loaded but not instantiated
+* @return	object
+*/
+function &load_class($class, $instantiate = TRUE)
+{
+	static $objects = array();
+
+	// Does the class exist?  If so, we're done...
+	if (isset($objects[$class]))
+	{
+		return $objects[$class];
+	}
+
+	// If the requested class does not exist in the application/libraries
+	// folder we'll load the native class from the system/libraries folder.	
+	if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT))
+	{
+		require(BASEPATH.'libraries/'.$class.EXT);
+		require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT);
+		$is_subclass = TRUE;
+	}
+	else
+	{
+		if (file_exists(APPPATH.'libraries/'.$class.EXT))
+		{
+			require(APPPATH.'libraries/'.$class.EXT);
+			$is_subclass = FALSE;
+		}
+		else
+		{
+			require(BASEPATH.'libraries/'.$class.EXT);
+			$is_subclass = FALSE;
+		}
+	}
+
+	if ($instantiate == FALSE)
+	{
+		$objects[$class] = TRUE;
+		return $objects[$class];
+	}
+
+	if ($is_subclass == TRUE)
+	{
+		$name = config_item('subclass_prefix').$class;
+		$objects[$class] =& new $name();
+		return $objects[$class];
+	}
+
+	$name = ($class != 'Controller') ? 'CI_'.$class : $class;
+	
+	$objects[$class] =& new $name();
+	return $objects[$class];
+}
+
+/**
+* Loads the main config.php file
+*
+* @access	private
+* @return	array
+*/
+function &get_config()
+{
+	static $main_conf;
+
+	if ( ! isset($main_conf))
+	{
+		if ( ! file_exists(APPPATH.'config/config'.EXT))
+		{
+			exit('The configuration file config'.EXT.' does not exist.');
+		}
+
+		require(APPPATH.'config/config'.EXT);
+
+		if ( ! isset($config) OR ! is_array($config))
+		{
+			exit('Your config file does not appear to be formatted correctly.');
+		}
+
+		$main_conf[0] =& $config;
+	}
+	return $main_conf[0];
+}
+
+/**
+* Gets a config item
+*
+* @access	public
+* @return	mixed
+*/
+function config_item($item)
+{
+	static $config_item = array();
+
+	if ( ! isset($config_item[$item]))
+	{
+		$config =& get_config();
+
+		if ( ! isset($config[$item]))
+		{
+			return FALSE;
+		}
+		$config_item[$item] = $config[$item];
+	}
+
+	return $config_item[$item];
+}
+
+
+/**
+* Error Handler
+*
+* This function lets us invoke the exception class and
+* display errors using the standard error template located
+* in application/errors/errors.php
+* This function will send the error page directly to the
+* browser and exit.
+*
+* @access	public
+* @return	void
+*/
+function show_error($message)
+{
+	$error =& load_class('Exceptions');
+	echo $error->show_error('An Error Was Encountered', $message);
+	exit;
+}
+
+
+/**
+* 404 Page Handler
+*
+* This function is similar to the show_error() function above
+* However, instead of the standard error template it displays
+* 404 errors.
+*
+* @access	public
+* @return	void
+*/
+function show_404($page = '')
+{
+	$error =& load_class('Exceptions');
+	$error->show_404($page);
+	exit;
+}
+
+
+/**
+* Error Logging Interface
+*
+* We use this as a simple mechanism to access the logging
+* class and send messages to be logged.
+*
+* @access	public
+* @return	void
+*/
+function log_message($level = 'error', $message, $php_error = FALSE)
+{
+	static $LOG;
+	
+	$config =& get_config();
+	if ($config['log_threshold'] == 0)
+	{
+		return;
+	}
+
+	$LOG =& load_class('Log');
+	$LOG->write_log($level, $message, $php_error);
+}
+
+/**
+* Exception Handler
+*
+* This is the custom exception handler that is declaired at the top
+* of Codeigniter.php.  The main reason we use this is permit
+* PHP errors to be logged in our own log files since we may
+* not have access to server logs. Since this function
+* effectively intercepts PHP errors, however, we also need
+* to display errors based on the current error_reporting level.
+* We do that with the use of a PHP error template.
+*
+* @access	private
+* @return	void
+*/
+function _exception_handler($severity, $message, $filepath, $line)
+{	
+	 // We don't bother with "strict" notices since they will fill up
+	 // the log file with information that isn't normally very
+	 // helpful.  For example, if you are running PHP 5 and you
+	 // use version 4 style class functions (without prefixes
+	 // like "public", "private", etc.) you'll get notices telling
+	 // you that these have been deprecated.
+	
+	if ($severity == E_STRICT)
+	{
+		return;
+	}
+
+	$error =& load_class('Exceptions');
+
+	// Should we display the error?
+	// We'll get the current error_reporting level and add its bits
+	// with the severity bits to find out.
+	
+	if (($severity & error_reporting()) == $severity)
+	{
+		$error->show_php_error($severity, $message, $filepath, $line);
+	}
+	
+	// Should we log the error?  No?  We're done...
+	$config =& get_config();
+	if ($config['log_threshold'] == 0)
+	{
+		return;
+	}
+
+	$error->log_exception($severity, $message, $filepath, $line);
+}
+
+
+
+/* End of file Common.php */
 /* Location: ./system/codeigniter/Common.php */
\ No newline at end of file
diff --git a/system/codeigniter/Compat.php b/system/codeigniter/Compat.php
index 291f01d..6100956 100644
--- a/system/codeigniter/Compat.php
+++ b/system/codeigniter/Compat.php
@@ -1,93 +1,93 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Compatibility Functions

- *

- * Function overrides for older versions of PHP or PHP environments missing

- * certain extensions / libraries

- *

- * @package		CodeIgniter

- * @subpackage	codeigniter

- * @category	Compatibility Functions

- * @author		ExpressionEngine Development Team

- * @link		http://codeigniter.com/user_guide/

- */

-

-// ------------------------------------------------------------------------

-

-/*

- * PHP versions prior to 5.0 don't support the E_STRICT constant

- * so we need to explicitly define it otherwise the Exception class 

- * will generate errors when running under PHP 4

- *

- */

-if ( ! defined('E_STRICT'))

-{

-	define('E_STRICT', 2048);

-}

-

-/**

- * ctype_digit()

- *

- * Determines if a string is comprised only of digits

- * http://us.php.net/manual/en/function.ctype_digit.php

- *

- * @access	public

- * @param	string

- * @return	bool

- */

-if ( ! function_exists('ctype_digit'))

-{

-	function ctype_digit($str)

-	{

-		if ( ! is_string($str) OR $str == '')

-		{

-			return FALSE;

-		}

-		

-		return ! preg_match('/[^0-9]/', $str);

-	}	

-}

-

-// --------------------------------------------------------------------

-

-/**

- * ctype_alnum()

- *

- * Determines if a string is comprised of only alphanumeric characters

- * http://us.php.net/manual/en/function.ctype-alnum.php

- *

- * @access	public

- * @param	string

- * @return	bool

- */

-if ( ! function_exists('ctype_alnum'))

-{

-	function ctype_alnum($str)

-	{

-		if ( ! is_string($str) OR $str == '')

-		{

-			return FALSE;

-		}

-		

-		return ! preg_match('/[^0-9a-z]/i', $str);

-	}	

-}

-

-/* End of file Compat.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Compatibility Functions
+ *
+ * Function overrides for older versions of PHP or PHP environments missing
+ * certain extensions / libraries
+ *
+ * @package		CodeIgniter
+ * @subpackage	codeigniter
+ * @category	Compatibility Functions
+ * @author		ExpressionEngine Development Team
+ * @link		http://codeigniter.com/user_guide/
+ */
+
+// ------------------------------------------------------------------------
+
+/*
+ * PHP versions prior to 5.0 don't support the E_STRICT constant
+ * so we need to explicitly define it otherwise the Exception class 
+ * will generate errors when running under PHP 4
+ *
+ */
+if ( ! defined('E_STRICT'))
+{
+	define('E_STRICT', 2048);
+}
+
+/**
+ * ctype_digit()
+ *
+ * Determines if a string is comprised only of digits
+ * http://us.php.net/manual/en/function.ctype_digit.php
+ *
+ * @access	public
+ * @param	string
+ * @return	bool
+ */
+if ( ! function_exists('ctype_digit'))
+{
+	function ctype_digit($str)
+	{
+		if ( ! is_string($str) OR $str == '')
+		{
+			return FALSE;
+		}
+		
+		return ! preg_match('/[^0-9]/', $str);
+	}	
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * ctype_alnum()
+ *
+ * Determines if a string is comprised of only alphanumeric characters
+ * http://us.php.net/manual/en/function.ctype-alnum.php
+ *
+ * @access	public
+ * @param	string
+ * @return	bool
+ */
+if ( ! function_exists('ctype_alnum'))
+{
+	function ctype_alnum($str)
+	{
+		if ( ! is_string($str) OR $str == '')
+		{
+			return FALSE;
+		}
+		
+		return ! preg_match('/[^0-9a-z]/i', $str);
+	}	
+}
+
+/* End of file Compat.php */
 /* Location: ./system/codeigniter/Compat.php */
\ No newline at end of file
diff --git a/system/codeigniter/index.html b/system/codeigniter/index.html
index 065d2da..c942a79 100644
--- a/system/codeigniter/index.html
+++ b/system/codeigniter/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/DB.php b/system/database/DB.php
index 2b3ff3d..ca0cfc2 100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -1,146 +1,146 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Initialize the database

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-function &DB($params = '', $active_record_override = FALSE)

-{

-	// Load the DB config file if a DSN string wasn't passed

-	if (is_string($params) AND strpos($params, '://') === FALSE)

-	{

-		include(APPPATH.'config/database'.EXT);

-		

-		if ( ! isset($db) OR count($db) == 0)

-		{

-			show_error('No database connection settings were found in the database config file.');

-		}

-		

-		if ($params != '')

-		{

-			$active_group = $params;

-		}

-		

-		if ( ! isset($active_group) OR ! isset($db[$active_group]))

-		{

-			show_error('You have specified an invalid database connection group.');

-		}

-		

-		$params = $db[$active_group];

-	}

-	elseif (is_string($params))

-	{

-		

-		/* parse the URL from the DSN string

-		*  Database settings can be passed as discreet

-	 	*  parameters or as a data source name in the first

-	 	*  parameter. DSNs must have this prototype:

-	 	*  $dsn = 'driver://username:password@hostname/database';

-		*/

-	

-		if (($dns = @parse_url($params)) === FALSE)

-		{

-			show_error('Invalid DB Connection String');

-		}

-		

-		$params = array(

-							'dbdriver'	=> $dns['scheme'],

-							'hostname'	=> (isset($dns['host'])) ? rawurldecode($dns['host']) : '',

-							'username'	=> (isset($dns['user'])) ? rawurldecode($dns['user']) : '',

-							'password'	=> (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',

-							'database'	=> (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''

-						);

-		

-		// were additional config items set?

-		if (isset($dns['query']))

-		{

-			parse_str($dns['query'], $extra);

-

-			foreach($extra as $key => $val)

-			{

-				// booleans please

-				if (strtoupper($val) == "TRUE")

-				{

-					$val = TRUE;

-				}

-				elseif (strtoupper($val) == "FALSE")

-				{

-					$val = FALSE;

-				}

-

-				$params[$key] = $val;

-			}

-		}

-	}

-	

-	// No DB specified yet?  Beat them senseless...

-	if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')

-	{

-		show_error('You have not selected a database type to connect to.');

-	}

-

-	// Load the DB classes.  Note: Since the active record class is optional

-	// we need to dynamically create a class that extends proper parent class

-	// based on whether we're using the active record class or not.

-	// Kudos to Paul for discovering this clever use of eval()

-	

-	if ($active_record_override == TRUE)

-	{

-		$active_record = TRUE;

-	}

-	

-	require_once(BASEPATH.'database/DB_driver'.EXT);

-

-	if ( ! isset($active_record) OR $active_record == TRUE)

-	{

-		require_once(BASEPATH.'database/DB_active_rec'.EXT);

-		

-		if ( ! class_exists('CI_DB'))

-		{

-			eval('class CI_DB extends CI_DB_active_record { }');

-		}

-	}

-	else

-	{

-		if ( ! class_exists('CI_DB'))

-		{

-			eval('class CI_DB extends CI_DB_driver { }');

-		}

-	}

-			

-	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);

-

-	// Instantiate the DB adapter

-	$driver = 'CI_DB_'.$params['dbdriver'].'_driver';

-	$DB =& new $driver($params);

-	

-	if ($DB->autoinit == TRUE)

-	{

-		$DB->initialize();

-	}

-	

-	return $DB;

-}	

-

-

-

-/* End of file DB.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Initialize the database
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+function &DB($params = '', $active_record_override = FALSE)
+{
+	// Load the DB config file if a DSN string wasn't passed
+	if (is_string($params) AND strpos($params, '://') === FALSE)
+	{
+		include(APPPATH.'config/database'.EXT);
+		
+		if ( ! isset($db) OR count($db) == 0)
+		{
+			show_error('No database connection settings were found in the database config file.');
+		}
+		
+		if ($params != '')
+		{
+			$active_group = $params;
+		}
+		
+		if ( ! isset($active_group) OR ! isset($db[$active_group]))
+		{
+			show_error('You have specified an invalid database connection group.');
+		}
+		
+		$params = $db[$active_group];
+	}
+	elseif (is_string($params))
+	{
+		
+		/* parse the URL from the DSN string
+		*  Database settings can be passed as discreet
+	 	*  parameters or as a data source name in the first
+	 	*  parameter. DSNs must have this prototype:
+	 	*  $dsn = 'driver://username:password@hostname/database';
+		*/
+	
+		if (($dns = @parse_url($params)) === FALSE)
+		{
+			show_error('Invalid DB Connection String');
+		}
+		
+		$params = array(
+							'dbdriver'	=> $dns['scheme'],
+							'hostname'	=> (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
+							'username'	=> (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
+							'password'	=> (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
+							'database'	=> (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''
+						);
+		
+		// were additional config items set?
+		if (isset($dns['query']))
+		{
+			parse_str($dns['query'], $extra);
+
+			foreach($extra as $key => $val)
+			{
+				// booleans please
+				if (strtoupper($val) == "TRUE")
+				{
+					$val = TRUE;
+				}
+				elseif (strtoupper($val) == "FALSE")
+				{
+					$val = FALSE;
+				}
+
+				$params[$key] = $val;
+			}
+		}
+	}
+	
+	// No DB specified yet?  Beat them senseless...
+	if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
+	{
+		show_error('You have not selected a database type to connect to.');
+	}
+
+	// Load the DB classes.  Note: Since the active record class is optional
+	// we need to dynamically create a class that extends proper parent class
+	// based on whether we're using the active record class or not.
+	// Kudos to Paul for discovering this clever use of eval()
+	
+	if ($active_record_override == TRUE)
+	{
+		$active_record = TRUE;
+	}
+	
+	require_once(BASEPATH.'database/DB_driver'.EXT);
+
+	if ( ! isset($active_record) OR $active_record == TRUE)
+	{
+		require_once(BASEPATH.'database/DB_active_rec'.EXT);
+		
+		if ( ! class_exists('CI_DB'))
+		{
+			eval('class CI_DB extends CI_DB_active_record { }');
+		}
+	}
+	else
+	{
+		if ( ! class_exists('CI_DB'))
+		{
+			eval('class CI_DB extends CI_DB_driver { }');
+		}
+	}
+			
+	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
+
+	// Instantiate the DB adapter
+	$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
+	$DB =& new $driver($params);
+	
+	if ($DB->autoinit == TRUE)
+	{
+		$DB->initialize();
+	}
+	
+	return $DB;
+}	
+
+
+
+/* End of file DB.php */
 /* Location: ./system/database/DB.php */
\ No newline at end of file
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index b270b6f..e8cefa2 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -1,1814 +1,1814 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Active Record Class

- *

- * This is the platform-independent base Active Record implementation class.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_active_record extends CI_DB_driver {

-

-	var $ar_select				= array();

-	var $ar_distinct			= FALSE;

-	var $ar_from				= array();

-	var $ar_join				= array();

-	var $ar_where				= array();

-	var $ar_like				= array();

-	var $ar_groupby				= array();

-	var $ar_having				= array();

-	var $ar_limit				= FALSE;

-	var $ar_offset				= FALSE;

-	var $ar_order				= FALSE;

-	var $ar_orderby				= array();

-	var $ar_set					= array();	

-	var $ar_wherein				= array();

-	var $ar_aliased_tables		= array();

-	var $ar_store_array			= array();

-	

-	// Active Record Caching variables

-	var $ar_caching 			= FALSE;

-	var $ar_cache_exists		= array();

-	var $ar_cache_select		= array();

-	var $ar_cache_from			= array();

-	var $ar_cache_join			= array();

-	var $ar_cache_where			= array();

-	var $ar_cache_like			= array();

-	var $ar_cache_groupby		= array();

-	var $ar_cache_having		= array();

-	var $ar_cache_orderby		= array();

-	var $ar_cache_set			= array();	

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select

-	 *

-	 * Generates the SELECT portion of the query

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	object

-	 */

-	function select($select = '*', $escape = NULL)

-	{

-		// Set the global value if this was sepecified	

-		if (is_bool($escape))

-		{

-			$this->_protect_identifiers = $escape;

-		}

-		

-		if (is_string($select))

-		{

-			$select = explode(',', $select);

-		}

-

-		foreach ($select as $val)

-		{

-			$val = trim($val);

-

-			if ($val != '')

-			{

-				$this->ar_select[] = $val;

-

-				if ($this->ar_caching === TRUE)

-				{

-					$this->ar_cache_select[] = $val;

-					$this->ar_cache_exists[] = 'select';

-				}

-			}

-		}

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select Max

-	 *

-	 * Generates a SELECT MAX(field) portion of a query

-	 *

-	 * @access	public

-	 * @param	string	the field

-	 * @param	string	an alias

-	 * @return	object

-	 */

-	function select_max($select = '', $alias = '')

-	{

-		return $this->_max_min_avg_sum($select, $alias, 'MAX');

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select Min

-	 *

-	 * Generates a SELECT MIN(field) portion of a query

-	 *

-	 * @access	public

-	 * @param	string	the field

-	 * @param	string	an alias

-	 * @return	object

-	 */

-	function select_min($select = '', $alias = '')

-	{

-		return $this->_max_min_avg_sum($select, $alias, 'MIN');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select Average

-	 *

-	 * Generates a SELECT AVG(field) portion of a query

-	 *

-	 * @access	public

-	 * @param	string	the field

-	 * @param	string	an alias

-	 * @return	object

-	 */

-	function select_avg($select = '', $alias = '')

-	{

-		return $this->_max_min_avg_sum($select, $alias, 'AVG');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select Sum

-	 *

-	 * Generates a SELECT SUM(field) portion of a query

-	 *

-	 * @access	public

-	 * @param	string	the field

-	 * @param	string	an alias

-	 * @return	object

-	 */

-	function select_sum($select = '', $alias = '')

-	{

-		return $this->_max_min_avg_sum($select, $alias, 'SUM');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Processing Function for the four functions above:

-	 *

-	 *	select_max()

-	 *	select_min()

-	 *	select_avg()

-	 *  select_sum()

-	 *	

-	 * @access	public

-	 * @param	string	the field

-	 * @param	string	an alias

-	 * @return	object

-	 */

-	function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')

-	{

-		if ( ! is_string($select) OR $select == '')

-		{

-			$this->display_error('db_invalid_query');

-		}

-	

-		$type = strtoupper($type);

-	

-		if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))

-		{

-			show_error('Invalid function type: '.$type);

-		}

-	

-		if ($alias == '')

-		{

-			$alias = $this->_create_alias_from_table(trim($select));

-		}

-	

-		$sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;

-

-		$this->ar_select[] = $sql;

-		

-		if ($this->ar_caching === TRUE)

-		{

-			$this->ar_cache_select[] = $sql;

-			$this->ar_cache_exists[] = 'select';

-		}

-		

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determines the alias name based on the table

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _create_alias_from_table($item)

-	{

-		if (strpos($item, '.') !== FALSE)

-		{

-			return end(explode('.', $item));

-		}

-		

-		return $item;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * DISTINCT

-	 *

-	 * Sets a flag which tells the query string compiler to add DISTINCT

-	 *

-	 * @access	public

-	 * @param	bool

-	 * @return	object

-	 */

-	function distinct($val = TRUE)

-	{

-		$this->ar_distinct = (is_bool($val)) ? $val : TRUE;

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * From

-	 *

-	 * Generates the FROM portion of the query

-	 *

-	 * @access	public

-	 * @param	mixed	can be a string or array

-	 * @return	object

-	 */

-	function from($from)

-	{

-		foreach ((array)$from as $val)

-		{

-			if (strpos($val, ',') !== FALSE)

-			{

-				foreach (explode(',', $val) as $v)

-				{

-					$v = trim($v);

-					$this->_track_aliases($v);

-

-					$this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);

-					

-					if ($this->ar_caching === TRUE)

-					{

-						$this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);

-						$this->ar_cache_exists[] = 'from';

-					}				

-				}

-

-			}

-			else

-			{

-				$val = trim($val);

-

-				// Extract any aliases that might exist.  We use this information

-				// in the _protect_identifiers to know whether to add a table prefix 

-				$this->_track_aliases($val);

-	

-				$this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);

-				

-				if ($this->ar_caching === TRUE)

-				{

-					$this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);

-					$this->ar_cache_exists[] = 'from';

-				}

-			}

-		}

-

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Join

-	 *

-	 * Generates the JOIN portion of the query

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string	the join condition

-	 * @param	string	the type of join

-	 * @return	object

-	 */

-	function join($table, $cond, $type = '')

-	{		

-		if ($type != '')

-		{

-			$type = strtoupper(trim($type));

-

-			if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))

-			{

-				$type = '';

-			}

-			else

-			{

-				$type .= ' ';

-			}

-		}

-

-		// Extract any aliases that might exist.  We use this information

-		// in the _protect_identifiers to know whether to add a table prefix 

-		$this->_track_aliases($table);

-

-		// Strip apart the condition and protect the identifiers

-		if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))

-		{

-			$match[1] = $this->_protect_identifiers($match[1]);

-			$match[3] = $this->_protect_identifiers($match[3]);

-		

-			$cond = $match[1].$match[2].$match[3];		

-		}

-		

-		// Assemble the JOIN statement

-		$join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;

-

-		$this->ar_join[] = $join;

-		if ($this->ar_caching === TRUE)

-		{

-			$this->ar_cache_join[] = $join;

-			$this->ar_cache_exists[] = 'join';

-		}

-

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where

-	 *

-	 * Generates the WHERE portion of the query. Separates

-	 * multiple calls with AND

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function where($key, $value = NULL, $escape = TRUE)

-	{

-		return $this->_where($key, $value, 'AND ', $escape);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * OR Where

-	 *

-	 * Generates the WHERE portion of the query. Separates

-	 * multiple calls with OR

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function or_where($key, $value = NULL, $escape = TRUE)

-	{

-		return $this->_where($key, $value, 'OR ', $escape);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * orwhere() is an alias of or_where()

-	 * this function is here for backwards compatibility, as

-	 * orwhere() has been deprecated

-	 */

-	function orwhere($key, $value = NULL, $escape = TRUE)

-	{

-		return $this->or_where($key, $value, $escape);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where

-	 *

-	 * Called by where() or orwhere()

-	 *

-	 * @access	private

-	 * @param	mixed

-	 * @param	mixed

-	 * @param	string

-	 * @return	object

-	 */

-	function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)

-	{

-		if ( ! is_array($key))

-		{

-			$key = array($key => $value);

-		}

-		

-		// If the escape value was not set will will base it on the global setting

-		if ( ! is_bool($escape))

-		{

-			$escape = $this->_protect_identifiers;

-		}

-

-		foreach ($key as $k => $v)

-		{

-			$prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;

-

-			if (is_null($v) && ! $this->_has_operator($k))

-			{

-				// value appears not to have been set, assign the test to IS NULL

-				$k .= ' IS NULL';

-			}

-			

-			if ( ! is_null($v))

-			{

-				if ($escape === TRUE)

-				{

-					$k = $this->_protect_identifiers($k, FALSE, $escape);

-					

-					$v = ' '.$this->escape($v);

-				}

-

-				if ( ! $this->_has_operator($k))

-				{

-					$k .= ' =';

-				}

-			}

-			else

-			{

-				$k = $this->_protect_identifiers($k, FALSE, $escape);			

-			}

-

-			$this->ar_where[] = $prefix.$k.$v;

-			

-			if ($this->ar_caching === TRUE)

-			{

-				$this->ar_cache_where[] = $prefix.$k.$v;

-				$this->ar_cache_exists[] = 'where';

-			}

-			

-		}

-		

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where_in

-	 *

-	 * Generates a WHERE field IN ('item', 'item') SQL query joined with

-	 * AND if appropriate

-	 *

-	 * @access	public

-	 * @param	string	The field to search

-	 * @param	array	The values searched on

-	 * @return	object

-	 */

-	function where_in($key = NULL, $values = NULL)

-	{

-		return $this->_where_in($key, $values);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where_in_or

-	 *

-	 * Generates a WHERE field IN ('item', 'item') SQL query joined with

-	 * OR if appropriate

-	 *

-	 * @access	public

-	 * @param	string	The field to search

-	 * @param	array	The values searched on

-	 * @return	object

-	 */

-	function or_where_in($key = NULL, $values = NULL)

-	{

-		return $this->_where_in($key, $values, FALSE, 'OR ');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where_not_in

-	 *

-	 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined

-	 * with AND if appropriate

-	 *

-	 * @access	public

-	 * @param	string	The field to search

-	 * @param	array	The values searched on

-	 * @return	object

-	 */

-	function where_not_in($key = NULL, $values = NULL)

-	{

-		return $this->_where_in($key, $values, TRUE);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where_not_in_or

-	 *

-	 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined

-	 * with OR if appropriate

-	 *

-	 * @access	public

-	 * @param	string	The field to search

-	 * @param	array	The values searched on

-	 * @return	object

-	 */

-	function or_where_not_in($key = NULL, $values = NULL)

-	{

-		return $this->_where_in($key, $values, TRUE, 'OR ');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Where_in

-	 *

-	 * Called by where_in, where_in_or, where_not_in, where_not_in_or

-	 *

-	 * @access	public

-	 * @param	string	The field to search

-	 * @param	array	The values searched on

-	 * @param	boolean	If the statement would be IN or NOT IN

-	 * @param	string	

-	 * @return	object

-	 */

-	function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')

-	{

-		if ($key === NULL OR $values === NULL)

-		{

-			return;

-		}

-		

-		if ( ! is_array($values))

-		{

-			$values = array($values);

-		}

-		

-		$not = ($not) ? ' NOT' : '';

-

-		foreach ($values as $value)

-		{

-			$this->ar_wherein[] = $this->escape($value);

-		}

-

-		$prefix = (count($this->ar_where) == 0) ? '' : $type;

- 

-		$where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";

-

-		$this->ar_where[] = $where_in;

-		if ($this->ar_caching === TRUE)

-		{

-			$this->ar_cache_where[] = $where_in;

-			$this->ar_cache_exists[] = 'where';

-		}

-

-		// reset the array for multiple calls

-		$this->ar_wherein = array();

-		return $this;

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Like

-	 *

-	 * Generates a %LIKE% portion of the query. Separates

-	 * multiple calls with AND

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function like($field, $match = '', $side = 'both')

-	{

-		return $this->_like($field, $match, 'AND ', $side);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Not Like

-	 *

-	 * Generates a NOT LIKE portion of the query. Separates

-	 * multiple calls with AND

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function not_like($field, $match = '', $side = 'both')

-	{

-		return $this->_like($field, $match, 'AND ', $side, 'NOT');

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * OR Like

-	 *

-	 * Generates a %LIKE% portion of the query. Separates

-	 * multiple calls with OR

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function or_like($field, $match = '', $side = 'both')

-	{

-		return $this->_like($field, $match, 'OR ', $side);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * OR Not Like

-	 *

-	 * Generates a NOT LIKE portion of the query. Separates

-	 * multiple calls with OR

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @return	object

-	 */

-	function or_not_like($field, $match = '', $side = 'both')

-	{

-		return $this->_like($field, $match, 'OR ', $side, 'NOT');

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * orlike() is an alias of or_like()

-	 * this function is here for backwards compatibility, as

-	 * orlike() has been deprecated

-	 */

-	function orlike($field, $match = '', $side = 'both')

-	{

-		return $this->or_like($field, $match, $side);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Like

-	 *

-	 * Called by like() or orlike()

-	 *

-	 * @access	private

-	 * @param	mixed

-	 * @param	mixed

-	 * @param	string

-	 * @return	object

-	 */

-	function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')

-	{

-		if ( ! is_array($field))

-		{

-			$field = array($field => $match);

-		}

- 	

-		foreach ($field as $k => $v)

-		{

-			$k = $this->_protect_identifiers($k);

-

-			$prefix = (count($this->ar_like) == 0) ? '' : $type;

-

-			$v = $this->escape_str($v);

-

-			if ($side == 'before')

-			{

-				$like_statement = $prefix." $k $not LIKE '%{$v}'";

-			}

-			elseif ($side == 'after')

-			{

-				$like_statement = $prefix." $k $not LIKE '{$v}%'";

-			}

-			else

-			{

-				$like_statement = $prefix." $k $not LIKE '%{$v}%'";

-			}

-			

-			$this->ar_like[] = $like_statement;

-			if ($this->ar_caching === TRUE)

-			{

-				$this->ar_cache_like[] = $like_statement;

-				$this->ar_cache_exists[] = 'like';

-			}

-			

-		}

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * GROUP BY

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	object

-	 */

-	function group_by($by)

-	{

-		if (is_string($by))

-		{

-			$by = explode(',', $by);

-		}

-	

-		foreach ($by as $val)

-		{

-			$val = trim($val);

-		

-			if ($val != '')

-			{

-				$this->ar_groupby[] = $this->_protect_identifiers($val);

-				

-				if ($this->ar_caching === TRUE)

-				{

-					$this->ar_cache_groupby[] = $this->_protect_identifiers($val);

-					$this->ar_cache_exists[] = 'groupby';

-				}

-			}

-		}

-		return $this;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * groupby() is an alias of group_by()

-	 * this function is here for backwards compatibility, as

-	 * groupby() has been deprecated

-	 */

-	function groupby($by)

-	{

-		return $this->group_by($by);

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the HAVING value

-	 *

-	 * Separates multiple calls with AND

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	object

-	 */

-	function having($key, $value = '', $escape = TRUE)

-	{

-		return $this->_having($key, $value, 'AND ', $escape);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * orhaving() is an alias of or_having()

-	 * this function is here for backwards compatibility, as

-	 * orhaving() has been deprecated

-	 */

-

-	function orhaving($key, $value = '', $escape = TRUE)

-	{

-		return $this->or_having($key, $value, $escape);

-	}	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the OR HAVING value

-	 *

-	 * Separates multiple calls with OR

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	object

-	 */

-	function or_having($key, $value = '', $escape = TRUE)

-	{

-		return $this->_having($key, $value, 'OR ', $escape);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the HAVING values

-	 *

-	 * Called by having() or or_having()

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	object

-	 */

-	function _having($key, $value = '', $type = 'AND ', $escape = TRUE)

-	{

-		if ( ! is_array($key))

-		{

-			$key = array($key => $value);

-		}

-	

-		foreach ($key as $k => $v)

-		{

-			$prefix = (count($this->ar_having) == 0) ? '' : $type;

-

-			if ($escape === TRUE)

-			{

-				$k = $this->_protect_identifiers($k);

-			}

-

-			if ( ! $this->_has_operator($k))

-			{

-				$k .= ' = ';

-			}

-

-			if ($v != '')

-			{

-				$v = ' '.$this->escape_str($v);

-			}

-			

-			$this->ar_having[] = $prefix.$k.$v;

-			if ($this->ar_caching === TRUE)

-			{

-				$this->ar_cache_having[] = $prefix.$k.$v;

-				$this->ar_cache_exists[] = 'having';

-			}

-		}

-		

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the ORDER BY value

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string	direction: asc or desc

-	 * @return	object

-	 */

-	function order_by($orderby, $direction = '')

-	{

-		if (strtolower($direction) == 'random')

-		{

-			$orderby = ''; // Random results want or don't need a field name

-			$direction = $this->_random_keyword;

-		}

-		elseif (trim($direction) != '')

-		{

-			$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';

-		}

-	

-	

-		if (strpos($orderby, ',') !== FALSE)

-		{

-			$temp = array();

-			foreach (explode(',', $orderby) as $part)

-			{

-				$part = trim($part);

-				if ( ! in_array($part, $this->ar_aliased_tables))

-				{

-					$part = $this->_protect_identifiers(trim($part));

-				}

-				

-				$temp[] = $part;

-			}

-			

-			$orderby = implode(', ', $temp);			

-		}

-		else

-		{

-			$orderby = $this->_protect_identifiers($orderby);

-		}

-	

-		$orderby_statement = $orderby.$direction;

-		

-		$this->ar_orderby[] = $orderby_statement;

-		if ($this->ar_caching === TRUE)

-		{

-			$this->ar_cache_orderby[] = $orderby_statement;

-			$this->ar_cache_exists[] = 'orderby';

-		}

-

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * orderby() is an alias of order_by()

-	 * this function is here for backwards compatibility, as

-	 * orderby() has been deprecated

-	 */

-	function orderby($orderby, $direction = '')

-	{

-		return $this->order_by($orderby, $direction);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the LIMIT value

-	 *

-	 * @access	public

-	 * @param	integer	the limit value

-	 * @param	integer	the offset value

-	 * @return	object

-	 */

-	function limit($value, $offset = '')

-	{

-		$this->ar_limit = $value;

-

-		if ($offset != '')

-		{

-			$this->ar_offset = $offset;

-		}

-		

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Sets the OFFSET value

-	 *

-	 * @access	public

-	 * @param	integer	the offset value

-	 * @return	object

-	 */

-	function offset($offset)

-	{

-		$this->ar_offset = $offset;

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The "set" function.  Allows key/value pairs to be set for inserting or updating

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @param	boolean

-	 * @return	object

-	 */

-	function set($key, $value = '', $escape = TRUE)

-	{

-		$key = $this->_object_to_array($key);

-	

-		if ( ! is_array($key))

-		{

-			$key = array($key => $value);

-		}	

-

-		foreach ($key as $k => $v)

-		{

-			if ($escape === FALSE)

-			{

-				$this->ar_set[$this->_protect_identifiers($k)] = $v;

-			}

-			else

-			{

-				$this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);

-			}

-		}

-		

-		return $this;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get

-	 *

-	 * Compiles the select statement based on the other functions called

-	 * and runs the query

-	 *

-	 * @access	public

-	 * @param	string	the table

-	 * @param	string	the limit clause

-	 * @param	string	the offset clause

-	 * @return	object

-	 */

-	function get($table = '', $limit = null, $offset = null)

-	{

-		if ($table != '')

-		{

-			$this->_track_aliases($table);

-			$this->from($table);

-		}

-		

-		if ( ! is_null($limit))

-		{

-			$this->limit($limit, $offset);

-		}

-			

-		$sql = $this->_compile_select();

-

-		$result = $this->query($sql);

-		$this->_reset_select();

-		return $result;

-	}

-

-	/**

-	 * "Count All Results" query

-	 *

-	 * Generates a platform-specific query string that counts all records 

-	 * returned by an Active Record query.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all_results($table = '')

-	{

-		if ($table != '')

-		{

-			$this->_track_aliases($table);

-			$this->from($table);

-		}

-		

-		$sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));

-

-		$query = $this->query($sql);

-		$this->_reset_select();

-	

-		if ($query->num_rows() == 0)

-		{

-			return '0';

-		}

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get_Where

-	 *

-	 * Allows the where clause, limit and offset to be added directly

-	 *

-	 * @access	public

-	 * @param	string	the where clause

-	 * @param	string	the limit clause

-	 * @param	string	the offset clause

-	 * @return	object

-	 */

-	function get_where($table = '', $where = null, $limit = null, $offset = null)

-	{

-		if ($table != '')

-		{

-			$this->from($table);

-		}

-

-		if ( ! is_null($where))

-		{

-			$this->where($where);

-		}

-		

-		if ( ! is_null($limit))

-		{

-			$this->limit($limit, $offset);

-		}

-			

-		$sql = $this->_compile_select();

-

-		$result = $this->query($sql);

-		$this->_reset_select();

-		return $result;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * getwhere() is an alias of get_where()

-	 * this function is here for backwards compatibility, as

-	 * getwhere() has been deprecated

-	 */

-	function getwhere($table = '', $where = null, $limit = null, $offset = null)

-	{

-		return $this->get_where($table, $where, $limit, $offset);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert

-	 *

-	 * Compiles an insert string and runs the query

-	 *

-	 * @access	public

-	 * @param	string	the table to retrieve the results from

-	 * @param	array	an associative array of insert values

-	 * @return	object

-	 */

-	function insert($table = '', $set = NULL)

-	{	

-		if ( ! is_null($set))

-		{

-			$this->set($set);

-		}

-	

-		if (count($this->ar_set) == 0)

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_must_use_set');

-			}

-			return FALSE;

-		}

-

-		if ($table == '')

-		{

-			if ( ! isset($this->ar_from[0]))

-			{

-				if ($this->db_debug)

-				{

-					return $this->display_error('db_must_set_table');

-				}

-				return FALSE;

-			}

-			

-			$table = $this->ar_from[0];

-		}

-

-		$sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));

-		

-		$this->_reset_write();

-		return $this->query($sql);		

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update

-	 *

-	 * Compiles an update string and runs the query

-	 *

-	 * @access	public

-	 * @param	string	the table to retrieve the results from

-	 * @param	array	an associative array of update values

-	 * @param	mixed	the where clause

-	 * @return	object

-	 */

-	function update($table = '', $set = NULL, $where = NULL, $limit = NULL)

-	{

-		// Combine any cached components with the current statements

-		$this->_merge_cache();

-

-		if ( ! is_null($set))

-		{

-			$this->set($set);

-		}

-	

-		if (count($this->ar_set) == 0)

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_must_use_set');

-			}

-			return FALSE;

-		}

-

-		if ($table == '')

-		{

-			if ( ! isset($this->ar_from[0]))

-			{

-				if ($this->db_debug)

-				{

-					return $this->display_error('db_must_set_table');

-				}

-				return FALSE;

-			}

-			

-			$table = $this->ar_from[0];

-		}

-		

-		if ($where != NULL)

-		{

-			$this->where($where);

-		}

-

-		if ($limit != NULL)

-		{

-			$this->limit($limit);

-		}

-		

-		$sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);

-		

-		$this->_reset_write();

-		return $this->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Empty Table

-	 *

-	 * Compiles a delete string and runs "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table to empty

-	 * @return	object

-	 */

-	function empty_table($table = '')

-	{

-		if ($table == '')

-		{

-			if ( ! isset($this->ar_from[0]))

-			{

-				if ($this->db_debug)

-				{

-					return $this->display_error('db_must_set_table');

-				}

-				return FALSE;

-			}

-

-			$table = $this->ar_from[0];

-		}

-		else

-		{

-			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);

-		}

-

-		$sql = $this->_delete($table);

-

-		$this->_reset_write();

-		

-		return $this->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate

-	 *

-	 * Compiles a truncate string and runs the query

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table to truncate

-	 * @return	object

-	 */

-	function truncate($table = '')

-	{

-		if ($table == '')

-		{

-			if ( ! isset($this->ar_from[0]))

-			{

-				if ($this->db_debug)

-				{

-					return $this->display_error('db_must_set_table');

-				}

-				return FALSE;

-			}

-

-			$table = $this->ar_from[0];

-		}

-		else

-		{

-			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);

-		}

-

-		$sql = $this->_truncate($table);

-

-		$this->_reset_write();

-		

-		return $this->query($sql);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete

-	 *

-	 * Compiles a delete string and runs the query

-	 *

-	 * @access	public

-	 * @param	mixed	the table(s) to delete from. String or array

-	 * @param	mixed	the where clause

-	 * @param	mixed	the limit clause

-	 * @param	boolean

-	 * @return	object

-	 */

-	function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)

-	{

-		// Combine any cached components with the current statements

-		$this->_merge_cache();

-

-		if ($table == '')

-		{

-			if ( ! isset($this->ar_from[0]))

-			{

-				if ($this->db_debug)

-				{

-					return $this->display_error('db_must_set_table');

-				}

-				return FALSE;

-			}

-

-			$table = $this->ar_from[0];

-		}

-		elseif (is_array($table))

-		{

-			foreach($table as $single_table)

-			{

-				$this->delete($single_table, $where, $limit, FALSE);

-			}

-

-			$this->_reset_write();

-			return;

-		}

-		else

-		{

-			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);

-		}

-

-		if ($where != '')

-		{

-			$this->where($where);

-		}

-

-		if ($limit != NULL)

-		{

-			$this->limit($limit);

-		}

-

-		if (count($this->ar_where) == 0 && count($this->ar_like) == 0)

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_del_must_use_where');

-			}

-

-			return FALSE;

-		}		

-

-		$sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);

-

-		if ($reset_data)

-		{

-			$this->_reset_write();

-		}

-		

-		return $this->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * DB Prefix

-	 *

-	 * Prepends a database prefix if one exists in configuration

-	 *

-	 * @access	public

-	 * @param	string	the table

-	 * @return	string

-	 */

-	function dbprefix($table = '')

-	{

-		if ($table == '')

-		{

-			$this->display_error('db_table_name_required');

-		}

-

-		return $this->dbprefix.$table;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Track Aliases

-	 *

-	 * Used to track SQL statements written with aliased tables.

-	 *

-	 * @access	private

-	 * @param	string	The table to inspect

-	 * @return	string

-	 */	

-	function _track_aliases($table)

-	{

-		if (is_array($table))

-		{

-			foreach ($table as $t)

-			{

-				$this->_track_aliases($t);

-			}

-			return;

-		}

-		

-		// Does the string contain a comma?  If so, we need to separate

-		// the string into discreet statements

-		if (strpos($table, ',') !== FALSE)

-		{

-			return $this->_track_aliases(explode(',', $table));

-		}

-	

-		// if a table alias is used we can recognize it by a space

-		if (strpos($table, " ") !== FALSE)

-		{

-			// if the alias is written with the AS keyword, remove it

-			$table = preg_replace('/ AS /i', ' ', $table);

-			

-			// Grab the alias

-			$table = trim(strrchr($table, " "));

-			

-			// Store the alias, if it doesn't already exist

-			if ( ! in_array($table, $this->ar_aliased_tables))

-			{

-				$this->ar_aliased_tables[] = $table;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Compile the SELECT statement

-	 *

-	 * Generates a query string based on which functions were used.

-	 * Should not be called directly.  The get() function calls it.

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _compile_select($select_override = FALSE)

-	{

-		// Combine any cached components with the current statements

-		$this->_merge_cache();

-

-		// ----------------------------------------------------------------

-		

-		// Write the "select" portion of the query

-

-		if ($select_override !== FALSE)

-		{

-			$sql = $select_override;

-		}

-		else

-		{

-			$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';

-		

-			if (count($this->ar_select) == 0)

-			{

-				$sql .= '*';		

-			}

-			else

-			{				

-				// Cycle through the "select" portion of the query and prep each column name.

-				// The reason we protect identifiers here rather then in the select() function

-				// is because until the user calls the from() function we don't know if there are aliases

-				foreach ($this->ar_select as $key => $val)

-				{

-					$this->ar_select[$key] = $this->_protect_identifiers($val);

-				}

-				

-				$sql .= implode(', ', $this->ar_select);

-			}

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "FROM" portion of the query

-

-		if (count($this->ar_from) > 0)

-		{

-			$sql .= "\nFROM ";

-

-			$sql .= $this->_from_tables($this->ar_from);

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "JOIN" portion of the query

-

-		if (count($this->ar_join) > 0)

-		{

-			$sql .= "\n";

-

-			$sql .= implode("\n", $this->ar_join);

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "WHERE" portion of the query

-

-		if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)

-		{

-			$sql .= "\n";

-

-			$sql .= "WHERE ";

-		}

-

-		$sql .= implode("\n", $this->ar_where);

-

-		// ----------------------------------------------------------------

-		

-		// Write the "LIKE" portion of the query

-	

-		if (count($this->ar_like) > 0)

-		{

-			if (count($this->ar_where) > 0)

-			{

-				$sql .= "\nAND ";

-			}

-

-			$sql .= implode("\n", $this->ar_like);

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "GROUP BY" portion of the query

-	

-		if (count($this->ar_groupby) > 0)

-		{

-			$sql .= "\nGROUP BY ";

-			

-			$sql .= implode(', ', $this->ar_groupby);

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "HAVING" portion of the query

-		

-		if (count($this->ar_having) > 0)

-		{

-			$sql .= "\nHAVING ";

-			$sql .= implode("\n", $this->ar_having);

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "ORDER BY" portion of the query

-

-		if (count($this->ar_orderby) > 0)

-		{

-			$sql .= "\nORDER BY ";

-			$sql .= implode(', ', $this->ar_orderby);

-			

-			if ($this->ar_order !== FALSE)

-			{

-				$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';

-			}		

-		}

-

-		// ----------------------------------------------------------------

-		

-		// Write the "LIMIT" portion of the query

-		

-		if (is_numeric($this->ar_limit))

-		{

-			$sql .= "\n";

-			$sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);

-		}

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Object to Array

-	 *

-	 * Takes an object as input and converts the class variables to array key/vals

-	 *

-	 * @access	public

-	 * @param	object

-	 * @return	array

-	 */

-	function _object_to_array($object)

-	{

-		if ( ! is_object($object))

-		{

-			return $object;

-		}

-		

-		$array = array();

-		foreach (get_object_vars($object) as $key => $val)

-		{

-			// There are some built in keys we need to ignore for this conversion

-			if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')

-			{

-				$array[$key] = $val;

-			}

-		}

-	

-		return $array;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Start Cache

-	 *

-	 * Starts AR caching

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function start_cache()

-	{

-		$this->ar_caching = TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Stop Cache

-	 *

-	 * Stops AR caching

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function stop_cache()

-	{

-		$this->ar_caching = FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Flush Cache

-	 *

-	 * Empties the AR cache

-	 *

-	 * @access	public

-	 * @return	void

-	 */	

-	function flush_cache()

-	{	

-		$this->_reset_run(

-							array(

-									'ar_cache_select'	=> array(), 

-									'ar_cache_from'		=> array(), 

-									'ar_cache_join'		=> array(),

-									'ar_cache_where'	=> array(), 

-									'ar_cache_like'		=> array(), 

-									'ar_cache_groupby'	=> array(), 

-									'ar_cache_having'	=> array(), 

-									'ar_cache_orderby'	=> array(), 

-									'ar_cache_set'		=> array(),

-									'ar_cache_exists'	=> array()

-								)

-							);	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Merge Cache

-	 *

-	 * When called, this function merges any cached AR arrays with 

-	 * locally called ones.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _merge_cache()

-	{

-		if (count($this->ar_cache_exists) == 0)

-		{

-			return;

-		}

-

-		foreach ($this->ar_cache_exists as $val)

-		{

-			$ar_variable	= 'ar_'.$val;

-			$ar_cache_var	= 'ar_cache_'.$val;

-

-			if (count($this->$ar_cache_var) == 0)

-			{

-				continue;

-			}

-

-			$this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));

-		}

-

-		// If we are "protecting identifiers" we need to examine the "from"

-		// portion of the query to determine if there are any aliases

-		if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)

-		{

-			$this->_track_aliases($this->ar_from);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Resets the active record values.  Called by the get() function

-	 *

-	 * @access	private

-	 * @param	array	An array of fields to reset

-	 * @return	void

-	 */

-	function _reset_run($ar_reset_items)

-	{

-		foreach ($ar_reset_items as $item => $default_value)

-		{

-			if ( ! in_array($item, $this->ar_store_array))

-			{

-				$this->$item = $default_value;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Resets the active record values.  Called by the get() function

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _reset_select()

-	{

-		$ar_reset_items = array(

-								'ar_select'			=> array(), 

-								'ar_from'			=> array(), 

-								'ar_join'			=> array(), 

-								'ar_where'			=> array(), 

-								'ar_like'			=> array(), 

-								'ar_groupby'		=> array(), 

-								'ar_having'			=> array(), 

-								'ar_orderby'		=> array(), 

-								'ar_wherein'		=> array(), 

-								'ar_aliased_tables'	=> array(),

-								'ar_distinct'		=> FALSE, 

-								'ar_limit'			=> FALSE, 

-								'ar_offset'			=> FALSE, 

-								'ar_order'			=> FALSE,

-							);

-		

-		$this->_reset_run($ar_reset_items);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Resets the active record "write" values.

-	 *

-	 * Called by the insert() update() and delete() functions

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _reset_write()

-	{	

-		$ar_reset_items = array(

-								'ar_set'		=> array(), 

-								'ar_from'		=> array(), 

-								'ar_where'		=> array(), 

-								'ar_like'		=> array(),

-								'ar_orderby'	=> array(), 

-								'ar_limit'		=> FALSE, 

-								'ar_order'		=> FALSE

-								);

-

-		$this->_reset_run($ar_reset_items);

-	}

-	

-}

-

-/* End of file DB_active_rec.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Active Record Class
+ *
+ * This is the platform-independent base Active Record implementation class.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_active_record extends CI_DB_driver {
+
+	var $ar_select				= array();
+	var $ar_distinct			= FALSE;
+	var $ar_from				= array();
+	var $ar_join				= array();
+	var $ar_where				= array();
+	var $ar_like				= array();
+	var $ar_groupby				= array();
+	var $ar_having				= array();
+	var $ar_limit				= FALSE;
+	var $ar_offset				= FALSE;
+	var $ar_order				= FALSE;
+	var $ar_orderby				= array();
+	var $ar_set					= array();	
+	var $ar_wherein				= array();
+	var $ar_aliased_tables		= array();
+	var $ar_store_array			= array();
+	
+	// Active Record Caching variables
+	var $ar_caching 			= FALSE;
+	var $ar_cache_exists		= array();
+	var $ar_cache_select		= array();
+	var $ar_cache_from			= array();
+	var $ar_cache_join			= array();
+	var $ar_cache_where			= array();
+	var $ar_cache_like			= array();
+	var $ar_cache_groupby		= array();
+	var $ar_cache_having		= array();
+	var $ar_cache_orderby		= array();
+	var $ar_cache_set			= array();	
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select
+	 *
+	 * Generates the SELECT portion of the query
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	object
+	 */
+	function select($select = '*', $escape = NULL)
+	{
+		// Set the global value if this was sepecified	
+		if (is_bool($escape))
+		{
+			$this->_protect_identifiers = $escape;
+		}
+		
+		if (is_string($select))
+		{
+			$select = explode(',', $select);
+		}
+
+		foreach ($select as $val)
+		{
+			$val = trim($val);
+
+			if ($val != '')
+			{
+				$this->ar_select[] = $val;
+
+				if ($this->ar_caching === TRUE)
+				{
+					$this->ar_cache_select[] = $val;
+					$this->ar_cache_exists[] = 'select';
+				}
+			}
+		}
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select Max
+	 *
+	 * Generates a SELECT MAX(field) portion of a query
+	 *
+	 * @access	public
+	 * @param	string	the field
+	 * @param	string	an alias
+	 * @return	object
+	 */
+	function select_max($select = '', $alias = '')
+	{
+		return $this->_max_min_avg_sum($select, $alias, 'MAX');
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select Min
+	 *
+	 * Generates a SELECT MIN(field) portion of a query
+	 *
+	 * @access	public
+	 * @param	string	the field
+	 * @param	string	an alias
+	 * @return	object
+	 */
+	function select_min($select = '', $alias = '')
+	{
+		return $this->_max_min_avg_sum($select, $alias, 'MIN');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select Average
+	 *
+	 * Generates a SELECT AVG(field) portion of a query
+	 *
+	 * @access	public
+	 * @param	string	the field
+	 * @param	string	an alias
+	 * @return	object
+	 */
+	function select_avg($select = '', $alias = '')
+	{
+		return $this->_max_min_avg_sum($select, $alias, 'AVG');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select Sum
+	 *
+	 * Generates a SELECT SUM(field) portion of a query
+	 *
+	 * @access	public
+	 * @param	string	the field
+	 * @param	string	an alias
+	 * @return	object
+	 */
+	function select_sum($select = '', $alias = '')
+	{
+		return $this->_max_min_avg_sum($select, $alias, 'SUM');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Processing Function for the four functions above:
+	 *
+	 *	select_max()
+	 *	select_min()
+	 *	select_avg()
+	 *  select_sum()
+	 *	
+	 * @access	public
+	 * @param	string	the field
+	 * @param	string	an alias
+	 * @return	object
+	 */
+	function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')
+	{
+		if ( ! is_string($select) OR $select == '')
+		{
+			$this->display_error('db_invalid_query');
+		}
+	
+		$type = strtoupper($type);
+	
+		if ( ! in_array($type, array('MAX', 'MIN', 'AVG', 'SUM')))
+		{
+			show_error('Invalid function type: '.$type);
+		}
+	
+		if ($alias == '')
+		{
+			$alias = $this->_create_alias_from_table(trim($select));
+		}
+	
+		$sql = $type.'('.$this->_protect_identifiers(trim($select)).') AS '.$alias;
+
+		$this->ar_select[] = $sql;
+		
+		if ($this->ar_caching === TRUE)
+		{
+			$this->ar_cache_select[] = $sql;
+			$this->ar_cache_exists[] = 'select';
+		}
+		
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determines the alias name based on the table
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _create_alias_from_table($item)
+	{
+		if (strpos($item, '.') !== FALSE)
+		{
+			return end(explode('.', $item));
+		}
+		
+		return $item;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * DISTINCT
+	 *
+	 * Sets a flag which tells the query string compiler to add DISTINCT
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	object
+	 */
+	function distinct($val = TRUE)
+	{
+		$this->ar_distinct = (is_bool($val)) ? $val : TRUE;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * From
+	 *
+	 * Generates the FROM portion of the query
+	 *
+	 * @access	public
+	 * @param	mixed	can be a string or array
+	 * @return	object
+	 */
+	function from($from)
+	{
+		foreach ((array)$from as $val)
+		{
+			if (strpos($val, ',') !== FALSE)
+			{
+				foreach (explode(',', $val) as $v)
+				{
+					$v = trim($v);
+					$this->_track_aliases($v);
+
+					$this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
+					
+					if ($this->ar_caching === TRUE)
+					{
+						$this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
+						$this->ar_cache_exists[] = 'from';
+					}				
+				}
+
+			}
+			else
+			{
+				$val = trim($val);
+
+				// Extract any aliases that might exist.  We use this information
+				// in the _protect_identifiers to know whether to add a table prefix 
+				$this->_track_aliases($val);
+	
+				$this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
+				
+				if ($this->ar_caching === TRUE)
+				{
+					$this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
+					$this->ar_cache_exists[] = 'from';
+				}
+			}
+		}
+
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Join
+	 *
+	 * Generates the JOIN portion of the query
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string	the join condition
+	 * @param	string	the type of join
+	 * @return	object
+	 */
+	function join($table, $cond, $type = '')
+	{		
+		if ($type != '')
+		{
+			$type = strtoupper(trim($type));
+
+			if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER')))
+			{
+				$type = '';
+			}
+			else
+			{
+				$type .= ' ';
+			}
+		}
+
+		// Extract any aliases that might exist.  We use this information
+		// in the _protect_identifiers to know whether to add a table prefix 
+		$this->_track_aliases($table);
+
+		// Strip apart the condition and protect the identifiers
+		if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))
+		{
+			$match[1] = $this->_protect_identifiers($match[1]);
+			$match[3] = $this->_protect_identifiers($match[3]);
+		
+			$cond = $match[1].$match[2].$match[3];		
+		}
+		
+		// Assemble the JOIN statement
+		$join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
+
+		$this->ar_join[] = $join;
+		if ($this->ar_caching === TRUE)
+		{
+			$this->ar_cache_join[] = $join;
+			$this->ar_cache_exists[] = 'join';
+		}
+
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where
+	 *
+	 * Generates the WHERE portion of the query. Separates
+	 * multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function where($key, $value = NULL, $escape = TRUE)
+	{
+		return $this->_where($key, $value, 'AND ', $escape);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * OR Where
+	 *
+	 * Generates the WHERE portion of the query. Separates
+	 * multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function or_where($key, $value = NULL, $escape = TRUE)
+	{
+		return $this->_where($key, $value, 'OR ', $escape);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * orwhere() is an alias of or_where()
+	 * this function is here for backwards compatibility, as
+	 * orwhere() has been deprecated
+	 */
+	function orwhere($key, $value = NULL, $escape = TRUE)
+	{
+		return $this->or_where($key, $value, $escape);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where
+	 *
+	 * Called by where() or orwhere()
+	 *
+	 * @access	private
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 */
+	function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
+	{
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}
+		
+		// If the escape value was not set will will base it on the global setting
+		if ( ! is_bool($escape))
+		{
+			$escape = $this->_protect_identifiers;
+		}
+
+		foreach ($key as $k => $v)
+		{
+			$prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;
+
+			if (is_null($v) && ! $this->_has_operator($k))
+			{
+				// value appears not to have been set, assign the test to IS NULL
+				$k .= ' IS NULL';
+			}
+			
+			if ( ! is_null($v))
+			{
+				if ($escape === TRUE)
+				{
+					$k = $this->_protect_identifiers($k, FALSE, $escape);
+					
+					$v = ' '.$this->escape($v);
+				}
+
+				if ( ! $this->_has_operator($k))
+				{
+					$k .= ' =';
+				}
+			}
+			else
+			{
+				$k = $this->_protect_identifiers($k, FALSE, $escape);			
+			}
+
+			$this->ar_where[] = $prefix.$k.$v;
+			
+			if ($this->ar_caching === TRUE)
+			{
+				$this->ar_cache_where[] = $prefix.$k.$v;
+				$this->ar_cache_exists[] = 'where';
+			}
+			
+		}
+		
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where_in
+	 *
+	 * Generates a WHERE field IN ('item', 'item') SQL query joined with
+	 * AND if appropriate
+	 *
+	 * @access	public
+	 * @param	string	The field to search
+	 * @param	array	The values searched on
+	 * @return	object
+	 */
+	function where_in($key = NULL, $values = NULL)
+	{
+		return $this->_where_in($key, $values);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where_in_or
+	 *
+	 * Generates a WHERE field IN ('item', 'item') SQL query joined with
+	 * OR if appropriate
+	 *
+	 * @access	public
+	 * @param	string	The field to search
+	 * @param	array	The values searched on
+	 * @return	object
+	 */
+	function or_where_in($key = NULL, $values = NULL)
+	{
+		return $this->_where_in($key, $values, FALSE, 'OR ');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where_not_in
+	 *
+	 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+	 * with AND if appropriate
+	 *
+	 * @access	public
+	 * @param	string	The field to search
+	 * @param	array	The values searched on
+	 * @return	object
+	 */
+	function where_not_in($key = NULL, $values = NULL)
+	{
+		return $this->_where_in($key, $values, TRUE);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where_not_in_or
+	 *
+	 * Generates a WHERE field NOT IN ('item', 'item') SQL query joined
+	 * with OR if appropriate
+	 *
+	 * @access	public
+	 * @param	string	The field to search
+	 * @param	array	The values searched on
+	 * @return	object
+	 */
+	function or_where_not_in($key = NULL, $values = NULL)
+	{
+		return $this->_where_in($key, $values, TRUE, 'OR ');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where_in
+	 *
+	 * Called by where_in, where_in_or, where_not_in, where_not_in_or
+	 *
+	 * @access	public
+	 * @param	string	The field to search
+	 * @param	array	The values searched on
+	 * @param	boolean	If the statement would be IN or NOT IN
+	 * @param	string	
+	 * @return	object
+	 */
+	function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
+	{
+		if ($key === NULL OR $values === NULL)
+		{
+			return;
+		}
+		
+		if ( ! is_array($values))
+		{
+			$values = array($values);
+		}
+		
+		$not = ($not) ? ' NOT' : '';
+
+		foreach ($values as $value)
+		{
+			$this->ar_wherein[] = $this->escape($value);
+		}
+
+		$prefix = (count($this->ar_where) == 0) ? '' : $type;
+ 
+		$where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
+
+		$this->ar_where[] = $where_in;
+		if ($this->ar_caching === TRUE)
+		{
+			$this->ar_cache_where[] = $where_in;
+			$this->ar_cache_exists[] = 'where';
+		}
+
+		// reset the array for multiple calls
+		$this->ar_wherein = array();
+		return $this;
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Like
+	 *
+	 * Generates a %LIKE% portion of the query. Separates
+	 * multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function like($field, $match = '', $side = 'both')
+	{
+		return $this->_like($field, $match, 'AND ', $side);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Not Like
+	 *
+	 * Generates a NOT LIKE portion of the query. Separates
+	 * multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function not_like($field, $match = '', $side = 'both')
+	{
+		return $this->_like($field, $match, 'AND ', $side, 'NOT');
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * OR Like
+	 *
+	 * Generates a %LIKE% portion of the query. Separates
+	 * multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function or_like($field, $match = '', $side = 'both')
+	{
+		return $this->_like($field, $match, 'OR ', $side);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * OR Not Like
+	 *
+	 * Generates a NOT LIKE portion of the query. Separates
+	 * multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @return	object
+	 */
+	function or_not_like($field, $match = '', $side = 'both')
+	{
+		return $this->_like($field, $match, 'OR ', $side, 'NOT');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * orlike() is an alias of or_like()
+	 * this function is here for backwards compatibility, as
+	 * orlike() has been deprecated
+	 */
+	function orlike($field, $match = '', $side = 'both')
+	{
+		return $this->or_like($field, $match, $side);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Like
+	 *
+	 * Called by like() or orlike()
+	 *
+	 * @access	private
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 */
+	function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
+	{
+		if ( ! is_array($field))
+		{
+			$field = array($field => $match);
+		}
+ 	
+		foreach ($field as $k => $v)
+		{
+			$k = $this->_protect_identifiers($k);
+
+			$prefix = (count($this->ar_like) == 0) ? '' : $type;
+
+			$v = $this->escape_str($v);
+
+			if ($side == 'before')
+			{
+				$like_statement = $prefix." $k $not LIKE '%{$v}'";
+			}
+			elseif ($side == 'after')
+			{
+				$like_statement = $prefix." $k $not LIKE '{$v}%'";
+			}
+			else
+			{
+				$like_statement = $prefix." $k $not LIKE '%{$v}%'";
+			}
+			
+			$this->ar_like[] = $like_statement;
+			if ($this->ar_caching === TRUE)
+			{
+				$this->ar_cache_like[] = $like_statement;
+				$this->ar_cache_exists[] = 'like';
+			}
+			
+		}
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * GROUP BY
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	object
+	 */
+	function group_by($by)
+	{
+		if (is_string($by))
+		{
+			$by = explode(',', $by);
+		}
+	
+		foreach ($by as $val)
+		{
+			$val = trim($val);
+		
+			if ($val != '')
+			{
+				$this->ar_groupby[] = $this->_protect_identifiers($val);
+				
+				if ($this->ar_caching === TRUE)
+				{
+					$this->ar_cache_groupby[] = $this->_protect_identifiers($val);
+					$this->ar_cache_exists[] = 'groupby';
+				}
+			}
+		}
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * groupby() is an alias of group_by()
+	 * this function is here for backwards compatibility, as
+	 * groupby() has been deprecated
+	 */
+	function groupby($by)
+	{
+		return $this->group_by($by);
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the HAVING value
+	 *
+	 * Separates multiple calls with AND
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function having($key, $value = '', $escape = TRUE)
+	{
+		return $this->_having($key, $value, 'AND ', $escape);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * orhaving() is an alias of or_having()
+	 * this function is here for backwards compatibility, as
+	 * orhaving() has been deprecated
+	 */
+
+	function orhaving($key, $value = '', $escape = TRUE)
+	{
+		return $this->or_having($key, $value, $escape);
+	}	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the OR HAVING value
+	 *
+	 * Separates multiple calls with OR
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function or_having($key, $value = '', $escape = TRUE)
+	{
+		return $this->_having($key, $value, 'OR ', $escape);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the HAVING values
+	 *
+	 * Called by having() or or_having()
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	object
+	 */
+	function _having($key, $value = '', $type = 'AND ', $escape = TRUE)
+	{
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}
+	
+		foreach ($key as $k => $v)
+		{
+			$prefix = (count($this->ar_having) == 0) ? '' : $type;
+
+			if ($escape === TRUE)
+			{
+				$k = $this->_protect_identifiers($k);
+			}
+
+			if ( ! $this->_has_operator($k))
+			{
+				$k .= ' = ';
+			}
+
+			if ($v != '')
+			{
+				$v = ' '.$this->escape_str($v);
+			}
+			
+			$this->ar_having[] = $prefix.$k.$v;
+			if ($this->ar_caching === TRUE)
+			{
+				$this->ar_cache_having[] = $prefix.$k.$v;
+				$this->ar_cache_exists[] = 'having';
+			}
+		}
+		
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the ORDER BY value
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string	direction: asc or desc
+	 * @return	object
+	 */
+	function order_by($orderby, $direction = '')
+	{
+		if (strtolower($direction) == 'random')
+		{
+			$orderby = ''; // Random results want or don't need a field name
+			$direction = $this->_random_keyword;
+		}
+		elseif (trim($direction) != '')
+		{
+			$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
+		}
+	
+	
+		if (strpos($orderby, ',') !== FALSE)
+		{
+			$temp = array();
+			foreach (explode(',', $orderby) as $part)
+			{
+				$part = trim($part);
+				if ( ! in_array($part, $this->ar_aliased_tables))
+				{
+					$part = $this->_protect_identifiers(trim($part));
+				}
+				
+				$temp[] = $part;
+			}
+			
+			$orderby = implode(', ', $temp);			
+		}
+		else
+		{
+			$orderby = $this->_protect_identifiers($orderby);
+		}
+	
+		$orderby_statement = $orderby.$direction;
+		
+		$this->ar_orderby[] = $orderby_statement;
+		if ($this->ar_caching === TRUE)
+		{
+			$this->ar_cache_orderby[] = $orderby_statement;
+			$this->ar_cache_exists[] = 'orderby';
+		}
+
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * orderby() is an alias of order_by()
+	 * this function is here for backwards compatibility, as
+	 * orderby() has been deprecated
+	 */
+	function orderby($orderby, $direction = '')
+	{
+		return $this->order_by($orderby, $direction);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the LIMIT value
+	 *
+	 * @access	public
+	 * @param	integer	the limit value
+	 * @param	integer	the offset value
+	 * @return	object
+	 */
+	function limit($value, $offset = '')
+	{
+		$this->ar_limit = $value;
+
+		if ($offset != '')
+		{
+			$this->ar_offset = $offset;
+		}
+		
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Sets the OFFSET value
+	 *
+	 * @access	public
+	 * @param	integer	the offset value
+	 * @return	object
+	 */
+	function offset($offset)
+	{
+		$this->ar_offset = $offset;
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The "set" function.  Allows key/value pairs to be set for inserting or updating
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @param	boolean
+	 * @return	object
+	 */
+	function set($key, $value = '', $escape = TRUE)
+	{
+		$key = $this->_object_to_array($key);
+	
+		if ( ! is_array($key))
+		{
+			$key = array($key => $value);
+		}	
+
+		foreach ($key as $k => $v)
+		{
+			if ($escape === FALSE)
+			{
+				$this->ar_set[$this->_protect_identifiers($k)] = $v;
+			}
+			else
+			{
+				$this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
+			}
+		}
+		
+		return $this;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get
+	 *
+	 * Compiles the select statement based on the other functions called
+	 * and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table
+	 * @param	string	the limit clause
+	 * @param	string	the offset clause
+	 * @return	object
+	 */
+	function get($table = '', $limit = null, $offset = null)
+	{
+		if ($table != '')
+		{
+			$this->_track_aliases($table);
+			$this->from($table);
+		}
+		
+		if ( ! is_null($limit))
+		{
+			$this->limit($limit, $offset);
+		}
+			
+		$sql = $this->_compile_select();
+
+		$result = $this->query($sql);
+		$this->_reset_select();
+		return $result;
+	}
+
+	/**
+	 * "Count All Results" query
+	 *
+	 * Generates a platform-specific query string that counts all records 
+	 * returned by an Active Record query.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all_results($table = '')
+	{
+		if ($table != '')
+		{
+			$this->_track_aliases($table);
+			$this->from($table);
+		}
+		
+		$sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
+
+		$query = $this->query($sql);
+		$this->_reset_select();
+	
+		if ($query->num_rows() == 0)
+		{
+			return '0';
+		}
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get_Where
+	 *
+	 * Allows the where clause, limit and offset to be added directly
+	 *
+	 * @access	public
+	 * @param	string	the where clause
+	 * @param	string	the limit clause
+	 * @param	string	the offset clause
+	 * @return	object
+	 */
+	function get_where($table = '', $where = null, $limit = null, $offset = null)
+	{
+		if ($table != '')
+		{
+			$this->from($table);
+		}
+
+		if ( ! is_null($where))
+		{
+			$this->where($where);
+		}
+		
+		if ( ! is_null($limit))
+		{
+			$this->limit($limit, $offset);
+		}
+			
+		$sql = $this->_compile_select();
+
+		$result = $this->query($sql);
+		$this->_reset_select();
+		return $result;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * getwhere() is an alias of get_where()
+	 * this function is here for backwards compatibility, as
+	 * getwhere() has been deprecated
+	 */
+	function getwhere($table = '', $where = null, $limit = null, $offset = null)
+	{
+		return $this->get_where($table, $where, $limit, $offset);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert
+	 *
+	 * Compiles an insert string and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table to retrieve the results from
+	 * @param	array	an associative array of insert values
+	 * @return	object
+	 */
+	function insert($table = '', $set = NULL)
+	{	
+		if ( ! is_null($set))
+		{
+			$this->set($set);
+		}
+	
+		if (count($this->ar_set) == 0)
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_must_use_set');
+			}
+			return FALSE;
+		}
+
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+			
+			$table = $this->ar_from[0];
+		}
+
+		$sql = $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
+		
+		$this->_reset_write();
+		return $this->query($sql);		
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update
+	 *
+	 * Compiles an update string and runs the query
+	 *
+	 * @access	public
+	 * @param	string	the table to retrieve the results from
+	 * @param	array	an associative array of update values
+	 * @param	mixed	the where clause
+	 * @return	object
+	 */
+	function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
+	{
+		// Combine any cached components with the current statements
+		$this->_merge_cache();
+
+		if ( ! is_null($set))
+		{
+			$this->set($set);
+		}
+	
+		if (count($this->ar_set) == 0)
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_must_use_set');
+			}
+			return FALSE;
+		}
+
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+			
+			$table = $this->ar_from[0];
+		}
+		
+		if ($where != NULL)
+		{
+			$this->where($where);
+		}
+
+		if ($limit != NULL)
+		{
+			$this->limit($limit);
+		}
+		
+		$sql = $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+		
+		$this->_reset_write();
+		return $this->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Empty Table
+	 *
+	 * Compiles a delete string and runs "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table to empty
+	 * @return	object
+	 */
+	function empty_table($table = '')
+	{
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+
+			$table = $this->ar_from[0];
+		}
+		else
+		{
+			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		}
+
+		$sql = $this->_delete($table);
+
+		$this->_reset_write();
+		
+		return $this->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate
+	 *
+	 * Compiles a truncate string and runs the query
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table to truncate
+	 * @return	object
+	 */
+	function truncate($table = '')
+	{
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+
+			$table = $this->ar_from[0];
+		}
+		else
+		{
+			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		}
+
+		$sql = $this->_truncate($table);
+
+		$this->_reset_write();
+		
+		return $this->query($sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete
+	 *
+	 * Compiles a delete string and runs the query
+	 *
+	 * @access	public
+	 * @param	mixed	the table(s) to delete from. String or array
+	 * @param	mixed	the where clause
+	 * @param	mixed	the limit clause
+	 * @param	boolean
+	 * @return	object
+	 */
+	function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE)
+	{
+		// Combine any cached components with the current statements
+		$this->_merge_cache();
+
+		if ($table == '')
+		{
+			if ( ! isset($this->ar_from[0]))
+			{
+				if ($this->db_debug)
+				{
+					return $this->display_error('db_must_set_table');
+				}
+				return FALSE;
+			}
+
+			$table = $this->ar_from[0];
+		}
+		elseif (is_array($table))
+		{
+			foreach($table as $single_table)
+			{
+				$this->delete($single_table, $where, $limit, FALSE);
+			}
+
+			$this->_reset_write();
+			return;
+		}
+		else
+		{
+			$table = $this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		}
+
+		if ($where != '')
+		{
+			$this->where($where);
+		}
+
+		if ($limit != NULL)
+		{
+			$this->limit($limit);
+		}
+
+		if (count($this->ar_where) == 0 && count($this->ar_like) == 0)
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_del_must_use_where');
+			}
+
+			return FALSE;
+		}		
+
+		$sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
+
+		if ($reset_data)
+		{
+			$this->_reset_write();
+		}
+		
+		return $this->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * DB Prefix
+	 *
+	 * Prepends a database prefix if one exists in configuration
+	 *
+	 * @access	public
+	 * @param	string	the table
+	 * @return	string
+	 */
+	function dbprefix($table = '')
+	{
+		if ($table == '')
+		{
+			$this->display_error('db_table_name_required');
+		}
+
+		return $this->dbprefix.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Track Aliases
+	 *
+	 * Used to track SQL statements written with aliased tables.
+	 *
+	 * @access	private
+	 * @param	string	The table to inspect
+	 * @return	string
+	 */	
+	function _track_aliases($table)
+	{
+		if (is_array($table))
+		{
+			foreach ($table as $t)
+			{
+				$this->_track_aliases($t);
+			}
+			return;
+		}
+		
+		// Does the string contain a comma?  If so, we need to separate
+		// the string into discreet statements
+		if (strpos($table, ',') !== FALSE)
+		{
+			return $this->_track_aliases(explode(',', $table));
+		}
+	
+		// if a table alias is used we can recognize it by a space
+		if (strpos($table, " ") !== FALSE)
+		{
+			// if the alias is written with the AS keyword, remove it
+			$table = preg_replace('/ AS /i', ' ', $table);
+			
+			// Grab the alias
+			$table = trim(strrchr($table, " "));
+			
+			// Store the alias, if it doesn't already exist
+			if ( ! in_array($table, $this->ar_aliased_tables))
+			{
+				$this->ar_aliased_tables[] = $table;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile the SELECT statement
+	 *
+	 * Generates a query string based on which functions were used.
+	 * Should not be called directly.  The get() function calls it.
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _compile_select($select_override = FALSE)
+	{
+		// Combine any cached components with the current statements
+		$this->_merge_cache();
+
+		// ----------------------------------------------------------------
+		
+		// Write the "select" portion of the query
+
+		if ($select_override !== FALSE)
+		{
+			$sql = $select_override;
+		}
+		else
+		{
+			$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
+		
+			if (count($this->ar_select) == 0)
+			{
+				$sql .= '*';		
+			}
+			else
+			{				
+				// Cycle through the "select" portion of the query and prep each column name.
+				// The reason we protect identifiers here rather then in the select() function
+				// is because until the user calls the from() function we don't know if there are aliases
+				foreach ($this->ar_select as $key => $val)
+				{
+					$this->ar_select[$key] = $this->_protect_identifiers($val);
+				}
+				
+				$sql .= implode(', ', $this->ar_select);
+			}
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "FROM" portion of the query
+
+		if (count($this->ar_from) > 0)
+		{
+			$sql .= "\nFROM ";
+
+			$sql .= $this->_from_tables($this->ar_from);
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "JOIN" portion of the query
+
+		if (count($this->ar_join) > 0)
+		{
+			$sql .= "\n";
+
+			$sql .= implode("\n", $this->ar_join);
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "WHERE" portion of the query
+
+		if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
+		{
+			$sql .= "\n";
+
+			$sql .= "WHERE ";
+		}
+
+		$sql .= implode("\n", $this->ar_where);
+
+		// ----------------------------------------------------------------
+		
+		// Write the "LIKE" portion of the query
+	
+		if (count($this->ar_like) > 0)
+		{
+			if (count($this->ar_where) > 0)
+			{
+				$sql .= "\nAND ";
+			}
+
+			$sql .= implode("\n", $this->ar_like);
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "GROUP BY" portion of the query
+	
+		if (count($this->ar_groupby) > 0)
+		{
+			$sql .= "\nGROUP BY ";
+			
+			$sql .= implode(', ', $this->ar_groupby);
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "HAVING" portion of the query
+		
+		if (count($this->ar_having) > 0)
+		{
+			$sql .= "\nHAVING ";
+			$sql .= implode("\n", $this->ar_having);
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "ORDER BY" portion of the query
+
+		if (count($this->ar_orderby) > 0)
+		{
+			$sql .= "\nORDER BY ";
+			$sql .= implode(', ', $this->ar_orderby);
+			
+			if ($this->ar_order !== FALSE)
+			{
+				$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
+			}		
+		}
+
+		// ----------------------------------------------------------------
+		
+		// Write the "LIMIT" portion of the query
+		
+		if (is_numeric($this->ar_limit))
+		{
+			$sql .= "\n";
+			$sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
+		}
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Object to Array
+	 *
+	 * Takes an object as input and converts the class variables to array key/vals
+	 *
+	 * @access	public
+	 * @param	object
+	 * @return	array
+	 */
+	function _object_to_array($object)
+	{
+		if ( ! is_object($object))
+		{
+			return $object;
+		}
+		
+		$array = array();
+		foreach (get_object_vars($object) as $key => $val)
+		{
+			// There are some built in keys we need to ignore for this conversion
+			if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name' && $key != '_ci_scaffolding' && $key != '_ci_scaff_table')
+			{
+				$array[$key] = $val;
+			}
+		}
+	
+		return $array;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Start Cache
+	 *
+	 * Starts AR caching
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function start_cache()
+	{
+		$this->ar_caching = TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Stop Cache
+	 *
+	 * Stops AR caching
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function stop_cache()
+	{
+		$this->ar_caching = FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Flush Cache
+	 *
+	 * Empties the AR cache
+	 *
+	 * @access	public
+	 * @return	void
+	 */	
+	function flush_cache()
+	{	
+		$this->_reset_run(
+							array(
+									'ar_cache_select'	=> array(), 
+									'ar_cache_from'		=> array(), 
+									'ar_cache_join'		=> array(),
+									'ar_cache_where'	=> array(), 
+									'ar_cache_like'		=> array(), 
+									'ar_cache_groupby'	=> array(), 
+									'ar_cache_having'	=> array(), 
+									'ar_cache_orderby'	=> array(), 
+									'ar_cache_set'		=> array(),
+									'ar_cache_exists'	=> array()
+								)
+							);	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Merge Cache
+	 *
+	 * When called, this function merges any cached AR arrays with 
+	 * locally called ones.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _merge_cache()
+	{
+		if (count($this->ar_cache_exists) == 0)
+		{
+			return;
+		}
+
+		foreach ($this->ar_cache_exists as $val)
+		{
+			$ar_variable	= 'ar_'.$val;
+			$ar_cache_var	= 'ar_cache_'.$val;
+
+			if (count($this->$ar_cache_var) == 0)
+			{
+				continue;
+			}
+
+			$this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));
+		}
+
+		// If we are "protecting identifiers" we need to examine the "from"
+		// portion of the query to determine if there are any aliases
+		if ($this->_protect_identifiers === TRUE AND count($this->ar_cache_from) > 0)
+		{
+			$this->_track_aliases($this->ar_from);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Resets the active record values.  Called by the get() function
+	 *
+	 * @access	private
+	 * @param	array	An array of fields to reset
+	 * @return	void
+	 */
+	function _reset_run($ar_reset_items)
+	{
+		foreach ($ar_reset_items as $item => $default_value)
+		{
+			if ( ! in_array($item, $this->ar_store_array))
+			{
+				$this->$item = $default_value;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Resets the active record values.  Called by the get() function
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reset_select()
+	{
+		$ar_reset_items = array(
+								'ar_select'			=> array(), 
+								'ar_from'			=> array(), 
+								'ar_join'			=> array(), 
+								'ar_where'			=> array(), 
+								'ar_like'			=> array(), 
+								'ar_groupby'		=> array(), 
+								'ar_having'			=> array(), 
+								'ar_orderby'		=> array(), 
+								'ar_wherein'		=> array(), 
+								'ar_aliased_tables'	=> array(),
+								'ar_distinct'		=> FALSE, 
+								'ar_limit'			=> FALSE, 
+								'ar_offset'			=> FALSE, 
+								'ar_order'			=> FALSE,
+							);
+		
+		$this->_reset_run($ar_reset_items);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Resets the active record "write" values.
+	 *
+	 * Called by the insert() update() and delete() functions
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reset_write()
+	{	
+		$ar_reset_items = array(
+								'ar_set'		=> array(), 
+								'ar_from'		=> array(), 
+								'ar_where'		=> array(), 
+								'ar_like'		=> array(),
+								'ar_orderby'	=> array(), 
+								'ar_limit'		=> FALSE, 
+								'ar_order'		=> FALSE
+								);
+
+		$this->_reset_run($ar_reset_items);
+	}
+	
+}
+
+/* End of file 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 9bb1b16..70a2d95 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -1,195 +1,195 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Database Cache Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_Cache {

-

-	var $CI;

-	var $db;	// allows passing of db object so that multiple database connections and returned db objects can be supported

-

-	/**

-	 * Constructor

-	 *

-	 * Grabs the CI super object instance so we can access it.

-	 *

-	 */	

-	function CI_DB_Cache(&$db)

-	{

-		// Assign the main CI object to $this->CI

-		// and load the file helper since we use it a lot

-		$this->CI =& get_instance();

-		$this->db =& $db;

-		$this->CI->load->helper('file');	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Cache Directory Path

-	 *

-	 * @access	public

-	 * @param	string	the path to the cache directory

-	 * @return	bool

-	 */		

-	function check_path($path = '')

-	{

-		if ($path == '')

-		{

-			if ($this->db->cachedir == '')

-			{

-				return $this->db->cache_off();

-			}

-		

-			$path = $this->db->cachedir;

-		}

-	

-		// Add a trailing slash to the path if needed

-		$path = preg_replace("/(.+?)\/*$/", "\\1/",  $path);

-

-		if ( ! is_dir($path) OR ! is_really_writable($path))

-		{

-			// If the path is wrong we'll turn off caching

-			return $this->db->cache_off();

-		}

-		

-		$this->db->cachedir = $path;

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Retrieve a cached query

-	 *

-	 * The URI being requested will become the name of the cache sub-folder.

-	 * An MD5 hash of the SQL statement will become the cache file name

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function read($sql)

-	{

-		if ( ! $this->check_path())

-		{

-			return $this->db->cache_off();

-		}

-

-		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);

-		

-		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);

-	

-		$filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);		

-		

-		if (FALSE === ($cachedata = read_file($filepath)))

-		{	

-			return FALSE;

-		}

-		

-		return unserialize($cachedata);			

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write a query to a cache file

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function write($sql, $object)

-	{

-		if ( ! $this->check_path())

-		{

-			return $this->db->cache_off();

-		}

-

-		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);

-		

-		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);

-	

-		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';

-		

-		$filename = md5($sql);

-	

-		if ( ! @is_dir($dir_path))

-		{

-			if ( ! @mkdir($dir_path, DIR_WRITE_MODE))

-			{

-				return FALSE;

-			}

-			

-			@chmod($dir_path, DIR_WRITE_MODE);			

-		}

-		

-		if (write_file($dir_path.$filename, serialize($object)) === FALSE)

-		{

-			return FALSE;

-		}

-		

-		@chmod($dir_path.$filename, DIR_WRITE_MODE);

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete cache files within a particular directory

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function delete($segment_one = '', $segment_two = '')

-	{	

-		if ($segment_one == '')

-		{

-			$segment_one  = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);

-		}

-		

-		if ($segment_two == '')

-		{

-			$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);

-		}

-		

-		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';

-		

-		delete_files($dir_path, TRUE);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete all existing cache files

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function delete_all()

-	{

-		delete_files($this->db->cachedir, TRUE);

-	}

-

-}

-

-

-/* End of file DB_cache.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Database Cache Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_Cache {
+
+	var $CI;
+	var $db;	// allows passing of db object so that multiple database connections and returned db objects can be supported
+
+	/**
+	 * Constructor
+	 *
+	 * Grabs the CI super object instance so we can access it.
+	 *
+	 */	
+	function CI_DB_Cache(&$db)
+	{
+		// Assign the main CI object to $this->CI
+		// and load the file helper since we use it a lot
+		$this->CI =& get_instance();
+		$this->db =& $db;
+		$this->CI->load->helper('file');	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Cache Directory Path
+	 *
+	 * @access	public
+	 * @param	string	the path to the cache directory
+	 * @return	bool
+	 */		
+	function check_path($path = '')
+	{
+		if ($path == '')
+		{
+			if ($this->db->cachedir == '')
+			{
+				return $this->db->cache_off();
+			}
+		
+			$path = $this->db->cachedir;
+		}
+	
+		// Add a trailing slash to the path if needed
+		$path = preg_replace("/(.+?)\/*$/", "\\1/",  $path);
+
+		if ( ! is_dir($path) OR ! is_really_writable($path))
+		{
+			// If the path is wrong we'll turn off caching
+			return $this->db->cache_off();
+		}
+		
+		$this->db->cachedir = $path;
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Retrieve a cached query
+	 *
+	 * The URI being requested will become the name of the cache sub-folder.
+	 * An MD5 hash of the SQL statement will become the cache file name
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function read($sql)
+	{
+		if ( ! $this->check_path())
+		{
+			return $this->db->cache_off();
+		}
+
+		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
+		
+		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+	
+		$filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);		
+		
+		if (FALSE === ($cachedata = read_file($filepath)))
+		{	
+			return FALSE;
+		}
+		
+		return unserialize($cachedata);			
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write a query to a cache file
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function write($sql, $object)
+	{
+		if ( ! $this->check_path())
+		{
+			return $this->db->cache_off();
+		}
+
+		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
+		
+		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+	
+		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
+		
+		$filename = md5($sql);
+	
+		if ( ! @is_dir($dir_path))
+		{
+			if ( ! @mkdir($dir_path, DIR_WRITE_MODE))
+			{
+				return FALSE;
+			}
+			
+			@chmod($dir_path, DIR_WRITE_MODE);			
+		}
+		
+		if (write_file($dir_path.$filename, serialize($object)) === FALSE)
+		{
+			return FALSE;
+		}
+		
+		@chmod($dir_path.$filename, DIR_WRITE_MODE);
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete cache files within a particular directory
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function delete($segment_one = '', $segment_two = '')
+	{	
+		if ($segment_one == '')
+		{
+			$segment_one  = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
+		}
+		
+		if ($segment_two == '')
+		{
+			$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
+		}
+		
+		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
+		
+		delete_files($dir_path, TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete all existing cache files
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function delete_all()
+	{
+		delete_files($this->db->cachedir, TRUE);
+	}
+
+}
+
+
+/* End of file DB_cache.php */
 /* Location: ./system/database/DB_cache.php */
\ No newline at end of file
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index dbd82db..4293acc 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -1,1319 +1,1319 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Database Driver Class

- *

- * This is the platform-independent base DB implementation class.

- * This class will not be called directly. Rather, the adapter

- * class for the specific database will extend and instantiate it.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_driver {

-

-	var $username;

-	var $password;

-	var $hostname;

-	var $database;

-	var $dbdriver		= 'mysql';

-	var $dbprefix		= '';

-	var $char_set		= 'utf8';

-	var $dbcollat		= 'utf8_general_ci';

-	var $autoinit		= TRUE; // Whether to automatically initialize the DB

-	var $swap_pre		= '';

-	var $port			= '';

-	var $pconnect		= FALSE;

-	var $conn_id		= FALSE;

-	var $result_id		= FALSE;

-	var $db_debug		= FALSE;

-	var $benchmark		= 0;

-	var $query_count	= 0;

-	var $bind_marker	= '?';

-	var $save_queries	= TRUE;

-	var $queries		= array();

-	var $query_times	= array();

-	var $data_cache		= array();

-	var $trans_enabled	= TRUE;

-	var $trans_strict	= TRUE;

-	var $_trans_depth	= 0;

-	var $_trans_status	= TRUE; // Used with transactions to determine if a rollback should occur

-	var $cache_on		= FALSE;

-	var $cachedir		= '';

-	var $cache_autodel	= FALSE;

-	var $CACHE; // The cache class object

-

-	// Private variables

-	var $_protect_identifiers	= TRUE;

-	var $_reserved_identifiers	= array('*'); // Identifiers that should NOT be escaped

-

-	// These are use with Oracle

-	var $stmt_id;

-	var $curs_id;

-	var $limit_used;

-

-

-	

-	/**

-	 * Constructor.  Accepts one parameter containing the database

-	 * connection settings.

-	 *

-	 * @param array

-	 */	

-	function CI_DB_driver($params)

-	{

-		if (is_array($params))

-		{

-			foreach ($params as $key => $val)

-			{

-				$this->$key = $val;

-			}

-		}

-

-		log_message('debug', 'Database Driver Class Initialized');

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize Database Settings

-	 *

-	 * @access	private Called by the constructor

-	 * @param	mixed

-	 * @return	void

-	 */	

-	function initialize()

-	{

-		// If an existing connection resource is available

-		// there is no need to connect and select the database

-		if (is_resource($this->conn_id) OR is_object($this->conn_id))

-		{

-			return TRUE;

-		}

-	

-		// ----------------------------------------------------------------

-		

-		// Connect to the database and set the connection ID

-		$this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();

-

-		// No connection resource?  Throw an error

-		if ( ! $this->conn_id)

-		{

-			log_message('error', 'Unable to connect to the database');

-			

-			if ($this->db_debug)

-			{

-				$this->display_error('db_unable_to_connect');

-			}

-			return FALSE;

-		}

-

-		// ----------------------------------------------------------------

-

-		// Select the DB... assuming a database name is specified in the config file

-		if ($this->database != '')

-		{

-			if ( ! $this->db_select())

-			{

-				log_message('error', 'Unable to select database: '.$this->database);

-			

-				if ($this->db_debug)

-				{

-					$this->display_error('db_unable_to_select', $this->database);

-				}

-				return FALSE;			

-			}

-			else

-			{

-				// We've selected the DB. Now we set the character set

-				if ( ! $this->db_set_charset($this->char_set, $this->dbcollat))

-				{

-					return FALSE;

-				}

-		

-				return TRUE;

-			}

-		}

-

-		return TRUE;

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		if ( ! $this->_db_set_charset($this->char_set, $this->dbcollat))

-		{

-			log_message('error', 'Unable to set database connection charset: '.$this->char_set);

-		

-			if ($this->db_debug)

-			{

-				$this->display_error('db_unable_to_set_charset', $this->char_set);

-			}

-			

-			return FALSE;

-		}

-		

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The name of the platform in use (mysql, mssql, etc...)

-	 *

-	 * @access	public

-	 * @return	string		

-	 */	

-	function platform()

-	{

-		return $this->dbdriver;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Database Version Number.  Returns a string containing the

-	 * version of the database being used

-	 *

-	 * @access	public

-	 * @return	string	

-	 */	

-	function version()

-	{

-		if (FALSE === ($sql = $this->_version()))

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_unsupported_function');

-			}

-			return FALSE;

-		}

-		

-		if ($this->dbdriver == 'oci8')

-		{

-			return $sql;

-		}

-	

-		$query = $this->query($sql);

-		return $query->row('ver');

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * Accepts an SQL string as input and returns a result object upon

-	 * successful execution of a "read" type query.  Returns boolean TRUE

-	 * upon successful execution of a "write" type query. Returns boolean

-	 * FALSE upon failure, and if the $db_debug variable is set to TRUE

-	 * will raise an error.

-	 *

-	 * @access	public

-	 * @param	string	An SQL query string

-	 * @param	array	An array of binding data

-	 * @return	mixed		

-	 */	

-	function query($sql, $binds = FALSE, $return_object = TRUE)

-	{

-		if ($sql == '')

-		{

-			if ($this->db_debug)

-			{

-				log_message('error', 'Invalid query: '.$sql);

-				return $this->display_error('db_invalid_query');

-			}

-			return FALSE;

-		}

-

-		// Verify table prefix and replace if necessary

-		if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )

-		{			

-			$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);

-		}

-		

-		// Is query caching enabled?  If the query is a "read type"

-		// we will load the caching class and return the previously

-		// cached query if it exists

-		if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))

-		{

-			if ($this->_cache_init())

-			{

-				$this->load_rdriver();

-				if (FALSE !== ($cache = $this->CACHE->read($sql)))

-				{

-					return $cache;

-				}

-			}

-		}

-		

-		// Compile binds if needed

-		if ($binds !== FALSE)

-		{

-			$sql = $this->compile_binds($sql, $binds);

-		}

-

-		// Save the  query for debugging

-		if ($this->save_queries == TRUE)

-		{

-			$this->queries[] = $sql;

-		}

-		

-		// Start the Query Timer

-		$time_start = list($sm, $ss) = explode(' ', microtime());

-	

-		// Run the Query

-		if (FALSE === ($this->result_id = $this->simple_query($sql)))

-		{

-			if ($this->save_queries == TRUE)

-			{

-				$this->query_times[] = 0;

-			}

-		

-			// This will trigger a rollback if transactions are being used

-			$this->_trans_status = FALSE;

-

-			if ($this->db_debug)

-			{

-				// grab the error number and message now, as we might run some

-				// additional queries before displaying the error

-				$error_no = $this->_error_number();

-				$error_msg = $this->_error_message();

-				

-				// We call this function in order to roll-back queries

-				// if transactions are enabled.  If we don't call this here

-				// the error message will trigger an exit, causing the 

-				// transactions to remain in limbo.

-				$this->trans_complete();

-

-				// Log and display errors

-				log_message('error', 'Query error: '.$error_msg);

-				return $this->display_error(

-										array(

-												'Error Number: '.$error_no,

-												$error_msg,

-												$sql

-											)

-										);

-			}

-		

-			return FALSE;

-		}

-		

-		// Stop and aggregate the query time results

-		$time_end = list($em, $es) = explode(' ', microtime());

-		$this->benchmark += ($em + $es) - ($sm + $ss);

-

-		if ($this->save_queries == TRUE)

-		{

-			$this->query_times[] = ($em + $es) - ($sm + $ss);

-		}

-		

-		// Increment the query counter

-		$this->query_count++;

-		

-		// Was the query a "write" type?

-		// If so we'll simply return true

-		if ($this->is_write_type($sql) === TRUE)

-		{

-			// If caching is enabled we'll auto-cleanup any

-			// existing files related to this particular URI

-			if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())

-			{

-				$this->CACHE->delete();

-			}

-		

-			return TRUE;

-		}

-		

-		// Return TRUE if we don't need to create a result object

-		// Currently only the Oracle driver uses this when stored

-		// procedures are used

-		if ($return_object !== TRUE)

-		{

-			return TRUE;

-		}

-	

-		// Load and instantiate the result driver	

-		

-		$driver 		= $this->load_rdriver();

-		$RES 			= new $driver();

-		$RES->conn_id	= $this->conn_id;

-		$RES->result_id	= $this->result_id;

-

-		if ($this->dbdriver == 'oci8')

-		{

-			$RES->stmt_id		= $this->stmt_id;

-			$RES->curs_id		= NULL;

-			$RES->limit_used	= $this->limit_used;

-			$this->stmt_id		= FALSE;

-		}

-		

-		// oci8 vars must be set before calling this

-		$RES->num_rows	= $RES->num_rows();

-				

-		// Is query caching enabled?  If so, we'll serialize the

-		// result object and save it to a cache file.

-		if ($this->cache_on == TRUE AND $this->_cache_init())

-		{

-			// We'll create a new instance of the result object

-			// only without the platform specific driver since

-			// we can't use it with cached data (the query result

-			// resource ID won't be any good once we've cached the

-			// result object, so we'll have to compile the data

-			// and save it)

-			$CR = new CI_DB_result();

-			$CR->num_rows 		= $RES->num_rows();

-			$CR->result_object	= $RES->result_object();

-			$CR->result_array	= $RES->result_array();

-			

-			// Reset these since cached objects can not utilize resource IDs.

-			$CR->conn_id		= NULL;

-			$CR->result_id		= NULL;

-

-			$this->CACHE->write($sql, $CR);

-		}

-		

-		return $RES;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load the result drivers

-	 *

-	 * @access	public

-	 * @return	string 	the name of the result class		

-	 */		

-	function load_rdriver()

-	{

-		$driver = 'CI_DB_'.$this->dbdriver.'_result';

-

-		if ( ! class_exists($driver))

-		{

-			include_once(BASEPATH.'database/DB_result'.EXT);

-			include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);

-		}

-		

-		return $driver;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Simple Query

-	 * This is a simplified version of the query() function.  Internally

-	 * we only use it when running transaction commands since they do

-	 * not require all the features of the main query() function.

-	 *

-	 * @access	public

-	 * @param	string	the sql query

-	 * @return	mixed		

-	 */	

-	function simple_query($sql)

-	{

-		if ( ! $this->conn_id)

-		{

-			$this->initialize();

-		}

-

-		return $this->_execute($sql);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Disable Transactions

-	 * This permits transactions to be disabled at run-time.

-	 *

-	 * @access	public

-	 * @return	void		

-	 */	

-	function trans_off()

-	{

-		$this->trans_enabled = FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Enable/disable Transaction Strict Mode

-	 * When strict mode is enabled, if you are running multiple groups of

-	 * transactions, if one group fails all groups will be rolled back.

-	 * If strict mode is disabled, each group is treated autonomously, meaning

-	 * a failure of one group will not affect any others

-	 *

-	 * @access	public

-	 * @return	void		

-	 */	

-	function trans_strict($mode = TRUE)

-	{

-		$this->trans_strict = is_bool($mode) ? $mode : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Start Transaction

-	 *

-	 * @access	public

-	 * @return	void		

-	 */	

-	function trans_start($test_mode = FALSE)

-	{	

-		if ( ! $this->trans_enabled)

-		{

-			return FALSE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			$this->_trans_depth += 1;

-			return;

-		}

-		

-		$this->trans_begin($test_mode);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Complete Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_complete()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return FALSE;

-		}

-	

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 1)

-		{

-			$this->_trans_depth -= 1;

-			return TRUE;

-		}

-	

-		// The query() function will set this flag to FALSE in the event that a query failed

-		if ($this->_trans_status === FALSE)

-		{

-			$this->trans_rollback();

-			

-			// If we are NOT running in strict mode, we will reset

-			// the _trans_status flag so that subsequent groups of transactions

-			// will be permitted.

-			if ($this->trans_strict === FALSE)

-			{

-				$this->_trans_status = TRUE;

-			}

-

-			log_message('debug', 'DB Transaction Failure');

-			return FALSE;

-		}

-		

-		$this->trans_commit();

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Lets you retrieve the transaction flag to determine if it has failed

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_status()

-	{

-		return $this->_trans_status;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Compile Bindings

-	 *

-	 * @access	public

-	 * @param	string	the sql statement

-	 * @param	array	an array of bind data

-	 * @return	string		

-	 */	

-	function compile_binds($sql, $binds)

-	{

-		if (strpos($sql, $this->bind_marker) === FALSE)

-		{

-			return $sql;

-		}

-		

-		if ( ! is_array($binds))

-		{

-			$binds = array($binds);

-		}

-		

-		// Get the sql segments around the bind markers

-		$segments = explode($this->bind_marker, $sql);

-

-		// The count of bind should be 1 less then the count of segments

-		// If there are more bind arguments trim it down

-		if (count($binds) >= count($segments)) {

-			$binds = array_slice($binds, 0, count($segments)-1);

-		}

-

-		// Construct the binded query

-		$result = $segments[0];

-		$i = 0;

-		foreach ($binds as $bind)

-		{

-			$result .= $this->escape($bind);

-			$result .= $segments[++$i];

-		}

-

-		return $result;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determines if a query is a "write" type.

-	 *

-	 * @access	public

-	 * @param	string	An SQL query string

-	 * @return	boolean		

-	 */	

-	function is_write_type($sql)

-	{

-		if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))

-		{

-			return FALSE;

-		}

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Calculate the aggregate query elapsed time

-	 *

-	 * @access	public

-	 * @param	integer	The number of decimal places

-	 * @return	integer		

-	 */	

-	function elapsed_time($decimals = 6)

-	{

-		return number_format($this->benchmark, $decimals);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the total number of queries

-	 *

-	 * @access	public

-	 * @return	integer		

-	 */	

-	function total_queries()

-	{

-		return $this->query_count;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the last query that was executed

-	 *

-	 * @access	public

-	 * @return	void		

-	 */	

-	function last_query()

-	{

-		return end($this->queries);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Smart" Escape String

-	 *

-	 * Escapes data based on type

-	 * Sets boolean and null types

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	integer		

-	 */	

-	function escape($str)

-	{	

-		switch (gettype($str))

-		{

-			case 'string'	:	$str = "'".$this->escape_str($str)."'";

-				break;

-			case 'boolean'	:	$str = ($str === FALSE) ? 0 : 1;

-				break;

-			default			:	$str = ($str === NULL) ? 'NULL' : $str;

-				break;

-		}		

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Primary

-	 *

-	 * Retrieves the primary key.  It assumes that the row in the first

-	 * position is the primary key

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string		

-	 */	

-	function primary($table = '')

-	{	

-		$fields = $this->list_fields($table);

-		

-		if ( ! is_array($fields))

-		{

-			return FALSE;

-		}

-

-		return current($fields);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns an array of table names

-	 *

-	 * @access	public

-	 * @return	array		

-	 */	

-	function list_tables($constrain_by_prefix = FALSE)

-	{

-		// Is there a cached result?

-		if (isset($this->data_cache['table_names']))

-		{

-			return $this->data_cache['table_names'];

-		}

-	

-		if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_unsupported_function');

-			}

-			return FALSE;

-		}

-

-		$retval = array();

-		$query = $this->query($sql);

-		

-		if ($query->num_rows() > 0)

-		{

-			foreach($query->result_array() as $row)

-			{

-				if (isset($row['TABLE_NAME']))

-				{

-					$retval[] = $row['TABLE_NAME'];

-				}

-				else

-				{

-					$retval[] = array_shift($row);

-				}

-			}

-		}

-

-		$this->data_cache['table_names'] = $retval;

-		return $this->data_cache['table_names'];

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determine if a particular table exists

-	 * @access	public

-	 * @return	boolean

-	 */

-	function table_exists($table_name)

-	{	

-		return ( ! in_array($this->_protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables())) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch MySQL Field Names

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	array		

-	 */

-	function list_fields($table = '')

-	{

-		// Is there a cached result?

-		if (isset($this->data_cache['field_names'][$table]))

-		{

-			return $this->data_cache['field_names'][$table];

-		}

-	

-		if ($table == '')

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_field_param_missing');

-			}

-			return FALSE;

-		}

-		

-		if (FALSE === ($sql = $this->_list_columns($this->_protect_identifiers($table, TRUE, NULL, FALSE))))

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_unsupported_function');

-			}

-			return FALSE;

-		}

-		

-		$query = $this->query($sql);

-		

-		$retval = array();

-		foreach($query->result_array() as $row)

-		{

-			if (isset($row['COLUMN_NAME']))

-			{

-				$retval[] = $row['COLUMN_NAME'];

-			}

-			else

-			{

-				$retval[] = current($row);

-			}		

-		}

-		

-		$this->data_cache['field_names'][$table] = $retval;

-		return $this->data_cache['field_names'][$table];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determine if a particular field exists

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	boolean

-	 */

-	function field_exists($field_name, $table_name)

-	{	

-		return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns an object with field data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	object		

-	 */	

-	function field_data($table = '')

-	{

-		if ($table == '')

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_field_param_missing');

-			}

-			return FALSE;

-		}

-		

-		$query = $this->query($this->_field_data($this->_protect_identifiers($table, TRUE, NULL, FALSE)));

-

-		return $query->field_data();

-	}	

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Generate an insert string

-	 *

-	 * @access	public

-	 * @param	string	the table upon which the query will be performed

-	 * @param	array	an associative array data of key/values

-	 * @return	string		

-	 */	

-	function insert_string($table, $data)

-	{

-		$fields = array();

-		$values = array();

-		

-		foreach($data as $key => $val)

-		{

-			$fields[] = $this->_escape_identifiers($key);

-			$values[] = $this->escape($val);

-		}

-				

-		return $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values);

-	}	

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate an update string

-	 *

-	 * @access	public

-	 * @param	string	the table upon which the query will be performed

-	 * @param	array	an associative array data of key/values

-	 * @param	mixed	the "where" statement

-	 * @return	string		

-	 */	

-	function update_string($table, $data, $where)

-	{

-		if ($where == '')

-		{

-			return false;

-		}

-					

-		$fields = array();

-		foreach($data as $key => $val)

-		{

-			$fields[$this->_protect_identifiers($key)] = $this->escape($val);

-		}

-

-		if ( ! is_array($where))

-		{

-			$dest = array($where);

-		}

-		else

-		{

-			$dest = array();

-			foreach ($where as $key => $val)

-			{

-				$prefix = (count($dest) == 0) ? '' : ' AND ';

-	

-				if ($val !== '')

-				{

-					if ( ! $this->_has_operator($key))

-					{

-						$key .= ' =';

-					}

-				

-					$val = ' '.$this->escape($val);

-				}

-							

-				$dest[] = $prefix.$key.$val;

-			}

-		}		

-

-		return $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $dest);

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Tests whether the string has an SQL operator

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	bool

-	 */

-	function _has_operator($str)

-	{

-		$str = trim($str);

-		if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))

-		{

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Enables a native PHP function to be run, using a platform agnostic wrapper.

-	 *

-	 * @access	public

-	 * @param	string	the function name

-	 * @param	mixed	any parameters needed by the function

-	 * @return	mixed		

-	 */	

-	function call_function($function)

-	{

-		$driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';

-	

-		if (FALSE === strpos($driver, $function))

-		{

-			$function = $driver.$function;

-		}

-		

-		if ( ! function_exists($function))

-		{

-			if ($this->db_debug)

-			{

-				return $this->display_error('db_unsupported_function');

-			}

-			return FALSE;

-		}

-		else

-		{

-			$args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;

-

-			return call_user_func_array($function, $args);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Cache Directory Path

-	 *

-	 * @access	public

-	 * @param	string	the path to the cache directory

-	 * @return	void

-	 */		

-	function cache_set_path($path = '')

-	{

-		$this->cachedir = $path;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Enable Query Caching

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function cache_on()

-	{

-		$this->cache_on = TRUE;

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Disable Query Caching

-	 *

-	 * @access	public

-	 * @return	void

-	 */	

-	function cache_off()

-	{

-		$this->cache_on = FALSE;

-		return FALSE;

-	}

-	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete the cache files associated with a particular URI

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function cache_delete($segment_one = '', $segment_two = '')

-	{

-		if ( ! $this->_cache_init())

-		{

-			return FALSE;

-		}

-		return $this->CACHE->delete($segment_one, $segment_two);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete All cache files

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function cache_delete_all()

-	{

-		if ( ! $this->_cache_init())

-		{

-			return FALSE;

-		}

-

-		return $this->CACHE->delete_all();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize the Cache Class

-	 *

-	 * @access	private

-	 * @return	void

-	 */	

-	function _cache_init()

-	{

-		if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))

-		{

-			return TRUE;

-		}

-	

-		if ( ! @include(BASEPATH.'database/DB_cache'.EXT))

-		{

-			return $this->cache_off();

-		}

-		

-		$this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @return	void		

-	 */	

-	function close()

-	{

-		if (is_resource($this->conn_id) OR is_object($this->conn_id))

-		{

-			$this->_close($this->conn_id);

-		}

-		$this->conn_id = FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Display an error message

-	 *

-	 * @access	public

-	 * @param	string	the error message

-	 * @param	string	any "swap" values

-	 * @param	boolean	whether to localize the message

-	 * @return	string	sends the application/error_db.php template		

-	 */	

-	function display_error($error = '', $swap = '', $native = FALSE)

-	{

-		$LANG =& load_class('Language');

-		$LANG->load('db');

-

-		$heading = $LANG->line('db_error_heading');

-

-		if ($native == TRUE)

-		{

-			$message = $error;

-		}

-		else

-		{

-			$message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;

-		}

-		

-		$error =& load_class('Exceptions');

-		echo $error->show_error($heading, $message, 'error_db');

-		exit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Protect Identifiers

-	 *

-	 * This function adds backticks if appropriate based on db type

-	 *

-	 * @access	private

-	 * @param	mixed	the item to escape

-	 * @return	mixed	the item with backticks

-	 */

-	function protect_identifiers($item, $prefix_single = FALSE)

-	{

-		return $this->_protect_identifiers($item, $prefix_single);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Protect Identifiers

-	 *

-	 * This function is used extensively by the Active Record class, and by

-	 * a couple functions in this class. 

-	 * It takes a column or table name (optionally with an alias) and inserts

-	 * the table prefix onto it.  Some logic is necessary in order to deal with

-	 * column names that include the path.  Consider a query like this:

-	 *

-	 * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table

-	 *

-	 * Or a query with aliasing:

-	 *

-	 * SELECT m.member_id, m.member_name FROM members AS m

-	 *

-	 * Since the column name can include up to four segments (host, DB, table, column)

-	 * or also have an alias prefix, we need to do a bit of work to figure this out and

-	 * insert the table prefix (if it exists) in the proper position, and escape only

-	 * the correct identifiers.

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	bool

-	 * @param	mixed

-	 * @param	bool

-	 * @return	string

-	 */	

-	function _protect_identifiers($item, $prefix_single = FALSE, $protect_identifiers = NULL, $field_exists = TRUE)

-	{

-		if ( ! is_bool($protect_identifiers))

-		{

-			$protect_identifiers = $this->_protect_identifiers;

-		}

-		

-		// Convert tabs or multiple spaces into single spaces

-		$item = preg_replace('/[\t| ]+/', ' ', $item);

-	

-		// If the item has an alias declaration we remove it and set it aside.

-		// Basically we remove everything to the right of the first space

-		$alias = '';

-		if (strpos($item, ' ') !== FALSE)

-		{		

-			$alias = strstr($item, " ");

-			$item = substr($item, 0, - strlen($alias));

-		}

-

-		// Break the string apart if it contains periods, then insert the table prefix

-		// in the correct location, assuming the period doesn't indicate that we're dealing

-		// with an alias. While we're at it, we will escape the components

-		if (strpos($item, '.') !== FALSE)

-		{

-			$parts	= explode('.', $item);

-			

-			// Does the first segment of the exploded item match

-			// one of the aliases previously identified?  If so,

-			// we have nothing more to do other than escape the item

-			if (in_array($parts[0], $this->ar_aliased_tables))

-			{				

-				if ($protect_identifiers === TRUE)

-				{

-					foreach ($parts as $key => $val)

-					{

-						if ( ! in_array($val, $this->_reserved_identifiers))

-						{

-							$parts[$key] = $this->_escape_identifiers($val);

-						}

-					}

-				

-					$item = implode('.', $parts);

-				}			

-				return $item.$alias;

-			}

-			

-			// Is there a table prefix defined in the config file?  If not, no need to do anything

-			if ($this->dbprefix != '')

-			{

-				// We now add the table prefix based on some logic.

-				// Do we have 4 segments (hostname.database.table.column)?

-				// If so, we add the table prefix to the column name in the 3rd segment.

-				if (isset($parts[3]))

-				{

-					$i = 2;

-				}

-				// Do we have 3 segments (database.table.column)?

-				// If so, we add the table prefix to the column name in 2nd position

-				elseif (isset($parts[2]))

-				{

-					$i = 1;

-				}

-				// Do we have 2 segments (table.column)?

-				// If so, we add the table prefix to the column name in 1st segment

-				else

-				{

-					$i = 0;

-				}

-				

-				// This flag is set when the supplied $item does not contain a field name.

-				// This can happen when this function is being called from a JOIN.

-				if ($field_exists == FALSE)

-				{

-					$i++;

-				}

-				

-				// We only add the table prefix if it does not already exist

-				if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix)

-				{

-					$parts[$i] = $this->dbprefix.$parts[$i];

-				}

-				

-				// Put the parts back together

-				$item = implode('.', $parts);

-			}

-			

-			if ($protect_identifiers === TRUE)

-			{

-				$item = $this->_escape_identifiers($item);

-			}

-			

-			return $item.$alias;

-		}

-

-		// This is basically a bug fix for queries that use MAX, MIN, etc.

-		// If a parenthesis is found we know that we do not need to 

-		// escape the data or add a prefix.  There's probably a more graceful

-		// way to deal with this, but I'm not thinking of it -- Rick

-		if (strpos($item, '(') !== FALSE)

-		{

-			return $item.$alias;

-		}

-		

-		// Is there a table prefix?  If not, no need to insert it

-		if ($this->dbprefix != '')

-		{

-			// Do we prefix an item with no segments?

-			if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix)

-			{

-				$item = $this->dbprefix.$item;

-			}		

-		}

-

-		if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers))

-		{

-			$item = $this->_escape_identifiers($item);

-		}

-		

-		return $item.$alias;

-	}

-

-

-}

-

-

-/* End of file DB_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Database Driver Class
+ *
+ * This is the platform-independent base DB implementation class.
+ * This class will not be called directly. Rather, the adapter
+ * class for the specific database will extend and instantiate it.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_driver {
+
+	var $username;
+	var $password;
+	var $hostname;
+	var $database;
+	var $dbdriver		= 'mysql';
+	var $dbprefix		= '';
+	var $char_set		= 'utf8';
+	var $dbcollat		= 'utf8_general_ci';
+	var $autoinit		= TRUE; // Whether to automatically initialize the DB
+	var $swap_pre		= '';
+	var $port			= '';
+	var $pconnect		= FALSE;
+	var $conn_id		= FALSE;
+	var $result_id		= FALSE;
+	var $db_debug		= FALSE;
+	var $benchmark		= 0;
+	var $query_count	= 0;
+	var $bind_marker	= '?';
+	var $save_queries	= TRUE;
+	var $queries		= array();
+	var $query_times	= array();
+	var $data_cache		= array();
+	var $trans_enabled	= TRUE;
+	var $trans_strict	= TRUE;
+	var $_trans_depth	= 0;
+	var $_trans_status	= TRUE; // Used with transactions to determine if a rollback should occur
+	var $cache_on		= FALSE;
+	var $cachedir		= '';
+	var $cache_autodel	= FALSE;
+	var $CACHE; // The cache class object
+
+	// Private variables
+	var $_protect_identifiers	= TRUE;
+	var $_reserved_identifiers	= array('*'); // Identifiers that should NOT be escaped
+
+	// These are use with Oracle
+	var $stmt_id;
+	var $curs_id;
+	var $limit_used;
+
+
+	
+	/**
+	 * Constructor.  Accepts one parameter containing the database
+	 * connection settings.
+	 *
+	 * @param array
+	 */	
+	function CI_DB_driver($params)
+	{
+		if (is_array($params))
+		{
+			foreach ($params as $key => $val)
+			{
+				$this->$key = $val;
+			}
+		}
+
+		log_message('debug', 'Database Driver Class Initialized');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize Database Settings
+	 *
+	 * @access	private Called by the constructor
+	 * @param	mixed
+	 * @return	void
+	 */	
+	function initialize()
+	{
+		// If an existing connection resource is available
+		// there is no need to connect and select the database
+		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		{
+			return TRUE;
+		}
+	
+		// ----------------------------------------------------------------
+		
+		// Connect to the database and set the connection ID
+		$this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
+
+		// No connection resource?  Throw an error
+		if ( ! $this->conn_id)
+		{
+			log_message('error', 'Unable to connect to the database');
+			
+			if ($this->db_debug)
+			{
+				$this->display_error('db_unable_to_connect');
+			}
+			return FALSE;
+		}
+
+		// ----------------------------------------------------------------
+
+		// Select the DB... assuming a database name is specified in the config file
+		if ($this->database != '')
+		{
+			if ( ! $this->db_select())
+			{
+				log_message('error', 'Unable to select database: '.$this->database);
+			
+				if ($this->db_debug)
+				{
+					$this->display_error('db_unable_to_select', $this->database);
+				}
+				return FALSE;			
+			}
+			else
+			{
+				// We've selected the DB. Now we set the character set
+				if ( ! $this->db_set_charset($this->char_set, $this->dbcollat))
+				{
+					return FALSE;
+				}
+		
+				return TRUE;
+			}
+		}
+
+		return TRUE;
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		if ( ! $this->_db_set_charset($this->char_set, $this->dbcollat))
+		{
+			log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+		
+			if ($this->db_debug)
+			{
+				$this->display_error('db_unable_to_set_charset', $this->char_set);
+			}
+			
+			return FALSE;
+		}
+		
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The name of the platform in use (mysql, mssql, etc...)
+	 *
+	 * @access	public
+	 * @return	string		
+	 */	
+	function platform()
+	{
+		return $this->dbdriver;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database Version Number.  Returns a string containing the
+	 * version of the database being used
+	 *
+	 * @access	public
+	 * @return	string	
+	 */	
+	function version()
+	{
+		if (FALSE === ($sql = $this->_version()))
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_unsupported_function');
+			}
+			return FALSE;
+		}
+		
+		if ($this->dbdriver == 'oci8')
+		{
+			return $sql;
+		}
+	
+		$query = $this->query($sql);
+		return $query->row('ver');
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * Accepts an SQL string as input and returns a result object upon
+	 * successful execution of a "read" type query.  Returns boolean TRUE
+	 * upon successful execution of a "write" type query. Returns boolean
+	 * FALSE upon failure, and if the $db_debug variable is set to TRUE
+	 * will raise an error.
+	 *
+	 * @access	public
+	 * @param	string	An SQL query string
+	 * @param	array	An array of binding data
+	 * @return	mixed		
+	 */	
+	function query($sql, $binds = FALSE, $return_object = TRUE)
+	{
+		if ($sql == '')
+		{
+			if ($this->db_debug)
+			{
+				log_message('error', 'Invalid query: '.$sql);
+				return $this->display_error('db_invalid_query');
+			}
+			return FALSE;
+		}
+
+		// Verify table prefix and replace if necessary
+		if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )
+		{			
+			$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
+		}
+		
+		// Is query caching enabled?  If the query is a "read type"
+		// we will load the caching class and return the previously
+		// cached query if it exists
+		if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
+		{
+			if ($this->_cache_init())
+			{
+				$this->load_rdriver();
+				if (FALSE !== ($cache = $this->CACHE->read($sql)))
+				{
+					return $cache;
+				}
+			}
+		}
+		
+		// Compile binds if needed
+		if ($binds !== FALSE)
+		{
+			$sql = $this->compile_binds($sql, $binds);
+		}
+
+		// Save the  query for debugging
+		if ($this->save_queries == TRUE)
+		{
+			$this->queries[] = $sql;
+		}
+		
+		// Start the Query Timer
+		$time_start = list($sm, $ss) = explode(' ', microtime());
+	
+		// Run the Query
+		if (FALSE === ($this->result_id = $this->simple_query($sql)))
+		{
+			if ($this->save_queries == TRUE)
+			{
+				$this->query_times[] = 0;
+			}
+		
+			// This will trigger a rollback if transactions are being used
+			$this->_trans_status = FALSE;
+
+			if ($this->db_debug)
+			{
+				// grab the error number and message now, as we might run some
+				// additional queries before displaying the error
+				$error_no = $this->_error_number();
+				$error_msg = $this->_error_message();
+				
+				// We call this function in order to roll-back queries
+				// if transactions are enabled.  If we don't call this here
+				// the error message will trigger an exit, causing the 
+				// transactions to remain in limbo.
+				$this->trans_complete();
+
+				// Log and display errors
+				log_message('error', 'Query error: '.$error_msg);
+				return $this->display_error(
+										array(
+												'Error Number: '.$error_no,
+												$error_msg,
+												$sql
+											)
+										);
+			}
+		
+			return FALSE;
+		}
+		
+		// Stop and aggregate the query time results
+		$time_end = list($em, $es) = explode(' ', microtime());
+		$this->benchmark += ($em + $es) - ($sm + $ss);
+
+		if ($this->save_queries == TRUE)
+		{
+			$this->query_times[] = ($em + $es) - ($sm + $ss);
+		}
+		
+		// Increment the query counter
+		$this->query_count++;
+		
+		// Was the query a "write" type?
+		// If so we'll simply return true
+		if ($this->is_write_type($sql) === TRUE)
+		{
+			// If caching is enabled we'll auto-cleanup any
+			// existing files related to this particular URI
+			if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
+			{
+				$this->CACHE->delete();
+			}
+		
+			return TRUE;
+		}
+		
+		// Return TRUE if we don't need to create a result object
+		// Currently only the Oracle driver uses this when stored
+		// procedures are used
+		if ($return_object !== TRUE)
+		{
+			return TRUE;
+		}
+	
+		// Load and instantiate the result driver	
+		
+		$driver 		= $this->load_rdriver();
+		$RES 			= new $driver();
+		$RES->conn_id	= $this->conn_id;
+		$RES->result_id	= $this->result_id;
+
+		if ($this->dbdriver == 'oci8')
+		{
+			$RES->stmt_id		= $this->stmt_id;
+			$RES->curs_id		= NULL;
+			$RES->limit_used	= $this->limit_used;
+			$this->stmt_id		= FALSE;
+		}
+		
+		// oci8 vars must be set before calling this
+		$RES->num_rows	= $RES->num_rows();
+				
+		// Is query caching enabled?  If so, we'll serialize the
+		// result object and save it to a cache file.
+		if ($this->cache_on == TRUE AND $this->_cache_init())
+		{
+			// We'll create a new instance of the result object
+			// only without the platform specific driver since
+			// we can't use it with cached data (the query result
+			// resource ID won't be any good once we've cached the
+			// result object, so we'll have to compile the data
+			// and save it)
+			$CR = new CI_DB_result();
+			$CR->num_rows 		= $RES->num_rows();
+			$CR->result_object	= $RES->result_object();
+			$CR->result_array	= $RES->result_array();
+			
+			// Reset these since cached objects can not utilize resource IDs.
+			$CR->conn_id		= NULL;
+			$CR->result_id		= NULL;
+
+			$this->CACHE->write($sql, $CR);
+		}
+		
+		return $RES;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load the result drivers
+	 *
+	 * @access	public
+	 * @return	string 	the name of the result class		
+	 */		
+	function load_rdriver()
+	{
+		$driver = 'CI_DB_'.$this->dbdriver.'_result';
+
+		if ( ! class_exists($driver))
+		{
+			include_once(BASEPATH.'database/DB_result'.EXT);
+			include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT);
+		}
+		
+		return $driver;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Simple Query
+	 * This is a simplified version of the query() function.  Internally
+	 * we only use it when running transaction commands since they do
+	 * not require all the features of the main query() function.
+	 *
+	 * @access	public
+	 * @param	string	the sql query
+	 * @return	mixed		
+	 */	
+	function simple_query($sql)
+	{
+		if ( ! $this->conn_id)
+		{
+			$this->initialize();
+		}
+
+		return $this->_execute($sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Disable Transactions
+	 * This permits transactions to be disabled at run-time.
+	 *
+	 * @access	public
+	 * @return	void		
+	 */	
+	function trans_off()
+	{
+		$this->trans_enabled = FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Enable/disable Transaction Strict Mode
+	 * When strict mode is enabled, if you are running multiple groups of
+	 * transactions, if one group fails all groups will be rolled back.
+	 * If strict mode is disabled, each group is treated autonomously, meaning
+	 * a failure of one group will not affect any others
+	 *
+	 * @access	public
+	 * @return	void		
+	 */	
+	function trans_strict($mode = TRUE)
+	{
+		$this->trans_strict = is_bool($mode) ? $mode : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Start Transaction
+	 *
+	 * @access	public
+	 * @return	void		
+	 */	
+	function trans_start($test_mode = FALSE)
+	{	
+		if ( ! $this->trans_enabled)
+		{
+			return FALSE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			$this->_trans_depth += 1;
+			return;
+		}
+		
+		$this->trans_begin($test_mode);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Complete Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_complete()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return FALSE;
+		}
+	
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 1)
+		{
+			$this->_trans_depth -= 1;
+			return TRUE;
+		}
+	
+		// The query() function will set this flag to FALSE in the event that a query failed
+		if ($this->_trans_status === FALSE)
+		{
+			$this->trans_rollback();
+			
+			// If we are NOT running in strict mode, we will reset
+			// the _trans_status flag so that subsequent groups of transactions
+			// will be permitted.
+			if ($this->trans_strict === FALSE)
+			{
+				$this->_trans_status = TRUE;
+			}
+
+			log_message('debug', 'DB Transaction Failure');
+			return FALSE;
+		}
+		
+		$this->trans_commit();
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Lets you retrieve the transaction flag to determine if it has failed
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_status()
+	{
+		return $this->_trans_status;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile Bindings
+	 *
+	 * @access	public
+	 * @param	string	the sql statement
+	 * @param	array	an array of bind data
+	 * @return	string		
+	 */	
+	function compile_binds($sql, $binds)
+	{
+		if (strpos($sql, $this->bind_marker) === FALSE)
+		{
+			return $sql;
+		}
+		
+		if ( ! is_array($binds))
+		{
+			$binds = array($binds);
+		}
+		
+		// Get the sql segments around the bind markers
+		$segments = explode($this->bind_marker, $sql);
+
+		// The count of bind should be 1 less then the count of segments
+		// If there are more bind arguments trim it down
+		if (count($binds) >= count($segments)) {
+			$binds = array_slice($binds, 0, count($segments)-1);
+		}
+
+		// Construct the binded query
+		$result = $segments[0];
+		$i = 0;
+		foreach ($binds as $bind)
+		{
+			$result .= $this->escape($bind);
+			$result .= $segments[++$i];
+		}
+
+		return $result;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determines if a query is a "write" type.
+	 *
+	 * @access	public
+	 * @param	string	An SQL query string
+	 * @return	boolean		
+	 */	
+	function is_write_type($sql)
+	{
+		if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
+		{
+			return FALSE;
+		}
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Calculate the aggregate query elapsed time
+	 *
+	 * @access	public
+	 * @param	integer	The number of decimal places
+	 * @return	integer		
+	 */	
+	function elapsed_time($decimals = 6)
+	{
+		return number_format($this->benchmark, $decimals);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the total number of queries
+	 *
+	 * @access	public
+	 * @return	integer		
+	 */	
+	function total_queries()
+	{
+		return $this->query_count;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the last query that was executed
+	 *
+	 * @access	public
+	 * @return	void		
+	 */	
+	function last_query()
+	{
+		return end($this->queries);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Smart" Escape String
+	 *
+	 * Escapes data based on type
+	 * Sets boolean and null types
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	integer		
+	 */	
+	function escape($str)
+	{	
+		switch (gettype($str))
+		{
+			case 'string'	:	$str = "'".$this->escape_str($str)."'";
+				break;
+			case 'boolean'	:	$str = ($str === FALSE) ? 0 : 1;
+				break;
+			default			:	$str = ($str === NULL) ? 'NULL' : $str;
+				break;
+		}		
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Primary
+	 *
+	 * Retrieves the primary key.  It assumes that the row in the first
+	 * position is the primary key
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string		
+	 */	
+	function primary($table = '')
+	{	
+		$fields = $this->list_fields($table);
+		
+		if ( ! is_array($fields))
+		{
+			return FALSE;
+		}
+
+		return current($fields);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns an array of table names
+	 *
+	 * @access	public
+	 * @return	array		
+	 */	
+	function list_tables($constrain_by_prefix = FALSE)
+	{
+		// Is there a cached result?
+		if (isset($this->data_cache['table_names']))
+		{
+			return $this->data_cache['table_names'];
+		}
+	
+		if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_unsupported_function');
+			}
+			return FALSE;
+		}
+
+		$retval = array();
+		$query = $this->query($sql);
+		
+		if ($query->num_rows() > 0)
+		{
+			foreach($query->result_array() as $row)
+			{
+				if (isset($row['TABLE_NAME']))
+				{
+					$retval[] = $row['TABLE_NAME'];
+				}
+				else
+				{
+					$retval[] = array_shift($row);
+				}
+			}
+		}
+
+		$this->data_cache['table_names'] = $retval;
+		return $this->data_cache['table_names'];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determine if a particular table exists
+	 * @access	public
+	 * @return	boolean
+	 */
+	function table_exists($table_name)
+	{	
+		return ( ! in_array($this->_protect_identifiers($table_name, TRUE, FALSE, FALSE), $this->list_tables())) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch MySQL Field Names
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	array		
+	 */
+	function list_fields($table = '')
+	{
+		// Is there a cached result?
+		if (isset($this->data_cache['field_names'][$table]))
+		{
+			return $this->data_cache['field_names'][$table];
+		}
+	
+		if ($table == '')
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_field_param_missing');
+			}
+			return FALSE;
+		}
+		
+		if (FALSE === ($sql = $this->_list_columns($this->_protect_identifiers($table, TRUE, NULL, FALSE))))
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_unsupported_function');
+			}
+			return FALSE;
+		}
+		
+		$query = $this->query($sql);
+		
+		$retval = array();
+		foreach($query->result_array() as $row)
+		{
+			if (isset($row['COLUMN_NAME']))
+			{
+				$retval[] = $row['COLUMN_NAME'];
+			}
+			else
+			{
+				$retval[] = current($row);
+			}		
+		}
+		
+		$this->data_cache['field_names'][$table] = $retval;
+		return $this->data_cache['field_names'][$table];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determine if a particular field exists
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	boolean
+	 */
+	function field_exists($field_name, $table_name)
+	{	
+		return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns an object with field data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	object		
+	 */	
+	function field_data($table = '')
+	{
+		if ($table == '')
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_field_param_missing');
+			}
+			return FALSE;
+		}
+		
+		$query = $this->query($this->_field_data($this->_protect_identifiers($table, TRUE, NULL, FALSE)));
+
+		return $query->field_data();
+	}	
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Generate an insert string
+	 *
+	 * @access	public
+	 * @param	string	the table upon which the query will be performed
+	 * @param	array	an associative array data of key/values
+	 * @return	string		
+	 */	
+	function insert_string($table, $data)
+	{
+		$fields = array();
+		$values = array();
+		
+		foreach($data as $key => $val)
+		{
+			$fields[] = $this->_escape_identifiers($key);
+			$values[] = $this->escape($val);
+		}
+				
+		return $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values);
+	}	
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate an update string
+	 *
+	 * @access	public
+	 * @param	string	the table upon which the query will be performed
+	 * @param	array	an associative array data of key/values
+	 * @param	mixed	the "where" statement
+	 * @return	string		
+	 */	
+	function update_string($table, $data, $where)
+	{
+		if ($where == '')
+		{
+			return false;
+		}
+					
+		$fields = array();
+		foreach($data as $key => $val)
+		{
+			$fields[$this->_protect_identifiers($key)] = $this->escape($val);
+		}
+
+		if ( ! is_array($where))
+		{
+			$dest = array($where);
+		}
+		else
+		{
+			$dest = array();
+			foreach ($where as $key => $val)
+			{
+				$prefix = (count($dest) == 0) ? '' : ' AND ';
+	
+				if ($val !== '')
+				{
+					if ( ! $this->_has_operator($key))
+					{
+						$key .= ' =';
+					}
+				
+					$val = ' '.$this->escape($val);
+				}
+							
+				$dest[] = $prefix.$key.$val;
+			}
+		}		
+
+		return $this->_update($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $dest);
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Tests whether the string has an SQL operator
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	bool
+	 */
+	function _has_operator($str)
+	{
+		$str = trim($str);
+		if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
+		{
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Enables a native PHP function to be run, using a platform agnostic wrapper.
+	 *
+	 * @access	public
+	 * @param	string	the function name
+	 * @param	mixed	any parameters needed by the function
+	 * @return	mixed		
+	 */	
+	function call_function($function)
+	{
+		$driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
+	
+		if (FALSE === strpos($driver, $function))
+		{
+			$function = $driver.$function;
+		}
+		
+		if ( ! function_exists($function))
+		{
+			if ($this->db_debug)
+			{
+				return $this->display_error('db_unsupported_function');
+			}
+			return FALSE;
+		}
+		else
+		{
+			$args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
+
+			return call_user_func_array($function, $args);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Cache Directory Path
+	 *
+	 * @access	public
+	 * @param	string	the path to the cache directory
+	 * @return	void
+	 */		
+	function cache_set_path($path = '')
+	{
+		$this->cachedir = $path;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Enable Query Caching
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function cache_on()
+	{
+		$this->cache_on = TRUE;
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Disable Query Caching
+	 *
+	 * @access	public
+	 * @return	void
+	 */	
+	function cache_off()
+	{
+		$this->cache_on = FALSE;
+		return FALSE;
+	}
+	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete the cache files associated with a particular URI
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function cache_delete($segment_one = '', $segment_two = '')
+	{
+		if ( ! $this->_cache_init())
+		{
+			return FALSE;
+		}
+		return $this->CACHE->delete($segment_one, $segment_two);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete All cache files
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function cache_delete_all()
+	{
+		if ( ! $this->_cache_init())
+		{
+			return FALSE;
+		}
+
+		return $this->CACHE->delete_all();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize the Cache Class
+	 *
+	 * @access	private
+	 * @return	void
+	 */	
+	function _cache_init()
+	{
+		if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
+		{
+			return TRUE;
+		}
+	
+		if ( ! @include(BASEPATH.'database/DB_cache'.EXT))
+		{
+			return $this->cache_off();
+		}
+		
+		$this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @return	void		
+	 */	
+	function close()
+	{
+		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		{
+			$this->_close($this->conn_id);
+		}
+		$this->conn_id = FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Display an error message
+	 *
+	 * @access	public
+	 * @param	string	the error message
+	 * @param	string	any "swap" values
+	 * @param	boolean	whether to localize the message
+	 * @return	string	sends the application/error_db.php template		
+	 */	
+	function display_error($error = '', $swap = '', $native = FALSE)
+	{
+		$LANG =& load_class('Language');
+		$LANG->load('db');
+
+		$heading = $LANG->line('db_error_heading');
+
+		if ($native == TRUE)
+		{
+			$message = $error;
+		}
+		else
+		{
+			$message = ( ! is_array($error)) ? array(str_replace('%s', $swap, $LANG->line($error))) : $error;
+		}
+		
+		$error =& load_class('Exceptions');
+		echo $error->show_error($heading, $message, 'error_db');
+		exit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Protect Identifiers
+	 *
+	 * This function adds backticks if appropriate based on db type
+	 *
+	 * @access	private
+	 * @param	mixed	the item to escape
+	 * @return	mixed	the item with backticks
+	 */
+	function protect_identifiers($item, $prefix_single = FALSE)
+	{
+		return $this->_protect_identifiers($item, $prefix_single);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Protect Identifiers
+	 *
+	 * This function is used extensively by the Active Record class, and by
+	 * a couple functions in this class. 
+	 * It takes a column or table name (optionally with an alias) and inserts
+	 * the table prefix onto it.  Some logic is necessary in order to deal with
+	 * column names that include the path.  Consider a query like this:
+	 *
+	 * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table
+	 *
+	 * Or a query with aliasing:
+	 *
+	 * SELECT m.member_id, m.member_name FROM members AS m
+	 *
+	 * Since the column name can include up to four segments (host, DB, table, column)
+	 * or also have an alias prefix, we need to do a bit of work to figure this out and
+	 * insert the table prefix (if it exists) in the proper position, and escape only
+	 * the correct identifiers.
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	bool
+	 * @param	mixed
+	 * @param	bool
+	 * @return	string
+	 */	
+	function _protect_identifiers($item, $prefix_single = FALSE, $protect_identifiers = NULL, $field_exists = TRUE)
+	{
+		if ( ! is_bool($protect_identifiers))
+		{
+			$protect_identifiers = $this->_protect_identifiers;
+		}
+		
+		// Convert tabs or multiple spaces into single spaces
+		$item = preg_replace('/[\t| ]+/', ' ', $item);
+	
+		// If the item has an alias declaration we remove it and set it aside.
+		// Basically we remove everything to the right of the first space
+		$alias = '';
+		if (strpos($item, ' ') !== FALSE)
+		{		
+			$alias = strstr($item, " ");
+			$item = substr($item, 0, - strlen($alias));
+		}
+
+		// Break the string apart if it contains periods, then insert the table prefix
+		// in the correct location, assuming the period doesn't indicate that we're dealing
+		// with an alias. While we're at it, we will escape the components
+		if (strpos($item, '.') !== FALSE)
+		{
+			$parts	= explode('.', $item);
+			
+			// Does the first segment of the exploded item match
+			// one of the aliases previously identified?  If so,
+			// we have nothing more to do other than escape the item
+			if (in_array($parts[0], $this->ar_aliased_tables))
+			{				
+				if ($protect_identifiers === TRUE)
+				{
+					foreach ($parts as $key => $val)
+					{
+						if ( ! in_array($val, $this->_reserved_identifiers))
+						{
+							$parts[$key] = $this->_escape_identifiers($val);
+						}
+					}
+				
+					$item = implode('.', $parts);
+				}			
+				return $item.$alias;
+			}
+			
+			// Is there a table prefix defined in the config file?  If not, no need to do anything
+			if ($this->dbprefix != '')
+			{
+				// We now add the table prefix based on some logic.
+				// Do we have 4 segments (hostname.database.table.column)?
+				// If so, we add the table prefix to the column name in the 3rd segment.
+				if (isset($parts[3]))
+				{
+					$i = 2;
+				}
+				// Do we have 3 segments (database.table.column)?
+				// If so, we add the table prefix to the column name in 2nd position
+				elseif (isset($parts[2]))
+				{
+					$i = 1;
+				}
+				// Do we have 2 segments (table.column)?
+				// If so, we add the table prefix to the column name in 1st segment
+				else
+				{
+					$i = 0;
+				}
+				
+				// This flag is set when the supplied $item does not contain a field name.
+				// This can happen when this function is being called from a JOIN.
+				if ($field_exists == FALSE)
+				{
+					$i++;
+				}
+				
+				// We only add the table prefix if it does not already exist
+				if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix)
+				{
+					$parts[$i] = $this->dbprefix.$parts[$i];
+				}
+				
+				// Put the parts back together
+				$item = implode('.', $parts);
+			}
+			
+			if ($protect_identifiers === TRUE)
+			{
+				$item = $this->_escape_identifiers($item);
+			}
+			
+			return $item.$alias;
+		}
+
+		// This is basically a bug fix for queries that use MAX, MIN, etc.
+		// If a parenthesis is found we know that we do not need to 
+		// escape the data or add a prefix.  There's probably a more graceful
+		// way to deal with this, but I'm not thinking of it -- Rick
+		if (strpos($item, '(') !== FALSE)
+		{
+			return $item.$alias;
+		}
+		
+		// Is there a table prefix?  If not, no need to insert it
+		if ($this->dbprefix != '')
+		{
+			// Do we prefix an item with no segments?
+			if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix)
+			{
+				$item = $this->dbprefix.$item;
+			}		
+		}
+
+		if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers))
+		{
+			$item = $this->_escape_identifiers($item);
+		}
+		
+		return $item.$alias;
+	}
+
+
+}
+
+
+/* End of file 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 20f0a30..f708910 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -1,355 +1,355 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * Code Igniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Database Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_forge {

-

-	var $fields		 	= array();

-	var $keys			= array();

-	var $primary_keys 	= array();

-	var $db_char_set	=	'';

-

-	/**

-	 * Constructor

-	 *

-	 * Grabs the CI super object instance so we can access it.

-	 *

-	 */	

-	function CI_DB_forge()

-	{

-		// Assign the main database object to $this->db

-		$CI =& get_instance();

-		$this->db =& $CI->db;

-		log_message('debug', "Database Forge Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function create_database($db_name)

-	{

-		$sql = $this->_create_database($db_name);

-		

-		if (is_bool($sql))

-		{

-			return $sql;

-		}

-	

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function drop_database($db_name)

-	{

-		$sql = $this->_drop_database($db_name);

-		

-		if (is_bool($sql))

-		{

-			return $sql;

-		}

-	

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Key

-	 *

-	 * @access	public

-	 * @param	string	key

-	 * @param	string	type

-	 * @return	void

-	 */

-	function add_key($key = '', $primary = FALSE)

-	{

-		if (is_array($key))

-		{

-			foreach($key as $one)

-			{

-				$this->add_key($one, $primary);

-			}

-			

-			return;

-		}

-	

-		if ($key == '')

-		{

-			show_error('Key information is required for that operation.');

-		}

-		

-		if ($primary === TRUE)

-		{

-			$this->primary_keys[] = $key;

-		}

-		else

-		{

-			$this->keys[] = $key;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Field

-	 *

-	 * @access	public

-	 * @param	string	collation

-	 * @return	void

-	 */

-	function add_field($field = '')

-	{

-		if ($field == '')

-		{

-			show_error('Field information is required.');

-		}

-		

-		if (is_string($field))

-		{

-			if ($field == 'id')

-			{

-				$this->add_field(array(

-										'id' => array(

-													'type' => 'INT',

-													'constraint' => 9,

-													'auto_increment' => TRUE

-													)

-								));

-				$this->add_key('id', TRUE);

-			}

-			else

-			{

-				if (strpos($field, ' ') === FALSE)

-				{

-					show_error('Field information is required for that operation.');

-				}

-				

-				$this->fields[] = $field;

-			}

-		}

-		

-		if (is_array($field))

-		{

-			$this->fields = array_merge($this->fields, $field);

-		}

-		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	bool

-	 */

-	function create_table($table = '', $if_not_exists = FALSE)

-	{	

-		if ($table == '')

-		{

-			show_error('A table name is required for that operation.');

-		}

-			

-		if (count($this->fields) == 0)

-		{	

-			show_error('Field information is required.');

-		}

-

-		$sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);

-		

-		$this->_reset();

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	bool

-	 */

-	function drop_table($table_name)

-	{

-		$sql = $this->_drop_table($this->db->dbprefix.$table_name);

-		

-		if (is_bool($sql))

-		{

-			return $sql;

-		}

-	

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename Table

-	 *

-	 * @access	public

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	bool

-	 */

-	function rename_table($table_name, $new_table_name)

-	{

-		if ($table_name == '' OR $new_table_name == '')

-		{

-			show_error('A table name is required for that operation.');

-		}

-			

-		$sql = $this->_rename_table($table_name, $new_table_name);

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Column Add

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	string	the column name

-	 * @param	string	the column definition

-	 * @return	bool

-	 */

-	function add_column($table = '', $field = array(), $after_field = '')

-	{

-		if ($table == '')

-		{

-			show_error('A table name is required for that operation.');

-		}

-

-		// add field info into field array, but we can only do one at a time

-		// so only grab the first field in the event there are more then one

-		$this->add_field(array_slice($field, 0, 1));

-

-		if (count($this->fields) == 0)

-		{	

-			show_error('Field information is required.');

-		}

-

-		$sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);

-

-		$this->_reset();

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Column Drop

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	string	the column name

-	 * @return	bool

-	 */

-	function drop_column($table = '', $column_name = '')

-	{

-	

-		if ($table == '')

-		{

-			show_error('A table name is required for that operation.');

-		}

-

-		if ($column_name == '')

-		{

-			show_error('A column name is required for that operation.');

-		}

-

-		$sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);

-	

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Column Modify

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	string	the column name

-	 * @param	string	the column definition

-	 * @return	bool

-	 */

-	function modify_column($table = '', $field = array())

-	{

-		if ($table == '')

-		{

-			show_error('A table name is required for that operation.');

-		}

-

-		// add field info into field array, but we can only do one at a time

-		// so only grab the first field in the event there are more then one

-		$this->add_field(array_slice($field, 0, 1));

-

-		if (count($this->fields) == 0)

-		{	

-			show_error('Field information is required.');

-		}

-

-		$sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);

-

-		$this->_reset();

-		return $this->db->query($sql);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Reset

-	 *

-	 * Resets table creation vars

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _reset()

-	{

-		$this->fields 		= array();

-		$this->keys			= array();

-		$this->primary_keys 	= array();

-	}

-

-}

-

-/* End of file DB_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Database Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_forge {
+
+	var $fields		 	= array();
+	var $keys			= array();
+	var $primary_keys 	= array();
+	var $db_char_set	=	'';
+
+	/**
+	 * Constructor
+	 *
+	 * Grabs the CI super object instance so we can access it.
+	 *
+	 */	
+	function CI_DB_forge()
+	{
+		// Assign the main database object to $this->db
+		$CI =& get_instance();
+		$this->db =& $CI->db;
+		log_message('debug', "Database Forge Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function create_database($db_name)
+	{
+		$sql = $this->_create_database($db_name);
+		
+		if (is_bool($sql))
+		{
+			return $sql;
+		}
+	
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function drop_database($db_name)
+	{
+		$sql = $this->_drop_database($db_name);
+		
+		if (is_bool($sql))
+		{
+			return $sql;
+		}
+	
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Key
+	 *
+	 * @access	public
+	 * @param	string	key
+	 * @param	string	type
+	 * @return	void
+	 */
+	function add_key($key = '', $primary = FALSE)
+	{
+		if (is_array($key))
+		{
+			foreach($key as $one)
+			{
+				$this->add_key($one, $primary);
+			}
+			
+			return;
+		}
+	
+		if ($key == '')
+		{
+			show_error('Key information is required for that operation.');
+		}
+		
+		if ($primary === TRUE)
+		{
+			$this->primary_keys[] = $key;
+		}
+		else
+		{
+			$this->keys[] = $key;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Field
+	 *
+	 * @access	public
+	 * @param	string	collation
+	 * @return	void
+	 */
+	function add_field($field = '')
+	{
+		if ($field == '')
+		{
+			show_error('Field information is required.');
+		}
+		
+		if (is_string($field))
+		{
+			if ($field == 'id')
+			{
+				$this->add_field(array(
+										'id' => array(
+													'type' => 'INT',
+													'constraint' => 9,
+													'auto_increment' => TRUE
+													)
+								));
+				$this->add_key('id', TRUE);
+			}
+			else
+			{
+				if (strpos($field, ' ') === FALSE)
+				{
+					show_error('Field information is required for that operation.');
+				}
+				
+				$this->fields[] = $field;
+			}
+		}
+		
+		if (is_array($field))
+		{
+			$this->fields = array_merge($this->fields, $field);
+		}
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	bool
+	 */
+	function create_table($table = '', $if_not_exists = FALSE)
+	{	
+		if ($table == '')
+		{
+			show_error('A table name is required for that operation.');
+		}
+			
+		if (count($this->fields) == 0)
+		{	
+			show_error('Field information is required.');
+		}
+
+		$sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
+		
+		$this->_reset();
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	bool
+	 */
+	function drop_table($table_name)
+	{
+		$sql = $this->_drop_table($this->db->dbprefix.$table_name);
+		
+		if (is_bool($sql))
+		{
+			return $sql;
+		}
+	
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename Table
+	 *
+	 * @access	public
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	bool
+	 */
+	function rename_table($table_name, $new_table_name)
+	{
+		if ($table_name == '' OR $new_table_name == '')
+		{
+			show_error('A table name is required for that operation.');
+		}
+			
+		$sql = $this->_rename_table($table_name, $new_table_name);
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Column Add
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	string	the column name
+	 * @param	string	the column definition
+	 * @return	bool
+	 */
+	function add_column($table = '', $field = array(), $after_field = '')
+	{
+		if ($table == '')
+		{
+			show_error('A table name is required for that operation.');
+		}
+
+		// add field info into field array, but we can only do one at a time
+		// so only grab the first field in the event there are more then one
+		$this->add_field(array_slice($field, 0, 1));
+
+		if (count($this->fields) == 0)
+		{	
+			show_error('Field information is required.');
+		}
+
+		$sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);
+
+		$this->_reset();
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Column Drop
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	string	the column name
+	 * @return	bool
+	 */
+	function drop_column($table = '', $column_name = '')
+	{
+	
+		if ($table == '')
+		{
+			show_error('A table name is required for that operation.');
+		}
+
+		if ($column_name == '')
+		{
+			show_error('A column name is required for that operation.');
+		}
+
+		$sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);
+	
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Column Modify
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	string	the column name
+	 * @param	string	the column definition
+	 * @return	bool
+	 */
+	function modify_column($table = '', $field = array())
+	{
+		if ($table == '')
+		{
+			show_error('A table name is required for that operation.');
+		}
+
+		// add field info into field array, but we can only do one at a time
+		// so only grab the first field in the event there are more then one
+		$this->add_field(array_slice($field, 0, 1));
+
+		if (count($this->fields) == 0)
+		{	
+			show_error('Field information is required.');
+		}
+
+		$sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);
+
+		$this->_reset();
+		return $this->db->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Reset
+	 *
+	 * Resets table creation vars
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reset()
+	{
+		$this->fields 		= array();
+		$this->keys			= array();
+		$this->primary_keys 	= array();
+	}
+
+}
+
+/* End of file 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 8f55f67..4128141 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -1,342 +1,342 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Database Result Class

- *

- * This is the platform-independent result class.

- * This class will not be called directly. Rather, the adapter

- * class for the specific database will extend and instantiate it.

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_result {

-

-	var $conn_id		= NULL;

-	var $result_id		= NULL;

-	var $result_array	= array();

-	var $result_object	= array();

-	var $current_row 	= 0;

-	var $num_rows		= 0;

-	var $row_data		= NULL;

-

-

-	/**

-	 * Query result.  Acts as a wrapper function for the following functions.

-	 *

-	 * @access	public

-	 * @param	string	can be "object" or "array"

-	 * @return	mixed	either a result object or array	

-	 */	

-	function result($type = 'object')

-	{	

-		return ($type == 'object') ? $this->result_object() : $this->result_array();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Query result.  "object" version.

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function result_object()

-	{

-		if (count($this->result_object) > 0)

-		{

-			return $this->result_object;

-		}

-		

-		// In the event that query caching is on the result_id variable 

-		// will return FALSE since there isn't a valid SQL resource so 

-		// we'll simply return an empty array.

-		if ($this->result_id === FALSE OR $this->num_rows() == 0)

-		{

-			return array();

-		}

-

-		$this->_data_seek(0);

-		while ($row = $this->_fetch_object())

-		{

-			$this->result_object[] = $row;

-		}

-		

-		return $this->result_object;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Query result.  "array" version.

-	 *

-	 * @access	public

-	 * @return	array

-	 */	

-	function result_array()

-	{

-		if (count($this->result_array) > 0)

-		{

-			return $this->result_array;

-		}

-

-		// In the event that query caching is on the result_id variable 

-		// will return FALSE since there isn't a valid SQL resource so 

-		// we'll simply return an empty array.

-		if ($this->result_id === FALSE OR $this->num_rows() == 0)

-		{

-			return array();

-		}

-

-		$this->_data_seek(0);

-		while ($row = $this->_fetch_assoc())

-		{

-			$this->result_array[] = $row;

-		}

-		

-		return $this->result_array;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Query result.  Acts as a wrapper function for the following functions.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string	can be "object" or "array"

-	 * @return	mixed	either a result object or array	

-	 */	

-	function row($n = 0, $type = 'object')

-	{

-		if ( ! is_numeric($n))

-		{

-			// We cache the row data for subsequent uses

-			if ( ! is_array($this->row_data))

-			{

-				$this->row_data = $this->row_array(0);

-			}

-		

-			// array_key_exists() instead of isset() to allow for MySQL NULL values

-			if (array_key_exists($n, $this->row_data))

-			{

-				return $this->row_data[$n];

-			}

-			// reset the $n variable if the result was not achieved			

-			$n = 0;

-		}

-		

-		return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Assigns an item into a particular column slot

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function set_row($key, $value = NULL)

-	{

-		// We cache the row data for subsequent uses

-		if ( ! is_array($this->row_data))

-		{

-			$this->row_data = $this->row_array(0);

-		}

-	

-		if (is_array($key))

-		{

-			foreach ($key as $k => $v)

-			{

-				$this->row_data[$k] = $v;

-			}

-			

-			return;

-		}

-	

-		if ($key != '' AND ! is_null($value))

-		{

-			$this->row_data[$key] = $value;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns a single result row - object version

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function row_object($n = 0)

-	{

-		$result = $this->result_object();

-		

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-

-		if ($n != $this->current_row AND isset($result[$n]))

-		{

-			$this->current_row = $n;

-		}

-

-		return $result[$this->current_row];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns a single result row - array version

-	 *

-	 * @access	public

-	 * @return	array

-	 */	

-	function row_array($n = 0)

-	{

-		$result = $this->result_array();

-

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-			

-		if ($n != $this->current_row AND isset($result[$n]))

-		{

-			$this->current_row = $n;

-		}

-		

-		return $result[$this->current_row];

-	}

-

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the "first" row

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function first_row($type = 'object')

-	{

-		$result = $this->result($type);

-

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-		return $result[0];

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the "last" row

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function last_row($type = 'object')

-	{

-		$result = $this->result($type);

-

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-		return $result[count($result) -1];

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the "next" row

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function next_row($type = 'object')

-	{

-		$result = $this->result($type);

-

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-

-		if (isset($result[$this->current_row + 1]))

-		{

-			++$this->current_row;

-		}

-				

-		return $result[$this->current_row];

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Returns the "previous" row

-	 *

-	 * @access	public

-	 * @return	object

-	 */	

-	function previous_row($type = 'object')

-	{

-		$result = $this->result($type);

-

-		if (count($result) == 0)

-		{

-			return $result;

-		}

-

-		if (isset($result[$this->current_row - 1]))

-		{

-			--$this->current_row;

-		}

-		return $result[$this->current_row];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The following functions are normally overloaded by the identically named

-	 * methods in the platform-specific driver -- except when query caching

-	 * is used.  When caching is enabled we do not load the other driver.

-	 * These functions are primarily here to prevent undefined function errors

-	 * when a cached result object is in use.  They are not otherwise fully

-	 * operational due to the unavailability of the database resource IDs with

-	 * cached results.

-	 */

-	function num_rows() { return $this->num_rows; }

-	function num_fields() { return 0; }

-	function list_fields() { return array(); }

-	function field_data() { return array(); }	

-	function free_result() { return TRUE; }

-	function _data_seek() { return TRUE; }

-	function _fetch_assoc() { return array(); }	

-	function _fetch_object() { return array(); }

-	

-}

-// END DB_result class

-

-/* End of file DB_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Database Result Class
+ *
+ * This is the platform-independent result class.
+ * This class will not be called directly. Rather, the adapter
+ * class for the specific database will extend and instantiate it.
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_result {
+
+	var $conn_id		= NULL;
+	var $result_id		= NULL;
+	var $result_array	= array();
+	var $result_object	= array();
+	var $current_row 	= 0;
+	var $num_rows		= 0;
+	var $row_data		= NULL;
+
+
+	/**
+	 * Query result.  Acts as a wrapper function for the following functions.
+	 *
+	 * @access	public
+	 * @param	string	can be "object" or "array"
+	 * @return	mixed	either a result object or array	
+	 */	
+	function result($type = 'object')
+	{	
+		return ($type == 'object') ? $this->result_object() : $this->result_array();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "object" version.
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		
+		// In the event that query caching is on the result_id variable 
+		// will return FALSE since there isn't a valid SQL resource so 
+		// we'll simply return an empty array.
+		if ($this->result_id === FALSE OR $this->num_rows() == 0)
+		{
+			return array();
+		}
+
+		$this->_data_seek(0);
+		while ($row = $this->_fetch_object())
+		{
+			$this->result_object[] = $row;
+		}
+		
+		return $this->result_object;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "array" version.
+	 *
+	 * @access	public
+	 * @return	array
+	 */	
+	function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+
+		// In the event that query caching is on the result_id variable 
+		// will return FALSE since there isn't a valid SQL resource so 
+		// we'll simply return an empty array.
+		if ($this->result_id === FALSE OR $this->num_rows() == 0)
+		{
+			return array();
+		}
+
+		$this->_data_seek(0);
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->result_array[] = $row;
+		}
+		
+		return $this->result_array;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  Acts as a wrapper function for the following functions.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string	can be "object" or "array"
+	 * @return	mixed	either a result object or array	
+	 */	
+	function row($n = 0, $type = 'object')
+	{
+		if ( ! is_numeric($n))
+		{
+			// We cache the row data for subsequent uses
+			if ( ! is_array($this->row_data))
+			{
+				$this->row_data = $this->row_array(0);
+			}
+		
+			// array_key_exists() instead of isset() to allow for MySQL NULL values
+			if (array_key_exists($n, $this->row_data))
+			{
+				return $this->row_data[$n];
+			}
+			// reset the $n variable if the result was not achieved			
+			$n = 0;
+		}
+		
+		return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Assigns an item into a particular column slot
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function set_row($key, $value = NULL)
+	{
+		// We cache the row data for subsequent uses
+		if ( ! is_array($this->row_data))
+		{
+			$this->row_data = $this->row_array(0);
+		}
+	
+		if (is_array($key))
+		{
+			foreach ($key as $k => $v)
+			{
+				$this->row_data[$k] = $v;
+			}
+			
+			return;
+		}
+	
+		if ($key != '' AND ! is_null($value))
+		{
+			$this->row_data[$key] = $value;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns a single result row - object version
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function row_object($n = 0)
+	{
+		$result = $this->result_object();
+		
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+
+		if ($n != $this->current_row AND isset($result[$n]))
+		{
+			$this->current_row = $n;
+		}
+
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns a single result row - array version
+	 *
+	 * @access	public
+	 * @return	array
+	 */	
+	function row_array($n = 0)
+	{
+		$result = $this->result_array();
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+			
+		if ($n != $this->current_row AND isset($result[$n]))
+		{
+			$this->current_row = $n;
+		}
+		
+		return $result[$this->current_row];
+	}
+
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "first" row
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function first_row($type = 'object')
+	{
+		$result = $this->result($type);
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+		return $result[0];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "last" row
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function last_row($type = 'object')
+	{
+		$result = $this->result($type);
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+		return $result[count($result) -1];
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "next" row
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function next_row($type = 'object')
+	{
+		$result = $this->result($type);
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+
+		if (isset($result[$this->current_row + 1]))
+		{
+			++$this->current_row;
+		}
+				
+		return $result[$this->current_row];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Returns the "previous" row
+	 *
+	 * @access	public
+	 * @return	object
+	 */	
+	function previous_row($type = 'object')
+	{
+		$result = $this->result($type);
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+
+		if (isset($result[$this->current_row - 1]))
+		{
+			--$this->current_row;
+		}
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The following functions are normally overloaded by the identically named
+	 * methods in the platform-specific driver -- except when query caching
+	 * is used.  When caching is enabled we do not load the other driver.
+	 * These functions are primarily here to prevent undefined function errors
+	 * when a cached result object is in use.  They are not otherwise fully
+	 * operational due to the unavailability of the database resource IDs with
+	 * cached results.
+	 */
+	function num_rows() { return $this->num_rows; }
+	function num_fields() { return 0; }
+	function list_fields() { return array(); }
+	function field_data() { return array(); }	
+	function free_result() { return TRUE; }
+	function _data_seek() { return TRUE; }
+	function _fetch_assoc() { return array(); }	
+	function _fetch_object() { return array(); }
+	
+}
+// END DB_result class
+
+/* End of file 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 a37522d..195e4c4 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -1,389 +1,389 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * Code Igniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Database Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_utility extends CI_DB_forge {

-

-	var $db;

-	var $data_cache 	= array();

-

-	/**

-	 * Constructor

-	 *

-	 * Grabs the CI super object instance so we can access it.

-	 *

-	 */	

-	function CI_DB_utility()

-	{

-		// Assign the main database object to $this->db

-		$CI =& get_instance();

-		$this->db =& $CI->db;

-		

-		log_message('debug', "Database Utility Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List databases

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function list_databases()

-	{	

-		// Is there a cached result?

-		if (isset($this->data_cache['db_names']))

-		{

-			return $this->data_cache['db_names'];

-		}

-	

-		$query = $this->db->query($this->_list_databases());

-		$dbs = array();

-		if ($query->num_rows() > 0)

-		{

-			foreach ($query->result_array() as $row)

-			{

-				$dbs[] = current($row);

-			}

-		}

-			

-		$this->data_cache['db_names'] = $dbs;

-		return $this->data_cache['db_names'];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize Table

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	bool

-	 */

-	function optimize_table($table_name)

-	{

-		$sql = $this->_optimize_table($table_name);

-		

-		if (is_bool($sql))

-		{

-				show_error('db_must_use_set');

-		}

-	

-		$query = $this->db->query($sql);

-		$res = $query->result_array();

-		

-		// Note: Due to a bug in current() that affects some versions

-		// of PHP we can not pass function call directly into it

-		return current($res);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize Database

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function optimize_database()

-	{

-		$result = array();

-		foreach ($this->db->list_tables() as $table_name)

-		{

-			$sql = $this->_optimize_table($table_name);

-			

-			if (is_bool($sql))

-			{

-				return $sql;

-			}

-			

-			$query = $this->db->query($sql);

-			

-			// Build the result array...

-			// Note: Due to a bug in current() that affects some versions

-			// of PHP we can not pass function call directly into it

-			$res = $query->result_array();

-			$res = current($res);

-			$key = str_replace($this->db->database.'.', '', current($res));

-			$keys = array_keys($res);

-			unset($res[$keys[0]]);

-			

-			$result[$key] = $res;

-		}

-

-		return $result;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair Table

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	bool

-	 */

-	function repair_table($table_name)

-	{

-		$sql = $this->_repair_table($table_name);

-		

-		if (is_bool($sql))

-		{

-			return $sql;

-		}

-	

-		$query = $this->db->query($sql);

-		

-		// Note: Due to a bug in current() that affects some versions

-		// of PHP we can not pass function call directly into it

-		$res = $query->result_array();

-		return current($res);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate CSV from a query result object

-	 *

-	 * @access	public

-	 * @param	object	The query result object

-	 * @param	string	The delimiter - comma by default

-	 * @param	string	The newline character - \n by default

-	 * @param	string	The enclosure - double quote by default

-	 * @return	string

-	 */

-	function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')

-	{

-		if ( ! is_object($query) OR ! method_exists($query, 'field_names'))

-		{

-			show_error('You must submit a valid result object');

-		}	

-	

-		$out = '';

-		

-		// First generate the headings from the table column names

-		foreach ($query->list_fields() as $name)

-		{

-			$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;

-		}

-		

-		$out = rtrim($out);

-		$out .= $newline;

-		

-		// Next blast through the result array and build out the rows

-		foreach ($query->result_array() as $row)

-		{

-			foreach ($row as $item)

-			{

-				$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;			

-			}

-			$out = rtrim($out);

-			$out .= $newline;

-		}

-

-		return $out;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate XML data from a query result object

-	 *

-	 * @access	public

-	 * @param	object	The query result object

-	 * @param	array	Any preferences

-	 * @return	string

-	 */

-	function xml_from_result($query, $params = array())

-	{

-		if ( ! is_object($query) OR ! method_exists($query, 'field_names'))

-		{

-			show_error('You must submit a valid result object');

-		}

-		

-		// Set our default values

-		foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)

-		{

-			if ( ! isset($params[$key]))

-			{

-				$params[$key] = $val;

-			}

-		}

-		

-		// Create variables for convenience

-		extract($params);

-			

-		// Load the xml helper

-		$CI =& get_instance();

-		$CI->load->helper('xml');

-

-		// Generate the result

-		$xml = "<{$root}>".$newline;

-		foreach ($query->result_array() as $row)

-		{

-			$xml .= $tab."<{$element}>".$newline;

-			

-			foreach ($row as $key => $val)

-			{

-				$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;

-			}

-			$xml .= $tab."</{$element}>".$newline;

-		}

-		$xml .= "</$root>".$newline;

-		

-		return $xml;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Database Backup

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function backup($params = array())

-	{

-		// If the parameters have not been submitted as an

-		// array then we know that it is simply the table

-		// name, which is a valid short cut.

-		if (is_string($params))

-		{

-			$params = array('tables' => $params);

-		}

-		

-		// ------------------------------------------------------

-	

-		// Set up our default preferences

-		$prefs = array(

-							'tables'		=> array(),

-							'ignore'		=> array(),

-							'filename'		=> '',

-							'format'		=> 'gzip', // gzip, zip, txt

-							'add_drop'		=> TRUE,

-							'add_insert'	=> TRUE,

-							'newline'		=> "\n"

-						);

-

-		// Did the user submit any preferences? If so set them....

-		if (count($params) > 0)

-		{

-			foreach ($prefs as $key => $val)

-			{

-				if (isset($params[$key]))

-				{

-					$prefs[$key] = $params[$key];

-				}

-			}

-		}

-

-		// ------------------------------------------------------

-

-		// Are we backing up a complete database or individual tables?	

-		// If no table names were submitted we'll fetch the entire table list

-		if (count($prefs['tables']) == 0)

-		{

-			$prefs['tables'] = $this->db->list_tables();

-		}

-		

-		// ------------------------------------------------------

-

-		// Validate the format

-		if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))

-		{

-			$prefs['format'] = 'txt';

-		}

-

-		// ------------------------------------------------------

-

-		// Is the encoder supported?  If not, we'll either issue an

-		// error or use plain text depending on the debug settings

-		if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))

-		 OR ($prefs['format'] == 'zip'  AND ! @function_exists('gzcompress')))

-		{

-			if ($this->db->db_debug)

-			{

-				return $this->db->display_error('db_unsuported_compression');

-			}

-		

-			$prefs['format'] = 'txt';

-		}

-

-		// ------------------------------------------------------

-

-		// Set the filename if not provided - Only needed with Zip files

-		if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')

-		{

-			$prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;

-			$prefs['filename'] .= '_'.date('Y-m-d_H-i', time());

-		}

-

-		// ------------------------------------------------------

-				

-		// Was a Gzip file requested?

-		if ($prefs['format'] == 'gzip')

-		{

-			return gzencode($this->_backup($prefs));

-		}

-

-		// ------------------------------------------------------

-		

-		// Was a text file requested?

-		if ($prefs['format'] == 'txt')

-		{

-			return $this->_backup($prefs);

-		}

-

-		// ------------------------------------------------------

-

-		// Was a Zip file requested?		

-		if ($prefs['format'] == 'zip')

-		{

-			// If they included the .zip file extension we'll remove it

-			if (preg_match("|.+?\.zip$|", $prefs['filename']))

-			{

-				$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);

-			}

-			

-			// Tack on the ".sql" file extension if needed

-			if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))

-			{

-				$prefs['filename'] .= '.sql';

-			}

-

-			// Load the Zip class and output it

-			

-			$CI =& get_instance();

-			$CI->load->library('zip');

-			$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));							

-			return $CI->zip->get_zip();

-		}

-		

-	}

-

-}

-

-

-/* End of file DB_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * Code Igniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Database Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_utility extends CI_DB_forge {
+
+	var $db;
+	var $data_cache 	= array();
+
+	/**
+	 * Constructor
+	 *
+	 * Grabs the CI super object instance so we can access it.
+	 *
+	 */	
+	function CI_DB_utility()
+	{
+		// Assign the main database object to $this->db
+		$CI =& get_instance();
+		$this->db =& $CI->db;
+		
+		log_message('debug', "Database Utility Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List databases
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function list_databases()
+	{	
+		// Is there a cached result?
+		if (isset($this->data_cache['db_names']))
+		{
+			return $this->data_cache['db_names'];
+		}
+	
+		$query = $this->db->query($this->_list_databases());
+		$dbs = array();
+		if ($query->num_rows() > 0)
+		{
+			foreach ($query->result_array() as $row)
+			{
+				$dbs[] = current($row);
+			}
+		}
+			
+		$this->data_cache['db_names'] = $dbs;
+		return $this->data_cache['db_names'];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize Table
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	bool
+	 */
+	function optimize_table($table_name)
+	{
+		$sql = $this->_optimize_table($table_name);
+		
+		if (is_bool($sql))
+		{
+				show_error('db_must_use_set');
+		}
+	
+		$query = $this->db->query($sql);
+		$res = $query->result_array();
+		
+		// Note: Due to a bug in current() that affects some versions
+		// of PHP we can not pass function call directly into it
+		return current($res);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize Database
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function optimize_database()
+	{
+		$result = array();
+		foreach ($this->db->list_tables() as $table_name)
+		{
+			$sql = $this->_optimize_table($table_name);
+			
+			if (is_bool($sql))
+			{
+				return $sql;
+			}
+			
+			$query = $this->db->query($sql);
+			
+			// Build the result array...
+			// Note: Due to a bug in current() that affects some versions
+			// of PHP we can not pass function call directly into it
+			$res = $query->result_array();
+			$res = current($res);
+			$key = str_replace($this->db->database.'.', '', current($res));
+			$keys = array_keys($res);
+			unset($res[$keys[0]]);
+			
+			$result[$key] = $res;
+		}
+
+		return $result;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair Table
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	bool
+	 */
+	function repair_table($table_name)
+	{
+		$sql = $this->_repair_table($table_name);
+		
+		if (is_bool($sql))
+		{
+			return $sql;
+		}
+	
+		$query = $this->db->query($sql);
+		
+		// Note: Due to a bug in current() that affects some versions
+		// of PHP we can not pass function call directly into it
+		$res = $query->result_array();
+		return current($res);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate CSV from a query result object
+	 *
+	 * @access	public
+	 * @param	object	The query result object
+	 * @param	string	The delimiter - comma by default
+	 * @param	string	The newline character - \n by default
+	 * @param	string	The enclosure - double quote by default
+	 * @return	string
+	 */
+	function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
+	{
+		if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+		{
+			show_error('You must submit a valid result object');
+		}	
+	
+		$out = '';
+		
+		// First generate the headings from the table column names
+		foreach ($query->list_fields() as $name)
+		{
+			$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
+		}
+		
+		$out = rtrim($out);
+		$out .= $newline;
+		
+		// Next blast through the result array and build out the rows
+		foreach ($query->result_array() as $row)
+		{
+			foreach ($row as $item)
+			{
+				$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;			
+			}
+			$out = rtrim($out);
+			$out .= $newline;
+		}
+
+		return $out;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate XML data from a query result object
+	 *
+	 * @access	public
+	 * @param	object	The query result object
+	 * @param	array	Any preferences
+	 * @return	string
+	 */
+	function xml_from_result($query, $params = array())
+	{
+		if ( ! is_object($query) OR ! method_exists($query, 'field_names'))
+		{
+			show_error('You must submit a valid result object');
+		}
+		
+		// Set our default values
+		foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
+		{
+			if ( ! isset($params[$key]))
+			{
+				$params[$key] = $val;
+			}
+		}
+		
+		// Create variables for convenience
+		extract($params);
+			
+		// Load the xml helper
+		$CI =& get_instance();
+		$CI->load->helper('xml');
+
+		// Generate the result
+		$xml = "<{$root}>".$newline;
+		foreach ($query->result_array() as $row)
+		{
+			$xml .= $tab."<{$element}>".$newline;
+			
+			foreach ($row as $key => $val)
+			{
+				$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
+			}
+			$xml .= $tab."</{$element}>".$newline;
+		}
+		$xml .= "</$root>".$newline;
+		
+		return $xml;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database Backup
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function backup($params = array())
+	{
+		// If the parameters have not been submitted as an
+		// array then we know that it is simply the table
+		// name, which is a valid short cut.
+		if (is_string($params))
+		{
+			$params = array('tables' => $params);
+		}
+		
+		// ------------------------------------------------------
+	
+		// Set up our default preferences
+		$prefs = array(
+							'tables'		=> array(),
+							'ignore'		=> array(),
+							'filename'		=> '',
+							'format'		=> 'gzip', // gzip, zip, txt
+							'add_drop'		=> TRUE,
+							'add_insert'	=> TRUE,
+							'newline'		=> "\n"
+						);
+
+		// Did the user submit any preferences? If so set them....
+		if (count($params) > 0)
+		{
+			foreach ($prefs as $key => $val)
+			{
+				if (isset($params[$key]))
+				{
+					$prefs[$key] = $params[$key];
+				}
+			}
+		}
+
+		// ------------------------------------------------------
+
+		// Are we backing up a complete database or individual tables?	
+		// If no table names were submitted we'll fetch the entire table list
+		if (count($prefs['tables']) == 0)
+		{
+			$prefs['tables'] = $this->db->list_tables();
+		}
+		
+		// ------------------------------------------------------
+
+		// Validate the format
+		if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
+		{
+			$prefs['format'] = 'txt';
+		}
+
+		// ------------------------------------------------------
+
+		// Is the encoder supported?  If not, we'll either issue an
+		// error or use plain text depending on the debug settings
+		if (($prefs['format'] == 'gzip' AND ! @function_exists('gzencode'))
+		 OR ($prefs['format'] == 'zip'  AND ! @function_exists('gzcompress')))
+		{
+			if ($this->db->db_debug)
+			{
+				return $this->db->display_error('db_unsuported_compression');
+			}
+		
+			$prefs['format'] = 'txt';
+		}
+
+		// ------------------------------------------------------
+
+		// Set the filename if not provided - Only needed with Zip files
+		if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
+		{
+			$prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
+			$prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
+		}
+
+		// ------------------------------------------------------
+				
+		// Was a Gzip file requested?
+		if ($prefs['format'] == 'gzip')
+		{
+			return gzencode($this->_backup($prefs));
+		}
+
+		// ------------------------------------------------------
+		
+		// Was a text file requested?
+		if ($prefs['format'] == 'txt')
+		{
+			return $this->_backup($prefs);
+		}
+
+		// ------------------------------------------------------
+
+		// Was a Zip file requested?		
+		if ($prefs['format'] == 'zip')
+		{
+			// If they included the .zip file extension we'll remove it
+			if (preg_match("|.+?\.zip$|", $prefs['filename']))
+			{
+				$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
+			}
+			
+			// Tack on the ".sql" file extension if needed
+			if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
+			{
+				$prefs['filename'] .= '.sql';
+			}
+
+			// Load the Zip class and output it
+			
+			$CI =& get_instance();
+			$CI->load->library('zip');
+			$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));							
+			return $CI->zip->get_zip();
+		}
+		
+	}
+
+}
+
+
+/* End of file DB_utility.php */
 /* Location: ./system/database/DB_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/index.html b/system/database/drivers/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/index.html
+++ b/system/database/drivers/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/mssql/index.html b/system/database/drivers/mssql/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/mssql/index.html
+++ b/system/database/drivers/mssql/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 6ad0880..78f81da 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -1,622 +1,622 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MS SQL Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mssql_driver extends CI_DB {

-

-	var $dbdriver = 'mssql';

-	

-	// The character used for escaping

-	var $_escape_char = '';

-	/**

-	 * The syntax to count rows is slightly different across different

-	 * database engines, so this string appears in each driver and is

-	 * used for the count_all() and count_all_results() functions.

-	 */

-	var $_count_string = "SELECT COUNT(*) AS ";

-	var $_random_keyword = ' ASC'; // not currently supported

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{

-		if ($this->port != '')

-		{

-			$this->hostname .= ','.$this->port;

-		}

-

-		return @mssql_connect($this->hostname, $this->username, $this->password);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		if ($this->port != '')

-		{

-			$this->hostname .= ','.$this->port;

-		}

-

-		return @mssql_pconnect($this->hostname, $this->username, $this->password);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		// Note: The brackets are required in the event that the DB name

-		// contains reserved characters

-		return @mssql_select_db('['.$this->database.']', $this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		// @todo - add support if needed

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	function _execute($sql)

-	{

-		$sql = $this->_prep_query($sql);

-		return @mssql_query($sql, $this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Prep the query

-	 *

-	 * If needed, each database adapter can prep the query string

-	 *

-	 * @access	private called by execute()

-	 * @param	string	an SQL query

-	 * @return	string

-	 */	

-	function _prep_query($sql)

-	{

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Begin Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-

-		$this->simple_query('BEGIN TRAN');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('COMMIT TRAN');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('ROLLBACK TRAN');

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{

-		// Access the CI object

-		$CI =& get_instance();

-		

-		// Escape single quotes

-		return str_replace("'", "''", $CI->input->_remove_invisible_characters($str));

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return @mssql_rows_affected($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	* Insert ID

-	*

-	* Returns the last id created in the Identity column.

-	*

-	* @access public

-	* @return integer

-	*/

-	function insert_id()

-	{

-		$ver = self::_parse_major_version($this->version());

-		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");

-		$query = $this->query($sql);

-		$row = $query->row();

-		return $row->last_id;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Parse major version

-	*

-	* Grabs the major version number from the 

-	* database server version string passed in.

-	*

-	* @access private

-	* @param string $version

-	* @return int16 major version number

-	*/

-	function _parse_major_version($version)

-	{

-		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);

-		return $ver_info[1]; // return the major version b/c that's all we're interested in.

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Version number query string

-	*

-	* @access public

-	* @return string

-	*/

-	function _version()

-	{

-		return "SELECT @@VERSION AS ver";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-	

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";

-		

-		// for future compatibility

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			//$sql .= " LIKE '".$this->dbprefix."%'";

-			return FALSE; // not currently supported

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List column query

-	 *

-	 * Generates a platform-specific query string so that the column names can be fetched

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	string

-	 */

-	function _list_columns($table = '')

-	{

-		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT TOP 1 * FROM ".$table;	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		// Are errros even supported in MS SQL?

-		return '';

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		// Are error numbers supported?

-		return '';

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return implode(', ', $tables);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return "TRUNCATE ".$table;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{

-		$i = $limit + $offset;

-	

-		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@mssql_close($conn_id);

-	}	

-

-}

-

-

-

-/* End of file mssql_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MS SQL Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mssql_driver extends CI_DB {
+
+	var $dbdriver = 'mssql';
+	
+	// The character used for escaping
+	var $_escape_char = '';
+	/**
+	 * The syntax to count rows is slightly different across different
+	 * database engines, so this string appears in each driver and is
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	var $_count_string = "SELECT COUNT(*) AS ";
+	var $_random_keyword = ' ASC'; // not currently supported
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		if ($this->port != '')
+		{
+			$this->hostname .= ','.$this->port;
+		}
+
+		return @mssql_connect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		if ($this->port != '')
+		{
+			$this->hostname .= ','.$this->port;
+		}
+
+		return @mssql_pconnect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		// Note: The brackets are required in the event that the DB name
+		// contains reserved characters
+		return @mssql_select_db('['.$this->database.']', $this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// @todo - add support if needed
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	function _execute($sql)
+	{
+		$sql = $this->_prep_query($sql);
+		return @mssql_query($sql, $this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Prep the query
+	 *
+	 * If needed, each database adapter can prep the query string
+	 *
+	 * @access	private called by execute()
+	 * @param	string	an SQL query
+	 * @return	string
+	 */	
+	function _prep_query($sql)
+	{
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+		$this->simple_query('BEGIN TRAN');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('COMMIT TRAN');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('ROLLBACK TRAN');
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		// Access the CI object
+		$CI =& get_instance();
+		
+		// Escape single quotes
+		return str_replace("'", "''", $CI->input->_remove_invisible_characters($str));
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mssql_rows_affected($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	* Insert ID
+	*
+	* Returns the last id created in the Identity column.
+	*
+	* @access public
+	* @return integer
+	*/
+	function insert_id()
+	{
+		$ver = self::_parse_major_version($this->version());
+		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
+		$query = $this->query($sql);
+		$row = $query->row();
+		return $row->last_id;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Parse major version
+	*
+	* Grabs the major version number from the 
+	* database server version string passed in.
+	*
+	* @access private
+	* @param string $version
+	* @return int16 major version number
+	*/
+	function _parse_major_version($version)
+	{
+		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
+		return $ver_info[1]; // return the major version b/c that's all we're interested in.
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Version number query string
+	*
+	* @access public
+	* @return string
+	*/
+	function _version()
+	{
+		return "SELECT @@VERSION AS ver";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
+		
+		// for future compatibility
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			//$sql .= " LIKE '".$this->dbprefix."%'";
+			return FALSE; // not currently supported
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List column query
+	 *
+	 * Generates a platform-specific query string so that the column names can be fetched
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	function _list_columns($table = '')
+	{
+		return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$table."'";	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT TOP 1 * FROM ".$table;	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		// Are errros even supported in MS SQL?
+		return '';
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		// Are error numbers supported?
+		return '';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return implode(', ', $tables);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return "TRUNCATE ".$table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{
+		$i = $limit + $offset;
+	
+		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@mssql_close($conn_id);
+	}	
+
+}
+
+
+
+/* End of file 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 8665dc0..512fc47 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_forge.php
@@ -1,248 +1,248 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MS SQL Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mssql_forge extends CI_DB_forge {

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _drop_table($table)

-	{

-		return "DROP TABLE ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @param	array	the fields

-	 * @param	mixed	primary key(s)

-	 * @param	mixed	key(s)

-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-		$current_field_count = 0;

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-				

-				$sql .=  ' '.$attributes['TYPE'];

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)

-				{

-					$sql .= ' NULL';

-				}

-				else

-				{

-					$sql .= ' NOT NULL';			

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-

-		if (count($primary_keys) > 0)

-		{

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";

-		}

-		

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key = array($this->db->_protect_identifiers($key));

-				}

-				

-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";

-			}

-		}

-		

-		$sql .= "\n)";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	string	the table name

-	 * @param	string	the column definition

-	 * @param	string	the default value

-	 * @param	boolean	should 'NOT NULL' be added

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql;

-		}

-

-		$sql .= " $column_definition";

-

-		if ($default_value != '')

-		{

-			$sql .= " DEFAULT \"$default_value\"";

-		}

-

-		if ($null === NULL)

-		{

-			$sql .= ' NULL';

-		}

-		else

-		{

-			$sql .= ' NOT NULL';

-		}

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-}

-

-/* End of file mssql_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MS SQL Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mssql_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _drop_table($table)
+	{
+		return "DROP TABLE ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+		$current_field_count = 0;
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+				
+				$sql .=  ' '.$attributes['TYPE'];
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+				{
+					$sql .= ' NULL';
+				}
+				else
+				{
+					$sql .= ' NOT NULL';			
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+		}
+		
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key = array($this->db->_protect_identifiers($key));
+				}
+				
+				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+			}
+		}
+		
+		$sql .= "\n)";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql;
+		}
+
+		$sql .= " $column_definition";
+
+		if ($default_value != '')
+		{
+			$sql .= " DEFAULT \"$default_value\"";
+		}
+
+		if ($null === NULL)
+		{
+			$sql .= ' NULL';
+		}
+		else
+		{
+			$sql .= ' NOT NULL';
+		}
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+}
+
+/* End of file 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 33fdda9..e9679cb 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_result.php
@@ -1,169 +1,169 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MS SQL Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mssql_result extends CI_DB_result {

-	

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @mssql_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @mssql_num_fields($this->result_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		while ($field = mssql_fetch_field($this->result_id))

-		{

-			$field_names[] = $field->name;

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		while ($field = mssql_fetch_field($this->result_id))

-		{	

-			$F 				= new stdClass();

-			$F->name 		= $field->name;

-			$F->type 		= $field->type;

-			$F->max_length	= $field->max_length;

-			$F->primary_key = 0;

-			$F->default		= '';

-			

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_resource($this->result_id))

-		{

-			mssql_free_result($this->result_id);

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return mssql_data_seek($this->result_id, $n);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		return mssql_fetch_assoc($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		return mssql_fetch_object($this->result_id);

-	}

-

-}

-

-

-/* End of file mssql_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MS SQL Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mssql_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mssql_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mssql_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		while ($field = mssql_fetch_field($this->result_id))
+		{
+			$field_names[] = $field->name;
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mssql_fetch_field($this->result_id))
+		{	
+			$F 				= new stdClass();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = 0;
+			$F->default		= '';
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_resource($this->result_id))
+		{
+			mssql_free_result($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return mssql_data_seek($this->result_id, $n);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mssql_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return mssql_fetch_object($this->result_id);
+	}
+
+}
+
+
+/* End of file mssql_result.php */
 /* Location: ./system/database/drivers/mssql/mssql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index 1736fba..38118ac 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_utility.php
@@ -1,123 +1,123 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MS SQL Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mssql_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Generates a platform-specific query so that a table can be optimized

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return FALSE; // Is this supported in MS SQL?

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Repair table query

-	 *

-	 * Generates a platform-specific query so that a table can be repaired

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return FALSE; // Is this supported in MS SQL?

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * MSSQL Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-}

-

-

-/* End of file mssql_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MS SQL Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mssql_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Generates a platform-specific query so that a table can be optimized
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return FALSE; // Is this supported in MS SQL?
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Repair table query
+	 *
+	 * Generates a platform-specific query so that a table can be repaired
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return FALSE; // Is this supported in MS SQL?
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * MSSQL Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+}
+
+
+/* End of file mssql_utility.php */
 /* Location: ./system/database/drivers/mssql/mssql_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/index.html b/system/database/drivers/mysql/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/mysql/index.html
+++ b/system/database/drivers/mysql/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 45bf771..943b3c0 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -1,634 +1,634 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQL Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysql_driver extends CI_DB {

-

-	var $dbdriver = 'mysql';

-

-	// The character used for escaping

-	var	$_escape_char = '`';

-	

-	/**

-	 * Whether to use the MySQL "delete hack" which allows the number

-	 * of affected rows to be shown. Uses a preg_replace when enabled,

-	 * adding a bit more processing to all queries.

-	 */	

-	var $delete_hack = TRUE;

-	

-	/**

-	 * 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

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{

-		if ($this->port != '')

-		{

-			$this->hostname .= ':'.$this->port;

-		}

-		

-		return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		if ($this->port != '')

-		{

-			$this->hostname .= ':'.$this->port;

-		}

-

-		return @mysql_pconnect($this->hostname, $this->username, $this->password);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		return @mysql_select_db($this->database, $this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _version()

-	{

-		return "SELECT version() AS ver";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	function _execute($sql)

-	{

-		$sql = $this->_prep_query($sql);

-		return @mysql_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)

-	{

-		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies

-		// the query so that it returns the number of affected rows

-		if ($this->delete_hack === TRUE)

-		{

-			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))

-			{

-				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);

-			}

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Begin Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-		

-		$this->simple_query('SET AUTOCOMMIT=0');

-		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('COMMIT');

-		$this->simple_query('SET AUTOCOMMIT=1');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('ROLLBACK');

-		$this->simple_query('SET AUTOCOMMIT=1');

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{	

-		if (is_array($str))

-		{

-			foreach($str as $key => $val)

-	   		{

-				$str[$key] = $this->escape_str($val);

-	   		}

-   		

-	   		return $str;

-	   	}

-

-		if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))

-		{

-			return mysql_real_escape_string($str, $this->conn_id);

-		}

-		elseif (function_exists('mysql_escape_string'))

-		{

-			return mysql_escape_string($str);

-		}

-		else

-		{

-			return addslashes($str);

-		}

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return @mysql_affected_rows($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function insert_id()

-	{

-		return @mysql_insert_id($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-	

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-		

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return (int)$row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;	

-

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			$sql .= " LIKE '".$this->dbprefix."%'";

-		}

-

-		return $sql;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		return "SHOW COLUMNS FROM ".$table;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT * FROM ".$table." LIMIT 1";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		return mysql_error($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		return mysql_errno($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-		

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-	

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-			

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return '('.implode(', ', $tables).')';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return "TRUNCATE ".$table;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{	

-		if ($offset == 0)

-		{

-			$offset = '';

-		}

-		else

-		{

-			$offset .= ", ";

-		}

-		

-		return $sql."LIMIT ".$offset.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@mysql_close($conn_id);

-	}

-	

-}

-

-

-/* End of file mysql_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQL Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysql_driver extends CI_DB {
+
+	var $dbdriver = 'mysql';
+
+	// The character used for escaping
+	var	$_escape_char = '`';
+	
+	/**
+	 * Whether to use the MySQL "delete hack" which allows the number
+	 * of affected rows to be shown. Uses a preg_replace when enabled,
+	 * adding a bit more processing to all queries.
+	 */	
+	var $delete_hack = TRUE;
+	
+	/**
+	 * 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
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		if ($this->port != '')
+		{
+			$this->hostname .= ':'.$this->port;
+		}
+		
+		return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		if ($this->port != '')
+		{
+			$this->hostname .= ':'.$this->port;
+		}
+
+		return @mysql_pconnect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return @mysql_select_db($this->database, $this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	function _execute($sql)
+	{
+		$sql = $this->_prep_query($sql);
+		return @mysql_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)
+	{
+		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
+		// the query so that it returns the number of affected rows
+		if ($this->delete_hack === TRUE)
+		{
+			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
+			{
+				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
+			}
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		
+		$this->simple_query('SET AUTOCOMMIT=0');
+		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('COMMIT');
+		$this->simple_query('SET AUTOCOMMIT=1');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('ROLLBACK');
+		$this->simple_query('SET AUTOCOMMIT=1');
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		if (is_array($str))
+		{
+			foreach($str as $key => $val)
+	   		{
+				$str[$key] = $this->escape_str($val);
+	   		}
+   		
+	   		return $str;
+	   	}
+
+		if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
+		{
+			return mysql_real_escape_string($str, $this->conn_id);
+		}
+		elseif (function_exists('mysql_escape_string'))
+		{
+			return mysql_escape_string($str);
+		}
+		else
+		{
+			return addslashes($str);
+		}
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mysql_affected_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @mysql_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return (int)$row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;	
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " LIKE '".$this->dbprefix."%'";
+		}
+
+		return $sql;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SHOW COLUMNS FROM ".$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." LIMIT 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return mysql_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return mysql_errno($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+		
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+	
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+			
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return "TRUNCATE ".$table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{	
+		if ($offset == 0)
+		{
+			$offset = '';
+		}
+		else
+		{
+			$offset .= ", ";
+		}
+		
+		return $sql."LIMIT ".$offset.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@mysql_close($conn_id);
+	}
+	
+}
+
+
+/* End of file mysql_driver.php */
 /* Location: ./system/database/drivers/mysql/mysql_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index 28a77b3..d8cb77e 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -1,254 +1,254 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQL Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysql_forge extends CI_DB_forge {

-	

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Process Fields

-	 *

-	 * @access	private

-	 * @param	mixed	the fields

-	 * @return	string

-	 */

-	function _process_fields($fields)

-	{

-		$current_field_count = 0;

-		$sql = '';

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-

-				if (array_key_exists('NAME', $attributes))

-				{

-					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';

-				}

-				

-				if (array_key_exists('TYPE', $attributes))

-				{

-					$sql .=  ' '.$attributes['TYPE'];

-				}

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes))

-				{

-					$sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * 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

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-

-		$sql .= $this->_process_fields($fields);

-

-		if (count($primary_keys) > 0)

-		{

-			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";

-		}

-

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key_name = $this->db->_protect_identifiers(implode('_', $key));

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key_name = $this->db->_protect_identifiers($key);

-					$key = array($key_name);

-				}

-				

-				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";

-			}

-		}

-

-		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _drop_table($table)

-	{

-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	array	fields

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $fields, $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql.$this->db->_protect_identifiers($fields);

-		}

-

-		$sql .= $this->_process_fields($fields);

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-}

-

-/* End of file mysql_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQL Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysql_forge extends CI_DB_forge {
+	
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Process Fields
+	 *
+	 * @access	private
+	 * @param	mixed	the fields
+	 * @return	string
+	 */
+	function _process_fields($fields)
+	{
+		$current_field_count = 0;
+		$sql = '';
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+
+				if (array_key_exists('NAME', $attributes))
+				{
+					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
+				}
+				
+				if (array_key_exists('TYPE', $attributes))
+				{
+					$sql .=  ' '.$attributes['TYPE'];
+				}
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes))
+				{
+					$sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+
+		$sql .= $this->_process_fields($fields);
+
+		if (count($primary_keys) > 0)
+		{
+			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key_name = $this->db->_protect_identifiers(implode('_', $key));
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key_name = $this->db->_protect_identifiers($key);
+					$key = array($key_name);
+				}
+				
+				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _drop_table($table)
+	{
+		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	array	fields
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql.$this->db->_protect_identifiers($fields);
+		}
+
+		$sql .= $this->_process_fields($fields);
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+}
+
+/* End of file 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 a28a198..673aeac 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -1,169 +1,169 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// --------------------------------------------------------------------

-

-/**

- * MySQL Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysql_result extends CI_DB_result {

-

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @mysql_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @mysql_num_fields($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		while ($field = mysql_fetch_field($this->result_id))

-		{

-			$field_names[] = $field->name;

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		while ($field = mysql_fetch_field($this->result_id))

-		{	

-			$F				= new stdClass();

-			$F->name 		= $field->name;

-			$F->type 		= $field->type;

-			$F->default		= $field->def;

-			$F->max_length	= $field->max_length;

-			$F->primary_key = $field->primary_key;

-			

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_resource($this->result_id))

-		{

-			mysql_free_result($this->result_id);

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return mysql_data_seek($this->result_id, $n);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		return mysql_fetch_assoc($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		return mysql_fetch_object($this->result_id);

-	}

-	

-}

-

-

-/* End of file mysql_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// --------------------------------------------------------------------
+
+/**
+ * MySQL Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysql_result extends CI_DB_result {
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mysql_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mysql_num_fields($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		while ($field = mysql_fetch_field($this->result_id))
+		{
+			$field_names[] = $field->name;
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mysql_fetch_field($this->result_id))
+		{	
+			$F				= new stdClass();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->default		= $field->def;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = $field->primary_key;
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_resource($this->result_id))
+		{
+			mysql_free_result($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return mysql_data_seek($this->result_id, $n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mysql_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return mysql_fetch_object($this->result_id);
+	}
+	
+}
+
+
+/* End of file mysql_result.php */
 /* Location: ./system/database/drivers/mysql/mysql_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index d2c10db..003b1dd 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -1,245 +1,245 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQL Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysql_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		return "SHOW DATABASES";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Generates a platform-specific query so that a table can be optimized

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Generates a platform-specific query so that a table can be repaired

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-	/**

-	 * MySQL Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		if (count($params) == 0)

-		{

-			return FALSE;

-		}

-

-		// Extract the prefs for simplicity

-		extract($params);

-	

-		// Build the output

-		$output = '';

-		foreach ((array)$tables as $table)

-		{

-			// Is the table in the "ignore" list?

-			if (in_array($table, (array)$ignore, TRUE))

-			{

-				continue;

-			}

-

-			// Get the table schema

-			$query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.'.$table);

-			

-			// No result means the table name was invalid

-			if ($query === FALSE)

-			{

-				continue;

-			}

-			

-			// Write out the table schema

-			$output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;

-

- 			if ($add_drop == TRUE)

- 			{

-				$output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;

-			}

-			

-			$i = 0;

-			$result = $query->result_array();

-			foreach ($result[0] as $val)

-			{

-				if ($i++ % 2)

-				{ 					

-					$output .= $val.';'.$newline.$newline;

-				}

-			}

-			

-			// If inserts are not needed we're done...

-			if ($add_insert == FALSE)

-			{

-				continue;

-			}

-

-			// Grab all the data from the current table

-			$query = $this->db->query("SELECT * FROM $table");

-			

-			if ($query->num_rows() == 0)

-			{

-				continue;

-			}

-		

-			// Fetch the field names and determine if the field is an

-			// integer type.  We use this info to decide whether to

-			// surround the data with quotes or not

-			

-			$i = 0;

-			$field_str = '';

-			$is_int = array();

-			while ($field = mysql_fetch_field($query->result_id))

-			{

-				// Most versions of MySQL store timestamp as a string

-				$is_int[$i] = (in_array(

-										strtolower(mysql_field_type($query->result_id, $i)),

-										array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), 

-										TRUE)

-										) ? TRUE : FALSE;

-										

-				// Create a string of field names

-				$field_str .= '`'.$field->name.'`, ';

-				$i++;

-			}

-			

-			// Trim off the end comma

-			$field_str = preg_replace( "/, $/" , "" , $field_str);

-			

-			

-			// Build the insert string

-			foreach ($query->result_array() as $row)

-			{

-				$val_str = '';

-			

-				$i = 0;

-				foreach ($row as $v)

-				{

-					// Is the value NULL?

-					if ($v === NULL)

-					{

-						$val_str .= 'NULL';

-					}

-					else

-					{

-						// Escape the data if it's not an integer

-						if ($is_int[$i] == FALSE)

-						{

-							$val_str .= $this->db->escape($v);

-						}

-						else

-						{

-							$val_str .= $v;

-						}					

-					}					

-					

-					// Append a comma

-					$val_str .= ', ';

-					$i++;

-				}

-				

-				// Remove the comma at the end of the string

-				$val_str = preg_replace( "/, $/" , "" , $val_str);

-								

-				// Build the INSERT string

-				$output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;

-			}

-			

-			$output .= $newline.$newline;

-		}

-

-		return $output;

-	}

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-}

-

-/* End of file mysql_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQL Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysql_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		return "SHOW DATABASES";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Generates a platform-specific query so that a table can be optimized
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Generates a platform-specific query so that a table can be repaired
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+	/**
+	 * MySQL Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		if (count($params) == 0)
+		{
+			return FALSE;
+		}
+
+		// Extract the prefs for simplicity
+		extract($params);
+	
+		// Build the output
+		$output = '';
+		foreach ((array)$tables as $table)
+		{
+			// Is the table in the "ignore" list?
+			if (in_array($table, (array)$ignore, TRUE))
+			{
+				continue;
+			}
+
+			// Get the table schema
+			$query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.'.$table);
+			
+			// No result means the table name was invalid
+			if ($query === FALSE)
+			{
+				continue;
+			}
+			
+			// Write out the table schema
+			$output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;
+
+ 			if ($add_drop == TRUE)
+ 			{
+				$output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;
+			}
+			
+			$i = 0;
+			$result = $query->result_array();
+			foreach ($result[0] as $val)
+			{
+				if ($i++ % 2)
+				{ 					
+					$output .= $val.';'.$newline.$newline;
+				}
+			}
+			
+			// If inserts are not needed we're done...
+			if ($add_insert == FALSE)
+			{
+				continue;
+			}
+
+			// Grab all the data from the current table
+			$query = $this->db->query("SELECT * FROM $table");
+			
+			if ($query->num_rows() == 0)
+			{
+				continue;
+			}
+		
+			// Fetch the field names and determine if the field is an
+			// integer type.  We use this info to decide whether to
+			// surround the data with quotes or not
+			
+			$i = 0;
+			$field_str = '';
+			$is_int = array();
+			while ($field = mysql_fetch_field($query->result_id))
+			{
+				// Most versions of MySQL store timestamp as a string
+				$is_int[$i] = (in_array(
+										strtolower(mysql_field_type($query->result_id, $i)),
+										array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'), 
+										TRUE)
+										) ? TRUE : FALSE;
+										
+				// Create a string of field names
+				$field_str .= '`'.$field->name.'`, ';
+				$i++;
+			}
+			
+			// Trim off the end comma
+			$field_str = preg_replace( "/, $/" , "" , $field_str);
+			
+			
+			// Build the insert string
+			foreach ($query->result_array() as $row)
+			{
+				$val_str = '';
+			
+				$i = 0;
+				foreach ($row as $v)
+				{
+					// Is the value NULL?
+					if ($v === NULL)
+					{
+						$val_str .= 'NULL';
+					}
+					else
+					{
+						// Escape the data if it's not an integer
+						if ($is_int[$i] == FALSE)
+						{
+							$val_str .= $this->db->escape($v);
+						}
+						else
+						{
+							$val_str .= $v;
+						}					
+					}					
+					
+					// Append a comma
+					$val_str .= ', ';
+					$i++;
+				}
+				
+				// Remove the comma at the end of the string
+				$val_str = preg_replace( "/, $/" , "" , $val_str);
+								
+				// Build the INSERT string
+				$output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
+			}
+			
+			$output .= $newline.$newline;
+		}
+
+		return $output;
+	}
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+}
+
+/* End of file mysql_utility.php */
 /* Location: ./system/database/drivers/mysql/mysql_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/index.html b/system/database/drivers/mysqli/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/mysqli/index.html
+++ b/system/database/drivers/mysqli/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 1b3da7a..ce458f2 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -1,625 +1,625 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQLi Database Adapter Class - MySQLi only works with PHP 5

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysqli_driver extends CI_DB {

-

-	var $dbdriver = 'mysqli';

-	

-	// The character used for escaping

-	var $_escape_char = '`';

-

-	/**

-	 * The syntax to count rows is slightly different across different

-	 * database engines, so this string appears in each driver and is

-	 * used for the count_all() and count_all_results() functions.

-	 */

-	var $_count_string = "SELECT COUNT(*) AS ";

-	var $_random_keyword = ' RAND()'; // database specific random keyword

-

-	/**

-	 * Whether to use the MySQL "delete hack" which allows the number

-	 * of affected rows to be shown. Uses a preg_replace when enabled,

-	 * adding a bit more processing to all queries.

-	 */	

-	var $delete_hack = TRUE;

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{

-		if ($this->port != '')

-		{

-			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);			

-		}

-		else

-		{

-			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);

-		}

-

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		return $this->db_connect();

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		return @mysqli_select_db($this->conn_id, $this->database);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function _db_set_charset($charset, $collation)

-	{

-		return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _version()

-	{

-		return "SELECT version() AS ver";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	function _execute($sql)

-	{

-		$sql = $this->_prep_query($sql);	

-		$result = @mysqli_query($this->conn_id, $sql);

-		return $result;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * 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)

-	{

-		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies

-		// the query so that it returns the number of affected rows

-		if ($this->delete_hack === TRUE)

-		{

-			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))

-			{

-				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);

-			}

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Begin Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-

-		$this->simple_query('SET AUTOCOMMIT=0');

-		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('COMMIT');

-		$this->simple_query('SET AUTOCOMMIT=1');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('ROLLBACK');

-		$this->simple_query('SET AUTOCOMMIT=1');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{

-		if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))

-		{

-			return mysqli_real_escape_string($this->conn_id, $str);

-		}

-		elseif (function_exists('mysql_escape_string'))

-		{

-			return mysql_escape_string($str);

-		}

-		else

-		{

-			return addslashes($str);

-		}

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return @mysqli_affected_rows($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function insert_id()

-	{

-		return @mysqli_insert_id($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-		

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-		

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;	

-		

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			$sql .= " LIKE '".$this->dbprefix."%'";

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		return "SHOW COLUMNS FROM ".$table;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT * FROM ".$table." LIMIT 1";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		return mysqli_error($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		return mysqli_errno($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-		

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-		

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-			

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return '('.implode(', ', $tables).')';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-		

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-		

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return "TRUNCATE ".$table;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{	

-		$sql .= "LIMIT ".$limit;

-	

-		if ($offset > 0)

-		{

-			$sql .= " OFFSET ".$offset;

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@mysqli_close($conn_id);

-	}

-

-

-}

-

-

-/* End of file mysqli_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQLi Database Adapter Class - MySQLi only works with PHP 5
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysqli_driver extends CI_DB {
+
+	var $dbdriver = 'mysqli';
+	
+	// The character used for escaping
+	var $_escape_char = '`';
+
+	/**
+	 * The syntax to count rows is slightly different across different
+	 * database engines, so this string appears in each driver and is
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	var $_count_string = "SELECT COUNT(*) AS ";
+	var $_random_keyword = ' RAND()'; // database specific random keyword
+
+	/**
+	 * Whether to use the MySQL "delete hack" which allows the number
+	 * of affected rows to be shown. Uses a preg_replace when enabled,
+	 * adding a bit more processing to all queries.
+	 */	
+	var $delete_hack = TRUE;
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		if ($this->port != '')
+		{
+			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);			
+		}
+		else
+		{
+			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
+		}
+
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return $this->db_connect();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return @mysqli_select_db($this->conn_id, $this->database);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function _db_set_charset($charset, $collation)
+	{
+		return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	function _execute($sql)
+	{
+		$sql = $this->_prep_query($sql);	
+		$result = @mysqli_query($this->conn_id, $sql);
+		return $result;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
+		// the query so that it returns the number of affected rows
+		if ($this->delete_hack === TRUE)
+		{
+			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
+			{
+				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
+			}
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+		$this->simple_query('SET AUTOCOMMIT=0');
+		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('COMMIT');
+		$this->simple_query('SET AUTOCOMMIT=1');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('ROLLBACK');
+		$this->simple_query('SET AUTOCOMMIT=1');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
+		{
+			return mysqli_real_escape_string($this->conn_id, $str);
+		}
+		elseif (function_exists('mysql_escape_string'))
+		{
+			return mysql_escape_string($str);
+		}
+		else
+		{
+			return addslashes($str);
+		}
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @mysqli_affected_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @mysqli_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+		
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;	
+		
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " LIKE '".$this->dbprefix."%'";
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SHOW COLUMNS FROM ".$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." LIMIT 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return mysqli_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return mysqli_errno($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+		
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+		
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+			
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+		
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+		
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return "TRUNCATE ".$table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{	
+		$sql .= "LIMIT ".$limit;
+	
+		if ($offset > 0)
+		{
+			$sql .= " OFFSET ".$offset;
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@mysqli_close($conn_id);
+	}
+
+
+}
+
+
+/* End of file mysqli_driver.php */
 /* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index c7889bf..99c2ebc 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -1,254 +1,254 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQLi Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysqli_forge extends CI_DB_forge {

-	

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Process Fields

-	 *

-	 * @access	private

-	 * @param	mixed	the fields

-	 * @return	string

-	 */

-	function _process_fields($fields)

-	{

-		$current_field_count = 0;

-		$sql = '';

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-

-				if (array_key_exists('NAME', $attributes))

-				{

-					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';

-				}

-				

-				if (array_key_exists('TYPE', $attributes))

-				{

-					$sql .=  ' '.$attributes['TYPE'];

-				}

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes))

-				{

-					$sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * 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

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-

-		$sql .= $this->_process_fields($fields);

-

-		if (count($primary_keys) > 0)

-		{

-			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";

-		}

-

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key_name = $this->db->_protect_identifiers(implode('_', $key));

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key_name = $this->db->_protect_identifiers($key);

-					$key = array($key_name);

-				}

-				

-				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";

-			}

-		}

-

-		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _drop_table($table)

-	{

-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	array	fields

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $fields, $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql.$this->db->_protect_identifiers($fields);

-		}

-

-		$sql .= $this->_process_fields($fields);

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-}

-

-/* End of file mysqli_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQLi Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysqli_forge extends CI_DB_forge {
+	
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Process Fields
+	 *
+	 * @access	private
+	 * @param	mixed	the fields
+	 * @return	string
+	 */
+	function _process_fields($fields)
+	{
+		$current_field_count = 0;
+		$sql = '';
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+
+				if (array_key_exists('NAME', $attributes))
+				{
+					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
+				}
+				
+				if (array_key_exists('TYPE', $attributes))
+				{
+					$sql .=  ' '.$attributes['TYPE'];
+				}
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes))
+				{
+					$sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL';
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+
+		$sql .= $this->_process_fields($fields);
+
+		if (count($primary_keys) > 0)
+		{
+			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key_name = $this->db->_protect_identifiers(implode('_', $key));
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key_name = $this->db->_protect_identifiers($key);
+					$key = array($key_name);
+				}
+				
+				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _drop_table($table)
+	{
+		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	array	fields
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql.$this->db->_protect_identifiers($fields);
+		}
+
+		$sql .= $this->_process_fields($fields);
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+}
+
+/* End of file 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 b690914..5b1f793 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -1,169 +1,169 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQLi Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysqli_result extends CI_DB_result {

-	

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @mysqli_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @mysqli_num_fields($this->result_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		while ($field = mysqli_fetch_field($this->result_id))

-		{

-			$field_names[] = $field->name;

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		while ($field = mysqli_fetch_field($this->result_id))

-		{	

-			$F 				= new stdClass();

-			$F->name 		= $field->name;

-			$F->type 		= $field->type;

-			$F->default		= $field->def;

-			$F->max_length	= $field->max_length;

-			$F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0;

-			

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_object($this->result_id))

-		{

-			mysqli_free_result($this->result_id);

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return mysqli_data_seek($this->result_id, $n);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		return mysqli_fetch_assoc($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		return mysqli_fetch_object($this->result_id);

-	}

-	

-}

-

-

-/* End of file mysqli_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQLi Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysqli_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @mysqli_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @mysqli_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		while ($field = mysqli_fetch_field($this->result_id))
+		{
+			$field_names[] = $field->name;
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		while ($field = mysqli_fetch_field($this->result_id))
+		{	
+			$F 				= new stdClass();
+			$F->name 		= $field->name;
+			$F->type 		= $field->type;
+			$F->default		= $field->def;
+			$F->max_length	= $field->max_length;
+			$F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0;
+			
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_object($this->result_id))
+		{
+			mysqli_free_result($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return mysqli_data_seek($this->result_id, $n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return mysqli_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		return mysqli_fetch_object($this->result_id);
+	}
+	
+}
+
+
+/* End of file mysqli_result.php */
 /* Location: ./system/database/drivers/mysqli/mysqli_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index d19b643..c1d191d 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -1,123 +1,123 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * MySQLi Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_mysqli_utility extends CI_DB_utility {

-	

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		return "SHOW DATABASES";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Generates a platform-specific query so that a table can be optimized

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Generates a platform-specific query so that a table can be repaired

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * MySQLi Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-}

-

-/* End of file mysqli_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * MySQLi Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_mysqli_utility extends CI_DB_utility {
+	
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		return "SHOW DATABASES";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Generates a platform-specific query so that a table can be optimized
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Generates a platform-specific query so that a table can be repaired
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * MySQLi Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+}
+
+/* End of file mysqli_utility.php */
 /* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/oci8/index.html b/system/database/drivers/oci8/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/oci8/index.html
+++ b/system/database/drivers/oci8/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 0c14677..0629a59 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -1,737 +1,737 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package	 	CodeIgniter

- * @author	  	ExpressionEngine Dev Team

- * @copyright   Copyright (c) 2008, EllisLab, Inc.

- * @license	 	http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since	   	Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * oci8 Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package	 	CodeIgniter

- * @subpackage  Drivers

- * @category	Database

- * @author	  	ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-

-/**

- * oci8 Database Adapter Class

- *

- * This is a modification of the DB_driver class to

- * permit access to oracle databases

- *

- * NOTE: this uses the PHP 4 oci methods

- *

- * @author	  Kelly McArdle

- *

- */

-

-class CI_DB_oci8_driver extends CI_DB {

-

-	var $dbdriver = 'oci8';

-	

-	// The character used for excaping

-	var $_escape_char = '"';

-

-	/**

-	 * The syntax to count rows is slightly different across different

-	 * database engines, so this string appears in each driver and is

-	 * used for the count_all() and count_all_results() functions.

-	 */

-	var $_count_string = "SELECT COUNT(1) AS ";

-	var $_random_keyword = ' ASC'; // not currently supported

-

-	// Set "auto commit" by default

-	var $_commit = OCI_COMMIT_ON_SUCCESS;

-

-	// need to track statement id and cursor id

-	var $stmt_id;

-	var $curs_id;

-

-	// if we use a limit, we will add a field that will

-	// throw off num_fields later

-	var $limit_used;

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access  private called by the base class

-	 * @return  resource

-	 */

-	function db_connect()

-	{

-		return @ocilogon($this->username, $this->password, $this->hostname);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access  private called by the base class

-	 * @return  resource

-	 */

-	function db_pconnect()

-	{

-		return @ociplogon($this->username, $this->password, $this->hostname);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access  private called by the base class

-	 * @return  resource

-	 */

-	function db_select()

-	{

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		// @todo - add support if needed

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access  public

-	 * @return  string

-	 */

-	function _version()

-	{

-		return ociserverversion($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access  private called by the base class

-	 * @param   string  an SQL query

-	 * @return  resource

-	 */

-	function _execute($sql)

-	{

-		// oracle must parse the query before it is run. All of the actions with

-		// the query are based on the statement id returned by ociparse

-		$this->stmt_id = FALSE;

-		$this->_set_stmt_id($sql);

-		ocisetprefetch($this->stmt_id, 1000);

-		return @ociexecute($this->stmt_id, $this->_commit);

-	}

-

-	/**

-	 * Generate a statement ID

-	 *

-	 * @access  private

-	 * @param   string  an SQL query

-	 * @return  none

-	 */

-	function _set_stmt_id($sql)

-	{

-		if ( ! is_resource($this->stmt_id))

-		{

-			$this->stmt_id = ociparse($this->conn_id, $this->_prep_query($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;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * getCursor.  Returns a cursor from the datbase

-	 *

-	 * @access  public

-	 * @return  cursor id

-	 */

-	function get_cursor()

-	{

-		$this->curs_id = ocinewcursor($this->conn_id);

-		return $this->curs_id;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Stored Procedure.  Executes a stored procedure

-	 *

-	 * @access  public

-	 * @param   package	 package stored procedure is in

-	 * @param   procedure   stored procedure to execute

-	 * @param   params	  array of parameters

-	 * @return  array

-	 *

-	 * params array keys

-	 *

-	 * KEY	  OPTIONAL	NOTES

-	 * name		no		the name of the parameter should be in :<param_name> format

-	 * value	no		the value of the parameter.  If this is an OUT or IN OUT parameter,

-	 *					this should be a reference to a variable

-	 * type		yes		the type of the parameter

-	 * length	yes		the max size of the parameter

-	 */

-	function stored_procedure($package, $procedure, $params)

-	{

-		if ($package == '' OR $procedure == '' OR ! is_array($params))

-		{

-			if ($this->db_debug)

-			{

-				log_message('error', 'Invalid query: '.$package.'.'.$procedure);

-				return $this->display_error('db_invalid_query');

-			}

-			return FALSE;

-		}

-		

-		// build the query string

-		$sql = "begin $package.$procedure(";

-

-		$have_cursor = FALSE;

-		foreach($params as $param)

-		{

-			$sql .= $param['name'] . ",";

-			

-			if (array_key_exists('type', $param) && ($param['type'] == OCI_B_CURSOR))

-			{

-				$have_cursor = TRUE;

-			}

-		}

-		$sql = trim($sql, ",") . "); end;";

-				

-		$this->stmt_id = FALSE;

-		$this->_set_stmt_id($sql);

-		$this->_bind_params($params);

-		$this->query($sql, FALSE, $have_cursor);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Bind parameters

-	 *

-	 * @access  private

-	 * @return  none

-	 */

-	function _bind_params($params)

-	{

-		if ( ! is_array($params) OR ! is_resource($this->stmt_id))

-		{

-			return;

-		}

-		

-		foreach ($params as $param)

-		{

- 			foreach (array('name', 'value', 'type', 'length') as $val)

-			{

-				if ( ! isset($param[$val]))

-				{

-					$param[$val] = '';

-				}

-			}

-

-			ocibindbyname($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Begin Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-		

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-		

-		$this->_commit = OCI_DEFAULT;

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$ret = OCIcommit($this->conn_id);

-		$this->_commit = OCI_COMMIT_ON_SUCCESS;

-		return $ret;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$ret = OCIrollback($this->conn_id);

-		$this->_commit = OCI_COMMIT_ON_SUCCESS;

-		return $ret;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access  public

-	 * @param   string

-	 * @return  string

-	 */

-	function escape_str($str)

-	{

-		// Access the CI object

-		$CI =& get_instance();

-

-		return $CI->_remove_invisible_characters($str);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access  public

-	 * @return  integer

-	 */

-	function affected_rows()

-	{

-		return @ocirowcount($this->stmt_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access  public

-	 * @return  integer

-	 */

-	function insert_id()

-	{

-		// not supported in oracle

-		return $this->display_error('db_unsupported_function');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access  public

-	 * @param   string

-	 * @return  string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-

-		if ($query == FALSE)

-			{

-			return 0;

-			}

-

-		$row = $query->row();

-		return $row->NUMROWS;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access  private

-	 * @param	boolean

-	 * @return  string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SELECT TABLE_NAME FROM ALL_TABLES";

-

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			$sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'";

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT * FROM ".$table." where rownum = 1";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access  private

-	 * @return  string

-	 */

-	function _error_message()

-	{

-		$error = ocierror($this->conn_id);

-		return $error['message'];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access  private

-	 * @return  integer

-	 */

-	function _error_number()

-	{

-		$error = ocierror($this->conn_id);

-		return $error['code'];

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-	

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return implode(', ', $tables);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access  public

-	 * @param   string  the table name

-	 * @param   array   the insert keys

-	 * @param   array   the insert values

-	 * @return  string

-	 */

-	function _insert($table, $keys, $values)

-	{

-	return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return "TRUNCATE TABLE ".$table;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access  public

-	 * @param   string  the sql query string

-	 * @param   integer the number of rows to limit the query to

-	 * @param   integer the offset value

-	 * @return  string

-	 */

-	function _limit($sql, $limit, $offset)

-	{

-		$limit = $offset + $limit;

-		$newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)";

-

-		if ($offset != 0)

-		{

-			$newsql .= " WHERE rnum >= $offset";

-		}

-

-		// remember that we used limits

-		$this->limit_used = TRUE;

-

-		return $newsql;

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access  public

-	 * @param   resource

-	 * @return  void

-	 */

-	function _close($conn_id)

-	{

-		@ocilogoff($conn_id);

-	}

-

-

-}

-

-

-

-/* End of file oci8_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package	 	CodeIgniter
+ * @author	  	ExpressionEngine Dev Team
+ * @copyright   Copyright (c) 2008, EllisLab, Inc.
+ * @license	 	http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since	   	Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * oci8 Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package	 	CodeIgniter
+ * @subpackage  Drivers
+ * @category	Database
+ * @author	  	ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+
+/**
+ * oci8 Database Adapter Class
+ *
+ * This is a modification of the DB_driver class to
+ * permit access to oracle databases
+ *
+ * NOTE: this uses the PHP 4 oci methods
+ *
+ * @author	  Kelly McArdle
+ *
+ */
+
+class CI_DB_oci8_driver extends CI_DB {
+
+	var $dbdriver = 'oci8';
+	
+	// The character used for excaping
+	var $_escape_char = '"';
+
+	/**
+	 * The syntax to count rows is slightly different across different
+	 * database engines, so this string appears in each driver and is
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	var $_count_string = "SELECT COUNT(1) AS ";
+	var $_random_keyword = ' ASC'; // not currently supported
+
+	// Set "auto commit" by default
+	var $_commit = OCI_COMMIT_ON_SUCCESS;
+
+	// need to track statement id and cursor id
+	var $stmt_id;
+	var $curs_id;
+
+	// if we use a limit, we will add a field that will
+	// throw off num_fields later
+	var $limit_used;
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access  private called by the base class
+	 * @return  resource
+	 */
+	function db_connect()
+	{
+		return @ocilogon($this->username, $this->password, $this->hostname);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access  private called by the base class
+	 * @return  resource
+	 */
+	function db_pconnect()
+	{
+		return @ociplogon($this->username, $this->password, $this->hostname);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access  private called by the base class
+	 * @return  resource
+	 */
+	function db_select()
+	{
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// @todo - add support if needed
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access  public
+	 * @return  string
+	 */
+	function _version()
+	{
+		return ociserverversion($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access  private called by the base class
+	 * @param   string  an SQL query
+	 * @return  resource
+	 */
+	function _execute($sql)
+	{
+		// oracle must parse the query before it is run. All of the actions with
+		// the query are based on the statement id returned by ociparse
+		$this->stmt_id = FALSE;
+		$this->_set_stmt_id($sql);
+		ocisetprefetch($this->stmt_id, 1000);
+		return @ociexecute($this->stmt_id, $this->_commit);
+	}
+
+	/**
+	 * Generate a statement ID
+	 *
+	 * @access  private
+	 * @param   string  an SQL query
+	 * @return  none
+	 */
+	function _set_stmt_id($sql)
+	{
+		if ( ! is_resource($this->stmt_id))
+		{
+			$this->stmt_id = ociparse($this->conn_id, $this->_prep_query($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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * getCursor.  Returns a cursor from the datbase
+	 *
+	 * @access  public
+	 * @return  cursor id
+	 */
+	function get_cursor()
+	{
+		$this->curs_id = ocinewcursor($this->conn_id);
+		return $this->curs_id;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Stored Procedure.  Executes a stored procedure
+	 *
+	 * @access  public
+	 * @param   package	 package stored procedure is in
+	 * @param   procedure   stored procedure to execute
+	 * @param   params	  array of parameters
+	 * @return  array
+	 *
+	 * params array keys
+	 *
+	 * KEY	  OPTIONAL	NOTES
+	 * name		no		the name of the parameter should be in :<param_name> format
+	 * value	no		the value of the parameter.  If this is an OUT or IN OUT parameter,
+	 *					this should be a reference to a variable
+	 * type		yes		the type of the parameter
+	 * length	yes		the max size of the parameter
+	 */
+	function stored_procedure($package, $procedure, $params)
+	{
+		if ($package == '' OR $procedure == '' OR ! is_array($params))
+		{
+			if ($this->db_debug)
+			{
+				log_message('error', 'Invalid query: '.$package.'.'.$procedure);
+				return $this->display_error('db_invalid_query');
+			}
+			return FALSE;
+		}
+		
+		// build the query string
+		$sql = "begin $package.$procedure(";
+
+		$have_cursor = FALSE;
+		foreach($params as $param)
+		{
+			$sql .= $param['name'] . ",";
+			
+			if (array_key_exists('type', $param) && ($param['type'] == OCI_B_CURSOR))
+			{
+				$have_cursor = TRUE;
+			}
+		}
+		$sql = trim($sql, ",") . "); end;";
+				
+		$this->stmt_id = FALSE;
+		$this->_set_stmt_id($sql);
+		$this->_bind_params($params);
+		$this->query($sql, FALSE, $have_cursor);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Bind parameters
+	 *
+	 * @access  private
+	 * @return  none
+	 */
+	function _bind_params($params)
+	{
+		if ( ! is_array($params) OR ! is_resource($this->stmt_id))
+		{
+			return;
+		}
+		
+		foreach ($params as $param)
+		{
+ 			foreach (array('name', 'value', 'type', 'length') as $val)
+			{
+				if ( ! isset($param[$val]))
+				{
+					$param[$val] = '';
+				}
+			}
+
+			ocibindbyname($this->stmt_id, $param['name'], $param['value'], $param['length'], $param['type']);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+		
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		
+		$this->_commit = OCI_DEFAULT;
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$ret = OCIcommit($this->conn_id);
+		$this->_commit = OCI_COMMIT_ON_SUCCESS;
+		return $ret;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$ret = OCIrollback($this->conn_id);
+		$this->_commit = OCI_COMMIT_ON_SUCCESS;
+		return $ret;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access  public
+	 * @param   string
+	 * @return  string
+	 */
+	function escape_str($str)
+	{
+		// Access the CI object
+		$CI =& get_instance();
+
+		return $CI->_remove_invisible_characters($str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access  public
+	 * @return  integer
+	 */
+	function affected_rows()
+	{
+		return @ocirowcount($this->stmt_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access  public
+	 * @return  integer
+	 */
+	function insert_id()
+	{
+		// not supported in oracle
+		return $this->display_error('db_unsupported_function');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access  public
+	 * @param   string
+	 * @return  string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+
+		if ($query == FALSE)
+			{
+			return 0;
+			}
+
+		$row = $query->row();
+		return $row->NUMROWS;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access  private
+	 * @param	boolean
+	 * @return  string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SELECT TABLE_NAME FROM ALL_TABLES";
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " WHERE TABLE_NAME LIKE '".$this->dbprefix."%'";
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." where rownum = 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access  private
+	 * @return  string
+	 */
+	function _error_message()
+	{
+		$error = ocierror($this->conn_id);
+		return $error['message'];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access  private
+	 * @return  integer
+	 */
+	function _error_number()
+	{
+		$error = ocierror($this->conn_id);
+		return $error['code'];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+	
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return implode(', ', $tables);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access  public
+	 * @param   string  the table name
+	 * @param   array   the insert keys
+	 * @param   array   the insert values
+	 * @return  string
+	 */
+	function _insert($table, $keys, $values)
+	{
+	return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return "TRUNCATE TABLE ".$table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access  public
+	 * @param   string  the sql query string
+	 * @param   integer the number of rows to limit the query to
+	 * @param   integer the offset value
+	 * @return  string
+	 */
+	function _limit($sql, $limit, $offset)
+	{
+		$limit = $offset + $limit;
+		$newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)";
+
+		if ($offset != 0)
+		{
+			$newsql .= " WHERE rnum >= $offset";
+		}
+
+		// remember that we used limits
+		$this->limit_used = TRUE;
+
+		return $newsql;
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access  public
+	 * @param   resource
+	 * @return  void
+	 */
+	function _close($conn_id)
+	{
+		@ocilogoff($conn_id);
+	}
+
+
+}
+
+
+
+/* End of file 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 4b073d0..bbc11f3 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_forge.php
@@ -1,248 +1,248 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Oracle Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_oci8_forge extends CI_DB_forge {

-

-	/**

-	 * Create database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @param	array	the fields

-	 * @param	mixed	primary key(s)

-	 * @param	mixed	key(s)

-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-		$current_field_count = 0;

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-				

-				$sql .=  ' '.$attributes['TYPE'];

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)

-				{

-					$sql .= ' NULL';

-				}

-				else

-				{

-					$sql .= ' NOT NULL';			

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-

-		if (count($primary_keys) > 0)

-		{

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";

-		}

-

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key = array($this->db->_protect_identifiers($key));

-				}

-				

-				$sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $key) . ")";

-			}

-		}

-		

-		$sql .= "\n)";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _drop_table($table)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	string	the table name

-	 * @param	string	the column definition

-	 * @param	string	the default value

-	 * @param	boolean	should 'NOT NULL' be added

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql;

-		}

-

-		$sql .= " $column_definition";

-

-		if ($default_value != '')

-		{

-			$sql .= " DEFAULT \"$default_value\"";

-		}

-

-		if ($null === NULL)

-		{

-			$sql .= ' NULL';

-		}

-		else

-		{

-			$sql .= ' NOT NULL';

-		}

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-

-}

-

-/* End of file oci8_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Oracle Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_oci8_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+		$current_field_count = 0;
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+				
+				$sql .=  ' '.$attributes['TYPE'];
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+				{
+					$sql .= ' NULL';
+				}
+				else
+				{
+					$sql .= ' NOT NULL';			
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key = array($this->db->_protect_identifiers($key));
+				}
+				
+				$sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $key) . ")";
+			}
+		}
+		
+		$sql .= "\n)";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _drop_table($table)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql;
+		}
+
+		$sql .= " $column_definition";
+
+		if ($default_value != '')
+		{
+			$sql .= " DEFAULT \"$default_value\"";
+		}
+
+		if ($null === NULL)
+		{
+			$sql .= ' NULL';
+		}
+		else
+		{
+			$sql .= ' NOT NULL';
+		}
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+
+}
+
+/* End of file 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 4cfbfa4..7d7cd1c 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -1,249 +1,249 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package	 	CodeIgniter

- * @author	 	ExpressionEngine Dev Team

- * @copyright   Copyright (c) 2008, EllisLab, Inc.

- * @license	 	http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since	   	Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * oci8 Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author	 	ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_oci8_result extends CI_DB_result {

-

-	var $stmt_id;

-	var $curs_id;

-	var $limit_used;

-

-	/**

-	 * Number of rows in the result set.

-	 *

-	 * Oracle doesn't have a graceful way to retun the number of rows

-	 * so we have to use what amounts to a hack.

-	 * 

-	 *

-	 * @access  public

-	 * @return  integer

-	 */

-	function num_rows()

-	{

-		$rowcount = count($this->result_array());

-		@ociexecute($this->stmt_id);

-

-		if ($this->curs_id)

-		{

-			@ociexecute($this->curs_id);

-		}

-

-		return $rowcount;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access  public

-	 * @return  integer

-	 */

-	function num_fields()

-	{

-		$count = @ocinumcols($this->stmt_id);

-

-		// if we used a limit we subtract it

-		if ($this->limit_used)

-		{

-			$count = $count - 1;

-		}

-

-		return $count;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		$fieldCount = $this->num_fields();

-		for ($c = 1; $c <= $fieldCount; $c++)

-		{

-			$field_names[] = ocicolumnname($this->stmt_id, $c);

-		}

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access  public

-	 * @return  array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		$fieldCount = $this->num_fields();

-		for ($c = 1; $c <= $fieldCount; $c++)

-		{

-			$F			  = new stdClass();

-			$F->name		= ocicolumnname($this->stmt_id, $c);

-			$F->type		= ocicolumntype($this->stmt_id, $c);

-			$F->max_length  = ocicolumnsize($this->stmt_id, $c);

-

-			$retval[] = $F;

-		}

-

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_resource($this->result_id))

-		{

-			ocifreestatement($this->result_id);			

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access  private

-	 * @return  array

-	 */

-	function _fetch_assoc(&$row)

-	{

-		$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;

-	

-		return ocifetchinto($id, $row, OCI_ASSOC + OCI_RETURN_NULLS);	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access  private

-	 * @return  object

-	 */

-	function _fetch_object()

-	{	

-		$result = array();

-

-		// If PHP 5 is being used we can fetch an result object

-		if (function_exists('oci_fetch_object'))

-		{

-			$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;

-			

-			return @oci_fetch_object($id);

-		}

-		

-		// If PHP 4 is being used we have to build our own result

-		foreach ($this->result_array() as $key => $val)

-		{

-			$obj = new stdClass();

-			if (is_array($val))

-			{

-				foreach ($val as $k => $v)

-				{

-					$obj->$k = $v;

-				}

-			}

-			else

-			{

-				$obj->$key = $val;

-			}

-			

-			$result[] = $obj;

-		}

-

-		return $result;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Query result.  "array" version.

-	 *

-	 * @access  public

-	 * @return  array

-	 */

-	function result_array()

-	{

-		if (count($this->result_array) > 0)

-		{

-			return $this->result_array;

-		}

-

-		// oracle's fetch functions do not return arrays.

-		// The information is returned in reference parameters

-		$row = NULL;

-		while ($this->_fetch_assoc($row))

-		{

-			$this->result_array[] = $row;

-		}

-

-		return $this->result_array;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return FALSE; // Not needed

-	}

-

-}

-

-

-/* End of file oci8_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package	 	CodeIgniter
+ * @author	 	ExpressionEngine Dev Team
+ * @copyright   Copyright (c) 2008, EllisLab, Inc.
+ * @license	 	http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since	   	Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * oci8 Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author	 	ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_oci8_result extends CI_DB_result {
+
+	var $stmt_id;
+	var $curs_id;
+	var $limit_used;
+
+	/**
+	 * Number of rows in the result set.
+	 *
+	 * Oracle doesn't have a graceful way to retun the number of rows
+	 * so we have to use what amounts to a hack.
+	 * 
+	 *
+	 * @access  public
+	 * @return  integer
+	 */
+	function num_rows()
+	{
+		$rowcount = count($this->result_array());
+		@ociexecute($this->stmt_id);
+
+		if ($this->curs_id)
+		{
+			@ociexecute($this->curs_id);
+		}
+
+		return $rowcount;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access  public
+	 * @return  integer
+	 */
+	function num_fields()
+	{
+		$count = @ocinumcols($this->stmt_id);
+
+		// if we used a limit we subtract it
+		if ($this->limit_used)
+		{
+			$count = $count - 1;
+		}
+
+		return $count;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		$fieldCount = $this->num_fields();
+		for ($c = 1; $c <= $fieldCount; $c++)
+		{
+			$field_names[] = ocicolumnname($this->stmt_id, $c);
+		}
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access  public
+	 * @return  array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		$fieldCount = $this->num_fields();
+		for ($c = 1; $c <= $fieldCount; $c++)
+		{
+			$F			  = new stdClass();
+			$F->name		= ocicolumnname($this->stmt_id, $c);
+			$F->type		= ocicolumntype($this->stmt_id, $c);
+			$F->max_length  = ocicolumnsize($this->stmt_id, $c);
+
+			$retval[] = $F;
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_resource($this->result_id))
+		{
+			ocifreestatement($this->result_id);			
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access  private
+	 * @return  array
+	 */
+	function _fetch_assoc(&$row)
+	{
+		$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
+	
+		return ocifetchinto($id, $row, OCI_ASSOC + OCI_RETURN_NULLS);	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access  private
+	 * @return  object
+	 */
+	function _fetch_object()
+	{	
+		$result = array();
+
+		// If PHP 5 is being used we can fetch an result object
+		if (function_exists('oci_fetch_object'))
+		{
+			$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
+			
+			return @oci_fetch_object($id);
+		}
+		
+		// If PHP 4 is being used we have to build our own result
+		foreach ($this->result_array() as $key => $val)
+		{
+			$obj = new stdClass();
+			if (is_array($val))
+			{
+				foreach ($val as $k => $v)
+				{
+					$obj->$k = $v;
+				}
+			}
+			else
+			{
+				$obj->$key = $val;
+			}
+			
+			$result[] = $obj;
+		}
+
+		return $result;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "array" version.
+	 *
+	 * @access  public
+	 * @return  array
+	 */
+	function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+
+		// oracle's fetch functions do not return arrays.
+		// The information is returned in reference parameters
+		$row = NULL;
+		while ($this->_fetch_assoc($row))
+		{
+			$this->result_array[] = $row;
+		}
+
+		return $this->result_array;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return FALSE; // Not needed
+	}
+
+}
+
+
+/* End of file 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 a3b6d81..cf6e9e6 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_utility.php
@@ -1,122 +1,122 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Oracle Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_oci8_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Generates a platform-specific query so that a table can be optimized

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return FALSE; // Is this supported in Oracle?

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Generates a platform-specific query so that a table can be repaired

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return FALSE; // Is this supported in Oracle?

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Oracle Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return FALSE;

-	}

-

-}

-

-/* End of file oci8_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Oracle Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_oci8_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Generates a platform-specific query so that a table can be optimized
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return FALSE; // Is this supported in Oracle?
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Generates a platform-specific query so that a table can be repaired
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return FALSE; // Is this supported in Oracle?
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Oracle Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return FALSE;
+	}
+
+}
+
+/* End of file oci8_utility.php */
 /* Location: ./system/database/drivers/oci8/oci8_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/odbc/index.html b/system/database/drivers/odbc/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/odbc/index.html
+++ b/system/database/drivers/odbc/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 3c6f015..8fcbcfe 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -1,594 +1,594 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * ODBC Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_odbc_driver extends CI_DB {

-

-	var $dbdriver = 'odbc';

-	

-	// the character used to excape - not necessary for ODBC

-	var $_escape_char = '';

-

-	/**

-	 * 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;

-

-

-	function CI_DB_odbc_driver($params)

-	{

-		parent::CI_DB($params);

-		

-		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword

-	}

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{

-		return @odbc_connect($this->hostname, $this->username, $this->password);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		return @odbc_pconnect($this->hostname, $this->username, $this->password);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		// Not needed for ODBC

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		// @todo - add support if needed

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _version()

-	{

-		return "SELECT version() AS ver";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	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)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-

-		return odbc_autocommit($this->conn_id, FALSE);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$ret = odbc_commit($this->conn_id);

-		odbc_autocommit($this->conn_id, TRUE);

-		return $ret;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$ret = odbc_rollback($this->conn_id);

-		odbc_autocommit($this->conn_id, TRUE);

-		return $ret;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{

-		// Access the CI object

-		$CI =& get_instance();

-

-		// ODBC doesn't require escaping

-		return $CI->_remove_invisible_characters($str);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return @odbc_num_rows($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function insert_id()

-	{

-		return @odbc_insert_id($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-	

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-	

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SHOW TABLES FROM `".$this->database."`";

-

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			//$sql .= " LIKE '".$this->dbprefix."%'";

-			return FALSE; // not currently supported

-		}

-		

-		return $sql;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		return "SHOW COLUMNS FROM ".$table;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT TOP 1 FROM ".$table;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		return odbc_errormsg($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		return odbc_error($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-	

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-			

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return '('.implode(', ', $tables).')';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return $this->_delete($table);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{

-		// Does ODBC doesn't use the LIMIT clause?

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@odbc_close($conn_id);

-	}

-

-	

-}

-

-

-

-/* End of file odbc_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * ODBC Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_odbc_driver extends CI_DB {
+
+	var $dbdriver = 'odbc';
+	
+	// the character used to excape - not necessary for ODBC
+	var $_escape_char = '';
+
+	/**
+	 * 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;
+
+
+	function CI_DB_odbc_driver($params)
+	{
+		parent::CI_DB($params);
+		
+		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
+	}
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		return @odbc_connect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return @odbc_pconnect($this->hostname, $this->username, $this->password);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		// Not needed for ODBC
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// @todo - add support if needed
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	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)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+		return odbc_autocommit($this->conn_id, FALSE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$ret = odbc_commit($this->conn_id);
+		odbc_autocommit($this->conn_id, TRUE);
+		return $ret;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$ret = odbc_rollback($this->conn_id);
+		odbc_autocommit($this->conn_id, TRUE);
+		return $ret;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		// Access the CI object
+		$CI =& get_instance();
+
+		// ODBC doesn't require escaping
+		return $CI->_remove_invisible_characters($str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @odbc_num_rows($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @odbc_insert_id($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+	
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SHOW TABLES FROM `".$this->database."`";
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			//$sql .= " LIKE '".$this->dbprefix."%'";
+			return FALSE; // not currently supported
+		}
+		
+		return $sql;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SHOW COLUMNS FROM ".$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT TOP 1 FROM ".$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return odbc_errormsg($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return odbc_error($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+	
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+			
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return $this->_delete($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{
+		// Does ODBC doesn't use the LIMIT clause?
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@odbc_close($conn_id);
+	}
+
+	
+}
+
+
+
+/* End of file 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 099925c..5305afb 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_forge.php
@@ -1,266 +1,266 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * ODBC Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/database/

- */

-class CI_DB_odbc_forge extends CI_DB_forge {

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database()

-	{

-		// ODBC has no "create database" command since it's

-		// designed to connect to an existing database

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		// ODBC has no "drop database" command since it's

-		// designed to connect to an existing database		

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @param	array	the fields

-	 * @param	mixed	primary key(s)

-	 * @param	mixed	key(s)

-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-		$current_field_count = 0;

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-				

-				$sql .=  ' '.$attributes['TYPE'];

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)

-				{

-					$sql .= ' NULL';

-				}

-				else

-				{

-					$sql .= ' NOT NULL';			

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-

-		if (count($primary_keys) > 0)

-		{

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";

-		}

-		

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key = array($this->db->_protect_identifiers($key));

-				}

-				

-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";

-			}

-		}

-		

-		$sql .= "\n)";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _drop_table($table)

-	{

-		// Not a supported ODBC feature	

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	string	the table name

-	 * @param	string	the column definition

-	 * @param	string	the default value

-	 * @param	boolean	should 'NOT NULL' be added

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql;

-		}

-

-		$sql .= " $column_definition";

-

-		if ($default_value != '')

-		{

-			$sql .= " DEFAULT \"$default_value\"";

-		}

-

-		if ($null === NULL)

-		{

-			$sql .= ' NULL';

-		}

-		else

-		{

-			$sql .= ' NOT NULL';

-		}

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-		

-	}

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-

-}

-

-/* End of file odbc_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * ODBC Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/database/
+ */
+class CI_DB_odbc_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database()
+	{
+		// ODBC has no "create database" command since it's
+		// designed to connect to an existing database
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		// ODBC has no "drop database" command since it's
+		// designed to connect to an existing database		
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+		$current_field_count = 0;
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+				
+				$sql .=  ' '.$attributes['TYPE'];
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+				{
+					$sql .= ' NULL';
+				}
+				else
+				{
+					$sql .= ' NOT NULL';			
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+		}
+		
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key = array($this->db->_protect_identifiers($key));
+				}
+				
+				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+			}
+		}
+		
+		$sql .= "\n)";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _drop_table($table)
+	{
+		// Not a supported ODBC feature	
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql;
+		}
+
+		$sql .= " $column_definition";
+
+		if ($default_value != '')
+		{
+			$sql .= " DEFAULT \"$default_value\"";
+		}
+
+		if ($null === NULL)
+		{
+			$sql .= ' NULL';
+		}
+		else
+		{
+			$sql .= ' NOT NULL';
+		}
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+		
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+
+}
+
+/* End of file 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 6d6542e..9a59cfc 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -1,228 +1,228 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * ODBC Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_odbc_result extends CI_DB_result {

-	

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @odbc_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @odbc_num_fields($this->result_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$field_names[] 	= odbc_field_name($this->result_id, $i);

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$F 				= new stdClass();

-			$F->name 		= odbc_field_name($this->result_id, $i);

-			$F->type 		= odbc_field_type($this->result_id, $i);

-			$F->max_length	= odbc_field_len($this->result_id, $i);

-			$F->primary_key = 0;

-			$F->default		= '';

-

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_resource($this->result_id))

-		{

-			odbc_free_result($this->result_id);

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		if (function_exists('odbc_fetch_object'))

-		{

-			return odbc_fetch_array($this->result_id);

-		}

-		else

-		{

-			return $this->_odbc_fetch_array($this->result_id);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		if (function_exists('odbc_fetch_object'))

-		{

-			return odbc_fetch_object($this->result_id);

-		}

-		else

-		{

-			return $this->_odbc_fetch_object($this->result_id);

-		}

-	}

-

-

-	/**

-	 * Result - object

-	 *

-	 * subsititutes the odbc_fetch_object function when

-	 * not available (odbc_fetch_object requires unixODBC)

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	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);

-				$rs_obj->$field_name = $v;

-			}

-		}

-		return $rs_obj;

-	}

-

-

-	/**

-	 * Result - array

-	 *

-	 * subsititutes the odbc_fetch_array function when

-	 * not available (odbc_fetch_array requires unixODBC)

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	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);

-				$rs_assoc[$field_name] = $v;

-			}

-		}

-		return $rs_assoc;

-	}

-

-}

-

-

-/* End of file odbc_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * ODBC Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_odbc_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @odbc_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @odbc_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$field_names[] 	= odbc_field_name($this->result_id, $i);
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new stdClass();
+			$F->name 		= odbc_field_name($this->result_id, $i);
+			$F->type 		= odbc_field_type($this->result_id, $i);
+			$F->max_length	= odbc_field_len($this->result_id, $i);
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_resource($this->result_id))
+		{
+			odbc_free_result($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		if (function_exists('odbc_fetch_object'))
+		{
+			return odbc_fetch_array($this->result_id);
+		}
+		else
+		{
+			return $this->_odbc_fetch_array($this->result_id);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		if (function_exists('odbc_fetch_object'))
+		{
+			return odbc_fetch_object($this->result_id);
+		}
+		else
+		{
+			return $this->_odbc_fetch_object($this->result_id);
+		}
+	}
+
+
+	/**
+	 * Result - object
+	 *
+	 * subsititutes the odbc_fetch_object function when
+	 * not available (odbc_fetch_object requires unixODBC)
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	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);
+				$rs_obj->$field_name = $v;
+			}
+		}
+		return $rs_obj;
+	}
+
+
+	/**
+	 * Result - array
+	 *
+	 * subsititutes the odbc_fetch_array function when
+	 * not available (odbc_fetch_array requires unixODBC)
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	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);
+				$rs_assoc[$field_name] = $v;
+			}
+		}
+		return $rs_assoc;
+	}
+
+}
+
+
+/* End of file 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 6f4376e..67aee64 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_utility.php
@@ -1,148 +1,148 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * ODBC Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/database/

- */

-class CI_DB_odbc_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		// Not sure if ODBC lets you list all databases...	

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Generates a platform-specific query so that a table can be optimized

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		// Not a supported ODBC feature	

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Generates a platform-specific query so that a table can be repaired

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		// Not a supported ODBC feature	

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * ODBC Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-	

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database()

-	{

-		// ODBC has no "create database" command since it's

-		// designed to connect to an existing database

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		// ODBC has no "drop database" command since it's

-		// designed to connect to an existing database		

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return FALSE;

-	}

-}

-

-/* End of file odbc_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * ODBC Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/database/
+ */
+class CI_DB_odbc_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		// Not sure if ODBC lets you list all databases...	
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Generates a platform-specific query so that a table can be optimized
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		// Not a supported ODBC feature	
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Generates a platform-specific query so that a table can be repaired
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		// Not a supported ODBC feature	
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * ODBC Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+	
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database()
+	{
+		// ODBC has no "create database" command since it's
+		// designed to connect to an existing database
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		// ODBC has no "drop database" command since it's
+		// designed to connect to an existing database		
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return FALSE;
+	}
+}
+
+/* End of file odbc_utility.php */
 /* Location: ./system/database/drivers/odbc/odbc_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/postgre/index.html b/system/database/drivers/postgre/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/postgre/index.html
+++ b/system/database/drivers/postgre/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 68622a2..da0b0f2 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -1,636 +1,636 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Postgre Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_postgre_driver extends CI_DB {

-

-	var $dbdriver = 'postgre';

-	

-	var $_escape_char = '"';

-

-	/**

-	 * 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

-

-	/**

-	 * Connection String

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _connect_string()

-	{

-		$components = array(

-								'hostname'	=> 'host',

-								'port'		=> 'port',

-								'database'	=> 'dbname',

-								'username'	=> 'user',

-								'password'	=> 'password'

-							);

-		

-		$connect_string = "";

-		foreach ($components as $key => $val)

-		{

-			if (isset($this->$key) && $this->$key != '')

-			{

-				$connect_string .= " $val=".$this->$key;

-			}

-		}

-		return trim($connect_string);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{		

-		return @pg_connect($this->_connect_string());

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		return @pg_pconnect($this->_connect_string());

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		// Not needed for Postgre so we'll return TRUE

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		// @todo - add support if needed

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _version()

-	{

-		return "SELECT version() AS ver";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	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

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-

-		return @pg_exec($this->conn_id, "begin");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		return @pg_exec($this->conn_id, "commit");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		return @pg_exec($this->conn_id, "rollback");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{	

-		return pg_escape_string($str);

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return @pg_affected_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function insert_id()

-	{

-		$v = $this->_version();

-		$v = $v['server'];

-		

-		$table	= func_num_args() > 0 ? func_get_arg(0) : null;

-		$column	= func_num_args() > 1 ? func_get_arg(1) : null;

-		

-		if ($table == null && $v >= '8.1')

-		{

-			$sql='SELECT LASTVAL() as ins_id';

-		}

-		elseif ($table != null && $column != null && $v >= '8.0')

-		{

-			$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);

-			$query = $this->query($sql);

-			$row = $query->row();

-			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);

-		}

-		elseif ($table != null)

-		{

-			// seq_name passed in table parameter

-			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);

-		}

-		else

-		{

-			return pg_last_oid($this->result_id);

-		}

-		$query = $this->query($sql);

-		$row = $query->row();

-		return $row->ins_id;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-				

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{	

-		$sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";	

-		

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			$sql .= " AND table_name LIKE '".$this->dbprefix."%'";

-		}

-		

-		return $sql;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT * FROM ".$table." LIMIT 1";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		return pg_last_error($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		return '';

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-	

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-			

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return implode(', ', $tables);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return "TRUNCATE ".$table;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-

-	// --------------------------------------------------------------------

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{	

-		$sql .= "LIMIT ".$limit;

-	

-		if ($offset > 0)

-		{

-			$sql .= " OFFSET ".$offset;

-		}

-		

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@pg_close($conn_id);

-	}

-

-

-}

-

-

-/* End of file postgre_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Postgre Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_postgre_driver extends CI_DB {
+
+	var $dbdriver = 'postgre';
+	
+	var $_escape_char = '"';
+
+	/**
+	 * 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
+
+	/**
+	 * Connection String
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _connect_string()
+	{
+		$components = array(
+								'hostname'	=> 'host',
+								'port'		=> 'port',
+								'database'	=> 'dbname',
+								'username'	=> 'user',
+								'password'	=> 'password'
+							);
+		
+		$connect_string = "";
+		foreach ($components as $key => $val)
+		{
+			if (isset($this->$key) && $this->$key != '')
+			{
+				$connect_string .= " $val=".$this->$key;
+			}
+		}
+		return trim($connect_string);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{		
+		return @pg_connect($this->_connect_string());
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		return @pg_pconnect($this->_connect_string());
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		// Not needed for Postgre so we'll return TRUE
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// @todo - add support if needed
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return "SELECT version() AS ver";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	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
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+		return @pg_exec($this->conn_id, "begin");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return @pg_exec($this->conn_id, "commit");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return @pg_exec($this->conn_id, "rollback");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{	
+		return pg_escape_string($str);
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return @pg_affected_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		$v = $this->_version();
+		$v = $v['server'];
+		
+		$table	= func_num_args() > 0 ? func_get_arg(0) : null;
+		$column	= func_num_args() > 1 ? func_get_arg(1) : null;
+		
+		if ($table == null && $v >= '8.1')
+		{
+			$sql='SELECT LASTVAL() as ins_id';
+		}
+		elseif ($table != null && $column != null && $v >= '8.0')
+		{
+			$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
+			$query = $this->query($sql);
+			$row = $query->row();
+			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
+		}
+		elseif ($table != null)
+		{
+			// seq_name passed in table parameter
+			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
+		}
+		else
+		{
+			return pg_last_oid($this->result_id);
+		}
+		$query = $this->query($sql);
+		$row = $query->row();
+		return $row->ins_id;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+				
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{	
+		$sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";	
+		
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " AND table_name LIKE '".$this->dbprefix."%'";
+		}
+		
+		return $sql;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." LIMIT 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return pg_last_error($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return '';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+	
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+			
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return implode(', ', $tables);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return "TRUNCATE ".$table;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+
+	// --------------------------------------------------------------------
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{	
+		$sql .= "LIMIT ".$limit;
+	
+		if ($offset > 0)
+		{
+			$sql .= " OFFSET ".$offset;
+		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@pg_close($conn_id);
+	}
+
+
+}
+
+
+/* End of file 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 5b4bcc2..72c2dd7 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_forge.php
@@ -1,248 +1,248 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Postgre Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_postgre_forge extends CI_DB_forge {

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @param	array	the fields

-	 * @param	mixed	primary key(s)

-	 * @param	mixed	key(s)

-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		if ($if_not_exists === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)." (";

-		$current_field_count = 0;

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-				

-				$sql .=  ' '.$attributes['TYPE'];

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)

-				{

-					$sql .= ' NULL';

-				}

-				else

-				{

-					$sql .= ' NOT NULL';			

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-

-		if (count($primary_keys) > 0)

-		{

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";

-		}

-		

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key = array($this->db->_protect_identifiers($key));

-				}

-				

-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";

-			}

-		}

-

-		$sql .= "\n);";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _drop_table($table)

-	{

-		return "DROP TABLE ".$this->db->_escape_identifiers($table)." CASCADE";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	string	the table name

-	 * @param	string	the column definition

-	 * @param	string	the default value

-	 * @param	boolean	should 'NOT NULL' be added

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			return $sql;

-		}

-

-		$sql .= " $column_definition";

-

-		if ($default_value != '')

-		{

-			$sql .= " DEFAULT \"$default_value\"";

-		}

-

-		if ($null === NULL)

-		{

-			$sql .= ' NULL';

-		}

-		else

-		{

-			$sql .= ' NOT NULL';

-		}

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-

-

-}

-

-/* End of file postgre_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Postgre Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_postgre_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		if ($if_not_exists === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)." (";
+		$current_field_count = 0;
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+				
+				$sql .=  ' '.$attributes['TYPE'];
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+				{
+					$sql .= ' NULL';
+				}
+				else
+				{
+					$sql .= ' NOT NULL';			
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+		}
+		
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key = array($this->db->_protect_identifiers($key));
+				}
+				
+				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n);";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _drop_table($table)
+	{
+		return "DROP TABLE ".$this->db->_escape_identifiers($table)." CASCADE";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			return $sql;
+		}
+
+		$sql .= " $column_definition";
+
+		if ($default_value != '')
+		{
+			$sql .= " DEFAULT \"$default_value\"";
+		}
+
+		if ($null === NULL)
+		{
+			$sql .= ' NULL';
+		}
+		else
+		{
+			$sql .= ' NOT NULL';
+		}
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+
+
+}
+
+/* End of file postgre_forge.php */
 /* 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 78b9a60..3206c13 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_result.php
@@ -1,169 +1,169 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Postgres Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_postgre_result extends CI_DB_result {

-

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @pg_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @pg_num_fields($this->result_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$field_names[] = pg_field_name($this->result_id, $i);

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$F 				= new stdClass();

-			$F->name 		= pg_field_name($this->result_id, $i);

-			$F->type 		= pg_field_type($this->result_id, $i);

-			$F->max_length	= pg_field_size($this->result_id, $i);

-			$F->primary_key = 0;

-			$F->default		= '';

-

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		if (is_resource($this->result_id))

-		{

-			pg_free_result($this->result_id);

-			$this->result_id = FALSE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return pg_result_seek($this->result_id, $n);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		return pg_fetch_assoc($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		return pg_fetch_object($this->result_id);

-	}

-	

-}

-

-

-/* End of file postgre_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Postgres Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_postgre_result extends CI_DB_result {
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @pg_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @pg_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$field_names[] = pg_field_name($this->result_id, $i);
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new stdClass();
+			$F->name 		= pg_field_name($this->result_id, $i);
+			$F->type 		= pg_field_type($this->result_id, $i);
+			$F->max_length	= pg_field_size($this->result_id, $i);
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		if (is_resource($this->result_id))
+		{
+			pg_free_result($this->result_id);
+			$this->result_id = FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return pg_result_seek($this->result_id, $n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return pg_fetch_assoc($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	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 f9b0f22..06292f2 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -1,124 +1,124 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Postgre Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_postgre_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		return "SELECT datname FROM pg_database";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Is table optimization supported in Postgre?

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Are table repairs supported in Postgre?

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Postgre Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database($name)

-	{

-		return "CREATE DATABASE ".$name;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		return "DROP DATABASE ".$name;

-	}

-

-

-}

-

-

-/* End of file postgre_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Postgre Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_postgre_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		return "SELECT datname FROM pg_database";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Is table optimization supported in Postgre?
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Are table repairs supported in Postgre?
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Postgre Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database($name)
+	{
+		return "CREATE DATABASE ".$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		return "DROP DATABASE ".$name;
+	}
+
+
+}
+
+
+/* End of file postgre_utility.php */
 /* Location: ./system/database/drivers/postgre/postgre_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/index.html b/system/database/drivers/sqlite/index.html
index 065d2da..c942a79 100644
--- a/system/database/drivers/sqlite/index.html
+++ b/system/database/drivers/sqlite/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 992e247..058cef7 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -1,612 +1,612 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-

-

-/**

- * SQLite Database Adapter Class

- *

- * Note: _DB is an extender class that the app controller

- * creates dynamically based on whether the active record

- * class is being used or not.

- *

- * @package		CodeIgniter

- * @subpackage	Drivers

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_sqlite_driver extends CI_DB {

-

-	var $dbdriver = 'sqlite';

-	

-	// The character used to escape with - not needed for SQLite

-	var $_escape_char = '';

-

-	/**

-	 * 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

-

-	/**

-	 * Non-persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_connect()

-	{

-		if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))

-		{

-			log_message('error', $error);

-			

-			if ($this->db_debug)

-			{

-				$this->display_error($error, '', TRUE);

-			}

-			

-			return FALSE;

-		}

-		

-		return $conn_id;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Persistent database connection

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_pconnect()

-	{

-		if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))

-		{

-			log_message('error', $error);

-			

-			if ($this->db_debug)

-			{

-				$this->display_error($error, '', TRUE);

-			}

-			

-			return FALSE;

-		}

-		

-		return $conn_id;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Select the database

-	 *

-	 * @access	private called by the base class

-	 * @return	resource

-	 */	

-	function db_select()

-	{

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set client character set

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	resource

-	 */

-	function db_set_charset($charset, $collation)

-	{

-		// @todo - add support if needed

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Version number query string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _version()

-	{

-		return sqlite_libversion();

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Execute the query

-	 *

-	 * @access	private called by the base class

-	 * @param	string	an SQL query

-	 * @return	resource

-	 */	

-	function _execute($sql)

-	{

-		$sql = $this->_prep_query($sql);

-		return @sqlite_query($this->conn_id, $sql);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Prep the query

-	 *

-	 * If needed, each database adapter can prep the query string

-	 *

-	 * @access	private called by execute()

-	 * @param	string	an SQL query

-	 * @return	string

-	 */	

-	function _prep_query($sql)

-	{

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Begin Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_begin($test_mode = FALSE)

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-		

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		// Reset the transaction failure flag.

-		// If the $test_mode flag is set to TRUE transactions will be rolled back

-		// even if the queries produce a successful result.

-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;

-

-		$this->simple_query('BEGIN TRANSACTION');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Commit Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_commit()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('COMMIT');

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rollback Transaction

-	 *

-	 * @access	public

-	 * @return	bool		

-	 */	

-	function trans_rollback()

-	{

-		if ( ! $this->trans_enabled)

-		{

-			return TRUE;

-		}

-

-		// When transactions are nested we only begin/commit/rollback the outermost ones

-		if ($this->_trans_depth > 0)

-		{

-			return TRUE;

-		}

-

-		$this->simple_query('ROLLBACK');

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape String

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function escape_str($str)	

-	{

-		return sqlite_escape_string($str);

-	}

-		

-	// --------------------------------------------------------------------

-

-	/**

-	 * Affected Rows

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function affected_rows()

-	{

-		return sqlite_changes($this->conn_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Insert ID

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function insert_id()

-	{

-		return @sqlite_last_insert_rowid($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * "Count All" query

-	 *

-	 * Generates a platform-specific query string that counts all records in

-	 * the specified database

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function count_all($table = '')

-	{

-		if ($table == '')

-			return '0';

-	

-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));

-		

-		if ($query->num_rows() == 0)

-			return '0';

-

-		$row = $query->row();

-		return $row->numrows;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * List table query

-	 *

-	 * Generates a platform-specific query string so that the table names can be fetched

-	 *

-	 * @access	private

-	 * @param	boolean

-	 * @return	string

-	 */

-	function _list_tables($prefix_limit = FALSE)

-	{

-		$sql = "SELECT name from sqlite_master WHERE type='table'";

-

-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')

-		{

-			$sql .= " AND 'name' LIKE '".$this->dbprefix."%'";

-		}

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show column query

-	 *

-	 * 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 = '')

-	{

-		// Not supported

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data query

-	 *

-	 * 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)

-	{

-		return "SELECT * FROM ".$table." LIMIT 1";

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message string

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _error_message()

-	{

-		return sqlite_error_string(sqlite_last_error($this->conn_id));

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * The error message number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */

-	function _error_number()

-	{

-		return sqlite_last_error($this->conn_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Escape the SQL Identifiers

-	 *

-	 * This function escapes column and table names

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _escape_identifiers($item)

-	{

-		if ($this->_escape_char == '')

-		{

-			return $item;

-		}

-

-		foreach ($this->_reserved_identifiers as $id)

-		{

-			if (strpos($item, '.'.$id) !== FALSE)

-			{

-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  

-				

-				// remove duplicates if the user already included the escape

-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-			}		

-		}

-	

-		if (strpos($item, '.') !== FALSE)

-		{

-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			

-		}

-		else

-		{

-			$str = $this->_escape_char.$item.$this->_escape_char;

-		}

-		

-		// remove duplicates if the user already included the escape

-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);

-	}

-			

-	// --------------------------------------------------------------------

-

-	/**

-	 * From Tables

-	 *

-	 * This function implicitly groups FROM tables so there is no confusion

-	 * about operator precedence in harmony with SQL standards

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _from_tables($tables)

-	{

-		if ( ! is_array($tables))

-		{

-			$tables = array($tables);

-		}

-		

-		return '('.implode(', ', $tables).')';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert statement

-	 *

-	 * Generates a platform-specific insert string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the insert keys

-	 * @param	array	the insert values

-	 * @return	string

-	 */

-	function _insert($table, $keys, $values)

-	{	

-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update statement

-	 *

-	 * Generates a platform-specific update string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the update data

-	 * @param	array	the where clause

-	 * @param	array	the orderby clause

-	 * @param	array	the limit clause

-	 * @return	string

-	 */

-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)

-	{

-		foreach($values as $key => $val)

-		{

-			$valstr[] = $key." = ".$val;

-		}

-		

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-		

-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';

-	

-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);

-

-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';

-

-		$sql .= $orderby.$limit;

-		

-		return $sql;

-	}

-

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Truncate statement

-	 *

-	 * Generates a platform-specific truncate string from the supplied data

-	 * If the database does not support the truncate() command

-	 * This function maps to "DELETE FROM table"

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @return	string

-	 */	

-	function _truncate($table)

-	{

-		return $this->_delete($table);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete statement

-	 *

-	 * Generates a platform-specific delete string from the supplied data

-	 *

-	 * @access	public

-	 * @param	string	the table name

-	 * @param	array	the where clause

-	 * @param	string	the limit clause

-	 * @return	string

-	 */	

-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)

-	{

-		$conditions = '';

-

-		if (count($where) > 0 OR count($like) > 0)

-		{

-			$conditions = "\nWHERE ";

-			$conditions .= implode("\n", $this->ar_where);

-

-			if (count($where) > 0 && count($like) > 0)

-			{

-				$conditions .= " AND ";

-			}

-			$conditions .= implode("\n", $like);

-		}

-

-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;

-	

-		return "DELETE FROM ".$table.$conditions.$limit;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Limit string

-	 *

-	 * Generates a platform-specific LIMIT clause

-	 *

-	 * @access	public

-	 * @param	string	the sql query string

-	 * @param	integer	the number of rows to limit the query to

-	 * @param	integer	the offset value

-	 * @return	string

-	 */

-	function _limit($sql, $limit, $offset)

-	{	

-		if ($offset == 0)

-		{

-			$offset = '';

-		}

-		else

-		{

-			$offset .= ", ";

-		}

-		

-		return $sql."LIMIT ".$offset.$limit;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Close DB Connection

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function _close($conn_id)

-	{

-		@sqlite_close($conn_id);

-	}

-

-

-}

-

-

-/* End of file sqlite_driver.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+
+
+/**
+ * SQLite Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite_driver extends CI_DB {
+
+	var $dbdriver = 'sqlite';
+	
+	// The character used to escape with - not needed for SQLite
+	var $_escape_char = '';
+
+	/**
+	 * 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
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_connect()
+	{
+		if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))
+		{
+			log_message('error', $error);
+			
+			if ($this->db_debug)
+			{
+				$this->display_error($error, '', TRUE);
+			}
+			
+			return FALSE;
+		}
+		
+		return $conn_id;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_pconnect()
+	{
+		if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))
+		{
+			log_message('error', $error);
+			
+			if ($this->db_debug)
+			{
+				$this->display_error($error, '', TRUE);
+			}
+			
+			return FALSE;
+		}
+		
+		return $conn_id;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @access	private called by the base class
+	 * @return	resource
+	 */	
+	function db_select()
+	{
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set client character set
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	resource
+	 */
+	function db_set_charset($charset, $collation)
+	{
+		// @todo - add support if needed
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Version number query string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _version()
+	{
+		return sqlite_libversion();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @access	private called by the base class
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */	
+	function _execute($sql)
+	{
+		$sql = $this->_prep_query($sql);
+		return @sqlite_query($this->conn_id, $sql);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Prep the query
+	 *
+	 * If needed, each database adapter can prep the query string
+	 *
+	 * @access	private called by execute()
+	 * @param	string	an SQL query
+	 * @return	string
+	 */	
+	function _prep_query($sql)
+	{
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_begin($test_mode = FALSE)
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+		
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+
+		$this->simple_query('BEGIN TRANSACTION');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_commit()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('COMMIT');
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @access	public
+	 * @return	bool		
+	 */	
+	function trans_rollback()
+	{
+		if ( ! $this->trans_enabled)
+		{
+			return TRUE;
+		}
+
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ($this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		$this->simple_query('ROLLBACK');
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function escape_str($str)	
+	{
+		return sqlite_escape_string($str);
+	}
+		
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function affected_rows()
+	{
+		return sqlite_changes($this->conn_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function insert_id()
+	{
+		return @sqlite_last_insert_rowid($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function count_all($table = '')
+	{
+		if ($table == '')
+			return '0';
+	
+		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		
+		if ($query->num_rows() == 0)
+			return '0';
+
+		$row = $query->row();
+		return $row->numrows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * List table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @access	private
+	 * @param	boolean
+	 * @return	string
+	 */
+	function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = "SELECT name from sqlite_master WHERE type='table'";
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= " AND 'name' LIKE '".$this->dbprefix."%'";
+		}
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * 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 = '')
+	{
+		// Not supported
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * 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)
+	{
+		return "SELECT * FROM ".$table." LIMIT 1";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _error_message()
+	{
+		return sqlite_error_string(sqlite_last_error($this->conn_id));
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */
+	function _error_number()
+	{
+		return sqlite_last_error($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _escape_identifiers($item)
+	{
+		if ($this->_escape_char == '')
+		{
+			return $item;
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);  
+				
+				// remove duplicates if the user already included the escape
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+			}		
+		}
+	
+		if (strpos($item, '.') !== FALSE)
+		{
+			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;			
+		}
+		else
+		{
+			$str = $this->_escape_char.$item.$this->_escape_char;
+		}
+		
+		// remove duplicates if the user already included the escape
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
+	}
+			
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _from_tables($tables)
+	{
+		if ( ! is_array($tables))
+		{
+			$tables = array($tables);
+		}
+		
+		return '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	function _insert($table, $keys, $values)
+	{	
+		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @return	string
+	 */
+	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	{
+		foreach($values as $key => $val)
+		{
+			$valstr[] = $key." = ".$val;
+		}
+		
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		
+		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+	
+		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+
+		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+
+		$sql .= $orderby.$limit;
+		
+		return $sql;
+	}
+
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 * If the database does not support the truncate() command
+	 * This function maps to "DELETE FROM table"
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @return	string
+	 */	
+	function _truncate($table)
+	{
+		return $this->_delete($table);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @access	public
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */	
+	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = '';
+
+		if (count($where) > 0 OR count($like) > 0)
+		{
+			$conditions = "\nWHERE ";
+			$conditions .= implode("\n", $this->ar_where);
+
+			if (count($where) > 0 && count($like) > 0)
+			{
+				$conditions .= " AND ";
+			}
+			$conditions .= implode("\n", $like);
+		}
+
+		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+	
+		return "DELETE FROM ".$table.$conditions.$limit;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @access	public
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	function _limit($sql, $limit, $offset)
+	{	
+		if ($offset == 0)
+		{
+			$offset = '';
+		}
+		else
+		{
+			$offset .= ", ";
+		}
+		
+		return $sql."LIMIT ".$offset.$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function _close($conn_id)
+	{
+		@sqlite_close($conn_id);
+	}
+
+
+}
+
+
+/* End of file 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 2039525..73630de 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_forge.php
@@ -1,265 +1,265 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * SQLite Forge Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_sqlite_forge extends CI_DB_forge {

-

-	/**

-	 * Create database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database()

-	{

-		// In SQLite, a database is created when you connect to the database.

-		// We'll return TRUE so that an error isn't generated

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))

-		{

-			if ($this->db->db_debug)

-			{

-				return $this->db->display_error('db_unable_to_drop');

-			}

-			return FALSE;

-		}

-		return TRUE;

-	}

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Table

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @param	array	the fields

-	 * @param	mixed	primary key(s)

-	 * @param	mixed	key(s)

-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL

-	 * @return	bool

-	 */

-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)

-	{

-		$sql = 'CREATE TABLE ';

-		

-		// IF NOT EXISTS added to SQLite in 3.3.0

-		if ($if_not_exists === TRUE && version_compare($this->_version(), '3.3.0', '>=') === TRUE)

-		{

-			$sql .= 'IF NOT EXISTS ';

-		}

-		

-		$sql .= $this->db->_escape_identifiers($table)."(";

-		$current_field_count = 0;

-

-		foreach ($fields as $field=>$attributes)

-		{

-			// Numeric field names aren't allowed in databases, so if the key is

-			// numeric, we know it was assigned by PHP and the developer manually

-			// entered the field information, so we'll simply add it to the list

-			if (is_numeric($field))

-			{

-				$sql .= "\n\t$attributes";

-			}

-			else

-			{

-				$attributes = array_change_key_case($attributes, CASE_UPPER);

-				

-				$sql .= "\n\t".$this->db->_protect_identifiers($field);

-				

-				$sql .=  ' '.$attributes['TYPE'];

-	

-				if (array_key_exists('CONSTRAINT', $attributes))

-				{

-					$sql .= '('.$attributes['CONSTRAINT'].')';

-				}

-	

-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)

-				{

-					$sql .= ' UNSIGNED';

-				}

-	

-				if (array_key_exists('DEFAULT', $attributes))

-				{

-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';

-				}

-	

-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)

-				{

-					$sql .= ' NULL';

-				}

-				else

-				{

-					$sql .= ' NOT NULL';			

-				}

-	

-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)

-				{

-					$sql .= ' AUTO_INCREMENT';

-				}

-			}

-			

-			// don't add a comma on the end of the last field

-			if (++$current_field_count < count($fields))

-			{

-				$sql .= ',';

-			}

-		}

-

-		if (count($primary_keys) > 0)

-		{

-			$primary_keys = $this->db->_protect_identifiers($primary_keys);

-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";

-		}

-

-		if (is_array($keys) && count($keys) > 0)

-		{

-			foreach ($keys as $key)

-			{

-				if (is_array($key))

-				{

-					$key = $this->db->_protect_identifiers($key);	

-				}

-				else

-				{

-					$key = array($this->db->_protect_identifiers($key));

-				}

-				

-				$sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";

-			}

-		}

-

-		$sql .= "\n)";

-

-		return $sql;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop Table

-	 *

-	 *  Unsupported feature in SQLite

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _drop_table($table)

-	{

-		if ($this->db->db_debug)

-		{

-			return $this->db->display_error('db_unsuported_feature');

-		}

-		return array();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Alter table query

-	 *

-	 * Generates a platform-specific query so that a table can be altered

-	 * Called by add_column(), drop_column(), and column_alter(),

-	 *

-	 * @access	private

-	 * @param	string	the ALTER type (ADD, DROP, CHANGE)

-	 * @param	string	the column name

-	 * @param	string	the table name

-	 * @param	string	the column definition

-	 * @param	string	the default value

-	 * @param	boolean	should 'NOT NULL' be added

-	 * @param	string	the field after which we should add the new field

-	 * @return	object

-	 */

-	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);

-

-		// DROP has everything it needs now.

-		if ($alter_type == 'DROP')

-		{

-			// SQLite does not support dropping columns

-			// http://www.sqlite.org/omitted.html

-			// http://www.sqlite.org/faq.html#q11

-			return FALSE;

-		}

-

-		$sql .= " $column_definition";

-

-		if ($default_value != '')

-		{

-			$sql .= " DEFAULT \"$default_value\"";

-		}

-

-		if ($null === NULL)

-		{

-			$sql .= ' NULL';

-		}

-		else

-		{

-			$sql .= ' NOT NULL';

-		}

-

-		if ($after_field != '')

-		{

-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);

-		}

-		

-		return $sql;

-		

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename a table

-	 *

-	 * Generates a platform-specific query so that a table can be renamed

-	 *

-	 * @access	private

-	 * @param	string	the old table name

-	 * @param	string	the new table name

-	 * @return	string

-	 */

-	function _rename_table($table_name, $new_table_name)

-	{

-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);

-		return $sql;

-	}

-}

-

-/* End of file sqlite_forge.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * SQLite Forge Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database()
+	{
+		// In SQLite, a database is created when you connect to the database.
+		// We'll return TRUE so that an error isn't generated
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))
+		{
+			if ($this->db->db_debug)
+			{
+				return $this->db->display_error('db_unable_to_drop');
+			}
+			return FALSE;
+		}
+		return TRUE;
+	}
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+		
+		// IF NOT EXISTS added to SQLite in 3.3.0
+		if ($if_not_exists === TRUE && version_compare($this->_version(), '3.3.0', '>=') === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+		
+		$sql .= $this->db->_escape_identifiers($table)."(";
+		$current_field_count = 0;
+
+		foreach ($fields as $field=>$attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t$attributes";
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				
+				$sql .= "\n\t".$this->db->_protect_identifiers($field);
+				
+				$sql .=  ' '.$attributes['TYPE'];
+	
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+	
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+	
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+				}
+	
+				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
+				{
+					$sql .= ' NULL';
+				}
+				else
+				{
+					$sql .= ' NOT NULL';			
+				}
+	
+				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+			
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$primary_keys = $this->db->_protect_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				if (is_array($key))
+				{
+					$key = $this->db->_protect_identifiers($key);	
+				}
+				else
+				{
+					$key = array($this->db->_protect_identifiers($key));
+				}
+				
+				$sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n)";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 *  Unsupported feature in SQLite
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _drop_table($table)
+	{
+		if ($this->db->db_debug)
+		{
+			return $this->db->display_error('db_unsuported_feature');
+		}
+		return array();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @access	private
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	object
+	 */
+	function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name);
+
+		// DROP has everything it needs now.
+		if ($alter_type == 'DROP')
+		{
+			// SQLite does not support dropping columns
+			// http://www.sqlite.org/omitted.html
+			// http://www.sqlite.org/faq.html#q11
+			return FALSE;
+		}
+
+		$sql .= " $column_definition";
+
+		if ($default_value != '')
+		{
+			$sql .= " DEFAULT \"$default_value\"";
+		}
+
+		if ($null === NULL)
+		{
+			$sql .= ' NULL';
+		}
+		else
+		{
+			$sql .= ' NOT NULL';
+		}
+
+		if ($after_field != '')
+		{
+			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+		}
+		
+		return $sql;
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename a table
+	 *
+	 * Generates a platform-specific query so that a table can be renamed
+	 *
+	 * @access	private
+	 * @param	string	the old table name
+	 * @param	string	the new table name
+	 * @return	string
+	 */
+	function _rename_table($table_name, $new_table_name)
+	{
+		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
+		return $sql;
+	}
+}
+
+/* End of file 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 735a073..bed1698 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_result.php
@@ -1,179 +1,179 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * SQLite Result Class

- *

- * This class extends the parent result class: CI_DB_result

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_sqlite_result extends CI_DB_result {

-	

-	/**

-	 * Number of rows in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_rows()

-	{

-		return @sqlite_num_rows($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Number of fields in the result set

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function num_fields()

-	{

-		return @sqlite_num_fields($this->result_id);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch Field Names

-	 *

-	 * Generates an array of column names

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_fields()

-	{

-		$field_names = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$field_names[] = sqlite_field_name($this->result_id, $i);

-		}

-		

-		return $field_names;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Field data

-	 *

-	 * Generates an array of objects containing field meta-data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function field_data()

-	{

-		$retval = array();

-		for ($i = 0; $i < $this->num_fields(); $i++)

-		{

-			$F 				= new stdClass();

-			$F->name 		= sqlite_field_name($this->result_id, $i);

-			$F->type 		= 'varchar';

-			$F->max_length	= 0;

-			$F->primary_key = 0;

-			$F->default		= '';

-

-			$retval[] = $F;

-		}

-		

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Free the result

-	 *

-	 * @return	null

-	 */		

-	function free_result()

-	{

-		// Not implemented in SQLite

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Data Seek

-	 *

-	 * Moves the internal pointer to the desired offset.  We call

-	 * this internally before fetching results to make sure the

-	 * result set starts at zero

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _data_seek($n = 0)

-	{

-		return sqlite_seek($this->result_id, $n);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - associative array

-	 *

-	 * Returns the result set as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _fetch_assoc()

-	{

-		return sqlite_fetch_array($this->result_id);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Result - object

-	 *

-	 * Returns the result set as an object

-	 *

-	 * @access	private

-	 * @return	object

-	 */

-	function _fetch_object()

-	{

-		if (function_exists('sqlite_fetch_object'))

-		{

-			return sqlite_fetch_object($this->result_id);

-		}

-		else

-		{

-			$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);

-			if (is_array($arr))

-			{

-				$obj = (object) $arr;

-				return $obj;

-			} else {

-				return NULL;

-			} 

-		}

-	}

-

-}

-

-

-/* End of file sqlite_result.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * SQLite Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite_result extends CI_DB_result {
+	
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_rows()
+	{
+		return @sqlite_num_rows($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function num_fields()
+	{
+		return @sqlite_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$field_names[] = sqlite_field_name($this->result_id, $i);
+		}
+		
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function field_data()
+	{
+		$retval = array();
+		for ($i = 0; $i < $this->num_fields(); $i++)
+		{
+			$F 				= new stdClass();
+			$F->name 		= sqlite_field_name($this->result_id, $i);
+			$F->type 		= 'varchar';
+			$F->max_length	= 0;
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+		
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */		
+	function free_result()
+	{
+		// Not implemented in SQLite
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset.  We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _data_seek($n = 0)
+	{
+		return sqlite_seek($this->result_id, $n);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _fetch_assoc()
+	{
+		return sqlite_fetch_array($this->result_id);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @access	private
+	 * @return	object
+	 */
+	function _fetch_object()
+	{
+		if (function_exists('sqlite_fetch_object'))
+		{
+			return sqlite_fetch_object($this->result_id);
+		}
+		else
+		{
+			$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
+			if (is_array($arr))
+			{
+				$obj = (object) $arr;
+				return $obj;
+			} else {
+				return NULL;
+			} 
+		}
+	}
+
+}
+
+
+/* End of file sqlite_result.php */
 /* Location: ./system/database/drivers/sqlite/sqlite_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index 3527b5b..c067403 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -1,141 +1,141 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * SQLite Utility Class

- *

- * @category	Database

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/database/

- */

-class CI_DB_sqlite_utility extends CI_DB_utility {

-

-	/**

-	 * List databases

-	 *

-	 * I don't believe you can do a database listing with SQLite

-	 * since each database is its own file.  I suppose we could

-	 * try reading a directory looking for SQLite files, but

-	 * that doesn't seem like a terribly good idea

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _list_databases()

-	{

-		if ($this->db_debug)

-		{

-			return $this->display_error('db_unsuported_feature');

-		}

-		return array();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Optimize table query

-	 *

-	 * Is optimization even supported in SQLite?

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _optimize_table($table)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Repair table query

-	 *

-	 * Are table repairs even supported in SQLite?

-	 *

-	 * @access	private

-	 * @param	string	the table name

-	 * @return	object

-	 */

-	function _repair_table($table)

-	{

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * SQLite Export

-	 *

-	 * @access	private

-	 * @param	array	Preferences

-	 * @return	mixed

-	 */

-	function _backup($params = array())

-	{

-		// Currently unsupported

-		return $this->db->display_error('db_unsuported_feature');

-	}

-

-	/**

-	 *

-	 * The functions below have been deprecated as of 1.6, and are only here for backwards

-	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation

-	 * is STRONGLY discouraged in favour if using dbforge.

-	 *

-	 */

-

-	/**

-	 * Create database

-	 *

-	 * @access	public

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _create_database()

-	{

-		// In SQLite, a database is created when you connect to the database.

-		// We'll return TRUE so that an error isn't generated

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Drop database

-	 *

-	 * @access	private

-	 * @param	string	the database name

-	 * @return	bool

-	 */

-	function _drop_database($name)

-	{

-		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))

-		{

-			if ($this->db->db_debug)

-			{

-				return $this->db->display_error('db_unable_to_drop');

-			}

-			return FALSE;

-		}

-		return TRUE;

-	}

-

-}

-

-/* End of file sqlite_utility.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * SQLite Utility Class
+ *
+ * @category	Database
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite_utility extends CI_DB_utility {
+
+	/**
+	 * List databases
+	 *
+	 * I don't believe you can do a database listing with SQLite
+	 * since each database is its own file.  I suppose we could
+	 * try reading a directory looking for SQLite files, but
+	 * that doesn't seem like a terribly good idea
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _list_databases()
+	{
+		if ($this->db_debug)
+		{
+			return $this->display_error('db_unsuported_feature');
+		}
+		return array();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Optimize table query
+	 *
+	 * Is optimization even supported in SQLite?
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _optimize_table($table)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Repair table query
+	 *
+	 * Are table repairs even supported in SQLite?
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	function _repair_table($table)
+	{
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * SQLite Export
+	 *
+	 * @access	private
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	function _backup($params = array())
+	{
+		// Currently unsupported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+	/**
+	 *
+	 * The functions below have been deprecated as of 1.6, and are only here for backwards
+	 * compatibility.  They now reside in dbforge().  The use of dbutils for database manipulation
+	 * is STRONGLY discouraged in favour if using dbforge.
+	 *
+	 */
+
+	/**
+	 * Create database
+	 *
+	 * @access	public
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _create_database()
+	{
+		// In SQLite, a database is created when you connect to the database.
+		// We'll return TRUE so that an error isn't generated
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @access	private
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	function _drop_database($name)
+	{
+		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))
+		{
+			if ($this->db->db_debug)
+			{
+				return $this->db->display_error('db_unable_to_drop');
+			}
+			return FALSE;
+		}
+		return TRUE;
+	}
+
+}
+
+/* End of file sqlite_utility.php */
 /* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
\ No newline at end of file
diff --git a/system/database/index.html b/system/database/index.html
index 065d2da..c942a79 100644
--- a/system/database/index.html
+++ b/system/database/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/fonts/index.html b/system/fonts/index.html
index 065d2da..c942a79 100644
--- a/system/fonts/index.html
+++ b/system/fonts/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index 4c8323b..411d309 100644
--- a/system/helpers/array_helper.php
+++ b/system/helpers/array_helper.php
@@ -1,78 +1,78 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Array Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/array_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Element

- *

- * Lets you determine whether an array index is set and whether it has a value.

- * If the element is empty it returns FALSE (or whatever you specify as the default value.)

- *

- * @access	public

- * @param	string

- * @param	array

- * @param	mixed

- * @return	mixed	depends on what the array contains

- */	

-if ( ! function_exists('element'))

-{

-	function element($item, $array, $default = FALSE)

-	{

-		if ( ! isset($array[$item]) OR $array[$item] == "")

-		{

-			return $default;

-		}

-

-		return $array[$item];

-	}	

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Random Element - Takes an array as input and returns a random element

- *

- * @access	public

- * @param	array

- * @return	mixed	depends on what the array contains

- */	

-if ( ! function_exists('random_element'))

-{

-	function random_element($array)

-	{

-		if ( ! is_array($array))

-		{

-			return $array;

-		}

-		return $array[array_rand($array)];

-	}	

-}

-

-

-/* End of file array_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Array Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/array_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Element
+ *
+ * Lets you determine whether an array index is set and whether it has a value.
+ * If the element is empty it returns FALSE (or whatever you specify as the default value.)
+ *
+ * @access	public
+ * @param	string
+ * @param	array
+ * @param	mixed
+ * @return	mixed	depends on what the array contains
+ */	
+if ( ! function_exists('element'))
+{
+	function element($item, $array, $default = FALSE)
+	{
+		if ( ! isset($array[$item]) OR $array[$item] == "")
+		{
+			return $default;
+		}
+
+		return $array[$item];
+	}	
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Random Element - Takes an array as input and returns a random element
+ *
+ * @access	public
+ * @param	array
+ * @return	mixed	depends on what the array contains
+ */	
+if ( ! function_exists('random_element'))
+{
+	function random_element($array)
+	{
+		if ( ! is_array($array))
+		{
+			return $array;
+		}
+		return $array[array_rand($array)];
+	}	
+}
+
+
+/* End of file array_helper.php */
 /* Location: ./system/helpers/array_helper.php */
\ No newline at end of file
diff --git a/system/helpers/compatibility_helper.php b/system/helpers/compatibility_helper.php
index 996a6d7..3b37cea 100644
--- a/system/helpers/compatibility_helper.php
+++ b/system/helpers/compatibility_helper.php
@@ -1,498 +1,498 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Compatibility Helpers

- *

- * This helper contains some functions based on the PEAR PHP_Compat library

- * http://pear.php.net/package/PHP_Compat

- * 

- * The PEAR compat library is a little bloated and the code doesn't harmonize

- * well with CodeIgniter, so those functions have been refactored.

- * We cheat a little and use CI's _exception_handler() to output our own PHP errors

- * so that the behavior fully mimicks the PHP 5 counterparts.  -- Derek Jones

- * 

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/compatibility_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-if ( ! defined('PHP_EOL'))

-{

-	define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");

-} 

-

-// ------------------------------------------------------------------------

-

-/**

- * file_put_contents()

- *

- * Writes a string to a file

- * http://us.php.net/manual/en/function.file_put_contents.php

- * argument 4, $context, not supported

- *

- * @access	public

- * @param	string		file name

- * @param	mixed		data to be written

- * @param	int			flags

- * @return	int			length of written string

- */

-if ( ! function_exists('file_put_contents'))

-{

-	function file_put_contents($filename, $data, $flags = NULL)

-	{

-		if (is_scalar($data))

-		{

-			settype($data, 'STRING');

-		}

-

-		if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-

-		// read stream if given a stream resource

-		if (is_resource($data))

-		{

-			if (get_resource_type($data) !== 'stream')

-			{

-				$backtrace = debug_backtrace();

-				_exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);

-				return FALSE;

-			}

-

-			$text = '';

-			

-			while ( ! feof($data))

-			{

-				$text .= fread($data, 4096);

-			}

-			

-			$data = $text;

-			unset($text);

-		}

-	

-		// strings only please!

-		if (is_array($data))

-		{

-			$data = implode('', $data);

-		}

-

-		// Set the appropriate mode

-		if (($flags & 8) > 0) // 8 = FILE_APPEND flag

-		{

-			$mode = FOPEN_WRITE_CREATE;

-		}

-		else

-		{

-			$mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;

-		}

-	

-		// Check if we're using the include path

-		if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag

-		{

-			$use_include_path = TRUE;

-		}

-		else

-		{

-			$use_include_path = FALSE;

-		}

-	

-		$fp = @fopen($filename, $mode, $use_include_path);

-	

-		if ($fp === FALSE)

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		if (($flags & LOCK_EX) > 0)

-		{

-			if ( ! flock($fp, LOCK_EX))

-			{

-				$backtrace = debug_backtrace();

-				_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);

-				return FALSE;

-			}

-		}

-		

-		// write it

-		if (($written = @fwrite($fp, $data)) === FALSE)

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);

-		}

-	

-		// Close the handle

-		@fclose($fp);

-	

-		// Return length

-		return $written;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * fputcsv()

- *

- * Format line as CSV and write to file pointer

- * http://us.php.net/manual/en/function.fputcsv.php

- *

- * @access	public

- * @param	resource	file pointer

- * @param	array		data to be written

- * @param	string		delimiter

- * @param	string		enclosure

- * @return	int			length of written string

- */

-if ( ! function_exists('fputcsv'))

-{

-	function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')

-	{

-		// Checking for a handle resource

-		if ( ! is_resource($handle))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		// OK, it is a resource, but is it a stream?

-		if (get_resource_type($handle) !== 'stream')

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		// Checking for an array of fields

-		if ( ! is_array($fields))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		// validate delimiter

-		if (strlen($delimiter) > 1)

-		{

-			$delimiter = substr($delimiter, 0, 1);

-			$backtrace = debug_backtrace();

-			_exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);

-		}

-	

-		// validate enclosure

-		if (strlen($enclosure) > 1)

-		{

-			$enclosure = substr($enclosure, 0, 1);

-			$backtrace = debug_backtrace();

-			_exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);

-

-		}

-	

-		$out = '';

-	

-		foreach ($fields as $cell)

-		{

-			$cell = str_replace($enclosure, $enclosure.$enclosure, $cell);

-

-			if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)

-			{

-				$out .= $enclosure.$cell.$enclosure.$delimiter;

-			}

-			else

-			{

-				$out .= $cell.$delimiter;

-			}

-		}

-	

-		$length = @fwrite($handle, substr($out, 0, -1)."\n");

-	

-		return $length;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * stripos()

- *

- * Find position of first occurrence of a case-insensitive string

- * http://us.php.net/manual/en/function.stripos.php

- *

- * @access	public

- * @param	string		haystack

- * @param	string		needle

- * @param	int			offset

- * @return	int			numeric position of the first occurrence of needle in the haystack

- */

-if ( ! function_exists('stripos'))

-{

-	function stripos($haystack, $needle, $offset = NULL)

-	{

-		// Cast non string scalar values

-		if (is_scalar($haystack))

-		{

-			settype($haystack, 'STRING');

-		}

-	

-		if ( ! is_string($haystack))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		if ( ! is_scalar($needle))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		if (is_float($offset))

-		{

-			$offset = (int)$offset;

-		}

-	

-		if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return NULL;

-		}

-	

-		return strpos(strtolower($haystack), strtolower($needle), $offset);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * str_ireplace()

- *

- * Find position of first occurrence of a case-insensitive string

- * http://us.php.net/manual/en/function.str-ireplace.php

- * (parameter 4, $count, is not supported as to do so in PHP 4 would make

- * it a required parameter)

- *

- * @access	public

- * @param	mixed		search

- * @param	mixed		replace

- * @param	mixed		subject

- * @return	int			numeric position of the first occurrence of needle in the haystack

- */

-if ( ! function_exists('str_ireplace'))

-{

-	function str_ireplace($search, $replace, $subject)

-	{

-		// Nothing to do here

-		if ($search === NULL OR $subject === NULL)

-		{

-			return $subject;

-		}

-	

-		// Crazy arguments

-		if (is_scalar($search) && is_array($replace))

-		{

-			$backtrace = debug_backtrace();

-

-			if (is_object($replace))

-			{

-				show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);

-			}

-			else

-			{

-				_exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);

-			}

-		}

-	

-		// Searching for an array

-		if (is_array($search))

-		{

-			// Replacing with an array

-			if (is_array($replace))

-			{

-				$search = array_values($search);

-				$replace = array_values($replace);

-

-				if (count($search) >= count($replace))

-				{

-					$replace = array_pad($replace, count($search), '');

-				}

-				else

-				{

-					$replace = array_slice($replace, 0, count($search));

-				}

-			}

-			else

-			{

-				// Replacing with a string all positions

-				$replace = array_fill(0, count($search), $replace);

-			}

-		}

-		else

-		{

-			//Searching for a string and replacing with a string.

-			$search  = array((string)$search);

-			$replace = array((string)$replace);

-		}

-		

-		// Prepare the search array

-		foreach ($search as $search_key => $search_value)

-		{

-			$search[$search_key] = '/'.preg_quote($search_value, '/').'/i';

-		}

-		

-		// Prepare the replace array (escape backreferences)

-		foreach ($replace as $k => $v)

-		{

-			$replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);

-		}

-	

-		// do the replacement

-		$result = preg_replace($search, $replace, (array)$subject);

-	

-		// Check if subject was initially a string and return it as a string

-		if ( ! is_array($subject))

-		{

-			return current($result);

-		}

-	

-		// Otherwise, just return the array

-		return $result;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * http_build_query()

- *

- * Generate URL-encoded query string

- * http://us.php.net/manual/en/function.http-build-query.php

- *

- * @access	public

- * @param	array		form data

- * @param	string		numeric prefix

- * @param	string		argument separator

- * @return	string		URL-encoded string

- */

-if ( ! function_exists('http_build_query'))

-{

-	function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)

-	{

-		// Check the data

-		if ( ! is_array($formdata) && ! is_object($formdata))

-		{

-			$backtrace = debug_backtrace();

-			_exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);

-			return FALSE;

-		}

-	

-		// Cast it as array

-		if (is_object($formdata))

-		{

-			$formdata = get_object_vars($formdata);

-		}

-	

-		// If the array is empty, return NULL

-		if (empty($formdata))

-		{

-			return NULL;

-		}

-	

-		// Argument separator

-		if ($separator === NULL)

-		{

-			$separator = ini_get('arg_separator.output');

-

-			if (strlen($separator) == 0)

-			{

-				$separator = '&';

-			}

-		}

-	

-		// Start building the query

-		$tmp = array();

-

-		foreach ($formdata as $key => $val)

-		{

-			if ($val === NULL)

-			{

-				continue;

-			}

-	

-			if (is_integer($key) && $numeric_prefix != NULL)

-			{

-				$key = $numeric_prefix.$key;

-			}

-	

-			if (is_resource($val))

-			{

-				return NULL;

-			}

-			

-			// hand it off to a recursive parser

-			$tmp[] = _http_build_query_helper($key, $val, $separator);

-		}

-	

-		return implode($separator, $tmp);

-	}

-	

-	

-	// Helper helper.  Remind anyone of college?

-	// Required to handle recursion in nested arrays.

-	// 

-	// You could shave fractions of fractions of a second by moving where

-	// the urlencoding takes place, but it's much less intuitive, and if

-	// your application has 10,000 form fields, well, you have other problems ;)

-	function _http_build_query_helper($key, $val, $separator = '&')

-	{	

-		if (is_scalar($val))

-		{

-			return urlencode($key).'='.urlencode($val);			

-		}

-		else

-		{

-			// arrays please

-			if (is_object($val))

-			{

-				$val = get_object_vars($val);

-			}

-			

-			foreach ($val as $k => $v)

-			{

-				$tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);

-			}

-		}

-			

-		return implode($separator, $tmp);

-	}

-}

-

-

-/* End of file compatibility_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Compatibility Helpers
+ *
+ * This helper contains some functions based on the PEAR PHP_Compat library
+ * http://pear.php.net/package/PHP_Compat
+ * 
+ * The PEAR compat library is a little bloated and the code doesn't harmonize
+ * well with CodeIgniter, so those functions have been refactored.
+ * We cheat a little and use CI's _exception_handler() to output our own PHP errors
+ * so that the behavior fully mimicks the PHP 5 counterparts.  -- Derek Jones
+ * 
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/compatibility_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+if ( ! defined('PHP_EOL'))
+{
+	define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
+} 
+
+// ------------------------------------------------------------------------
+
+/**
+ * file_put_contents()
+ *
+ * Writes a string to a file
+ * http://us.php.net/manual/en/function.file_put_contents.php
+ * argument 4, $context, not supported
+ *
+ * @access	public
+ * @param	string		file name
+ * @param	mixed		data to be written
+ * @param	int			flags
+ * @return	int			length of written string
+ */
+if ( ! function_exists('file_put_contents'))
+{
+	function file_put_contents($filename, $data, $flags = NULL)
+	{
+		if (is_scalar($data))
+		{
+			settype($data, 'STRING');
+		}
+
+		if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+
+		// read stream if given a stream resource
+		if (is_resource($data))
+		{
+			if (get_resource_type($data) !== 'stream')
+			{
+				$backtrace = debug_backtrace();
+				_exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
+				return FALSE;
+			}
+
+			$text = '';
+			
+			while ( ! feof($data))
+			{
+				$text .= fread($data, 4096);
+			}
+			
+			$data = $text;
+			unset($text);
+		}
+	
+		// strings only please!
+		if (is_array($data))
+		{
+			$data = implode('', $data);
+		}
+
+		// Set the appropriate mode
+		if (($flags & 8) > 0) // 8 = FILE_APPEND flag
+		{
+			$mode = FOPEN_WRITE_CREATE;
+		}
+		else
+		{
+			$mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
+		}
+	
+		// Check if we're using the include path
+		if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
+		{
+			$use_include_path = TRUE;
+		}
+		else
+		{
+			$use_include_path = FALSE;
+		}
+	
+		$fp = @fopen($filename, $mode, $use_include_path);
+	
+		if ($fp === FALSE)
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		if (($flags & LOCK_EX) > 0)
+		{
+			if ( ! flock($fp, LOCK_EX))
+			{
+				$backtrace = debug_backtrace();
+				_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
+				return FALSE;
+			}
+		}
+		
+		// write it
+		if (($written = @fwrite($fp, $data)) === FALSE)
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
+		}
+	
+		// Close the handle
+		@fclose($fp);
+	
+		// Return length
+		return $written;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * fputcsv()
+ *
+ * Format line as CSV and write to file pointer
+ * http://us.php.net/manual/en/function.fputcsv.php
+ *
+ * @access	public
+ * @param	resource	file pointer
+ * @param	array		data to be written
+ * @param	string		delimiter
+ * @param	string		enclosure
+ * @return	int			length of written string
+ */
+if ( ! function_exists('fputcsv'))
+{
+	function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
+	{
+		// Checking for a handle resource
+		if ( ! is_resource($handle))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		// OK, it is a resource, but is it a stream?
+		if (get_resource_type($handle) !== 'stream')
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		// Checking for an array of fields
+		if ( ! is_array($fields))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		// validate delimiter
+		if (strlen($delimiter) > 1)
+		{
+			$delimiter = substr($delimiter, 0, 1);
+			$backtrace = debug_backtrace();
+			_exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+		}
+	
+		// validate enclosure
+		if (strlen($enclosure) > 1)
+		{
+			$enclosure = substr($enclosure, 0, 1);
+			$backtrace = debug_backtrace();
+			_exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+
+		}
+	
+		$out = '';
+	
+		foreach ($fields as $cell)
+		{
+			$cell = str_replace($enclosure, $enclosure.$enclosure, $cell);
+
+			if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)
+			{
+				$out .= $enclosure.$cell.$enclosure.$delimiter;
+			}
+			else
+			{
+				$out .= $cell.$delimiter;
+			}
+		}
+	
+		$length = @fwrite($handle, substr($out, 0, -1)."\n");
+	
+		return $length;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * stripos()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.stripos.php
+ *
+ * @access	public
+ * @param	string		haystack
+ * @param	string		needle
+ * @param	int			offset
+ * @return	int			numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('stripos'))
+{
+	function stripos($haystack, $needle, $offset = NULL)
+	{
+		// Cast non string scalar values
+		if (is_scalar($haystack))
+		{
+			settype($haystack, 'STRING');
+		}
+	
+		if ( ! is_string($haystack))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		if ( ! is_scalar($needle))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		if (is_float($offset))
+		{
+			$offset = (int)$offset;
+		}
+	
+		if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return NULL;
+		}
+	
+		return strpos(strtolower($haystack), strtolower($needle), $offset);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * str_ireplace()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.str-ireplace.php
+ * (parameter 4, $count, is not supported as to do so in PHP 4 would make
+ * it a required parameter)
+ *
+ * @access	public
+ * @param	mixed		search
+ * @param	mixed		replace
+ * @param	mixed		subject
+ * @return	int			numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('str_ireplace'))
+{
+	function str_ireplace($search, $replace, $subject)
+	{
+		// Nothing to do here
+		if ($search === NULL OR $subject === NULL)
+		{
+			return $subject;
+		}
+	
+		// Crazy arguments
+		if (is_scalar($search) && is_array($replace))
+		{
+			$backtrace = debug_backtrace();
+
+			if (is_object($replace))
+			{
+				show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
+			}
+			else
+			{
+				_exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
+			}
+		}
+	
+		// Searching for an array
+		if (is_array($search))
+		{
+			// Replacing with an array
+			if (is_array($replace))
+			{
+				$search = array_values($search);
+				$replace = array_values($replace);
+
+				if (count($search) >= count($replace))
+				{
+					$replace = array_pad($replace, count($search), '');
+				}
+				else
+				{
+					$replace = array_slice($replace, 0, count($search));
+				}
+			}
+			else
+			{
+				// Replacing with a string all positions
+				$replace = array_fill(0, count($search), $replace);
+			}
+		}
+		else
+		{
+			//Searching for a string and replacing with a string.
+			$search  = array((string)$search);
+			$replace = array((string)$replace);
+		}
+		
+		// Prepare the search array
+		foreach ($search as $search_key => $search_value)
+		{
+			$search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
+		}
+		
+		// Prepare the replace array (escape backreferences)
+		foreach ($replace as $k => $v)
+		{
+			$replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
+		}
+	
+		// do the replacement
+		$result = preg_replace($search, $replace, (array)$subject);
+	
+		// Check if subject was initially a string and return it as a string
+		if ( ! is_array($subject))
+		{
+			return current($result);
+		}
+	
+		// Otherwise, just return the array
+		return $result;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * http_build_query()
+ *
+ * Generate URL-encoded query string
+ * http://us.php.net/manual/en/function.http-build-query.php
+ *
+ * @access	public
+ * @param	array		form data
+ * @param	string		numeric prefix
+ * @param	string		argument separator
+ * @return	string		URL-encoded string
+ */
+if ( ! function_exists('http_build_query'))
+{
+	function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
+	{
+		// Check the data
+		if ( ! is_array($formdata) && ! is_object($formdata))
+		{
+			$backtrace = debug_backtrace();
+			_exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
+			return FALSE;
+		}
+	
+		// Cast it as array
+		if (is_object($formdata))
+		{
+			$formdata = get_object_vars($formdata);
+		}
+	
+		// If the array is empty, return NULL
+		if (empty($formdata))
+		{
+			return NULL;
+		}
+	
+		// Argument separator
+		if ($separator === NULL)
+		{
+			$separator = ini_get('arg_separator.output');
+
+			if (strlen($separator) == 0)
+			{
+				$separator = '&';
+			}
+		}
+	
+		// Start building the query
+		$tmp = array();
+
+		foreach ($formdata as $key => $val)
+		{
+			if ($val === NULL)
+			{
+				continue;
+			}
+	
+			if (is_integer($key) && $numeric_prefix != NULL)
+			{
+				$key = $numeric_prefix.$key;
+			}
+	
+			if (is_resource($val))
+			{
+				return NULL;
+			}
+			
+			// hand it off to a recursive parser
+			$tmp[] = _http_build_query_helper($key, $val, $separator);
+		}
+	
+		return implode($separator, $tmp);
+	}
+	
+	
+	// Helper helper.  Remind anyone of college?
+	// Required to handle recursion in nested arrays.
+	// 
+	// You could shave fractions of fractions of a second by moving where
+	// the urlencoding takes place, but it's much less intuitive, and if
+	// your application has 10,000 form fields, well, you have other problems ;)
+	function _http_build_query_helper($key, $val, $separator = '&')
+	{	
+		if (is_scalar($val))
+		{
+			return urlencode($key).'='.urlencode($val);			
+		}
+		else
+		{
+			// arrays please
+			if (is_object($val))
+			{
+				$val = get_object_vars($val);
+			}
+			
+			foreach ($val as $k => $v)
+			{
+				$tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
+			}
+		}
+			
+		return implode($separator, $tmp);
+	}
+}
+
+
+/* End of file compatibility_helper.php */
 /* Location: ./system/helpers/compatibility_helper.php */
\ No newline at end of file
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 61561b7..d906882 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -1,136 +1,136 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Cookie Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/cookie_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Set cookie

- *

- * Accepts six parameter, or you can submit an associative

- * array in the first parameter containing all the values.

- *

- * @access	public

- * @param	mixed

- * @param	string	the value of the cookie

- * @param	string	the number of seconds until expiration

- * @param	string	the cookie domain.  Usually:  .yourdomain.com

- * @param	string	the cookie path

- * @param	string	the cookie prefix

- * @return	void

- */

-if ( ! function_exists('set_cookie'))

-{

-	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')

-	{

-		if (is_array($name))

-		{		

-			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'name') as $item)

-			{

-				if (isset($name[$item]))

-				{

-					$$item = $name[$item];

-				}

-			}

-		}

-	

-		// Set the config file options

-		$CI =& get_instance();

-	

-		if ($prefix == '' AND $CI->config->item('cookie_prefix') != '')

-		{

-			$prefix = $CI->config->item('cookie_prefix');

-		}

-		if ($domain == '' AND $CI->config->item('cookie_domain') != '')

-		{

-			$domain = $CI->config->item('cookie_domain');

-		}

-		if ($path == '/' AND $CI->config->item('cookie_path') != '/')

-		{

-			$path = $CI->config->item('cookie_path');

-		}

-		

-		if ( ! is_numeric($expire))

-		{

-			$expire = time() - 86500;

-		}

-		else

-		{

-			if ($expire > 0)

-			{

-				$expire = time() + $expire;

-			}

-			else

-			{

-				$expire = 0;

-			}

-		}

-	

-		setcookie($prefix.$name, $value, $expire, $path, $domain, 0);

-	}

-}

-	

-// --------------------------------------------------------------------

-

-/**

- * Fetch an item from the COOKIE array

- *

- * @access	public

- * @param	string

- * @param	bool

- * @return	mixed

- */

-if ( ! function_exists('get_cookie'))

-{

-	function get_cookie($index = '', $xss_clean = FALSE)

-	{

-		$CI =& get_instance();

-		return $CI->input->cookie($index, $xss_clean);

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Delete a COOKIE

- *

- * @param	mixed

- * @param	string	the cookie domain.  Usually:  .yourdomain.com

- * @param	string	the cookie path

- * @param	string	the cookie prefix

- * @return	void

- */

-if ( ! function_exists('delete_cookie'))

-{

-	function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')

-	{

-		set_cookie($name, '', '', $domain, $path, $prefix);

-	}

-}

-

-

-/* End of file cookie_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Cookie Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set cookie
+ *
+ * Accepts six parameter, or you can submit an associative
+ * array in the first parameter containing all the values.
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string	the value of the cookie
+ * @param	string	the number of seconds until expiration
+ * @param	string	the cookie domain.  Usually:  .yourdomain.com
+ * @param	string	the cookie path
+ * @param	string	the cookie prefix
+ * @return	void
+ */
+if ( ! function_exists('set_cookie'))
+{
+	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')
+	{
+		if (is_array($name))
+		{		
+			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'name') as $item)
+			{
+				if (isset($name[$item]))
+				{
+					$$item = $name[$item];
+				}
+			}
+		}
+	
+		// Set the config file options
+		$CI =& get_instance();
+	
+		if ($prefix == '' AND $CI->config->item('cookie_prefix') != '')
+		{
+			$prefix = $CI->config->item('cookie_prefix');
+		}
+		if ($domain == '' AND $CI->config->item('cookie_domain') != '')
+		{
+			$domain = $CI->config->item('cookie_domain');
+		}
+		if ($path == '/' AND $CI->config->item('cookie_path') != '/')
+		{
+			$path = $CI->config->item('cookie_path');
+		}
+		
+		if ( ! is_numeric($expire))
+		{
+			$expire = time() - 86500;
+		}
+		else
+		{
+			if ($expire > 0)
+			{
+				$expire = time() + $expire;
+			}
+			else
+			{
+				$expire = 0;
+			}
+		}
+	
+		setcookie($prefix.$name, $value, $expire, $path, $domain, 0);
+	}
+}
+	
+// --------------------------------------------------------------------
+
+/**
+ * Fetch an item from the COOKIE array
+ *
+ * @access	public
+ * @param	string
+ * @param	bool
+ * @return	mixed
+ */
+if ( ! function_exists('get_cookie'))
+{
+	function get_cookie($index = '', $xss_clean = FALSE)
+	{
+		$CI =& get_instance();
+		return $CI->input->cookie($index, $xss_clean);
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Delete a COOKIE
+ *
+ * @param	mixed
+ * @param	string	the cookie domain.  Usually:  .yourdomain.com
+ * @param	string	the cookie path
+ * @param	string	the cookie prefix
+ * @return	void
+ */
+if ( ! function_exists('delete_cookie'))
+{
+	function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')
+	{
+		set_cookie($name, '', '', $domain, $path, $prefix);
+	}
+}
+
+
+/* End of file cookie_helper.php */
 /* Location: ./system/helpers/cookie_helper.php */
\ No newline at end of file
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index c9c8968..dbd7e0e 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -1,611 +1,611 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Date Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/date_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Get "now" time

- *

- * Returns time() or its GMT equivalent based on the config file preference

- *

- * @access	public

- * @return	integer

- */	

-if ( ! function_exists('now'))

-{

-	function now()

-	{

-		$CI =& get_instance();

-	

-		if (strtolower($CI->config->item('time_reference')) == 'gmt')

-		{

-			$now = time();

-			$system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));

-	

-			if (strlen($system_time) < 10)

-			{

-				$system_time = time();

-				log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.');

-			}

-	

-			return $system_time;

-		}

-		else

-		{

-			return time();

-		}

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Convert MySQL Style Datecodes

- *

- * This function is identical to PHPs date() function,

- * except that it allows date codes to be formatted using

- * the MySQL style, where each code letter is preceded

- * with a percent sign:  %Y %m %d etc...

- *

- * The benefit of doing dates this way is that you don't

- * have to worry about escaping your text letters that

- * match the date codes.

- *

- * @access	public

- * @param	string

- * @param	integer

- * @return	integer

- */	

-if ( ! function_exists('mdate'))

-{

-	function mdate($datestr = '', $time = '')

-	{

-		if ($datestr == '')

-			return '';

-	

-		if ($time == '')

-			$time = now();

-		

-		$datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));

-		return date($datestr, $time);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Standard Date

- *

- * Returns a date formatted according to the submitted standard.

- *

- * @access	public

- * @param	string	the chosen format

- * @param	integer	Unix timestamp

- * @return	string

- */	

-if ( ! function_exists('standard_date'))

-{

-	function standard_date($fmt = 'DATE_RFC822', $time = '')

-	{

-		$formats = array(

-						'DATE_ATOM'		=>	'%Y-%m-%dT%H:%i:%s%Q',

-						'DATE_COOKIE'	=>	'%l, %d-%M-%y %H:%i:%s UTC',

-						'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:%m:%i UTC',

-						'DATE_RFC1036'	=>	'%D, %d %M %y %H:%i:%s %O',

-						'DATE_RFC1123'	=>	'%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'

-						);

-

-		if ( ! isset($formats[$fmt]))

-		{

-			return FALSE;

-		}

-	

-		return mdate($formats[$fmt], $time);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Timespan

- *

- * Returns a span of seconds in this format:

- *	10 days 14 hours 36 minutes 47 seconds

- *

- * @access	public

- * @param	integer	a number of seconds

- * @param	integer	Unix timestamp

- * @return	integer

- */	

-if ( ! function_exists('timespan'))

-{

-	function timespan($seconds = 1, $time = '')

-	{

-		$CI =& get_instance();

-		$CI->lang->load('date');

-

-		if ( ! is_numeric($seconds))

-		{

-			$seconds = 1;

-		}

-	

-		if ( ! is_numeric($time))

-		{

-			$time = time();

-		}

-	

-		if ($time <= $seconds)

-		{

-			$seconds = 1;

-		}

-		else

-		{

-			$seconds = $time - $seconds;

-		}

-		

-		$str = '';

-		$years = floor($seconds / 31536000);

-	

-		if ($years > 0)

-		{	

-			$str .= $years.' '.$CI->lang->line((($years	> 1) ? 'date_years' : 'date_year')).', ';

-		}	

-	

-		$seconds -= $years * 31536000;

-		$months = floor($seconds / 2628000);

-	

-		if ($years > 0 OR $months > 0)

-		{

-			if ($months > 0)

-			{	

-				$str .= $months.' '.$CI->lang->line((($months	> 1) ? 'date_months' : 'date_month')).', ';

-			}	

-	

-			$seconds -= $months * 2628000;

-		}

-

-		$weeks = floor($seconds / 604800);

-	

-		if ($years > 0 OR $months > 0 OR $weeks > 0)

-		{

-			if ($weeks > 0)

-			{	

-				$str .= $weeks.' '.$CI->lang->line((($weeks	> 1) ? 'date_weeks' : 'date_week')).', ';

-			}

-		

-			$seconds -= $weeks * 604800;

-		}			

-

-		$days = floor($seconds / 86400);

-	

-		if ($months > 0 OR $weeks > 0 OR $days > 0)

-		{

-			if ($days > 0)

-			{	

-				$str .= $days.' '.$CI->lang->line((($days	> 1) ? 'date_days' : 'date_day')).', ';

-			}

-	

-			$seconds -= $days * 86400;

-		}

-	

-		$hours = floor($seconds / 3600);

-	

-		if ($days > 0 OR $hours > 0)

-		{

-			if ($hours > 0)

-			{

-				$str .= $hours.' '.$CI->lang->line((($hours	> 1) ? 'date_hours' : 'date_hour')).', ';

-			}

-		

-			$seconds -= $hours * 3600;

-		}

-	

-		$minutes = floor($seconds / 60);

-	

-		if ($days > 0 OR $hours > 0 OR $minutes > 0)

-		{

-			if ($minutes > 0)

-			{	

-				$str .= $minutes.' '.$CI->lang->line((($minutes	> 1) ? 'date_minutes' : 'date_minute')).', ';

-			}

-		

-			$seconds -= $minutes * 60;

-		}

-	

-		if ($str == '')

-		{

-			$str .= $seconds.' '.$CI->lang->line((($seconds	> 1) ? 'date_seconds' : 'date_second')).', ';

-		}

-			

-		return substr(trim($str), 0, -1);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Number of days in a month

- *

- * Takes a month/year as input and returns the number of days

- * for the given month/year. Takes leap years into consideration.

- *

- * @access	public

- * @param	integer a numeric month

- * @param	integer	a numeric year

- * @return	integer

- */	

-if ( ! function_exists('days_in_month'))

-{

-	function days_in_month($month = 0, $year = '')

-	{

-		if ($month < 1 OR $month > 12)

-		{

-			return 0;

-		}

-	

-		if ( ! is_numeric($year) OR strlen($year) != 4)

-		{

-			$year = date('Y');

-		}

-	

-		if ($month == 2)

-		{

-			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))

-			{

-				return 29;

-			}

-		}

-

-		$days_in_month	= array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

-		return $days_in_month[$month - 1];

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Converts a local Unix timestamp to GMT

- *

- * @access	public

- * @param	integer Unix timestamp

- * @return	integer

- */	

-if ( ! function_exists('local_to_gmt'))

-{

-	function local_to_gmt($time = '')

-	{

-		if ($time == '')

-			$time = time();

-	

-		return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time));

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Converts GMT time to a localized value

- *

- * Takes a Unix timestamp (in GMT) as input, and returns

- * at the local value based on the timezone and DST setting

- * submitted

- *

- * @access	public

- * @param	integer Unix timestamp

- * @param	string	timezone

- * @param	bool	whether DST is active

- * @return	integer

- */	

-if ( ! function_exists('gmt_to_local'))

-{

-	function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)

-	{			

-		if ($time == '')

-		{

-			return now();

-		}

-	

-		$time += timezones($timezone) * 3600;

-

-		if ($dst == TRUE)

-		{

-			$time += 3600;

-		}

-	

-		return $time;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Converts a MySQL Timestamp to Unix

- *

- * @access	public

- * @param	integer Unix timestamp

- * @return	integer

- */	

-if ( ! function_exists('mysql_to_unix'))

-{

-	function mysql_to_unix($time = '')

-	{

-		// We'll remove certain characters for backward compatibility

-		// since the formatting changed with MySQL 4.1

-		// YYYY-MM-DD HH:MM:SS

-	

-		$time = str_replace('-', '', $time);

-		$time = str_replace(':', '', $time);

-		$time = str_replace(' ', '', $time);

-	

-		// YYYYMMDDHHMMSS

-		return  mktime(

-						substr($time, 8, 2),

-						substr($time, 10, 2),

-						substr($time, 12, 2),

-						substr($time, 4, 2),

-						substr($time, 6, 2),

-						substr($time, 0, 4)

-						);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Unix to "Human"

- *

- * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM

- *

- * @access	public

- * @param	integer Unix timestamp

- * @param	bool	whether to show seconds

- * @param	string	format: us or euro

- * @return	string

- */	

-if ( ! function_exists('unix_to_human'))

-{

-	function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')

-	{

-		$r  = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';

-		

-		if ($fmt == 'us')

-		{

-			$r .= date('h', $time).':'.date('i', $time);

-		}

-		else

-		{

-			$r .= date('H', $time).':'.date('i', $time);

-		}

-	

-		if ($seconds)

-		{

-			$r .= ':'.date('s', $time);

-		}

-	

-		if ($fmt == 'us')

-		{

-			$r .= ' '.date('A', $time);

-		}

-		

-		return $r;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Convert "human" date to GMT

- *

- * Reverses the above process

- *

- * @access	public

- * @param	string	format: us or euro

- * @return	integer

- */	

-if ( ! function_exists('human_to_unix'))

-{

-	function human_to_unix($datestr = '')

-	{

-		if ($datestr == '')

-		{

-			return FALSE;

-		}

-	

-		$datestr = trim($datestr);

-		$datestr = preg_replace("/\040+/", "\040", $datestr);

-

-		if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))

-		{

-			return FALSE;

-		}

-

-		$split = preg_split("/\040/", $datestr);

-

-		$ex = explode("-", $split['0']);

-	

-		$year  = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];

-		$month = (strlen($ex['1']) == 1) ? '0'.$ex['1']  : $ex['1'];

-		$day   = (strlen($ex['2']) == 1) ? '0'.$ex['2']  : $ex['2'];

-

-		$ex = explode(":", $split['1']);

-	

-		$hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];

-		$min  = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];

-

-		if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2']))

-		{

-			$sec  = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];

-		}

-		else

-		{

-			// Unless specified, seconds get set to zero.

-			$sec = '00';

-		}

-	

-		if (isset($split['2']))

-		{

-			$ampm = strtolower($split['2']);

-		

-			if (substr($ampm, 0, 1) == 'p' AND $hour < 12)

-				$hour = $hour + 12;

-			

-			if (substr($ampm, 0, 1) == 'a' AND $hour == 12)

-				$hour =  '00';

-			

-			if (strlen($hour) == 1)

-				$hour = '0'.$hour;

-		}

-			

-		return mktime($hour, $min, $sec, $month, $day, $year);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Timezone Menu

- *

- * Generates a drop-down menu of timezones.

- *

- * @access	public

- * @param	string	timezone

- * @param	string	classname

- * @param	string	menu name

- * @return	string

- */	

-if ( ! function_exists('timezone_menu'))

-{

-	function timezone_menu($default = 'UTC', $class = "", $name = 'timezones')

-	{

-		$CI =& get_instance();

-		$CI->lang->load('date');

-	

-		if ($default == 'GMT')

-			$default = 'UTC';

-

-		$menu = '<select name="'.$name.'"';

-	

-		if ($class != '')

-		{

-			$menu .= ' class="'.$class.'"';

-		}

-	

-		$menu .= ">\n";

-	

-		foreach (timezones() as $key => $val)

-		{

-			$selected = ($default == $key) ? " selected='selected'" : '';

-			$menu .= "<option value='{$key}'{$selected}>".$CI->lang->line($key)."</option>\n";

-		}

-

-		$menu .= "</select>";

-

-		return $menu;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Timezones

- *

- * Returns an array of timezones.  This is a helper function

- * for various other ones in this library

- *

- * @access	public

- * @param	string	timezone

- * @return	string

- */	

-if ( ! function_exists('timezones'))

-{

-	function timezones($tz = '')

-	{

-		// Note: Don't change the order of these even though

-		// some items appear to be in the wrong order

-		

-		$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

-					);

-				

-		if ($tz == '')

-		{

-			return $zones;

-		}

-	

-		if ($tz == 'GMT')

-			$tz = 'UTC';

-	

-		return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];

-	}

-}

-

-

-/* End of file date_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Date Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/date_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get "now" time
+ *
+ * Returns time() or its GMT equivalent based on the config file preference
+ *
+ * @access	public
+ * @return	integer
+ */	
+if ( ! function_exists('now'))
+{
+	function now()
+	{
+		$CI =& get_instance();
+	
+		if (strtolower($CI->config->item('time_reference')) == 'gmt')
+		{
+			$now = time();
+			$system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
+	
+			if (strlen($system_time) < 10)
+			{
+				$system_time = time();
+				log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.');
+			}
+	
+			return $system_time;
+		}
+		else
+		{
+			return time();
+		}
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Convert MySQL Style Datecodes
+ *
+ * This function is identical to PHPs date() function,
+ * except that it allows date codes to be formatted using
+ * the MySQL style, where each code letter is preceded
+ * with a percent sign:  %Y %m %d etc...
+ *
+ * The benefit of doing dates this way is that you don't
+ * have to worry about escaping your text letters that
+ * match the date codes.
+ *
+ * @access	public
+ * @param	string
+ * @param	integer
+ * @return	integer
+ */	
+if ( ! function_exists('mdate'))
+{
+	function mdate($datestr = '', $time = '')
+	{
+		if ($datestr == '')
+			return '';
+	
+		if ($time == '')
+			$time = now();
+		
+		$datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));
+		return date($datestr, $time);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Standard Date
+ *
+ * Returns a date formatted according to the submitted standard.
+ *
+ * @access	public
+ * @param	string	the chosen format
+ * @param	integer	Unix timestamp
+ * @return	string
+ */	
+if ( ! function_exists('standard_date'))
+{
+	function standard_date($fmt = 'DATE_RFC822', $time = '')
+	{
+		$formats = array(
+						'DATE_ATOM'		=>	'%Y-%m-%dT%H:%i:%s%Q',
+						'DATE_COOKIE'	=>	'%l, %d-%M-%y %H:%i:%s UTC',
+						'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:%m:%i UTC',
+						'DATE_RFC1036'	=>	'%D, %d %M %y %H:%i:%s %O',
+						'DATE_RFC1123'	=>	'%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'
+						);
+
+		if ( ! isset($formats[$fmt]))
+		{
+			return FALSE;
+		}
+	
+		return mdate($formats[$fmt], $time);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Timespan
+ *
+ * Returns a span of seconds in this format:
+ *	10 days 14 hours 36 minutes 47 seconds
+ *
+ * @access	public
+ * @param	integer	a number of seconds
+ * @param	integer	Unix timestamp
+ * @return	integer
+ */	
+if ( ! function_exists('timespan'))
+{
+	function timespan($seconds = 1, $time = '')
+	{
+		$CI =& get_instance();
+		$CI->lang->load('date');
+
+		if ( ! is_numeric($seconds))
+		{
+			$seconds = 1;
+		}
+	
+		if ( ! is_numeric($time))
+		{
+			$time = time();
+		}
+	
+		if ($time <= $seconds)
+		{
+			$seconds = 1;
+		}
+		else
+		{
+			$seconds = $time - $seconds;
+		}
+		
+		$str = '';
+		$years = floor($seconds / 31536000);
+	
+		if ($years > 0)
+		{	
+			$str .= $years.' '.$CI->lang->line((($years	> 1) ? 'date_years' : 'date_year')).', ';
+		}	
+	
+		$seconds -= $years * 31536000;
+		$months = floor($seconds / 2628000);
+	
+		if ($years > 0 OR $months > 0)
+		{
+			if ($months > 0)
+			{	
+				$str .= $months.' '.$CI->lang->line((($months	> 1) ? 'date_months' : 'date_month')).', ';
+			}	
+	
+			$seconds -= $months * 2628000;
+		}
+
+		$weeks = floor($seconds / 604800);
+	
+		if ($years > 0 OR $months > 0 OR $weeks > 0)
+		{
+			if ($weeks > 0)
+			{	
+				$str .= $weeks.' '.$CI->lang->line((($weeks	> 1) ? 'date_weeks' : 'date_week')).', ';
+			}
+		
+			$seconds -= $weeks * 604800;
+		}			
+
+		$days = floor($seconds / 86400);
+	
+		if ($months > 0 OR $weeks > 0 OR $days > 0)
+		{
+			if ($days > 0)
+			{	
+				$str .= $days.' '.$CI->lang->line((($days	> 1) ? 'date_days' : 'date_day')).', ';
+			}
+	
+			$seconds -= $days * 86400;
+		}
+	
+		$hours = floor($seconds / 3600);
+	
+		if ($days > 0 OR $hours > 0)
+		{
+			if ($hours > 0)
+			{
+				$str .= $hours.' '.$CI->lang->line((($hours	> 1) ? 'date_hours' : 'date_hour')).', ';
+			}
+		
+			$seconds -= $hours * 3600;
+		}
+	
+		$minutes = floor($seconds / 60);
+	
+		if ($days > 0 OR $hours > 0 OR $minutes > 0)
+		{
+			if ($minutes > 0)
+			{	
+				$str .= $minutes.' '.$CI->lang->line((($minutes	> 1) ? 'date_minutes' : 'date_minute')).', ';
+			}
+		
+			$seconds -= $minutes * 60;
+		}
+	
+		if ($str == '')
+		{
+			$str .= $seconds.' '.$CI->lang->line((($seconds	> 1) ? 'date_seconds' : 'date_second')).', ';
+		}
+			
+		return substr(trim($str), 0, -1);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Number of days in a month
+ *
+ * Takes a month/year as input and returns the number of days
+ * for the given month/year. Takes leap years into consideration.
+ *
+ * @access	public
+ * @param	integer a numeric month
+ * @param	integer	a numeric year
+ * @return	integer
+ */	
+if ( ! function_exists('days_in_month'))
+{
+	function days_in_month($month = 0, $year = '')
+	{
+		if ($month < 1 OR $month > 12)
+		{
+			return 0;
+		}
+	
+		if ( ! is_numeric($year) OR strlen($year) != 4)
+		{
+			$year = date('Y');
+		}
+	
+		if ($month == 2)
+		{
+			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
+			{
+				return 29;
+			}
+		}
+
+		$days_in_month	= array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+		return $days_in_month[$month - 1];
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Converts a local Unix timestamp to GMT
+ *
+ * @access	public
+ * @param	integer Unix timestamp
+ * @return	integer
+ */	
+if ( ! function_exists('local_to_gmt'))
+{
+	function local_to_gmt($time = '')
+	{
+		if ($time == '')
+			$time = time();
+	
+		return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time));
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Converts GMT time to a localized value
+ *
+ * Takes a Unix timestamp (in GMT) as input, and returns
+ * at the local value based on the timezone and DST setting
+ * submitted
+ *
+ * @access	public
+ * @param	integer Unix timestamp
+ * @param	string	timezone
+ * @param	bool	whether DST is active
+ * @return	integer
+ */	
+if ( ! function_exists('gmt_to_local'))
+{
+	function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)
+	{			
+		if ($time == '')
+		{
+			return now();
+		}
+	
+		$time += timezones($timezone) * 3600;
+
+		if ($dst == TRUE)
+		{
+			$time += 3600;
+		}
+	
+		return $time;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Converts a MySQL Timestamp to Unix
+ *
+ * @access	public
+ * @param	integer Unix timestamp
+ * @return	integer
+ */	
+if ( ! function_exists('mysql_to_unix'))
+{
+	function mysql_to_unix($time = '')
+	{
+		// We'll remove certain characters for backward compatibility
+		// since the formatting changed with MySQL 4.1
+		// YYYY-MM-DD HH:MM:SS
+	
+		$time = str_replace('-', '', $time);
+		$time = str_replace(':', '', $time);
+		$time = str_replace(' ', '', $time);
+	
+		// YYYYMMDDHHMMSS
+		return  mktime(
+						substr($time, 8, 2),
+						substr($time, 10, 2),
+						substr($time, 12, 2),
+						substr($time, 4, 2),
+						substr($time, 6, 2),
+						substr($time, 0, 4)
+						);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Unix to "Human"
+ *
+ * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
+ *
+ * @access	public
+ * @param	integer Unix timestamp
+ * @param	bool	whether to show seconds
+ * @param	string	format: us or euro
+ * @return	string
+ */	
+if ( ! function_exists('unix_to_human'))
+{
+	function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')
+	{
+		$r  = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';
+		
+		if ($fmt == 'us')
+		{
+			$r .= date('h', $time).':'.date('i', $time);
+		}
+		else
+		{
+			$r .= date('H', $time).':'.date('i', $time);
+		}
+	
+		if ($seconds)
+		{
+			$r .= ':'.date('s', $time);
+		}
+	
+		if ($fmt == 'us')
+		{
+			$r .= ' '.date('A', $time);
+		}
+		
+		return $r;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Convert "human" date to GMT
+ *
+ * Reverses the above process
+ *
+ * @access	public
+ * @param	string	format: us or euro
+ * @return	integer
+ */	
+if ( ! function_exists('human_to_unix'))
+{
+	function human_to_unix($datestr = '')
+	{
+		if ($datestr == '')
+		{
+			return FALSE;
+		}
+	
+		$datestr = trim($datestr);
+		$datestr = preg_replace("/\040+/", "\040", $datestr);
+
+		if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))
+		{
+			return FALSE;
+		}
+
+		$split = preg_split("/\040/", $datestr);
+
+		$ex = explode("-", $split['0']);
+	
+		$year  = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];
+		$month = (strlen($ex['1']) == 1) ? '0'.$ex['1']  : $ex['1'];
+		$day   = (strlen($ex['2']) == 1) ? '0'.$ex['2']  : $ex['2'];
+
+		$ex = explode(":", $split['1']);
+	
+		$hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];
+		$min  = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
+
+		if (isset($ex['2']) AND ereg("[0-9]{1,2}", $ex['2']))
+		{
+			$sec  = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
+		}
+		else
+		{
+			// Unless specified, seconds get set to zero.
+			$sec = '00';
+		}
+	
+		if (isset($split['2']))
+		{
+			$ampm = strtolower($split['2']);
+		
+			if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
+				$hour = $hour + 12;
+			
+			if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
+				$hour =  '00';
+			
+			if (strlen($hour) == 1)
+				$hour = '0'.$hour;
+		}
+			
+		return mktime($hour, $min, $sec, $month, $day, $year);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Timezone Menu
+ *
+ * Generates a drop-down menu of timezones.
+ *
+ * @access	public
+ * @param	string	timezone
+ * @param	string	classname
+ * @param	string	menu name
+ * @return	string
+ */	
+if ( ! function_exists('timezone_menu'))
+{
+	function timezone_menu($default = 'UTC', $class = "", $name = 'timezones')
+	{
+		$CI =& get_instance();
+		$CI->lang->load('date');
+	
+		if ($default == 'GMT')
+			$default = 'UTC';
+
+		$menu = '<select name="'.$name.'"';
+	
+		if ($class != '')
+		{
+			$menu .= ' class="'.$class.'"';
+		}
+	
+		$menu .= ">\n";
+	
+		foreach (timezones() as $key => $val)
+		{
+			$selected = ($default == $key) ? " selected='selected'" : '';
+			$menu .= "<option value='{$key}'{$selected}>".$CI->lang->line($key)."</option>\n";
+		}
+
+		$menu .= "</select>";
+
+		return $menu;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Timezones
+ *
+ * Returns an array of timezones.  This is a helper function
+ * for various other ones in this library
+ *
+ * @access	public
+ * @param	string	timezone
+ * @return	string
+ */	
+if ( ! function_exists('timezones'))
+{
+	function timezones($tz = '')
+	{
+		// Note: Don't change the order of these even though
+		// some items appear to be in the wrong order
+		
+		$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
+					);
+				
+		if ($tz == '')
+		{
+			return $zones;
+		}
+	
+		if ($tz == 'GMT')
+			$tz = 'UTC';
+	
+		return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];
+	}
+}
+
+
+/* End of file date_helper.php */
 /* Location: ./system/helpers/date_helper.php */
\ No newline at end of file
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index 8a1b999..be36590 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -1,80 +1,80 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Directory Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Create a Directory Map

- *

- * Reads the specified directory and builds an array

- * representation of it.  Sub-folders contained with the

- * directory will be mapped as well.

- *

- * @access	public

- * @param	string	path to source

- * @param	bool	whether to limit the result to the top level only

- * @return	array

- */	

-if ( ! function_exists('directory_map'))

-{

-	function directory_map($source_dir, $top_level_only = FALSE)

-	{	

-		if ($fp = @opendir($source_dir))

-		{

-			$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;		

-			$filedata = array();

-			

-			while (FALSE !== ($file = readdir($fp)))

-			{

-				if (strncmp($file, '.', 1) == 0)

-				{

-					continue;

-				}

-				

-				if ($top_level_only == FALSE && @is_dir($source_dir.$file))

-				{

-					$temp_array = array();

-				

-					$temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR);

-				

-					$filedata[$file] = $temp_array;

-				}

-				else

-				{

-					$filedata[] = $file;

-				}

-			}

-			

-			closedir($fp);

-			return $filedata;

-		}

-	}

-}

-

-

-/* End of file directory_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Directory Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Directory Map
+ *
+ * Reads the specified directory and builds an array
+ * representation of it.  Sub-folders contained with the
+ * directory will be mapped as well.
+ *
+ * @access	public
+ * @param	string	path to source
+ * @param	bool	whether to limit the result to the top level only
+ * @return	array
+ */	
+if ( ! function_exists('directory_map'))
+{
+	function directory_map($source_dir, $top_level_only = FALSE)
+	{	
+		if ($fp = @opendir($source_dir))
+		{
+			$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;		
+			$filedata = array();
+			
+			while (FALSE !== ($file = readdir($fp)))
+			{
+				if (strncmp($file, '.', 1) == 0)
+				{
+					continue;
+				}
+				
+				if ($top_level_only == FALSE && @is_dir($source_dir.$file))
+				{
+					$temp_array = array();
+				
+					$temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR);
+				
+					$filedata[$file] = $temp_array;
+				}
+				else
+				{
+					$filedata[] = $file;
+				}
+			}
+			
+			closedir($fp);
+			return $filedata;
+		}
+	}
+}
+
+
+/* End of file directory_helper.php */
 /* Location: ./system/helpers/directory_helper.php */
\ No newline at end of file
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index 2a555ae..ce2dd48 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -1,100 +1,100 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Download Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/download_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Force Download

- *

- * Generates headers that force a download to happen

- *

- * @access	public

- * @param	string	filename

- * @param	mixed	the data to be downloaded

- * @return	void

- */	

-if ( ! function_exists('force_download'))

-{

-	function force_download($filename = '', $data = '')

-	{

-		if ($filename == '' OR $data == '')

-		{

-			return FALSE;

-		}

-

-		// Try to determine if the filename includes a file extension.

-		// We need it in order to set the MIME type

-		if (FALSE === strpos($filename, '.'))

-		{

-			return FALSE;

-		}

-	

-		// Grab the file extension

-		$x = explode('.', $filename);

-		$extension = end($x);

-

-		// Load the mime types

-		@include(APPPATH.'config/mimes'.EXT);

-	

-		// Set a default mime if we can't find it

-		if ( ! isset($mimes[$extension]))

-		{

-			$mime = 'application/octet-stream';

-		}

-		else

-		{

-			$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];

-		}

-	

-		// Generate the server headers

-		if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))

-		{

-			header('Content-Type: "'.$mime.'"');

-			header('Content-Disposition: attachment; filename="'.$filename.'"');

-			header('Expires: 0');

-			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

-			header("Content-Transfer-Encoding: binary");

-			header('Pragma: public');

-			header("Content-Length: ".strlen($data));

-		}

-		else

-		{

-			header('Content-Type: "'.$mime.'"');

-			header('Content-Disposition: attachment; filename="'.$filename.'"');

-			header("Content-Transfer-Encoding: binary");

-			header('Expires: 0');

-			header('Pragma: no-cache');

-			header("Content-Length: ".strlen($data));

-		}

-	

-		exit($data);

-	}

-}

-

-

-/* End of file download_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Download Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/download_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Force Download
+ *
+ * Generates headers that force a download to happen
+ *
+ * @access	public
+ * @param	string	filename
+ * @param	mixed	the data to be downloaded
+ * @return	void
+ */	
+if ( ! function_exists('force_download'))
+{
+	function force_download($filename = '', $data = '')
+	{
+		if ($filename == '' OR $data == '')
+		{
+			return FALSE;
+		}
+
+		// Try to determine if the filename includes a file extension.
+		// We need it in order to set the MIME type
+		if (FALSE === strpos($filename, '.'))
+		{
+			return FALSE;
+		}
+	
+		// Grab the file extension
+		$x = explode('.', $filename);
+		$extension = end($x);
+
+		// Load the mime types
+		@include(APPPATH.'config/mimes'.EXT);
+	
+		// Set a default mime if we can't find it
+		if ( ! isset($mimes[$extension]))
+		{
+			$mime = 'application/octet-stream';
+		}
+		else
+		{
+			$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
+		}
+	
+		// Generate the server headers
+		if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
+		{
+			header('Content-Type: "'.$mime.'"');
+			header('Content-Disposition: attachment; filename="'.$filename.'"');
+			header('Expires: 0');
+			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+			header("Content-Transfer-Encoding: binary");
+			header('Pragma: public');
+			header("Content-Length: ".strlen($data));
+		}
+		else
+		{
+			header('Content-Type: "'.$mime.'"');
+			header('Content-Disposition: attachment; filename="'.$filename.'"');
+			header("Content-Transfer-Encoding: binary");
+			header('Expires: 0');
+			header('Pragma: no-cache');
+			header("Content-Length: ".strlen($data));
+		}
+	
+		exit($data);
+	}
+}
+
+
+/* End of file download_helper.php */
 /* Location: ./system/helpers/download_helper.php */
\ No newline at end of file
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index ab12b70..af1fdb9 100644
--- a/system/helpers/email_helper.php
+++ b/system/helpers/email_helper.php
@@ -1,62 +1,62 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Email Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/email_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Validate email address

- *

- * @access	public

- * @return	bool

- */	

-if ( ! function_exists('valid_email'))

-{

-	function valid_email($address)

-	{

-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Send an email

- *

- * @access	public

- * @return	bool

- */	

-if ( ! function_exists('send_email'))

-{

-	function send_email($recipient, $subject = 'Test email', $message = 'Hello World')

-	{

-		return mail($recipient, $subject, $message);

-	}

-}

-

-

-/* End of file email_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Email Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/email_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validate email address
+ *
+ * @access	public
+ * @return	bool
+ */	
+if ( ! function_exists('valid_email'))
+{
+	function valid_email($address)
+	{
+		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Send an email
+ *
+ * @access	public
+ * @return	bool
+ */	
+if ( ! function_exists('send_email'))
+{
+	function send_email($recipient, $subject = 'Test email', $message = 'Hello World')
+	{
+		return mail($recipient, $subject, $message);
+	}
+}
+
+
+/* End of file email_helper.php */
 /* Location: ./system/helpers/email_helper.php */
\ No newline at end of file
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 6378784..8078d96 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -1,465 +1,465 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter File Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/file_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Read File

- *

- * Opens the file specfied in the path and returns it as a string.

- *

- * @access	public

- * @param	string	path to file

- * @return	string

- */	

-if ( ! function_exists('read_file'))

-{

-	function read_file($file)

-	{

-		if ( ! file_exists($file))

-		{

-			return FALSE;

-		}

-	

-		if (function_exists('file_get_contents'))

-		{

-			return file_get_contents($file);		

-		}

-

-		if ( ! $fp = @fopen($file, FOPEN_READ))

-		{

-			return FALSE;

-		}

-		

-		flock($fp, LOCK_SH);

-	

-		$data = '';

-		if (filesize($file) > 0)

-		{

-			$data =& fread($fp, filesize($file));

-		}

-

-		flock($fp, LOCK_UN);

-		fclose($fp);

-

-		return $data;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Write File

- *

- * Writes data to the file specified in the path.

- * Creates a new file if non-existent.

- *

- * @access	public

- * @param	string	path to file

- * @param	string	file data

- * @return	bool

- */	

-if ( ! function_exists('write_file'))

-{

-	function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)

-	{

-		if ( ! $fp = @fopen($path, $mode))

-		{

-			return FALSE;

-		}

-		

-		flock($fp, LOCK_EX);

-		fwrite($fp, $data);

-		flock($fp, LOCK_UN);

-		fclose($fp);	

-

-		return TRUE;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Delete Files

- *

- * Deletes all files contained in the supplied directory path.

- * Files must be writable or owned by the system in order to be deleted.

- * If the second parameter is set to TRUE, any directories contained

- * within the supplied base directory will be nuked as well.

- *

- * @access	public

- * @param	string	path to file

- * @param	bool	whether to delete any directories found in the path

- * @return	bool

- */	

-if ( ! function_exists('delete_files'))

-{

-	function delete_files($path, $del_dir = FALSE, $level = 0)

-	{	

-		// Trim the trailing slash

-		$path = preg_replace("|^(.+?)/*$|", "\\1", $path);

-		

-		if ( ! $current_dir = @opendir($path))

-			return;

-	

-		while(FALSE !== ($filename = @readdir($current_dir)))

-		{

-			if ($filename != "." and $filename != "..")

-			{

-				if (is_dir($path.'/'.$filename))

-				{

-					// Ignore empty folders

-					if (substr($filename, 0, 1) != '.')

-					{

-						delete_files($path.'/'.$filename, $del_dir, $level + 1);

-					}

-				}

-				else

-				{

-					unlink($path.'/'.$filename);

-				}

-			}

-		}

-		@closedir($current_dir);

-	

-		if ($del_dir == TRUE AND $level > 0)

-		{

-			@rmdir($path);

-		}

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Get Filenames

- *

- * Reads the specified directory and builds an array containing the filenames.  

- * Any sub-folders contained within the specified path are read as well.

- *

- * @access	public

- * @param	string	path to source

- * @param	bool	whether to include the path as part of the filename

- * @param	bool	internal variable to determine recursion status - do not use in calls

- * @return	array

- */	

-if ( ! function_exists('get_filenames'))

-{

-	function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)

-	{

-		static $_filedata = array();

-				

-		if ($fp = @opendir($source_dir))

-		{

-			// reset the array and make sure $source_dir has a trailing slash on the initial call

-			if ($_recursion === FALSE)

-			{

-				$_filedata = array();

-				$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;

-			}

-			

-			while (FALSE !== ($file = readdir($fp)))

-			{

-				if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)

-				{

-					 get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);

-				}

-				elseif (strncmp($file, '.', 1) !== 0)

-				{

-			

-					$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;

-				}

-			}

-			return $_filedata;

-		}

-		else

-		{

-			return FALSE;

-		}

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Get Directory File Information

- *

- * Reads the specified directory and builds an array containing the filenames,  

- * filesize, dates, and permissions

- *

- * Any sub-folders contained within the specified path are read as well.

- *

- * @access	public

- * @param	string	path to source

- * @param	bool	whether to include the path as part of the filename

- * @param	bool	internal variable to determine recursion status - do not use in calls

- * @return	array

- */	

-if ( ! function_exists('get_dir_file_info'))

-{

-	function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE)

-	{

-		$_filedata = array();

-		$relative_path = $source_dir;

-				

-		if ($fp = @opendir($source_dir))

-		{

-			// reset the array and make sure $source_dir has a trailing slash on the initial call

-			if ($_recursion === FALSE)

-			{

-				$_filedata = array();

-				$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;

-			}

-

-			while (FALSE !== ($file = readdir($fp)))

-			{

-				if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)

-				{

-					 get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);

-				}

-				elseif (strncmp($file, '.', 1) !== 0)

-				{

-					$_filedata[$file] = get_file_info($source_dir.$file);

-					$_filedata[$file]['relative_path'] = $relative_path;

-				}

-			}

-			return $_filedata;

-		}

-		else

-		{

-			return FALSE;

-		}

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

-* Get File Info

-*

-* Given a file and path, returns the name, path, size, date modified

-* Second parameter allows you to explicitly declare what information you want returned

-* Options are: name, server_path, size, date, readable, writable, executable, fileperms

-* Returns FALSE if the file cannot be found.

-*

-* @access	public

-* @param	string		path to file

-* @param	mixed		array or comma separated string of information returned

-* @return	array

-*/

-if ( ! function_exists('get_file_info'))

-{

-	function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))

-	{

-

-		if ( ! file_exists($file))

-		{

-			return FALSE;

-		}

-

-		if (is_string($returned_values))

-		{

-			$returned_values = explode(',', $returned_values);

-		}

-

-		foreach ($returned_values as $key)

-		{

-			switch ($key)

-			{

-				case 'name':

-					$fileinfo['name'] = substr(strrchr($file, '/'), 1);

-					break;

-				case 'server_path':

-					$fileinfo['server_path'] = $file;

-					break;

-				case 'size':

-					$fileinfo['size'] = filesize($file);

-					break;

-				case 'date':

-					$fileinfo['date'] = filectime($file);

-					break;

-				case 'readable':

-					$fileinfo['readable'] = is_readable($file);

-					break;

-				case 'writable':

-					// There are known problems using is_weritable on IIS.  It may not be reliable - consider fileperms()

-					$fileinfo['writable'] = is_writable($file);

-					break;

-				case 'executable':

-					$fileinfo['executable'] = is_executable($file);

-					break;

-				case 'fileperms':

-					$fileinfo['fileperms'] = fileperms($file);

-					break;

-			}

-		}

-

-		return $fileinfo;

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Get Mime by Extension

- *

- * Translates a file extension into a mime type based on config/mimes.php. 

- * Returns FALSE if it can't determine the type, or open the mime config file

- *

- * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience

- * It should NOT be trusted, and should certainly NOT be used for security

- *

- * @access	public

- * @param	string	path to file

- * @return	mixed

- */	

-if ( ! function_exists('get_mime_by_extension'))

-{

-	function get_mime_by_extension($file)

-	{

-		$extension = substr(strrchr($file, '.'), 1);

-	

-		global $mimes;

-	

-		if ( ! is_array($mimes))

-		{

-			if ( ! require_once(APPPATH.'config/mimes.php'))

-			{

-				return FALSE;

-			}

-		}

-

-		if (array_key_exists($extension, $mimes))

-		{

-			if (is_array($mimes[$extension]))

-			{

-				// Multiple mime types, just give the first one

-				return current($mimes[$extension]);

-			}

-			else

-			{

-				return $mimes[$extension];

-			}

-		}

-		else

-		{

-			return FALSE;

-		}

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Symbolic Permissions

- *

- * Takes a numeric value representing a file's permissions and returns

- * standard symbolic notation representing that value

- *

- * @access	public

- * @param	int

- * @return	string

- */	

-if ( ! function_exists('symbolic_permissions'))

-{

-	function symbolic_permissions($perms)

-	{	

-		if (($perms & 0xC000) == 0xC000)

-		{

-			$symbolic = 's'; // Socket

-		}

-		elseif (($perms & 0xA000) == 0xA000)

-		{

-			$symbolic = 'l'; // Symbolic Link

-		}

-		elseif (($perms & 0x8000) == 0x8000)

-		{

-			$symbolic = '-'; // Regular

-		}

-		elseif (($perms & 0x6000) == 0x6000)

-		{

-			$symbolic = 'b'; // Block special

-		}

-		elseif (($perms & 0x4000) == 0x4000)

-		{

-			$symbolic = 'd'; // Directory

-		}

-		elseif (($perms & 0x2000) == 0x2000)

-		{

-			$symbolic = 'c'; // Character special

-		}

-		elseif (($perms & 0x1000) == 0x1000)

-		{

-			$symbolic = 'p'; // FIFO pipe

-		}

-		else

-		{

-			$symbolic = 'u'; // Unknown

-		}

-

-		// Owner

-		$symbolic .= (($perms & 0x0100) ? 'r' : '-');

-		$symbolic .= (($perms & 0x0080) ? 'w' : '-');

-		$symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));

-

-		// Group

-		$symbolic .= (($perms & 0x0020) ? 'r' : '-');

-		$symbolic .= (($perms & 0x0010) ? 'w' : '-');

-		$symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));

-

-		// World

-		$symbolic .= (($perms & 0x0004) ? 'r' : '-');

-		$symbolic .= (($perms & 0x0002) ? 'w' : '-');

-		$symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));

-

-		return $symbolic;		

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Octal Permissions

- *

- * Takes a numeric value representing a file's permissions and returns

- * a three character string representing the file's octal permissions

- *

- * @access	public

- * @param	int

- * @return	string

- */	

-if ( ! function_exists('octal_permissions'))

-{

-	function octal_permissions($perms)

-	{

-		return substr(sprintf('%o', $perms), -3);

-	}

-}

-

-

-/* End of file file_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter File Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/file_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Read File
+ *
+ * Opens the file specfied in the path and returns it as a string.
+ *
+ * @access	public
+ * @param	string	path to file
+ * @return	string
+ */	
+if ( ! function_exists('read_file'))
+{
+	function read_file($file)
+	{
+		if ( ! file_exists($file))
+		{
+			return FALSE;
+		}
+	
+		if (function_exists('file_get_contents'))
+		{
+			return file_get_contents($file);		
+		}
+
+		if ( ! $fp = @fopen($file, FOPEN_READ))
+		{
+			return FALSE;
+		}
+		
+		flock($fp, LOCK_SH);
+	
+		$data = '';
+		if (filesize($file) > 0)
+		{
+			$data =& fread($fp, filesize($file));
+		}
+
+		flock($fp, LOCK_UN);
+		fclose($fp);
+
+		return $data;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Write File
+ *
+ * Writes data to the file specified in the path.
+ * Creates a new file if non-existent.
+ *
+ * @access	public
+ * @param	string	path to file
+ * @param	string	file data
+ * @return	bool
+ */	
+if ( ! function_exists('write_file'))
+{
+	function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)
+	{
+		if ( ! $fp = @fopen($path, $mode))
+		{
+			return FALSE;
+		}
+		
+		flock($fp, LOCK_EX);
+		fwrite($fp, $data);
+		flock($fp, LOCK_UN);
+		fclose($fp);	
+
+		return TRUE;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Delete Files
+ *
+ * Deletes all files contained in the supplied directory path.
+ * Files must be writable or owned by the system in order to be deleted.
+ * If the second parameter is set to TRUE, any directories contained
+ * within the supplied base directory will be nuked as well.
+ *
+ * @access	public
+ * @param	string	path to file
+ * @param	bool	whether to delete any directories found in the path
+ * @return	bool
+ */	
+if ( ! function_exists('delete_files'))
+{
+	function delete_files($path, $del_dir = FALSE, $level = 0)
+	{	
+		// Trim the trailing slash
+		$path = preg_replace("|^(.+?)/*$|", "\\1", $path);
+		
+		if ( ! $current_dir = @opendir($path))
+			return;
+	
+		while(FALSE !== ($filename = @readdir($current_dir)))
+		{
+			if ($filename != "." and $filename != "..")
+			{
+				if (is_dir($path.'/'.$filename))
+				{
+					// Ignore empty folders
+					if (substr($filename, 0, 1) != '.')
+					{
+						delete_files($path.'/'.$filename, $del_dir, $level + 1);
+					}
+				}
+				else
+				{
+					unlink($path.'/'.$filename);
+				}
+			}
+		}
+		@closedir($current_dir);
+	
+		if ($del_dir == TRUE AND $level > 0)
+		{
+			@rmdir($path);
+		}
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Filenames
+ *
+ * Reads the specified directory and builds an array containing the filenames.  
+ * Any sub-folders contained within the specified path are read as well.
+ *
+ * @access	public
+ * @param	string	path to source
+ * @param	bool	whether to include the path as part of the filename
+ * @param	bool	internal variable to determine recursion status - do not use in calls
+ * @return	array
+ */	
+if ( ! function_exists('get_filenames'))
+{
+	function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
+	{
+		static $_filedata = array();
+				
+		if ($fp = @opendir($source_dir))
+		{
+			// reset the array and make sure $source_dir has a trailing slash on the initial call
+			if ($_recursion === FALSE)
+			{
+				$_filedata = array();
+				$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+			}
+			
+			while (FALSE !== ($file = readdir($fp)))
+			{
+				if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
+				{
+					 get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
+				}
+				elseif (strncmp($file, '.', 1) !== 0)
+				{
+			
+					$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
+				}
+			}
+			return $_filedata;
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Get Directory File Information
+ *
+ * Reads the specified directory and builds an array containing the filenames,  
+ * filesize, dates, and permissions
+ *
+ * Any sub-folders contained within the specified path are read as well.
+ *
+ * @access	public
+ * @param	string	path to source
+ * @param	bool	whether to include the path as part of the filename
+ * @param	bool	internal variable to determine recursion status - do not use in calls
+ * @return	array
+ */	
+if ( ! function_exists('get_dir_file_info'))
+{
+	function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE)
+	{
+		$_filedata = array();
+		$relative_path = $source_dir;
+				
+		if ($fp = @opendir($source_dir))
+		{
+			// reset the array and make sure $source_dir has a trailing slash on the initial call
+			if ($_recursion === FALSE)
+			{
+				$_filedata = array();
+				$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+			}
+
+			while (FALSE !== ($file = readdir($fp)))
+			{
+				if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
+				{
+					 get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
+				}
+				elseif (strncmp($file, '.', 1) !== 0)
+				{
+					$_filedata[$file] = get_file_info($source_dir.$file);
+					$_filedata[$file]['relative_path'] = $relative_path;
+				}
+			}
+			return $_filedata;
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+* Get File Info
+*
+* Given a file and path, returns the name, path, size, date modified
+* Second parameter allows you to explicitly declare what information you want returned
+* Options are: name, server_path, size, date, readable, writable, executable, fileperms
+* Returns FALSE if the file cannot be found.
+*
+* @access	public
+* @param	string		path to file
+* @param	mixed		array or comma separated string of information returned
+* @return	array
+*/
+if ( ! function_exists('get_file_info'))
+{
+	function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))
+	{
+
+		if ( ! file_exists($file))
+		{
+			return FALSE;
+		}
+
+		if (is_string($returned_values))
+		{
+			$returned_values = explode(',', $returned_values);
+		}
+
+		foreach ($returned_values as $key)
+		{
+			switch ($key)
+			{
+				case 'name':
+					$fileinfo['name'] = substr(strrchr($file, '/'), 1);
+					break;
+				case 'server_path':
+					$fileinfo['server_path'] = $file;
+					break;
+				case 'size':
+					$fileinfo['size'] = filesize($file);
+					break;
+				case 'date':
+					$fileinfo['date'] = filectime($file);
+					break;
+				case 'readable':
+					$fileinfo['readable'] = is_readable($file);
+					break;
+				case 'writable':
+					// There are known problems using is_weritable on IIS.  It may not be reliable - consider fileperms()
+					$fileinfo['writable'] = is_writable($file);
+					break;
+				case 'executable':
+					$fileinfo['executable'] = is_executable($file);
+					break;
+				case 'fileperms':
+					$fileinfo['fileperms'] = fileperms($file);
+					break;
+			}
+		}
+
+		return $fileinfo;
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Get Mime by Extension
+ *
+ * Translates a file extension into a mime type based on config/mimes.php. 
+ * Returns FALSE if it can't determine the type, or open the mime config file
+ *
+ * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
+ * It should NOT be trusted, and should certainly NOT be used for security
+ *
+ * @access	public
+ * @param	string	path to file
+ * @return	mixed
+ */	
+if ( ! function_exists('get_mime_by_extension'))
+{
+	function get_mime_by_extension($file)
+	{
+		$extension = substr(strrchr($file, '.'), 1);
+	
+		global $mimes;
+	
+		if ( ! is_array($mimes))
+		{
+			if ( ! require_once(APPPATH.'config/mimes.php'))
+			{
+				return FALSE;
+			}
+		}
+
+		if (array_key_exists($extension, $mimes))
+		{
+			if (is_array($mimes[$extension]))
+			{
+				// Multiple mime types, just give the first one
+				return current($mimes[$extension]);
+			}
+			else
+			{
+				return $mimes[$extension];
+			}
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Symbolic Permissions
+ *
+ * Takes a numeric value representing a file's permissions and returns
+ * standard symbolic notation representing that value
+ *
+ * @access	public
+ * @param	int
+ * @return	string
+ */	
+if ( ! function_exists('symbolic_permissions'))
+{
+	function symbolic_permissions($perms)
+	{	
+		if (($perms & 0xC000) == 0xC000)
+		{
+			$symbolic = 's'; // Socket
+		}
+		elseif (($perms & 0xA000) == 0xA000)
+		{
+			$symbolic = 'l'; // Symbolic Link
+		}
+		elseif (($perms & 0x8000) == 0x8000)
+		{
+			$symbolic = '-'; // Regular
+		}
+		elseif (($perms & 0x6000) == 0x6000)
+		{
+			$symbolic = 'b'; // Block special
+		}
+		elseif (($perms & 0x4000) == 0x4000)
+		{
+			$symbolic = 'd'; // Directory
+		}
+		elseif (($perms & 0x2000) == 0x2000)
+		{
+			$symbolic = 'c'; // Character special
+		}
+		elseif (($perms & 0x1000) == 0x1000)
+		{
+			$symbolic = 'p'; // FIFO pipe
+		}
+		else
+		{
+			$symbolic = 'u'; // Unknown
+		}
+
+		// Owner
+		$symbolic .= (($perms & 0x0100) ? 'r' : '-');
+		$symbolic .= (($perms & 0x0080) ? 'w' : '-');
+		$symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
+
+		// Group
+		$symbolic .= (($perms & 0x0020) ? 'r' : '-');
+		$symbolic .= (($perms & 0x0010) ? 'w' : '-');
+		$symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
+
+		// World
+		$symbolic .= (($perms & 0x0004) ? 'r' : '-');
+		$symbolic .= (($perms & 0x0002) ? 'w' : '-');
+		$symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
+
+		return $symbolic;		
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Octal Permissions
+ *
+ * Takes a numeric value representing a file's permissions and returns
+ * a three character string representing the file's octal permissions
+ *
+ * @access	public
+ * @param	int
+ * @return	string
+ */	
+if ( ! function_exists('octal_permissions'))
+{
+	function octal_permissions($perms)
+	{
+		return substr(sprintf('%o', $perms), -3);
+	}
+}
+
+
+/* End of file file_helper.php */
 /* Location: ./system/helpers/file_helper.php */
\ No newline at end of file
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 109d8c1..c002c6f 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -1,963 +1,963 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Form Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/form_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Declaration

- *

- * Creates the opening portion of the form.

- *

- * @access	public

- * @param	string	the URI segments of the form destination

- * @param	array	a key/value pair of attributes

- * @param	array	a key/value pair hidden data

- * @return	string

- */	

-if ( ! function_exists('form_open'))

-{

-	function form_open($action = '', $attributes = '', $hidden = array())

-	{

-		$CI =& get_instance();

-

-		if ($attributes == '')

-		{

-			$attributes = 'method="post"';

-		}

-

-		$action = ( strpos($action, '://') === FALSE) ? $CI->config->site_url($action) : $action;

-

-		$form = '<form action="'.$action.'"';

-	

-		$form .= _attributes_to_string($attributes, TRUE);

-	

-		$form .= '>';

-

-		if (is_array($hidden) AND count($hidden) > 0)

-		{

-			$form .= form_hidden($hidden);

-		}

-

-		return $form;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Declaration - Multipart type

- *

- * Creates the opening portion of the form, but with "multipart/form-data".

- *

- * @access	public

- * @param	string	the URI segments of the form destination

- * @param	array	a key/value pair of attributes

- * @param	array	a key/value pair hidden data

- * @return	string

- */

-if ( ! function_exists('form_open_multipart'))

-{

-	function form_open_multipart($action, $attributes = array(), $hidden = array())

-	{

-		$attributes['enctype'] = 'multipart/form-data';

-		return form_open($action, $attributes, $hidden);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Hidden Input Field

- *

- * Generates hidden fields.  You can pass a simple key/value string or an associative

- * array with multiple values.

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_hidden'))

-{

-	function form_hidden($name, $value = '')

-	{

-		if ( ! is_array($name))

-		{

-			return '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';

-		}

-

-		$form = '';

-

-		foreach ($name as $name => $value)

-		{

-			$form .= "\n";

-			$form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';

-		}

-

-		return $form;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Text Input Field

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_input'))

-{

-	function form_input($data = '', $value = '', $extra = '')

-	{

-		$defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);

-

-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Password Field

- *

- * Identical to the input function but adds the "password" type

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_password'))

-{

-	function form_password($data = '', $value = '', $extra = '')

-	{

-		if ( ! is_array($data))

-		{

-			$data = array('name' => $data);

-		}

-

-		$data['type'] = 'password';

-		return form_input($data, $value, $extra);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Upload Field

- *

- * Identical to the input function but adds the "file" type

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_upload'))

-{

-	function form_upload($data = '', $value = '', $extra = '')

-	{

-		if ( ! is_array($data))

-		{

-			$data = array('name' => $data);

-		}

-

-		$data['type'] = 'file';

-		return form_input($data, $value, $extra);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Textarea field

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_textarea'))

-{

-	function form_textarea($data = '', $value = '', $extra = '')

-	{

-		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12');

-

-		if ( ! is_array($data) OR ! isset($data['value']))

-		{

-			$val = $value;

-		}

-		else

-		{

-			$val = $data['value']; 

-			unset($data['value']); // textareas don't use the value attribute

-		}

-

-		return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".$val."</textarea>";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Drop-down Menu

- *

- * @access	public

- * @param	string

- * @param	array

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_dropdown'))

-{

-	function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')

-	{

-		if ( ! is_array($selected))

-		{

-			$selected = array($selected);

-		}

-

-		// If no selected state was submitted we will attempt to set it automatically

-		if (count($selected) === 0)

-		{

-			// If the form name appears in the $_POST array we have a winner!

-			if (isset($_POST[$name]))

-			{

-				$selected = array($_POST[$name]);

-			}

-		}

-

-		if ($extra != '') $extra = ' '.$extra;

-

-		$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';

-

-		$form = '<select name="'.$name.'"'.$extra.$multiple.">\n";

-	

-		foreach ($options as $key => $val)

-		{

-			$key = (string) $key;

-			$val = (string) $val;

-

-			$sel = (in_array($key, $selected))?' selected="selected"':'';

-

-			$form .= '<option value="'.$key.'"'.$sel.'>'.$val."</option>\n";

-		}

-

-		$form .= '</select>';

-

-		return $form;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Checkbox Field

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	bool

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_checkbox'))

-{

-	function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')

-	{

-		$defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);

-

-		if (is_array($data) AND array_key_exists('checked', $data))

-		{

-			$checked = $data['checked'];

-

-			if ($checked == FALSE)

-			{

-				unset($data['checked']);

-			}

-			else

-			{

-				$data['checked'] = 'checked';

-			}

-		}

-

-		if ($checked == TRUE)

-		{

-			$defaults['checked'] = 'checked';

-		}

-		else

-		{

-			unset($defaults['checked']);

-		}

-

-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Radio Button

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	bool

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_radio'))

-{

-	function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')

-	{

-		if ( ! is_array($data))

-		{	

-			$data = array('name' => $data);

-		}

-

-		$data['type'] = 'radio';

-		return form_checkbox($data, $value, $checked, $extra);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Submit Button

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_submit'))

-{	

-	function form_submit($data = '', $value = '', $extra = '')

-	{

-		$defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);

-

-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Reset Button

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_reset'))

-{

-	function form_reset($data = '', $value = '', $extra = '')

-	{

-		$defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);

-

-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Button

- *

- * @access	public

- * @param	mixed

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_button'))

-{

-	function form_button($data = '', $content = '', $extra = '')

-	{

-		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'submit');

-

-		if ( is_array($data) AND isset($data['content']))

-		{

-			$content = $data['content'];

-			unset($data['content']); // content is not an attribute

-		}

-

-		return "<button "._parse_form_attributes($data, $defaults).$extra.">".$content."</button>";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Label Tag

- *

- * @access	public

- * @param	string	The text to appear onscreen

- * @param	string	The id the label applies to

- * @param	string	Additional attributes

- * @return	string

- */

-if ( ! function_exists('form_label'))

-{

-	function form_label($label_text = '', $id = '', $attributes = array())

-	{

-

-		$label = '<label';

-

-		if ($id != '')

-		{

-			 $label .= " for=\"$id\"";

-		}

-

-		if (is_array($attributes) AND count($attributes) > 0)

-		{

-			foreach ($attributes as $key => $val)

-			{

-				$label .= ' '.$key.'="'.$val.'"';

-			}

-		}

-

-		$label .= ">$label_text</label>";

-

-		return $label;

-	}

-}

-

-// ------------------------------------------------------------------------

-/**

- * Fieldset Tag

- *

- * Used to produce <fieldset><legend>text</legend>.  To close fieldset

- * use form_fieldset_close()

- *

- * @access	public

- * @param	string	The legend text

- * @param	string	Additional attributes

- * @return	string

- */

-if ( ! function_exists('form_fieldset'))

-{

-	function form_fieldset($legend_text = '', $attributes = array())

-	{

-		$fieldset = "<fieldset";

-

-		$fieldset .= _attributes_to_string($attributes, FALSE);

-

-		$fieldset .= ">\n";

-

-		if ($legend_text != '')

-		{

-			$fieldset .= "<legend>$legend_text</legend>\n";

-		}

-

-		return $fieldset;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Fieldset Close Tag

- *

- * @access	public

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_fieldset_close'))

-{

-	function form_fieldset_close($extra = '')

-	{

-		return "</fieldset>".$extra;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Close Tag

- *

- * @access	public

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_close'))

-{

-	function form_close($extra = '')

-	{

-		return "</form>".$extra;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Prep

- *

- * Formats text so that it can be safely placed in a form field in the event it has HTML tags.

- *

- * @access	public

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_prep'))

-{

-	function form_prep($str = '')

-	{

-		// if the field name is an array we do this recursively

-		if (is_array($str))

-		{

-			foreach ($str as $key => $val)

-			{

-				$str[$key] = form_prep($val);

-			}

-

-			return $str;

-		}

-

-		if ($str === '')

-		{

-			return '';

-		}

-

-		$temp = '__TEMP_AMPERSANDS__';

-

-		// Replace entities to temporary markers so that 

-		// htmlspecialchars won't mess them up

-		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);

-		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);

-

-		$str = htmlspecialchars($str);

-

-		// In case htmlspecialchars misses these.

-		$str = str_replace(array("'", '"'), array("&#39;", "&quot;"), $str);

-

-		// Decode the temp markers back to entities

-		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);

-		$str = preg_replace("/$temp(\w+);/","&\\1;",$str);

-

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Value

- *

- * Grabs a value from the POST array for the specified field so you can

- * re-populate an input field or textarea.  If Form Validation

- * is active it retrieves the info from the validation class

- *

- * @access	public

- * @param	string

- * @return	mixed

- */

-if ( ! function_exists('set_value'))

-{

-	function set_value($field = '', $default = '')

-	{

-		if (FALSE === ($OBJ =& _get_validation_object()))

-		{

-			if ( ! isset($_POST[$field]))

-			{

-				return $default;

-			}

-

-			return form_prep($_POST[$field]);

-		}

-

-		return form_prep($OBJ->set_value($field, $default));

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Set Select

- *

- * Let's you set the selected value of a <select> menu via data in the POST array.

- * If Form Validation is active it retrieves the info from the validation class

- *

- * @access	public

- * @param	string

- * @param	string

- * @param	bool

- * @return	string

- */

-if ( ! function_exists('set_select'))

-{

-	function set_select($field = '', $value = '', $default = FALSE)

-	{

-		$OBJ =& _get_validation_object();

-

-		if ($OBJ === FALSE)

-		{

-			if ( ! isset($_POST[$field]))

-			{

-				if (count($_POST) === 0)

-				{

-					return ' selected="selected"';

-				}

-				return '';

-			}

-

-			$field = $_POST[$field];

-

-			if (is_array($field))

-			{

-				if ( ! in_array($value, $field))

-				{

-					return '';

-				}

-			}

-			else

-			{

-				if (($field == '' OR $value == '') OR ($field != $value))

-				{

-					return '';

-				}

-			}

-

-			return ' selected="selected"';

-		}

-

-		return $OBJ->set_select($field, $value, $default);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Set Checkbox

- *

- * Let's you set the selected value of a checkbox via the value in the POST array.

- * If Form Validation is active it retrieves the info from the validation class

- *

- * @access	public

- * @param	string

- * @param	string

- * @param	bool

- * @return	string

- */

-if ( ! function_exists('set_checkbox'))

-{

-	function set_checkbox($field = '', $value = '', $default = FALSE)

-	{

-		$OBJ =& _get_validation_object();

-

-		if ($OBJ === FALSE)

-		{ 

-			if ( ! isset($_POST[$field]))

-			{

-				if (count($_POST) === 0)

-				{

-					return ' checked="checked"';

-				}

-				return '';

-			}

-

-			$field = $_POST[$field];

-			

-			if (is_array($field))

-			{

-				if ( ! in_array($value, $field))

-				{

-					return '';

-				}

-			}

-			else

-			{

-				if (($field == '' OR $value == '') OR ($field != $value))

-				{

-					return '';

-				}

-			}

-

-			return ' checked="checked"';

-		}

-

-		return $OBJ->set_checkbox($field, $value, $default);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Set Radio

- *

- * Let's you set the selected value of a radio field via info in the POST array.

- * If Form Validation is active it retrieves the info from the validation class

- *

- * @access	public

- * @param	string

- * @param	string

- * @param	bool

- * @return	string

- */

-if ( ! function_exists('set_radio'))

-{

-	function set_radio($field = '', $value = '', $default = FALSE)

-	{

-		$OBJ =& _get_validation_object();

-

-		if ($OBJ === FALSE)

-		{

-			if ( ! isset($_POST[$field]))

-			{

-				if (count($_POST) === 0)

-				{

-					return ' checked="checked"';

-				}

-				return '';

-			}

-

-			$field = $_POST[$field];

-			

-			if (is_array($field))

-			{

-				if ( ! in_array($value, $field))

-				{

-					return '';

-				}

-			}

-			else

-			{

-				if (($field == '' OR $value == '') OR ($field != $value))

-				{

-					return '';

-				}

-			}

-

-			return ' checked="checked"';

-		}

-

-		return $OBJ->set_radio($field, $value, $default);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Error

- *

- * Returns the error for a specific form field.  This is a helper for the

- * form validation class.

- *

- * @access	public

- * @param	string

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('form_error'))

-{

-	function form_error($field = '', $prefix = '', $suffix = '')

-	{

-		if (FALSE === ($OBJ =& _get_validation_object()))

-		{

-			return '';

-		}

-

-		return $OBJ->error($field, $prefix, $suffix);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Validation Error String

- *

- * Returns all the errors associated with a form submission.  This is a helper

- * function for the form validation class.

- *

- * @access	public

- * @param	string

- * @param	string

- * @return	string

- */

-if ( ! function_exists('validation_errors'))

-{

-	function validation_errors($prefix = '', $suffix = '')

-	{

-		if (FALSE === ($OBJ =& _get_validation_object()))

-		{

-			return '';

-		}

-

-		return $OBJ->error_string($prefix, $suffix);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Parse the form attributes

- *

- * Helper function used by some of the form helpers

- *

- * @access	private

- * @param	array

- * @param	array

- * @return	string

- */

-if ( ! function_exists('_parse_form_attributes'))

-{

-	function _parse_form_attributes($attributes, $default)

-	{

-		if (is_array($attributes))

-		{

-			foreach ($default as $key => $val)

-			{

-				if (isset($attributes[$key]))

-				{

-					$default[$key] = $attributes[$key];

-					unset($attributes[$key]);

-				}

-			}

-

-			if (count($attributes) > 0)

-			{

-				$default = array_merge($default, $attributes);

-			}

-		}

-

-		$att = '';

-

-		foreach ($default as $key => $val)

-		{

-			if ($key == 'value')

-			{

-				$val = form_prep($val);

-			}

-

-			$att .= $key . '="' . $val . '" ';

-		}

-

-		return $att;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Attributes To String

- *

- * Helper function used by some of the form helpers

- *

- * @access	private

- * @param	mixed

- * @param	bool

- * @return	string

- */

-if ( ! function_exists('_attributes_to_string'))

-{

-	function _attributes_to_string($attributes, $formtag = FALSE)

-	{

-		if (is_string($attributes) AND strlen($attributes) > 0)

-		{

-			if ($formtag == TRUE AND strpos($attributes, 'method=') === FALSE)

-			{

-				$attributes .= ' method="post"';

-			}

-

-		return ' '.$attributes;

-		}

-	

-		if (is_object($attributes) AND count($attributes) > 0)

-		{

-			$attributes = (array)$attributes;

-		}

-

-		if (is_array($attributes) AND count($attributes) > 0)

-		{

-		$atts = '';

-

-		if ( ! isset($attributes['method']) AND $formtag === TRUE)

-		{

-			$atts .= ' method="post"';

-		}

-

-		foreach ($attributes as $key => $val)

-		{

-			$atts .= ' '.$key.'="'.$val.'"';

-		}

-

-		return $atts;

-		}

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Validation Object

- *

- * Determines what the form validation class was instantiated as, fetches

- * the object and returns it.

- *

- * @access	private

- * @return	mixed

- */

-if ( ! function_exists('_get_validation_object'))

-{

-	function &_get_validation_object()

-	{

-		$CI =& get_instance();

-

-		// We set this as a variable since we're returning by reference

-		$return = FALSE;

-

-		if ( ! isset($CI->load->_ci_classes) OR  ! isset($CI->load->_ci_classes['form_validation']))

-		{

-			return $return;

-		}

-

-		$object = $CI->load->_ci_classes['form_validation'];

-

-		if ( ! isset($CI->$object) OR ! is_object($CI->$object))

-		{

-			return $return;

-		}

-

-		return $CI->$object;

-	}

-}

-

-

-/* End of file form_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Form Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/form_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Declaration
+ *
+ * Creates the opening portion of the form.
+ *
+ * @access	public
+ * @param	string	the URI segments of the form destination
+ * @param	array	a key/value pair of attributes
+ * @param	array	a key/value pair hidden data
+ * @return	string
+ */	
+if ( ! function_exists('form_open'))
+{
+	function form_open($action = '', $attributes = '', $hidden = array())
+	{
+		$CI =& get_instance();
+
+		if ($attributes == '')
+		{
+			$attributes = 'method="post"';
+		}
+
+		$action = ( strpos($action, '://') === FALSE) ? $CI->config->site_url($action) : $action;
+
+		$form = '<form action="'.$action.'"';
+	
+		$form .= _attributes_to_string($attributes, TRUE);
+	
+		$form .= '>';
+
+		if (is_array($hidden) AND count($hidden) > 0)
+		{
+			$form .= form_hidden($hidden);
+		}
+
+		return $form;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Declaration - Multipart type
+ *
+ * Creates the opening portion of the form, but with "multipart/form-data".
+ *
+ * @access	public
+ * @param	string	the URI segments of the form destination
+ * @param	array	a key/value pair of attributes
+ * @param	array	a key/value pair hidden data
+ * @return	string
+ */
+if ( ! function_exists('form_open_multipart'))
+{
+	function form_open_multipart($action, $attributes = array(), $hidden = array())
+	{
+		$attributes['enctype'] = 'multipart/form-data';
+		return form_open($action, $attributes, $hidden);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Hidden Input Field
+ *
+ * Generates hidden fields.  You can pass a simple key/value string or an associative
+ * array with multiple values.
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_hidden'))
+{
+	function form_hidden($name, $value = '')
+	{
+		if ( ! is_array($name))
+		{
+			return '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';
+		}
+
+		$form = '';
+
+		foreach ($name as $name => $value)
+		{
+			$form .= "\n";
+			$form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value).'" />';
+		}
+
+		return $form;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Text Input Field
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_input'))
+{
+	function form_input($data = '', $value = '', $extra = '')
+	{
+		$defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Password Field
+ *
+ * Identical to the input function but adds the "password" type
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_password'))
+{
+	function form_password($data = '', $value = '', $extra = '')
+	{
+		if ( ! is_array($data))
+		{
+			$data = array('name' => $data);
+		}
+
+		$data['type'] = 'password';
+		return form_input($data, $value, $extra);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Upload Field
+ *
+ * Identical to the input function but adds the "file" type
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_upload'))
+{
+	function form_upload($data = '', $value = '', $extra = '')
+	{
+		if ( ! is_array($data))
+		{
+			$data = array('name' => $data);
+		}
+
+		$data['type'] = 'file';
+		return form_input($data, $value, $extra);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Textarea field
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_textarea'))
+{
+	function form_textarea($data = '', $value = '', $extra = '')
+	{
+		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12');
+
+		if ( ! is_array($data) OR ! isset($data['value']))
+		{
+			$val = $value;
+		}
+		else
+		{
+			$val = $data['value']; 
+			unset($data['value']); // textareas don't use the value attribute
+		}
+
+		return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".$val."</textarea>";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Drop-down Menu
+ *
+ * @access	public
+ * @param	string
+ * @param	array
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_dropdown'))
+{
+	function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
+	{
+		if ( ! is_array($selected))
+		{
+			$selected = array($selected);
+		}
+
+		// If no selected state was submitted we will attempt to set it automatically
+		if (count($selected) === 0)
+		{
+			// If the form name appears in the $_POST array we have a winner!
+			if (isset($_POST[$name]))
+			{
+				$selected = array($_POST[$name]);
+			}
+		}
+
+		if ($extra != '') $extra = ' '.$extra;
+
+		$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
+
+		$form = '<select name="'.$name.'"'.$extra.$multiple.">\n";
+	
+		foreach ($options as $key => $val)
+		{
+			$key = (string) $key;
+			$val = (string) $val;
+
+			$sel = (in_array($key, $selected))?' selected="selected"':'';
+
+			$form .= '<option value="'.$key.'"'.$sel.'>'.$val."</option>\n";
+		}
+
+		$form .= '</select>';
+
+		return $form;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Checkbox Field
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	bool
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_checkbox'))
+{
+	function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')
+	{
+		$defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+		if (is_array($data) AND array_key_exists('checked', $data))
+		{
+			$checked = $data['checked'];
+
+			if ($checked == FALSE)
+			{
+				unset($data['checked']);
+			}
+			else
+			{
+				$data['checked'] = 'checked';
+			}
+		}
+
+		if ($checked == TRUE)
+		{
+			$defaults['checked'] = 'checked';
+		}
+		else
+		{
+			unset($defaults['checked']);
+		}
+
+		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Radio Button
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	bool
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_radio'))
+{
+	function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')
+	{
+		if ( ! is_array($data))
+		{	
+			$data = array('name' => $data);
+		}
+
+		$data['type'] = 'radio';
+		return form_checkbox($data, $value, $checked, $extra);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Submit Button
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_submit'))
+{	
+	function form_submit($data = '', $value = '', $extra = '')
+	{
+		$defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Reset Button
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_reset'))
+{
+	function form_reset($data = '', $value = '', $extra = '')
+	{
+		$defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Button
+ *
+ * @access	public
+ * @param	mixed
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_button'))
+{
+	function form_button($data = '', $content = '', $extra = '')
+	{
+		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'submit');
+
+		if ( is_array($data) AND isset($data['content']))
+		{
+			$content = $data['content'];
+			unset($data['content']); // content is not an attribute
+		}
+
+		return "<button "._parse_form_attributes($data, $defaults).$extra.">".$content."</button>";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Label Tag
+ *
+ * @access	public
+ * @param	string	The text to appear onscreen
+ * @param	string	The id the label applies to
+ * @param	string	Additional attributes
+ * @return	string
+ */
+if ( ! function_exists('form_label'))
+{
+	function form_label($label_text = '', $id = '', $attributes = array())
+	{
+
+		$label = '<label';
+
+		if ($id != '')
+		{
+			 $label .= " for=\"$id\"";
+		}
+
+		if (is_array($attributes) AND count($attributes) > 0)
+		{
+			foreach ($attributes as $key => $val)
+			{
+				$label .= ' '.$key.'="'.$val.'"';
+			}
+		}
+
+		$label .= ">$label_text</label>";
+
+		return $label;
+	}
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Fieldset Tag
+ *
+ * Used to produce <fieldset><legend>text</legend>.  To close fieldset
+ * use form_fieldset_close()
+ *
+ * @access	public
+ * @param	string	The legend text
+ * @param	string	Additional attributes
+ * @return	string
+ */
+if ( ! function_exists('form_fieldset'))
+{
+	function form_fieldset($legend_text = '', $attributes = array())
+	{
+		$fieldset = "<fieldset";
+
+		$fieldset .= _attributes_to_string($attributes, FALSE);
+
+		$fieldset .= ">\n";
+
+		if ($legend_text != '')
+		{
+			$fieldset .= "<legend>$legend_text</legend>\n";
+		}
+
+		return $fieldset;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Fieldset Close Tag
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_fieldset_close'))
+{
+	function form_fieldset_close($extra = '')
+	{
+		return "</fieldset>".$extra;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Close Tag
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_close'))
+{
+	function form_close($extra = '')
+	{
+		return "</form>".$extra;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Prep
+ *
+ * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_prep'))
+{
+	function form_prep($str = '')
+	{
+		// if the field name is an array we do this recursively
+		if (is_array($str))
+		{
+			foreach ($str as $key => $val)
+			{
+				$str[$key] = form_prep($val);
+			}
+
+			return $str;
+		}
+
+		if ($str === '')
+		{
+			return '';
+		}
+
+		$temp = '__TEMP_AMPERSANDS__';
+
+		// Replace entities to temporary markers so that 
+		// htmlspecialchars won't mess them up
+		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
+		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
+
+		$str = htmlspecialchars($str);
+
+		// In case htmlspecialchars misses these.
+		$str = str_replace(array("'", '"'), array("&#39;", "&quot;"), $str);
+
+		// Decode the temp markers back to entities
+		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
+		$str = preg_replace("/$temp(\w+);/","&\\1;",$str);
+
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Value
+ *
+ * Grabs a value from the POST array for the specified field so you can
+ * re-populate an input field or textarea.  If Form Validation
+ * is active it retrieves the info from the validation class
+ *
+ * @access	public
+ * @param	string
+ * @return	mixed
+ */
+if ( ! function_exists('set_value'))
+{
+	function set_value($field = '', $default = '')
+	{
+		if (FALSE === ($OBJ =& _get_validation_object()))
+		{
+			if ( ! isset($_POST[$field]))
+			{
+				return $default;
+			}
+
+			return form_prep($_POST[$field]);
+		}
+
+		return form_prep($OBJ->set_value($field, $default));
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Select
+ *
+ * Let's you set the selected value of a <select> menu via data in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access	public
+ * @param	string
+ * @param	string
+ * @param	bool
+ * @return	string
+ */
+if ( ! function_exists('set_select'))
+{
+	function set_select($field = '', $value = '', $default = FALSE)
+	{
+		$OBJ =& _get_validation_object();
+
+		if ($OBJ === FALSE)
+		{
+			if ( ! isset($_POST[$field]))
+			{
+				if (count($_POST) === 0)
+				{
+					return ' selected="selected"';
+				}
+				return '';
+			}
+
+			$field = $_POST[$field];
+
+			if (is_array($field))
+			{
+				if ( ! in_array($value, $field))
+				{
+					return '';
+				}
+			}
+			else
+			{
+				if (($field == '' OR $value == '') OR ($field != $value))
+				{
+					return '';
+				}
+			}
+
+			return ' selected="selected"';
+		}
+
+		return $OBJ->set_select($field, $value, $default);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Checkbox
+ *
+ * Let's you set the selected value of a checkbox via the value in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access	public
+ * @param	string
+ * @param	string
+ * @param	bool
+ * @return	string
+ */
+if ( ! function_exists('set_checkbox'))
+{
+	function set_checkbox($field = '', $value = '', $default = FALSE)
+	{
+		$OBJ =& _get_validation_object();
+
+		if ($OBJ === FALSE)
+		{ 
+			if ( ! isset($_POST[$field]))
+			{
+				if (count($_POST) === 0)
+				{
+					return ' checked="checked"';
+				}
+				return '';
+			}
+
+			$field = $_POST[$field];
+			
+			if (is_array($field))
+			{
+				if ( ! in_array($value, $field))
+				{
+					return '';
+				}
+			}
+			else
+			{
+				if (($field == '' OR $value == '') OR ($field != $value))
+				{
+					return '';
+				}
+			}
+
+			return ' checked="checked"';
+		}
+
+		return $OBJ->set_checkbox($field, $value, $default);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Radio
+ *
+ * Let's you set the selected value of a radio field via info in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access	public
+ * @param	string
+ * @param	string
+ * @param	bool
+ * @return	string
+ */
+if ( ! function_exists('set_radio'))
+{
+	function set_radio($field = '', $value = '', $default = FALSE)
+	{
+		$OBJ =& _get_validation_object();
+
+		if ($OBJ === FALSE)
+		{
+			if ( ! isset($_POST[$field]))
+			{
+				if (count($_POST) === 0)
+				{
+					return ' checked="checked"';
+				}
+				return '';
+			}
+
+			$field = $_POST[$field];
+			
+			if (is_array($field))
+			{
+				if ( ! in_array($value, $field))
+				{
+					return '';
+				}
+			}
+			else
+			{
+				if (($field == '' OR $value == '') OR ($field != $value))
+				{
+					return '';
+				}
+			}
+
+			return ' checked="checked"';
+		}
+
+		return $OBJ->set_radio($field, $value, $default);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Error
+ *
+ * Returns the error for a specific form field.  This is a helper for the
+ * form validation class.
+ *
+ * @access	public
+ * @param	string
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('form_error'))
+{
+	function form_error($field = '', $prefix = '', $suffix = '')
+	{
+		if (FALSE === ($OBJ =& _get_validation_object()))
+		{
+			return '';
+		}
+
+		return $OBJ->error($field, $prefix, $suffix);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validation Error String
+ *
+ * Returns all the errors associated with a form submission.  This is a helper
+ * function for the form validation class.
+ *
+ * @access	public
+ * @param	string
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('validation_errors'))
+{
+	function validation_errors($prefix = '', $suffix = '')
+	{
+		if (FALSE === ($OBJ =& _get_validation_object()))
+		{
+			return '';
+		}
+
+		return $OBJ->error_string($prefix, $suffix);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse the form attributes
+ *
+ * Helper function used by some of the form helpers
+ *
+ * @access	private
+ * @param	array
+ * @param	array
+ * @return	string
+ */
+if ( ! function_exists('_parse_form_attributes'))
+{
+	function _parse_form_attributes($attributes, $default)
+	{
+		if (is_array($attributes))
+		{
+			foreach ($default as $key => $val)
+			{
+				if (isset($attributes[$key]))
+				{
+					$default[$key] = $attributes[$key];
+					unset($attributes[$key]);
+				}
+			}
+
+			if (count($attributes) > 0)
+			{
+				$default = array_merge($default, $attributes);
+			}
+		}
+
+		$att = '';
+
+		foreach ($default as $key => $val)
+		{
+			if ($key == 'value')
+			{
+				$val = form_prep($val);
+			}
+
+			$att .= $key . '="' . $val . '" ';
+		}
+
+		return $att;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Attributes To String
+ *
+ * Helper function used by some of the form helpers
+ *
+ * @access	private
+ * @param	mixed
+ * @param	bool
+ * @return	string
+ */
+if ( ! function_exists('_attributes_to_string'))
+{
+	function _attributes_to_string($attributes, $formtag = FALSE)
+	{
+		if (is_string($attributes) AND strlen($attributes) > 0)
+		{
+			if ($formtag == TRUE AND strpos($attributes, 'method=') === FALSE)
+			{
+				$attributes .= ' method="post"';
+			}
+
+		return ' '.$attributes;
+		}
+	
+		if (is_object($attributes) AND count($attributes) > 0)
+		{
+			$attributes = (array)$attributes;
+		}
+
+		if (is_array($attributes) AND count($attributes) > 0)
+		{
+		$atts = '';
+
+		if ( ! isset($attributes['method']) AND $formtag === TRUE)
+		{
+			$atts .= ' method="post"';
+		}
+
+		foreach ($attributes as $key => $val)
+		{
+			$atts .= ' '.$key.'="'.$val.'"';
+		}
+
+		return $atts;
+		}
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validation Object
+ *
+ * Determines what the form validation class was instantiated as, fetches
+ * the object and returns it.
+ *
+ * @access	private
+ * @return	mixed
+ */
+if ( ! function_exists('_get_validation_object'))
+{
+	function &_get_validation_object()
+	{
+		$CI =& get_instance();
+
+		// We set this as a variable since we're returning by reference
+		$return = FALSE;
+
+		if ( ! isset($CI->load->_ci_classes) OR  ! isset($CI->load->_ci_classes['form_validation']))
+		{
+			return $return;
+		}
+
+		$object = $CI->load->_ci_classes['form_validation'];
+
+		if ( ! isset($CI->$object) OR ! is_object($CI->$object))
+		{
+			return $return;
+		}
+
+		return $CI->$object;
+	}
+}
+
+
+/* End of file form_helper.php */
 /* Location: ./system/helpers/form_helper.php */
\ No newline at end of file
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index cc34b65..e552b86 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -1,416 +1,416 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter HTML Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/html_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Heading

- *

- * Generates an HTML heading tag.  First param is the data.

- * Second param is the size of the heading tag.

- *

- * @access	public

- * @param	string

- * @param	integer

- * @return	string

- */

-if ( ! function_exists('heading'))

-{

-	function heading($data = '', $h = '1')

-	{

-		return "<h".$h.">".$data."</h".$h.">";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Unordered List

- *

- * Generates an HTML unordered list from an single or multi-dimensional array.

- *

- * @access	public

- * @param	array

- * @param	mixed

- * @return	string

- */

-if ( ! function_exists('ul'))

-{

-	function ul($list, $attributes = '')

-	{

-		return _list('ul', $list, $attributes);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Ordered List

- *

- * Generates an HTML ordered list from an single or multi-dimensional array.

- *

- * @access	public

- * @param	array

- * @param	mixed

- * @return	string

- */

-if ( ! function_exists('ol'))

-{

-	function ol($list, $attributes = '')

-	{

-		return _list('ol', $list, $attributes);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Generates the list

- *

- * Generates an HTML ordered list from an single or multi-dimensional array.

- *

- * @access	private

- * @param	string

- * @param	mixed

- * @param	mixed

- * @param	intiger

- * @return	string

- */

-if ( ! function_exists('_list'))

-{

-	function _list($type = 'ul', $list, $attributes = '', $depth = 0)

-	{

-		// If an array wasn't submitted there's nothing to do...

-		if ( ! is_array($list))

-		{

-			return $list;

-		}

-

-		// Set the indentation based on the depth

-		$out = str_repeat(" ", $depth);

-

-		// Were any attributes submitted?  If so generate a string

-		if (is_array($attributes))

-		{

-			$atts = '';

-			foreach ($attributes as $key => $val)

-			{

-				$atts .= ' ' . $key . '="' . $val . '"';

-			}

-			$attributes = $atts;

-		}

-

-		// Write the opening list tag

-		$out .= "<".$type.$attributes.">\n";

-

-		// Cycle through the list elements.  If an array is

-		// encountered we will recursively call _list()

-

-		static $_last_list_item = '';

-		foreach ($list as $key => $val)

-		{

-			$_last_list_item = $key;

-

-			$out .= str_repeat(" ", $depth + 2);

-			$out .= "<li>";

-

-			if ( ! is_array($val))

-			{

-				$out .= $val;

-			}

-			else

-			{

-				$out .= $_last_list_item."\n";

-				$out .= _list($type, $val, '', $depth + 4);

-				$out .= str_repeat(" ", $depth + 2);

-			}

-

-			$out .= "</li>\n";

-		}

-

-		// Set the indentation for the closing tag

-		$out .= str_repeat(" ", $depth);

-

-		// Write the closing list tag

-		$out .= "</".$type.">\n";

-

-		return $out;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Generates HTML BR tags based on number supplied

- *

- * @access	public

- * @param	integer

- * @return	string

- */

-if ( ! function_exists('br'))

-{

-	function br($num = 1)

-	{

-		return str_repeat("<br />", $num);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Image

- *

- * Generates an <img /> element

- *

- * @access	public

- * @param	mixed

- * @return	string

- */

-if ( ! function_exists('img'))

-{

-	function img($src = '', $index_page = FALSE)

-	{

-		if ( ! is_array($src) )

-		{

-			$src = array('src' => $src);

-		}

-

-		$img = '<img';

-

-		foreach ($src as $k=>$v)

-		{

-

-			if ($k == 'src' AND strpos($v, '://') === FALSE)

-			{

-				$CI =& get_instance();

-

-				if ($index_page === TRUE)

-				{

-					$img .= ' src="'.$CI->config->site_url($v).'" ';

-				}

-				else

-				{

-					$img .= ' src="'.$CI->config->slash_item('base_url').$v.'" ';

-				}

-			}

-			else

-			{

-				$img .= " $k=\"$v\" ";

-			}

-		}

-

-		$img .= '/>';

-

-		return $img;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Doctype

- *

- * Generates a page document type declaration

- *

- * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,

- * html4-strict, html4-trans, and html4-frame.  Values are saved in the

- * doctypes config file.

- *

- * @access	public

- * @param	string	type	The doctype to be generated

- * @return	string

- */

-if ( ! function_exists('doctype'))

-{

-	function doctype($type = 'xhtml-strict')

-	{

-		global $_doctypes;

-

-		if ( ! is_array($_doctypes))

-		{

-			if ( ! require_once(APPPATH.'config/doctypes.php'))

-			{

-				return FALSE;

-			}

-		}

-

-		if (isset($_doctypes[$type]))

-		{

-			return $_doctypes[$type];

-		}

-		else

-		{

-			return FALSE;

-		}

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Link

- *

- * Generates link to a CSS file

- *

- * @access	public

- * @param	mixed	stylesheet hrefs or an array

- * @param	string	rel

- * @param	string	type

- * @param	string	title

- * @param	string	media

- * @param	boolean	should index_page be added to the css path

- * @return	string

- */

-if ( ! function_exists('link_tag'))

-{

-	function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)

-	{

-		$CI =& get_instance();

-

-		$link = '<link ';

-

-		if (is_array($href))

-		{

-			foreach ($href as $k=>$v)

-			{

-				if ($k == 'href' AND strpos($v, '://') === FALSE)

-				{

-					if ($index_page === TRUE)

-					{

-						$link .= ' href="'.$CI->config->site_url($v).'" ';

-					}

-					else

-					{

-						$link .= ' href="'.$CI->config->slash_item('base_url').$v.'" ';

-					}

-				}

-				else

-				{

-					$link .= "$k=\"$v\" ";

-				}

-			}

-

-			$link .= "/>";

-		}

-		else

-		{

-			if ( strpos($href, '://') !== FALSE)

-			{

-				$link .= ' href="'.$href.'" ';

-			}

-			elseif ($index_page === TRUE)

-			{

-				$link .= ' href="'.$CI->config->site_url($href).'" ';

-			}

-			else

-			{

-				$link .= ' href="'.$CI->config->slash_item('base_url').$href.'" ';

-			}

-

-			$link .= 'rel="'.$rel.'" type="'.$type.'" ';

-

-			if ($media	!= '')

-			{

-				$link .= 'media="'.$media.'" ';

-			}

-

-			if ($title	!= '')

-			{

-				$link .= 'title="'.$title.'" ';

-			}

-

-			$link .= '/>';

-		}

-

-

-		return $link;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Generates meta tags from an array of key/values

- *

- * @access	public

- * @param	array

- * @return	string

- */

-if ( ! function_exists('meta'))

-{

-	function meta($name = '', $content = '', $type = 'name', $newline = "\n")

-	{

-		// Since we allow the data to be passes as a string, a simple array

-		// or a multidimensional one, we need to do a little prepping.

-		if ( ! is_array($name))

-		{

-			$name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));

-		}

-		else

-		{

-			// Turn single array into multidimensional

-			if (isset($name['name']))

-			{

-				$name = array($name);

-			}

-		}

-

-		$str = '';

-		foreach ($name as $meta)

-		{

-			$type 		= ( ! isset($meta['type']) OR $meta['type'] == 'name') ? 'name' : 'http-equiv';

-			$name 		= ( ! isset($meta['name'])) 	? '' 	: $meta['name'];

-			$content	= ( ! isset($meta['content']))	? '' 	: $meta['content'];

-			$newline	= ( ! isset($meta['newline']))	? "\n"	: $meta['newline'];

-

-			$str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;

-		}

-

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Generates non-breaking space entities based on number supplied

- *

- * @access	public

- * @param	integer

- * @return	string

- */

-if ( ! function_exists('nbs'))

-{

-	function nbs($num = 1)

-	{

-		return str_repeat("&nbsp;", $num);

-	}

-}

-

-

-/* End of file html_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter HTML Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/html_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Heading
+ *
+ * Generates an HTML heading tag.  First param is the data.
+ * Second param is the size of the heading tag.
+ *
+ * @access	public
+ * @param	string
+ * @param	integer
+ * @return	string
+ */
+if ( ! function_exists('heading'))
+{
+	function heading($data = '', $h = '1')
+	{
+		return "<h".$h.">".$data."</h".$h.">";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Unordered List
+ *
+ * Generates an HTML unordered list from an single or multi-dimensional array.
+ *
+ * @access	public
+ * @param	array
+ * @param	mixed
+ * @return	string
+ */
+if ( ! function_exists('ul'))
+{
+	function ul($list, $attributes = '')
+	{
+		return _list('ul', $list, $attributes);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Ordered List
+ *
+ * Generates an HTML ordered list from an single or multi-dimensional array.
+ *
+ * @access	public
+ * @param	array
+ * @param	mixed
+ * @return	string
+ */
+if ( ! function_exists('ol'))
+{
+	function ol($list, $attributes = '')
+	{
+		return _list('ol', $list, $attributes);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates the list
+ *
+ * Generates an HTML ordered list from an single or multi-dimensional array.
+ *
+ * @access	private
+ * @param	string
+ * @param	mixed
+ * @param	mixed
+ * @param	intiger
+ * @return	string
+ */
+if ( ! function_exists('_list'))
+{
+	function _list($type = 'ul', $list, $attributes = '', $depth = 0)
+	{
+		// If an array wasn't submitted there's nothing to do...
+		if ( ! is_array($list))
+		{
+			return $list;
+		}
+
+		// Set the indentation based on the depth
+		$out = str_repeat(" ", $depth);
+
+		// Were any attributes submitted?  If so generate a string
+		if (is_array($attributes))
+		{
+			$atts = '';
+			foreach ($attributes as $key => $val)
+			{
+				$atts .= ' ' . $key . '="' . $val . '"';
+			}
+			$attributes = $atts;
+		}
+
+		// Write the opening list tag
+		$out .= "<".$type.$attributes.">\n";
+
+		// Cycle through the list elements.  If an array is
+		// encountered we will recursively call _list()
+
+		static $_last_list_item = '';
+		foreach ($list as $key => $val)
+		{
+			$_last_list_item = $key;
+
+			$out .= str_repeat(" ", $depth + 2);
+			$out .= "<li>";
+
+			if ( ! is_array($val))
+			{
+				$out .= $val;
+			}
+			else
+			{
+				$out .= $_last_list_item."\n";
+				$out .= _list($type, $val, '', $depth + 4);
+				$out .= str_repeat(" ", $depth + 2);
+			}
+
+			$out .= "</li>\n";
+		}
+
+		// Set the indentation for the closing tag
+		$out .= str_repeat(" ", $depth);
+
+		// Write the closing list tag
+		$out .= "</".$type.">\n";
+
+		return $out;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates HTML BR tags based on number supplied
+ *
+ * @access	public
+ * @param	integer
+ * @return	string
+ */
+if ( ! function_exists('br'))
+{
+	function br($num = 1)
+	{
+		return str_repeat("<br />", $num);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Image
+ *
+ * Generates an <img /> element
+ *
+ * @access	public
+ * @param	mixed
+ * @return	string
+ */
+if ( ! function_exists('img'))
+{
+	function img($src = '', $index_page = FALSE)
+	{
+		if ( ! is_array($src) )
+		{
+			$src = array('src' => $src);
+		}
+
+		$img = '<img';
+
+		foreach ($src as $k=>$v)
+		{
+
+			if ($k == 'src' AND strpos($v, '://') === FALSE)
+			{
+				$CI =& get_instance();
+
+				if ($index_page === TRUE)
+				{
+					$img .= ' src="'.$CI->config->site_url($v).'" ';
+				}
+				else
+				{
+					$img .= ' src="'.$CI->config->slash_item('base_url').$v.'" ';
+				}
+			}
+			else
+			{
+				$img .= " $k=\"$v\" ";
+			}
+		}
+
+		$img .= '/>';
+
+		return $img;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Doctype
+ *
+ * Generates a page document type declaration
+ *
+ * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,
+ * html4-strict, html4-trans, and html4-frame.  Values are saved in the
+ * doctypes config file.
+ *
+ * @access	public
+ * @param	string	type	The doctype to be generated
+ * @return	string
+ */
+if ( ! function_exists('doctype'))
+{
+	function doctype($type = 'xhtml-strict')
+	{
+		global $_doctypes;
+
+		if ( ! is_array($_doctypes))
+		{
+			if ( ! require_once(APPPATH.'config/doctypes.php'))
+			{
+				return FALSE;
+			}
+		}
+
+		if (isset($_doctypes[$type]))
+		{
+			return $_doctypes[$type];
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Link
+ *
+ * Generates link to a CSS file
+ *
+ * @access	public
+ * @param	mixed	stylesheet hrefs or an array
+ * @param	string	rel
+ * @param	string	type
+ * @param	string	title
+ * @param	string	media
+ * @param	boolean	should index_page be added to the css path
+ * @return	string
+ */
+if ( ! function_exists('link_tag'))
+{
+	function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)
+	{
+		$CI =& get_instance();
+
+		$link = '<link ';
+
+		if (is_array($href))
+		{
+			foreach ($href as $k=>$v)
+			{
+				if ($k == 'href' AND strpos($v, '://') === FALSE)
+				{
+					if ($index_page === TRUE)
+					{
+						$link .= ' href="'.$CI->config->site_url($v).'" ';
+					}
+					else
+					{
+						$link .= ' href="'.$CI->config->slash_item('base_url').$v.'" ';
+					}
+				}
+				else
+				{
+					$link .= "$k=\"$v\" ";
+				}
+			}
+
+			$link .= "/>";
+		}
+		else
+		{
+			if ( strpos($href, '://') !== FALSE)
+			{
+				$link .= ' href="'.$href.'" ';
+			}
+			elseif ($index_page === TRUE)
+			{
+				$link .= ' href="'.$CI->config->site_url($href).'" ';
+			}
+			else
+			{
+				$link .= ' href="'.$CI->config->slash_item('base_url').$href.'" ';
+			}
+
+			$link .= 'rel="'.$rel.'" type="'.$type.'" ';
+
+			if ($media	!= '')
+			{
+				$link .= 'media="'.$media.'" ';
+			}
+
+			if ($title	!= '')
+			{
+				$link .= 'title="'.$title.'" ';
+			}
+
+			$link .= '/>';
+		}
+
+
+		return $link;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates meta tags from an array of key/values
+ *
+ * @access	public
+ * @param	array
+ * @return	string
+ */
+if ( ! function_exists('meta'))
+{
+	function meta($name = '', $content = '', $type = 'name', $newline = "\n")
+	{
+		// Since we allow the data to be passes as a string, a simple array
+		// or a multidimensional one, we need to do a little prepping.
+		if ( ! is_array($name))
+		{
+			$name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));
+		}
+		else
+		{
+			// Turn single array into multidimensional
+			if (isset($name['name']))
+			{
+				$name = array($name);
+			}
+		}
+
+		$str = '';
+		foreach ($name as $meta)
+		{
+			$type 		= ( ! isset($meta['type']) OR $meta['type'] == 'name') ? 'name' : 'http-equiv';
+			$name 		= ( ! isset($meta['name'])) 	? '' 	: $meta['name'];
+			$content	= ( ! isset($meta['content']))	? '' 	: $meta['content'];
+			$newline	= ( ! isset($meta['newline']))	? "\n"	: $meta['newline'];
+
+			$str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
+		}
+
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates non-breaking space entities based on number supplied
+ *
+ * @access	public
+ * @param	integer
+ * @return	string
+ */
+if ( ! function_exists('nbs'))
+{
+	function nbs($num = 1)
+	{
+		return str_repeat("&nbsp;", $num);
+	}
+}
+
+
+/* End of file html_helper.php */
 /* Location: ./system/helpers/html_helper.php */
\ No newline at end of file
diff --git a/system/helpers/index.html b/system/helpers/index.html
index 065d2da..c942a79 100644
--- a/system/helpers/index.html
+++ b/system/helpers/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index 8a87e50..9393f11 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -1,169 +1,169 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Inflector Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html

- */

-

-

-// --------------------------------------------------------------------

-

-/**

- * Singular

- *

- * Takes a plural word and makes it singular

- *

- * @access	public

- * @param	string

- * @return	str

- */	

-if ( ! function_exists('singular'))

-{	

-	function singular($str)

-	{

-		$str = strtolower(trim($str));

-		$end = substr($str, -3);

-	

-		if ($end == 'ies')

-		{

-			$str = substr($str, 0, strlen($str)-3).'y';

-		}

-		elseif ($end == 'ses')

-		{

-			$str = substr($str, 0, strlen($str)-2);

-		}

-		else

-		{

-			$end = substr($str, -1);

-		

-			if ($end == 's')

-			{

-				$str = substr($str, 0, strlen($str)-1);

-			}

-		}

-	

-		return $str;

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Plural

- *

- * Takes a singular word and makes it plural

- *

- * @access	public

- * @param	string

- * @param	bool

- * @return	str

- */	

-if ( ! function_exists('plural'))

-{	

-	function plural($str, $force = FALSE)

-	{

-		$str = strtolower(trim($str));

-		$end = substr($str, -1);

-

-		if ($end == 'y')

-		{

-			$str = substr($str, 0, strlen($str)-1).'ies';

-		}

-		elseif ($end == 's')

-		{

-			if ($force == TRUE)

-			{

-				$str .= 'es';

-			}

-		}

-		else

-		{

-			$str .= 's';

-		}

-

-		return $str;

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Camelize

- *

- * Takes multiple words separated by spaces or underscores and camelizes them

- *

- * @access	public

- * @param	string

- * @return	str

- */	

-if ( ! function_exists('camelize'))

-{	

-	function camelize($str)

-	{		

-		$str = 'x'.strtolower(trim($str));

-		$str = ucwords(preg_replace('/[\s_]+/', ' ', $str));

-		return substr(str_replace(' ', '', $str), 1);

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Underscore

- *

- * Takes multiple words separated by spaces and underscores them

- *

- * @access	public

- * @param	string

- * @return	str

- */	

-if ( ! function_exists('underscore'))

-{

-	function underscore($str)

-	{

-		return preg_replace('/[\s]+/', '_', strtolower(trim($str)));

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Humanize

- *

- * Takes multiple words separated by underscores and changes them to spaces

- *

- * @access	public

- * @param	string

- * @return	str

- */	

-if ( ! function_exists('humanize'))

-{	

-	function humanize($str)

-	{

-		return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));

-	}

-}

-	

-

-/* End of file inflector_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Inflector Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html
+ */
+
+
+// --------------------------------------------------------------------
+
+/**
+ * Singular
+ *
+ * Takes a plural word and makes it singular
+ *
+ * @access	public
+ * @param	string
+ * @return	str
+ */	
+if ( ! function_exists('singular'))
+{	
+	function singular($str)
+	{
+		$str = strtolower(trim($str));
+		$end = substr($str, -3);
+	
+		if ($end == 'ies')
+		{
+			$str = substr($str, 0, strlen($str)-3).'y';
+		}
+		elseif ($end == 'ses')
+		{
+			$str = substr($str, 0, strlen($str)-2);
+		}
+		else
+		{
+			$end = substr($str, -1);
+		
+			if ($end == 's')
+			{
+				$str = substr($str, 0, strlen($str)-1);
+			}
+		}
+	
+		return $str;
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Plural
+ *
+ * Takes a singular word and makes it plural
+ *
+ * @access	public
+ * @param	string
+ * @param	bool
+ * @return	str
+ */	
+if ( ! function_exists('plural'))
+{	
+	function plural($str, $force = FALSE)
+	{
+		$str = strtolower(trim($str));
+		$end = substr($str, -1);
+
+		if ($end == 'y')
+		{
+			$str = substr($str, 0, strlen($str)-1).'ies';
+		}
+		elseif ($end == 's')
+		{
+			if ($force == TRUE)
+			{
+				$str .= 'es';
+			}
+		}
+		else
+		{
+			$str .= 's';
+		}
+
+		return $str;
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Camelize
+ *
+ * Takes multiple words separated by spaces or underscores and camelizes them
+ *
+ * @access	public
+ * @param	string
+ * @return	str
+ */	
+if ( ! function_exists('camelize'))
+{	
+	function camelize($str)
+	{		
+		$str = 'x'.strtolower(trim($str));
+		$str = ucwords(preg_replace('/[\s_]+/', ' ', $str));
+		return substr(str_replace(' ', '', $str), 1);
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Underscore
+ *
+ * Takes multiple words separated by spaces and underscores them
+ *
+ * @access	public
+ * @param	string
+ * @return	str
+ */	
+if ( ! function_exists('underscore'))
+{
+	function underscore($str)
+	{
+		return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Humanize
+ *
+ * Takes multiple words separated by underscores and changes them to spaces
+ *
+ * @access	public
+ * @param	string
+ * @return	str
+ */	
+if ( ! function_exists('humanize'))
+{	
+	function humanize($str)
+	{
+		return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));
+	}
+}
+	
+
+/* End of file inflector_helper.php */
 /* Location: ./system/helpers/inflector_helper.php */
\ No newline at end of file
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index d90fe31..2091fd4 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -1,58 +1,58 @@
-<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Language Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/language_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Lang

- *

- * Fetches a language variable and optionally outputs a form label

- *

- * @access	public

- * @param	string	the language line

- * @param	string	the id of the form element

- * @return	string

- */	

-if ( ! function_exists('lang'))

-{

-	function lang($line, $id = '')

-	{

-		$CI =& get_instance();

-		$line = $CI->lang->line($line);

-

-		if ($id != '')

-		{

-			$line = '<label for="'.$id.'">'.$line."</label>";

-		}

-

-		return $line;

-	}

-}

-

-// ------------------------------------------------------------------------

-/* End of file language_helper.php */

+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Language Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/language_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Lang
+ *
+ * Fetches a language variable and optionally outputs a form label
+ *
+ * @access	public
+ * @param	string	the language line
+ * @param	string	the id of the form element
+ * @return	string
+ */	
+if ( ! function_exists('lang'))
+{
+	function lang($line, $id = '')
+	{
+		$CI =& get_instance();
+		$line = $CI->lang->line($line);
+
+		if ($id != '')
+		{
+			$line = '<label for="'.$id.'">'.$line."</label>";
+		}
+
+		return $line;
+	}
+}
+
+// ------------------------------------------------------------------------
+/* End of file language_helper.php */
 /* Location: ./system/helpers/language_helper.php */
\ No newline at end of file
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 5b3ea1f..aeca8b2 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -1,75 +1,75 @@
-<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Number Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/number_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Formats a numbers as bytes, based on size, and adds the appropriate suffix

- *

- * @access	public

- * @param	mixed	// will be cast as int

- * @return	string

- */

-if ( ! function_exists('byte_format'))

-{

-	function byte_format($num)

-	{

-		$CI =& get_instance();

-		$CI->lang->load('number');

-	

-		if ($num >= 1000000000000) 

-		{

-			$num = round($num / 1099511627776, 1);

-			$unit = $CI->lang->line('terabyte_abbr');

-		}

-		elseif ($num >= 1000000000) 

-		{

-			$num = round($num / 1073741824, 1);

-			$unit = $CI->lang->line('gigabyte_abbr');

-		}

-		elseif ($num >= 1000000) 

-		{

-			$num = round($num / 1048576, 1);

-			$unit = $CI->lang->line('megabyte_abbr');

-		}

-		elseif ($num >= 1000) 

-		{

-			$num = round($num / 1024, 1);

-			$unit = $CI->lang->line('kilobyte_abbr');

-		}

-		else

-		{

-			$unit = $CI->lang->line('bytes');

-			return number_format($num).' '.$unit;

-		}

-

-		return number_format($num, 1).' '.$unit;

-	}	

-}

-

-/* End of file number_helper.php */

+<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Number Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/number_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Formats a numbers as bytes, based on size, and adds the appropriate suffix
+ *
+ * @access	public
+ * @param	mixed	// will be cast as int
+ * @return	string
+ */
+if ( ! function_exists('byte_format'))
+{
+	function byte_format($num)
+	{
+		$CI =& get_instance();
+		$CI->lang->load('number');
+	
+		if ($num >= 1000000000000) 
+		{
+			$num = round($num / 1099511627776, 1);
+			$unit = $CI->lang->line('terabyte_abbr');
+		}
+		elseif ($num >= 1000000000) 
+		{
+			$num = round($num / 1073741824, 1);
+			$unit = $CI->lang->line('gigabyte_abbr');
+		}
+		elseif ($num >= 1000000) 
+		{
+			$num = round($num / 1048576, 1);
+			$unit = $CI->lang->line('megabyte_abbr');
+		}
+		elseif ($num >= 1000) 
+		{
+			$num = round($num / 1024, 1);
+			$unit = $CI->lang->line('kilobyte_abbr');
+		}
+		else
+		{
+			$unit = $CI->lang->line('bytes');
+			return number_format($num).' '.$unit;
+		}
+
+		return number_format($num, 1).' '.$unit;
+	}	
+}
+
+/* End of file number_helper.php */
 /* Location: ./system/helpers/number_helper.php */
\ No newline at end of file
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index c5ee1fb..da5df98 100644
--- a/system/helpers/path_helper.php
+++ b/system/helpers/path_helper.php
@@ -1,72 +1,72 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Path Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/xml_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Set Realpath

- *

- * @access	public

- * @param	string

- * @param	bool	checks to see if the path exists

- * @return	string

- */	

-if ( ! function_exists('set_realpath'))

-{

-	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))

-		{

-			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)

-		{

-			$path = realpath($path).'/';

-		}

-	

-		// Add a trailing slash

-		$path = preg_replace("#([^/])/*$#", "\\1/", $path);

-	

-		// Make sure the path exists

-		if ($check_existance == TRUE)

-		{

-			if ( ! is_dir($path))

-			{

-				show_error('Not a valid path: '.$path);

-			}

-		}

-	

-		return $path;

-	}

-}

-

-

-/* End of file path_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Path Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/xml_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Realpath
+ *
+ * @access	public
+ * @param	string
+ * @param	bool	checks to see if the path exists
+ * @return	string
+ */	
+if ( ! function_exists('set_realpath'))
+{
+	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))
+		{
+			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)
+		{
+			$path = realpath($path).'/';
+		}
+	
+		// Add a trailing slash
+		$path = preg_replace("#([^/])/*$#", "\\1/", $path);
+	
+		// Make sure the path exists
+		if ($check_existance == TRUE)
+		{
+			if ( ! is_dir($path))
+			{
+				show_error('Not a valid path: '.$path);
+			}
+		}
+	
+		return $path;
+	}
+}
+
+
+/* End of file path_helper.php */
 /* Location: ./system/helpers/path_helper.php */
\ No newline at end of file
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index f2c5bac..0e2ba78 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -1,126 +1,126 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Security Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/security_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * XSS Filtering

- *

- * @access	public

- * @param	string

- * @param	string	the character set of your data

- * @return	string

- */	

-if ( ! function_exists('xss_clean'))

-{

-	function xss_clean($str, $charset = 'ISO-8859-1')

-	{

-		$CI =& get_instance();

-		return $CI->input->xss_clean($str, $charset);

-	}

-}

-

-// --------------------------------------------------------------------

-

-/**

- * Hash encode a string

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('dohash'))

-{	

-	function dohash($str, $type = 'sha1')

-	{

-		if ($type == 'sha1')

-		{

-			if ( ! function_exists('sha1'))

-			{

-				if ( ! function_exists('mhash'))

-				{	

-					require_once(BASEPATH.'libraries/Sha1'.EXT);

-					$SH = new CI_SHA;

-					return $SH->generate($str);

-				}

-				else

-				{

-					return bin2hex(mhash(MHASH_SHA1, $str));

-				}

-			}

-			else

-			{

-				return sha1($str);

-			}	

-		}

-		else

-		{

-			return md5($str);

-		}

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Strip Image Tags

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('strip_image_tags'))

-{

-	function strip_image_tags($str)

-	{

-		$str = preg_replace("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "\\1", $str);

-		$str = preg_replace("#<img\s+.*?src\s*=\s*(.+?).*?\>#", "\\1", $str);

-			

-		return $str;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Convert PHP tags to entities

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('encode_php_tags'))

-{

-	function encode_php_tags($str)

-	{

-		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);

-	}

-}

-

-

-/* End of file security_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Security Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/security_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * XSS Filtering
+ *
+ * @access	public
+ * @param	string
+ * @param	string	the character set of your data
+ * @return	string
+ */	
+if ( ! function_exists('xss_clean'))
+{
+	function xss_clean($str, $charset = 'ISO-8859-1')
+	{
+		$CI =& get_instance();
+		return $CI->input->xss_clean($str, $charset);
+	}
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Hash encode a string
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('dohash'))
+{	
+	function dohash($str, $type = 'sha1')
+	{
+		if ($type == 'sha1')
+		{
+			if ( ! function_exists('sha1'))
+			{
+				if ( ! function_exists('mhash'))
+				{	
+					require_once(BASEPATH.'libraries/Sha1'.EXT);
+					$SH = new CI_SHA;
+					return $SH->generate($str);
+				}
+				else
+				{
+					return bin2hex(mhash(MHASH_SHA1, $str));
+				}
+			}
+			else
+			{
+				return sha1($str);
+			}	
+		}
+		else
+		{
+			return md5($str);
+		}
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Image Tags
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('strip_image_tags'))
+{
+	function strip_image_tags($str)
+	{
+		$str = preg_replace("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "\\1", $str);
+		$str = preg_replace("#<img\s+.*?src\s*=\s*(.+?).*?\>#", "\\1", $str);
+			
+		return $str;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Convert PHP tags to entities
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('encode_php_tags'))
+{
+	function encode_php_tags($str)
+	{
+		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+	}
+}
+
+
+/* End of file security_helper.php */
 /* Location: ./system/helpers/security_helper.php */
\ No newline at end of file
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 51c9dd0..ce7eb8b 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_helper.php
@@ -1,175 +1,175 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Smiley Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/smiley_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * JS Insert Smiley

- *

- * Generates the javascrip function needed to insert smileys into a form field

- *

- * @access	public

- * @param	string	form name

- * @param	string	field name

- * @return	string

- */

-if ( ! function_exists('js_insert_smiley'))

-{

-	function js_insert_smiley($form_name = '', $form_field = '')

-	{

-		return <<<EOF

-<script type="text/javascript">

-	function insert_smiley(smiley)

-	{

-		document.{$form_name}.{$form_field}.value += " " + smiley;

-	}

-</script>

-EOF;

-	}

-}

-// ------------------------------------------------------------------------

-

-/**

- * Get Clickable Smileys

- *

- * Returns an array of image tag links that can be clicked to be inserted 

- * into a form field.  

- *

- * @access	public

- * @param	string	the URL to the folder containing the smiley images

- * @return	array

- */

-if ( ! function_exists('get_clickable_smileys'))

-{

-	function get_clickable_smileys($image_url = '', $smileys = NULL)

-	{

-		if ( ! is_array($smileys))

-		{

-			if (FALSE === ($smileys = _get_smiley_array()))

-			{

-				return $smileys;

-			}

-		}

-

-		// Add a trailing slash to the file path if needed

-		$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);

-

-		$used = array();

-		foreach ($smileys as $key => $val)

-		{

-			// Keep duplicates from being used, which can happen if the

-			// mapping array contains multiple identical replacements.  For example:

-			// :-) and :) might be replaced with the same image so both smileys

-			// will be in the array.

-			if (isset($used[$smileys[$key][0]]))

-			{

-				continue;

-			}

-

-			$link[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";

-

-			$used[$smileys[$key][0]] = TRUE;

-		}

-

-		return $link;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Parse Smileys

- *

- * Takes a string as input and swaps any contained smileys for the actual image

- *

- * @access	public

- * @param	string	the text to be parsed

- * @param	string	the URL to the folder containing the smiley images

- * @return	string

- */

-if ( ! function_exists('parse_smileys'))

-{

-	function parse_smileys($str = '', $image_url = '', $smileys = NULL)

-	{

-		if ($image_url == '')

-		{

-			return $str;

-		}

-

-		if ( ! is_array($smileys))

-		{

-			if (FALSE === ($smileys = _get_smiley_array()))

-			{

-				return $str;

-			}

-		}

-

-		// Add a trailing slash to the file path if needed

-		$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);

-

-		foreach ($smileys as $key => $val)

-		{

-			$str = str_replace($key, "<img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" />", $str);

-		}

-

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Get Smiley Array

- *

- * Fetches the config/smiley.php file

- *

- * @access	private

- * @return	mixed

- */

-if ( ! function_exists('_get_smiley_array'))

-{

-	function _get_smiley_array()

-	{

-		if ( ! file_exists(APPPATH.'config/smileys'.EXT))

-		{

-			return FALSE;

-		}

-

-		include(APPPATH.'config/smileys'.EXT);

-

-		if ( ! isset($smileys) OR ! is_array($smileys))

-		{

-			return FALSE;

-		}

-

-		return $smileys;

-	}

-}

-

-

-/* End of file smiley_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Smiley Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/smiley_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * JS Insert Smiley
+ *
+ * Generates the javascrip function needed to insert smileys into a form field
+ *
+ * @access	public
+ * @param	string	form name
+ * @param	string	field name
+ * @return	string
+ */
+if ( ! function_exists('js_insert_smiley'))
+{
+	function js_insert_smiley($form_name = '', $form_field = '')
+	{
+		return <<<EOF
+<script type="text/javascript">
+	function insert_smiley(smiley)
+	{
+		document.{$form_name}.{$form_field}.value += " " + smiley;
+	}
+</script>
+EOF;
+	}
+}
+// ------------------------------------------------------------------------
+
+/**
+ * Get Clickable Smileys
+ *
+ * Returns an array of image tag links that can be clicked to be inserted 
+ * into a form field.  
+ *
+ * @access	public
+ * @param	string	the URL to the folder containing the smiley images
+ * @return	array
+ */
+if ( ! function_exists('get_clickable_smileys'))
+{
+	function get_clickable_smileys($image_url = '', $smileys = NULL)
+	{
+		if ( ! is_array($smileys))
+		{
+			if (FALSE === ($smileys = _get_smiley_array()))
+			{
+				return $smileys;
+			}
+		}
+
+		// Add a trailing slash to the file path if needed
+		$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);
+
+		$used = array();
+		foreach ($smileys as $key => $val)
+		{
+			// Keep duplicates from being used, which can happen if the
+			// mapping array contains multiple identical replacements.  For example:
+			// :-) and :) might be replaced with the same image so both smileys
+			// will be in the array.
+			if (isset($used[$smileys[$key][0]]))
+			{
+				continue;
+			}
+
+			$link[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";
+
+			$used[$smileys[$key][0]] = TRUE;
+		}
+
+		return $link;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse Smileys
+ *
+ * Takes a string as input and swaps any contained smileys for the actual image
+ *
+ * @access	public
+ * @param	string	the text to be parsed
+ * @param	string	the URL to the folder containing the smiley images
+ * @return	string
+ */
+if ( ! function_exists('parse_smileys'))
+{
+	function parse_smileys($str = '', $image_url = '', $smileys = NULL)
+	{
+		if ($image_url == '')
+		{
+			return $str;
+		}
+
+		if ( ! is_array($smileys))
+		{
+			if (FALSE === ($smileys = _get_smiley_array()))
+			{
+				return $str;
+			}
+		}
+
+		// Add a trailing slash to the file path if needed
+		$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);
+
+		foreach ($smileys as $key => $val)
+		{
+			$str = str_replace($key, "<img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" />", $str);
+		}
+
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Smiley Array
+ *
+ * Fetches the config/smiley.php file
+ *
+ * @access	private
+ * @return	mixed
+ */
+if ( ! function_exists('_get_smiley_array'))
+{
+	function _get_smiley_array()
+	{
+		if ( ! file_exists(APPPATH.'config/smileys'.EXT))
+		{
+			return FALSE;
+		}
+
+		include(APPPATH.'config/smileys'.EXT);
+
+		if ( ! isset($smileys) OR ! is_array($smileys))
+		{
+			return FALSE;
+		}
+
+		return $smileys;
+	}
+}
+
+
+/* End of file smiley_helper.php */
 /* Location: ./system/helpers/smiley_helper.php */
\ No newline at end of file
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 4e376a8..319002e 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -1,273 +1,273 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter String Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/string_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Trim Slashes

- *

- * Removes any leading/traling slashes from a string:

- *

- * /this/that/theother/

- *

- * becomes:

- *

- * this/that/theother

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('trim_slashes'))

-{

-	function trim_slashes($str)

-	{

-		return trim($str, '/');

-	} 

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Strip Slashes

- *

- * Removes slashes contained in a string or in an array

- *

- * @access	public

- * @param	mixed	string or array

- * @return	mixed	string or array

- */	

-if ( ! function_exists('strip_slashes'))

-{

-	function strip_slashes($str)

-	{

-		if (is_array($str))

-		{	

-			foreach ($str as $key => $val)

-			{

-				$str[$key] = strip_slashes($val);

-			}

-		}

-		else

-		{

-			$str = stripslashes($str);

-		}

-	

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Strip Quotes

- *

- * Removes single and double quotes from a string

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('strip_quotes'))

-{

-	function strip_quotes($str)

-	{

-		return str_replace(array('"', "'"), '', $str);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Quotes to Entities

- *

- * Converts single and double quotes to entities

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('quotes_to_entities'))

-{

-	function quotes_to_entities($str)

-	{	

-		return str_replace(array("\'","\"","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $str);

-	}

-}

-

-// ------------------------------------------------------------------------

-/**

- * Reduce Double Slashes

- *

- * Converts double slashes in a string to a single slash,

- * except those found in http://

- *

- * http://www.some-site.com//index.php

- *

- * becomes:

- *

- * http://www.some-site.com/index.php

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('reduce_double_slashes'))

-{

-	function reduce_double_slashes($str)

-	{

-		return preg_replace("#([^:])//+#", "\\1/", $str);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Reduce Multiples

- *

- * Reduces multiple instances of a particular character.  Example:

- *

- * Fred, Bill,, Joe, Jimmy

- *

- * becomes:

- *

- * Fred, Bill, Joe, Jimmy

- *

- * @access	public

- * @param	string

- * @param	string	the character you wish to reduce

- * @param	bool	TRUE/FALSE - whether to trim the character from the beginning/end

- * @return	string

- */	

-if ( ! function_exists('reduce_multiples'))

-{

-	function reduce_multiples($str, $character = ',', $trim = FALSE)

-	{

-		$str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);

-

-		if ($trim === TRUE)

-		{

-			$str = trim($str, $character);

-		}

-

-		return $str;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Create a Random String

- *

- * Useful for generating passwords or hashes.

- *

- * @access	public

- * @param	string 	type of random string.  Options: alunum, numeric, nozero, unique

- * @param	integer	number of characters

- * @return	string

- */

-if ( ! function_exists('random_string'))

-{	

-	function random_string($type = 'alnum', $len = 8)

-	{					

-		switch($type)

-		{

-			case 'alnum'	:

-			case 'numeric'	:

-			case 'nozero'	:

-		

-					switch ($type)

-					{

-						case 'alnum'	:	$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

-							break;

-						case 'numeric'	:	$pool = '0123456789';

-							break;

-						case 'nozero'	:	$pool = '123456789';

-							break;

-					}

-

-					$str = '';

-					for ($i=0; $i < $len; $i++)

-					{

-						$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);

-					}

-					return $str;

-			  break;

-			case 'unique' : return md5(uniqid(mt_rand()));

-			  break;

-		}

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Alternator

- *

- * Allows strings to be alternated.  See docs...

- *

- * @access	public

- * @param	string (as many parameters as needed)

- * @return	string

- */	

-if ( ! function_exists('alternator'))

-{

-	function alternator()

-	{

-		static $i;	

-

-		if (func_num_args() == 0)

-		{

-			$i = 0;

-			return '';

-		}

-		$args = func_get_args();

-		return $args[($i++ % count($args))];

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Repeater function

- *

- * @access	public

- * @param	string

- * @param	integer	number of repeats

- * @return	string

- */	

-if ( ! function_exists('repeater'))

-{

-	function repeater($data, $num = 1)

-	{

-		return (($num > 0) ? str_repeat($data, $num) : '');

-	} 

-}

-

-

-/* End of file string_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter String Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/string_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Trim Slashes
+ *
+ * Removes any leading/traling slashes from a string:
+ *
+ * /this/that/theother/
+ *
+ * becomes:
+ *
+ * this/that/theother
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('trim_slashes'))
+{
+	function trim_slashes($str)
+	{
+		return trim($str, '/');
+	} 
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Slashes
+ *
+ * Removes slashes contained in a string or in an array
+ *
+ * @access	public
+ * @param	mixed	string or array
+ * @return	mixed	string or array
+ */	
+if ( ! function_exists('strip_slashes'))
+{
+	function strip_slashes($str)
+	{
+		if (is_array($str))
+		{	
+			foreach ($str as $key => $val)
+			{
+				$str[$key] = strip_slashes($val);
+			}
+		}
+		else
+		{
+			$str = stripslashes($str);
+		}
+	
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Quotes
+ *
+ * Removes single and double quotes from a string
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('strip_quotes'))
+{
+	function strip_quotes($str)
+	{
+		return str_replace(array('"', "'"), '', $str);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Quotes to Entities
+ *
+ * Converts single and double quotes to entities
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('quotes_to_entities'))
+{
+	function quotes_to_entities($str)
+	{	
+		return str_replace(array("\'","\"","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $str);
+	}
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Reduce Double Slashes
+ *
+ * Converts double slashes in a string to a single slash,
+ * except those found in http://
+ *
+ * http://www.some-site.com//index.php
+ *
+ * becomes:
+ *
+ * http://www.some-site.com/index.php
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('reduce_double_slashes'))
+{
+	function reduce_double_slashes($str)
+	{
+		return preg_replace("#([^:])//+#", "\\1/", $str);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Reduce Multiples
+ *
+ * Reduces multiple instances of a particular character.  Example:
+ *
+ * Fred, Bill,, Joe, Jimmy
+ *
+ * becomes:
+ *
+ * Fred, Bill, Joe, Jimmy
+ *
+ * @access	public
+ * @param	string
+ * @param	string	the character you wish to reduce
+ * @param	bool	TRUE/FALSE - whether to trim the character from the beginning/end
+ * @return	string
+ */	
+if ( ! function_exists('reduce_multiples'))
+{
+	function reduce_multiples($str, $character = ',', $trim = FALSE)
+	{
+		$str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
+
+		if ($trim === TRUE)
+		{
+			$str = trim($str, $character);
+		}
+
+		return $str;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Random String
+ *
+ * Useful for generating passwords or hashes.
+ *
+ * @access	public
+ * @param	string 	type of random string.  Options: alunum, numeric, nozero, unique
+ * @param	integer	number of characters
+ * @return	string
+ */
+if ( ! function_exists('random_string'))
+{	
+	function random_string($type = 'alnum', $len = 8)
+	{					
+		switch($type)
+		{
+			case 'alnum'	:
+			case 'numeric'	:
+			case 'nozero'	:
+		
+					switch ($type)
+					{
+						case 'alnum'	:	$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+							break;
+						case 'numeric'	:	$pool = '0123456789';
+							break;
+						case 'nozero'	:	$pool = '123456789';
+							break;
+					}
+
+					$str = '';
+					for ($i=0; $i < $len; $i++)
+					{
+						$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+					}
+					return $str;
+			  break;
+			case 'unique' : return md5(uniqid(mt_rand()));
+			  break;
+		}
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Alternator
+ *
+ * Allows strings to be alternated.  See docs...
+ *
+ * @access	public
+ * @param	string (as many parameters as needed)
+ * @return	string
+ */	
+if ( ! function_exists('alternator'))
+{
+	function alternator()
+	{
+		static $i;	
+
+		if (func_num_args() == 0)
+		{
+			$i = 0;
+			return '';
+		}
+		$args = func_get_args();
+		return $args[($i++ % count($args))];
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Repeater function
+ *
+ * @access	public
+ * @param	string
+ * @param	integer	number of repeats
+ * @return	string
+ */	
+if ( ! function_exists('repeater'))
+{
+	function repeater($data, $num = 1)
+	{
+		return (($num > 0) ? str_repeat($data, $num) : '');
+	} 
+}
+
+
+/* End of file string_helper.php */
 /* Location: ./system/helpers/string_helper.php */
\ No newline at end of file
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index 8a44608..6e61f77 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -1,443 +1,443 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Text Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/text_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Word Limiter

- *

- * Limits a string to X number of words.

- *

- * @access	public

- * @param	string

- * @param	integer

- * @param	string	the end character. Usually an ellipsis

- * @return	string

- */	

-if ( ! function_exists('word_limiter'))

-{

-	function word_limiter($str, $limit = 100, $end_char = '&#8230;')

-	{

-		if (trim($str) == '')

-		{

-			return $str;

-		}

-	

-		preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);

-			

-		if (strlen($str) == strlen($matches[0]))

-		{

-			$end_char = '';

-		}

-		

-		return rtrim($matches[0]).$end_char;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Character Limiter

- *

- * Limits the string based on the character count.  Preserves complete words

- * so the character count may not be exactly as specified.

- *

- * @access	public

- * @param	string

- * @param	integer

- * @param	string	the end character. Usually an ellipsis

- * @return	string

- */	

-if ( ! function_exists('character_limiter'))

-{

-	function character_limiter($str, $n = 500, $end_char = '&#8230;')

-	{

-		if (strlen($str) < $n)

-		{

-			return $str;

-		}

-		

-		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));

-

-		if (strlen($str) <= $n)

-		{

-			return $str;

-		}

-									

-		$out = "";

-		foreach (explode(' ', trim($str)) as $val)

-		{

-			$out .= $val.' ';			

-			if (strlen($out) >= $n)

-			{

-				return trim($out).$end_char;

-			}		

-		}

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * High ASCII to Entities

- *

- * Converts High ascii text and MS Word special characters to character entities

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('ascii_to_entities'))

-{

-	function ascii_to_entities($str)

-	{

-	   $count	= 1;

-	   $out	= '';

-	   $temp	= array();

-	

-	   for ($i = 0, $s = strlen($str); $i < $s; $i++)

-	   {

-		   $ordinal = ord($str[$i]);

-	

-		   if ($ordinal < 128)

-		   {

-			   $out .= $str[$i];

-		   }

-		   else

-		   {

-			   if (count($temp) == 0)

-			   {

-				   $count = ($ordinal < 224) ? 2 : 3;

-			   }

-		

-			   $temp[] = $ordinal;

-		

-			   if (count($temp) == $count)

-			   {

-				   $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);

-

-				   $out .= '&#'.$number.';';

-				   $count = 1;

-				   $temp = array();

-			   }

-		   }

-	   }

-

-	   return $out;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Entities to ASCII

- *

- * Converts character entities back to ASCII

- *

- * @access	public

- * @param	string

- * @param	bool

- * @return	string

- */	

-if ( ! function_exists('entities_to_ascii'))

-{

-	function entities_to_ascii($str, $all = TRUE)

-	{

-	   if (preg_match_all('/\&#(\d+)\;/', $str, $matches))

-	   {

-		   for ($i = 0, $s = count($matches['0']); $i < $s; $i++)

-		   {				

-			   $digits = $matches['1'][$i];

-

-			   $out = '';

-

-			   if ($digits < 128)

-			   {

-				   $out .= chr($digits);

-		

-			   }

-			   elseif ($digits < 2048)

-			   {

-				   $out .= chr(192 + (($digits - ($digits % 64)) / 64));

-				   $out .= chr(128 + ($digits % 64));

-			   }

-			   else

-			   {

-				   $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));

-				   $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));

-				   $out .= chr(128 + ($digits % 64));

-			   }

-

-			   $str = str_replace($matches['0'][$i], $out, $str);				

-		   }

-	   }

-

-	   if ($all)

-	   {

-		   $str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),

-							  array("&","<",">","\"", "'", "-"),

-							  $str);

-	   }

-

-	   return $str;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Word Censoring Function

- *

- * Supply a string and an array of disallowed words and any

- * matched words will be converted to #### or to the replacement

- * word you've submitted.

- *

- * @access	public

- * @param	string	the text string

- * @param	string	the array of censoered words

- * @param	string	the optional replacement value

- * @return	string

- */	

-if ( ! function_exists('word_censor'))

-{

-	function word_censor($str, $censored, $replacement = '')

-	{

-		if ( ! is_array($censored))

-		{

-			return $str;

-		}

-

-		$str = ' '.$str.' ';

-		foreach ($censored as $badword)

-		{

-			if ($replacement != '')

-			{

-				$str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/i", $replacement, $str);

-			}

-			else

-			{

-				$str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);

-			}

-		}

-	

-		return trim($str);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Code Highlighter

- *

- * Colorizes code strings

- *

- * @access	public

- * @param	string	the text string

- * @return	string

- */	

-if ( ! function_exists('highlight_code'))

-{

-	function highlight_code($str)

-	{		

-		// The highlight string function encodes and highlights

-		// brackets so we need them to start raw

-		$str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);

-	

-		// Replace any existing PHP tags to temporary markers so they don't accidentally

-		// break the string out of PHP, and thus, thwart the highlighting.

-	

-		$str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'), 

-							array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);

-

-		// The highlight_string function requires that the text be surrounded

-		// by PHP tags, which we will remove later

-		$str = '<?php '.$str.' ?>'; // <?

-

-		// All the magic happens here, baby!	

-		$str = highlight_string($str, TRUE);

-

-		// Prior to PHP 5, the highligh function used icky <font> tags

-		// so we'll replace them with <span> tags.

-

-		if (abs(PHP_VERSION) < 5)

-		{

-			$str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);

-			$str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);

-		}

-		

-		// Remove our artificially added PHP, and the syntax highlighting that came with it

-		$str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);

-		$str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);

-		$str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);

-			

-		// Replace our markers back to PHP tags.

-		$str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),

-							array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);

-										

-		return $str;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Phrase Highlighter

- *

- * Highlights a phrase within a text string

- *

- * @access	public

- * @param	string	the text string

- * @param	string	the phrase you'd like to highlight

- * @param	string	the openging tag to precede the phrase with

- * @param	string	the closing tag to end the phrase with

- * @return	string

- */	

-if ( ! function_exists('highlight_phrase'))

-{

-	function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')

-	{

-		if ($str == '')

-		{

-			return '';

-		}

-	

-		if ($phrase != '')

-		{

-			return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);

-		}

-

-		return $str;

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Word Wrap

- *

- * Wraps text at the specified character.  Maintains the integrity of words.

- * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor

- * will URLs.

- *

- * @access	public

- * @param	string	the text string

- * @param	integer	the number of characters to wrap at

- * @return	string

- */	

-if ( ! function_exists('word_wrap'))

-{

-	function word_wrap($str, $charlim = '76')

-	{

-		// Se the character limit

-		if ( ! is_numeric($charlim))

-			$charlim = 76;

-	

-		// Reduce multiple spaces

-		$str = preg_replace("| +|", " ", $str);

-	

-		// Standardize newlines

-		if (strpos($str, "\r") !== FALSE)

-		{

-			$str = str_replace(array("\r\n", "\r"), "\n", $str);			

-		}

-	

-		// If the current word is surrounded by {unwrap} tags we'll 

-		// strip the entire chunk and replace it with a marker.

-		$unwrap = array();

-		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))

-		{

-			for ($i = 0; $i < count($matches['0']); $i++)

-			{

-				$unwrap[] = $matches['1'][$i];				

-				$str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);

-			}

-		}

-	

-		// Use PHP's native function to do the initial wordwrap.  

-		// We set the cut flag to FALSE so that any individual words that are 

-		// too long get left alone.  In the next step we'll deal with them.

-		$str = wordwrap($str, $charlim, "\n", FALSE);

-	

-		// Split the string into individual lines of text and cycle through them

-		$output = "";

-		foreach (explode("\n", $str) as $line) 

-		{

-			// Is the line within the allowed character count?

-			// If so we'll join it to the output and continue

-			if (strlen($line) <= $charlim)

-			{

-				$output .= $line."\n";			

-				continue;

-			}

-			

-			$temp = '';

-			while((strlen($line)) > $charlim) 

-			{

-				// If the over-length word is a URL we won't wrap it

-				if (preg_match("!\[url.+\]|://|wwww.!", $line))

-				{

-					break;

-				}

-

-				// Trim the word down

-				$temp .= substr($line, 0, $charlim-1);

-				$line = substr($line, $charlim-1);

-			}

-		

-			// If $temp contains data it means we had to split up an over-length 

-			// word into smaller chunks so we'll add it back to our current line

-			if ($temp != '')

-			{

-				$output .= $temp . "\n" . $line; 

-			}

-			else

-			{

-				$output .= $line;

-			}

-

-			$output .= "\n";

-		}

-

-		// Put our markers back

-		if (count($unwrap) > 0)

-		{	

-			foreach ($unwrap as $key => $val)

-			{

-				$output = str_replace("{{unwrapped".$key."}}", $val, $output);

-			}

-		}

-

-		// Remove the unwrap tags

-		$output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);

-

-		return $output;	

-	}

-}

-

-

-/* End of file text_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Text Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/text_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Limiter
+ *
+ * Limits a string to X number of words.
+ *
+ * @access	public
+ * @param	string
+ * @param	integer
+ * @param	string	the end character. Usually an ellipsis
+ * @return	string
+ */	
+if ( ! function_exists('word_limiter'))
+{
+	function word_limiter($str, $limit = 100, $end_char = '&#8230;')
+	{
+		if (trim($str) == '')
+		{
+			return $str;
+		}
+	
+		preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
+			
+		if (strlen($str) == strlen($matches[0]))
+		{
+			$end_char = '';
+		}
+		
+		return rtrim($matches[0]).$end_char;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Character Limiter
+ *
+ * Limits the string based on the character count.  Preserves complete words
+ * so the character count may not be exactly as specified.
+ *
+ * @access	public
+ * @param	string
+ * @param	integer
+ * @param	string	the end character. Usually an ellipsis
+ * @return	string
+ */	
+if ( ! function_exists('character_limiter'))
+{
+	function character_limiter($str, $n = 500, $end_char = '&#8230;')
+	{
+		if (strlen($str) < $n)
+		{
+			return $str;
+		}
+		
+		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+
+		if (strlen($str) <= $n)
+		{
+			return $str;
+		}
+									
+		$out = "";
+		foreach (explode(' ', trim($str)) as $val)
+		{
+			$out .= $val.' ';			
+			if (strlen($out) >= $n)
+			{
+				return trim($out).$end_char;
+			}		
+		}
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * High ASCII to Entities
+ *
+ * Converts High ascii text and MS Word special characters to character entities
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('ascii_to_entities'))
+{
+	function ascii_to_entities($str)
+	{
+	   $count	= 1;
+	   $out	= '';
+	   $temp	= array();
+	
+	   for ($i = 0, $s = strlen($str); $i < $s; $i++)
+	   {
+		   $ordinal = ord($str[$i]);
+	
+		   if ($ordinal < 128)
+		   {
+			   $out .= $str[$i];
+		   }
+		   else
+		   {
+			   if (count($temp) == 0)
+			   {
+				   $count = ($ordinal < 224) ? 2 : 3;
+			   }
+		
+			   $temp[] = $ordinal;
+		
+			   if (count($temp) == $count)
+			   {
+				   $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+
+				   $out .= '&#'.$number.';';
+				   $count = 1;
+				   $temp = array();
+			   }
+		   }
+	   }
+
+	   return $out;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Entities to ASCII
+ *
+ * Converts character entities back to ASCII
+ *
+ * @access	public
+ * @param	string
+ * @param	bool
+ * @return	string
+ */	
+if ( ! function_exists('entities_to_ascii'))
+{
+	function entities_to_ascii($str, $all = TRUE)
+	{
+	   if (preg_match_all('/\&#(\d+)\;/', $str, $matches))
+	   {
+		   for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
+		   {				
+			   $digits = $matches['1'][$i];
+
+			   $out = '';
+
+			   if ($digits < 128)
+			   {
+				   $out .= chr($digits);
+		
+			   }
+			   elseif ($digits < 2048)
+			   {
+				   $out .= chr(192 + (($digits - ($digits % 64)) / 64));
+				   $out .= chr(128 + ($digits % 64));
+			   }
+			   else
+			   {
+				   $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
+				   $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
+				   $out .= chr(128 + ($digits % 64));
+			   }
+
+			   $str = str_replace($matches['0'][$i], $out, $str);				
+		   }
+	   }
+
+	   if ($all)
+	   {
+		   $str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),
+							  array("&","<",">","\"", "'", "-"),
+							  $str);
+	   }
+
+	   return $str;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Word Censoring Function
+ *
+ * Supply a string and an array of disallowed words and any
+ * matched words will be converted to #### or to the replacement
+ * word you've submitted.
+ *
+ * @access	public
+ * @param	string	the text string
+ * @param	string	the array of censoered words
+ * @param	string	the optional replacement value
+ * @return	string
+ */	
+if ( ! function_exists('word_censor'))
+{
+	function word_censor($str, $censored, $replacement = '')
+	{
+		if ( ! is_array($censored))
+		{
+			return $str;
+		}
+
+		$str = ' '.$str.' ';
+		foreach ($censored as $badword)
+		{
+			if ($replacement != '')
+			{
+				$str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/i", $replacement, $str);
+			}
+			else
+			{
+				$str = preg_replace("/\b(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")\b/ie", "str_repeat('#', strlen('\\1'))", $str);
+			}
+		}
+	
+		return trim($str);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Code Highlighter
+ *
+ * Colorizes code strings
+ *
+ * @access	public
+ * @param	string	the text string
+ * @return	string
+ */	
+if ( ! function_exists('highlight_code'))
+{
+	function highlight_code($str)
+	{		
+		// The highlight string function encodes and highlights
+		// brackets so we need them to start raw
+		$str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);
+	
+		// Replace any existing PHP tags to temporary markers so they don't accidentally
+		// break the string out of PHP, and thus, thwart the highlighting.
+	
+		$str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'), 
+							array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);
+
+		// The highlight_string function requires that the text be surrounded
+		// by PHP tags, which we will remove later
+		$str = '<?php '.$str.' ?>'; // <?
+
+		// All the magic happens here, baby!	
+		$str = highlight_string($str, TRUE);
+
+		// Prior to PHP 5, the highligh function used icky <font> tags
+		// so we'll replace them with <span> tags.
+
+		if (abs(PHP_VERSION) < 5)
+		{
+			$str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
+			$str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
+		}
+		
+		// Remove our artificially added PHP, and the syntax highlighting that came with it
+		$str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);
+		$str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);
+		$str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);
+			
+		// Replace our markers back to PHP tags.
+		$str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+							array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);
+										
+		return $str;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Phrase Highlighter
+ *
+ * Highlights a phrase within a text string
+ *
+ * @access	public
+ * @param	string	the text string
+ * @param	string	the phrase you'd like to highlight
+ * @param	string	the openging tag to precede the phrase with
+ * @param	string	the closing tag to end the phrase with
+ * @return	string
+ */	
+if ( ! function_exists('highlight_phrase'))
+{
+	function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
+	{
+		if ($str == '')
+		{
+			return '';
+		}
+	
+		if ($phrase != '')
+		{
+			return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
+		}
+
+		return $str;
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Word Wrap
+ *
+ * Wraps text at the specified character.  Maintains the integrity of words.
+ * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
+ * will URLs.
+ *
+ * @access	public
+ * @param	string	the text string
+ * @param	integer	the number of characters to wrap at
+ * @return	string
+ */	
+if ( ! function_exists('word_wrap'))
+{
+	function word_wrap($str, $charlim = '76')
+	{
+		// Se the character limit
+		if ( ! is_numeric($charlim))
+			$charlim = 76;
+	
+		// Reduce multiple spaces
+		$str = preg_replace("| +|", " ", $str);
+	
+		// Standardize newlines
+		if (strpos($str, "\r") !== FALSE)
+		{
+			$str = str_replace(array("\r\n", "\r"), "\n", $str);			
+		}
+	
+		// If the current word is surrounded by {unwrap} tags we'll 
+		// strip the entire chunk and replace it with a marker.
+		$unwrap = array();
+		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+		{
+			for ($i = 0; $i < count($matches['0']); $i++)
+			{
+				$unwrap[] = $matches['1'][$i];				
+				$str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+			}
+		}
+	
+		// Use PHP's native function to do the initial wordwrap.  
+		// We set the cut flag to FALSE so that any individual words that are 
+		// too long get left alone.  In the next step we'll deal with them.
+		$str = wordwrap($str, $charlim, "\n", FALSE);
+	
+		// Split the string into individual lines of text and cycle through them
+		$output = "";
+		foreach (explode("\n", $str) as $line) 
+		{
+			// Is the line within the allowed character count?
+			// If so we'll join it to the output and continue
+			if (strlen($line) <= $charlim)
+			{
+				$output .= $line."\n";			
+				continue;
+			}
+			
+			$temp = '';
+			while((strlen($line)) > $charlim) 
+			{
+				// If the over-length word is a URL we won't wrap it
+				if (preg_match("!\[url.+\]|://|wwww.!", $line))
+				{
+					break;
+				}
+
+				// Trim the word down
+				$temp .= substr($line, 0, $charlim-1);
+				$line = substr($line, $charlim-1);
+			}
+		
+			// If $temp contains data it means we had to split up an over-length 
+			// word into smaller chunks so we'll add it back to our current line
+			if ($temp != '')
+			{
+				$output .= $temp . "\n" . $line; 
+			}
+			else
+			{
+				$output .= $line;
+			}
+
+			$output .= "\n";
+		}
+
+		// Put our markers back
+		if (count($unwrap) > 0)
+		{	
+			foreach ($unwrap as $key => $val)
+			{
+				$output = str_replace("{{unwrapped".$key."}}", $val, $output);
+			}
+		}
+
+		// Remove the unwrap tags
+		$output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
+
+		return $output;	
+	}
+}
+
+
+/* End of file text_helper.php */
 /* Location: ./system/helpers/text_helper.php */
\ No newline at end of file
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index d3cc7f1..46fe6bf 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -1,71 +1,71 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Typography Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/typography_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Convert newlines to HTML line breaks except within PRE tags

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('nl2br_except_pre'))

-{

-	function nl2br_except_pre($str)

-	{

-		$CI =& get_instance();

-	

-		$CI->load->library('typography');

-		

-		return $CI->typography->nl2br_except_pre($str);

-	}

-}

-	

-// ------------------------------------------------------------------------

-

-/**

- * Auto Typography Wrapper Function

- *

- *

- * @access	public

- * @param	string

- * @param	bool	whether to reduce multiple instances of double newlines to two

- * @return	string

- */

-if ( ! function_exists('auto_typography'))

-{

-	function auto_typography($str, $reduce_linebreaks = FALSE)

-	{

-		$CI =& get_instance();	

-		$CI->load->library('typography');

-		return $CI->typography->auto_typography($str, $reduce_linebreaks);

-	}

-}

-

-/* End of file typography_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Typography Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/typography_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert newlines to HTML line breaks except within PRE tags
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('nl2br_except_pre'))
+{
+	function nl2br_except_pre($str)
+	{
+		$CI =& get_instance();
+	
+		$CI->load->library('typography');
+		
+		return $CI->typography->nl2br_except_pre($str);
+	}
+}
+	
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Wrapper Function
+ *
+ *
+ * @access	public
+ * @param	string
+ * @param	bool	whether to reduce multiple instances of double newlines to two
+ * @return	string
+ */
+if ( ! function_exists('auto_typography'))
+{
+	function auto_typography($str, $reduce_linebreaks = FALSE)
+	{
+		$CI =& get_instance();	
+		$CI->load->library('typography');
+		return $CI->typography->auto_typography($str, $reduce_linebreaks);
+	}
+}
+
+/* End of file typography_helper.php */
 /* Location: ./system/helpers/typography_helper.php */
\ No newline at end of file
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 744295f..fd13dc2 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -1,582 +1,582 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter URL Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/url_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Site URL

- *

- * Create a local URL based on your basepath. Segments can be passed via the

- * first parameter either as a string or an array.

- *

- * @access	public

- * @param	string

- * @return	string

- */

-if ( ! function_exists('site_url'))

-{

-	function site_url($uri = '')

-	{

-		$CI =& get_instance();

-		return $CI->config->site_url($uri);

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Base URL

- *

- * Returns the "base_url" item from your config file

- *

- * @access	public

- * @return	string

- */

-if ( ! function_exists('base_url'))

-{

-	function base_url()

-	{

-		$CI =& get_instance();

-		return $CI->config->slash_item('base_url');

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Current URL

- *

- * Returns the full URL (including segments) of the page where this 

- * function is placed

- *

- * @access	public

- * @return	string

- */

-if ( ! function_exists('current_url'))

-{

-	function current_url()

-	{

-		$CI =& get_instance();

-		return $CI->config->site_url($CI->uri->uri_string());

-	}

-}

-

-// ------------------------------------------------------------------------

-/**

- * URL String

- *

- * Returns the URI segments.

- *

- * @access	public

- * @return	string

- */

-if ( ! function_exists('uri_string'))

-{

-	function uri_string()

-	{

-		$CI =& get_instance();

-		return $CI->uri->uri_string();

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Index page

- *

- * Returns the "index_page" from your config file

- *

- * @access	public

- * @return	string

- */

-if ( ! function_exists('index_page'))

-{

-	function index_page()

-	{

-		$CI =& get_instance();

-		return $CI->config->item('index_page');

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Anchor Link

- *

- * Creates an anchor based on the local URL.

- *

- * @access	public

- * @param	string	the URL

- * @param	string	the link title

- * @param	mixed	any attributes

- * @return	string

- */

-if ( ! function_exists('anchor'))

-{

-	function anchor($uri = '', $title = '', $attributes = '')

-	{

-		$title = (string) $title;

-

-		if ( ! is_array($uri))

-		{

-			$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;

-		}

-		else

-		{

-			$site_url = site_url($uri);

-		}

-

-		if ($title == '')

-		{

-			$title = $site_url;

-		}

-

-		if ($attributes != '')

-		{

-			$attributes = _parse_attributes($attributes);

-		}

-

-		return '<a href="'.$site_url.'"'.$attributes.'>'.$title.'</a>';

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Anchor Link - Pop-up version

- *

- * Creates an anchor based on the local URL. The link

- * opens a new window based on the attributes specified.

- *

- * @access	public

- * @param	string	the URL

- * @param	string	the link title

- * @param	mixed	any attributes

- * @return	string

- */

-if ( ! function_exists('anchor_popup'))

-{

-	function anchor_popup($uri = '', $title = '', $attributes = FALSE)

-	{

-		$title = (string) $title;

-

-		$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;

-

-		if ($title == '')

-		{

-			$title = $site_url;

-		}

-

-		if ($attributes === FALSE)

-		{

-			return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title."</a>";

-		}

-

-		if ( ! is_array($attributes))

-		{

-			$attributes = array();

-		}

-

-		foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)

-		{

-			$atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];

-			unset($attributes[$key]);

-		}

-

-		if ($attributes != '')

-		{

-			$attributes = _parse_attributes($attributes);

-		}

-

-		return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"$attributes>".$title."</a>";

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Mailto Link

- *

- * @access	public

- * @param	string	the email address

- * @param	string	the link title

- * @param	mixed 	any attributes

- * @return	string

- */

-if ( ! function_exists('mailto'))

-{

-	function mailto($email, $title = '', $attributes = '')

-	{

-		$title = (string) $title;

-

-		if ($title == "")

-		{

-			$title = $email;

-		}

-

-		$attributes = _parse_attributes($attributes);

-

-		return '<a href="mailto:'.$email.'"'.$attributes.'>'.$title.'</a>';

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Encoded Mailto Link

- *

- * Create a spam-protected mailto link written in Javascript

- *

- * @access	public

- * @param	string	the email address

- * @param	string	the link title

- * @param	mixed 	any attributes

- * @return	string

- */

-if ( ! function_exists('safe_mailto'))

-{

-	function safe_mailto($email, $title = '', $attributes = '')

-	{

-		$title = (string) $title;

-

-		if ($title == "")

-		{

-			$title = $email;

-		}

-

-		for ($i = 0; $i < 16; $i++)

-		{

-			$x[] = substr('<a href="mailto:', $i, 1);

-		}

-

-		for ($i = 0; $i < strlen($email); $i++)

-		{

-			$x[] = "|".ord(substr($email, $i, 1));

-		}

-

-		$x[] = '"';

-

-		if ($attributes != '')

-		{

-			if (is_array($attributes))

-			{

-				foreach ($attributes as $key => $val)

-				{

-					$x[] =  ' '.$key.'="';

-					for ($i = 0; $i < strlen($val); $i++)

-					{

-						$x[] = "|".ord(substr($val, $i, 1));

-					}

-					$x[] = '"';

-				}

-			}

-			else

-			{

-				for ($i = 0; $i < strlen($attributes); $i++)

-				{

-					$x[] = substr($attributes, $i, 1);

-				}

-			}

-		}

-

-		$x[] = '>';

-

-		$temp = array();

-		for ($i = 0; $i < strlen($title); $i++)

-		{

-			$ordinal = ord($title[$i]);

-

-			if ($ordinal < 128)

-			{

-				$x[] = "|".$ordinal;

-			}

-			else

-			{

-				if (count($temp) == 0)

-				{

-					$count = ($ordinal < 224) ? 2 : 3;

-				}

-	

-				$temp[] = $ordinal;

-				if (count($temp) == $count)

-				{

-					$number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);

-					$x[] = "|".$number;

-					$count = 1;

-					$temp = array();

-				}

-			}

-		}

-

-		$x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>';

-

-		$x = array_reverse($x);

-		ob_start();

-

-	?><script type="text/javascript">

-	//<![CDATA[

-	var l=new Array();

-	<?php

-	$i = 0;

-	foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>

-

-	for (var i = l.length-1; i >= 0; i=i-1){

-	if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");

-	else document.write(unescape(l[i]));}

-	//]]>

-	</script><?php

-

-		$buffer = ob_get_contents();

-		ob_end_clean();

-		return $buffer;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Auto-linker

- *

- * Automatically links URL and Email addresses.

- * Note: There's a bit of extra code here to deal with

- * URLs or emails that end in a period.  We'll strip these

- * off and add them after the link.

- *

- * @access	public

- * @param	string	the string

- * @param	string	the type: email, url, or both

- * @param	bool 	whether to create pop-up links

- * @return	string

- */

-if ( ! function_exists('auto_link'))

-{

-	function auto_link($str, $type = 'both', $popup = FALSE)

-	{

-		if ($type != 'email')

-		{

-			if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))

-			{

-				$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

-	

-				for ($i = 0; $i < sizeof($matches['0']); $i++)

-				{

-					$period = '';

-					if (preg_match("|\.$|", $matches['6'][$i]))

-					{

-						$period = '.';

-						$matches['6'][$i] = substr($matches['6'][$i], 0, -1);

-					}

-		

-					$str = str_replace($matches['0'][$i],

-										$matches['1'][$i].'<a href="http'.

-										$matches['4'][$i].'://'.

-										$matches['5'][$i].

-										$matches['6'][$i].'"'.$pop.'>http'.

-										$matches['4'][$i].'://'.

-										$matches['5'][$i].

-										$matches['6'][$i].'</a>'.

-										$period, $str);

-				}

-			}

-		}

-

-		if ($type != 'url')

-		{

-			if (preg_match_all("/([a-zA-Z0-9_\.\-\+Å]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))

-			{

-				for ($i = 0; $i < sizeof($matches['0']); $i++)

-				{

-					$period = '';

-					if (preg_match("|\.$|", $matches['3'][$i]))

-					{

-						$period = '.';

-						$matches['3'][$i] = substr($matches['3'][$i], 0, -1);

-					}

-		

-					$str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);

-				}

-			}

-		}

-

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Prep URL

- *

- * Simply adds the http:// part if missing

- *

- * @access	public

- * @param	string	the URL

- * @return	string

- */

-if ( ! function_exists('prep_url'))

-{

-	function prep_url($str = '')

-	{

-		if ($str == 'http://' OR $str == '')

-		{

-			return '';

-		}

-

-		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')

-		{

-			$str = 'http://'.$str;

-		}

-

-		return $str;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Create URL Title

- *

- * Takes a "title" string as input and creates a

- * human-friendly URL string with either a dash

- * or an underscore as the word separator.

- *

- * @access	public

- * @param	string	the string

- * @param	string	the separator: dash, or underscore

- * @return	string

- */

-if ( ! function_exists('url_title'))

-{

-	function url_title($str, $separator = 'dash')

-	{

-		if ($separator == 'dash')

-		{

-			$search		= '_';

-			$replace	= '-';

-		}

-		else

-		{

-			$search		= '-';

-			$replace	= '_';

-		}

-

-		$trans = array(

-						'&\#\d+?;'				=> '',

-						'&\S+?;'				=> '',

-						'\s+'					=> $replace,

-						'[^a-z0-9\-\._]'		=> '',

-						$replace.'+'			=> $replace,

-						$replace.'$'			=> $replace,

-						'^'.$replace			=> $replace

-					  );

-

-		$str = strip_tags($str);

-

-		foreach ($trans as $key => $val)

-		{

-			$str = preg_replace("#".$key."#i", $val, $str);

-		}

-

-		return trim(stripslashes($str));

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Header Redirect

- *

- * Header redirect in two flavors

- * For very fine grained control over headers, you could use the Output

- * Library's set_header() function.

- *

- * @access	public

- * @param	string	the URL

- * @param	string	the method: location or redirect

- * @return	string

- */

-if ( ! function_exists('redirect'))

-{

-	function redirect($uri = '', $method = 'location', $http_response_code = 302)

-	{

-		switch($method)

-		{

-			case 'refresh'	: header("Refresh:0;url=".site_url($uri));

-				break;

-			default			: header("Location: ".site_url($uri), TRUE, $http_response_code);

-				break;

-		}

-		exit;

-	}

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * Parse out the attributes

- *

- * Some of the functions use this

- *

- * @access	private

- * @param	array

- * @param	bool

- * @return	string

- */

-if ( ! function_exists('_parse_attributes'))

-{

-	function _parse_attributes($attributes, $javascript = FALSE)

-	{

-		if (is_string($attributes))

-		{

-			return ($attributes != '') ? ' '.$attributes : '';

-		}

-

-		$att = '';

-		foreach ($attributes as $key => $val)

-		{

-			if ($javascript == TRUE)

-			{

-				$att .= $key . '=' . $val . ',';

-			}

-			else

-			{

-				$att .= ' ' . $key . '="' . $val . '"';

-			}

-		}

-

-		if ($javascript == TRUE AND $att != '')

-		{

-			$att = substr($att, 0, -1);

-		}

-

-		return $att;

-	}

-}

-

-

-/* End of file url_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter URL Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/url_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Site URL
+ *
+ * Create a local URL based on your basepath. Segments can be passed via the
+ * first parameter either as a string or an array.
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */
+if ( ! function_exists('site_url'))
+{
+	function site_url($uri = '')
+	{
+		$CI =& get_instance();
+		return $CI->config->site_url($uri);
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Base URL
+ *
+ * Returns the "base_url" item from your config file
+ *
+ * @access	public
+ * @return	string
+ */
+if ( ! function_exists('base_url'))
+{
+	function base_url()
+	{
+		$CI =& get_instance();
+		return $CI->config->slash_item('base_url');
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Current URL
+ *
+ * Returns the full URL (including segments) of the page where this 
+ * function is placed
+ *
+ * @access	public
+ * @return	string
+ */
+if ( ! function_exists('current_url'))
+{
+	function current_url()
+	{
+		$CI =& get_instance();
+		return $CI->config->site_url($CI->uri->uri_string());
+	}
+}
+
+// ------------------------------------------------------------------------
+/**
+ * URL String
+ *
+ * Returns the URI segments.
+ *
+ * @access	public
+ * @return	string
+ */
+if ( ! function_exists('uri_string'))
+{
+	function uri_string()
+	{
+		$CI =& get_instance();
+		return $CI->uri->uri_string();
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Index page
+ *
+ * Returns the "index_page" from your config file
+ *
+ * @access	public
+ * @return	string
+ */
+if ( ! function_exists('index_page'))
+{
+	function index_page()
+	{
+		$CI =& get_instance();
+		return $CI->config->item('index_page');
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Anchor Link
+ *
+ * Creates an anchor based on the local URL.
+ *
+ * @access	public
+ * @param	string	the URL
+ * @param	string	the link title
+ * @param	mixed	any attributes
+ * @return	string
+ */
+if ( ! function_exists('anchor'))
+{
+	function anchor($uri = '', $title = '', $attributes = '')
+	{
+		$title = (string) $title;
+
+		if ( ! is_array($uri))
+		{
+			$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+		}
+		else
+		{
+			$site_url = site_url($uri);
+		}
+
+		if ($title == '')
+		{
+			$title = $site_url;
+		}
+
+		if ($attributes != '')
+		{
+			$attributes = _parse_attributes($attributes);
+		}
+
+		return '<a href="'.$site_url.'"'.$attributes.'>'.$title.'</a>';
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Anchor Link - Pop-up version
+ *
+ * Creates an anchor based on the local URL. The link
+ * opens a new window based on the attributes specified.
+ *
+ * @access	public
+ * @param	string	the URL
+ * @param	string	the link title
+ * @param	mixed	any attributes
+ * @return	string
+ */
+if ( ! function_exists('anchor_popup'))
+{
+	function anchor_popup($uri = '', $title = '', $attributes = FALSE)
+	{
+		$title = (string) $title;
+
+		$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+
+		if ($title == '')
+		{
+			$title = $site_url;
+		}
+
+		if ($attributes === FALSE)
+		{
+			return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title."</a>";
+		}
+
+		if ( ! is_array($attributes))
+		{
+			$attributes = array();
+		}
+
+		foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)
+		{
+			$atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];
+			unset($attributes[$key]);
+		}
+
+		if ($attributes != '')
+		{
+			$attributes = _parse_attributes($attributes);
+		}
+
+		return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"$attributes>".$title."</a>";
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Mailto Link
+ *
+ * @access	public
+ * @param	string	the email address
+ * @param	string	the link title
+ * @param	mixed 	any attributes
+ * @return	string
+ */
+if ( ! function_exists('mailto'))
+{
+	function mailto($email, $title = '', $attributes = '')
+	{
+		$title = (string) $title;
+
+		if ($title == "")
+		{
+			$title = $email;
+		}
+
+		$attributes = _parse_attributes($attributes);
+
+		return '<a href="mailto:'.$email.'"'.$attributes.'>'.$title.'</a>';
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Encoded Mailto Link
+ *
+ * Create a spam-protected mailto link written in Javascript
+ *
+ * @access	public
+ * @param	string	the email address
+ * @param	string	the link title
+ * @param	mixed 	any attributes
+ * @return	string
+ */
+if ( ! function_exists('safe_mailto'))
+{
+	function safe_mailto($email, $title = '', $attributes = '')
+	{
+		$title = (string) $title;
+
+		if ($title == "")
+		{
+			$title = $email;
+		}
+
+		for ($i = 0; $i < 16; $i++)
+		{
+			$x[] = substr('<a href="mailto:', $i, 1);
+		}
+
+		for ($i = 0; $i < strlen($email); $i++)
+		{
+			$x[] = "|".ord(substr($email, $i, 1));
+		}
+
+		$x[] = '"';
+
+		if ($attributes != '')
+		{
+			if (is_array($attributes))
+			{
+				foreach ($attributes as $key => $val)
+				{
+					$x[] =  ' '.$key.'="';
+					for ($i = 0; $i < strlen($val); $i++)
+					{
+						$x[] = "|".ord(substr($val, $i, 1));
+					}
+					$x[] = '"';
+				}
+			}
+			else
+			{
+				for ($i = 0; $i < strlen($attributes); $i++)
+				{
+					$x[] = substr($attributes, $i, 1);
+				}
+			}
+		}
+
+		$x[] = '>';
+
+		$temp = array();
+		for ($i = 0; $i < strlen($title); $i++)
+		{
+			$ordinal = ord($title[$i]);
+
+			if ($ordinal < 128)
+			{
+				$x[] = "|".$ordinal;
+			}
+			else
+			{
+				if (count($temp) == 0)
+				{
+					$count = ($ordinal < 224) ? 2 : 3;
+				}
+	
+				$temp[] = $ordinal;
+				if (count($temp) == $count)
+				{
+					$number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+					$x[] = "|".$number;
+					$count = 1;
+					$temp = array();
+				}
+			}
+		}
+
+		$x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>';
+
+		$x = array_reverse($x);
+		ob_start();
+
+	?><script type="text/javascript">
+	//<![CDATA[
+	var l=new Array();
+	<?php
+	$i = 0;
+	foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>
+
+	for (var i = l.length-1; i >= 0; i=i-1){
+	if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
+	else document.write(unescape(l[i]));}
+	//]]>
+	</script><?php
+
+		$buffer = ob_get_contents();
+		ob_end_clean();
+		return $buffer;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto-linker
+ *
+ * Automatically links URL and Email addresses.
+ * Note: There's a bit of extra code here to deal with
+ * URLs or emails that end in a period.  We'll strip these
+ * off and add them after the link.
+ *
+ * @access	public
+ * @param	string	the string
+ * @param	string	the type: email, url, or both
+ * @param	bool 	whether to create pop-up links
+ * @return	string
+ */
+if ( ! function_exists('auto_link'))
+{
+	function auto_link($str, $type = 'both', $popup = FALSE)
+	{
+		if ($type != 'email')
+		{
+			if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))
+			{
+				$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
+	
+				for ($i = 0; $i < sizeof($matches['0']); $i++)
+				{
+					$period = '';
+					if (preg_match("|\.$|", $matches['6'][$i]))
+					{
+						$period = '.';
+						$matches['6'][$i] = substr($matches['6'][$i], 0, -1);
+					}
+		
+					$str = str_replace($matches['0'][$i],
+										$matches['1'][$i].'<a href="http'.
+										$matches['4'][$i].'://'.
+										$matches['5'][$i].
+										$matches['6'][$i].'"'.$pop.'>http'.
+										$matches['4'][$i].'://'.
+										$matches['5'][$i].
+										$matches['6'][$i].'</a>'.
+										$period, $str);
+				}
+			}
+		}
+
+		if ($type != 'url')
+		{
+			if (preg_match_all("/([a-zA-Z0-9_\.\-\+Å]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))
+			{
+				for ($i = 0; $i < sizeof($matches['0']); $i++)
+				{
+					$period = '';
+					if (preg_match("|\.$|", $matches['3'][$i]))
+					{
+						$period = '.';
+						$matches['3'][$i] = substr($matches['3'][$i], 0, -1);
+					}
+		
+					$str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);
+				}
+			}
+		}
+
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Prep URL
+ *
+ * Simply adds the http:// part if missing
+ *
+ * @access	public
+ * @param	string	the URL
+ * @return	string
+ */
+if ( ! function_exists('prep_url'))
+{
+	function prep_url($str = '')
+	{
+		if ($str == 'http://' OR $str == '')
+		{
+			return '';
+		}
+
+		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
+		{
+			$str = 'http://'.$str;
+		}
+
+		return $str;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create URL Title
+ *
+ * Takes a "title" string as input and creates a
+ * human-friendly URL string with either a dash
+ * or an underscore as the word separator.
+ *
+ * @access	public
+ * @param	string	the string
+ * @param	string	the separator: dash, or underscore
+ * @return	string
+ */
+if ( ! function_exists('url_title'))
+{
+	function url_title($str, $separator = 'dash')
+	{
+		if ($separator == 'dash')
+		{
+			$search		= '_';
+			$replace	= '-';
+		}
+		else
+		{
+			$search		= '-';
+			$replace	= '_';
+		}
+
+		$trans = array(
+						'&\#\d+?;'				=> '',
+						'&\S+?;'				=> '',
+						'\s+'					=> $replace,
+						'[^a-z0-9\-\._]'		=> '',
+						$replace.'+'			=> $replace,
+						$replace.'$'			=> $replace,
+						'^'.$replace			=> $replace
+					  );
+
+		$str = strip_tags($str);
+
+		foreach ($trans as $key => $val)
+		{
+			$str = preg_replace("#".$key."#i", $val, $str);
+		}
+
+		return trim(stripslashes($str));
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Header Redirect
+ *
+ * Header redirect in two flavors
+ * For very fine grained control over headers, you could use the Output
+ * Library's set_header() function.
+ *
+ * @access	public
+ * @param	string	the URL
+ * @param	string	the method: location or redirect
+ * @return	string
+ */
+if ( ! function_exists('redirect'))
+{
+	function redirect($uri = '', $method = 'location', $http_response_code = 302)
+	{
+		switch($method)
+		{
+			case 'refresh'	: header("Refresh:0;url=".site_url($uri));
+				break;
+			default			: header("Location: ".site_url($uri), TRUE, $http_response_code);
+				break;
+		}
+		exit;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse out the attributes
+ *
+ * Some of the functions use this
+ *
+ * @access	private
+ * @param	array
+ * @param	bool
+ * @return	string
+ */
+if ( ! function_exists('_parse_attributes'))
+{
+	function _parse_attributes($attributes, $javascript = FALSE)
+	{
+		if (is_string($attributes))
+		{
+			return ($attributes != '') ? ' '.$attributes : '';
+		}
+
+		$att = '';
+		foreach ($attributes as $key => $val)
+		{
+			if ($javascript == TRUE)
+			{
+				$att .= $key . '=' . $val . ',';
+			}
+			else
+			{
+				$att .= ' ' . $key . '="' . $val . '"';
+			}
+		}
+
+		if ($javascript == TRUE AND $att != '')
+		{
+			$att = substr($att, 0, -1);
+		}
+
+		return $att;
+	}
+}
+
+
+/* End of file url_helper.php */
 /* Location: ./system/helpers/url_helper.php */
\ No newline at end of file
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 83e2bb3..90cce3d 100644
--- a/system/helpers/xml_helper.php
+++ b/system/helpers/xml_helper.php
@@ -1,62 +1,62 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter XML Helpers

- *

- * @package		CodeIgniter

- * @subpackage	Helpers

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/xml_helper.html

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Convert Reserved XML characters to Entities

- *

- * @access	public

- * @param	string

- * @return	string

- */	

-if ( ! function_exists('xml_convert'))

-{

-	function xml_convert($str)

-	{

-		$temp = '__TEMP_AMPERSANDS__';

-

-		// Replace entities to temporary markers so that 

-		// ampersands won't get messed up

-		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);

-		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);

-	

-		$str = str_replace(array("&","<",">","\"", "'", "-"),

-						   array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),

-						   $str);

-

-		// Decode the temp markers back to entities		

-		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);

-		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);

-		

-		return $str;

-	}

-}

-

-

-/* End of file xml_helper.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter XML Helpers
+ *
+ * @package		CodeIgniter
+ * @subpackage	Helpers
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/xml_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert Reserved XML characters to Entities
+ *
+ * @access	public
+ * @param	string
+ * @return	string
+ */	
+if ( ! function_exists('xml_convert'))
+{
+	function xml_convert($str)
+	{
+		$temp = '__TEMP_AMPERSANDS__';
+
+		// Replace entities to temporary markers so that 
+		// ampersands won't get messed up
+		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
+		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
+	
+		$str = str_replace(array("&","<",">","\"", "'", "-"),
+						   array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
+						   $str);
+
+		// Decode the temp markers back to entities		
+		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
+		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);
+		
+		return $str;
+	}
+}
+
+
+/* End of file xml_helper.php */
 /* Location: ./system/helpers/xml_helper.php */
\ No newline at end of file
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
index 107c0f7..e26f849 100644
--- a/system/language/english/calendar_lang.php
+++ b/system/language/english/calendar_lang.php
@@ -1,51 +1,51 @@
-<?php

-

-$lang['cal_su']			= "Su";

-$lang['cal_mo'] 		= "Mo";

-$lang['cal_tu'] 		= "Tu";

-$lang['cal_we'] 		= "We";

-$lang['cal_th'] 		= "Th";

-$lang['cal_fr'] 		= "Fr";

-$lang['cal_sa'] 		= "Sa";

-$lang['cal_sun'] 		= "Sun";

-$lang['cal_mon'] 		= "Mon";

-$lang['cal_tue'] 		= "Tue";

-$lang['cal_wed'] 		= "Wed";

-$lang['cal_thu'] 		= "Thu";

-$lang['cal_fri'] 		= "Fri";

-$lang['cal_sat'] 		= "Sat";

-$lang['cal_sunday']		= "Sunday";

-$lang['cal_monday']		= "Monday";

-$lang['cal_tuesday']	= "Tuesday";

-$lang['cal_wednesday']	= "Wednesday";

-$lang['cal_thursday']	= "Thursday";

-$lang['cal_friday']		= "Friday";

-$lang['cal_saturday']	= "Saturday";

-$lang['cal_jan'] 		= "Jan";

-$lang['cal_feb'] 		= "Feb";

-$lang['cal_mar'] 		= "Mar";

-$lang['cal_apr'] 		= "Apr";

-$lang['cal_may'] 		= "May";

-$lang['cal_jun'] 		= "Jun";

-$lang['cal_jul'] 		= "Jul";

-$lang['cal_aug'] 		= "Aug";

-$lang['cal_sep'] 		= "Sep";

-$lang['cal_oct'] 		= "Oct";

-$lang['cal_nov'] 		= "Nov";

-$lang['cal_dec'] 		= "Dec";

-$lang['cal_january'] 	= "January";

-$lang['cal_february'] 	= "February";

-$lang['cal_march'] 		= "March";

-$lang['cal_april']		= "April";

-$lang['cal_mayl'] 		= "May";

-$lang['cal_june'] 		= "June";

-$lang['cal_july'] 		= "July";

-$lang['cal_august']		= "August";

-$lang['cal_september']	= "September";

-$lang['cal_october'] 	= "October";

-$lang['cal_november']	= "November";

-$lang['cal_december'] 	= "December";

-

+<?php
+
+$lang['cal_su']			= "Su";
+$lang['cal_mo'] 		= "Mo";
+$lang['cal_tu'] 		= "Tu";
+$lang['cal_we'] 		= "We";
+$lang['cal_th'] 		= "Th";
+$lang['cal_fr'] 		= "Fr";
+$lang['cal_sa'] 		= "Sa";
+$lang['cal_sun'] 		= "Sun";
+$lang['cal_mon'] 		= "Mon";
+$lang['cal_tue'] 		= "Tue";
+$lang['cal_wed'] 		= "Wed";
+$lang['cal_thu'] 		= "Thu";
+$lang['cal_fri'] 		= "Fri";
+$lang['cal_sat'] 		= "Sat";
+$lang['cal_sunday']		= "Sunday";
+$lang['cal_monday']		= "Monday";
+$lang['cal_tuesday']	= "Tuesday";
+$lang['cal_wednesday']	= "Wednesday";
+$lang['cal_thursday']	= "Thursday";
+$lang['cal_friday']		= "Friday";
+$lang['cal_saturday']	= "Saturday";
+$lang['cal_jan'] 		= "Jan";
+$lang['cal_feb'] 		= "Feb";
+$lang['cal_mar'] 		= "Mar";
+$lang['cal_apr'] 		= "Apr";
+$lang['cal_may'] 		= "May";
+$lang['cal_jun'] 		= "Jun";
+$lang['cal_jul'] 		= "Jul";
+$lang['cal_aug'] 		= "Aug";
+$lang['cal_sep'] 		= "Sep";
+$lang['cal_oct'] 		= "Oct";
+$lang['cal_nov'] 		= "Nov";
+$lang['cal_dec'] 		= "Dec";
+$lang['cal_january'] 	= "January";
+$lang['cal_february'] 	= "February";
+$lang['cal_march'] 		= "March";
+$lang['cal_april']		= "April";
+$lang['cal_mayl'] 		= "May";
+$lang['cal_june'] 		= "June";
+$lang['cal_july'] 		= "July";
+$lang['cal_august']		= "August";
+$lang['cal_september']	= "September";
+$lang['cal_october'] 	= "October";
+$lang['cal_november']	= "November";
+$lang['cal_december'] 	= "December";
+
 
 /* End of file calendar_lang.php */
 /* Location: ./system/language/english/calendar_lang.php */
\ No newline at end of file
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index 29b00f5..628e55b 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -1,60 +1,60 @@
-<?php

-

-$lang['date_year'] = "Year";

-$lang['date_years'] = "Years";

-$lang['date_month'] = "Month";

-$lang['date_months'] = "Months";

-$lang['date_week'] = "Week";

-$lang['date_weeks'] = "Weeks";

-$lang['date_day'] = "Day";

-$lang['date_days'] = "Days";

-$lang['date_hour'] = "Hour";

-$lang['date_hours'] = "Hours";

-$lang['date_minute'] = "Minute";

-$lang['date_minutes'] = "Minutes";

-$lang['date_second'] = "Second";

-$lang['date_seconds'] = "Seconds";

-

-$lang['UM12']	= '(UTC -12:00) Baker/Howland Island';

-$lang['UM11']	= '(UTC -11:00) Samoa Time Zone, Niue';

-$lang['UM10']	= '(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti';

-$lang['UM95']	= '(UTC -9:30) Marquesas Islands';

-$lang['UM9']	= '(UTC -9:00) Alaska Standard Time, Gambier Islands';

-$lang['UM8']	= '(UTC -8:00) Pacific Standard Time, Clipperton Island';

-$lang['UM7']	= '(UTC -7:00) Mountain Standard Time';

-$lang['UM6']	= '(UTC -6:00) Central Standard Time';

-$lang['UM5']	= '(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time';

-$lang['UM45']	= '(UTC -4:30) Venezuelan Standard Time';

-$lang['UM4']	= '(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time';

-$lang['UM35']	= '(UTC -3:30) Newfoundland Standard Time';

-$lang['UM3']	= '(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay';

-$lang['UM2']	= '(UTC -2:00) South Georgia/South Sandwich Islands';

-$lang['UM1']	= '(UTC -1:00) Azores, Cape Verde Islands';

-$lang['UTC']	= '(UTC) Greenwich Mean Time, Western European Time';

-$lang['UP1']	= '(UTC +1:00) Central European Time, West Africa Time';

-$lang['UP2']	= '(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time';

-$lang['UP3']	= '(UTC +3:00) Moscow Time, East Africa Time';

-$lang['UP35']	= '(UTC +3:30) Iran Standard Time';

-$lang['UP4']	= '(UTC +4:00) Azerbaijan Standard Time, Samara Time';

-$lang['UP45']	= '(UTC +4:30) Afghanistan';

-$lang['UP5']	= '(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time';

-$lang['UP55']	= '(UTC +5:30) Indian Standard Time, Sri Lanka Time';

-$lang['UP575']	= '(UTC +5:45) Nepal Time';

-$lang['UP6']	= '(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time';

-$lang['UP65']	= '(UTC +6:30) Cocos Islands, Myanmar';

-$lang['UP7']	= '(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam';

-$lang['UP8']	= '(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time';

-$lang['UP875']	= '(UTC +8:45) Australian Central Western Standard Time';

-$lang['UP9']	= '(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time';

-$lang['UP95']	= '(UTC +9:30) Australian Central Standard Time';

-$lang['UP10']	= '(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time';

-$lang['UP105']	= '(UTC +10:30) Lord Howe Island';

-$lang['UP11']	= '(UTC +11:00) Magadan Time, Solomon Islands, Vanuatu';

-$lang['UP115']	= '(UTC +11:30) Norfolk Island';

-$lang['UP12']	= '(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time';

-$lang['UP1275']	= '(UTC +12:45) Chatham Islands Standard Time';

-$lang['UP13']	= '(UTC +13:00) Phoenix Islands Time, Tonga';

-$lang['UP14']	= '(UTC +14:00) Line Islands';

-

-/* End of file date_lang.php */

+<?php
+
+$lang['date_year'] = "Year";
+$lang['date_years'] = "Years";
+$lang['date_month'] = "Month";
+$lang['date_months'] = "Months";
+$lang['date_week'] = "Week";
+$lang['date_weeks'] = "Weeks";
+$lang['date_day'] = "Day";
+$lang['date_days'] = "Days";
+$lang['date_hour'] = "Hour";
+$lang['date_hours'] = "Hours";
+$lang['date_minute'] = "Minute";
+$lang['date_minutes'] = "Minutes";
+$lang['date_second'] = "Second";
+$lang['date_seconds'] = "Seconds";
+
+$lang['UM12']	= '(UTC -12:00) Baker/Howland Island';
+$lang['UM11']	= '(UTC -11:00) Samoa Time Zone, Niue';
+$lang['UM10']	= '(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti';
+$lang['UM95']	= '(UTC -9:30) Marquesas Islands';
+$lang['UM9']	= '(UTC -9:00) Alaska Standard Time, Gambier Islands';
+$lang['UM8']	= '(UTC -8:00) Pacific Standard Time, Clipperton Island';
+$lang['UM7']	= '(UTC -7:00) Mountain Standard Time';
+$lang['UM6']	= '(UTC -6:00) Central Standard Time';
+$lang['UM5']	= '(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time';
+$lang['UM45']	= '(UTC -4:30) Venezuelan Standard Time';
+$lang['UM4']	= '(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time';
+$lang['UM35']	= '(UTC -3:30) Newfoundland Standard Time';
+$lang['UM3']	= '(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay';
+$lang['UM2']	= '(UTC -2:00) South Georgia/South Sandwich Islands';
+$lang['UM1']	= '(UTC -1:00) Azores, Cape Verde Islands';
+$lang['UTC']	= '(UTC) Greenwich Mean Time, Western European Time';
+$lang['UP1']	= '(UTC +1:00) Central European Time, West Africa Time';
+$lang['UP2']	= '(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time';
+$lang['UP3']	= '(UTC +3:00) Moscow Time, East Africa Time';
+$lang['UP35']	= '(UTC +3:30) Iran Standard Time';
+$lang['UP4']	= '(UTC +4:00) Azerbaijan Standard Time, Samara Time';
+$lang['UP45']	= '(UTC +4:30) Afghanistan';
+$lang['UP5']	= '(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time';
+$lang['UP55']	= '(UTC +5:30) Indian Standard Time, Sri Lanka Time';
+$lang['UP575']	= '(UTC +5:45) Nepal Time';
+$lang['UP6']	= '(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time';
+$lang['UP65']	= '(UTC +6:30) Cocos Islands, Myanmar';
+$lang['UP7']	= '(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam';
+$lang['UP8']	= '(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time';
+$lang['UP875']	= '(UTC +8:45) Australian Central Western Standard Time';
+$lang['UP9']	= '(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time';
+$lang['UP95']	= '(UTC +9:30) Australian Central Standard Time';
+$lang['UP10']	= '(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time';
+$lang['UP105']	= '(UTC +10:30) Lord Howe Island';
+$lang['UP11']	= '(UTC +11:00) Magadan Time, Solomon Islands, Vanuatu';
+$lang['UP115']	= '(UTC +11:30) Norfolk Island';
+$lang['UP12']	= '(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time';
+$lang['UP1275']	= '(UTC +12:45) Chatham Islands Standard Time';
+$lang['UP13']	= '(UTC +13:00) Phoenix Islands Time, Tonga';
+$lang['UP14']	= '(UTC +14:00) Line Islands';
+
+/* End of file date_lang.php */
 /* Location: ./system/language/english/date_lang.php */
\ No newline at end of file
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
index 2f7ccb5..dc98afc 100644
--- a/system/language/english/db_lang.php
+++ b/system/language/english/db_lang.php
@@ -1,28 +1,28 @@
-<?php

-

-$lang['db_invalid_connection_str'] = 'Unable to determine the database settings based on the connection string you submitted.';

-$lang['db_unable_to_connect'] = 'Unable to connect to your database server using the provided settings.';

-$lang['db_unable_to_select'] = 'Unable to select the specified database: %s';

-$lang['db_unable_to_create'] = 'Unable to create the specified database: %s';

-$lang['db_invalid_query'] = 'The query you submitted is not valid.';

-$lang['db_must_set_table'] = 'You must set the database table to be used with your query.';

-$lang['db_must_set_database'] = 'You must set the database name in your database config file.';

-$lang['db_must_use_set'] = 'You must use the "set" method to update an entry.';

-$lang['db_must_use_where'] = 'Updates are not allowed unless they contain a "where" clause.';

-$lang['db_del_must_use_where'] = 'Deletes are not allowed unless they contain a "where" or "like" clause.';

-$lang['db_field_param_missing'] = 'To fetch fields requires the name of the table as a parameter.';

-$lang['db_unsupported_function'] = 'This feature is not available for the database you are using.';

-$lang['db_transaction_failure'] = 'Transaction failure: Rollback performed.';

-$lang['db_unable_to_drop'] = 'Unable to drop the specified database.';

-$lang['db_unsuported_feature'] = 'Unsupported feature of the database platform you are using.';

-$lang['db_unsuported_compression'] = 'The file compression format you chose is not supported by your server.';

-$lang['db_filepath_error'] = 'Unable to write data to the file path you have submitted.';

-$lang['db_invalid_cache_path'] = 'The cache path you submitted is not valid or writable.';

-$lang['db_table_name_required'] = 'A table name is required for that operation.';

-$lang['db_column_name_required'] = 'A column name is required for that operation.';

-$lang['db_column_definition_required'] = 'A column definition is required for that operation.';

-$lang['db_unable_to_set_charset'] = 'Unable to set client connection character set: %s';

-$lang['db_error_heading'] = 'A Database Error Occurred';

-

-/* End of file db_lang.php */

+<?php
+
+$lang['db_invalid_connection_str'] = 'Unable to determine the database settings based on the connection string you submitted.';
+$lang['db_unable_to_connect'] = 'Unable to connect to your database server using the provided settings.';
+$lang['db_unable_to_select'] = 'Unable to select the specified database: %s';
+$lang['db_unable_to_create'] = 'Unable to create the specified database: %s';
+$lang['db_invalid_query'] = 'The query you submitted is not valid.';
+$lang['db_must_set_table'] = 'You must set the database table to be used with your query.';
+$lang['db_must_set_database'] = 'You must set the database name in your database config file.';
+$lang['db_must_use_set'] = 'You must use the "set" method to update an entry.';
+$lang['db_must_use_where'] = 'Updates are not allowed unless they contain a "where" clause.';
+$lang['db_del_must_use_where'] = 'Deletes are not allowed unless they contain a "where" or "like" clause.';
+$lang['db_field_param_missing'] = 'To fetch fields requires the name of the table as a parameter.';
+$lang['db_unsupported_function'] = 'This feature is not available for the database you are using.';
+$lang['db_transaction_failure'] = 'Transaction failure: Rollback performed.';
+$lang['db_unable_to_drop'] = 'Unable to drop the specified database.';
+$lang['db_unsuported_feature'] = 'Unsupported feature of the database platform you are using.';
+$lang['db_unsuported_compression'] = 'The file compression format you chose is not supported by your server.';
+$lang['db_filepath_error'] = 'Unable to write data to the file path you have submitted.';
+$lang['db_invalid_cache_path'] = 'The cache path you submitted is not valid or writable.';
+$lang['db_table_name_required'] = 'A table name is required for that operation.';
+$lang['db_column_name_required'] = 'A column name is required for that operation.';
+$lang['db_column_definition_required'] = 'A column definition is required for that operation.';
+$lang['db_unable_to_set_charset'] = 'Unable to set client connection character set: %s';
+$lang['db_error_heading'] = 'A Database Error Occurred';
+
+/* End of file db_lang.php */
 /* Location: ./system/language/english/db_lang.php */
\ No newline at end of file
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
index 3e94bf3..9324277 100644
--- a/system/language/english/email_lang.php
+++ b/system/language/english/email_lang.php
@@ -1,23 +1,23 @@
-<?php

-

-$lang['email_must_be_array'] = "The email validation method must be passed an array.";

-$lang['email_invalid_address'] = "Invalid email address: %s";

-$lang['email_attachment_missing'] = "Unable to locate the following email attachment: %s";

-$lang['email_attachment_unreadable'] = "Unable to open this attachment: %s";

-$lang['email_no_recipients'] = "You must include recipients: To, Cc, or Bcc";

-$lang['email_send_failure_phpmail'] = "Unable to send email using PHP mail().  Your server might not be configured to send mail using this method.";

-$lang['email_send_failure_sendmail'] = "Unable to send email using PHP Sendmail.  Your server might not be configured to send mail using this method.";

-$lang['email_send_failure_smtp'] = "Unable to send email using PHP SMTP.  Your server might not be configured to send mail using this method.";

-$lang['email_sent'] = "Your message has been successfully sent using the following protocol: %s";

-$lang['email_no_socket'] = "Unable to open a socket to Sendmail. Please check settings.";

-$lang['email_no_hostname'] = "You did not specify a SMTP hostname.";

-$lang['email_smtp_error'] = "The following SMTP error was encountered: %s";

-$lang['email_no_smtp_unpw'] = "Error: You must assign a SMTP username and password.";

-$lang['email_failed_smtp_login'] = "Failed to send AUTH LOGIN command. Error: %s";

-$lang['email_smtp_auth_un'] = "Failed to authenticate username. Error: %s";

-$lang['email_smtp_auth_pw'] = "Failed to authenticate password. Error: %s";

-$lang['email_smtp_data_failure'] = "Unable to send data: %s";

-

+<?php
+
+$lang['email_must_be_array'] = "The email validation method must be passed an array.";
+$lang['email_invalid_address'] = "Invalid email address: %s";
+$lang['email_attachment_missing'] = "Unable to locate the following email attachment: %s";
+$lang['email_attachment_unreadable'] = "Unable to open this attachment: %s";
+$lang['email_no_recipients'] = "You must include recipients: To, Cc, or Bcc";
+$lang['email_send_failure_phpmail'] = "Unable to send email using PHP mail().  Your server might not be configured to send mail using this method.";
+$lang['email_send_failure_sendmail'] = "Unable to send email using PHP Sendmail.  Your server might not be configured to send mail using this method.";
+$lang['email_send_failure_smtp'] = "Unable to send email using PHP SMTP.  Your server might not be configured to send mail using this method.";
+$lang['email_sent'] = "Your message has been successfully sent using the following protocol: %s";
+$lang['email_no_socket'] = "Unable to open a socket to Sendmail. Please check settings.";
+$lang['email_no_hostname'] = "You did not specify a SMTP hostname.";
+$lang['email_smtp_error'] = "The following SMTP error was encountered: %s";
+$lang['email_no_smtp_unpw'] = "Error: You must assign a SMTP username and password.";
+$lang['email_failed_smtp_login'] = "Failed to send AUTH LOGIN command. Error: %s";
+$lang['email_smtp_auth_un'] = "Failed to authenticate username. Error: %s";
+$lang['email_smtp_auth_pw'] = "Failed to authenticate password. Error: %s";
+$lang['email_smtp_data_failure'] = "Unable to send data: %s";
+
 
 /* End of file email_lang.php */
 /* Location: ./system/language/english/email_lang.php */
\ No newline at end of file
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index c157fe4..8a123f4 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -1,24 +1,24 @@
-<?php

-

-$lang['required'] 			= "The %s field is required.";

-$lang['isset']				= "The %s field must have a value.";

-$lang['valid_email']		= "The %s field must contain a valid email address.";

-$lang['valid_emails'] 		= "The %s field must contain all valid email addresses.";

-$lang['valid_url'] 			= "The %s field must contain a valid URL.";

-$lang['valid_ip'] 			= "The %s field must contain a valid IP.";

-$lang['min_length']			= "The %s field must be at least %s characters in length.";

-$lang['max_length']			= "The %s field can not exceed %s characters in length.";

-$lang['exact_length']		= "The %s field must be exactly %s characters in length.";

-$lang['alpha']				= "The %s field may only contain alphabetical characters.";

-$lang['alpha_numeric']		= "The %s field may only contain alpha-numeric characters.";

-$lang['alpha_dash']			= "The %s field may only contain alpha-numeric characters, underscores, and dashes.";

-$lang['numeric']			= "The %s field must contain only numbers.";

-$lang['is_numeric']			= "The %s field must contain only numeric characters.";

-$lang['integer']			= "The %s field must contain an integer.";

-$lang['matches']			= "The %s field does not match the %s field.";

-$lang['is_natural']			= "The %s field must contain only positive numbers.";

-$lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";

-

-

-/* End of file form_validation_lang.php */

+<?php
+
+$lang['required'] 			= "The %s field is required.";
+$lang['isset']				= "The %s field must have a value.";
+$lang['valid_email']		= "The %s field must contain a valid email address.";
+$lang['valid_emails'] 		= "The %s field must contain all valid email addresses.";
+$lang['valid_url'] 			= "The %s field must contain a valid URL.";
+$lang['valid_ip'] 			= "The %s field must contain a valid IP.";
+$lang['min_length']			= "The %s field must be at least %s characters in length.";
+$lang['max_length']			= "The %s field can not exceed %s characters in length.";
+$lang['exact_length']		= "The %s field must be exactly %s characters in length.";
+$lang['alpha']				= "The %s field may only contain alphabetical characters.";
+$lang['alpha_numeric']		= "The %s field may only contain alpha-numeric characters.";
+$lang['alpha_dash']			= "The %s field may only contain alpha-numeric characters, underscores, and dashes.";
+$lang['numeric']			= "The %s field must contain only numbers.";
+$lang['is_numeric']			= "The %s field must contain only numeric characters.";
+$lang['integer']			= "The %s field must contain an integer.";
+$lang['matches']			= "The %s field does not match the %s field.";
+$lang['is_natural']			= "The %s field must contain only positive numbers.";
+$lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";
+
+
+/* End of file form_validation_lang.php */
 /* Location: ./system/language/english/form_validation_lang.php */
\ No newline at end of file
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
index e014028..42403b9 100644
--- a/system/language/english/ftp_lang.php
+++ b/system/language/english/ftp_lang.php
@@ -1,17 +1,17 @@
-<?php

-

-$lang['ftp_no_connection']			= "Unable to locate a valid connection ID.  Please make sure you are connected before peforming any file routines.";

-$lang['ftp_unable_to_connect']		= "Unable to connect to your FTP server using the supplied hostname.";

-$lang['ftp_unable_to_login']		= "Unable to login to your FTP server.  Please check your username and password.";

-$lang['ftp_unable_to_makdir']		= "Unable to create the directory you have specified.";

-$lang['ftp_unable_to_changedir']	= "Unable to change directories.";

-$lang['ftp_unable_to_chmod']		= "Unable to set file permissions.  Please check your path.  Note: This feature is only available in PHP 5 or higher.";

-$lang['ftp_unable_to_upload']		= "Unable to upload the specified file.  Please check your path.";

-$lang['ftp_no_source_file']			= "Unable to locate the source file.  Please check your path.";

-$lang['ftp_unable_to_rename']		= "Unable to rename the file.";

-$lang['ftp_unable_to_delete']		= "Unable to delete the file.";

-$lang['ftp_unable_to_move']			= "Unable to move the file.  Please make sure the destination directory exists.";

-

+<?php
+
+$lang['ftp_no_connection']			= "Unable to locate a valid connection ID.  Please make sure you are connected before peforming any file routines.";
+$lang['ftp_unable_to_connect']		= "Unable to connect to your FTP server using the supplied hostname.";
+$lang['ftp_unable_to_login']		= "Unable to login to your FTP server.  Please check your username and password.";
+$lang['ftp_unable_to_makdir']		= "Unable to create the directory you have specified.";
+$lang['ftp_unable_to_changedir']	= "Unable to change directories.";
+$lang['ftp_unable_to_chmod']		= "Unable to set file permissions.  Please check your path.  Note: This feature is only available in PHP 5 or higher.";
+$lang['ftp_unable_to_upload']		= "Unable to upload the specified file.  Please check your path.";
+$lang['ftp_no_source_file']			= "Unable to locate the source file.  Please check your path.";
+$lang['ftp_unable_to_rename']		= "Unable to rename the file.";
+$lang['ftp_unable_to_delete']		= "Unable to delete the file.";
+$lang['ftp_unable_to_move']			= "Unable to move the file.  Please make sure the destination directory exists.";
+
 
 /* End of file ftp_lang.php */
 /* Location: ./system/language/english/ftp_lang.php */
\ No newline at end of file
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index 4baf971..a587c0b 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -1,23 +1,23 @@
-<?php

-

-$lang['imglib_source_image_required'] = "You must specify a source image in your preferences.";

-$lang['imglib_gd_required'] = "The GD image library is required for this feature.";

-$lang['imglib_gd_required_for_props'] = "Your server must support the GD image library in order to determine the image properties.";

-$lang['imglib_unsupported_imagecreate'] = "Your server does not support the GD function required to process this type of image.";

-$lang['imglib_gif_not_supported'] = "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.";

-$lang['imglib_jpg_not_supported'] = "JPG images are not supported.";

-$lang['imglib_png_not_supported'] = "PNG images are not supported.";

-$lang['imglib_jpg_or_png_required'] = "The image resize protocol specified in your preferences only works with JPEG or PNG image types.";

-$lang['imglib_copy_error'] = "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.";

-$lang['imglib_rotate_unsupported'] = "Image rotation does not appear to be supported by your server.";

-$lang['imglib_libpath_invalid'] = "The path to your image library is not correct.  Please set the correct path in your image preferences.";

-$lang['imglib_image_process_failed'] = "Image processing failed.  Please verify that your server supports the chosen protocol and that the path to your image library is correct.";

-$lang['imglib_rotation_angle_required'] = "An angle of rotation is required to rotate the image.";

-$lang['imglib_writing_failed_gif'] = "GIF image.";

-$lang['imglib_invalid_path'] = "The path to the image is not correct.";

-$lang['imglib_copy_failed'] = "The image copy routine failed.";

-$lang['imglib_missing_font'] = "Unable to find a font to use.";

-

+<?php
+
+$lang['imglib_source_image_required'] = "You must specify a source image in your preferences.";
+$lang['imglib_gd_required'] = "The GD image library is required for this feature.";
+$lang['imglib_gd_required_for_props'] = "Your server must support the GD image library in order to determine the image properties.";
+$lang['imglib_unsupported_imagecreate'] = "Your server does not support the GD function required to process this type of image.";
+$lang['imglib_gif_not_supported'] = "GIF images are often not supported due to licensing restrictions.  You may have to use JPG or PNG images instead.";
+$lang['imglib_jpg_not_supported'] = "JPG images are not supported.";
+$lang['imglib_png_not_supported'] = "PNG images are not supported.";
+$lang['imglib_jpg_or_png_required'] = "The image resize protocol specified in your preferences only works with JPEG or PNG image types.";
+$lang['imglib_copy_error'] = "An error was encountered while attempting to replace the file.  Please make sure your file directory is writable.";
+$lang['imglib_rotate_unsupported'] = "Image rotation does not appear to be supported by your server.";
+$lang['imglib_libpath_invalid'] = "The path to your image library is not correct.  Please set the correct path in your image preferences.";
+$lang['imglib_image_process_failed'] = "Image processing failed.  Please verify that your server supports the chosen protocol and that the path to your image library is correct.";
+$lang['imglib_rotation_angle_required'] = "An angle of rotation is required to rotate the image.";
+$lang['imglib_writing_failed_gif'] = "GIF image.";
+$lang['imglib_invalid_path'] = "The path to the image is not correct.";
+$lang['imglib_copy_failed'] = "The image copy routine failed.";
+$lang['imglib_missing_font'] = "Unable to find a font to use.";
+
 
 /* End of file imglib_lang.php */
 /* Location: ./system/language/english/imglib_lang.php */
\ No newline at end of file
diff --git a/system/language/english/index.html b/system/language/english/index.html
index 065d2da..c942a79 100644
--- a/system/language/english/index.html
+++ b/system/language/english/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php
index f9b9166..9085809 100644
--- a/system/language/english/number_lang.php
+++ b/system/language/english/number_lang.php
@@ -1,10 +1,10 @@
-<?php

-

-$lang['terabyte_abbr'] = "TB";

-$lang['gigabyte_abbr'] = "GB";

-$lang['megabyte_abbr'] = "MB";

-$lang['kilobyte_abbr'] = "KB";

-$lang['bytes'] = "Bytes";

-

-/* End of file number_lang.php */

+<?php
+
+$lang['terabyte_abbr'] = "TB";
+$lang['gigabyte_abbr'] = "GB";
+$lang['megabyte_abbr'] = "MB";
+$lang['kilobyte_abbr'] = "KB";
+$lang['bytes'] = "Bytes";
+
+/* End of file number_lang.php */
 /* Location: ./system/language/english/number_lang.php */
\ No newline at end of file
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
index 4db5511..7c40e3f 100644
--- a/system/language/english/profiler_lang.php
+++ b/system/language/english/profiler_lang.php
@@ -1,19 +1,19 @@
-<?php

-

-$lang['profiler_database']		  = 'DATABASE';

-$lang['profiler_controller_info'] = 'CLASS/METHOD';

-$lang['profiler_benchmarks']	= 'BENCHMARKS';

-$lang['profiler_queries']		= 'QUERIES';

-$lang['profiler_get_data']		= 'GET DATA';

-$lang['profiler_post_data']		= 'POST DATA';

-$lang['profiler_uri_string']	= 'URI STRING';

-$lang['profiler_memory_usage']	= 'MEMORY USAGE';

-$lang['profiler_no_db']			= 'Database driver is not currently loaded';

-$lang['profiler_no_queries']	= 'No queries were run';

-$lang['profiler_no_post']		= 'No POST data exists';

-$lang['profiler_no_get']		= 'No GET data exists';

-$lang['profiler_no_uri']		= 'No URI data exists';

-$lang['profiler_no_memory']		= 'Memory Usage Unavailable';

-

-/* End of file profiler_lang.php */

+<?php
+
+$lang['profiler_database']		  = 'DATABASE';
+$lang['profiler_controller_info'] = 'CLASS/METHOD';
+$lang['profiler_benchmarks']	= 'BENCHMARKS';
+$lang['profiler_queries']		= 'QUERIES';
+$lang['profiler_get_data']		= 'GET DATA';
+$lang['profiler_post_data']		= 'POST DATA';
+$lang['profiler_uri_string']	= 'URI STRING';
+$lang['profiler_memory_usage']	= 'MEMORY USAGE';
+$lang['profiler_no_db']			= 'Database driver is not currently loaded';
+$lang['profiler_no_queries']	= 'No queries were run';
+$lang['profiler_no_post']		= 'No POST data exists';
+$lang['profiler_no_get']		= 'No GET data exists';
+$lang['profiler_no_uri']		= 'No URI data exists';
+$lang['profiler_no_memory']		= 'Memory Usage Unavailable';
+
+/* End of file profiler_lang.php */
 /* Location: ./system/language/english/profiler_lang.php */
\ No newline at end of file
diff --git a/system/language/english/scaffolding_lang.php b/system/language/english/scaffolding_lang.php
index 7df2970..c4d54d5 100644
--- a/system/language/english/scaffolding_lang.php
+++ b/system/language/english/scaffolding_lang.php
@@ -1,17 +1,17 @@
-<?php

-

-$lang['scaff_view_records']		= 'View Records';

-$lang['scaff_create_record']	= 'Create New Record';

-$lang['scaff_add']				= 'Add Data';

-$lang['scaff_view']				= 'View Data';

-$lang['scaff_edit']				= 'Edit';

-$lang['scaff_delete']			= 'Delete';

-$lang['scaff_view_all']			= 'View All';

-$lang['scaff_yes']				= 'Yes';

-$lang['scaff_no']				= 'No';

-$lang['scaff_no_data']			= 'No data exists for this table yet.';

-$lang['scaff_del_confirm']		= 'Are you sure you want to delete the following row:';

-

-

-/* End of file scaffolding_lang.php */

+<?php
+
+$lang['scaff_view_records']		= 'View Records';
+$lang['scaff_create_record']	= 'Create New Record';
+$lang['scaff_add']				= 'Add Data';
+$lang['scaff_view']				= 'View Data';
+$lang['scaff_edit']				= 'Edit';
+$lang['scaff_delete']			= 'Delete';
+$lang['scaff_view_all']			= 'View All';
+$lang['scaff_yes']				= 'Yes';
+$lang['scaff_no']				= 'No';
+$lang['scaff_no_data']			= 'No data exists for this table yet.';
+$lang['scaff_del_confirm']		= 'Are you sure you want to delete the following row:';
+
+
+/* End of file scaffolding_lang.php */
 /* Location: ./system/language/english/scaffolding_lang.php */
\ No newline at end of file
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
index 7e1b616..45b5acf 100644
--- a/system/language/english/unit_test_lang.php
+++ b/system/language/english/unit_test_lang.php
@@ -1,24 +1,24 @@
-<?php

-

-$lang['ut_test_name']		= 'Test Name';

-$lang['ut_test_datatype']	= 'Test Datatype';

-$lang['ut_res_datatype']	= 'Expected Datatype';

-$lang['ut_result']			= 'Result';

-$lang['ut_undefined']		= 'Undefined Test Name';

-$lang['ut_file']			= 'File Name';

-$lang['ut_line']			= 'Line Number';

-$lang['ut_passed']			= 'Passed';

-$lang['ut_failed']			= 'Failed';

-$lang['ut_boolean']			= 'Boolean';

-$lang['ut_integer']			= 'Integer';

-$lang['ut_float']			= 'Float';

-$lang['ut_double']			= 'Float'; // can be the same as float

-$lang['ut_string']			= 'String';

-$lang['ut_array']			= 'Array';

-$lang['ut_object']			= 'Object';

-$lang['ut_resource']		= 'Resource';

-$lang['ut_null']			= 'Null';

-

-

-/* End of file unit_test_lang.php */

+<?php
+
+$lang['ut_test_name']		= 'Test Name';
+$lang['ut_test_datatype']	= 'Test Datatype';
+$lang['ut_res_datatype']	= 'Expected Datatype';
+$lang['ut_result']			= 'Result';
+$lang['ut_undefined']		= 'Undefined Test Name';
+$lang['ut_file']			= 'File Name';
+$lang['ut_line']			= 'Line Number';
+$lang['ut_passed']			= 'Passed';
+$lang['ut_failed']			= 'Failed';
+$lang['ut_boolean']			= 'Boolean';
+$lang['ut_integer']			= 'Integer';
+$lang['ut_float']			= 'Float';
+$lang['ut_double']			= 'Float'; // can be the same as float
+$lang['ut_string']			= 'String';
+$lang['ut_array']			= 'Array';
+$lang['ut_object']			= 'Object';
+$lang['ut_resource']		= 'Resource';
+$lang['ut_null']			= 'Null';
+
+
+/* End of file unit_test_lang.php */
 /* Location: ./system/language/english/unit_test_lang.php */
\ No newline at end of file
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
index 5f7d449..4de9e9e 100644
--- a/system/language/english/upload_lang.php
+++ b/system/language/english/upload_lang.php
@@ -1,22 +1,22 @@
-<?php

-

-$lang['upload_userfile_not_set'] = "Unable to find a post variable called userfile.";

-$lang['upload_file_exceeds_limit'] = "The uploaded file exceeds the maximum allowed size in your PHP configuration file.";

-$lang['upload_file_exceeds_form_limit'] = "The uploaded file exceeds the maximum size allowed by the submission form.";

-$lang['upload_file_partial'] = "The file was only partially uploaded.";

-$lang['upload_no_temp_directory'] = "The temporary folder is missing.";

-$lang['upload_unable_to_write_file'] = "The file could not be written to disk.";

-$lang['upload_stopped_by_extension'] = "The file upload was stopped by extension.";

-$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_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.";

-$lang['upload_bad_filename'] = "The file name you submitted already exists on the server.";

-$lang['upload_not_writable'] = "The upload destination folder does not appear to be writable.";

-

+<?php
+
+$lang['upload_userfile_not_set'] = "Unable to find a post variable called userfile.";
+$lang['upload_file_exceeds_limit'] = "The uploaded file exceeds the maximum allowed size in your PHP configuration file.";
+$lang['upload_file_exceeds_form_limit'] = "The uploaded file exceeds the maximum size allowed by the submission form.";
+$lang['upload_file_partial'] = "The file was only partially uploaded.";
+$lang['upload_no_temp_directory'] = "The temporary folder is missing.";
+$lang['upload_unable_to_write_file'] = "The file could not be written to disk.";
+$lang['upload_stopped_by_extension'] = "The file upload was stopped by extension.";
+$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_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.";
+$lang['upload_bad_filename'] = "The file name you submitted already exists on the server.";
+$lang['upload_not_writable'] = "The upload destination folder does not appear to be writable.";
+
 
 /* End of file upload_lang.php */
 /* Location: ./system/language/english/upload_lang.php */
\ No newline at end of file
diff --git a/system/language/english/validation_lang.php b/system/language/english/validation_lang.php
index 7ca762d..a287892 100644
--- a/system/language/english/validation_lang.php
+++ b/system/language/english/validation_lang.php
@@ -1,24 +1,24 @@
-<?php

-

-$lang['required'] 			= "The %s field is required.";

-$lang['isset']				= "The %s field must have a value.";

-$lang['valid_email']		= "The %s field must contain a valid email address.";

-$lang['valid_emails'] 		= "The %s field must contain all valid email addresses.";

-$lang['valid_url'] 			= "The %s field must contain a valid URL.";

-$lang['valid_ip'] 			= "The %s field must contain a valid IP.";

-$lang['min_length']			= "The %s field must be at least %s characters in length.";

-$lang['max_length']			= "The %s field can not exceed %s characters in length.";

-$lang['exact_length']		= "The %s field must be exactly %s characters in length.";

-$lang['alpha']				= "The %s field may only contain alphabetical characters.";

-$lang['alpha_numeric']		= "The %s field may only contain alpha-numeric characters.";

-$lang['alpha_dash']			= "The %s field may only contain alpha-numeric characters, underscores, and dashes.";

-$lang['numeric']			= "The %s field must contain a number.";

-$lang['is_numeric']			= "The %s field must contain a number.";

-$lang['integer']			= "The %s field must contain an integer.";

-$lang['matches']			= "The %s field does not match the %s field.";

-$lang['is_natural']			= "The %s field must contain a number.";

-$lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";

-

-

-/* End of file validation_lang.php */

+<?php
+
+$lang['required'] 			= "The %s field is required.";
+$lang['isset']				= "The %s field must have a value.";
+$lang['valid_email']		= "The %s field must contain a valid email address.";
+$lang['valid_emails'] 		= "The %s field must contain all valid email addresses.";
+$lang['valid_url'] 			= "The %s field must contain a valid URL.";
+$lang['valid_ip'] 			= "The %s field must contain a valid IP.";
+$lang['min_length']			= "The %s field must be at least %s characters in length.";
+$lang['max_length']			= "The %s field can not exceed %s characters in length.";
+$lang['exact_length']		= "The %s field must be exactly %s characters in length.";
+$lang['alpha']				= "The %s field may only contain alphabetical characters.";
+$lang['alpha_numeric']		= "The %s field may only contain alpha-numeric characters.";
+$lang['alpha_dash']			= "The %s field may only contain alpha-numeric characters, underscores, and dashes.";
+$lang['numeric']			= "The %s field must contain a number.";
+$lang['is_numeric']			= "The %s field must contain a number.";
+$lang['integer']			= "The %s field must contain an integer.";
+$lang['matches']			= "The %s field does not match the %s field.";
+$lang['is_natural']			= "The %s field must contain a number.";
+$lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";
+
+
+/* End of file validation_lang.php */
 /* Location: ./system/language/english/validation_lang.php */
\ No newline at end of file
diff --git a/system/language/index.html b/system/language/index.html
index 065d2da..c942a79 100644
--- a/system/language/index.html
+++ b/system/language/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/libraries/Benchmark.php b/system/libraries/Benchmark.php
index 4984bb1..fec5071 100644
--- a/system/libraries/Benchmark.php
+++ b/system/libraries/Benchmark.php
@@ -1,113 +1,113 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Benchmark Class

- *

- * This class enables you to mark points and calculate the time difference

- * between them.  Memory consumption can also be displayed.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/benchmark.html

- */

-class CI_Benchmark {

-

-	var $marker = array();

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set a benchmark marker

-	 *

-	 * Multiple calls to this function can be made so that several

-	 * execution points can be timed

-	 *

-	 * @access	public

-	 * @param	string	$name	name of the marker

-	 * @return	void

-	 */

-	function mark($name)

-	{

-		$this->marker[$name] = microtime();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Calculates the time difference between two marked points.

-	 *

-	 * If the first parameter is empty this function instead returns the

-	 * {elapsed_time} pseudo-variable. This permits the full system

-	 * execution time to be shown in a template. The output class will

-	 * swap the real value for this variable.

-	 *

-	 * @access	public

-	 * @param	string	a particular marked point

-	 * @param	string	a particular marked point

-	 * @param	integer	the number of decimal places

-	 * @return	mixed

-	 */

-	function elapsed_time($point1 = '', $point2 = '', $decimals = 4)

-	{

-		if ($point1 == '')

-		{

-			return '{elapsed_time}';

-		}

-

-		if ( ! isset($this->marker[$point1]))

-		{

-			return '';

-		}

-

-		if ( ! isset($this->marker[$point2]))

-		{

-			$this->marker[$point2] = microtime();

-		}

-	

-		list($sm, $ss) = explode(' ', $this->marker[$point1]);

-		list($em, $es) = explode(' ', $this->marker[$point2]);

-

-		return number_format(($em + $es) - ($sm + $ss), $decimals);

-	}

- 	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Memory Usage

-	 *

-	 * This function returns the {memory_usage} pseudo-variable.

-	 * This permits it to be put it anywhere in a template

-	 * without the memory being calculated until the end.

-	 * The output class will swap the real value for this variable.

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function memory_usage()

-	{

-		return '{memory_usage}';

-	}

-

-}

-

-// END CI_Benchmark class

-

-/* End of file Benchmark.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Benchmark Class
+ *
+ * This class enables you to mark points and calculate the time difference
+ * between them.  Memory consumption can also be displayed.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/benchmark.html
+ */
+class CI_Benchmark {
+
+	var $marker = array();
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set a benchmark marker
+	 *
+	 * Multiple calls to this function can be made so that several
+	 * execution points can be timed
+	 *
+	 * @access	public
+	 * @param	string	$name	name of the marker
+	 * @return	void
+	 */
+	function mark($name)
+	{
+		$this->marker[$name] = microtime();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Calculates the time difference between two marked points.
+	 *
+	 * If the first parameter is empty this function instead returns the
+	 * {elapsed_time} pseudo-variable. This permits the full system
+	 * execution time to be shown in a template. The output class will
+	 * swap the real value for this variable.
+	 *
+	 * @access	public
+	 * @param	string	a particular marked point
+	 * @param	string	a particular marked point
+	 * @param	integer	the number of decimal places
+	 * @return	mixed
+	 */
+	function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
+	{
+		if ($point1 == '')
+		{
+			return '{elapsed_time}';
+		}
+
+		if ( ! isset($this->marker[$point1]))
+		{
+			return '';
+		}
+
+		if ( ! isset($this->marker[$point2]))
+		{
+			$this->marker[$point2] = microtime();
+		}
+	
+		list($sm, $ss) = explode(' ', $this->marker[$point1]);
+		list($em, $es) = explode(' ', $this->marker[$point2]);
+
+		return number_format(($em + $es) - ($sm + $ss), $decimals);
+	}
+ 	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Memory Usage
+	 *
+	 * This function returns the {memory_usage} pseudo-variable.
+	 * This permits it to be put it anywhere in a template
+	 * without the memory being calculated until the end.
+	 * The output class will swap the real value for this variable.
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function memory_usage()
+	{
+		return '{memory_usage}';
+	}
+
+}
+
+// END CI_Benchmark class
+
+/* End of file Benchmark.php */
 /* Location: ./system/libraries/Benchmark.php */
\ No newline at end of file
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index dcf8a12..ca4b9d5 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -1,477 +1,477 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Calendar Class

- *

- * This class enables the creation of calendars

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/calendar.html

- */

-class CI_Calendar {

-

-	var $CI;

-	var $lang;

-	var $local_time;

-	var $template		= '';

-	var $start_day		= 'sunday';

-	var $month_type 	= 'long';

-	var $day_type		= 'abr';

-	var $show_next_prev	= FALSE;

-	var $next_prev_url	= '';

-

-	/**

-	 * Constructor

-	 *

-	 * Loads the calendar language file and sets the default time reference

-	 *

-	 * @access	public

-	 */

-	function CI_Calendar($config = array())

-	{		

-		$this->CI =& get_instance();

-		

-		if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE))

-		{

-			$this->CI->lang->load('calendar');

-		}

-

-		$this->local_time = time();

-		

-		if (count($config) > 0)

-		{

-			$this->initialize($config);

-		}

-		

-		log_message('debug', "Calendar Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Initialize the user preferences

-	 *

-	 * Accepts an associative array as input, containing display preferences

-	 *

-	 * @access	public

-	 * @param	array	config preferences

-	 * @return	void

-	 */	

-	function initialize($config = array())

-	{

-		foreach ($config as $key => $val)

-		{

-			if (isset($this->$key))

-			{

-				$this->$key = $val;

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate the calendar

-	 *

-	 * @access	public

-	 * @param	integer	the year

-	 * @param	integer	the month

-	 * @param	array	the data to be shown in the calendar cells

-	 * @return	string

-	 */

-	function generate($year = '', $month = '', $data = array())

-	{

-		// Set and validate the supplied month/year

-		if ($year == '')

-			$year  = date("Y", $this->local_time);

-			

-		if ($month == '')

-			$month = date("m", $this->local_time);

-			

- 		if (strlen($year) == 1)

-			$year = '200'.$year;

-		

- 		if (strlen($year) == 2)

-			$year = '20'.$year;

-

- 		if (strlen($month) == 1)

-			$month = '0'.$month;

-		

-		$adjusted_date = $this->adjust_date($month, $year);

-		

-		$month	= $adjusted_date['month'];

-		$year	= $adjusted_date['year'];

-		

-		// Determine the total days in the month

-		$total_days = $this->get_total_days($month, $year);

-						

-		// Set the starting day of the week

-		$start_days	= array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);

-		$start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];

-		

-		// Set the starting day number

-		$local_date = mktime(12, 0, 0, $month, 1, $year);

-		$date = getdate($local_date);

-		$day  = $start_day + 1 - $date["wday"];

-		

-		while ($day > 1)

-		{

-			$day -= 7;

-		}

-		

-		// Set the current month/year/day

-		// We use this to determine the "today" date

-		$cur_year	= date("Y", $this->local_time);

-		$cur_month	= date("m", $this->local_time);

-		$cur_day	= date("j", $this->local_time);

-		

-		$is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;

-	

-		// Generate the template data array

-		$this->parse_template();

-	

-		// Begin building the calendar output						

-		$out = $this->temp['table_open'];

-		$out .= "\n";	

-

-		$out .= "\n";		

-		$out .= $this->temp['heading_row_start'];

-		$out .= "\n";

-		

-		// "previous" month link

-		if ($this->show_next_prev == TRUE)

-		{

-			// Add a trailing slash to the  URL if needed

-			$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->next_prev_url);

-		

-			$adjusted_date = $this->adjust_date($month - 1, $year);

-			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);

-			$out .= "\n";

-		}

-

-		// Heading containing the month/year

-		$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;

-		

-		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);

-		$this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);

-		

-		$out .= $this->temp['heading_title_cell'];

-		$out .= "\n";

-

-		// "next" month link

-		if ($this->show_next_prev == TRUE)

-		{		

-			$adjusted_date = $this->adjust_date($month + 1, $year);

-			$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);

-		}

-

-		$out .= "\n";		

-		$out .= $this->temp['heading_row_end'];

-		$out .= "\n";

-

-		// Write the cells containing the days of the week

-		$out .= "\n";	

-		$out .= $this->temp['week_row_start'];

-		$out .= "\n";

-

-		$day_names = $this->get_day_names();

-

-		for ($i = 0; $i < 7; $i ++)

-		{

-			$out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);

-		}

-

-		$out .= "\n";

-		$out .= $this->temp['week_row_end'];

-		$out .= "\n";

-

-		// Build the main body of the calendar

-		while ($day <= $total_days)

-		{

-			$out .= "\n";

-			$out .= $this->temp['cal_row_start'];

-			$out .= "\n";

-

-			for ($i = 0; $i < 7; $i++)

-			{

-				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];

-			

-				if ($day > 0 AND $day <= $total_days)

-				{ 					

-					if (isset($data[$day]))

-					{	

-						// Cells with content

-						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];

-						$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));

-					}

-					else

-					{

-						// Cells with no content

-						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];

-						$out .= str_replace('{day}', $day, $temp);

-					}

-				}

-				else

-				{

-					// Blank cells

-					$out .= $this->temp['cal_cell_blank'];

-				}

-				

-				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];					  	

-				$day++;

-			}

-			

-			$out .= "\n";		

-			$out .= $this->temp['cal_row_end'];

-			$out .= "\n";		

-		}

-

-		$out .= "\n";		

-		$out .= $this->temp['table_close'];

-

-		return $out;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Month Name

-	 *

-	 * Generates a textual month name based on the numeric

-	 * month provided.

-	 *

-	 * @access	public

-	 * @param	integer	the month

-	 * @return	string

-	 */

-	function get_month_name($month)

-	{

-		if ($this->month_type == 'short')

-		{

-			$month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec');

-		}

-		else

-		{

-			$month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_may', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december');

-		}

-		

-		$month = $month_names[$month];

-		

-		if ($this->CI->lang->line($month) === FALSE)

-		{

-			return ucfirst(str_replace('cal_', '', $month));

-		}

-

-		return $this->CI->lang->line($month);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Day Names

-	 *

-	 * Returns an array of day names (Sunday, Monday, etc.) based

-	 * on the type.  Options: long, short, abrev

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	array

-	 */

-	function get_day_names($day_type = '')

-	{

-		if ($day_type != '')

-			$this->day_type = $day_type;

-	

-		if ($this->day_type == 'long')

-		{

-			$day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');

-		}

-		elseif ($this->day_type == 'short')

-		{

-			$day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');

-		}

-		else

-		{

-			$day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');

-		}

-	

-		$days = array();

-		foreach ($day_names as $val)

-		{			

-			$days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);

-		}

-	

-		return $days;

-	}

- 	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Adjust Date

-	 *

-	 * This function makes sure that we have a valid month/year.

-	 * For example, if you submit 13 as the month, the year will

-	 * increment and the month will become January.

-	 *

-	 * @access	public

-	 * @param	integer	the month

-	 * @param	integer	the year

-	 * @return	array

-	 */

-	function adjust_date($month, $year)

-	{

-		$date = array();

-

-		$date['month']	= $month;

-		$date['year']	= $year;

-

-		while ($date['month'] > 12)

-		{

-			$date['month'] -= 12;

-			$date['year']++;

-		}

-

-		while ($date['month'] <= 0)

-		{

-			$date['month'] += 12;

-			$date['year']--;

-		}

-

-		if (strlen($date['month']) == 1)

-		{

-			$date['month'] = '0'.$date['month'];

-		}

-

-		return $date;

-	}

- 	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Total days in a given month

-	 *

-	 * @access	public

-	 * @param	integer	the month

-	 * @param	integer	the year

-	 * @return	integer

-	 */

-	function get_total_days($month, $year)

-	{

-		$days_in_month	= array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

-

-		if ($month < 1 OR $month > 12)

-		{

-			return 0;

-		}

-

-		// Is the year a leap year?

-		if ($month == 2)

-		{

-			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))

-			{

-				return 29;

-			}

-		}

-

-		return $days_in_month[$month - 1];

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Default Template Data

-	 *

-	 * This is used in the event that the user has not created their own template

-	 *

-	 * @access	public

-	 * @return array

-	 */

-	function default_template()

-	{

-		return  array (

-						'table_open' 				=> '<table border="0" cellpadding="4" cellspacing="0">',

-						'heading_row_start' 		=> '<tr>',

-						'heading_previous_cell'		=> '<th><a href="{previous_url}">&lt;&lt;</a></th>',

-						'heading_title_cell' 		=> '<th colspan="{colspan}">{heading}</th>',

-						'heading_next_cell' 		=> '<th><a href="{next_url}">&gt;&gt;</a></th>',

-						'heading_row_end' 			=> '</tr>',

-						'week_row_start' 			=> '<tr>',

-						'week_day_cell' 			=> '<td>{week_day}</td>',

-						'week_row_end' 				=> '</tr>',

-						'cal_row_start' 			=> '<tr>',

-						'cal_cell_start' 			=> '<td>',

-						'cal_cell_start_today'		=> '<td>',

-						'cal_cell_content'			=> '<a href="{content}">{day}</a>',

-						'cal_cell_content_today'	=> '<a href="{content}"><strong>{day}</strong></a>',

-						'cal_cell_no_content'		=> '{day}',

-						'cal_cell_no_content_today'	=> '<strong>{day}</strong>',

-						'cal_cell_blank'			=> '&nbsp;',

-						'cal_cell_end'				=> '</td>',

-						'cal_cell_end_today'		=> '</td>',

-						'cal_row_end'				=> '</tr>',

-						'table_close'				=> '</table>'

-					);	

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Parse Template

-	 *

-	 * Harvests the data within the template {pseudo-variables}

-	 * used to display the calendar

-	 *

-	 * @access	public

-	 * @return	void

-	 */

- 	function parse_template()

- 	{

-		$this->temp = $this->default_template();

- 	

- 		if ($this->template == '')

- 		{

- 			return;

- 		}

- 		

-		$today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');

-		

-		foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content',  'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val)

-		{

-			if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))

-			{

-				$this->temp[$val] = $match['1'];

-			}

-			else

-			{

-				if (in_array($val, $today, TRUE))

-				{

-					$this->temp[$val] = $this->temp[str_replace('_today', '', $val)];

-				}

-			}

-		} 	

- 	}

-

-}

-

-// END CI_Calendar class

-

-/* End of file Calendar.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Calendar Class
+ *
+ * This class enables the creation of calendars
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/calendar.html
+ */
+class CI_Calendar {
+
+	var $CI;
+	var $lang;
+	var $local_time;
+	var $template		= '';
+	var $start_day		= 'sunday';
+	var $month_type 	= 'long';
+	var $day_type		= 'abr';
+	var $show_next_prev	= FALSE;
+	var $next_prev_url	= '';
+
+	/**
+	 * Constructor
+	 *
+	 * Loads the calendar language file and sets the default time reference
+	 *
+	 * @access	public
+	 */
+	function CI_Calendar($config = array())
+	{		
+		$this->CI =& get_instance();
+		
+		if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE))
+		{
+			$this->CI->lang->load('calendar');
+		}
+
+		$this->local_time = time();
+		
+		if (count($config) > 0)
+		{
+			$this->initialize($config);
+		}
+		
+		log_message('debug', "Calendar Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Initialize the user preferences
+	 *
+	 * Accepts an associative array as input, containing display preferences
+	 *
+	 * @access	public
+	 * @param	array	config preferences
+	 * @return	void
+	 */	
+	function initialize($config = array())
+	{
+		foreach ($config as $key => $val)
+		{
+			if (isset($this->$key))
+			{
+				$this->$key = $val;
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate the calendar
+	 *
+	 * @access	public
+	 * @param	integer	the year
+	 * @param	integer	the month
+	 * @param	array	the data to be shown in the calendar cells
+	 * @return	string
+	 */
+	function generate($year = '', $month = '', $data = array())
+	{
+		// Set and validate the supplied month/year
+		if ($year == '')
+			$year  = date("Y", $this->local_time);
+			
+		if ($month == '')
+			$month = date("m", $this->local_time);
+			
+ 		if (strlen($year) == 1)
+			$year = '200'.$year;
+		
+ 		if (strlen($year) == 2)
+			$year = '20'.$year;
+
+ 		if (strlen($month) == 1)
+			$month = '0'.$month;
+		
+		$adjusted_date = $this->adjust_date($month, $year);
+		
+		$month	= $adjusted_date['month'];
+		$year	= $adjusted_date['year'];
+		
+		// Determine the total days in the month
+		$total_days = $this->get_total_days($month, $year);
+						
+		// Set the starting day of the week
+		$start_days	= array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
+		$start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];
+		
+		// Set the starting day number
+		$local_date = mktime(12, 0, 0, $month, 1, $year);
+		$date = getdate($local_date);
+		$day  = $start_day + 1 - $date["wday"];
+		
+		while ($day > 1)
+		{
+			$day -= 7;
+		}
+		
+		// Set the current month/year/day
+		// We use this to determine the "today" date
+		$cur_year	= date("Y", $this->local_time);
+		$cur_month	= date("m", $this->local_time);
+		$cur_day	= date("j", $this->local_time);
+		
+		$is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE;
+	
+		// Generate the template data array
+		$this->parse_template();
+	
+		// Begin building the calendar output						
+		$out = $this->temp['table_open'];
+		$out .= "\n";	
+
+		$out .= "\n";		
+		$out .= $this->temp['heading_row_start'];
+		$out .= "\n";
+		
+		// "previous" month link
+		if ($this->show_next_prev == TRUE)
+		{
+			// Add a trailing slash to the  URL if needed
+			$this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->next_prev_url);
+		
+			$adjusted_date = $this->adjust_date($month - 1, $year);
+			$out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']);
+			$out .= "\n";
+		}
+
+		// Heading containing the month/year
+		$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
+		
+		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']);
+		$this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)."&nbsp;".$year, $this->temp['heading_title_cell']);
+		
+		$out .= $this->temp['heading_title_cell'];
+		$out .= "\n";
+
+		// "next" month link
+		if ($this->show_next_prev == TRUE)
+		{		
+			$adjusted_date = $this->adjust_date($month + 1, $year);
+			$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
+		}
+
+		$out .= "\n";		
+		$out .= $this->temp['heading_row_end'];
+		$out .= "\n";
+
+		// Write the cells containing the days of the week
+		$out .= "\n";	
+		$out .= $this->temp['week_row_start'];
+		$out .= "\n";
+
+		$day_names = $this->get_day_names();
+
+		for ($i = 0; $i < 7; $i ++)
+		{
+			$out .= str_replace('{week_day}', $day_names[($start_day + $i) %7], $this->temp['week_day_cell']);
+		}
+
+		$out .= "\n";
+		$out .= $this->temp['week_row_end'];
+		$out .= "\n";
+
+		// Build the main body of the calendar
+		while ($day <= $total_days)
+		{
+			$out .= "\n";
+			$out .= $this->temp['cal_row_start'];
+			$out .= "\n";
+
+			for ($i = 0; $i < 7; $i++)
+			{
+				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start'];
+			
+				if ($day > 0 AND $day <= $total_days)
+				{ 					
+					if (isset($data[$day]))
+					{	
+						// Cells with content
+						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
+						$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
+					}
+					else
+					{
+						// Cells with no content
+						$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
+						$out .= str_replace('{day}', $day, $temp);
+					}
+				}
+				else
+				{
+					// Blank cells
+					$out .= $this->temp['cal_cell_blank'];
+				}
+				
+				$out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end'];					  	
+				$day++;
+			}
+			
+			$out .= "\n";		
+			$out .= $this->temp['cal_row_end'];
+			$out .= "\n";		
+		}
+
+		$out .= "\n";		
+		$out .= $this->temp['table_close'];
+
+		return $out;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Month Name
+	 *
+	 * Generates a textual month name based on the numeric
+	 * month provided.
+	 *
+	 * @access	public
+	 * @param	integer	the month
+	 * @return	string
+	 */
+	function get_month_name($month)
+	{
+		if ($this->month_type == 'short')
+		{
+			$month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec');
+		}
+		else
+		{
+			$month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_may', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december');
+		}
+		
+		$month = $month_names[$month];
+		
+		if ($this->CI->lang->line($month) === FALSE)
+		{
+			return ucfirst(str_replace('cal_', '', $month));
+		}
+
+		return $this->CI->lang->line($month);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Day Names
+	 *
+	 * Returns an array of day names (Sunday, Monday, etc.) based
+	 * on the type.  Options: long, short, abrev
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	array
+	 */
+	function get_day_names($day_type = '')
+	{
+		if ($day_type != '')
+			$this->day_type = $day_type;
+	
+		if ($this->day_type == 'long')
+		{
+			$day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
+		}
+		elseif ($this->day_type == 'short')
+		{
+			$day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
+		}
+		else
+		{
+			$day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa');
+		}
+	
+		$days = array();
+		foreach ($day_names as $val)
+		{			
+			$days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val);
+		}
+	
+		return $days;
+	}
+ 	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Adjust Date
+	 *
+	 * This function makes sure that we have a valid month/year.
+	 * For example, if you submit 13 as the month, the year will
+	 * increment and the month will become January.
+	 *
+	 * @access	public
+	 * @param	integer	the month
+	 * @param	integer	the year
+	 * @return	array
+	 */
+	function adjust_date($month, $year)
+	{
+		$date = array();
+
+		$date['month']	= $month;
+		$date['year']	= $year;
+
+		while ($date['month'] > 12)
+		{
+			$date['month'] -= 12;
+			$date['year']++;
+		}
+
+		while ($date['month'] <= 0)
+		{
+			$date['month'] += 12;
+			$date['year']--;
+		}
+
+		if (strlen($date['month']) == 1)
+		{
+			$date['month'] = '0'.$date['month'];
+		}
+
+		return $date;
+	}
+ 	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Total days in a given month
+	 *
+	 * @access	public
+	 * @param	integer	the month
+	 * @param	integer	the year
+	 * @return	integer
+	 */
+	function get_total_days($month, $year)
+	{
+		$days_in_month	= array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+
+		if ($month < 1 OR $month > 12)
+		{
+			return 0;
+		}
+
+		// Is the year a leap year?
+		if ($month == 2)
+		{
+			if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
+			{
+				return 29;
+			}
+		}
+
+		return $days_in_month[$month - 1];
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Default Template Data
+	 *
+	 * This is used in the event that the user has not created their own template
+	 *
+	 * @access	public
+	 * @return array
+	 */
+	function default_template()
+	{
+		return  array (
+						'table_open' 				=> '<table border="0" cellpadding="4" cellspacing="0">',
+						'heading_row_start' 		=> '<tr>',
+						'heading_previous_cell'		=> '<th><a href="{previous_url}">&lt;&lt;</a></th>',
+						'heading_title_cell' 		=> '<th colspan="{colspan}">{heading}</th>',
+						'heading_next_cell' 		=> '<th><a href="{next_url}">&gt;&gt;</a></th>',
+						'heading_row_end' 			=> '</tr>',
+						'week_row_start' 			=> '<tr>',
+						'week_day_cell' 			=> '<td>{week_day}</td>',
+						'week_row_end' 				=> '</tr>',
+						'cal_row_start' 			=> '<tr>',
+						'cal_cell_start' 			=> '<td>',
+						'cal_cell_start_today'		=> '<td>',
+						'cal_cell_content'			=> '<a href="{content}">{day}</a>',
+						'cal_cell_content_today'	=> '<a href="{content}"><strong>{day}</strong></a>',
+						'cal_cell_no_content'		=> '{day}',
+						'cal_cell_no_content_today'	=> '<strong>{day}</strong>',
+						'cal_cell_blank'			=> '&nbsp;',
+						'cal_cell_end'				=> '</td>',
+						'cal_cell_end_today'		=> '</td>',
+						'cal_row_end'				=> '</tr>',
+						'table_close'				=> '</table>'
+					);	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Parse Template
+	 *
+	 * Harvests the data within the template {pseudo-variables}
+	 * used to display the calendar
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+ 	function parse_template()
+ 	{
+		$this->temp = $this->default_template();
+ 	
+ 		if ($this->template == '')
+ 		{
+ 			return;
+ 		}
+ 		
+		$today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today');
+		
+		foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content',  'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val)
+		{
+			if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match))
+			{
+				$this->temp[$val] = $match['1'];
+			}
+			else
+			{
+				if (in_array($val, $today, TRUE))
+				{
+					$this->temp[$val] = $this->temp[str_replace('_today', '', $val)];
+				}
+			}
+		} 	
+ 	}
+
+}
+
+// END CI_Calendar class
+
+/* End of file Calendar.php */
 /* Location: ./system/libraries/Calendar.php */
\ No newline at end of file
diff --git a/system/libraries/Config.php b/system/libraries/Config.php
index a9cf9f4..027f6bf 100644
--- a/system/libraries/Config.php
+++ b/system/libraries/Config.php
@@ -1,244 +1,244 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Config Class

- *

- * This class contains functions that enable config files to be managed

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/config.html

- */

-class CI_Config {

-

-	var $config = array();

-	var $is_loaded = array();

-

-	/**

-	 * Constructor

-	 *

-	 * Sets the $config data from the primary config.php file as a class variable

-	 *

-	 * @access   public

-	 * @param   string	the config file name

-	 * @param   boolean  if configuration values should be loaded into their own section

-	 * @param   boolean  true if errors should just return false, false if an error message should be displayed

-	 * @return  boolean  if the file was successfully loaded or not

-	 */

-	function CI_Config()

-	{

-		$this->config =& get_config();

-		log_message('debug', "Config Class Initialized");

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load Config File

-	 *

-	 * @access	public

-	 * @param	string	the config file name

-	 * @return	boolean	if the file was loaded correctly

-	 */	

-	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)

-	{

-		$file = ($file == '') ? 'config' : str_replace(EXT, '', $file);

-	

-		if (in_array($file, $this->is_loaded, TRUE))

-		{

-			return TRUE;

-		}

-

-		if ( ! file_exists(APPPATH.'config/'.$file.EXT))

-		{

-			if ($fail_gracefully === TRUE)

-			{

-				return FALSE;

-			}

-			show_error('The configuration file '.$file.EXT.' does not exist.');

-		}

-	

-		include(APPPATH.'config/'.$file.EXT);

-

-		if ( ! isset($config) OR ! is_array($config))

-		{

-			if ($fail_gracefully === TRUE)

-			{

-				return FALSE;

-			}

-			show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.');

-		}

-

-		if ($use_sections === TRUE)

-		{

-			if (isset($this->config[$file]))

-			{

-				$this->config[$file] = array_merge($this->config[$file], $config);

-			}

-			else

-			{

-				$this->config[$file] = $config;

-			}

-		}

-		else

-		{

-			$this->config = array_merge($this->config, $config);

-		}

-

-		$this->is_loaded[] = $file;

-		unset($config);

-

-		log_message('debug', 'Config file loaded: config/'.$file.EXT);

-		return TRUE;

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a config file item

-	 *

-	 *

-	 * @access	public

-	 * @param	string	the config item name

-	 * @param	string	the index name

-	 * @param	bool

-	 * @return	string

-	 */

-	function item($item, $index = '')

-	{	

-		if ($index == '')

-		{	

-			if ( ! isset($this->config[$item]))

-			{

-				return FALSE;

-			}

-

-			$pref = $this->config[$item];

-		}

-		else

-		{

-			if ( ! isset($this->config[$index]))

-			{

-				return FALSE;

-			}

-

-			if ( ! isset($this->config[$index][$item]))

-			{

-				return FALSE;

-			}

-

-			$pref = $this->config[$index][$item];

-		}

-

-		return $pref;

-	}

-  	

-  	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a config file item - adds slash after item

-	 *

-	 * The second parameter allows a slash to be added to the end of

-	 * the item, in the case of a path.

-	 *

-	 * @access	public

-	 * @param	string	the config item name

-	 * @param	bool

-	 * @return	string

-	 */

-	function slash_item($item)

-	{

-		if ( ! isset($this->config[$item]))

-		{

-			return FALSE;

-		}

-

-		$pref = $this->config[$item];

-

-		if ($pref != '' && substr($pref, -1) != '/')

-		{	

-			$pref .= '/';

-		}

-

-		return $pref;

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Site URL

-	 *

-	 * @access	public

-	 * @param	string	the URI string

-	 * @return	string

-	 */

-	function site_url($uri = '')

-	{

-		if (is_array($uri))

-		{

-			$uri = implode('/', $uri);

-		}

-

-		if ($uri == '')

-		{

-			return $this->slash_item('base_url').$this->item('index_page');

-		}

-		else

-		{

-			$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');

-			return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix;

-		}

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * System URL

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function system_url()

-	{

-		$x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));

-		return $this->slash_item('base_url').end($x).'/';

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set a config file item

-	 *

-	 * @access	public

-	 * @param	string	the config item key

-	 * @param	string	the config item value

-	 * @return	void

-	 */

-	function set_item($item, $value)

-	{

-		$this->config[$item] = $value;

-	}

-

-}

-

-// END CI_Config class

-

-/* End of file Config.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Config Class
+ *
+ * This class contains functions that enable config files to be managed
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/config.html
+ */
+class CI_Config {
+
+	var $config = array();
+	var $is_loaded = array();
+
+	/**
+	 * Constructor
+	 *
+	 * Sets the $config data from the primary config.php file as a class variable
+	 *
+	 * @access   public
+	 * @param   string	the config file name
+	 * @param   boolean  if configuration values should be loaded into their own section
+	 * @param   boolean  true if errors should just return false, false if an error message should be displayed
+	 * @return  boolean  if the file was successfully loaded or not
+	 */
+	function CI_Config()
+	{
+		$this->config =& get_config();
+		log_message('debug', "Config Class Initialized");
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load Config File
+	 *
+	 * @access	public
+	 * @param	string	the config file name
+	 * @return	boolean	if the file was loaded correctly
+	 */	
+	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+	{
+		$file = ($file == '') ? 'config' : str_replace(EXT, '', $file);
+	
+		if (in_array($file, $this->is_loaded, TRUE))
+		{
+			return TRUE;
+		}
+
+		if ( ! file_exists(APPPATH.'config/'.$file.EXT))
+		{
+			if ($fail_gracefully === TRUE)
+			{
+				return FALSE;
+			}
+			show_error('The configuration file '.$file.EXT.' does not exist.');
+		}
+	
+		include(APPPATH.'config/'.$file.EXT);
+
+		if ( ! isset($config) OR ! is_array($config))
+		{
+			if ($fail_gracefully === TRUE)
+			{
+				return FALSE;
+			}
+			show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.');
+		}
+
+		if ($use_sections === TRUE)
+		{
+			if (isset($this->config[$file]))
+			{
+				$this->config[$file] = array_merge($this->config[$file], $config);
+			}
+			else
+			{
+				$this->config[$file] = $config;
+			}
+		}
+		else
+		{
+			$this->config = array_merge($this->config, $config);
+		}
+
+		$this->is_loaded[] = $file;
+		unset($config);
+
+		log_message('debug', 'Config file loaded: config/'.$file.EXT);
+		return TRUE;
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a config file item
+	 *
+	 *
+	 * @access	public
+	 * @param	string	the config item name
+	 * @param	string	the index name
+	 * @param	bool
+	 * @return	string
+	 */
+	function item($item, $index = '')
+	{	
+		if ($index == '')
+		{	
+			if ( ! isset($this->config[$item]))
+			{
+				return FALSE;
+			}
+
+			$pref = $this->config[$item];
+		}
+		else
+		{
+			if ( ! isset($this->config[$index]))
+			{
+				return FALSE;
+			}
+
+			if ( ! isset($this->config[$index][$item]))
+			{
+				return FALSE;
+			}
+
+			$pref = $this->config[$index][$item];
+		}
+
+		return $pref;
+	}
+  	
+  	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a config file item - adds slash after item
+	 *
+	 * The second parameter allows a slash to be added to the end of
+	 * the item, in the case of a path.
+	 *
+	 * @access	public
+	 * @param	string	the config item name
+	 * @param	bool
+	 * @return	string
+	 */
+	function slash_item($item)
+	{
+		if ( ! isset($this->config[$item]))
+		{
+			return FALSE;
+		}
+
+		$pref = $this->config[$item];
+
+		if ($pref != '' && substr($pref, -1) != '/')
+		{	
+			$pref .= '/';
+		}
+
+		return $pref;
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Site URL
+	 *
+	 * @access	public
+	 * @param	string	the URI string
+	 * @return	string
+	 */
+	function site_url($uri = '')
+	{
+		if (is_array($uri))
+		{
+			$uri = implode('/', $uri);
+		}
+
+		if ($uri == '')
+		{
+			return $this->slash_item('base_url').$this->item('index_page');
+		}
+		else
+		{
+			$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
+			return $this->slash_item('base_url').$this->slash_item('index_page').preg_replace("|^/*(.+?)/*$|", "\\1", $uri).$suffix;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * System URL
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function system_url()
+	{
+		$x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
+		return $this->slash_item('base_url').end($x).'/';
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set a config file item
+	 *
+	 * @access	public
+	 * @param	string	the config item key
+	 * @param	string	the config item value
+	 * @return	void
+	 */
+	function set_item($item, $value)
+	{
+		$this->config[$item] = $value;
+	}
+
+}
+
+// END CI_Config class
+
+/* End of file Config.php */
 /* Location: ./system/libraries/Config.php */
\ No newline at end of file
diff --git a/system/libraries/Controller.php b/system/libraries/Controller.php
index b6e10a3..5d9b80d 100644
--- a/system/libraries/Controller.php
+++ b/system/libraries/Controller.php
@@ -1,127 +1,127 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Application Controller Class

- *

- * This class object is the super class that every library in

- * CodeIgniter will be assigned to.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/general/controllers.html

- */

-class Controller extends CI_Base {

-

-	var $_ci_scaffolding	= FALSE;

-	var $_ci_scaff_table	= FALSE;

-	

-	/**

-	 * Constructor

-	 *

-	 * Calls the initialize() function

-	 */

-	function Controller()

-	{	

-		parent::CI_Base();

-		$this->_ci_initialize();

-		log_message('debug', "Controller Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize

-	 *

-	 * Assigns all the bases classes loaded by the front controller to

-	 * variables in this class.  Also calls the autoload routine.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _ci_initialize()

-	{

-		// Assign all the class objects that were instantiated by the

-		// front controller to local class variables so that CI can be

-		// run as one big super object.

-		$classes = array(

-							'config'	=> 'Config',

-							'input'		=> 'Input',

-							'benchmark'	=> 'Benchmark',

-							'uri'		=> 'URI',

-							'output'	=> 'Output',

-							'lang'		=> 'Language',

-							'router'	=> 'Router'

-							);

-		

-		foreach ($classes as $var => $class)

-		{

-			$this->$var =& load_class($class);

-		}

-

-		// In PHP 5 the Loader class is run as a discreet

-		// class.  In PHP 4 it extends the Controller

-		if (floor(phpversion()) >= 5)

-		{

-			$this->load =& load_class('Loader');

-			$this->load->_ci_autoloader();

-		}

-		else

-		{

-			$this->_ci_autoloader();

-			

-			// sync up the objects since PHP4 was working from a copy

-			foreach (array_keys(get_object_vars($this)) as $attribute)

-			{

-				if (is_object($this->$attribute))

-				{

-					$this->load->$attribute =& $this->$attribute;

-				}

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Run Scaffolding

-	 *

-	 * @access	private

-	 * @return	void

-	 */	

-	function _ci_scaffolding()

-	{

-		if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)

-		{

-			show_404('Scaffolding unavailable');

-		}

-		

-		$method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3);

-		

-		require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);

-		$scaff = new Scaffolding($this->_ci_scaff_table);

-		$scaff->$method();

-	}

-

-

-}

-// END _Controller class

-

-/* End of file Controller.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Application Controller Class
+ *
+ * This class object is the super class that every library in
+ * CodeIgniter will be assigned to.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/general/controllers.html
+ */
+class Controller extends CI_Base {
+
+	var $_ci_scaffolding	= FALSE;
+	var $_ci_scaff_table	= FALSE;
+	
+	/**
+	 * Constructor
+	 *
+	 * Calls the initialize() function
+	 */
+	function Controller()
+	{	
+		parent::CI_Base();
+		$this->_ci_initialize();
+		log_message('debug', "Controller Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize
+	 *
+	 * Assigns all the bases classes loaded by the front controller to
+	 * variables in this class.  Also calls the autoload routine.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _ci_initialize()
+	{
+		// Assign all the class objects that were instantiated by the
+		// front controller to local class variables so that CI can be
+		// run as one big super object.
+		$classes = array(
+							'config'	=> 'Config',
+							'input'		=> 'Input',
+							'benchmark'	=> 'Benchmark',
+							'uri'		=> 'URI',
+							'output'	=> 'Output',
+							'lang'		=> 'Language',
+							'router'	=> 'Router'
+							);
+		
+		foreach ($classes as $var => $class)
+		{
+			$this->$var =& load_class($class);
+		}
+
+		// In PHP 5 the Loader class is run as a discreet
+		// class.  In PHP 4 it extends the Controller
+		if (floor(phpversion()) >= 5)
+		{
+			$this->load =& load_class('Loader');
+			$this->load->_ci_autoloader();
+		}
+		else
+		{
+			$this->_ci_autoloader();
+			
+			// sync up the objects since PHP4 was working from a copy
+			foreach (array_keys(get_object_vars($this)) as $attribute)
+			{
+				if (is_object($this->$attribute))
+				{
+					$this->load->$attribute =& $this->$attribute;
+				}
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Run Scaffolding
+	 *
+	 * @access	private
+	 * @return	void
+	 */	
+	function _ci_scaffolding()
+	{
+		if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
+		{
+			show_404('Scaffolding unavailable');
+		}
+		
+		$method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3);
+		
+		require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
+		$scaff = new Scaffolding($this->_ci_scaff_table);
+		$scaff->$method();
+	}
+
+
+}
+// END _Controller class
+
+/* End of file Controller.php */
 /* Location: ./system/libraries/Controller.php */
\ No newline at end of file
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index a0ede72..94f517c 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1,2028 +1,2028 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Email Class

- *

- * Permits email to be sent using Mail, Sendmail, or SMTP.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/email.html

- */

-class CI_Email {

-

-	var	$useragent		= "CodeIgniter";

-	var	$mailpath		= "/usr/sbin/sendmail";	// Sendmail path

-	var	$protocol		= "mail";	// mail/sendmail/smtp

-	var	$smtp_host		= "";		// SMTP Server.  Example: mail.earthlink.net

-	var	$smtp_user		= "";		// SMTP Username

-	var	$smtp_pass		= "";		// SMTP Password

-	var	$smtp_port		= "25";		// SMTP Port

-	var	$smtp_timeout	= 5;		// SMTP Timeout in seconds

-	var	$wordwrap		= TRUE;		// TRUE/FALSE  Turns word-wrap on/off

-	var	$wrapchars		= "76";		// Number of characters to wrap at.

-	var	$mailtype		= "text";	// text/html  Defines email formatting

-	var	$charset		= "utf-8";	// Default char set: iso-8859-1 or us-ascii

-	var	$multipart		= "mixed";	// "mixed" (in the body) or "related" (separate)

-	var $alt_message	= '';		// Alternative message for HTML emails

-	var	$validate		= FALSE;	// TRUE/FALSE.  Enables email validation

-	var	$priority		= "3";		// Default priority (1 - 5)

-	var	$newline		= "\n";		// Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)

-	var $crlf			= "\n";		// The RFC 2045 compliant CRLF for quoted-printable is "\r\n".  Apparently some servers,

-									// even on the receiving end think they need to muck with CRLFs, so using "\n", while

-									// distasteful, is the only thing that seems to work for all environments.

-	var $send_multipart	= TRUE;		// TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override.  Set to FALSE for Yahoo.

-	var	$bcc_batch_mode	= FALSE;	// TRUE/FALSE  Turns on/off Bcc batch feature

-	var	$bcc_batch_size	= 200;		// If bcc_batch_mode = TRUE, sets max number of Bccs in each batch

-	var $_safe_mode		= FALSE;

-	var	$_subject		= "";

-	var	$_body			= "";

-	var	$_finalbody		= "";

-	var	$_alt_boundary	= "";

-	var	$_atc_boundary	= "";

-	var	$_header_str	= "";

-	var	$_smtp_connect	= "";

-	var	$_encoding		= "8bit";

-	var $_IP			= FALSE;

-	var	$_smtp_auth		= FALSE;

-	var $_replyto_flag	= FALSE;

-	var	$_debug_msg		= array();

-	var	$_recipients	= array();

-	var	$_cc_array		= array();

-	var	$_bcc_array		= array();

-	var	$_headers		= array();

-	var	$_attach_name	= array();

-	var	$_attach_type	= array();

-	var	$_attach_disp	= array();

-	var	$_protocols		= array('mail', 'sendmail', 'smtp');

-	var	$_base_charsets	= array('us-ascii', 'iso-2022-');	// 7-bit charsets (excluding language suffix)

-	var	$_bit_depths	= array('7bit', '8bit');

-	var	$_priorities	= array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');

-

-

-	/**

-	 * Constructor - Sets Email Preferences

-	 *

-	 * The constructor can be passed an array of config values

-	 */

-	function CI_Email($config = array())

-	{

-		if (count($config) > 0)

-		{

-			$this->initialize($config);

-		}

-		else

-		{

-			$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;

-			$this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;

-		}

-

-		log_message('debug', "Email Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize preferences

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function initialize($config = array())

-	{

-		$this->clear();

-		foreach ($config as $key => $val)

-		{

-			if (isset($this->$key))

-			{

-				$method = 'set_'.$key;

-

-				if (method_exists($this, $method))

-				{

-					$this->$method($val);

-				}

-				else

-				{

-					$this->$key = $val;

-				}

-			}

-		}

-

-		$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;

-		$this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize the Email Data

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function clear($clear_attachments = FALSE)

-	{

-		$this->_subject		= "";

-		$this->_body		= "";

-		$this->_finalbody	= "";

-		$this->_header_str	= "";

-		$this->_replyto_flag = FALSE;

-		$this->_recipients	= array();

-		$this->_headers		= array();

-		$this->_debug_msg	= array();

-

-		$this->_set_header('User-Agent', $this->useragent);

-		$this->_set_header('Date', $this->_set_date());

-

-		if ($clear_attachments !== FALSE)

-		{

-			$this->_attach_name = array();

-			$this->_attach_type = array();

-			$this->_attach_disp = array();

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set FROM

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function from($from, $name = '')

-	{

-		if (preg_match( '/\<(.*)\>/', $from, $match))

-		{

-			$from = $match['1'];

-		}

-

-		if ($this->validate)

-		{

-			$this->validate_email($this->_str_to_array($from));

-		}

-

-		// prepare the display name

-		if ($name != '')

-		{

-			// only use Q encoding if there are characters that would require it

-			if ( ! preg_match('/[\200-\377]/', $name))

-			{

-				// add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes

-				$name = '"'.addcslashes($name, '\0..\37\177"\\').'"';

-			}

-			else

-			{

-				$name = $this->_prep_q_encoding($name, TRUE);

-			}

-		}

-

-		$this->_set_header('From', $name.' <'.$from.'>');

-		$this->_set_header('Return-Path', '<'.$from.'>');

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Reply-to

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function reply_to($replyto, $name = '')

-	{

-		if (preg_match( '/\<(.*)\>/', $replyto, $match))

-		{

-			$replyto = $match['1'];

-		}

-

-		if ($this->validate)

-		{

-			$this->validate_email($this->_str_to_array($replyto));

-		}

-

-		if ($name == '')

-		{

-			$name = $replyto;

-		}

-

-		if (strncmp($name, '"', 1) != 0)

-		{

-			$name = '"'.$name.'"';

-		}

-

-		$this->_set_header('Reply-To', $name.' <'.$replyto.'>');

-		$this->_replyto_flag = TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Recipients

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function to($to)

-	{

-		$to = $this->_str_to_array($to);

-		$to = $this->clean_email($to);

-

-		if ($this->validate)

-		{

-			$this->validate_email($to);

-		}

-

-		if ($this->_get_protocol() != 'mail')

-		{

-			$this->_set_header('To', implode(", ", $to));

-		}

-

-		switch ($this->_get_protocol())

-		{

-			case 'smtp'		: $this->_recipients = $to;

-			break;

-			case 'sendmail'	: $this->_recipients = implode(", ", $to);

-			break;

-			case 'mail'		: $this->_recipients = implode(", ", $to);

-			break;

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set CC

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function cc($cc)

-	{

-		$cc = $this->_str_to_array($cc);

-		$cc = $this->clean_email($cc);

-

-		if ($this->validate)

-		{

-			$this->validate_email($cc);

-		}

-

-		$this->_set_header('Cc', implode(", ", $cc));

-

-		if ($this->_get_protocol() == "smtp")

-		{

-			$this->_cc_array = $cc;

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set BCC

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function bcc($bcc, $limit = '')

-	{

-		if ($limit != '' && is_numeric($limit))

-		{

-			$this->bcc_batch_mode = TRUE;

-			$this->bcc_batch_size = $limit;

-		}

-

-		$bcc = $this->_str_to_array($bcc);

-		$bcc = $this->clean_email($bcc);

-

-		if ($this->validate)

-		{

-			$this->validate_email($bcc);

-		}

-

-		if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))

-		{

-			$this->_bcc_array = $bcc;

-		}

-		else

-		{

-			$this->_set_header('Bcc', implode(", ", $bcc));

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Email Subject

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function subject($subject)

-	{

-		$subject = $this->_prep_q_encoding($subject);

-		$this->_set_header('Subject', $subject);

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Body

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function message($body)

-	{

-		$this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));

-	}

- 

-	// --------------------------------------------------------------------

-

-	/**

-	 * Assign file attachments

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function attach($filename, $disposition = 'attachment')

-	{

-		$this->_attach_name[] = $filename;

-		$this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));

-		$this->_attach_disp[] = $disposition; // Can also be 'inline'  Not sure if it matters

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add a Header Item

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function _set_header($header, $value)

-	{

-		$this->_headers[$header] = $value;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Convert a String to an Array

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	array

-	 */

-	function _str_to_array($email)

-	{

-		if ( ! is_array($email))

-		{

-			if (strpos($email, ',') !== FALSE)

-			{

-				$email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);

-			}

-			else

-			{

-				$email = trim($email);

-				settype($email, "array");

-			}

-		}

-		return $email;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Multipart Value

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_alt_message($str = '')

-	{

-		$this->alt_message = ($str == '') ? '' : $str;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Mailtype

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_mailtype($type = 'text')

-	{

-		$this->mailtype = ($type == 'html') ? 'html' : 'text';

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Wordwrap

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_wordwrap($wordwrap = TRUE)

-	{

-		$this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Protocol

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_protocol($protocol = 'mail')

-	{

-		$this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Priority

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */

-	function set_priority($n = 3)

-	{

-		if ( ! is_numeric($n))

-		{

-			$this->priority = 3;

-			return;

-		}

-

-		if ($n < 1 OR $n > 5)

-		{

-			$this->priority = 3;

-			return;

-		}

-

-		$this->priority = $n;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Newline Character

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_newline($newline = "\n")

-	{

-		if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")

-		{

-			$this->newline	= "\n";

-			return;

-		}

-

-		$this->newline	= $newline;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set CRLF

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_crlf($crlf = "\n")

-	{

-		if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")

-		{

-			$this->crlf	= "\n";

-			return;

-		}

-

-		$this->crlf	= $crlf;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Message Boundary

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _set_boundaries()

-	{

-		$this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative

-		$this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get the Message ID

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_message_id()

-	{

-		$from = $this->_headers['Return-Path'];

-		$from = str_replace(">", "", $from);

-		$from = str_replace("<", "", $from);

-

-		return  "<".uniqid('').strstr($from, '@').">";

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Mail Protocol

-	 *

-	 * @access	private

-	 * @param	bool

-	 * @return	string

-	 */

-	function _get_protocol($return = TRUE)

-	{

-		$this->protocol = strtolower($this->protocol);

-		$this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;

-

-		if ($return == TRUE)

-		{

-			return $this->protocol;

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Mail Encoding

-	 *

-	 * @access	private

-	 * @param	bool

-	 * @return	string

-	 */

-	function _get_encoding($return = TRUE)

-	{

-		$this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;

-

-		foreach ($this->_base_charsets as $charset)

-		{

-			if (strncmp($charset, $this->charset, strlen($charset)) == 0)

-			{

-				$this->_encoding = '7bit';

-			}

-		}

-

-		if ($return == TRUE)

-		{

-			return $this->_encoding;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get content type (text/html/attachment)

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_content_type()

-	{

-		if	($this->mailtype == 'html' &&  count($this->_attach_name) == 0)

-		{

-			return 'html';

-		}

-		elseif	($this->mailtype == 'html' &&  count($this->_attach_name)  > 0)

-		{

-			return 'html-attach';

-		}

-		elseif	($this->mailtype == 'text' &&  count($this->_attach_name)  > 0)

-		{

-			return 'plain-attach';

-		}

-		else

-		{

-			return 'plain';

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set RFC 822 Date

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _set_date()

-	{

-		$timezone = date("Z");

-		$operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';

-		$timezone = abs($timezone);

-		$timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;

-

-		return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Mime message

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_mime_message()

-	{

-		return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Validate Email Address

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function validate_email($email)

-	{

-		if ( ! is_array($email))

-		{

-			$this->_set_error_message('email_must_be_array');

-			return FALSE;

-		}

-

-		foreach ($email as $val)

-		{

-			if ( ! $this->valid_email($val))

-			{

-				$this->_set_error_message('email_invalid_address', $val);

-				return FALSE;

-			}

-		}

-

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Email Validation

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function valid_email($address)

-	{

-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Clean Extended Email Address: Joe Smith <joe@smith.com>

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function clean_email($email)

-	{

-		if ( ! is_array($email))

-		{

-			if (preg_match('/\<(.*)\>/', $email, $match))

-			{

-		   		return $match['1'];

-			}

-		   	else

-			{

-		   		return $email;

-			}

-		}

-

-		$clean_email = array();

-

-		foreach ($email as $addy)

-		{

-			if (preg_match( '/\<(.*)\>/', $addy, $match))

-			{

-		   		$clean_email[] = $match['1'];

-			}

-		   	else

-			{

-		   		$clean_email[] = $addy;

-			}

-		}

-

-		return $clean_email;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Build alternative plain text message

-	 *

-	 * This function provides the raw message for use

-	 * in plain-text headers of HTML-formatted emails.

-	 * If the user hasn't specified his own alternative message

-	 * it creates one by stripping the HTML

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_alt_message()

-	{

-		if ($this->alt_message != "")

-		{

-			return $this->word_wrap($this->alt_message, '76');

-		}

-

-		if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))

-		{

-			$body = $match['1'];

-		}

-		else

-		{

-			$body = $this->_body;

-		}

-

-		$body = trim(strip_tags($body));

-		$body = preg_replace( '#<!--(.*)--\>#', "", $body);

-		$body = str_replace("\t", "", $body);

-

-		for ($i = 20; $i >= 3; $i--)

-		{

-			$n = "";

-

-			for ($x = 1; $x <= $i; $x ++)

-			{

-				 $n .= "\n";

-			}

-

-			$body = str_replace($n, "\n\n", $body);

-		}

-

-		return $this->word_wrap($body, '76');

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Word Wrap

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	integer

-	 * @return	string

-	 */

-	function word_wrap($str, $charlim = '')

-	{

-		// Se the character limit

-		if ($charlim == '')

-		{

-			$charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;

-		}

-

-		// Reduce multiple spaces

-		$str = preg_replace("| +|", " ", $str);

-

-		// Standardize newlines

-		if (strpos($str, "\r") !== FALSE)

-		{

-			$str = str_replace(array("\r\n", "\r"), "\n", $str);

-		}

-

-		// If the current word is surrounded by {unwrap} tags we'll

-		// strip the entire chunk and replace it with a marker.

-		$unwrap = array();

-		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))

-		{

-			for ($i = 0; $i < count($matches['0']); $i++)

-			{

-				$unwrap[] = $matches['1'][$i];

-				$str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);

-			}

-		}

-

-		// Use PHP's native function to do the initial wordwrap.

-		// We set the cut flag to FALSE so that any individual words that are

-		// too long get left alone.  In the next step we'll deal with them.

-		$str = wordwrap($str, $charlim, "\n", FALSE);

-

-		// Split the string into individual lines of text and cycle through them

-		$output = "";

-		foreach (explode("\n", $str) as $line)

-		{

-			// Is the line within the allowed character count?

-			// If so we'll join it to the output and continue

-			if (strlen($line) <= $charlim)

-			{

-				$output .= $line.$this->newline;

-				continue;

-			}

-

-			$temp = '';

-			while((strlen($line)) > $charlim)

-			{

-				// If the over-length word is a URL we won't wrap it

-				if (preg_match("!\[url.+\]|://|wwww.!", $line))

-				{

-					break;

-				}

-

-				// Trim the word down

-				$temp .= substr($line, 0, $charlim-1);

-				$line = substr($line, $charlim-1);

-			}

-

-			// If $temp contains data it means we had to split up an over-length

-			// word into smaller chunks so we'll add it back to our current line

-			if ($temp != '')

-			{

-				$output .= $temp.$this->newline.$line;

-			}

-			else

-			{

-				$output .= $line;

-			}

-

-			$output .= $this->newline;

-		}

-

-		// Put our markers back

-		if (count($unwrap) > 0)

-		{

-			foreach ($unwrap as $key => $val)

-			{

-				$output = str_replace("{{unwrapped".$key."}}", $val, $output);

-			}

-		}

-

-		return $output;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Build final headers

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _build_headers()

-	{

-		$this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));

-		$this->_set_header('X-Mailer', $this->useragent);

-		$this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);

-		$this->_set_header('Message-ID', $this->_get_message_id());

-		$this->_set_header('Mime-Version', '1.0');

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write Headers as a string

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _write_headers()

-	{

-		if ($this->protocol == 'mail')

-		{

-			$this->_subject = $this->_headers['Subject'];

-			unset($this->_headers['Subject']);

-		}

-

-		reset($this->_headers);

-		$this->_header_str = "";

-

-		foreach($this->_headers as $key => $val)

-		{

-			$val = trim($val);

-

-			if ($val != "")

-			{

-				$this->_header_str .= $key.": ".$val.$this->newline;

-			}

-		}

-

-		if ($this->_get_protocol() == 'mail')

-		{

-			$this->_header_str = substr($this->_header_str, 0, -1);

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Build Final Body and attachments

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _build_message()

-	{

-		if ($this->wordwrap === TRUE  AND  $this->mailtype != 'html')

-		{

-			$this->_body = $this->word_wrap($this->_body);

-		}

-

-		$this->_set_boundaries();

-		$this->_write_headers();

-

-		$hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';

-

-		switch ($this->_get_content_type())

-		{

-			case 'plain' :

-

-				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;

-				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();

-

-				if ($this->_get_protocol() == 'mail')

-				{

-					$this->_header_str .= $hdr;

-					$this->_finalbody = $this->_body;

-

-					return;

-				}

-

-				$hdr .= $this->newline . $this->newline . $this->_body;

-

-				$this->_finalbody = $hdr;

-				return;

-

-			break;

-			case 'html' :

-

-				if ($this->send_multipart === FALSE)

-				{

-					$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;

-					$hdr .= "Content-Transfer-Encoding: quoted-printable";

-				}

-				else

-				{

-					$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;

-					$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;

-					$hdr .= "--" . $this->_alt_boundary . $this->newline;

-

-					$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;

-					$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;

-					$hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;

-

-					$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;

-					$hdr .= "Content-Transfer-Encoding: quoted-printable";

-				}

-

-				$this->_body = $this->_prep_quoted_printable($this->_body);

-

-				if ($this->_get_protocol() == 'mail')

-				{

-					$this->_header_str .= $hdr;

-					$this->_finalbody = $this->_body . $this->newline . $this->newline;

-

-					if ($this->send_multipart !== FALSE)

-					{

-						$this->_finalbody .= "--" . $this->_alt_boundary . "--";

-					}

-

-					return;

-				}

-

-				$hdr .= $this->newline . $this->newline;

-				$hdr .= $this->_body . $this->newline . $this->newline;

-

-				if ($this->send_multipart !== FALSE)

-				{

-					$hdr .= "--" . $this->_alt_boundary . "--";

-				}

-

-				$this->_finalbody = $hdr;

-				return;

-

-			break;

-			case 'plain-attach' :

-

-				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;

-				$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;

-				$hdr .= "--" . $this->_atc_boundary . $this->newline;

-

-				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;

-				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();

-

-				if ($this->_get_protocol() == 'mail')

-				{

-					$this->_header_str .= $hdr;

-

-					$body  = $this->_body . $this->newline . $this->newline;

-				}

-

-				$hdr .= $this->newline . $this->newline;

-				$hdr .= $this->_body . $this->newline . $this->newline;

-

-			break;

-			case 'html-attach' :

-

-				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;

-				$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;

-				$hdr .= "--" . $this->_atc_boundary . $this->newline;

-

-				$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;

-				$hdr .= "--" . $this->_alt_boundary . $this->newline;

-

-				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;

-				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;

-				$hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;

-

-				$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;

-				$hdr .= "Content-Transfer-Encoding: quoted-printable";

-

-				$this->_body = $this->_prep_quoted_printable($this->_body);

-

-				if ($this->_get_protocol() == 'mail')

-				{

-					$this->_header_str .= $hdr;

-

-					$body  = $this->_body . $this->newline . $this->newline;

-					$body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;

-				}

-

-				$hdr .= $this->newline . $this->newline;

-				$hdr .= $this->_body . $this->newline . $this->newline;

-				$hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;

-

-			break;

-		}

-

-		$attachment = array();

-

-		$z = 0;

-

-		for ($i=0; $i < count($this->_attach_name); $i++)

-		{

-			$filename = $this->_attach_name[$i];

-			$basename = basename($filename);

-			$ctype = $this->_attach_type[$i];

-

-			if ( ! file_exists($filename))

-			{

-				$this->_set_error_message('email_attachment_missing', $filename);

-				return FALSE;

-			}

-

-			$h  = "--".$this->_atc_boundary.$this->newline;

-			$h .= "Content-type: ".$ctype."; ";

-			$h .= "name=\"".$basename."\"".$this->newline;

-			$h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;

-			$h .= "Content-Transfer-Encoding: base64".$this->newline;

-

-			$attachment[$z++] = $h;

-			$file = filesize($filename) +1;

-

-			if ( ! $fp = fopen($filename, FOPEN_READ))

-			{

-				$this->_set_error_message('email_attachment_unreadable', $filename);

-				return FALSE;

-			}

-

-			$attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));

-			fclose($fp);

-		}

-

-		if ($this->_get_protocol() == 'mail')

-		{

-			$this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";

-

-			return;

-		}

-

-		$this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";

-

-		return;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Prep Quoted Printable

-	 *

-	 * Prepares string for Quoted-Printable Content-Transfer-Encoding

-	 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	integer

-	 * @return	string

-	 */

-	function _prep_quoted_printable($str, $charlim = '')

-	{

-		// Set the character limit

-		// Don't allow over 76, as that will make servers and MUAs barf

-		// all over quoted-printable data

-		if ($charlim == '' OR $charlim > '76')

-		{

-			$charlim = '76';

-		}

-

-		// Reduce multiple spaces

-		$str = preg_replace("| +|", " ", $str);

-

-		// kill nulls

-		$str = preg_replace('/\x00+/', '', $str);

-

-		// Standardize newlines

-		if (strpos($str, "\r") !== FALSE)

-		{

-			$str = str_replace(array("\r\n", "\r"), "\n", $str);

-		}

-

-		// We are intentionally wrapping so mail servers will encode characters

-		// properly and MUAs will behave, so {unwrap} must go!

-		$str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);

-

-		// Break into an array of lines

-		$lines = explode("\n", $str);

-

-		$escape = '=';

-		$output = '';

-

-		foreach ($lines as $line)

-		{

-			$length = strlen($line);

-			$temp = '';

-

-			// Loop through each character in the line to add soft-wrap

-			// characters at the end of a line " =\r\n" and add the newly

-			// processed line(s) to the output (see comment on $crlf class property)

-			for ($i = 0; $i < $length; $i++)

-			{

-				// Grab the next character

-				$char = substr($line, $i, 1);

-				$ascii = ord($char);

-

-				// Convert spaces and tabs but only if it's the end of the line

-				if ($i == ($length - 1))

-				{

-					$char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;

-				}

-

-				// encode = signs

-				if ($ascii == '61')

-				{

-					$char = $escape.strtoupper(sprintf('%02s', dechex($ascii)));  // =3D

-				}

-

-				// If we're at the character limit, add the line to the output,

-				// reset our temp variable, and keep on chuggin'

-				if ((strlen($temp) + strlen($char)) >= $charlim)

-				{

-					$output .= $temp.$escape.$this->crlf;

-					$temp = '';

-				}

-

-				// Add the character to our temporary line

-				$temp .= $char;

-			}

-

-			// Add our completed line to the output

-			$output .= $temp.$this->crlf;

-		}

-

-		// get rid of extra CRLF tacked onto the end

-		$output = substr($output, 0, strlen($this->crlf) * -1);

-

-		return $output;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep Q Encoding

-	 *

-	 * Performs "Q Encoding" on a string for use in email headers.  It's related

-	 * but not identical to quoted-printable, so it has its own method

-	 *

-	 * @access	public

-	 * @param	str

-	 * @param	bool	// set to TRUE for processing From: headers

-	 * @return	str

-	 */

-	function _prep_q_encoding($str, $from = FALSE)

-	{

-		$str = str_replace(array("\r", "\n"), array('', ''), $str);

-

-		// Line length must not exceed 76 characters, so we adjust for

-		// a space, 7 extra characters =??Q??=, and the charset that we will add to each line

-		$limit = 75 - 7 - strlen($this->charset);

-

-		// these special characters must be converted too

-		$convert = array('_', '=', '?');

-

-		if ($from === TRUE)

-		{

-			$convert[] = ',';

-			$convert[] = ';';

-		}

-

-		$output = '';

-		$temp = '';

-

-		for ($i = 0, $length = strlen($str); $i < $length; $i++)

-		{

-			// Grab the next character

-			$char = substr($str, $i, 1);

-			$ascii = ord($char);

-

-			// convert ALL non-printable ASCII characters and our specials

-			if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))

-			{

-				$char = '='.dechex($ascii);

-			}

-

-			// handle regular spaces a bit more compactly than =20

-			if ($ascii == 32)

-			{

-				$char = '_';

-			}

-

-			// If we're at the character limit, add the line to the output,

-			// reset our temp variable, and keep on chuggin'

-			if ((strlen($temp) + strlen($char)) >= $limit)

-			{

-				$output .= $temp.$this->crlf;

-				$temp = '';

-			}

-

-			// Add the character to our temporary line

-			$temp .= $char;

-		}

-

-		$str = $output.$temp;

-

-		// wrap each line with the shebang, charset, and transfer encoding

-		// the preceding space on successive lines is required for header "folding"

-		$str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Send Email

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function send()

-	{

-		if ($this->_replyto_flag == FALSE)

-		{

-			$this->reply_to($this->_headers['From']);

-		}

-

-		if (( ! isset($this->_recipients) AND ! isset($this->_headers['To']))  AND

-			( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND

-			( ! isset($this->_headers['Cc'])))

-		{

-			$this->_set_error_message('email_no_recipients');

-			return FALSE;

-		}

-

-		$this->_build_headers();

-

-		if ($this->bcc_batch_mode  AND  count($this->_bcc_array) > 0)

-		{

-			if (count($this->_bcc_array) > $this->bcc_batch_size)

-				return $this->batch_bcc_send();

-		}

-

-		$this->_build_message();

-

-		if ( ! $this->_spool_email())

-		{

-			return FALSE;

-		}

-		else

-		{

-			return TRUE;

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Batch Bcc Send.  Sends groups of BCCs in batches

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function batch_bcc_send()

-	{

-		$float = $this->bcc_batch_size -1;

-

-		$set = "";

-

-		$chunk = array();

-

-		for ($i = 0; $i < count($this->_bcc_array); $i++)

-		{

-			if (isset($this->_bcc_array[$i]))

-			{

-				$set .= ", ".$this->_bcc_array[$i];

-			}

-

-			if ($i == $float)

-			{

-				$chunk[] = substr($set, 1);

-				$float = $float + $this->bcc_batch_size;

-				$set = "";

-			}

-

-			if ($i == count($this->_bcc_array)-1)

-			{

-				$chunk[] = substr($set, 1);

-			}

-		}

-

-		for ($i = 0; $i < count($chunk); $i++)

-		{

-			unset($this->_headers['Bcc']);

-			unset($bcc);

-

-			$bcc = $this->_str_to_array($chunk[$i]);

-			$bcc = $this->clean_email($bcc);

-

-			if ($this->protocol != 'smtp')

-			{

-				$this->_set_header('Bcc', implode(", ", $bcc));

-			}

-			else

-			{

-				$this->_bcc_array = $bcc;

-			}

-

-			$this->_build_message();

-			$this->_spool_email();

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Unwrap special elements

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _unwrap_specials()

-	{

-		$this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Strip line-breaks via callback

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _remove_nl_callback($matches)

-	{

-		if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)

-		{

-			$matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);

-		}

-

-		return $matches[1];

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Spool mail to the mail server

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _spool_email()

-	{

-		$this->_unwrap_specials();

-

-		switch ($this->_get_protocol())

-		{

-			case 'mail'	:

-

-					if ( ! $this->_send_with_mail())

-					{

-						$this->_set_error_message('email_send_failure_phpmail');

-						return FALSE;

-					}

-			break;

-			case 'sendmail'	:

-

-					if ( ! $this->_send_with_sendmail())

-					{

-						$this->_set_error_message('email_send_failure_sendmail');

-						return FALSE;

-					}

-			break;

-			case 'smtp'	:

-

-					if ( ! $this->_send_with_smtp())

-					{

-						$this->_set_error_message('email_send_failure_smtp');

-						return FALSE;

-					}

-			break;

-

-		}

-

-		$this->_set_error_message('email_sent', $this->_get_protocol());

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Send using mail()

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _send_with_mail()

-	{

-		if ($this->_safe_mode == TRUE)

-		{

-			if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))

-			{

-				return FALSE;

-			}

-			else

-			{

-				return TRUE;

-			}

-		}

-		else

-		{

-			// most documentation of sendmail using the "-f" flag lacks a space after it, however

-			// we've encountered servers that seem to require it to be in place.

-			if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))

-			{

-				return FALSE;

-			}

-			else

-			{

-				return TRUE;

-			}

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Send using Sendmail

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _send_with_sendmail()

-	{

-		$fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');

-

-		if ( ! is_resource($fp))

-		{

-			$this->_set_error_message('email_no_socket');

-			return FALSE;

-		}

-

-		fputs($fp, $this->_header_str);

-		fputs($fp, $this->_finalbody);

-		pclose($fp) >> 8 & 0xFF;

-

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Send using SMTP

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _send_with_smtp()

-	{

-		if ($this->smtp_host == '')

-		{

-			$this->_set_error_message('email_no_hostname');

-			return FALSE;

-		}

-

-		$this->_smtp_connect();

-		$this->_smtp_authenticate();

-

-		$this->_send_command('from', $this->clean_email($this->_headers['From']));

-

-		foreach($this->_recipients as $val)

-		{

-			$this->_send_command('to', $val);

-		}

-

-		if (count($this->_cc_array) > 0)

-		{

-			foreach($this->_cc_array as $val)

-			{

-				if ($val != "")

-				{

-					$this->_send_command('to', $val);

-				}

-			}

-		}

-

-		if (count($this->_bcc_array) > 0)

-		{

-			foreach($this->_bcc_array as $val)

-			{

-				if ($val != "")

-				{

-					$this->_send_command('to', $val);

-				}

-			}

-		}

-

-		$this->_send_command('data');

-

-		// perform dot transformation on any lines that begin with a dot

-		$this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));

-

-		$this->_send_data('.');

-

-		$reply = $this->_get_smtp_data();

-

-		$this->_set_error_message($reply);

-

-		if (strncmp($reply, '250', 3) != 0)

-		{

-			$this->_set_error_message('email_smtp_error', $reply);

-			return FALSE;

-		}

-

-		$this->_send_command('quit');

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * SMTP Connect

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _smtp_connect()

-	{

-		$this->_smtp_connect = fsockopen($this->smtp_host,

-										$this->smtp_port,

-										$errno,

-										$errstr,

-										$this->smtp_timeout);

-

-		if( ! is_resource($this->_smtp_connect))

-		{

-			$this->_set_error_message('email_smtp_error', $errno." ".$errstr);

-			return FALSE;

-		}

-

-		$this->_set_error_message($this->_get_smtp_data());

-		return $this->_send_command('hello');

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Send SMTP command

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _send_command($cmd, $data = '')

-	{

-		switch ($cmd)

-		{

-			case 'hello' :

-

-					if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')

-						$this->_send_data('EHLO '.$this->_get_hostname());

-					else

-						$this->_send_data('HELO '.$this->_get_hostname());

-

-						$resp = 250;

-			break;

-			case 'from' :

-

-						$this->_send_data('MAIL FROM:<'.$data.'>');

-

-						$resp = 250;

-			break;

-			case 'to'	:

-

-						$this->_send_data('RCPT TO:<'.$data.'>');

-

-						$resp = 250;

-			break;

-			case 'data'	:

-

-						$this->_send_data('DATA');

-

-						$resp = 354;

-			break;

-			case 'quit'	:

-

-						$this->_send_data('QUIT');

-

-						$resp = 221;

-			break;

-		}

-

-		$reply = $this->_get_smtp_data();

-

-		$this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";

-

-		if (substr($reply, 0, 3) != $resp)

-		{

-			$this->_set_error_message('email_smtp_error', $reply);

-			return FALSE;

-		}

-

-		if ($cmd == 'quit')

-		{

-			fclose($this->_smtp_connect);

-		}

-

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 *  SMTP Authenticate

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _smtp_authenticate()

-	{

-		if ( ! $this->_smtp_auth)

-		{

-			return TRUE;

-		}

-

-		if ($this->smtp_user == ""  AND  $this->smtp_pass == "")

-		{

-			$this->_set_error_message('email_no_smtp_unpw');

-			return FALSE;

-		}

-

-		$this->_send_data('AUTH LOGIN');

-

-		$reply = $this->_get_smtp_data();

-

-		if (strncmp($reply, '334', 3) != 0)

-		{

-			$this->_set_error_message('email_failed_smtp_login', $reply);

-			return FALSE;

-		}

-

-		$this->_send_data(base64_encode($this->smtp_user));

-

-		$reply = $this->_get_smtp_data();

-

-		if (strncmp($reply, '334', 3) != 0)

-		{

-			$this->_set_error_message('email_smtp_auth_un', $reply);

-			return FALSE;

-		}

-

-		$this->_send_data(base64_encode($this->smtp_pass));

-

-		$reply = $this->_get_smtp_data();

-

-		if (strncmp($reply, '235', 3) != 0)

-		{

-			$this->_set_error_message('email_smtp_auth_pw', $reply);

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Send SMTP data

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _send_data($data)

-	{

-		if ( ! fwrite($this->_smtp_connect, $data . $this->newline))

-		{

-			$this->_set_error_message('email_smtp_data_failure', $data);

-			return FALSE;

-		}

-		else

-		{

-			return TRUE;

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get SMTP data

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_smtp_data()

-	{

-		$data = "";

-

-		while ($str = fgets($this->_smtp_connect, 512))

-		{

-			$data .= $str;

-

-			if (substr($str, 3, 1) == " ")

-			{

-				break;

-			}

-		}

-

-		return $data;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Hostname

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_hostname()

-	{

-		return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get IP

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_ip()

-	{

-		if ($this->_IP !== FALSE)

-		{

-			return $this->_IP;

-		}

-

-		$cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;

-		$rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;

-		$fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;

-

-		if ($cip && $rip) 	$this->_IP = $cip;

-		elseif ($rip)		$this->_IP = $rip;

-		elseif ($cip)		$this->_IP = $cip;

-		elseif ($fip)		$this->_IP = $fip;

-

-		if (strstr($this->_IP, ','))

-		{

-			$x = explode(',', $this->_IP);

-			$this->_IP = end($x);

-		}

-

-		if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))

-		{

-			$this->_IP = '0.0.0.0';

-		}

-

-		unset($cip);

-		unset($rip);

-		unset($fip);

-

-		return $this->_IP;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Debug Message

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function print_debugger()

-	{

-		$msg = '';

-

-		if (count($this->_debug_msg) > 0)

-		{

-			foreach ($this->_debug_msg as $val)

-			{

-				$msg .= $val;

-			}

-		}

-

-		$msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';

-		return $msg;

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Message

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _set_error_message($msg, $val = '')

-	{

-		$CI =& get_instance();

-		$CI->lang->load('email');

-

-		if (FALSE === ($line = $CI->lang->line($msg)))

-		{

-			$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";

-		}

-		else

-		{

-			$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";

-		}

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Mime Types

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _mime_types($ext = "")

-	{

-		$mimes = array(	'hqx'	=>	'application/mac-binhex40',

-						'cpt'	=>	'application/mac-compactpro',

-						'doc'	=>	'application/msword',

-						'bin'	=>	'application/macbinary',

-						'dms'	=>	'application/octet-stream',

-						'lha'	=>	'application/octet-stream',

-						'lzh'	=>	'application/octet-stream',

-						'exe'	=>	'application/octet-stream',

-						'class'	=>	'application/octet-stream',

-						'psd'	=>	'application/octet-stream',

-						'so'	=>	'application/octet-stream',

-						'sea'	=>	'application/octet-stream',

-						'dll'	=>	'application/octet-stream',

-						'oda'	=>	'application/oda',

-						'pdf'	=>	'application/pdf',

-						'ai'	=>	'application/postscript',

-						'eps'	=>	'application/postscript',

-						'ps'	=>	'application/postscript',

-						'smi'	=>	'application/smil',

-						'smil'	=>	'application/smil',

-						'mif'	=>	'application/vnd.mif',

-						'xls'	=>	'application/vnd.ms-excel',

-						'ppt'	=>	'application/vnd.ms-powerpoint',

-						'wbxml'	=>	'application/vnd.wap.wbxml',

-						'wmlc'	=>	'application/vnd.wap.wmlc',

-						'dcr'	=>	'application/x-director',

-						'dir'	=>	'application/x-director',

-						'dxr'	=>	'application/x-director',

-						'dvi'	=>	'application/x-dvi',

-						'gtar'	=>	'application/x-gtar',

-						'php'	=>	'application/x-httpd-php',

-						'php4'	=>	'application/x-httpd-php',

-						'php3'	=>	'application/x-httpd-php',

-						'phtml'	=>	'application/x-httpd-php',

-						'phps'	=>	'application/x-httpd-php-source',

-						'js'	=>	'application/x-javascript',

-						'swf'	=>	'application/x-shockwave-flash',

-						'sit'	=>	'application/x-stuffit',

-						'tar'	=>	'application/x-tar',

-						'tgz'	=>	'application/x-tar',

-						'xhtml'	=>	'application/xhtml+xml',

-						'xht'	=>	'application/xhtml+xml',

-						'zip'	=>	'application/zip',

-						'mid'	=>	'audio/midi',

-						'midi'	=>	'audio/midi',

-						'mpga'	=>	'audio/mpeg',

-						'mp2'	=>	'audio/mpeg',

-						'mp3'	=>	'audio/mpeg',

-						'aif'	=>	'audio/x-aiff',

-						'aiff'	=>	'audio/x-aiff',

-						'aifc'	=>	'audio/x-aiff',

-						'ram'	=>	'audio/x-pn-realaudio',

-						'rm'	=>	'audio/x-pn-realaudio',

-						'rpm'	=>	'audio/x-pn-realaudio-plugin',

-						'ra'	=>	'audio/x-realaudio',

-						'rv'	=>	'video/vnd.rn-realvideo',

-						'wav'	=>	'audio/x-wav',

-						'bmp'	=>	'image/bmp',

-						'gif'	=>	'image/gif',

-						'jpeg'	=>	'image/jpeg',

-						'jpg'	=>	'image/jpeg',

-						'jpe'	=>	'image/jpeg',

-						'png'	=>	'image/png',

-						'tiff'	=>	'image/tiff',

-						'tif'	=>	'image/tiff',

-						'css'	=>	'text/css',

-						'html'	=>	'text/html',

-						'htm'	=>	'text/html',

-						'shtml'	=>	'text/html',

-						'txt'	=>	'text/plain',

-						'text'	=>	'text/plain',

-						'log'	=>	'text/plain',

-						'rtx'	=>	'text/richtext',

-						'rtf'	=>	'text/rtf',

-						'xml'	=>	'text/xml',

-						'xsl'	=>	'text/xml',

-						'mpeg'	=>	'video/mpeg',

-						'mpg'	=>	'video/mpeg',

-						'mpe'	=>	'video/mpeg',

-						'qt'	=>	'video/quicktime',

-						'mov'	=>	'video/quicktime',

-						'avi'	=>	'video/x-msvideo',

-						'movie'	=>	'video/x-sgi-movie',

-						'doc'	=>	'application/msword',

-						'word'	=>	'application/msword',

-						'xl'	=>	'application/excel',

-						'eml'	=>	'message/rfc822'

-					);

-

-		return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];

-	}

-

-}

-// END CI_Email class

-

-/* End of file Email.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Email Class
+ *
+ * Permits email to be sent using Mail, Sendmail, or SMTP.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/email.html
+ */
+class CI_Email {
+
+	var	$useragent		= "CodeIgniter";
+	var	$mailpath		= "/usr/sbin/sendmail";	// Sendmail path
+	var	$protocol		= "mail";	// mail/sendmail/smtp
+	var	$smtp_host		= "";		// SMTP Server.  Example: mail.earthlink.net
+	var	$smtp_user		= "";		// SMTP Username
+	var	$smtp_pass		= "";		// SMTP Password
+	var	$smtp_port		= "25";		// SMTP Port
+	var	$smtp_timeout	= 5;		// SMTP Timeout in seconds
+	var	$wordwrap		= TRUE;		// TRUE/FALSE  Turns word-wrap on/off
+	var	$wrapchars		= "76";		// Number of characters to wrap at.
+	var	$mailtype		= "text";	// text/html  Defines email formatting
+	var	$charset		= "utf-8";	// Default char set: iso-8859-1 or us-ascii
+	var	$multipart		= "mixed";	// "mixed" (in the body) or "related" (separate)
+	var $alt_message	= '';		// Alternative message for HTML emails
+	var	$validate		= FALSE;	// TRUE/FALSE.  Enables email validation
+	var	$priority		= "3";		// Default priority (1 - 5)
+	var	$newline		= "\n";		// Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
+	var $crlf			= "\n";		// The RFC 2045 compliant CRLF for quoted-printable is "\r\n".  Apparently some servers,
+									// even on the receiving end think they need to muck with CRLFs, so using "\n", while
+									// distasteful, is the only thing that seems to work for all environments.
+	var $send_multipart	= TRUE;		// TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override.  Set to FALSE for Yahoo.
+	var	$bcc_batch_mode	= FALSE;	// TRUE/FALSE  Turns on/off Bcc batch feature
+	var	$bcc_batch_size	= 200;		// If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
+	var $_safe_mode		= FALSE;
+	var	$_subject		= "";
+	var	$_body			= "";
+	var	$_finalbody		= "";
+	var	$_alt_boundary	= "";
+	var	$_atc_boundary	= "";
+	var	$_header_str	= "";
+	var	$_smtp_connect	= "";
+	var	$_encoding		= "8bit";
+	var $_IP			= FALSE;
+	var	$_smtp_auth		= FALSE;
+	var $_replyto_flag	= FALSE;
+	var	$_debug_msg		= array();
+	var	$_recipients	= array();
+	var	$_cc_array		= array();
+	var	$_bcc_array		= array();
+	var	$_headers		= array();
+	var	$_attach_name	= array();
+	var	$_attach_type	= array();
+	var	$_attach_disp	= array();
+	var	$_protocols		= array('mail', 'sendmail', 'smtp');
+	var	$_base_charsets	= array('us-ascii', 'iso-2022-');	// 7-bit charsets (excluding language suffix)
+	var	$_bit_depths	= array('7bit', '8bit');
+	var	$_priorities	= array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
+
+
+	/**
+	 * Constructor - Sets Email Preferences
+	 *
+	 * The constructor can be passed an array of config values
+	 */
+	function CI_Email($config = array())
+	{
+		if (count($config) > 0)
+		{
+			$this->initialize($config);
+		}
+		else
+		{
+			$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
+			$this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
+		}
+
+		log_message('debug', "Email Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize preferences
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function initialize($config = array())
+	{
+		$this->clear();
+		foreach ($config as $key => $val)
+		{
+			if (isset($this->$key))
+			{
+				$method = 'set_'.$key;
+
+				if (method_exists($this, $method))
+				{
+					$this->$method($val);
+				}
+				else
+				{
+					$this->$key = $val;
+				}
+			}
+		}
+
+		$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
+		$this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize the Email Data
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function clear($clear_attachments = FALSE)
+	{
+		$this->_subject		= "";
+		$this->_body		= "";
+		$this->_finalbody	= "";
+		$this->_header_str	= "";
+		$this->_replyto_flag = FALSE;
+		$this->_recipients	= array();
+		$this->_headers		= array();
+		$this->_debug_msg	= array();
+
+		$this->_set_header('User-Agent', $this->useragent);
+		$this->_set_header('Date', $this->_set_date());
+
+		if ($clear_attachments !== FALSE)
+		{
+			$this->_attach_name = array();
+			$this->_attach_type = array();
+			$this->_attach_disp = array();
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set FROM
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function from($from, $name = '')
+	{
+		if (preg_match( '/\<(.*)\>/', $from, $match))
+		{
+			$from = $match['1'];
+		}
+
+		if ($this->validate)
+		{
+			$this->validate_email($this->_str_to_array($from));
+		}
+
+		// prepare the display name
+		if ($name != '')
+		{
+			// only use Q encoding if there are characters that would require it
+			if ( ! preg_match('/[\200-\377]/', $name))
+			{
+				// add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes
+				$name = '"'.addcslashes($name, '\0..\37\177"\\').'"';
+			}
+			else
+			{
+				$name = $this->_prep_q_encoding($name, TRUE);
+			}
+		}
+
+		$this->_set_header('From', $name.' <'.$from.'>');
+		$this->_set_header('Return-Path', '<'.$from.'>');
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Reply-to
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function reply_to($replyto, $name = '')
+	{
+		if (preg_match( '/\<(.*)\>/', $replyto, $match))
+		{
+			$replyto = $match['1'];
+		}
+
+		if ($this->validate)
+		{
+			$this->validate_email($this->_str_to_array($replyto));
+		}
+
+		if ($name == '')
+		{
+			$name = $replyto;
+		}
+
+		if (strncmp($name, '"', 1) != 0)
+		{
+			$name = '"'.$name.'"';
+		}
+
+		$this->_set_header('Reply-To', $name.' <'.$replyto.'>');
+		$this->_replyto_flag = TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Recipients
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function to($to)
+	{
+		$to = $this->_str_to_array($to);
+		$to = $this->clean_email($to);
+
+		if ($this->validate)
+		{
+			$this->validate_email($to);
+		}
+
+		if ($this->_get_protocol() != 'mail')
+		{
+			$this->_set_header('To', implode(", ", $to));
+		}
+
+		switch ($this->_get_protocol())
+		{
+			case 'smtp'		: $this->_recipients = $to;
+			break;
+			case 'sendmail'	: $this->_recipients = implode(", ", $to);
+			break;
+			case 'mail'		: $this->_recipients = implode(", ", $to);
+			break;
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set CC
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function cc($cc)
+	{
+		$cc = $this->_str_to_array($cc);
+		$cc = $this->clean_email($cc);
+
+		if ($this->validate)
+		{
+			$this->validate_email($cc);
+		}
+
+		$this->_set_header('Cc', implode(", ", $cc));
+
+		if ($this->_get_protocol() == "smtp")
+		{
+			$this->_cc_array = $cc;
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set BCC
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function bcc($bcc, $limit = '')
+	{
+		if ($limit != '' && is_numeric($limit))
+		{
+			$this->bcc_batch_mode = TRUE;
+			$this->bcc_batch_size = $limit;
+		}
+
+		$bcc = $this->_str_to_array($bcc);
+		$bcc = $this->clean_email($bcc);
+
+		if ($this->validate)
+		{
+			$this->validate_email($bcc);
+		}
+
+		if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))
+		{
+			$this->_bcc_array = $bcc;
+		}
+		else
+		{
+			$this->_set_header('Bcc', implode(", ", $bcc));
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Email Subject
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function subject($subject)
+	{
+		$subject = $this->_prep_q_encoding($subject);
+		$this->_set_header('Subject', $subject);
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Body
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function message($body)
+	{
+		$this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
+	}
+ 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Assign file attachments
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function attach($filename, $disposition = 'attachment')
+	{
+		$this->_attach_name[] = $filename;
+		$this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
+		$this->_attach_disp[] = $disposition; // Can also be 'inline'  Not sure if it matters
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add a Header Item
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function _set_header($header, $value)
+	{
+		$this->_headers[$header] = $value;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Convert a String to an Array
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	array
+	 */
+	function _str_to_array($email)
+	{
+		if ( ! is_array($email))
+		{
+			if (strpos($email, ',') !== FALSE)
+			{
+				$email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
+			}
+			else
+			{
+				$email = trim($email);
+				settype($email, "array");
+			}
+		}
+		return $email;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Multipart Value
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_alt_message($str = '')
+	{
+		$this->alt_message = ($str == '') ? '' : $str;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Mailtype
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_mailtype($type = 'text')
+	{
+		$this->mailtype = ($type == 'html') ? 'html' : 'text';
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Wordwrap
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_wordwrap($wordwrap = TRUE)
+	{
+		$this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Protocol
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_protocol($protocol = 'mail')
+	{
+		$this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Priority
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */
+	function set_priority($n = 3)
+	{
+		if ( ! is_numeric($n))
+		{
+			$this->priority = 3;
+			return;
+		}
+
+		if ($n < 1 OR $n > 5)
+		{
+			$this->priority = 3;
+			return;
+		}
+
+		$this->priority = $n;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Newline Character
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_newline($newline = "\n")
+	{
+		if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
+		{
+			$this->newline	= "\n";
+			return;
+		}
+
+		$this->newline	= $newline;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set CRLF
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_crlf($crlf = "\n")
+	{
+		if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")
+		{
+			$this->crlf	= "\n";
+			return;
+		}
+
+		$this->crlf	= $crlf;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Message Boundary
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _set_boundaries()
+	{
+		$this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
+		$this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get the Message ID
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_message_id()
+	{
+		$from = $this->_headers['Return-Path'];
+		$from = str_replace(">", "", $from);
+		$from = str_replace("<", "", $from);
+
+		return  "<".uniqid('').strstr($from, '@').">";
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Mail Protocol
+	 *
+	 * @access	private
+	 * @param	bool
+	 * @return	string
+	 */
+	function _get_protocol($return = TRUE)
+	{
+		$this->protocol = strtolower($this->protocol);
+		$this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
+
+		if ($return == TRUE)
+		{
+			return $this->protocol;
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Mail Encoding
+	 *
+	 * @access	private
+	 * @param	bool
+	 * @return	string
+	 */
+	function _get_encoding($return = TRUE)
+	{
+		$this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
+
+		foreach ($this->_base_charsets as $charset)
+		{
+			if (strncmp($charset, $this->charset, strlen($charset)) == 0)
+			{
+				$this->_encoding = '7bit';
+			}
+		}
+
+		if ($return == TRUE)
+		{
+			return $this->_encoding;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get content type (text/html/attachment)
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_content_type()
+	{
+		if	($this->mailtype == 'html' &&  count($this->_attach_name) == 0)
+		{
+			return 'html';
+		}
+		elseif	($this->mailtype == 'html' &&  count($this->_attach_name)  > 0)
+		{
+			return 'html-attach';
+		}
+		elseif	($this->mailtype == 'text' &&  count($this->_attach_name)  > 0)
+		{
+			return 'plain-attach';
+		}
+		else
+		{
+			return 'plain';
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set RFC 822 Date
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _set_date()
+	{
+		$timezone = date("Z");
+		$operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';
+		$timezone = abs($timezone);
+		$timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;
+
+		return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Mime message
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_mime_message()
+	{
+		return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Validate Email Address
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function validate_email($email)
+	{
+		if ( ! is_array($email))
+		{
+			$this->_set_error_message('email_must_be_array');
+			return FALSE;
+		}
+
+		foreach ($email as $val)
+		{
+			if ( ! $this->valid_email($val))
+			{
+				$this->_set_error_message('email_invalid_address', $val);
+				return FALSE;
+			}
+		}
+
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Email Validation
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function valid_email($address)
+	{
+		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Clean Extended Email Address: Joe Smith <joe@smith.com>
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function clean_email($email)
+	{
+		if ( ! is_array($email))
+		{
+			if (preg_match('/\<(.*)\>/', $email, $match))
+			{
+		   		return $match['1'];
+			}
+		   	else
+			{
+		   		return $email;
+			}
+		}
+
+		$clean_email = array();
+
+		foreach ($email as $addy)
+		{
+			if (preg_match( '/\<(.*)\>/', $addy, $match))
+			{
+		   		$clean_email[] = $match['1'];
+			}
+		   	else
+			{
+		   		$clean_email[] = $addy;
+			}
+		}
+
+		return $clean_email;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Build alternative plain text message
+	 *
+	 * This function provides the raw message for use
+	 * in plain-text headers of HTML-formatted emails.
+	 * If the user hasn't specified his own alternative message
+	 * it creates one by stripping the HTML
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_alt_message()
+	{
+		if ($this->alt_message != "")
+		{
+			return $this->word_wrap($this->alt_message, '76');
+		}
+
+		if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))
+		{
+			$body = $match['1'];
+		}
+		else
+		{
+			$body = $this->_body;
+		}
+
+		$body = trim(strip_tags($body));
+		$body = preg_replace( '#<!--(.*)--\>#', "", $body);
+		$body = str_replace("\t", "", $body);
+
+		for ($i = 20; $i >= 3; $i--)
+		{
+			$n = "";
+
+			for ($x = 1; $x <= $i; $x ++)
+			{
+				 $n .= "\n";
+			}
+
+			$body = str_replace($n, "\n\n", $body);
+		}
+
+		return $this->word_wrap($body, '76');
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Word Wrap
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	integer
+	 * @return	string
+	 */
+	function word_wrap($str, $charlim = '')
+	{
+		// Se the character limit
+		if ($charlim == '')
+		{
+			$charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
+		}
+
+		// Reduce multiple spaces
+		$str = preg_replace("| +|", " ", $str);
+
+		// Standardize newlines
+		if (strpos($str, "\r") !== FALSE)
+		{
+			$str = str_replace(array("\r\n", "\r"), "\n", $str);
+		}
+
+		// If the current word is surrounded by {unwrap} tags we'll
+		// strip the entire chunk and replace it with a marker.
+		$unwrap = array();
+		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+		{
+			for ($i = 0; $i < count($matches['0']); $i++)
+			{
+				$unwrap[] = $matches['1'][$i];
+				$str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+			}
+		}
+
+		// Use PHP's native function to do the initial wordwrap.
+		// We set the cut flag to FALSE so that any individual words that are
+		// too long get left alone.  In the next step we'll deal with them.
+		$str = wordwrap($str, $charlim, "\n", FALSE);
+
+		// Split the string into individual lines of text and cycle through them
+		$output = "";
+		foreach (explode("\n", $str) as $line)
+		{
+			// Is the line within the allowed character count?
+			// If so we'll join it to the output and continue
+			if (strlen($line) <= $charlim)
+			{
+				$output .= $line.$this->newline;
+				continue;
+			}
+
+			$temp = '';
+			while((strlen($line)) > $charlim)
+			{
+				// If the over-length word is a URL we won't wrap it
+				if (preg_match("!\[url.+\]|://|wwww.!", $line))
+				{
+					break;
+				}
+
+				// Trim the word down
+				$temp .= substr($line, 0, $charlim-1);
+				$line = substr($line, $charlim-1);
+			}
+
+			// If $temp contains data it means we had to split up an over-length
+			// word into smaller chunks so we'll add it back to our current line
+			if ($temp != '')
+			{
+				$output .= $temp.$this->newline.$line;
+			}
+			else
+			{
+				$output .= $line;
+			}
+
+			$output .= $this->newline;
+		}
+
+		// Put our markers back
+		if (count($unwrap) > 0)
+		{
+			foreach ($unwrap as $key => $val)
+			{
+				$output = str_replace("{{unwrapped".$key."}}", $val, $output);
+			}
+		}
+
+		return $output;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Build final headers
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _build_headers()
+	{
+		$this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
+		$this->_set_header('X-Mailer', $this->useragent);
+		$this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
+		$this->_set_header('Message-ID', $this->_get_message_id());
+		$this->_set_header('Mime-Version', '1.0');
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write Headers as a string
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _write_headers()
+	{
+		if ($this->protocol == 'mail')
+		{
+			$this->_subject = $this->_headers['Subject'];
+			unset($this->_headers['Subject']);
+		}
+
+		reset($this->_headers);
+		$this->_header_str = "";
+
+		foreach($this->_headers as $key => $val)
+		{
+			$val = trim($val);
+
+			if ($val != "")
+			{
+				$this->_header_str .= $key.": ".$val.$this->newline;
+			}
+		}
+
+		if ($this->_get_protocol() == 'mail')
+		{
+			$this->_header_str = substr($this->_header_str, 0, -1);
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Build Final Body and attachments
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _build_message()
+	{
+		if ($this->wordwrap === TRUE  AND  $this->mailtype != 'html')
+		{
+			$this->_body = $this->word_wrap($this->_body);
+		}
+
+		$this->_set_boundaries();
+		$this->_write_headers();
+
+		$hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';
+
+		switch ($this->_get_content_type())
+		{
+			case 'plain' :
+
+				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
+				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
+
+				if ($this->_get_protocol() == 'mail')
+				{
+					$this->_header_str .= $hdr;
+					$this->_finalbody = $this->_body;
+
+					return;
+				}
+
+				$hdr .= $this->newline . $this->newline . $this->_body;
+
+				$this->_finalbody = $hdr;
+				return;
+
+			break;
+			case 'html' :
+
+				if ($this->send_multipart === FALSE)
+				{
+					$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
+					$hdr .= "Content-Transfer-Encoding: quoted-printable";
+				}
+				else
+				{
+					$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;
+					$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
+					$hdr .= "--" . $this->_alt_boundary . $this->newline;
+
+					$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
+					$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
+					$hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
+
+					$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
+					$hdr .= "Content-Transfer-Encoding: quoted-printable";
+				}
+
+				$this->_body = $this->_prep_quoted_printable($this->_body);
+
+				if ($this->_get_protocol() == 'mail')
+				{
+					$this->_header_str .= $hdr;
+					$this->_finalbody = $this->_body . $this->newline . $this->newline;
+
+					if ($this->send_multipart !== FALSE)
+					{
+						$this->_finalbody .= "--" . $this->_alt_boundary . "--";
+					}
+
+					return;
+				}
+
+				$hdr .= $this->newline . $this->newline;
+				$hdr .= $this->_body . $this->newline . $this->newline;
+
+				if ($this->send_multipart !== FALSE)
+				{
+					$hdr .= "--" . $this->_alt_boundary . "--";
+				}
+
+				$this->_finalbody = $hdr;
+				return;
+
+			break;
+			case 'plain-attach' :
+
+				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
+				$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
+				$hdr .= "--" . $this->_atc_boundary . $this->newline;
+
+				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
+				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
+
+				if ($this->_get_protocol() == 'mail')
+				{
+					$this->_header_str .= $hdr;
+
+					$body  = $this->_body . $this->newline . $this->newline;
+				}
+
+				$hdr .= $this->newline . $this->newline;
+				$hdr .= $this->_body . $this->newline . $this->newline;
+
+			break;
+			case 'html-attach' :
+
+				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
+				$hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
+				$hdr .= "--" . $this->_atc_boundary . $this->newline;
+
+				$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;
+				$hdr .= "--" . $this->_alt_boundary . $this->newline;
+
+				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
+				$hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
+				$hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
+
+				$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
+				$hdr .= "Content-Transfer-Encoding: quoted-printable";
+
+				$this->_body = $this->_prep_quoted_printable($this->_body);
+
+				if ($this->_get_protocol() == 'mail')
+				{
+					$this->_header_str .= $hdr;
+
+					$body  = $this->_body . $this->newline . $this->newline;
+					$body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
+				}
+
+				$hdr .= $this->newline . $this->newline;
+				$hdr .= $this->_body . $this->newline . $this->newline;
+				$hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
+
+			break;
+		}
+
+		$attachment = array();
+
+		$z = 0;
+
+		for ($i=0; $i < count($this->_attach_name); $i++)
+		{
+			$filename = $this->_attach_name[$i];
+			$basename = basename($filename);
+			$ctype = $this->_attach_type[$i];
+
+			if ( ! file_exists($filename))
+			{
+				$this->_set_error_message('email_attachment_missing', $filename);
+				return FALSE;
+			}
+
+			$h  = "--".$this->_atc_boundary.$this->newline;
+			$h .= "Content-type: ".$ctype."; ";
+			$h .= "name=\"".$basename."\"".$this->newline;
+			$h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;
+			$h .= "Content-Transfer-Encoding: base64".$this->newline;
+
+			$attachment[$z++] = $h;
+			$file = filesize($filename) +1;
+
+			if ( ! $fp = fopen($filename, FOPEN_READ))
+			{
+				$this->_set_error_message('email_attachment_unreadable', $filename);
+				return FALSE;
+			}
+
+			$attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
+			fclose($fp);
+		}
+
+		if ($this->_get_protocol() == 'mail')
+		{
+			$this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
+
+			return;
+		}
+
+		$this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
+
+		return;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Prep Quoted Printable
+	 *
+	 * Prepares string for Quoted-Printable Content-Transfer-Encoding
+	 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	integer
+	 * @return	string
+	 */
+	function _prep_quoted_printable($str, $charlim = '')
+	{
+		// Set the character limit
+		// Don't allow over 76, as that will make servers and MUAs barf
+		// all over quoted-printable data
+		if ($charlim == '' OR $charlim > '76')
+		{
+			$charlim = '76';
+		}
+
+		// Reduce multiple spaces
+		$str = preg_replace("| +|", " ", $str);
+
+		// kill nulls
+		$str = preg_replace('/\x00+/', '', $str);
+
+		// Standardize newlines
+		if (strpos($str, "\r") !== FALSE)
+		{
+			$str = str_replace(array("\r\n", "\r"), "\n", $str);
+		}
+
+		// We are intentionally wrapping so mail servers will encode characters
+		// properly and MUAs will behave, so {unwrap} must go!
+		$str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
+
+		// Break into an array of lines
+		$lines = explode("\n", $str);
+
+		$escape = '=';
+		$output = '';
+
+		foreach ($lines as $line)
+		{
+			$length = strlen($line);
+			$temp = '';
+
+			// Loop through each character in the line to add soft-wrap
+			// characters at the end of a line " =\r\n" and add the newly
+			// processed line(s) to the output (see comment on $crlf class property)
+			for ($i = 0; $i < $length; $i++)
+			{
+				// Grab the next character
+				$char = substr($line, $i, 1);
+				$ascii = ord($char);
+
+				// Convert spaces and tabs but only if it's the end of the line
+				if ($i == ($length - 1))
+				{
+					$char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;
+				}
+
+				// encode = signs
+				if ($ascii == '61')
+				{
+					$char = $escape.strtoupper(sprintf('%02s', dechex($ascii)));  // =3D
+				}
+
+				// If we're at the character limit, add the line to the output,
+				// reset our temp variable, and keep on chuggin'
+				if ((strlen($temp) + strlen($char)) >= $charlim)
+				{
+					$output .= $temp.$escape.$this->crlf;
+					$temp = '';
+				}
+
+				// Add the character to our temporary line
+				$temp .= $char;
+			}
+
+			// Add our completed line to the output
+			$output .= $temp.$this->crlf;
+		}
+
+		// get rid of extra CRLF tacked onto the end
+		$output = substr($output, 0, strlen($this->crlf) * -1);
+
+		return $output;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep Q Encoding
+	 *
+	 * Performs "Q Encoding" on a string for use in email headers.  It's related
+	 * but not identical to quoted-printable, so it has its own method
+	 *
+	 * @access	public
+	 * @param	str
+	 * @param	bool	// set to TRUE for processing From: headers
+	 * @return	str
+	 */
+	function _prep_q_encoding($str, $from = FALSE)
+	{
+		$str = str_replace(array("\r", "\n"), array('', ''), $str);
+
+		// Line length must not exceed 76 characters, so we adjust for
+		// a space, 7 extra characters =??Q??=, and the charset that we will add to each line
+		$limit = 75 - 7 - strlen($this->charset);
+
+		// these special characters must be converted too
+		$convert = array('_', '=', '?');
+
+		if ($from === TRUE)
+		{
+			$convert[] = ',';
+			$convert[] = ';';
+		}
+
+		$output = '';
+		$temp = '';
+
+		for ($i = 0, $length = strlen($str); $i < $length; $i++)
+		{
+			// Grab the next character
+			$char = substr($str, $i, 1);
+			$ascii = ord($char);
+
+			// convert ALL non-printable ASCII characters and our specials
+			if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))
+			{
+				$char = '='.dechex($ascii);
+			}
+
+			// handle regular spaces a bit more compactly than =20
+			if ($ascii == 32)
+			{
+				$char = '_';
+			}
+
+			// If we're at the character limit, add the line to the output,
+			// reset our temp variable, and keep on chuggin'
+			if ((strlen($temp) + strlen($char)) >= $limit)
+			{
+				$output .= $temp.$this->crlf;
+				$temp = '';
+			}
+
+			// Add the character to our temporary line
+			$temp .= $char;
+		}
+
+		$str = $output.$temp;
+
+		// wrap each line with the shebang, charset, and transfer encoding
+		// the preceding space on successive lines is required for header "folding"
+		$str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Send Email
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function send()
+	{
+		if ($this->_replyto_flag == FALSE)
+		{
+			$this->reply_to($this->_headers['From']);
+		}
+
+		if (( ! isset($this->_recipients) AND ! isset($this->_headers['To']))  AND
+			( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
+			( ! isset($this->_headers['Cc'])))
+		{
+			$this->_set_error_message('email_no_recipients');
+			return FALSE;
+		}
+
+		$this->_build_headers();
+
+		if ($this->bcc_batch_mode  AND  count($this->_bcc_array) > 0)
+		{
+			if (count($this->_bcc_array) > $this->bcc_batch_size)
+				return $this->batch_bcc_send();
+		}
+
+		$this->_build_message();
+
+		if ( ! $this->_spool_email())
+		{
+			return FALSE;
+		}
+		else
+		{
+			return TRUE;
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Batch Bcc Send.  Sends groups of BCCs in batches
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function batch_bcc_send()
+	{
+		$float = $this->bcc_batch_size -1;
+
+		$set = "";
+
+		$chunk = array();
+
+		for ($i = 0; $i < count($this->_bcc_array); $i++)
+		{
+			if (isset($this->_bcc_array[$i]))
+			{
+				$set .= ", ".$this->_bcc_array[$i];
+			}
+
+			if ($i == $float)
+			{
+				$chunk[] = substr($set, 1);
+				$float = $float + $this->bcc_batch_size;
+				$set = "";
+			}
+
+			if ($i == count($this->_bcc_array)-1)
+			{
+				$chunk[] = substr($set, 1);
+			}
+		}
+
+		for ($i = 0; $i < count($chunk); $i++)
+		{
+			unset($this->_headers['Bcc']);
+			unset($bcc);
+
+			$bcc = $this->_str_to_array($chunk[$i]);
+			$bcc = $this->clean_email($bcc);
+
+			if ($this->protocol != 'smtp')
+			{
+				$this->_set_header('Bcc', implode(", ", $bcc));
+			}
+			else
+			{
+				$this->_bcc_array = $bcc;
+			}
+
+			$this->_build_message();
+			$this->_spool_email();
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Unwrap special elements
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _unwrap_specials()
+	{
+		$this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Strip line-breaks via callback
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _remove_nl_callback($matches)
+	{
+		if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
+		{
+			$matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);
+		}
+
+		return $matches[1];
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Spool mail to the mail server
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _spool_email()
+	{
+		$this->_unwrap_specials();
+
+		switch ($this->_get_protocol())
+		{
+			case 'mail'	:
+
+					if ( ! $this->_send_with_mail())
+					{
+						$this->_set_error_message('email_send_failure_phpmail');
+						return FALSE;
+					}
+			break;
+			case 'sendmail'	:
+
+					if ( ! $this->_send_with_sendmail())
+					{
+						$this->_set_error_message('email_send_failure_sendmail');
+						return FALSE;
+					}
+			break;
+			case 'smtp'	:
+
+					if ( ! $this->_send_with_smtp())
+					{
+						$this->_set_error_message('email_send_failure_smtp');
+						return FALSE;
+					}
+			break;
+
+		}
+
+		$this->_set_error_message('email_sent', $this->_get_protocol());
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send using mail()
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _send_with_mail()
+	{
+		if ($this->_safe_mode == TRUE)
+		{
+			if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
+			{
+				return FALSE;
+			}
+			else
+			{
+				return TRUE;
+			}
+		}
+		else
+		{
+			// most documentation of sendmail using the "-f" flag lacks a space after it, however
+			// we've encountered servers that seem to require it to be in place.
+			if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
+			{
+				return FALSE;
+			}
+			else
+			{
+				return TRUE;
+			}
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send using Sendmail
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _send_with_sendmail()
+	{
+		$fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
+
+		if ( ! is_resource($fp))
+		{
+			$this->_set_error_message('email_no_socket');
+			return FALSE;
+		}
+
+		fputs($fp, $this->_header_str);
+		fputs($fp, $this->_finalbody);
+		pclose($fp) >> 8 & 0xFF;
+
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send using SMTP
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _send_with_smtp()
+	{
+		if ($this->smtp_host == '')
+		{
+			$this->_set_error_message('email_no_hostname');
+			return FALSE;
+		}
+
+		$this->_smtp_connect();
+		$this->_smtp_authenticate();
+
+		$this->_send_command('from', $this->clean_email($this->_headers['From']));
+
+		foreach($this->_recipients as $val)
+		{
+			$this->_send_command('to', $val);
+		}
+
+		if (count($this->_cc_array) > 0)
+		{
+			foreach($this->_cc_array as $val)
+			{
+				if ($val != "")
+				{
+					$this->_send_command('to', $val);
+				}
+			}
+		}
+
+		if (count($this->_bcc_array) > 0)
+		{
+			foreach($this->_bcc_array as $val)
+			{
+				if ($val != "")
+				{
+					$this->_send_command('to', $val);
+				}
+			}
+		}
+
+		$this->_send_command('data');
+
+		// perform dot transformation on any lines that begin with a dot
+		$this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
+
+		$this->_send_data('.');
+
+		$reply = $this->_get_smtp_data();
+
+		$this->_set_error_message($reply);
+
+		if (strncmp($reply, '250', 3) != 0)
+		{
+			$this->_set_error_message('email_smtp_error', $reply);
+			return FALSE;
+		}
+
+		$this->_send_command('quit');
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * SMTP Connect
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _smtp_connect()
+	{
+		$this->_smtp_connect = fsockopen($this->smtp_host,
+										$this->smtp_port,
+										$errno,
+										$errstr,
+										$this->smtp_timeout);
+
+		if( ! is_resource($this->_smtp_connect))
+		{
+			$this->_set_error_message('email_smtp_error', $errno." ".$errstr);
+			return FALSE;
+		}
+
+		$this->_set_error_message($this->_get_smtp_data());
+		return $this->_send_command('hello');
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send SMTP command
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _send_command($cmd, $data = '')
+	{
+		switch ($cmd)
+		{
+			case 'hello' :
+
+					if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
+						$this->_send_data('EHLO '.$this->_get_hostname());
+					else
+						$this->_send_data('HELO '.$this->_get_hostname());
+
+						$resp = 250;
+			break;
+			case 'from' :
+
+						$this->_send_data('MAIL FROM:<'.$data.'>');
+
+						$resp = 250;
+			break;
+			case 'to'	:
+
+						$this->_send_data('RCPT TO:<'.$data.'>');
+
+						$resp = 250;
+			break;
+			case 'data'	:
+
+						$this->_send_data('DATA');
+
+						$resp = 354;
+			break;
+			case 'quit'	:
+
+						$this->_send_data('QUIT');
+
+						$resp = 221;
+			break;
+		}
+
+		$reply = $this->_get_smtp_data();
+
+		$this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
+
+		if (substr($reply, 0, 3) != $resp)
+		{
+			$this->_set_error_message('email_smtp_error', $reply);
+			return FALSE;
+		}
+
+		if ($cmd == 'quit')
+		{
+			fclose($this->_smtp_connect);
+		}
+
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 *  SMTP Authenticate
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _smtp_authenticate()
+	{
+		if ( ! $this->_smtp_auth)
+		{
+			return TRUE;
+		}
+
+		if ($this->smtp_user == ""  AND  $this->smtp_pass == "")
+		{
+			$this->_set_error_message('email_no_smtp_unpw');
+			return FALSE;
+		}
+
+		$this->_send_data('AUTH LOGIN');
+
+		$reply = $this->_get_smtp_data();
+
+		if (strncmp($reply, '334', 3) != 0)
+		{
+			$this->_set_error_message('email_failed_smtp_login', $reply);
+			return FALSE;
+		}
+
+		$this->_send_data(base64_encode($this->smtp_user));
+
+		$reply = $this->_get_smtp_data();
+
+		if (strncmp($reply, '334', 3) != 0)
+		{
+			$this->_set_error_message('email_smtp_auth_un', $reply);
+			return FALSE;
+		}
+
+		$this->_send_data(base64_encode($this->smtp_pass));
+
+		$reply = $this->_get_smtp_data();
+
+		if (strncmp($reply, '235', 3) != 0)
+		{
+			$this->_set_error_message('email_smtp_auth_pw', $reply);
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send SMTP data
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _send_data($data)
+	{
+		if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
+		{
+			$this->_set_error_message('email_smtp_data_failure', $data);
+			return FALSE;
+		}
+		else
+		{
+			return TRUE;
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get SMTP data
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_smtp_data()
+	{
+		$data = "";
+
+		while ($str = fgets($this->_smtp_connect, 512))
+		{
+			$data .= $str;
+
+			if (substr($str, 3, 1) == " ")
+			{
+				break;
+			}
+		}
+
+		return $data;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Hostname
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_hostname()
+	{
+		return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get IP
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_ip()
+	{
+		if ($this->_IP !== FALSE)
+		{
+			return $this->_IP;
+		}
+
+		$cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
+		$rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
+		$fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
+
+		if ($cip && $rip) 	$this->_IP = $cip;
+		elseif ($rip)		$this->_IP = $rip;
+		elseif ($cip)		$this->_IP = $cip;
+		elseif ($fip)		$this->_IP = $fip;
+
+		if (strstr($this->_IP, ','))
+		{
+			$x = explode(',', $this->_IP);
+			$this->_IP = end($x);
+		}
+
+		if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))
+		{
+			$this->_IP = '0.0.0.0';
+		}
+
+		unset($cip);
+		unset($rip);
+		unset($fip);
+
+		return $this->_IP;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Debug Message
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function print_debugger()
+	{
+		$msg = '';
+
+		if (count($this->_debug_msg) > 0)
+		{
+			foreach ($this->_debug_msg as $val)
+			{
+				$msg .= $val;
+			}
+		}
+
+		$msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
+		return $msg;
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Message
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _set_error_message($msg, $val = '')
+	{
+		$CI =& get_instance();
+		$CI->lang->load('email');
+
+		if (FALSE === ($line = $CI->lang->line($msg)))
+		{
+			$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
+		}
+		else
+		{
+			$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
+		}
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Mime Types
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _mime_types($ext = "")
+	{
+		$mimes = array(	'hqx'	=>	'application/mac-binhex40',
+						'cpt'	=>	'application/mac-compactpro',
+						'doc'	=>	'application/msword',
+						'bin'	=>	'application/macbinary',
+						'dms'	=>	'application/octet-stream',
+						'lha'	=>	'application/octet-stream',
+						'lzh'	=>	'application/octet-stream',
+						'exe'	=>	'application/octet-stream',
+						'class'	=>	'application/octet-stream',
+						'psd'	=>	'application/octet-stream',
+						'so'	=>	'application/octet-stream',
+						'sea'	=>	'application/octet-stream',
+						'dll'	=>	'application/octet-stream',
+						'oda'	=>	'application/oda',
+						'pdf'	=>	'application/pdf',
+						'ai'	=>	'application/postscript',
+						'eps'	=>	'application/postscript',
+						'ps'	=>	'application/postscript',
+						'smi'	=>	'application/smil',
+						'smil'	=>	'application/smil',
+						'mif'	=>	'application/vnd.mif',
+						'xls'	=>	'application/vnd.ms-excel',
+						'ppt'	=>	'application/vnd.ms-powerpoint',
+						'wbxml'	=>	'application/vnd.wap.wbxml',
+						'wmlc'	=>	'application/vnd.wap.wmlc',
+						'dcr'	=>	'application/x-director',
+						'dir'	=>	'application/x-director',
+						'dxr'	=>	'application/x-director',
+						'dvi'	=>	'application/x-dvi',
+						'gtar'	=>	'application/x-gtar',
+						'php'	=>	'application/x-httpd-php',
+						'php4'	=>	'application/x-httpd-php',
+						'php3'	=>	'application/x-httpd-php',
+						'phtml'	=>	'application/x-httpd-php',
+						'phps'	=>	'application/x-httpd-php-source',
+						'js'	=>	'application/x-javascript',
+						'swf'	=>	'application/x-shockwave-flash',
+						'sit'	=>	'application/x-stuffit',
+						'tar'	=>	'application/x-tar',
+						'tgz'	=>	'application/x-tar',
+						'xhtml'	=>	'application/xhtml+xml',
+						'xht'	=>	'application/xhtml+xml',
+						'zip'	=>	'application/zip',
+						'mid'	=>	'audio/midi',
+						'midi'	=>	'audio/midi',
+						'mpga'	=>	'audio/mpeg',
+						'mp2'	=>	'audio/mpeg',
+						'mp3'	=>	'audio/mpeg',
+						'aif'	=>	'audio/x-aiff',
+						'aiff'	=>	'audio/x-aiff',
+						'aifc'	=>	'audio/x-aiff',
+						'ram'	=>	'audio/x-pn-realaudio',
+						'rm'	=>	'audio/x-pn-realaudio',
+						'rpm'	=>	'audio/x-pn-realaudio-plugin',
+						'ra'	=>	'audio/x-realaudio',
+						'rv'	=>	'video/vnd.rn-realvideo',
+						'wav'	=>	'audio/x-wav',
+						'bmp'	=>	'image/bmp',
+						'gif'	=>	'image/gif',
+						'jpeg'	=>	'image/jpeg',
+						'jpg'	=>	'image/jpeg',
+						'jpe'	=>	'image/jpeg',
+						'png'	=>	'image/png',
+						'tiff'	=>	'image/tiff',
+						'tif'	=>	'image/tiff',
+						'css'	=>	'text/css',
+						'html'	=>	'text/html',
+						'htm'	=>	'text/html',
+						'shtml'	=>	'text/html',
+						'txt'	=>	'text/plain',
+						'text'	=>	'text/plain',
+						'log'	=>	'text/plain',
+						'rtx'	=>	'text/richtext',
+						'rtf'	=>	'text/rtf',
+						'xml'	=>	'text/xml',
+						'xsl'	=>	'text/xml',
+						'mpeg'	=>	'video/mpeg',
+						'mpg'	=>	'video/mpeg',
+						'mpe'	=>	'video/mpeg',
+						'qt'	=>	'video/quicktime',
+						'mov'	=>	'video/quicktime',
+						'avi'	=>	'video/x-msvideo',
+						'movie'	=>	'video/x-sgi-movie',
+						'doc'	=>	'application/msword',
+						'word'	=>	'application/msword',
+						'xl'	=>	'application/excel',
+						'eml'	=>	'message/rfc822'
+					);
+
+		return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
+	}
+
+}
+// END CI_Email class
+
+/* End of file Email.php */
 /* Location: ./system/libraries/Email.php */
\ No newline at end of file
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index 035ce8f..4edfaa7 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -1,484 +1,484 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Encryption Class

- *

- * Provides two-way keyed encoding using XOR Hashing and Mcrypt

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/encryption.html

- */

-class CI_Encrypt {

-

-	var $CI;

-	var $encryption_key	= '';

-	var $_hash_type	= 'sha1';

-	var $_mcrypt_exists = FALSE;

-	var $_mcrypt_cipher;

-	var $_mcrypt_mode;

-

-	/**

-	 * Constructor

-	 *

-	 * Simply determines whether the mcrypt library exists.

-	 *

-	 */

-	function CI_Encrypt()

-	{

-		$this->CI =& get_instance();

-		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;

-		log_message('debug', "Encrypt Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch the encryption key

-	 *

-	 * Returns it as MD5 in order to have an exact-length 128 bit key.

-	 * Mcrypt is sensitive to keys that are not the correct length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function get_key($key = '')

-	{

-		if ($key == '')

-		{

-			if ($this->encryption_key != '')

-			{

-				return $this->encryption_key;

-			}

-

-			$CI =& get_instance();

-			$key = $CI->config->item('encryption_key');

-

-			if ($key === FALSE)

-			{

-				show_error('In order to use the encryption class requires that you set an encryption key in your config file.');

-			}

-		}

-

-		return md5($key);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the encryption key

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_key($key = '')

-	{

-		$this->encryption_key = $key;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Encode

-	 *

-	 * Encodes the message string using bitwise XOR encoding.

-	 * The key is combined with a random hash, and then it

-	 * too gets converted using XOR. The whole thing is then run

-	 * through mcrypt (if supported) using the randomized key.

-	 * The end result is a double-encrypted message string

-	 * that is randomized with each call to this function,

-	 * even if the supplied message and key are the same.

-	 *

-	 * @access	public

-	 * @param	string	the string to encode

-	 * @param	string	the key

-	 * @return	string

-	 */

-	function encode($string, $key = '')

-	{

-		$key = $this->get_key($key);

-		$enc = $this->_xor_encode($string, $key);

-		

-		if ($this->_mcrypt_exists === TRUE)

-		{

-			$enc = $this->mcrypt_encode($enc, $key);

-		}

-		return base64_encode($enc);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Decode

-	 *

-	 * Reverses the above process

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function decode($string, $key = '')

-	{

-		$key = $this->get_key($key);

-		

-		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))

-		{

-			return FALSE;

-		}

-

-		$dec = base64_decode($string);

-

-		if ($this->_mcrypt_exists === TRUE)

-		{

-			if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)

-			{

-				return FALSE;

-			}

-		}

-

-		return $this->_xor_decode($dec, $key);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * XOR Encode

-	 *

-	 * Takes a plain-text string and key as input and generates an

-	 * encoded bit-string using XOR

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _xor_encode($string, $key)

-	{

-		$rand = '';

-		while (strlen($rand) < 32)

-		{

-			$rand .= mt_rand(0, mt_getrandmax());

-		}

-

-		$rand = $this->hash($rand);

-

-		$enc = '';

-		for ($i = 0; $i < strlen($string); $i++)

-		{			

-			$enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));

-		}

-

-		return $this->_xor_merge($enc, $key);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * XOR Decode

-	 *

-	 * Takes an encoded string and key as input and generates the

-	 * plain-text original message

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _xor_decode($string, $key)

-	{

-		$string = $this->_xor_merge($string, $key);

-

-		$dec = '';

-		for ($i = 0; $i < strlen($string); $i++)

-		{

-			$dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));

-		}

-

-		return $dec;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * XOR key + string Combiner

-	 *

-	 * Takes a string and key as input and computes the difference using XOR

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _xor_merge($string, $key)

-	{

-		$hash = $this->hash($key);

-		$str = '';

-		for ($i = 0; $i < strlen($string); $i++)

-		{

-			$str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Encrypt using Mcrypt

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function mcrypt_encode($data, $key)

-	{

-		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());

-		$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);

-		return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Decrypt using Mcrypt

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function mcrypt_decode($data, $key)

-	{

-		$data = $this->_remove_cipher_noise($data, $key);

-		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());

-

-		if ($init_size > strlen($data))

-		{

-			return FALSE;

-		}

-

-		$init_vect = substr($data, 0, $init_size);

-		$data = substr($data, $init_size);

-		return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Adds permuted noise to the IV + encrypted data to protect

-	 * against Man-in-the-middle attacks on CBC mode ciphers

-	 * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV

-	 *

-	 * Function description

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _add_cipher_noise($data, $key)

-	{

-		$keyhash = $this->hash($key);

-		$keylen = strlen($keyhash);

-		$str = '';

-

-		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)

-		{

-			if ($j >= $keylen)

-			{

-				$j = 0;

-			}

-

-			$str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Removes permuted noise from the IV + encrypted data, reversing

-	 * _add_cipher_noise()

-	 *

-	 * Function description

-	 *

-	 * @access	public

-	 * @param	type

-	 * @return	type

-	 */

-	function _remove_cipher_noise($data, $key)

-	{

-		$keyhash = $this->hash($key);

-		$keylen = strlen($keyhash);

-		$str = '';

-

-		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)

-		{

-			if ($j >= $keylen)

-			{

-				$j = 0;

-			}

-

-			$temp = ord($data[$i]) - ord($keyhash[$j]);

-

-			if ($temp < 0)

-			{

-				$temp = $temp + 256;

-			}

-			

-			$str .= chr($temp);

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Mcrypt Cipher

-	 *

-	 * @access	public

-	 * @param	constant

-	 * @return	string

-	 */

-	function set_cipher($cipher)

-	{

-		$this->_mcrypt_cipher = $cipher;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the Mcrypt Mode

-	 *

-	 * @access	public

-	 * @param	constant

-	 * @return	string

-	 */

-	function set_mode($mode)

-	{

-		$this->_mcrypt_mode = $mode;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Mcrypt cipher Value

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_cipher()

-	{

-		if ($this->_mcrypt_cipher == '')

-		{

-			$this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;

-		}

-

-		return $this->_mcrypt_cipher;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get Mcrypt Mode Value

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_mode()

-	{

-		if ($this->_mcrypt_mode == '')

-		{

-			$this->_mcrypt_mode = MCRYPT_MODE_ECB;

-		}

-		

-		return $this->_mcrypt_mode;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the Hash type

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function set_hash($type = 'sha1')

-	{

-		$this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Hash encode a string

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function hash($str)

-	{

-		return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate an SHA1 Hash

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function sha1($str)

-	{

-		if ( ! function_exists('sha1'))

-		{

-			if ( ! function_exists('mhash'))

-			{

-				require_once(BASEPATH.'libraries/Sha1'.EXT);

-				$SH = new CI_SHA;

-				return $SH->generate($str);

-			}

-			else

-			{

-				return bin2hex(mhash(MHASH_SHA1, $str));

-			}

-		}

-		else

-		{

-			return sha1($str);

-		}

-	}

-

-}

-

-// END CI_Encrypt class

-

-/* End of file Encrypt.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Encryption Class
+ *
+ * Provides two-way keyed encoding using XOR Hashing and Mcrypt
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/encryption.html
+ */
+class CI_Encrypt {
+
+	var $CI;
+	var $encryption_key	= '';
+	var $_hash_type	= 'sha1';
+	var $_mcrypt_exists = FALSE;
+	var $_mcrypt_cipher;
+	var $_mcrypt_mode;
+
+	/**
+	 * Constructor
+	 *
+	 * Simply determines whether the mcrypt library exists.
+	 *
+	 */
+	function CI_Encrypt()
+	{
+		$this->CI =& get_instance();
+		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
+		log_message('debug', "Encrypt Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch the encryption key
+	 *
+	 * Returns it as MD5 in order to have an exact-length 128 bit key.
+	 * Mcrypt is sensitive to keys that are not the correct length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function get_key($key = '')
+	{
+		if ($key == '')
+		{
+			if ($this->encryption_key != '')
+			{
+				return $this->encryption_key;
+			}
+
+			$CI =& get_instance();
+			$key = $CI->config->item('encryption_key');
+
+			if ($key === FALSE)
+			{
+				show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
+			}
+		}
+
+		return md5($key);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the encryption key
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_key($key = '')
+	{
+		$this->encryption_key = $key;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Encode
+	 *
+	 * Encodes the message string using bitwise XOR encoding.
+	 * The key is combined with a random hash, and then it
+	 * too gets converted using XOR. The whole thing is then run
+	 * through mcrypt (if supported) using the randomized key.
+	 * The end result is a double-encrypted message string
+	 * that is randomized with each call to this function,
+	 * even if the supplied message and key are the same.
+	 *
+	 * @access	public
+	 * @param	string	the string to encode
+	 * @param	string	the key
+	 * @return	string
+	 */
+	function encode($string, $key = '')
+	{
+		$key = $this->get_key($key);
+		$enc = $this->_xor_encode($string, $key);
+		
+		if ($this->_mcrypt_exists === TRUE)
+		{
+			$enc = $this->mcrypt_encode($enc, $key);
+		}
+		return base64_encode($enc);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Decode
+	 *
+	 * Reverses the above process
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function decode($string, $key = '')
+	{
+		$key = $this->get_key($key);
+		
+		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
+		{
+			return FALSE;
+		}
+
+		$dec = base64_decode($string);
+
+		if ($this->_mcrypt_exists === TRUE)
+		{
+			if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
+			{
+				return FALSE;
+			}
+		}
+
+		return $this->_xor_decode($dec, $key);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * XOR Encode
+	 *
+	 * Takes a plain-text string and key as input and generates an
+	 * encoded bit-string using XOR
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _xor_encode($string, $key)
+	{
+		$rand = '';
+		while (strlen($rand) < 32)
+		{
+			$rand .= mt_rand(0, mt_getrandmax());
+		}
+
+		$rand = $this->hash($rand);
+
+		$enc = '';
+		for ($i = 0; $i < strlen($string); $i++)
+		{			
+			$enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));
+		}
+
+		return $this->_xor_merge($enc, $key);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * XOR Decode
+	 *
+	 * Takes an encoded string and key as input and generates the
+	 * plain-text original message
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _xor_decode($string, $key)
+	{
+		$string = $this->_xor_merge($string, $key);
+
+		$dec = '';
+		for ($i = 0; $i < strlen($string); $i++)
+		{
+			$dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));
+		}
+
+		return $dec;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * XOR key + string Combiner
+	 *
+	 * Takes a string and key as input and computes the difference using XOR
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _xor_merge($string, $key)
+	{
+		$hash = $this->hash($key);
+		$str = '';
+		for ($i = 0; $i < strlen($string); $i++)
+		{
+			$str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Encrypt using Mcrypt
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function mcrypt_encode($data, $key)
+	{
+		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
+		$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
+		return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Decrypt using Mcrypt
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function mcrypt_decode($data, $key)
+	{
+		$data = $this->_remove_cipher_noise($data, $key);
+		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
+
+		if ($init_size > strlen($data))
+		{
+			return FALSE;
+		}
+
+		$init_vect = substr($data, 0, $init_size);
+		$data = substr($data, $init_size);
+		return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Adds permuted noise to the IV + encrypted data to protect
+	 * against Man-in-the-middle attacks on CBC mode ciphers
+	 * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
+	 *
+	 * Function description
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _add_cipher_noise($data, $key)
+	{
+		$keyhash = $this->hash($key);
+		$keylen = strlen($keyhash);
+		$str = '';
+
+		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
+		{
+			if ($j >= $keylen)
+			{
+				$j = 0;
+			}
+
+			$str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Removes permuted noise from the IV + encrypted data, reversing
+	 * _add_cipher_noise()
+	 *
+	 * Function description
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _remove_cipher_noise($data, $key)
+	{
+		$keyhash = $this->hash($key);
+		$keylen = strlen($keyhash);
+		$str = '';
+
+		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
+		{
+			if ($j >= $keylen)
+			{
+				$j = 0;
+			}
+
+			$temp = ord($data[$i]) - ord($keyhash[$j]);
+
+			if ($temp < 0)
+			{
+				$temp = $temp + 256;
+			}
+			
+			$str .= chr($temp);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Mcrypt Cipher
+	 *
+	 * @access	public
+	 * @param	constant
+	 * @return	string
+	 */
+	function set_cipher($cipher)
+	{
+		$this->_mcrypt_cipher = $cipher;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the Mcrypt Mode
+	 *
+	 * @access	public
+	 * @param	constant
+	 * @return	string
+	 */
+	function set_mode($mode)
+	{
+		$this->_mcrypt_mode = $mode;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Mcrypt cipher Value
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_cipher()
+	{
+		if ($this->_mcrypt_cipher == '')
+		{
+			$this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
+		}
+
+		return $this->_mcrypt_cipher;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get Mcrypt Mode Value
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_mode()
+	{
+		if ($this->_mcrypt_mode == '')
+		{
+			$this->_mcrypt_mode = MCRYPT_MODE_ECB;
+		}
+		
+		return $this->_mcrypt_mode;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the Hash type
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function set_hash($type = 'sha1')
+	{
+		$this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Hash encode a string
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function hash($str)
+	{
+		return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate an SHA1 Hash
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function sha1($str)
+	{
+		if ( ! function_exists('sha1'))
+		{
+			if ( ! function_exists('mhash'))
+			{
+				require_once(BASEPATH.'libraries/Sha1'.EXT);
+				$SH = new CI_SHA;
+				return $SH->generate($str);
+			}
+			else
+			{
+				return bin2hex(mhash(MHASH_SHA1, $str));
+			}
+		}
+		else
+		{
+			return sha1($str);
+		}
+	}
+
+}
+
+// END CI_Encrypt class
+
+/* End of file Encrypt.php */
 /* Location: ./system/libraries/Encrypt.php */
\ No newline at end of file
diff --git a/system/libraries/Exceptions.php b/system/libraries/Exceptions.php
index 5858266..541fd1a 100644
--- a/system/libraries/Exceptions.php
+++ b/system/libraries/Exceptions.php
@@ -1,172 +1,172 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Exceptions Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Exceptions

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/exceptions.html

- */

-class CI_Exceptions {

-	var $action;

-	var $severity;

-	var $message;

-	var $filename;

-	var $line;

-	var $ob_level;

-

-	var $levels = array(

-						E_ERROR				=>	'Error',

-						E_WARNING			=>	'Warning',

-						E_PARSE				=>	'Parsing Error',

-						E_NOTICE			=>	'Notice',

-						E_CORE_ERROR		=>	'Core Error',

-						E_CORE_WARNING		=>	'Core Warning',

-						E_COMPILE_ERROR		=>	'Compile Error',

-						E_COMPILE_WARNING	=>	'Compile Warning',

-						E_USER_ERROR		=>	'User Error',

-						E_USER_WARNING		=>	'User Warning',

-						E_USER_NOTICE		=>	'User Notice',

-						E_STRICT			=>	'Runtime Notice'

-					);

-

-

-	/**

-	 * Constructor

-	 *

-	 */	

-	function CI_Exceptions()

-	{

-		$this->ob_level = ob_get_level();

-		// Note:  Do not log messages from this constructor.

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Exception Logger

-	 *

-	 * This function logs PHP generated error messages

-	 *

-	 * @access	private

-	 * @param	string	the error severity

-	 * @param	string	the error string

-	 * @param	string	the error filepath

-	 * @param	string	the error line number

-	 * @return	string

-	 */

-	function log_exception($severity, $message, $filepath, $line)

-	{	

-		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];

-		

-		log_message('error', 'Severity: '.$severity.'  --> '.$message. ' '.$filepath.' '.$line, TRUE);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * 404 Page Not Found Handler

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function show_404($page = '')

-	{	

-		$heading = "404 Page Not Found";

-		$message = "The page you requested was not found.";

-

-		log_message('error', '404 Page Not Found --> '.$page);

-		echo $this->show_error($heading, $message, 'error_404');

-		exit;

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * General Error Page

-	 *

-	 * This function takes an error message as input

-	 * (either as a string or an array) and displays

-	 * it using the specified template.

-	 *

-	 * @access	private

-	 * @param	string	the heading

-	 * @param	string	the message

-	 * @param	string	the template name

-	 * @return	string

-	 */

-	function show_error($heading, $message, $template = 'error_general')

-	{

-		$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';

-

-		if (ob_get_level() > $this->ob_level + 1)

-		{

-			ob_end_flush();	

-		}

-		ob_start();

-		include(APPPATH.'errors/'.$template.EXT);

-		$buffer = ob_get_contents();

-		ob_end_clean();

-		return $buffer;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Native PHP error handler

-	 *

-	 * @access	private

-	 * @param	string	the error severity

-	 * @param	string	the error string

-	 * @param	string	the error filepath

-	 * @param	string	the error line number

-	 * @return	string

-	 */

-	function show_php_error($severity, $message, $filepath, $line)

-	{	

-		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];

-	

-		$filepath = str_replace("\\", "/", $filepath);

-		

-		// For safety reasons we do not show the full file path

-		if (FALSE !== strpos($filepath, '/'))

-		{

-			$x = explode('/', $filepath);

-			$filepath = $x[count($x)-2].'/'.end($x);

-		}

-		

-		if (ob_get_level() > $this->ob_level + 1)

-		{

-			ob_end_flush();	

-		}

-		ob_start();

-		include(APPPATH.'errors/error_php'.EXT);

-		$buffer = ob_get_contents();

-		ob_end_clean();

-		echo $buffer;

-	}

-

-

-}

-// END Exceptions Class

-

-/* End of file Exceptions.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Exceptions Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Exceptions
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/exceptions.html
+ */
+class CI_Exceptions {
+	var $action;
+	var $severity;
+	var $message;
+	var $filename;
+	var $line;
+	var $ob_level;
+
+	var $levels = array(
+						E_ERROR				=>	'Error',
+						E_WARNING			=>	'Warning',
+						E_PARSE				=>	'Parsing Error',
+						E_NOTICE			=>	'Notice',
+						E_CORE_ERROR		=>	'Core Error',
+						E_CORE_WARNING		=>	'Core Warning',
+						E_COMPILE_ERROR		=>	'Compile Error',
+						E_COMPILE_WARNING	=>	'Compile Warning',
+						E_USER_ERROR		=>	'User Error',
+						E_USER_WARNING		=>	'User Warning',
+						E_USER_NOTICE		=>	'User Notice',
+						E_STRICT			=>	'Runtime Notice'
+					);
+
+
+	/**
+	 * Constructor
+	 *
+	 */	
+	function CI_Exceptions()
+	{
+		$this->ob_level = ob_get_level();
+		// Note:  Do not log messages from this constructor.
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Exception Logger
+	 *
+	 * This function logs PHP generated error messages
+	 *
+	 * @access	private
+	 * @param	string	the error severity
+	 * @param	string	the error string
+	 * @param	string	the error filepath
+	 * @param	string	the error line number
+	 * @return	string
+	 */
+	function log_exception($severity, $message, $filepath, $line)
+	{	
+		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
+		
+		log_message('error', 'Severity: '.$severity.'  --> '.$message. ' '.$filepath.' '.$line, TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 404 Page Not Found Handler
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function show_404($page = '')
+	{	
+		$heading = "404 Page Not Found";
+		$message = "The page you requested was not found.";
+
+		log_message('error', '404 Page Not Found --> '.$page);
+		echo $this->show_error($heading, $message, 'error_404');
+		exit;
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * General Error Page
+	 *
+	 * This function takes an error message as input
+	 * (either as a string or an array) and displays
+	 * it using the specified template.
+	 *
+	 * @access	private
+	 * @param	string	the heading
+	 * @param	string	the message
+	 * @param	string	the template name
+	 * @return	string
+	 */
+	function show_error($heading, $message, $template = 'error_general')
+	{
+		$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
+
+		if (ob_get_level() > $this->ob_level + 1)
+		{
+			ob_end_flush();	
+		}
+		ob_start();
+		include(APPPATH.'errors/'.$template.EXT);
+		$buffer = ob_get_contents();
+		ob_end_clean();
+		return $buffer;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Native PHP error handler
+	 *
+	 * @access	private
+	 * @param	string	the error severity
+	 * @param	string	the error string
+	 * @param	string	the error filepath
+	 * @param	string	the error line number
+	 * @return	string
+	 */
+	function show_php_error($severity, $message, $filepath, $line)
+	{	
+		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
+	
+		$filepath = str_replace("\\", "/", $filepath);
+		
+		// For safety reasons we do not show the full file path
+		if (FALSE !== strpos($filepath, '/'))
+		{
+			$x = explode('/', $filepath);
+			$filepath = $x[count($x)-2].'/'.end($x);
+		}
+		
+		if (ob_get_level() > $this->ob_level + 1)
+		{
+			ob_end_flush();	
+		}
+		ob_start();
+		include(APPPATH.'errors/error_php'.EXT);
+		$buffer = ob_get_contents();
+		ob_end_clean();
+		echo $buffer;
+	}
+
+
+}
+// END Exceptions Class
+
+/* End of file Exceptions.php */
 /* Location: ./system/libraries/Exceptions.php */
\ No newline at end of file
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 0c7687a..7be93a1 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -1,1287 +1,1287 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Form Validation Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Validation

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/form_validation.html

- */

-class CI_Form_validation {

-	

-	var $CI;

-	var $_field_data			= array();	

-	var $_config_rules			= array();

-	var $_error_array			= array();

-	var $_error_messages		= array();	

-	var $_error_prefix			= '<p>';

-	var $_error_suffix			= '</p>';

-	var $error_string			= '';

-	var $_safe_form_data 		= FALSE;

-

-

-	/**

-	 * Constructor

-	 *

-	 */	

-	function CI_Form_validation($rules = array())

-	{	

-		$this->CI =& get_instance();

-		

-		// Validation rules can be stored in a config file.

-		$this->_config_rules = $rules;

-		

-		// Automatically load the form helper

-		$this->CI->load->helper('form');

-

-		// Set the character encoding in MB.

-		if (function_exists('mb_internal_encoding'))

-		{

-			mb_internal_encoding($this->CI->config->item('charset'));

-		}

-	

-		log_message('debug', "Form Validation Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Rules

-	 *

-	 * This function takes an array of field names and validation

-	 * rules as input, validates the info, and stores it

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @return	void

-	 */

-	function set_rules($field, $label = '', $rules = '')

-	{

-		// No reason to set rules if we have no POST data

-		if (count($_POST) == 0)

-		{

-			return;

-		}

-	

-		// If an array was passed via the first parameter instead of indidual string

-		// values we cycle through it and recursively call this function.

-		if (is_array($field))

-		{

-			foreach ($field as $row)

-			{

-				// Houston, we have a problem...

-				if ( ! isset($row['field']) OR ! isset($row['rules']))

-				{

-					continue;

-				}

-

-				// If the field label wasn't passed we use the field name

-				$label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];

-

-				// Here we go!

-				$this->set_rules($row['field'], $label, $row['rules']);

-			}

-			return;

-		}

-		

-		// No fields? Nothing to do...

-		if ( ! is_string($field) OR  ! is_string($rules) OR $field == '')

-		{

-			return;

-		}

-

-		// If the field label wasn't passed we use the field name

-		$label = ($label == '') ? $field : $label;

-

-		// Is the field name an array?  We test for the existence of a bracket "[" in

-		// the field name to determine this.  If it is an array, we break it apart

-		// into its components so that we can fetch the corresponding POST data later		

-		if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))

-		{	

-			// Note: Due to a bug in current() that affects some versions

-			// of PHP we can not pass function call directly into it

-			$x = explode('[', $field);

-			$indexes[] = current($x);

-

-			for ($i = 0; $i < count($matches['0']); $i++)

-			{

-				if ($matches['1'][$i] != '')

-				{

-					$indexes[] = $matches['1'][$i];

-				}

-			}

-			

-			$is_array = TRUE;

-		}

-		else

-		{

-			$indexes 	= array();

-			$is_array	= FALSE;		

-		}

-		

-		// Build our master array		

-		$this->_field_data[$field] = array(

-											'field'				=> $field, 

-											'label'				=> $label, 

-											'rules'				=> $rules,

-											'is_array'			=> $is_array,

-											'keys'				=> $indexes,

-											'postdata'			=> NULL,

-											'error'				=> ''

-											);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Error Message

-	 *

-	 * Lets users set their own error messages on the fly.  Note:  The key

-	 * name has to match the  function name that it corresponds to.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function set_message($lang, $val = '')

-	{

-		if ( ! is_array($lang))

-		{

-			$lang = array($lang => $val);

-		}

-	

-		$this->_error_messages = array_merge($this->_error_messages, $lang);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set The Error Delimiter

-	 *

-	 * Permits a prefix/suffix to be added to each error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_error_delimiters($prefix = '<p>', $suffix = '</p>')

-	{

-		$this->_error_prefix = $prefix;

-		$this->_error_suffix = $suffix;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get Error Message

-	 *

-	 * Gets the error message associated with a particular field

-	 *

-	 * @access	public

-	 * @param	string	the field name

-	 * @return	void

-	 */	

-	function error($field = '', $prefix = '', $suffix = '')

-	{	

-		if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')

-		{

-			return '';

-		}

-		

-		if ($prefix == '')

-		{

-			$prefix = $this->_error_prefix;

-		}

-

-		if ($suffix == '')

-		{

-			$suffix = $this->_error_suffix;

-		}

-

-		return $prefix.$this->_field_data[$field]['error'].$suffix;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Error String

-	 *

-	 * Returns the error messages as a string, wrapped in the error delimiters

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	str

-	 */	

-	function error_string($prefix = '', $suffix = '')

-	{

-		// No errrors, validation passes!

-		if (count($this->_error_array) === 0)

-		{

-			return '';

-		}

-		

-		if ($prefix == '')

-		{

-			$prefix = $this->_error_prefix;

-		}

-

-		if ($suffix == '')

-		{

-			$suffix = $this->_error_suffix;

-		}

-		

-		// Generate the error string

-		$str = '';

-		foreach ($this->_error_array as $val)

-		{

-			if ($val != '')

-			{

-				$str .= $prefix.$val.$suffix."\n";

-			}

-		}

-		

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Run the Validator

-	 *

-	 * This function does all the work.

-	 *

-	 * @access	public

-	 * @return	bool

-	 */		

-	function run($group = '')

-	{

-		// Do we even have any data to process?  Mm?

-		if (count($_POST) == 0)

-		{

-			return FALSE;

-		}

-		

-		// Does the _field_data array containing the validation rules exist?

-		// If not, we look to see if they were assigned via a config file

-		if (count($this->_field_data) == 0)

-		{

-			// No validation rules?  We're done...

-			if (count($this->_config_rules) == 0)

-			{

-				return FALSE;

-			}

-			

-			// Is there a validation rule for the particular URI being accessed?

-			$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;

-			

-			if ($uri != '' AND isset($this->_config_rules[$uri]))

-			{

-				$this->set_rules($this->_config_rules[$uri]);

-			}

-			else

-			{

-				$this->set_rules($this->_config_rules);

-			}

-	

-			// We're we able to set the rules correctly?

-			if (count($this->_field_data) == 0)

-			{

-				log_message('debug', "Unable to find validation rules");

-				return FALSE;

-			}

-		}

-	

-		// Load the language file containing error messages

-		$this->CI->lang->load('form_validation');

-							

-		// Cycle through the rules for each field, match the 

-		// corresponding $_POST item and test for errors

-		foreach ($this->_field_data as $field => $row)

-		{		

-			// Fetch the data from the corresponding $_POST array and cache it in the _field_data array.

-			// Depending on whether the field name is an array or a string will determine where we get it from.

-			

-			if ($row['is_array'] == TRUE)

-			{

-				$this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);

-			}

-			else

-			{

-				if (isset($_POST[$field]) AND $_POST[$field] != "")

-				{

-					$this->_field_data[$field]['postdata'] = $_POST[$field];

-				}

-			}

-		

-			$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);		

-		}

-

-		// Did we end up with any errors?

-		$total_errors = count($this->_error_array);

-

-		if ($total_errors > 0)

-		{

-			$this->_safe_form_data = TRUE;

-		}

-

-		// Now we need to re-set the POST data with the new, processed data

-		$this->_reset_post_array();

-		

-		// No errors, validation passes!

-		if ($total_errors == 0)

-		{

-			return TRUE;

-		}

-

-		// Validation fails

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Traverse a multidimensional $_POST array index until the data is found

-	 *

-	 * @access	private

-	 * @param	array

-	 * @param	array

-	 * @param	integer

-	 * @return	mixed

-	 */		

-	function _reduce_array($array, $keys, $i = 0)

-	{

-		if (is_array($array))

-		{

-			if (isset($keys[$i]))

-			{

-				if (isset($array[$keys[$i]]))

-				{

-					$array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));

-				}

-				else

-				{

-					return NULL;

-				}

-			}

-			else

-			{

-				return $array;

-			}

-		}

-	

-		return $array;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Re-populate the _POST array with our finalized and processed data

-	 *

-	 * @access	private

-	 * @return	null

-	 */		

-	function _reset_post_array()

-	{

-		foreach ($this->_field_data as $field => $row)

-		{

-			if ( ! is_null($row['postdata']))

-			{

-				if ($row['is_array'] == FALSE)

-				{

-					if (isset($_POST[$row['field']]))

-					{

-						$_POST[$row['field']] = $this->prep_for_form($row['postdata']);

-					}

-				}

-				else

-				{

-					$post = '$_POST["';

-					

-					if (count($row['keys']) == 1)

-					{

-						$post .= current($row['keys']);

-						$post .= '"]';

-					}

-					else

-					{

-						$i = 0;

-						foreach ($row['keys'] as $val)

-						{

-							if ($i == 0)

-							{

-								$post .= $val.'"]';

-								$i++;

-								continue;

-							}

-						

-							$post .= '["'.$val.'"]';

-						}

-					}

-					

-					if (is_array($row['postdata']))

-					{					

-						$array = array();

-						foreach ($row['postdata'] as $k => $v)

-						{

-							$array[$k] = $this->prep_for_form($v);

-						}

-						

-						$post .= ' = $array;';

-					}

-					else

-					{						

-						$post .= ' = "'.$this->prep_for_form($row['postdata']).'";';

-					}

-

-					eval($post);

-				}

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Executes the Validation routines

-	 *

-	 * @access	private

-	 * @param	array

-	 * @param	array

-	 * @param	mixed

-	 * @param	integer

-	 * @return	mixed

-	 */	

-	function _execute($row, $rules, $postdata = NULL, $cycles = 0)

-	{

-		// If the $_POST data is an array we will run a recursive call

-		if (is_array($postdata))

-		{ 

-			foreach ($postdata as $key => $val)

-			{

-				$this->_execute($row, $rules, $val, $cycles);

-				$cycles++;

-			}

-			

-			return;

-		}

-		

-		// --------------------------------------------------------------------

-

-		// If the field is blank, but NOT required, no further tests are necessary

-		$callback = FALSE;

-		if ( ! in_array('required', $rules) AND is_null($postdata))

-		{

-			// Before we bail out, does the rule contain a callback?

-			if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))

-			{

-				$callback = TRUE;

-				$rules = (array('1' => $match[1]));

-			}

-			else

-			{

-				return;

-			}

-		}

-

-		// --------------------------------------------------------------------

-		

-		// Isset Test. Typically this rule will only apply to checkboxes.

-		if (is_null($postdata) AND $callback == FALSE)

-		{

-			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))

-			{

-				// Set the message type

-				$type = (in_array('required', $rules)) ? 'required' : 'isset';

-			

-				if ( ! isset($this->_error_messages[$type]))

-				{

-					if (FALSE === ($line = $this->CI->lang->line($type)))

-					{

-						$line = 'The field was not set';

-					}							

-				}

-				else

-				{

-					$line = $this->_error_messages[$type];

-				}

-				

-				// Build the error message

-				$message = sprintf($line, $this->_translate_fieldname($row['label']));

-

-				// Save the error message

-				$this->_field_data[$row['field']]['error'] = $message;

-				

-				if ( ! isset($this->_error_array[$row['field']]))

-				{

-					$this->_error_array[$row['field']] = $message;

-				}

-			}

-					

-			return;

-		}

-

-		// --------------------------------------------------------------------

-

-		// Cycle through each rule and run it

-		foreach ($rules As $rule)

-		{

-			$_in_array = FALSE;

-			

-			// We set the $postdata variable with the current data in our master array so that

-			// each cycle of the loop is dealing with the processed data from the last cycle

-			if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))

-			{

-				// We shouldn't need this safety, but just in case there isn't an array index

-				// associated with this cycle we'll bail out

-				if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))

-				{

-					continue;

-				}

-			

-				$postdata = $this->_field_data[$row['field']]['postdata'][$cycles];

-				$_in_array = TRUE;

-			}

-			else

-			{

-				$postdata = $this->_field_data[$row['field']]['postdata'];

-			}

-

-			// --------------------------------------------------------------------

-	

-			// Is the rule a callback?			

-			$callback = FALSE;

-			if (substr($rule, 0, 9) == 'callback_')

-			{

-				$rule = substr($rule, 9);

-				$callback = TRUE;

-			}

-			

-			// Strip the parameter (if exists) from the rule

-			// Rules can contain a parameter: max_length[5]

-			$param = FALSE;

-			if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))

-			{

-				$rule	= $match[1];

-				$param	= $match[2];

-			}

-			

-			// Call the function that corresponds to the rule

-			if ($callback === TRUE)

-			{

-				if ( ! method_exists($this->CI, $rule))

-				{ 		

-					continue;

-				}

-				

-				// Run the function and grab the result

-				$result = $this->CI->$rule($postdata, $param);

-

-				// Re-assign the result to the master data array

-				if ($_in_array == TRUE)

-				{

-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;

-				}

-				else

-				{

-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;

-				}

-			

-				// If the field isn't required and we just processed a callback we'll move on...

-				if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)

-				{

-					return;

-				}

-			}

-			else

-			{				

-				if ( ! method_exists($this, $rule))

-				{

-					// If our own wrapper function doesn't exist we see if a native PHP function does. 

-					// Users can use any native PHP function call that has one param.

-					if (function_exists($rule))

-					{

-						$result = $rule($postdata);

-											

-						if ($_in_array == TRUE)

-						{

-							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;

-						}

-						else

-						{

-							$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;

-						}

-					}

-										

-					continue;

-				}

-

-				$result = $this->$rule($postdata, $param);

-

-				if ($_in_array == TRUE)

-				{

-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;

-				}

-				else

-				{

-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;

-				}

-			}

-							

-			// Did the rule test negatively?  If so, grab the error.

-			if ($result === FALSE)

-			{			

-				if ( ! isset($this->_error_messages[$rule]))

-				{

-					if (FALSE === ($line = $this->CI->lang->line($rule)))

-					{

-						$line = 'Unable to access an error message corresponding to your field name.';

-					}						

-				}

-				else

-				{

-					$line = $this->_error_messages[$rule];

-				}

-				

-				// Is the parameter we are inserting into the error message the name

-				// of another field?  If so we need to grab its "field label"

-				if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))

-				{

-					$param = $this->_field_data[$param]['label'];

-				}

-				

-				// Build the error message

-				$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);

-

-				// Save the error message

-				$this->_field_data[$row['field']]['error'] = $message;

-				

-				if ( ! isset($this->_error_array[$row['field']]))

-				{

-					$this->_error_array[$row['field']] = $message;

-				}

-				

-				return;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Translate a field name

-	 *

-	 * @access	private

-	 * @param	string	the field name

-	 * @return	string

-	 */	

-	function _translate_fieldname($fieldname)

-	{

-		// Do we need to translate the field name?

-		// We look for the prefix lang: to determine this

-		if (substr($fieldname, 0, 5) == 'lang:')

-		{

-			// Grab the variable

-			$line = substr($fieldname, 5);			

-			

-			// Were we able to translate the field name?  If not we use $line

-			if (FALSE === ($fieldname = $this->CI->lang->line($line)))

-			{

-				return $line;

-			}

-		}

-

-		return $fieldname;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the value from a form

-	 *

-	 * Permits you to repopulate a form field with the value it was submitted

-	 * with, or, if that value doesn't exist, with the default

-	 *

-	 * @access	public

-	 * @param	string	the field name

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_value($field = '', $default = '')

-	{

-		if ( ! isset($this->_field_data[$field]))

-		{

-			return $default;

-		}

-		

-		return $this->_field_data[$field]['postdata'];

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Select

-	 *

-	 * Enables pull-down lists to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_select($field = '', $value = '', $default = FALSE)

-	{		

-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))

-		{

-			if ($default === TRUE AND count($this->_field_data) === 0)

-			{

-				return ' selected="selected"';

-			}

-			return '';

-		}

-	

-		$field = $this->_field_data[$field]['postdata'];

-		

-		if (is_array($field))

-		{

-			if ( ! in_array($value, $field))

-			{

-				return '';

-			}

-		}

-		else

-		{

-			if (($field == '' OR $value == '') OR ($field != $value))

-			{

-				return '';

-			}

-		}

-			

-		return ' selected="selected"';

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Radio

-	 *

-	 * Enables radio buttons to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_radio($field = '', $value = '', $default = FALSE)

-	{

-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))

-		{

-			if ($default === TRUE AND count($this->_field_data) === 0)

-			{

-				return ' checked="checked"';

-			}

-			return '';

-		}

-	

-		$field = $this->_field_data[$field]['postdata'];

-		

-		if (is_array($field))

-		{

-			if ( ! in_array($value, $field))

-			{

-				return '';

-			}

-		}

-		else

-		{

-			if (($field == '' OR $value == '') OR ($field != $value))

-			{

-				return '';

-			}

-		}

-			

-		return ' checked="checked"';

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Checkbox

-	 *

-	 * Enables checkboxes to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_checkbox($field = '', $value = '', $default = FALSE)

-	{

-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))

-		{

-			if ($default === TRUE AND count($this->_field_data) === 0)

-			{

-				return ' checked="checked"';

-			}

-			return '';

-		}

-	

-		$field = $this->_field_data[$field]['postdata'];

-		

-		if (is_array($field))

-		{

-			if ( ! in_array($value, $field))

-			{

-				return '';

-			}

-		}

-		else

-		{

-			if (($field == '' OR $value == '') OR ($field != $value))

-			{

-				return '';

-			}

-		}

-			

-		return ' checked="checked"';

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Required

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function required($str)

-	{

-		if ( ! is_array($str))

-		{

-			return (trim($str) == '') ? FALSE : TRUE;

-		}

-		else

-		{

-			return ( ! empty($str));

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Match one field to another

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	field

-	 * @return	bool

-	 */

-	function matches($str, $field)

-	{

-		if ( ! isset($_POST[$field]))

-		{

-			return FALSE;				

-		}

-		

-		$field = $_POST[$field];

-

-		return ($str !== $field) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Minimum Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function min_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) < $val) ? FALSE : TRUE;		

-		}

-	

-		return (strlen($str) < $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Max Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function max_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) > $val) ? FALSE : TRUE;		

-		}

-	

-		return (strlen($str) > $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Exact Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function exact_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) != $val) ? FALSE : TRUE;		

-		}

-	

-		return (strlen($str) != $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Email

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function valid_email($str)

-	{

-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Emails

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function valid_emails($str)

-	{

-		if (strpos($str, ',') === FALSE)

-		{

-			return $this->valid_email(trim($str));

-		}

-		

-		foreach(explode(',', $str) as $email)

-		{

-			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)

-			{

-				return FALSE;

-			}

-		}

-		

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validate IP Address

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function valid_ip($ip)

-	{

-		return $this->CI->input->valid_ip($ip);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */		

-	function alpha($str)

-	{

-		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha-numeric

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function alpha_numeric($str)

-	{

-		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha-numeric with underscores and dashes

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function alpha_dash($str)

-	{

-		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Numeric

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function numeric($str)

-	{

-		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);

-

-	}

-

-	// --------------------------------------------------------------------

-

-    /**

-     * Is Numeric

-     *

-     * @access    public

-     * @param    string

-     * @return    bool

-     */

-    function is_numeric($str)

-    {

-        return ( ! is_numeric($str)) ? FALSE : TRUE;

-    } 

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Integer

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function integer($str)

-	{

-		return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);

-	}

-	

-	// --------------------------------------------------------------------

-

-    /**

-     * Is a Natural number  (0,1,2,3, etc.)

-     *

-     * @access	public

-     * @param	string

-     * @return	bool

-     */

-    function is_natural($str)

-    {   

-   		return (bool)preg_match( '/^[0-9]+$/', $str);

-    }

-

-	// --------------------------------------------------------------------

-

-    /**

-     * Is a Natural number, but not a zero  (1,2,3, etc.)

-     *

-     * @access	public

-     * @param	string

-     * @return	bool

-     */

-	function is_natural_no_zero($str)

-    {

-    	if ( ! preg_match( '/^[0-9]+$/', $str))

-    	{

-    		return FALSE;

-    	}

-    	

-    	if ($str == 0)

-    	{

-    		return FALSE;

-    	}

-    

-   		return TRUE;

-    }

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Base64

-	 *

-	 * Tests a string for characters outside of the Base64 alphabet

-	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function valid_base64($str)

-	{

-		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep data for form

-	 *

-	 * This function allows HTML to be safely shown in a form.

-	 * Special characters are converted.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function prep_for_form($data = '')

-	{

-		if (is_array($data))

-		{

-			foreach ($data as $key => $val)

-			{

-				$data[$key] = $this->prep_for_form($val);

-			}

-			

-			return $data;

-		}

-		

-		if ($this->_safe_form_data == FALSE OR $data === '')

-		{

-			return $data;

-		}

-

-		return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep URL

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function prep_url($str = '')

-	{

-		if ($str == 'http://' OR $str == '')

-		{

-			return '';

-		}

-		

-		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')

-		{

-			$str = 'http://'.$str;

-		}

-		

-		return $str;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Strip Image Tags

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function strip_image_tags($str)

-	{

-		return $this->CI->input->strip_image_tags($str);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * XSS Clean

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function xss_clean($str)

-	{

-		return $this->CI->input->xss_clean($str);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Convert PHP tags to entities

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function encode_php_tags($str)

-	{

-		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);

-	}

-

-}

-// END Form Validation Class

-

-/* End of file Form_validation.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Validation Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Validation
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/form_validation.html
+ */
+class CI_Form_validation {
+	
+	var $CI;
+	var $_field_data			= array();	
+	var $_config_rules			= array();
+	var $_error_array			= array();
+	var $_error_messages		= array();	
+	var $_error_prefix			= '<p>';
+	var $_error_suffix			= '</p>';
+	var $error_string			= '';
+	var $_safe_form_data 		= FALSE;
+
+
+	/**
+	 * Constructor
+	 *
+	 */	
+	function CI_Form_validation($rules = array())
+	{	
+		$this->CI =& get_instance();
+		
+		// Validation rules can be stored in a config file.
+		$this->_config_rules = $rules;
+		
+		// Automatically load the form helper
+		$this->CI->load->helper('form');
+
+		// Set the character encoding in MB.
+		if (function_exists('mb_internal_encoding'))
+		{
+			mb_internal_encoding($this->CI->config->item('charset'));
+		}
+	
+		log_message('debug', "Form Validation Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Rules
+	 *
+	 * This function takes an array of field names and validation
+	 * rules as input, validates the info, and stores it
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
+	function set_rules($field, $label = '', $rules = '')
+	{
+		// No reason to set rules if we have no POST data
+		if (count($_POST) == 0)
+		{
+			return;
+		}
+	
+		// If an array was passed via the first parameter instead of indidual string
+		// values we cycle through it and recursively call this function.
+		if (is_array($field))
+		{
+			foreach ($field as $row)
+			{
+				// Houston, we have a problem...
+				if ( ! isset($row['field']) OR ! isset($row['rules']))
+				{
+					continue;
+				}
+
+				// If the field label wasn't passed we use the field name
+				$label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];
+
+				// Here we go!
+				$this->set_rules($row['field'], $label, $row['rules']);
+			}
+			return;
+		}
+		
+		// No fields? Nothing to do...
+		if ( ! is_string($field) OR  ! is_string($rules) OR $field == '')
+		{
+			return;
+		}
+
+		// If the field label wasn't passed we use the field name
+		$label = ($label == '') ? $field : $label;
+
+		// Is the field name an array?  We test for the existence of a bracket "[" in
+		// the field name to determine this.  If it is an array, we break it apart
+		// into its components so that we can fetch the corresponding POST data later		
+		if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))
+		{	
+			// Note: Due to a bug in current() that affects some versions
+			// of PHP we can not pass function call directly into it
+			$x = explode('[', $field);
+			$indexes[] = current($x);
+
+			for ($i = 0; $i < count($matches['0']); $i++)
+			{
+				if ($matches['1'][$i] != '')
+				{
+					$indexes[] = $matches['1'][$i];
+				}
+			}
+			
+			$is_array = TRUE;
+		}
+		else
+		{
+			$indexes 	= array();
+			$is_array	= FALSE;		
+		}
+		
+		// Build our master array		
+		$this->_field_data[$field] = array(
+											'field'				=> $field, 
+											'label'				=> $label, 
+											'rules'				=> $rules,
+											'is_array'			=> $is_array,
+											'keys'				=> $indexes,
+											'postdata'			=> NULL,
+											'error'				=> ''
+											);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Error Message
+	 *
+	 * Lets users set their own error messages on the fly.  Note:  The key
+	 * name has to match the  function name that it corresponds to.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function set_message($lang, $val = '')
+	{
+		if ( ! is_array($lang))
+		{
+			$lang = array($lang => $val);
+		}
+	
+		$this->_error_messages = array_merge($this->_error_messages, $lang);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set The Error Delimiter
+	 *
+	 * Permits a prefix/suffix to be added to each error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
+	{
+		$this->_error_prefix = $prefix;
+		$this->_error_suffix = $suffix;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get Error Message
+	 *
+	 * Gets the error message associated with a particular field
+	 *
+	 * @access	public
+	 * @param	string	the field name
+	 * @return	void
+	 */	
+	function error($field = '', $prefix = '', $suffix = '')
+	{	
+		if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
+		{
+			return '';
+		}
+		
+		if ($prefix == '')
+		{
+			$prefix = $this->_error_prefix;
+		}
+
+		if ($suffix == '')
+		{
+			$suffix = $this->_error_suffix;
+		}
+
+		return $prefix.$this->_field_data[$field]['error'].$suffix;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Error String
+	 *
+	 * Returns the error messages as a string, wrapped in the error delimiters
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	str
+	 */	
+	function error_string($prefix = '', $suffix = '')
+	{
+		// No errrors, validation passes!
+		if (count($this->_error_array) === 0)
+		{
+			return '';
+		}
+		
+		if ($prefix == '')
+		{
+			$prefix = $this->_error_prefix;
+		}
+
+		if ($suffix == '')
+		{
+			$suffix = $this->_error_suffix;
+		}
+		
+		// Generate the error string
+		$str = '';
+		foreach ($this->_error_array as $val)
+		{
+			if ($val != '')
+			{
+				$str .= $prefix.$val.$suffix."\n";
+			}
+		}
+		
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Run the Validator
+	 *
+	 * This function does all the work.
+	 *
+	 * @access	public
+	 * @return	bool
+	 */		
+	function run($group = '')
+	{
+		// Do we even have any data to process?  Mm?
+		if (count($_POST) == 0)
+		{
+			return FALSE;
+		}
+		
+		// Does the _field_data array containing the validation rules exist?
+		// If not, we look to see if they were assigned via a config file
+		if (count($this->_field_data) == 0)
+		{
+			// No validation rules?  We're done...
+			if (count($this->_config_rules) == 0)
+			{
+				return FALSE;
+			}
+			
+			// Is there a validation rule for the particular URI being accessed?
+			$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
+			
+			if ($uri != '' AND isset($this->_config_rules[$uri]))
+			{
+				$this->set_rules($this->_config_rules[$uri]);
+			}
+			else
+			{
+				$this->set_rules($this->_config_rules);
+			}
+	
+			// We're we able to set the rules correctly?
+			if (count($this->_field_data) == 0)
+			{
+				log_message('debug', "Unable to find validation rules");
+				return FALSE;
+			}
+		}
+	
+		// Load the language file containing error messages
+		$this->CI->lang->load('form_validation');
+							
+		// Cycle through the rules for each field, match the 
+		// corresponding $_POST item and test for errors
+		foreach ($this->_field_data as $field => $row)
+		{		
+			// Fetch the data from the corresponding $_POST array and cache it in the _field_data array.
+			// Depending on whether the field name is an array or a string will determine where we get it from.
+			
+			if ($row['is_array'] == TRUE)
+			{
+				$this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
+			}
+			else
+			{
+				if (isset($_POST[$field]) AND $_POST[$field] != "")
+				{
+					$this->_field_data[$field]['postdata'] = $_POST[$field];
+				}
+			}
+		
+			$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);		
+		}
+
+		// Did we end up with any errors?
+		$total_errors = count($this->_error_array);
+
+		if ($total_errors > 0)
+		{
+			$this->_safe_form_data = TRUE;
+		}
+
+		// Now we need to re-set the POST data with the new, processed data
+		$this->_reset_post_array();
+		
+		// No errors, validation passes!
+		if ($total_errors == 0)
+		{
+			return TRUE;
+		}
+
+		// Validation fails
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Traverse a multidimensional $_POST array index until the data is found
+	 *
+	 * @access	private
+	 * @param	array
+	 * @param	array
+	 * @param	integer
+	 * @return	mixed
+	 */		
+	function _reduce_array($array, $keys, $i = 0)
+	{
+		if (is_array($array))
+		{
+			if (isset($keys[$i]))
+			{
+				if (isset($array[$keys[$i]]))
+				{
+					$array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
+				}
+				else
+				{
+					return NULL;
+				}
+			}
+			else
+			{
+				return $array;
+			}
+		}
+	
+		return $array;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Re-populate the _POST array with our finalized and processed data
+	 *
+	 * @access	private
+	 * @return	null
+	 */		
+	function _reset_post_array()
+	{
+		foreach ($this->_field_data as $field => $row)
+		{
+			if ( ! is_null($row['postdata']))
+			{
+				if ($row['is_array'] == FALSE)
+				{
+					if (isset($_POST[$row['field']]))
+					{
+						$_POST[$row['field']] = $this->prep_for_form($row['postdata']);
+					}
+				}
+				else
+				{
+					$post = '$_POST["';
+					
+					if (count($row['keys']) == 1)
+					{
+						$post .= current($row['keys']);
+						$post .= '"]';
+					}
+					else
+					{
+						$i = 0;
+						foreach ($row['keys'] as $val)
+						{
+							if ($i == 0)
+							{
+								$post .= $val.'"]';
+								$i++;
+								continue;
+							}
+						
+							$post .= '["'.$val.'"]';
+						}
+					}
+					
+					if (is_array($row['postdata']))
+					{					
+						$array = array();
+						foreach ($row['postdata'] as $k => $v)
+						{
+							$array[$k] = $this->prep_for_form($v);
+						}
+						
+						$post .= ' = $array;';
+					}
+					else
+					{						
+						$post .= ' = "'.$this->prep_for_form($row['postdata']).'";';
+					}
+
+					eval($post);
+				}
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Executes the Validation routines
+	 *
+	 * @access	private
+	 * @param	array
+	 * @param	array
+	 * @param	mixed
+	 * @param	integer
+	 * @return	mixed
+	 */	
+	function _execute($row, $rules, $postdata = NULL, $cycles = 0)
+	{
+		// If the $_POST data is an array we will run a recursive call
+		if (is_array($postdata))
+		{ 
+			foreach ($postdata as $key => $val)
+			{
+				$this->_execute($row, $rules, $val, $cycles);
+				$cycles++;
+			}
+			
+			return;
+		}
+		
+		// --------------------------------------------------------------------
+
+		// If the field is blank, but NOT required, no further tests are necessary
+		$callback = FALSE;
+		if ( ! in_array('required', $rules) AND is_null($postdata))
+		{
+			// Before we bail out, does the rule contain a callback?
+			if (preg_match("/(callback_\w+)/", implode(' ', $rules), $match))
+			{
+				$callback = TRUE;
+				$rules = (array('1' => $match[1]));
+			}
+			else
+			{
+				return;
+			}
+		}
+
+		// --------------------------------------------------------------------
+		
+		// Isset Test. Typically this rule will only apply to checkboxes.
+		if (is_null($postdata) AND $callback == FALSE)
+		{
+			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
+			{
+				// Set the message type
+				$type = (in_array('required', $rules)) ? 'required' : 'isset';
+			
+				if ( ! isset($this->_error_messages[$type]))
+				{
+					if (FALSE === ($line = $this->CI->lang->line($type)))
+					{
+						$line = 'The field was not set';
+					}							
+				}
+				else
+				{
+					$line = $this->_error_messages[$type];
+				}
+				
+				// Build the error message
+				$message = sprintf($line, $this->_translate_fieldname($row['label']));
+
+				// Save the error message
+				$this->_field_data[$row['field']]['error'] = $message;
+				
+				if ( ! isset($this->_error_array[$row['field']]))
+				{
+					$this->_error_array[$row['field']] = $message;
+				}
+			}
+					
+			return;
+		}
+
+		// --------------------------------------------------------------------
+
+		// Cycle through each rule and run it
+		foreach ($rules As $rule)
+		{
+			$_in_array = FALSE;
+			
+			// We set the $postdata variable with the current data in our master array so that
+			// each cycle of the loop is dealing with the processed data from the last cycle
+			if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
+			{
+				// We shouldn't need this safety, but just in case there isn't an array index
+				// associated with this cycle we'll bail out
+				if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
+				{
+					continue;
+				}
+			
+				$postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
+				$_in_array = TRUE;
+			}
+			else
+			{
+				$postdata = $this->_field_data[$row['field']]['postdata'];
+			}
+
+			// --------------------------------------------------------------------
+	
+			// Is the rule a callback?			
+			$callback = FALSE;
+			if (substr($rule, 0, 9) == 'callback_')
+			{
+				$rule = substr($rule, 9);
+				$callback = TRUE;
+			}
+			
+			// Strip the parameter (if exists) from the rule
+			// Rules can contain a parameter: max_length[5]
+			$param = FALSE;
+			if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
+			{
+				$rule	= $match[1];
+				$param	= $match[2];
+			}
+			
+			// Call the function that corresponds to the rule
+			if ($callback === TRUE)
+			{
+				if ( ! method_exists($this->CI, $rule))
+				{ 		
+					continue;
+				}
+				
+				// Run the function and grab the result
+				$result = $this->CI->$rule($postdata, $param);
+
+				// Re-assign the result to the master data array
+				if ($_in_array == TRUE)
+				{
+					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+				}
+				else
+				{
+					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+				}
+			
+				// If the field isn't required and we just processed a callback we'll move on...
+				if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
+				{
+					return;
+				}
+			}
+			else
+			{				
+				if ( ! method_exists($this, $rule))
+				{
+					// If our own wrapper function doesn't exist we see if a native PHP function does. 
+					// Users can use any native PHP function call that has one param.
+					if (function_exists($rule))
+					{
+						$result = $rule($postdata);
+											
+						if ($_in_array == TRUE)
+						{
+							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+						}
+						else
+						{
+							$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+						}
+					}
+										
+					continue;
+				}
+
+				$result = $this->$rule($postdata, $param);
+
+				if ($_in_array == TRUE)
+				{
+					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+				}
+				else
+				{
+					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+				}
+			}
+							
+			// Did the rule test negatively?  If so, grab the error.
+			if ($result === FALSE)
+			{			
+				if ( ! isset($this->_error_messages[$rule]))
+				{
+					if (FALSE === ($line = $this->CI->lang->line($rule)))
+					{
+						$line = 'Unable to access an error message corresponding to your field name.';
+					}						
+				}
+				else
+				{
+					$line = $this->_error_messages[$rule];
+				}
+				
+				// Is the parameter we are inserting into the error message the name
+				// of another field?  If so we need to grab its "field label"
+				if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
+				{
+					$param = $this->_field_data[$param]['label'];
+				}
+				
+				// Build the error message
+				$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
+
+				// Save the error message
+				$this->_field_data[$row['field']]['error'] = $message;
+				
+				if ( ! isset($this->_error_array[$row['field']]))
+				{
+					$this->_error_array[$row['field']] = $message;
+				}
+				
+				return;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Translate a field name
+	 *
+	 * @access	private
+	 * @param	string	the field name
+	 * @return	string
+	 */	
+	function _translate_fieldname($fieldname)
+	{
+		// Do we need to translate the field name?
+		// We look for the prefix lang: to determine this
+		if (substr($fieldname, 0, 5) == 'lang:')
+		{
+			// Grab the variable
+			$line = substr($fieldname, 5);			
+			
+			// Were we able to translate the field name?  If not we use $line
+			if (FALSE === ($fieldname = $this->CI->lang->line($line)))
+			{
+				return $line;
+			}
+		}
+
+		return $fieldname;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the value from a form
+	 *
+	 * Permits you to repopulate a form field with the value it was submitted
+	 * with, or, if that value doesn't exist, with the default
+	 *
+	 * @access	public
+	 * @param	string	the field name
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_value($field = '', $default = '')
+	{
+		if ( ! isset($this->_field_data[$field]))
+		{
+			return $default;
+		}
+		
+		return $this->_field_data[$field]['postdata'];
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Select
+	 *
+	 * Enables pull-down lists to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_select($field = '', $value = '', $default = FALSE)
+	{		
+		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
+		{
+			if ($default === TRUE AND count($this->_field_data) === 0)
+			{
+				return ' selected="selected"';
+			}
+			return '';
+		}
+	
+		$field = $this->_field_data[$field]['postdata'];
+		
+		if (is_array($field))
+		{
+			if ( ! in_array($value, $field))
+			{
+				return '';
+			}
+		}
+		else
+		{
+			if (($field == '' OR $value == '') OR ($field != $value))
+			{
+				return '';
+			}
+		}
+			
+		return ' selected="selected"';
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Radio
+	 *
+	 * Enables radio buttons to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_radio($field = '', $value = '', $default = FALSE)
+	{
+		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
+		{
+			if ($default === TRUE AND count($this->_field_data) === 0)
+			{
+				return ' checked="checked"';
+			}
+			return '';
+		}
+	
+		$field = $this->_field_data[$field]['postdata'];
+		
+		if (is_array($field))
+		{
+			if ( ! in_array($value, $field))
+			{
+				return '';
+			}
+		}
+		else
+		{
+			if (($field == '' OR $value == '') OR ($field != $value))
+			{
+				return '';
+			}
+		}
+			
+		return ' checked="checked"';
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Checkbox
+	 *
+	 * Enables checkboxes to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_checkbox($field = '', $value = '', $default = FALSE)
+	{
+		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
+		{
+			if ($default === TRUE AND count($this->_field_data) === 0)
+			{
+				return ' checked="checked"';
+			}
+			return '';
+		}
+	
+		$field = $this->_field_data[$field]['postdata'];
+		
+		if (is_array($field))
+		{
+			if ( ! in_array($value, $field))
+			{
+				return '';
+			}
+		}
+		else
+		{
+			if (($field == '' OR $value == '') OR ($field != $value))
+			{
+				return '';
+			}
+		}
+			
+		return ' checked="checked"';
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Required
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function required($str)
+	{
+		if ( ! is_array($str))
+		{
+			return (trim($str) == '') ? FALSE : TRUE;
+		}
+		else
+		{
+			return ( ! empty($str));
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Match one field to another
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	field
+	 * @return	bool
+	 */
+	function matches($str, $field)
+	{
+		if ( ! isset($_POST[$field]))
+		{
+			return FALSE;				
+		}
+		
+		$field = $_POST[$field];
+
+		return ($str !== $field) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Minimum Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function min_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) < $val) ? FALSE : TRUE;		
+		}
+	
+		return (strlen($str) < $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Max Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function max_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) > $val) ? FALSE : TRUE;		
+		}
+	
+		return (strlen($str) > $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Exact Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function exact_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) != $val) ? FALSE : TRUE;		
+		}
+	
+		return (strlen($str) != $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Email
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function valid_email($str)
+	{
+		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Emails
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function valid_emails($str)
+	{
+		if (strpos($str, ',') === FALSE)
+		{
+			return $this->valid_email(trim($str));
+		}
+		
+		foreach(explode(',', $str) as $email)
+		{
+			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
+			{
+				return FALSE;
+			}
+		}
+		
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate IP Address
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function valid_ip($ip)
+	{
+		return $this->CI->input->valid_ip($ip);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */		
+	function alpha($str)
+	{
+		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha-numeric
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function alpha_numeric($str)
+	{
+		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha-numeric with underscores and dashes
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function alpha_dash($str)
+	{
+		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Numeric
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function numeric($str)
+	{
+		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
+
+	}
+
+	// --------------------------------------------------------------------
+
+    /**
+     * Is Numeric
+     *
+     * @access    public
+     * @param    string
+     * @return    bool
+     */
+    function is_numeric($str)
+    {
+        return ( ! is_numeric($str)) ? FALSE : TRUE;
+    } 
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Integer
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function integer($str)
+	{
+		return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
+	}
+	
+	// --------------------------------------------------------------------
+
+    /**
+     * Is a Natural number  (0,1,2,3, etc.)
+     *
+     * @access	public
+     * @param	string
+     * @return	bool
+     */
+    function is_natural($str)
+    {   
+   		return (bool)preg_match( '/^[0-9]+$/', $str);
+    }
+
+	// --------------------------------------------------------------------
+
+    /**
+     * Is a Natural number, but not a zero  (1,2,3, etc.)
+     *
+     * @access	public
+     * @param	string
+     * @return	bool
+     */
+	function is_natural_no_zero($str)
+    {
+    	if ( ! preg_match( '/^[0-9]+$/', $str))
+    	{
+    		return FALSE;
+    	}
+    	
+    	if ($str == 0)
+    	{
+    		return FALSE;
+    	}
+    
+   		return TRUE;
+    }
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Base64
+	 *
+	 * Tests a string for characters outside of the Base64 alphabet
+	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function valid_base64($str)
+	{
+		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep data for form
+	 *
+	 * This function allows HTML to be safely shown in a form.
+	 * Special characters are converted.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function prep_for_form($data = '')
+	{
+		if (is_array($data))
+		{
+			foreach ($data as $key => $val)
+			{
+				$data[$key] = $this->prep_for_form($val);
+			}
+			
+			return $data;
+		}
+		
+		if ($this->_safe_form_data == FALSE OR $data === '')
+		{
+			return $data;
+		}
+
+		return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep URL
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function prep_url($str = '')
+	{
+		if ($str == 'http://' OR $str == '')
+		{
+			return '';
+		}
+		
+		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
+		{
+			$str = 'http://'.$str;
+		}
+		
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Strip Image Tags
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function strip_image_tags($str)
+	{
+		return $this->CI->input->strip_image_tags($str);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * XSS Clean
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function xss_clean($str)
+	{
+		return $this->CI->input->xss_clean($str);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Convert PHP tags to entities
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function encode_php_tags($str)
+	{
+		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+	}
+
+}
+// END Form Validation Class
+
+/* End of file 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 1a3ab18..ec84eb0 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -1,618 +1,618 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * FTP Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/ftp.html

- */

-class CI_FTP {

-

-	var $hostname	= '';

-	var $username	= '';

-	var $password	= '';

-	var $port		= 21;

-	var $passive	= TRUE;

-	var $debug		= FALSE;

-	var $conn_id	= FALSE;

-

-

-	/**

-	 * Constructor - Sets Preferences

-	 *

-	 * The constructor can be passed an array of config values

-	 */

-	function CI_FTP($config = array())

-	{

-		if (count($config) > 0)

-		{

-			$this->initialize($config);

-		}

-

-		log_message('debug', "FTP Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize preferences

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function initialize($config = array())

-	{

-		foreach ($config as $key => $val)

-		{

-			if (isset($this->$key))

-			{

-				$this->$key = $val;

-			}

-		}

-

-		// Prep the hostname

-		$this->hostname = preg_replace('|.+?://|', '', $this->hostname);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * FTP Connect

-	 *

-	 * @access	public

-	 * @param	array	 the connection values

-	 * @return	bool

-	 */

-	function connect($config = array())

-	{

-		if (count($config) > 0)

-		{

-			$this->initialize($config);

-		}

-

-		if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_connect');

-			}

-			return FALSE;

-		}

-

-		if ( ! $this->_login())

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_login');

-			}

-			return FALSE;

-		}

-

-		// Set passive mode if needed

-		if ($this->passive == TRUE)

-		{

-			ftp_pasv($this->conn_id, TRUE);

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * FTP Login

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _login()

-	{

-		return @ftp_login($this->conn_id, $this->username, $this->password);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Validates the connection ID

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _is_conn()

-	{

-		if ( ! is_resource($this->conn_id))

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_no_connection');

-			}

-			return FALSE;

-		}

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-

-	/**

-	 * Change direcotry

-	 *

-	 * The second parameter lets us momentarily turn off debugging so that

-	 * this function can be used to test for the existance of a folder

-	 * without throwing an error.  There's no FTP equivalent to is_dir()

-	 * so we do it by trying to change to a particular directory.

-	 * Internally, this paramter is only used by the "mirror" function below.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	bool

-	 * @return	bool

-	 */

-	function changedir($path = '', $supress_debug = FALSE)

-	{

-		if ($path == '' OR ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		$result = @ftp_chdir($this->conn_id, $path);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE AND $supress_debug == FALSE)

-			{

-				$this->_error('ftp_unable_to_changedir');

-			}

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create a directory

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function mkdir($path = '', $permissions = NULL)

-	{

-		if ($path == '' OR ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		$result = @ftp_mkdir($this->conn_id, $path);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_makdir');

-			}

-			return FALSE;

-		}

-

-		// Set file permissions if needed

-		if ( ! is_null($permissions))

-		{

-			$this->chmod($path, (int)$permissions);

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Upload a file to the server

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @param	string

-	 * @return	bool

-	 */

-	function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		if ( ! file_exists($locpath))

-		{

-			$this->_error('ftp_no_source_file');

-			return FALSE;

-		}

-

-		// Set the mode if not specified

-		if ($mode == 'auto')

-		{

-			// Get the file extension so we can set the upload type

-			$ext = $this->_getext($locpath);

-			$mode = $this->_settype($ext);

-		}

-

-		$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;

-

-		$result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_upload');

-			}

-			return FALSE;

-		}

-

-		// Set file permissions if needed

-		if ( ! is_null($permissions))

-		{

-			$this->chmod($rempath, (int)$permissions);

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename (or move) a file

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @param	bool

-	 * @return	bool

-	 */

-	function rename($old_file, $new_file, $move = FALSE)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		$result = @ftp_rename($this->conn_id, $old_file, $new_file);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';

-

-				$this->_error($msg);

-			}

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Move a file

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	bool

-	 */

-	function move($old_file, $new_file)

-	{

-		return $this->rename($old_file, $new_file, TRUE);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Rename (or move) a file

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function delete_file($filepath)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		$result = @ftp_delete($this->conn_id, $filepath);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_delete');

-			}

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete a folder and recursively delete everything (including sub-folders)

-	 * containted within it.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function delete_dir($filepath)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		// Add a trailing slash to the file path if needed

-		$filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);

-

-		$list = $this->list_files($filepath);

-

-		if ($list !== FALSE AND count($list) > 0)

-		{

-			foreach ($list as $item)

-			{

-				// If we can't delete the item it's probaly a folder so

-				// we'll recursively call delete_dir()

-				if ( ! @ftp_delete($this->conn_id, $item))

-				{

-					$this->delete_dir($item);

-				}

-			}

-		}

-

-		$result = @ftp_rmdir($this->conn_id, $filepath);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_delete');

-			}

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set file permissions

-	 *

-	 * @access	public

-	 * @param	string 	the file path

-	 * @param	string	the permissions

-	 * @return	bool

-	 */

-	function chmod($path, $perm)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		// Permissions can only be set when running PHP 5

-		if ( ! function_exists('ftp_chmod'))

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_chmod');

-			}

-			return FALSE;

-		}

-

-		$result = @ftp_chmod($this->conn_id, $perm, $path);

-

-		if ($result === FALSE)

-		{

-			if ($this->debug == TRUE)

-			{

-				$this->_error('ftp_unable_to_chmod');

-			}

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * FTP List files in the specified directory

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function list_files($path = '.')

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		return ftp_nlist($this->conn_id, $path);

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Read a directory and recreate it remotely

-	 *

-	 * This function recursively reads a folder and everything it contains (including

-	 * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure

-	 * of the original file path will be recreated on the server.

-	 *

-	 * @access	public

-	 * @param	string	path to source with trailing slash

-	 * @param	string	path to destination - include the base folder with trailing slash

-	 * @return	bool

-	 */

-	function mirror($locpath, $rempath)

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		// Open the local file path

-		if ($fp = @opendir($locpath))

-		{

-			// Attempt to open the remote file path.

-			if ( ! $this->changedir($rempath, TRUE))

-			{

-				// If it doesn't exist we'll attempt to create the direcotory

-				if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))

-				{

-					return FALSE;

-				}

-			}

-

-			// Recursively read the local directory

-			while (FALSE !== ($file = readdir($fp)))

-			{

-				if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')

-				{

-					$this->mirror($locpath.$file."/", $rempath.$file."/");

-				}

-				elseif (substr($file, 0, 1) != ".")

-				{

-					// Get the file extension so we can se the upload type

-					$ext = $this->_getext($file);

-					$mode = $this->_settype($ext);

-

-					$this->upload($locpath.$file, $rempath.$file, $mode);

-				}

-			}

-			return TRUE;

-		}

-

-		return FALSE;

-	}

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Extract the file extension

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _getext($filename)

-	{

-		if (FALSE === strpos($filename, '.'))

-		{

-			return 'txt';

-		}

-

-		$x = explode('.', $filename);

-		return end($x);

-	}

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the upload type

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _settype($ext)

-	{

-		$text_types = array(

-							'txt',

-							'text',

-							'php',

-							'phps',

-							'php4',

-							'js',

-							'css',

-							'htm',

-							'html',

-							'phtml',

-							'shtml',

-							'log',

-							'xml'

-							);

-

-

-		return (in_array($ext, $text_types)) ? 'ascii' : 'binary';

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Close the connection

-	 *

-	 * @access	public

-	 * @param	string	path to source

-	 * @param	string	path to destination

-	 * @return	bool

-	 */

-	function close()

-	{

-		if ( ! $this->_is_conn())

-		{

-			return FALSE;

-		}

-

-		@ftp_close($this->conn_id);

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Display error message

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	bool

-	 */

-	function _error($line)

-	{

-		$CI =& get_instance();

-		$CI->lang->load('ftp');

-		show_error($CI->lang->line($line));

-	}

-

-

-}

-// END FTP Class

-

-/* End of file Ftp.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * FTP Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/ftp.html
+ */
+class CI_FTP {
+
+	var $hostname	= '';
+	var $username	= '';
+	var $password	= '';
+	var $port		= 21;
+	var $passive	= TRUE;
+	var $debug		= FALSE;
+	var $conn_id	= FALSE;
+
+
+	/**
+	 * Constructor - Sets Preferences
+	 *
+	 * The constructor can be passed an array of config values
+	 */
+	function CI_FTP($config = array())
+	{
+		if (count($config) > 0)
+		{
+			$this->initialize($config);
+		}
+
+		log_message('debug', "FTP Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize preferences
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function initialize($config = array())
+	{
+		foreach ($config as $key => $val)
+		{
+			if (isset($this->$key))
+			{
+				$this->$key = $val;
+			}
+		}
+
+		// Prep the hostname
+		$this->hostname = preg_replace('|.+?://|', '', $this->hostname);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * FTP Connect
+	 *
+	 * @access	public
+	 * @param	array	 the connection values
+	 * @return	bool
+	 */
+	function connect($config = array())
+	{
+		if (count($config) > 0)
+		{
+			$this->initialize($config);
+		}
+
+		if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_connect');
+			}
+			return FALSE;
+		}
+
+		if ( ! $this->_login())
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_login');
+			}
+			return FALSE;
+		}
+
+		// Set passive mode if needed
+		if ($this->passive == TRUE)
+		{
+			ftp_pasv($this->conn_id, TRUE);
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * FTP Login
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _login()
+	{
+		return @ftp_login($this->conn_id, $this->username, $this->password);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Validates the connection ID
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _is_conn()
+	{
+		if ( ! is_resource($this->conn_id))
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_no_connection');
+			}
+			return FALSE;
+		}
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+
+	/**
+	 * Change direcotry
+	 *
+	 * The second parameter lets us momentarily turn off debugging so that
+	 * this function can be used to test for the existance of a folder
+	 * without throwing an error.  There's no FTP equivalent to is_dir()
+	 * so we do it by trying to change to a particular directory.
+	 * Internally, this paramter is only used by the "mirror" function below.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	bool
+	 * @return	bool
+	 */
+	function changedir($path = '', $supress_debug = FALSE)
+	{
+		if ($path == '' OR ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		$result = @ftp_chdir($this->conn_id, $path);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE AND $supress_debug == FALSE)
+			{
+				$this->_error('ftp_unable_to_changedir');
+			}
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create a directory
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function mkdir($path = '', $permissions = NULL)
+	{
+		if ($path == '' OR ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		$result = @ftp_mkdir($this->conn_id, $path);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_makdir');
+			}
+			return FALSE;
+		}
+
+		// Set file permissions if needed
+		if ( ! is_null($permissions))
+		{
+			$this->chmod($path, (int)$permissions);
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Upload a file to the server
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @param	string
+	 * @return	bool
+	 */
+	function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		if ( ! file_exists($locpath))
+		{
+			$this->_error('ftp_no_source_file');
+			return FALSE;
+		}
+
+		// Set the mode if not specified
+		if ($mode == 'auto')
+		{
+			// Get the file extension so we can set the upload type
+			$ext = $this->_getext($locpath);
+			$mode = $this->_settype($ext);
+		}
+
+		$mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
+
+		$result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_upload');
+			}
+			return FALSE;
+		}
+
+		// Set file permissions if needed
+		if ( ! is_null($permissions))
+		{
+			$this->chmod($rempath, (int)$permissions);
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename (or move) a file
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @param	bool
+	 * @return	bool
+	 */
+	function rename($old_file, $new_file, $move = FALSE)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		$result = @ftp_rename($this->conn_id, $old_file, $new_file);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';
+
+				$this->_error($msg);
+			}
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Move a file
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	bool
+	 */
+	function move($old_file, $new_file)
+	{
+		return $this->rename($old_file, $new_file, TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rename (or move) a file
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function delete_file($filepath)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		$result = @ftp_delete($this->conn_id, $filepath);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_delete');
+			}
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete a folder and recursively delete everything (including sub-folders)
+	 * containted within it.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function delete_dir($filepath)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		// Add a trailing slash to the file path if needed
+		$filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);
+
+		$list = $this->list_files($filepath);
+
+		if ($list !== FALSE AND count($list) > 0)
+		{
+			foreach ($list as $item)
+			{
+				// If we can't delete the item it's probaly a folder so
+				// we'll recursively call delete_dir()
+				if ( ! @ftp_delete($this->conn_id, $item))
+				{
+					$this->delete_dir($item);
+				}
+			}
+		}
+
+		$result = @ftp_rmdir($this->conn_id, $filepath);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_delete');
+			}
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set file permissions
+	 *
+	 * @access	public
+	 * @param	string 	the file path
+	 * @param	string	the permissions
+	 * @return	bool
+	 */
+	function chmod($path, $perm)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		// Permissions can only be set when running PHP 5
+		if ( ! function_exists('ftp_chmod'))
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_chmod');
+			}
+			return FALSE;
+		}
+
+		$result = @ftp_chmod($this->conn_id, $perm, $path);
+
+		if ($result === FALSE)
+		{
+			if ($this->debug == TRUE)
+			{
+				$this->_error('ftp_unable_to_chmod');
+			}
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * FTP List files in the specified directory
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function list_files($path = '.')
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		return ftp_nlist($this->conn_id, $path);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Read a directory and recreate it remotely
+	 *
+	 * This function recursively reads a folder and everything it contains (including
+	 * sub-folders) and creates a mirror via FTP based on it.  Whatever the directory structure
+	 * of the original file path will be recreated on the server.
+	 *
+	 * @access	public
+	 * @param	string	path to source with trailing slash
+	 * @param	string	path to destination - include the base folder with trailing slash
+	 * @return	bool
+	 */
+	function mirror($locpath, $rempath)
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		// Open the local file path
+		if ($fp = @opendir($locpath))
+		{
+			// Attempt to open the remote file path.
+			if ( ! $this->changedir($rempath, TRUE))
+			{
+				// If it doesn't exist we'll attempt to create the direcotory
+				if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
+				{
+					return FALSE;
+				}
+			}
+
+			// Recursively read the local directory
+			while (FALSE !== ($file = readdir($fp)))
+			{
+				if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
+				{
+					$this->mirror($locpath.$file."/", $rempath.$file."/");
+				}
+				elseif (substr($file, 0, 1) != ".")
+				{
+					// Get the file extension so we can se the upload type
+					$ext = $this->_getext($file);
+					$mode = $this->_settype($ext);
+
+					$this->upload($locpath.$file, $rempath.$file, $mode);
+				}
+			}
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Extract the file extension
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _getext($filename)
+	{
+		if (FALSE === strpos($filename, '.'))
+		{
+			return 'txt';
+		}
+
+		$x = explode('.', $filename);
+		return end($x);
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the upload type
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _settype($ext)
+	{
+		$text_types = array(
+							'txt',
+							'text',
+							'php',
+							'phps',
+							'php4',
+							'js',
+							'css',
+							'htm',
+							'html',
+							'phtml',
+							'shtml',
+							'log',
+							'xml'
+							);
+
+
+		return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Close the connection
+	 *
+	 * @access	public
+	 * @param	string	path to source
+	 * @param	string	path to destination
+	 * @return	bool
+	 */
+	function close()
+	{
+		if ( ! $this->_is_conn())
+		{
+			return FALSE;
+		}
+
+		@ftp_close($this->conn_id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Display error message
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	bool
+	 */
+	function _error($line)
+	{
+		$CI =& get_instance();
+		$CI->lang->load('ftp');
+		show_error($CI->lang->line($line));
+	}
+
+
+}
+// END FTP Class
+
+/* End of file Ftp.php */
 /* Location: ./system/libraries/Ftp.php */
\ No newline at end of file
diff --git a/system/libraries/Hooks.php b/system/libraries/Hooks.php
index 55019e4..46f3ac4 100644
--- a/system/libraries/Hooks.php
+++ b/system/libraries/Hooks.php
@@ -1,226 +1,226 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Hooks Class

- *

- * Provides a mechanism to extend the base system without hacking.  Most of

- * this class is borrowed from Paul's Extension class in ExpressionEngine.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/encryption.html

- */

-class CI_Hooks {

-

-	var $enabled 		= FALSE;

-	var $hooks   		= array();

-	var $in_progress	= FALSE;

-

-	/**

-	 * Constructor

-	 *

-	 */

-	function CI_Hooks()

-	{

-		$this->_initialize();

-		log_message('debug', "Hooks Class Initialized");

-	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize the Hooks Preferences

-	 *

-	 * @access	private

-	 * @return	void

-	 */  

-  	function _initialize()

-  	{

-		$CFG =& load_class('Config');

-

-		// If hooks are not enabled in the config file

-		// there is nothing else to do

-

-		if ($CFG->item('enable_hooks') == FALSE)

-		{

-			return;

-		}

-

-		// Grab the "hooks" definition file.

-		// If there are no hooks, we're done.

-

-		@include(APPPATH.'config/hooks'.EXT);

-

-		if ( ! isset($hook) OR ! is_array($hook))

-		{

-			return;

-		}

-

-		$this->hooks =& $hook;

-		$this->enabled = TRUE;

-  	}

-  

-	// --------------------------------------------------------------------

-

-	/**

-	 * Call Hook

-	 *

-	 * Calls a particular hook

-	 *

-	 * @access	private

-	 * @param	string	the hook name

-	 * @return	mixed

-	 */

-	function _call_hook($which = '')

-	{

-		if ( ! $this->enabled OR ! isset($this->hooks[$which]))

-		{

-			return FALSE;

-		}

-

-		if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))

-		{

-			foreach ($this->hooks[$which] as $val)

-			{

-				$this->_run_hook($val);

-			}

-		}

-		else

-		{

-			$this->_run_hook($this->hooks[$which]);

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Run Hook

-	 *

-	 * Runs a particular hook

-	 *

-	 * @access	private

-	 * @param	array	the hook details

-	 * @return	bool

-	 */

-	function _run_hook($data)

-	{

-		if ( ! is_array($data))

-		{

-			return FALSE;

-		}

-

-		// -----------------------------------

-		// Safety - Prevents run-away loops

-		// -----------------------------------

-

-		// If the script being called happens to have the same

-		// hook call within it a loop can happen

-

-		if ($this->in_progress == TRUE)

-		{

-			return;

-		}

-

-		// -----------------------------------

-		// Set file path

-		// -----------------------------------

-

-		if ( ! isset($data['filepath']) OR ! isset($data['filename']))

-		{

-			return FALSE;

-		}

-

-		$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];

-

-		if ( ! file_exists($filepath))

-		{

-			return FALSE;

-		}

-

-		// -----------------------------------

-		// Set class/function name

-		// -----------------------------------

-

-		$class		= FALSE;

-		$function	= FALSE;

-		$params		= '';

-

-		if (isset($data['class']) AND $data['class'] != '')

-		{

-			$class = $data['class'];

-		}

-

-		if (isset($data['function']))

-		{

-			$function = $data['function'];

-		}

-

-		if (isset($data['params']))

-		{

-			$params = $data['params'];

-		}

-

-		if ($class === FALSE AND $function === FALSE)

-		{

-			return FALSE;

-		}

-

-		// -----------------------------------

-		// Set the in_progress flag

-		// -----------------------------------

-

-		$this->in_progress = TRUE;

-

-		// -----------------------------------

-		// Call the requested class and/or function

-		// -----------------------------------

-

-		if ($class !== FALSE)

-		{

-			if ( ! class_exists($class))

-			{

-				require($filepath);

-			}

-

-			$HOOK = new $class;

-			$HOOK->$function($params);

-		}

-		else

-		{

-			if ( ! function_exists($function))

-			{

-				require($filepath);

-			}

-

-			$function($params);

-		}

-

-		$this->in_progress = FALSE;

-		return TRUE;

-	}

-

-}

-

-// END CI_Hooks class

-

-/* End of file Hooks.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Hooks Class
+ *
+ * Provides a mechanism to extend the base system without hacking.  Most of
+ * this class is borrowed from Paul's Extension class in ExpressionEngine.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/encryption.html
+ */
+class CI_Hooks {
+
+	var $enabled 		= FALSE;
+	var $hooks   		= array();
+	var $in_progress	= FALSE;
+
+	/**
+	 * Constructor
+	 *
+	 */
+	function CI_Hooks()
+	{
+		$this->_initialize();
+		log_message('debug', "Hooks Class Initialized");
+	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize the Hooks Preferences
+	 *
+	 * @access	private
+	 * @return	void
+	 */  
+  	function _initialize()
+  	{
+		$CFG =& load_class('Config');
+
+		// If hooks are not enabled in the config file
+		// there is nothing else to do
+
+		if ($CFG->item('enable_hooks') == FALSE)
+		{
+			return;
+		}
+
+		// Grab the "hooks" definition file.
+		// If there are no hooks, we're done.
+
+		@include(APPPATH.'config/hooks'.EXT);
+
+		if ( ! isset($hook) OR ! is_array($hook))
+		{
+			return;
+		}
+
+		$this->hooks =& $hook;
+		$this->enabled = TRUE;
+  	}
+  
+	// --------------------------------------------------------------------
+
+	/**
+	 * Call Hook
+	 *
+	 * Calls a particular hook
+	 *
+	 * @access	private
+	 * @param	string	the hook name
+	 * @return	mixed
+	 */
+	function _call_hook($which = '')
+	{
+		if ( ! $this->enabled OR ! isset($this->hooks[$which]))
+		{
+			return FALSE;
+		}
+
+		if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
+		{
+			foreach ($this->hooks[$which] as $val)
+			{
+				$this->_run_hook($val);
+			}
+		}
+		else
+		{
+			$this->_run_hook($this->hooks[$which]);
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Run Hook
+	 *
+	 * Runs a particular hook
+	 *
+	 * @access	private
+	 * @param	array	the hook details
+	 * @return	bool
+	 */
+	function _run_hook($data)
+	{
+		if ( ! is_array($data))
+		{
+			return FALSE;
+		}
+
+		// -----------------------------------
+		// Safety - Prevents run-away loops
+		// -----------------------------------
+
+		// If the script being called happens to have the same
+		// hook call within it a loop can happen
+
+		if ($this->in_progress == TRUE)
+		{
+			return;
+		}
+
+		// -----------------------------------
+		// Set file path
+		// -----------------------------------
+
+		if ( ! isset($data['filepath']) OR ! isset($data['filename']))
+		{
+			return FALSE;
+		}
+
+		$filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
+
+		if ( ! file_exists($filepath))
+		{
+			return FALSE;
+		}
+
+		// -----------------------------------
+		// Set class/function name
+		// -----------------------------------
+
+		$class		= FALSE;
+		$function	= FALSE;
+		$params		= '';
+
+		if (isset($data['class']) AND $data['class'] != '')
+		{
+			$class = $data['class'];
+		}
+
+		if (isset($data['function']))
+		{
+			$function = $data['function'];
+		}
+
+		if (isset($data['params']))
+		{
+			$params = $data['params'];
+		}
+
+		if ($class === FALSE AND $function === FALSE)
+		{
+			return FALSE;
+		}
+
+		// -----------------------------------
+		// Set the in_progress flag
+		// -----------------------------------
+
+		$this->in_progress = TRUE;
+
+		// -----------------------------------
+		// Call the requested class and/or function
+		// -----------------------------------
+
+		if ($class !== FALSE)
+		{
+			if ( ! class_exists($class))
+			{
+				require($filepath);
+			}
+
+			$HOOK = new $class;
+			$HOOK->$function($params);
+		}
+		else
+		{
+			if ( ! function_exists($function))
+			{
+				require($filepath);
+			}
+
+			$function($params);
+		}
+
+		$this->in_progress = FALSE;
+		return TRUE;
+	}
+
+}
+
+// END CI_Hooks class
+
+/* End of file Hooks.php */
 /* Location: ./system/libraries/Hooks.php */
\ No newline at end of file
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index f260e76..16201ee 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -1,1548 +1,1548 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Image Manipulation class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Image_lib

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/image_lib.html

- */

-class CI_Image_lib {

-

-	var $image_library		= 'gd2';  	// Can be:  imagemagick, netpbm, gd, gd2

-	var $library_path		= '';

-	var $dynamic_output		= FALSE;	// Whether to send to browser or write to disk

-	var $source_image		= '';

-	var $new_image			= '';

-	var $width				= '';

-	var $height				= '';

-	var $quality			= '90';

-	var $create_thumb		= FALSE;

-	var $thumb_marker		= '_thumb';

-	var $maintain_ratio		= TRUE;  	// Whether to maintain aspect ratio when resizing or use hard values

-	var $master_dim			= 'auto';	// auto, height, or width.  Determines what to use as the master dimension

-	var $rotation_angle		= '';

-	var $x_axis				= '';

-	var	$y_axis				= '';

-

-	// Watermark Vars

-	var $wm_text			= '';			// Watermark text if graphic is not used

-	var $wm_type			= 'text';		// Type of watermarking.  Options:  text/overlay

-	var $wm_x_transp		= 4;

-	var $wm_y_transp		= 4;

-	var $wm_overlay_path	= '';			// Watermark image path

-	var $wm_font_path		= '';			// TT font

-	var $wm_font_size		= 17;			// Font size (different versions of GD will either use points or pixels)

-	var $wm_vrt_alignment	= 'B';			// Vertical alignment:   T M B

-	var $wm_hor_alignment	= 'C';			// Horizontal alignment: L R C

-	var $wm_padding			= 0;			// Padding around text

-	var $wm_hor_offset		= 0;			// Lets you push text to the right

-	var $wm_vrt_offset		= 0;			 // Lets you push  text down

-	var $wm_font_color		= '#ffffff';	// Text color

-	var $wm_shadow_color	= '';			// Dropshadow color

-	var $wm_shadow_distance	= 2;			// Dropshadow distance

-	var $wm_opacity			= 50; 			// Image opacity: 1 - 100  Only works with image

-

-	// Private Vars

-	var $source_folder		= '';

-	var $dest_folder		= '';

-	var $mime_type			= '';

-	var $orig_width			= '';

-	var $orig_height		= '';

-	var $image_type			= '';

-	var $size_str			= '';

-	var $full_src_path		= '';

-	var $full_dst_path		= '';

-	var $create_fnc			= 'imagecreatetruecolor';

-	var $copy_fnc			= 'imagecopyresampled';

-	var $error_msg			= array();

-	var $wm_use_drop_shadow	= FALSE;

-	var $wm_use_truetype	= FALSE;

-

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function CI_Image_lib($props = array())

-	{

-		if (count($props) > 0)

-		{

-			$this->initialize($props);

-		}

-

-		log_message('debug', "Image Lib Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize image properties

-	 *

-	 * Resets values in case this class is used in a loop

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function clear()

-	{

-		$props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity');

-

-		foreach ($props as $val)

-		{

-			$this->$val = '';

-		}

-

-		// special consideration for master_dim

-		$this->master_dim = 'auto';

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * initialize image preferences

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	bool

-	 */

-	function initialize($props = array())

-	{

-		/*

-		 * Convert array elements into class variables

-		 */

-		if (count($props) > 0)

-		{

-			foreach ($props as $key => $val)

-			{

-				$this->$key = $val;

-			}

-		}

-

-		/*

-		 * Is there a source image?

-		 *

-		 * If not, there's no reason to continue

-		 *

-		 */

-		if ($this->source_image == '')

-		{

-			$this->set_error('imglib_source_image_required');

-			return FALSE;	   

-		}

-

-		/*

-		 * Is getimagesize() Available?

-		 *

-		 * We use it to determine the image properties (width/height).

-		 * Note:  We need to figure out how to determine image

-		 * properties using ImageMagick and NetPBM

-		 *

-		 */

-		if ( ! function_exists('getimagesize'))

-		{

-			$this->set_error('imglib_gd_required_for_props');

-			return FALSE;

-		}

-

-		$this->image_library = strtolower($this->image_library);

-

-		/*

-		 * Set the full server path

-		 *

-		 * The source image may or may not contain a path.

-		 * Either way, we'll try use realpath to generate the

-		 * full server path in order to more reliably read it.

-		 *

-		 */

-		if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)

-		{

-			$full_source_path = str_replace("\\", "/", realpath($this->source_image));

-		}

-		else

-		{

-			$full_source_path = $this->source_image;

-		}

-

-		$x = explode('/', $full_source_path);

-		$this->source_image = end($x);

-		$this->source_folder = str_replace($this->source_image, '', $full_source_path);

-

-		// Set the Image Properties

-		if ( ! $this->get_image_properties($this->source_folder.$this->source_image))

-		{

-			return FALSE;	   

-		}

-

-		/*

-		 * Assign the "new" image name/path

-		 *

-		 * If the user has set a "new_image" name it means

-		 * we are making a copy of the source image. If not

-		 * it means we are altering the original.  We'll

-		 * set the destination filename and path accordingly.

-		 *

-		 */

-		if ($this->new_image == '')

-		{

-			$this->dest_image = $this->source_image;

-			$this->dest_folder = $this->source_folder;

-		}

-		else

-		{

-			if (strpos($this->new_image, '/') === FALSE)

-			{

-				$this->dest_folder = $this->source_folder;

-				$this->dest_image = $this->new_image;

-			}

-			else

-			{

-				if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)

-				{

-					$full_dest_path = str_replace("\\", "/", realpath($this->new_image));

-				}

-				else

-				{

-					$full_dest_path = $this->new_image;

-				}

-

-				// Is there a file name?

-				if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))

-				{

-					$this->dest_folder = $full_dest_path.'/';

-					$this->dest_image = $this->source_image;

-				}

-				else

-				{

-					$x = explode('/', $full_dest_path);

-					$this->dest_image = end($x);

-					$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);

-				}

-			}

-		}

-

-		/*

-		 * Compile the finalized filenames/paths

-		 *

-		 * We'll create two master strings containing the

-		 * full server path to the source image and the

-		 * full server path to the destination image.

-		 * We'll also split the destination image name

-		 * so we can insert the thumbnail marker if needed.

-		 *

-		 */

-		if ($this->create_thumb === FALSE OR $this->thumb_marker == '')

-		{

-			$this->thumb_marker = '';

-		}

-

-		$xp	= $this->explode_name($this->dest_image);

-

-		$filename = $xp['name'];

-		$file_ext = $xp['ext'];

-

-		$this->full_src_path = $this->source_folder.$this->source_image;

-		$this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;

-

-		/*

-		 * Should we maintain image proportions?

-		 *

-		 * When creating thumbs or copies, the target width/height

-		 * might not be in correct proportion with the source

-		 * image's width/height.  We'll recalculate it here.

-		 *

-		 */

-		if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))

-		{

-			$this->image_reproportion();

-		}

-

-		/*

-		 * Was a width and height specified?

-		 *

-		 * If the destination width/height was

-		 * not submitted we will use the values

-		 * from the actual file

-		 *

-		 */

-		if ($this->width == '')

-			$this->width = $this->orig_width;

-

-		if ($this->height == '')

-			$this->height = $this->orig_height;

-

-		// Set the quality

-		$this->quality = trim(str_replace("%", "", $this->quality));

-

-		if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))

-			$this->quality = 90;

-

-		// Set the x/y coordinates

-		$this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;

-		$this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;

-

-		// Watermark-related Stuff...

-		if ($this->wm_font_color != '')

-		{

-			if (strlen($this->wm_font_color) == 6)

-			{

-				$this->wm_font_color = '#'.$this->wm_font_color;

-			}

-		}

-

-		if ($this->wm_shadow_color != '')

-		{

-			if (strlen($this->wm_shadow_color) == 6)

-			{

-				$this->wm_shadow_color = '#'.$this->wm_shadow_color;

-			}

-		}

-

-		if ($this->wm_overlay_path != '')

-		{

-			$this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));

-		}

-

-		if ($this->wm_shadow_color != '')

-		{

-			$this->wm_use_drop_shadow = TRUE;

-		}

-

-		if ($this->wm_font_path != '')

-		{

-			$this->wm_use_truetype = TRUE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Resize

-	 *

-	 * This is a wrapper function that chooses the proper

-	 * resize function based on the protocol specified

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function resize()

-	{

-		$protocol = 'image_process_'.$this->image_library;

-

-		if (eregi("gd2$", $protocol))

-		{

-			$protocol = 'image_process_gd';

-		}

-

-		return $this->$protocol('resize');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Crop

-	 *

-	 * This is a wrapper function that chooses the proper

-	 * cropping function based on the protocol specified

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function crop()

-	{

-		$protocol = 'image_process_'.$this->image_library;

-

-		if (eregi("gd2$", $protocol))

-		{

-			$protocol = 'image_process_gd';

-		}

-

-		return $this->$protocol('crop');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Rotate

-	 *

-	 * This is a wrapper function that chooses the proper

-	 * rotation function based on the protocol specified

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function rotate()

-	{

-		// Allowed rotation values

-		$degs = array(90, 180, 270, 'vrt', 'hor');

-

-		if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE))

-		{

-			$this->set_error('imglib_rotation_angle_required');

-			return FALSE;	   

-		}

-

-		// Reassign the width and height

-		if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)

-		{

-			$this->width	= $this->orig_height;

-			$this->height	= $this->orig_width;

-		}

-		else

-		{

-			$this->width	= $this->orig_width;

-			$this->height	= $this->orig_height;

-		}

-

-

-		// Choose resizing function

-		if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')

-		{

-			$protocol = 'image_process_'.$this->image_library;

-

-			return $this->$protocol('rotate');

-		}

-

-		if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')

-		{

-			return $this->image_mirror_gd();

-		}

-		else

-		{

-			return $this->image_rotate_gd();

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Process Using GD/GD2

-	 *

-	 * This function will resize or crop

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function image_process_gd($action = 'resize')

-	{

-		$v2_override = FALSE;

-

-		// If the target width/height match the source, AND if the new file name is not equal to the old file name

-		// we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.

-		if ($this->dynamic_output === FALSE)

-		{

-			if ($this->orig_width == $this->width AND $this->orig_height == $this->height)

-			{

- 				if ($this->source_image != $this->new_image)

- 				{

-					if (@copy($this->full_src_path, $this->full_dst_path))

-					{

-						@chmod($this->full_dst_path, DIR_WRITE_MODE);

-					}

-				}

-

-				return TRUE;

-			}

-		}

-

-		// Let's set up our values based on the action

-		if ($action == 'crop')

-		{

-			//  Reassign the source width/height if cropping

-			$this->orig_width  = $this->width;

-			$this->orig_height = $this->height;

-

-			// GD 2.0 has a cropping bug so we'll test for it

-			if ($this->gd_version() !== FALSE)

-			{

-				$gd_version = str_replace('0', '', $this->gd_version());

-				$v2_override = ($gd_version == 2) ? TRUE : FALSE;

-			}

-		}

-		else

-		{

-			// If resizing the x/y axis must be zero

-			$this->x_axis = 0;

-			$this->y_axis = 0;

-		}

-

-		//  Create the image handle

-		if ( ! ($src_img = $this->image_create_gd()))

-		{

-			return FALSE;

-		}

-

- 		//  Create The Image

-		//

-		//  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"

-		//  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment

-		//  below should that ever prove inaccurate.

-		//

-		//  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)

- 		if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))

-		{

-			$create	= 'imagecreatetruecolor';

-			$copy	= 'imagecopyresampled';

-		}

-		else

-		{

-			$create	= 'imagecreate';

-			$copy	= 'imagecopyresized';

-		}

-

-		$dst_img = $create($this->width, $this->height);

-		$copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);

-

-		//  Show the image

-		if ($this->dynamic_output == TRUE)

-		{

-			$this->image_display_gd($dst_img);

-		}

-		else

-		{

-			// Or save it

-			if ( ! $this->image_save_gd($dst_img))

-			{

-				return FALSE;

-			}

-		}

-

-		//  Kill the file handles

-		imagedestroy($dst_img);

-		imagedestroy($src_img);

-

-		// Set the file to 777

-		@chmod($this->full_dst_path, DIR_WRITE_MODE);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Process Using ImageMagick

-	 *

-	 * This function will resize, crop or rotate

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function image_process_imagemagick($action = 'resize')

-	{

-		//  Do we have a vaild library path?

-		if ($this->library_path == '')

-		{

-			$this->set_error('imglib_libpath_invalid');

-			return FALSE;

-		}

-

-		if ( ! eregi("convert$", $this->library_path))

-		{

-			if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/";

-

-			$this->library_path .= 'convert';

-		}

-

-		// Execute the command

-		$cmd = $this->library_path." -quality ".$this->quality;

-

-		if ($action == 'crop')

-		{

-			$cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";

-		}

-		elseif ($action == 'rotate')

-		{

-			switch ($this->rotation_angle)

-			{

-				case 'hor' 	: $angle = '-flop';

-					break;

-				case 'vrt' 	: $angle = '-flip';

-					break;

-				default		: $angle = '-rotate '.$this->rotation_angle;

-					break;

-			}

-

-			$cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";

-		}

-		else  // Resize

-		{

-			$cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";

-		}

-

-		$retval = 1;

-

-		@exec($cmd, $output, $retval);

-

-		//	Did it work?

-		if ($retval > 0)

-		{

-			$this->set_error('imglib_image_process_failed');

-			return FALSE;

-		}

-

-		// Set the file to 777

-		@chmod($this->full_dst_path, DIR_WRITE_MODE);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Process Using NetPBM

-	 *

-	 * This function will resize, crop or rotate

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function image_process_netpbm($action = 'resize')

-	{

-		if ($this->library_path == '')

-		{

-			$this->set_error('imglib_libpath_invalid');

-			return FALSE;

-		}

-

-		//  Build the resizing command

-		switch ($this->image_type)

-		{

-			case 1 :

-						$cmd_in		= 'giftopnm';

-						$cmd_out	= 'ppmtogif';

-				break;

-			case 2 :

-						$cmd_in		= 'jpegtopnm';

-						$cmd_out	= 'ppmtojpeg';

-				break;

-			case 3 :

-						$cmd_in		= 'pngtopnm';

-						$cmd_out	= 'ppmtopng';

-				break;

-		}

-

-		if ($action == 'crop')

-		{

-			$cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;

-		}

-		elseif ($action == 'rotate')

-		{

-			switch ($this->rotation_angle)

-			{

-				case 90		:	$angle = 'r270';

-					break;

-				case 180	:	$angle = 'r180';

-					break;

-				case 270 	:	$angle = 'r90';

-					break;

-				case 'vrt'	:	$angle = 'tb';

-					break;

-				case 'hor'	:	$angle = 'lr';

-					break;

-			}

-

-			$cmd_inner = 'pnmflip -'.$angle.' ';

-		}

-		else // Resize

-		{

-			$cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;

-		}

-

-		$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';

-

-		$retval = 1;

-

-		@exec($cmd, $output, $retval);

-

-		//  Did it work?

-		if ($retval > 0)

-		{

-			$this->set_error('imglib_image_process_failed');

-			return FALSE;

-		}

-

-		// With NetPBM we have to create a temporary image.

-		// If you try manipulating the original it fails so

-		// we have to rename the temp file.

-		copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);

-		unlink ($this->dest_folder.'netpbm.tmp');

-		@chmod($this->full_dst_path, DIR_WRITE_MODE);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Rotate Using GD

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function image_rotate_gd()

-	{

-		// Is Image Rotation Supported?

-		// this function is only supported as of PHP 4.3

-		if ( ! function_exists('imagerotate'))

-		{

-			$this->set_error('imglib_rotate_unsupported');

-			return FALSE;

-		}

-

-		//  Create the image handle

-		if ( ! ($src_img = $this->image_create_gd()))

-		{

-			return FALSE;

-		}

-

-		// Set the background color

-		// This won't work with transparent PNG files so we are

-		// going to have to figure out how to determine the color

-		// of the alpha channel in a future release.

-

-		$white	= imagecolorallocate($src_img, 255, 255, 255);

-

-		//  Rotate it!

-		$dst_img = imagerotate($src_img, $this->rotation_angle, $white);

-

-		//  Save the Image

-		if ($this->dynamic_output == TRUE)

-		{

-			$this->image_display_gd($dst_img);

-		}

-		else

-		{

-			// Or save it

-			if ( ! $this->image_save_gd($dst_img))

-			{

-				return FALSE;

-			}

-		}

-

-		//  Kill the file handles

-		imagedestroy($dst_img);

-		imagedestroy($src_img);

-

-		// Set the file to 777

-

-		@chmod($this->full_dst_path, DIR_WRITE_MODE);

-

-		return true;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Mirror Image using GD

-	 *

-	 * This function will flip horizontal or vertical

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function image_mirror_gd()

-	{

-		if ( ! $src_img = $this->image_create_gd())

-		{

-			return FALSE;

-		}

-

-		$width  = $this->orig_width;

-		$height = $this->orig_height;

-

-		if ($this->rotation_angle == 'hor')

-		{

-			for ($i = 0; $i < $height; $i++)

-			{

-				$left  = 0;

-				$right = $width-1;

-

-				while ($left < $right)

-				{

-					$cl = imagecolorat($src_img, $left, $i);

-					$cr = imagecolorat($src_img, $right, $i);

-

-					imagesetpixel($src_img, $left, $i, $cr);

-					imagesetpixel($src_img, $right, $i, $cl);

-

-					$left++;

-					$right--;

-				}

-			}

-		}

-		else

-		{

-			for ($i = 0; $i < $width; $i++)

-			{

-				$top = 0;

-				$bot = $height-1;

-

-				while ($top < $bot)

-				{

-					$ct = imagecolorat($src_img, $i, $top);

-					$cb = imagecolorat($src_img, $i, $bot);

-

-					imagesetpixel($src_img, $i, $top, $cb);

-					imagesetpixel($src_img, $i, $bot, $ct);

-

-					$top++;

-					$bot--;

-				}

-			}

-		}

-

-		//  Show the image

-		if ($this->dynamic_output == TRUE)

-		{

-			$this->image_display_gd($src_img);

-		}

-		else

-		{

-			// Or save it

-			if ( ! $this->image_save_gd($src_img))

-			{

-				return FALSE;

-			}

-		}

-

-		//  Kill the file handles

-		imagedestroy($src_img);

-

-		// Set the file to 777

-		@chmod($this->full_dst_path, DIR_WRITE_MODE);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Image Watermark

-	 *

-	 * This is a wrapper function that chooses the type

-	 * of watermarking based on the specified preference.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function watermark()

-	{

-		if ($this->wm_type == 'overlay')

-		{

-			return $this->overlay_watermark();

-		}

-		else

-		{

-			return $this->text_watermark();

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Watermark - Graphic Version

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function overlay_watermark()

-	{

-		if ( ! function_exists('imagecolortransparent'))

-		{

-			$this->set_error('imglib_gd_required');

-			return FALSE;

-		}

-

-		//  Fetch source image properties

-		$this->get_image_properties();

-

-		//  Fetch watermark image properties

-		$props 			= $this->get_image_properties($this->wm_overlay_path, TRUE);

-		$wm_img_type	= $props['image_type'];

-		$wm_width		= $props['width'];

-		$wm_height		= $props['height'];

-

-		//  Create two image resources

-		$wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);

-		$src_img = $this->image_create_gd($this->full_src_path);

-

-		// Reverse the offset if necessary

-		// When the image is positioned at the bottom

-		// we don't want the vertical offset to push it

-		// further down.  We want the reverse, so we'll

-		// invert the offset.  Same with the horizontal

-		// offset when the image is at the right

-

-		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));

-		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));

-

-		if ($this->wm_vrt_alignment == 'B')

-			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;

-

-		if ($this->wm_hor_alignment == 'R')

-			$this->wm_hor_offset = $this->wm_hor_offset * -1;

-

-		//  Set the base x and y axis values

-		$x_axis = $this->wm_hor_offset + $this->wm_padding;

-		$y_axis = $this->wm_vrt_offset + $this->wm_padding;

-

-		//  Set the vertical position

-		switch ($this->wm_vrt_alignment)

-		{

-			case 'T':

-				break;

-			case 'M':	$y_axis += ($this->orig_height / 2) - ($wm_height / 2);

-				break;

-			case 'B':	$y_axis += $this->orig_height - $wm_height;

-				break;

-		}

-

-		//  Set the horizontal position

-		switch ($this->wm_hor_alignment)

-		{

-			case 'L':

-				break;

-			case 'C':	$x_axis += ($this->orig_width / 2) - ($wm_width / 2);

-				break;

-			case 'R':	$x_axis += $this->orig_width - $wm_width;

-				break;

-		}

-

-		//  Build the finalized image

-		if ($wm_img_type == 3 AND function_exists('imagealphablending'))

-		{

-			@imagealphablending($src_img, TRUE);

-		} 

-

-		// Set RGB values for text and shadow

-		$rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);

-		$alpha = ($rgba & 0x7F000000) >> 24;

-

-		// make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency

-		if ($alpha > 0)

-		{

-			// copy the image directly, the image's alpha transparency being the sole determinant of blending

-			imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);

-		}

-		else

-		{

-			// set our RGB value from above to be transparent and merge the images with the specified opacity

-			imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));

-			imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);

-		}

-

-		//  Output the image

-		if ($this->dynamic_output == TRUE)

-		{

-			$this->image_display_gd($src_img);

-		}

-		else

-		{

-			if ( ! $this->image_save_gd($src_img))

-			{

-				return FALSE;

-			}

-		}

-

-		imagedestroy($src_img);

-		imagedestroy($wm_img);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Watermark - Text Version

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function text_watermark()

-	{

-		if ( ! ($src_img = $this->image_create_gd()))

-		{

-			return FALSE;

-		}

-

-		if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path))

-		{

-			$this->set_error('imglib_missing_font');

-			return FALSE;

-		}

-

-		//  Fetch source image properties

-		$this->get_image_properties();

-

-		// Set RGB values for text and shadow

-		$this->wm_font_color	= str_replace('#', '', $this->wm_font_color);

-		$this->wm_shadow_color	= str_replace('#', '', $this->wm_shadow_color);

-

-		$R1 = hexdec(substr($this->wm_font_color, 0, 2));

-		$G1 = hexdec(substr($this->wm_font_color, 2, 2));

-		$B1 = hexdec(substr($this->wm_font_color, 4, 2));

-

-		$R2 = hexdec(substr($this->wm_shadow_color, 0, 2));

-		$G2 = hexdec(substr($this->wm_shadow_color, 2, 2));

-		$B2 = hexdec(substr($this->wm_shadow_color, 4, 2));

-

-		$txt_color	= imagecolorclosest($src_img, $R1, $G1, $B1);

-		$drp_color	= imagecolorclosest($src_img, $R2, $G2, $B2);

-

-		// Reverse the vertical offset

-		// When the image is positioned at the bottom

-		// we don't want the vertical offset to push it

-		// further down.  We want the reverse, so we'll

-		// invert the offset.  Note: The horizontal

-		// offset flips itself automatically

-

-		if ($this->wm_vrt_alignment == 'B')

-			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;

-

-		if ($this->wm_hor_alignment == 'R')

-			$this->wm_hor_offset = $this->wm_hor_offset * -1;

-

-		// Set font width and height

-		// These are calculated differently depending on

-		// whether we are using the true type font or not

-		if ($this->wm_use_truetype == TRUE)

-		{

-			if ($this->wm_font_size == '')

-				$this->wm_font_size = '17';

-

-			$fontwidth  = $this->wm_font_size-($this->wm_font_size/4);

-			$fontheight = $this->wm_font_size;

-			$this->wm_vrt_offset += $this->wm_font_size;

-		}

-		else

-		{

-			$fontwidth  = imagefontwidth($this->wm_font_size);

-			$fontheight = imagefontheight($this->wm_font_size);

-		}

-

-		// Set base X and Y axis values

-		$x_axis = $this->wm_hor_offset + $this->wm_padding;

-		$y_axis = $this->wm_vrt_offset + $this->wm_padding;

-

-		// Set verticle alignment

-		if ($this->wm_use_drop_shadow == FALSE)

-			$this->wm_shadow_distance = 0;

-

-		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));

-		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));

-

-		switch ($this->wm_vrt_alignment)

-		{

-			case	 "T" :

-				break;

-			case "M":	$y_axis += ($this->orig_height/2)+($fontheight/2);

-				break;

-			case "B":	$y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));

-				break;

-		}

-

-		$x_shad = $x_axis + $this->wm_shadow_distance;

-		$y_shad = $y_axis + $this->wm_shadow_distance;

-

-		// Set horizontal alignment

-		switch ($this->wm_hor_alignment)

-		{

-			case "L":

-				break;

-			case "R":

-						if ($this->wm_use_drop_shadow)

-							$x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));

-							$x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));

-				break;

-			case "C":

-						if ($this->wm_use_drop_shadow)

-							$x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);

-							$x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);

-				break;

-		}

-

-		//  Add the text to the source image

-		if ($this->wm_use_truetype)

-		{

-			if ($this->wm_use_drop_shadow)

-				imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);

-				imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);

-		}

-		else

-		{

-			if ($this->wm_use_drop_shadow)

-				imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);

-				imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);

-		}

-

-		//  Output the final image

-		if ($this->dynamic_output == TRUE)

-		{

-			$this->image_display_gd($src_img);

-		}

-		else

-		{

-			$this->image_save_gd($src_img);

-		}

-

-		imagedestroy($src_img);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create Image - GD

-	 *

-	 * This simply creates an image resource handle

-	 * based on the type of image being processed

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	resource

-	 */

-	function image_create_gd($path = '', $image_type = '')

-	{

-		if ($path == '')

-			$path = $this->full_src_path;

-

-		if ($image_type == '')

-			$image_type = $this->image_type;

-

-

-		switch ($image_type)

-		{

-			case	 1 :

-						if ( ! function_exists('imagecreatefromgif'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));

-							return FALSE;

-						}

-

-						return imagecreatefromgif($path);

-				break;

-			case 2 :

-						if ( ! function_exists('imagecreatefromjpeg'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));

-							return FALSE;

-						}

-

-						return imagecreatefromjpeg($path);

-				break;

-			case 3 :

-						if ( ! function_exists('imagecreatefrompng'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));

-							return FALSE;

-						}

-

-						return imagecreatefrompng($path);

-				break;

-

-		}

-

-		$this->set_error(array('imglib_unsupported_imagecreate'));

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write image file to disk - GD

-	 *

-	 * Takes an image resource as input and writes the file

-	 * to the specified destination

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	bool

-	 */

-	function image_save_gd($resource)

-	{

-		switch ($this->image_type)

-		{

-			case 1 :

-						if ( ! function_exists('imagegif'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));

-							return FALSE;

-						}

-

-						@imagegif($resource, $this->full_dst_path);

-				break;

-			case 2	:

-						if ( ! function_exists('imagejpeg'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));

-							return FALSE;

-						}

-

-						if (phpversion() == '4.4.1')

-						{

-							@touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround

-						}

-

-						@imagejpeg($resource, $this->full_dst_path, $this->quality);

-				break;

-			case 3	:

-						if ( ! function_exists('imagepng'))

-						{

-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));

-							return FALSE;

-						}

-

-						@imagepng($resource, $this->full_dst_path);

-				break;

-			default		:

-							$this->set_error(array('imglib_unsupported_imagecreate'));

-							return FALSE;

-				break;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Dynamically outputs an image

-	 *

-	 * @access	public

-	 * @param	resource

-	 * @return	void

-	 */

-	function image_display_gd($resource)

-	{

-		header("Content-Disposition: filename={$this->source_image};");

-		header("Content-Type: {$this->mime_type}");

-		header('Content-Transfer-Encoding: binary');

-		header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');

-

-		switch ($this->image_type)

-		{

-			case 1 		:	imagegif($resource);

-				break;

-			case 2		:	imagejpeg($resource, '', $this->quality);

-				break;

-			case 3		:	imagepng($resource);

-				break;

-			default		:	echo 'Unable to display the image';

-				break;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Re-proportion Image Width/Height

-	 *

-	 * When creating thumbs, the desired width/height

-	 * can end up warping the image due to an incorrect

-	 * ratio between the full-sized image and the thumb.

-	 *

-	 * This function lets us re-proportion the width/height

-	 * if users choose to maintain the aspect ratio when resizing.

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function image_reproportion()

-	{

-		if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)

-			return;

-

-		if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)

-			return;

-

-		$new_width	= ceil($this->orig_width*$this->height/$this->orig_height);

-		$new_height	= ceil($this->width*$this->orig_height/$this->orig_width);

-

-		$ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));

-

-		if ($this->master_dim != 'width' AND $this->master_dim != 'height')

-		{

-			$this->master_dim = ($ratio < 0) ? 'width' : 'height';

-		}

-

-		if (($this->width != $new_width) AND ($this->height != $new_height))

-		{

-			if ($this->master_dim == 'height')

-			{

-				$this->width = $new_width;

-			}

-			else

-			{

-				$this->height = $new_height;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get image properties

-	 *

-	 * A helper function that gets info about the file

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	mixed

-	 */

-	function get_image_properties($path = '', $return = FALSE)

-	{

-		// For now we require GD but we should

-		// find a way to determine this using IM or NetPBM

-

-		if ($path == '')

-			$path = $this->full_src_path;

-

-		if ( ! file_exists($path))

-		{

-			$this->set_error('imglib_invalid_path');

-			return FALSE;

-		}

-

-		$vals = @getimagesize($path);

-

-		$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');

-

-		$mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';

-

-		if ($return == TRUE)

-		{

-			$v['width']			= $vals['0'];

-			$v['height']		= $vals['1'];

-			$v['image_type']	= $vals['2'];

-			$v['size_str']		= $vals['3'];

-			$v['mime_type']		= $mime;

-

-			return $v;

-		}

-

-		$this->orig_width	= $vals['0'];

-		$this->orig_height	= $vals['1'];

-		$this->image_type	= $vals['2'];

-		$this->size_str		= $vals['3'];

-		$this->mime_type	= $mime;

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Size calculator

-	 *

-	 * This function takes a known width x height and

-	 * recalculates it to a new size.  Only one

-	 * new variable needs to be known

-	 *

-	 *	$props = array(

-	 *					'width' 		=> $width,

-	 *					'height' 		=> $height,

-	 *					'new_width'		=> 40,

-	 *					'new_height'	=> ''

-	 *				  );

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	array

-	 */

-	function size_calculator($vals)

-	{

-		if ( ! is_array($vals))

-		{

-			return;

-		}

-

-		$allowed = array('new_width', 'new_height', 'width', 'height');

-

-		foreach ($allowed as $item)

-		{

-			if ( ! isset($vals[$item]) OR $vals[$item] == '')

-				$vals[$item] = 0;

-		}

-

-		if ($vals['width'] == 0 OR $vals['height'] == 0)

-		{

-			return $vals;

-		}

-

-		if ($vals['new_width'] == 0)

-		{

-			$vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);

-		}

-		elseif ($vals['new_height'] == 0)

-		{

-			$vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);

-		}

-

-		return $vals;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Explode source_image

-	 *

-	 * This is a helper function that extracts the extension

-	 * from the source_image.  This function lets us deal with

-	 * source_images with multiple periods, like:  my.cool.jpg

-	 * It returns an associative array with two elements:

-	 * $array['ext']  = '.jpg';

-	 * $array['name'] = 'my.cool';

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	array

-	 */

-	function explode_name($source_image)

-	{

-		$x = explode('.', $source_image);

-		$ret['ext'] = '.'.end($x);

-

-		$name = '';

-

-		$ct = count($x)-1;

-

-		for ($i = 0; $i < $ct; $i++)

-		{

-			$name .= $x[$i];

-

-			if ($i < ($ct - 1))

-			{

-				$name .= '.';

-			}

-		}

-

-		$ret['name'] = $name;

-

-		return $ret;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Is GD Installed?

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function gd_loaded()

-	{

-		if ( ! extension_loaded('gd'))

-		{

-			if ( ! dl('gd.so'))

-			{

-				return FALSE;

-			}

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get GD version

-	 *

-	 * @access	public

-	 * @return	mixed

-	 */

-	function gd_version()

-	{

-		if (function_exists('gd_info'))

-		{

-			$gd_version = @gd_info();

-			$gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);

-

-			return $gd_version;

-		}

-

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_error($msg)

-	{

-		$CI =& get_instance();

-		$CI->lang->load('imglib');

-

-		if (is_array($msg))

-		{

-			foreach ($msg as $val)

-			{

-

-				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);

-				$this->error_msg[] = $msg;

-				log_message('error', $msg);

-			}

-		}

-		else

-		{

-			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);

-			$this->error_msg[] = $msg;

-			log_message('error', $msg);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Show error messages

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function display_errors($open = '<p>', $close = '</p>')

-	{

-		$str = '';

-		foreach ($this->error_msg as $val)

-		{

-			$str .= $open.$val.$close;

-		}

-

-		return $str;

-	}

-

-}

-// END Image_lib Class

-

-/* End of file Image_lib.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Image Manipulation class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Image_lib
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/image_lib.html
+ */
+class CI_Image_lib {
+
+	var $image_library		= 'gd2';  	// Can be:  imagemagick, netpbm, gd, gd2
+	var $library_path		= '';
+	var $dynamic_output		= FALSE;	// Whether to send to browser or write to disk
+	var $source_image		= '';
+	var $new_image			= '';
+	var $width				= '';
+	var $height				= '';
+	var $quality			= '90';
+	var $create_thumb		= FALSE;
+	var $thumb_marker		= '_thumb';
+	var $maintain_ratio		= TRUE;  	// Whether to maintain aspect ratio when resizing or use hard values
+	var $master_dim			= 'auto';	// auto, height, or width.  Determines what to use as the master dimension
+	var $rotation_angle		= '';
+	var $x_axis				= '';
+	var	$y_axis				= '';
+
+	// Watermark Vars
+	var $wm_text			= '';			// Watermark text if graphic is not used
+	var $wm_type			= 'text';		// Type of watermarking.  Options:  text/overlay
+	var $wm_x_transp		= 4;
+	var $wm_y_transp		= 4;
+	var $wm_overlay_path	= '';			// Watermark image path
+	var $wm_font_path		= '';			// TT font
+	var $wm_font_size		= 17;			// Font size (different versions of GD will either use points or pixels)
+	var $wm_vrt_alignment	= 'B';			// Vertical alignment:   T M B
+	var $wm_hor_alignment	= 'C';			// Horizontal alignment: L R C
+	var $wm_padding			= 0;			// Padding around text
+	var $wm_hor_offset		= 0;			// Lets you push text to the right
+	var $wm_vrt_offset		= 0;			 // Lets you push  text down
+	var $wm_font_color		= '#ffffff';	// Text color
+	var $wm_shadow_color	= '';			// Dropshadow color
+	var $wm_shadow_distance	= 2;			// Dropshadow distance
+	var $wm_opacity			= 50; 			// Image opacity: 1 - 100  Only works with image
+
+	// Private Vars
+	var $source_folder		= '';
+	var $dest_folder		= '';
+	var $mime_type			= '';
+	var $orig_width			= '';
+	var $orig_height		= '';
+	var $image_type			= '';
+	var $size_str			= '';
+	var $full_src_path		= '';
+	var $full_dst_path		= '';
+	var $create_fnc			= 'imagecreatetruecolor';
+	var $copy_fnc			= 'imagecopyresampled';
+	var $error_msg			= array();
+	var $wm_use_drop_shadow	= FALSE;
+	var $wm_use_truetype	= FALSE;
+
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function CI_Image_lib($props = array())
+	{
+		if (count($props) > 0)
+		{
+			$this->initialize($props);
+		}
+
+		log_message('debug', "Image Lib Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize image properties
+	 *
+	 * Resets values in case this class is used in a loop
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function clear()
+	{
+		$props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity');
+
+		foreach ($props as $val)
+		{
+			$this->$val = '';
+		}
+
+		// special consideration for master_dim
+		$this->master_dim = 'auto';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * initialize image preferences
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	bool
+	 */
+	function initialize($props = array())
+	{
+		/*
+		 * Convert array elements into class variables
+		 */
+		if (count($props) > 0)
+		{
+			foreach ($props as $key => $val)
+			{
+				$this->$key = $val;
+			}
+		}
+
+		/*
+		 * Is there a source image?
+		 *
+		 * If not, there's no reason to continue
+		 *
+		 */
+		if ($this->source_image == '')
+		{
+			$this->set_error('imglib_source_image_required');
+			return FALSE;	   
+		}
+
+		/*
+		 * Is getimagesize() Available?
+		 *
+		 * We use it to determine the image properties (width/height).
+		 * Note:  We need to figure out how to determine image
+		 * properties using ImageMagick and NetPBM
+		 *
+		 */
+		if ( ! function_exists('getimagesize'))
+		{
+			$this->set_error('imglib_gd_required_for_props');
+			return FALSE;
+		}
+
+		$this->image_library = strtolower($this->image_library);
+
+		/*
+		 * Set the full server path
+		 *
+		 * The source image may or may not contain a path.
+		 * Either way, we'll try use realpath to generate the
+		 * full server path in order to more reliably read it.
+		 *
+		 */
+		if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)
+		{
+			$full_source_path = str_replace("\\", "/", realpath($this->source_image));
+		}
+		else
+		{
+			$full_source_path = $this->source_image;
+		}
+
+		$x = explode('/', $full_source_path);
+		$this->source_image = end($x);
+		$this->source_folder = str_replace($this->source_image, '', $full_source_path);
+
+		// Set the Image Properties
+		if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
+		{
+			return FALSE;	   
+		}
+
+		/*
+		 * Assign the "new" image name/path
+		 *
+		 * If the user has set a "new_image" name it means
+		 * we are making a copy of the source image. If not
+		 * it means we are altering the original.  We'll
+		 * set the destination filename and path accordingly.
+		 *
+		 */
+		if ($this->new_image == '')
+		{
+			$this->dest_image = $this->source_image;
+			$this->dest_folder = $this->source_folder;
+		}
+		else
+		{
+			if (strpos($this->new_image, '/') === FALSE)
+			{
+				$this->dest_folder = $this->source_folder;
+				$this->dest_image = $this->new_image;
+			}
+			else
+			{
+				if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)
+				{
+					$full_dest_path = str_replace("\\", "/", realpath($this->new_image));
+				}
+				else
+				{
+					$full_dest_path = $this->new_image;
+				}
+
+				// Is there a file name?
+				if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))
+				{
+					$this->dest_folder = $full_dest_path.'/';
+					$this->dest_image = $this->source_image;
+				}
+				else
+				{
+					$x = explode('/', $full_dest_path);
+					$this->dest_image = end($x);
+					$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
+				}
+			}
+		}
+
+		/*
+		 * Compile the finalized filenames/paths
+		 *
+		 * We'll create two master strings containing the
+		 * full server path to the source image and the
+		 * full server path to the destination image.
+		 * We'll also split the destination image name
+		 * so we can insert the thumbnail marker if needed.
+		 *
+		 */
+		if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
+		{
+			$this->thumb_marker = '';
+		}
+
+		$xp	= $this->explode_name($this->dest_image);
+
+		$filename = $xp['name'];
+		$file_ext = $xp['ext'];
+
+		$this->full_src_path = $this->source_folder.$this->source_image;
+		$this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
+
+		/*
+		 * Should we maintain image proportions?
+		 *
+		 * When creating thumbs or copies, the target width/height
+		 * might not be in correct proportion with the source
+		 * image's width/height.  We'll recalculate it here.
+		 *
+		 */
+		if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))
+		{
+			$this->image_reproportion();
+		}
+
+		/*
+		 * Was a width and height specified?
+		 *
+		 * If the destination width/height was
+		 * not submitted we will use the values
+		 * from the actual file
+		 *
+		 */
+		if ($this->width == '')
+			$this->width = $this->orig_width;
+
+		if ($this->height == '')
+			$this->height = $this->orig_height;
+
+		// Set the quality
+		$this->quality = trim(str_replace("%", "", $this->quality));
+
+		if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))
+			$this->quality = 90;
+
+		// Set the x/y coordinates
+		$this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;
+		$this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;
+
+		// Watermark-related Stuff...
+		if ($this->wm_font_color != '')
+		{
+			if (strlen($this->wm_font_color) == 6)
+			{
+				$this->wm_font_color = '#'.$this->wm_font_color;
+			}
+		}
+
+		if ($this->wm_shadow_color != '')
+		{
+			if (strlen($this->wm_shadow_color) == 6)
+			{
+				$this->wm_shadow_color = '#'.$this->wm_shadow_color;
+			}
+		}
+
+		if ($this->wm_overlay_path != '')
+		{
+			$this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));
+		}
+
+		if ($this->wm_shadow_color != '')
+		{
+			$this->wm_use_drop_shadow = TRUE;
+		}
+
+		if ($this->wm_font_path != '')
+		{
+			$this->wm_use_truetype = TRUE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Resize
+	 *
+	 * This is a wrapper function that chooses the proper
+	 * resize function based on the protocol specified
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function resize()
+	{
+		$protocol = 'image_process_'.$this->image_library;
+
+		if (eregi("gd2$", $protocol))
+		{
+			$protocol = 'image_process_gd';
+		}
+
+		return $this->$protocol('resize');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Crop
+	 *
+	 * This is a wrapper function that chooses the proper
+	 * cropping function based on the protocol specified
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function crop()
+	{
+		$protocol = 'image_process_'.$this->image_library;
+
+		if (eregi("gd2$", $protocol))
+		{
+			$protocol = 'image_process_gd';
+		}
+
+		return $this->$protocol('crop');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Rotate
+	 *
+	 * This is a wrapper function that chooses the proper
+	 * rotation function based on the protocol specified
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function rotate()
+	{
+		// Allowed rotation values
+		$degs = array(90, 180, 270, 'vrt', 'hor');
+
+		if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs, TRUE))
+		{
+			$this->set_error('imglib_rotation_angle_required');
+			return FALSE;	   
+		}
+
+		// Reassign the width and height
+		if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
+		{
+			$this->width	= $this->orig_height;
+			$this->height	= $this->orig_width;
+		}
+		else
+		{
+			$this->width	= $this->orig_width;
+			$this->height	= $this->orig_height;
+		}
+
+
+		// Choose resizing function
+		if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')
+		{
+			$protocol = 'image_process_'.$this->image_library;
+
+			return $this->$protocol('rotate');
+		}
+
+		if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')
+		{
+			return $this->image_mirror_gd();
+		}
+		else
+		{
+			return $this->image_rotate_gd();
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Process Using GD/GD2
+	 *
+	 * This function will resize or crop
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function image_process_gd($action = 'resize')
+	{
+		$v2_override = FALSE;
+
+		// If the target width/height match the source, AND if the new file name is not equal to the old file name
+		// we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
+		if ($this->dynamic_output === FALSE)
+		{
+			if ($this->orig_width == $this->width AND $this->orig_height == $this->height)
+			{
+ 				if ($this->source_image != $this->new_image)
+ 				{
+					if (@copy($this->full_src_path, $this->full_dst_path))
+					{
+						@chmod($this->full_dst_path, DIR_WRITE_MODE);
+					}
+				}
+
+				return TRUE;
+			}
+		}
+
+		// Let's set up our values based on the action
+		if ($action == 'crop')
+		{
+			//  Reassign the source width/height if cropping
+			$this->orig_width  = $this->width;
+			$this->orig_height = $this->height;
+
+			// GD 2.0 has a cropping bug so we'll test for it
+			if ($this->gd_version() !== FALSE)
+			{
+				$gd_version = str_replace('0', '', $this->gd_version());
+				$v2_override = ($gd_version == 2) ? TRUE : FALSE;
+			}
+		}
+		else
+		{
+			// If resizing the x/y axis must be zero
+			$this->x_axis = 0;
+			$this->y_axis = 0;
+		}
+
+		//  Create the image handle
+		if ( ! ($src_img = $this->image_create_gd()))
+		{
+			return FALSE;
+		}
+
+ 		//  Create The Image
+		//
+		//  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
+		//  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
+		//  below should that ever prove inaccurate.
+		//
+		//  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
+ 		if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
+		{
+			$create	= 'imagecreatetruecolor';
+			$copy	= 'imagecopyresampled';
+		}
+		else
+		{
+			$create	= 'imagecreate';
+			$copy	= 'imagecopyresized';
+		}
+
+		$dst_img = $create($this->width, $this->height);
+		$copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
+
+		//  Show the image
+		if ($this->dynamic_output == TRUE)
+		{
+			$this->image_display_gd($dst_img);
+		}
+		else
+		{
+			// Or save it
+			if ( ! $this->image_save_gd($dst_img))
+			{
+				return FALSE;
+			}
+		}
+
+		//  Kill the file handles
+		imagedestroy($dst_img);
+		imagedestroy($src_img);
+
+		// Set the file to 777
+		@chmod($this->full_dst_path, DIR_WRITE_MODE);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Process Using ImageMagick
+	 *
+	 * This function will resize, crop or rotate
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function image_process_imagemagick($action = 'resize')
+	{
+		//  Do we have a vaild library path?
+		if ($this->library_path == '')
+		{
+			$this->set_error('imglib_libpath_invalid');
+			return FALSE;
+		}
+
+		if ( ! eregi("convert$", $this->library_path))
+		{
+			if ( ! eregi("/$", $this->library_path)) $this->library_path .= "/";
+
+			$this->library_path .= 'convert';
+		}
+
+		// Execute the command
+		$cmd = $this->library_path." -quality ".$this->quality;
+
+		if ($action == 'crop')
+		{
+			$cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
+		}
+		elseif ($action == 'rotate')
+		{
+			switch ($this->rotation_angle)
+			{
+				case 'hor' 	: $angle = '-flop';
+					break;
+				case 'vrt' 	: $angle = '-flip';
+					break;
+				default		: $angle = '-rotate '.$this->rotation_angle;
+					break;
+			}
+
+			$cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
+		}
+		else  // Resize
+		{
+			$cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
+		}
+
+		$retval = 1;
+
+		@exec($cmd, $output, $retval);
+
+		//	Did it work?
+		if ($retval > 0)
+		{
+			$this->set_error('imglib_image_process_failed');
+			return FALSE;
+		}
+
+		// Set the file to 777
+		@chmod($this->full_dst_path, DIR_WRITE_MODE);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Process Using NetPBM
+	 *
+	 * This function will resize, crop or rotate
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function image_process_netpbm($action = 'resize')
+	{
+		if ($this->library_path == '')
+		{
+			$this->set_error('imglib_libpath_invalid');
+			return FALSE;
+		}
+
+		//  Build the resizing command
+		switch ($this->image_type)
+		{
+			case 1 :
+						$cmd_in		= 'giftopnm';
+						$cmd_out	= 'ppmtogif';
+				break;
+			case 2 :
+						$cmd_in		= 'jpegtopnm';
+						$cmd_out	= 'ppmtojpeg';
+				break;
+			case 3 :
+						$cmd_in		= 'pngtopnm';
+						$cmd_out	= 'ppmtopng';
+				break;
+		}
+
+		if ($action == 'crop')
+		{
+			$cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
+		}
+		elseif ($action == 'rotate')
+		{
+			switch ($this->rotation_angle)
+			{
+				case 90		:	$angle = 'r270';
+					break;
+				case 180	:	$angle = 'r180';
+					break;
+				case 270 	:	$angle = 'r90';
+					break;
+				case 'vrt'	:	$angle = 'tb';
+					break;
+				case 'hor'	:	$angle = 'lr';
+					break;
+			}
+
+			$cmd_inner = 'pnmflip -'.$angle.' ';
+		}
+		else // Resize
+		{
+			$cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
+		}
+
+		$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
+
+		$retval = 1;
+
+		@exec($cmd, $output, $retval);
+
+		//  Did it work?
+		if ($retval > 0)
+		{
+			$this->set_error('imglib_image_process_failed');
+			return FALSE;
+		}
+
+		// With NetPBM we have to create a temporary image.
+		// If you try manipulating the original it fails so
+		// we have to rename the temp file.
+		copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
+		unlink ($this->dest_folder.'netpbm.tmp');
+		@chmod($this->full_dst_path, DIR_WRITE_MODE);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Rotate Using GD
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function image_rotate_gd()
+	{
+		// Is Image Rotation Supported?
+		// this function is only supported as of PHP 4.3
+		if ( ! function_exists('imagerotate'))
+		{
+			$this->set_error('imglib_rotate_unsupported');
+			return FALSE;
+		}
+
+		//  Create the image handle
+		if ( ! ($src_img = $this->image_create_gd()))
+		{
+			return FALSE;
+		}
+
+		// Set the background color
+		// This won't work with transparent PNG files so we are
+		// going to have to figure out how to determine the color
+		// of the alpha channel in a future release.
+
+		$white	= imagecolorallocate($src_img, 255, 255, 255);
+
+		//  Rotate it!
+		$dst_img = imagerotate($src_img, $this->rotation_angle, $white);
+
+		//  Save the Image
+		if ($this->dynamic_output == TRUE)
+		{
+			$this->image_display_gd($dst_img);
+		}
+		else
+		{
+			// Or save it
+			if ( ! $this->image_save_gd($dst_img))
+			{
+				return FALSE;
+			}
+		}
+
+		//  Kill the file handles
+		imagedestroy($dst_img);
+		imagedestroy($src_img);
+
+		// Set the file to 777
+
+		@chmod($this->full_dst_path, DIR_WRITE_MODE);
+
+		return true;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Mirror Image using GD
+	 *
+	 * This function will flip horizontal or vertical
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function image_mirror_gd()
+	{
+		if ( ! $src_img = $this->image_create_gd())
+		{
+			return FALSE;
+		}
+
+		$width  = $this->orig_width;
+		$height = $this->orig_height;
+
+		if ($this->rotation_angle == 'hor')
+		{
+			for ($i = 0; $i < $height; $i++)
+			{
+				$left  = 0;
+				$right = $width-1;
+
+				while ($left < $right)
+				{
+					$cl = imagecolorat($src_img, $left, $i);
+					$cr = imagecolorat($src_img, $right, $i);
+
+					imagesetpixel($src_img, $left, $i, $cr);
+					imagesetpixel($src_img, $right, $i, $cl);
+
+					$left++;
+					$right--;
+				}
+			}
+		}
+		else
+		{
+			for ($i = 0; $i < $width; $i++)
+			{
+				$top = 0;
+				$bot = $height-1;
+
+				while ($top < $bot)
+				{
+					$ct = imagecolorat($src_img, $i, $top);
+					$cb = imagecolorat($src_img, $i, $bot);
+
+					imagesetpixel($src_img, $i, $top, $cb);
+					imagesetpixel($src_img, $i, $bot, $ct);
+
+					$top++;
+					$bot--;
+				}
+			}
+		}
+
+		//  Show the image
+		if ($this->dynamic_output == TRUE)
+		{
+			$this->image_display_gd($src_img);
+		}
+		else
+		{
+			// Or save it
+			if ( ! $this->image_save_gd($src_img))
+			{
+				return FALSE;
+			}
+		}
+
+		//  Kill the file handles
+		imagedestroy($src_img);
+
+		// Set the file to 777
+		@chmod($this->full_dst_path, DIR_WRITE_MODE);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Image Watermark
+	 *
+	 * This is a wrapper function that chooses the type
+	 * of watermarking based on the specified preference.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function watermark()
+	{
+		if ($this->wm_type == 'overlay')
+		{
+			return $this->overlay_watermark();
+		}
+		else
+		{
+			return $this->text_watermark();
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Watermark - Graphic Version
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function overlay_watermark()
+	{
+		if ( ! function_exists('imagecolortransparent'))
+		{
+			$this->set_error('imglib_gd_required');
+			return FALSE;
+		}
+
+		//  Fetch source image properties
+		$this->get_image_properties();
+
+		//  Fetch watermark image properties
+		$props 			= $this->get_image_properties($this->wm_overlay_path, TRUE);
+		$wm_img_type	= $props['image_type'];
+		$wm_width		= $props['width'];
+		$wm_height		= $props['height'];
+
+		//  Create two image resources
+		$wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
+		$src_img = $this->image_create_gd($this->full_src_path);
+
+		// Reverse the offset if necessary
+		// When the image is positioned at the bottom
+		// we don't want the vertical offset to push it
+		// further down.  We want the reverse, so we'll
+		// invert the offset.  Same with the horizontal
+		// offset when the image is at the right
+
+		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
+		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
+
+		if ($this->wm_vrt_alignment == 'B')
+			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
+
+		if ($this->wm_hor_alignment == 'R')
+			$this->wm_hor_offset = $this->wm_hor_offset * -1;
+
+		//  Set the base x and y axis values
+		$x_axis = $this->wm_hor_offset + $this->wm_padding;
+		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
+
+		//  Set the vertical position
+		switch ($this->wm_vrt_alignment)
+		{
+			case 'T':
+				break;
+			case 'M':	$y_axis += ($this->orig_height / 2) - ($wm_height / 2);
+				break;
+			case 'B':	$y_axis += $this->orig_height - $wm_height;
+				break;
+		}
+
+		//  Set the horizontal position
+		switch ($this->wm_hor_alignment)
+		{
+			case 'L':
+				break;
+			case 'C':	$x_axis += ($this->orig_width / 2) - ($wm_width / 2);
+				break;
+			case 'R':	$x_axis += $this->orig_width - $wm_width;
+				break;
+		}
+
+		//  Build the finalized image
+		if ($wm_img_type == 3 AND function_exists('imagealphablending'))
+		{
+			@imagealphablending($src_img, TRUE);
+		} 
+
+		// Set RGB values for text and shadow
+		$rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
+		$alpha = ($rgba & 0x7F000000) >> 24;
+
+		// make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
+		if ($alpha > 0)
+		{
+			// copy the image directly, the image's alpha transparency being the sole determinant of blending
+			imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
+		}
+		else
+		{
+			// set our RGB value from above to be transparent and merge the images with the specified opacity
+			imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
+			imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
+		}
+
+		//  Output the image
+		if ($this->dynamic_output == TRUE)
+		{
+			$this->image_display_gd($src_img);
+		}
+		else
+		{
+			if ( ! $this->image_save_gd($src_img))
+			{
+				return FALSE;
+			}
+		}
+
+		imagedestroy($src_img);
+		imagedestroy($wm_img);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Watermark - Text Version
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function text_watermark()
+	{
+		if ( ! ($src_img = $this->image_create_gd()))
+		{
+			return FALSE;
+		}
+
+		if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path))
+		{
+			$this->set_error('imglib_missing_font');
+			return FALSE;
+		}
+
+		//  Fetch source image properties
+		$this->get_image_properties();
+
+		// Set RGB values for text and shadow
+		$this->wm_font_color	= str_replace('#', '', $this->wm_font_color);
+		$this->wm_shadow_color	= str_replace('#', '', $this->wm_shadow_color);
+
+		$R1 = hexdec(substr($this->wm_font_color, 0, 2));
+		$G1 = hexdec(substr($this->wm_font_color, 2, 2));
+		$B1 = hexdec(substr($this->wm_font_color, 4, 2));
+
+		$R2 = hexdec(substr($this->wm_shadow_color, 0, 2));
+		$G2 = hexdec(substr($this->wm_shadow_color, 2, 2));
+		$B2 = hexdec(substr($this->wm_shadow_color, 4, 2));
+
+		$txt_color	= imagecolorclosest($src_img, $R1, $G1, $B1);
+		$drp_color	= imagecolorclosest($src_img, $R2, $G2, $B2);
+
+		// Reverse the vertical offset
+		// When the image is positioned at the bottom
+		// we don't want the vertical offset to push it
+		// further down.  We want the reverse, so we'll
+		// invert the offset.  Note: The horizontal
+		// offset flips itself automatically
+
+		if ($this->wm_vrt_alignment == 'B')
+			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
+
+		if ($this->wm_hor_alignment == 'R')
+			$this->wm_hor_offset = $this->wm_hor_offset * -1;
+
+		// Set font width and height
+		// These are calculated differently depending on
+		// whether we are using the true type font or not
+		if ($this->wm_use_truetype == TRUE)
+		{
+			if ($this->wm_font_size == '')
+				$this->wm_font_size = '17';
+
+			$fontwidth  = $this->wm_font_size-($this->wm_font_size/4);
+			$fontheight = $this->wm_font_size;
+			$this->wm_vrt_offset += $this->wm_font_size;
+		}
+		else
+		{
+			$fontwidth  = imagefontwidth($this->wm_font_size);
+			$fontheight = imagefontheight($this->wm_font_size);
+		}
+
+		// Set base X and Y axis values
+		$x_axis = $this->wm_hor_offset + $this->wm_padding;
+		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
+
+		// Set verticle alignment
+		if ($this->wm_use_drop_shadow == FALSE)
+			$this->wm_shadow_distance = 0;
+
+		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
+		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
+
+		switch ($this->wm_vrt_alignment)
+		{
+			case	 "T" :
+				break;
+			case "M":	$y_axis += ($this->orig_height/2)+($fontheight/2);
+				break;
+			case "B":	$y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));
+				break;
+		}
+
+		$x_shad = $x_axis + $this->wm_shadow_distance;
+		$y_shad = $y_axis + $this->wm_shadow_distance;
+
+		// Set horizontal alignment
+		switch ($this->wm_hor_alignment)
+		{
+			case "L":
+				break;
+			case "R":
+						if ($this->wm_use_drop_shadow)
+							$x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));
+							$x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));
+				break;
+			case "C":
+						if ($this->wm_use_drop_shadow)
+							$x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);
+							$x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);
+				break;
+		}
+
+		//  Add the text to the source image
+		if ($this->wm_use_truetype)
+		{
+			if ($this->wm_use_drop_shadow)
+				imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
+				imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
+		}
+		else
+		{
+			if ($this->wm_use_drop_shadow)
+				imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
+				imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
+		}
+
+		//  Output the final image
+		if ($this->dynamic_output == TRUE)
+		{
+			$this->image_display_gd($src_img);
+		}
+		else
+		{
+			$this->image_save_gd($src_img);
+		}
+
+		imagedestroy($src_img);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Image - GD
+	 *
+	 * This simply creates an image resource handle
+	 * based on the type of image being processed
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	resource
+	 */
+	function image_create_gd($path = '', $image_type = '')
+	{
+		if ($path == '')
+			$path = $this->full_src_path;
+
+		if ($image_type == '')
+			$image_type = $this->image_type;
+
+
+		switch ($image_type)
+		{
+			case	 1 :
+						if ( ! function_exists('imagecreatefromgif'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
+							return FALSE;
+						}
+
+						return imagecreatefromgif($path);
+				break;
+			case 2 :
+						if ( ! function_exists('imagecreatefromjpeg'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
+							return FALSE;
+						}
+
+						return imagecreatefromjpeg($path);
+				break;
+			case 3 :
+						if ( ! function_exists('imagecreatefrompng'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
+							return FALSE;
+						}
+
+						return imagecreatefrompng($path);
+				break;
+
+		}
+
+		$this->set_error(array('imglib_unsupported_imagecreate'));
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write image file to disk - GD
+	 *
+	 * Takes an image resource as input and writes the file
+	 * to the specified destination
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	bool
+	 */
+	function image_save_gd($resource)
+	{
+		switch ($this->image_type)
+		{
+			case 1 :
+						if ( ! function_exists('imagegif'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
+							return FALSE;
+						}
+
+						@imagegif($resource, $this->full_dst_path);
+				break;
+			case 2	:
+						if ( ! function_exists('imagejpeg'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
+							return FALSE;
+						}
+
+						if (phpversion() == '4.4.1')
+						{
+							@touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround
+						}
+
+						@imagejpeg($resource, $this->full_dst_path, $this->quality);
+				break;
+			case 3	:
+						if ( ! function_exists('imagepng'))
+						{
+							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
+							return FALSE;
+						}
+
+						@imagepng($resource, $this->full_dst_path);
+				break;
+			default		:
+							$this->set_error(array('imglib_unsupported_imagecreate'));
+							return FALSE;
+				break;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Dynamically outputs an image
+	 *
+	 * @access	public
+	 * @param	resource
+	 * @return	void
+	 */
+	function image_display_gd($resource)
+	{
+		header("Content-Disposition: filename={$this->source_image};");
+		header("Content-Type: {$this->mime_type}");
+		header('Content-Transfer-Encoding: binary');
+		header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+
+		switch ($this->image_type)
+		{
+			case 1 		:	imagegif($resource);
+				break;
+			case 2		:	imagejpeg($resource, '', $this->quality);
+				break;
+			case 3		:	imagepng($resource);
+				break;
+			default		:	echo 'Unable to display the image';
+				break;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Re-proportion Image Width/Height
+	 *
+	 * When creating thumbs, the desired width/height
+	 * can end up warping the image due to an incorrect
+	 * ratio between the full-sized image and the thumb.
+	 *
+	 * This function lets us re-proportion the width/height
+	 * if users choose to maintain the aspect ratio when resizing.
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function image_reproportion()
+	{
+		if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)
+			return;
+
+		if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)
+			return;
+
+		$new_width	= ceil($this->orig_width*$this->height/$this->orig_height);
+		$new_height	= ceil($this->width*$this->orig_height/$this->orig_width);
+
+		$ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));
+
+		if ($this->master_dim != 'width' AND $this->master_dim != 'height')
+		{
+			$this->master_dim = ($ratio < 0) ? 'width' : 'height';
+		}
+
+		if (($this->width != $new_width) AND ($this->height != $new_height))
+		{
+			if ($this->master_dim == 'height')
+			{
+				$this->width = $new_width;
+			}
+			else
+			{
+				$this->height = $new_height;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get image properties
+	 *
+	 * A helper function that gets info about the file
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	mixed
+	 */
+	function get_image_properties($path = '', $return = FALSE)
+	{
+		// For now we require GD but we should
+		// find a way to determine this using IM or NetPBM
+
+		if ($path == '')
+			$path = $this->full_src_path;
+
+		if ( ! file_exists($path))
+		{
+			$this->set_error('imglib_invalid_path');
+			return FALSE;
+		}
+
+		$vals = @getimagesize($path);
+
+		$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
+
+		$mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';
+
+		if ($return == TRUE)
+		{
+			$v['width']			= $vals['0'];
+			$v['height']		= $vals['1'];
+			$v['image_type']	= $vals['2'];
+			$v['size_str']		= $vals['3'];
+			$v['mime_type']		= $mime;
+
+			return $v;
+		}
+
+		$this->orig_width	= $vals['0'];
+		$this->orig_height	= $vals['1'];
+		$this->image_type	= $vals['2'];
+		$this->size_str		= $vals['3'];
+		$this->mime_type	= $mime;
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Size calculator
+	 *
+	 * This function takes a known width x height and
+	 * recalculates it to a new size.  Only one
+	 * new variable needs to be known
+	 *
+	 *	$props = array(
+	 *					'width' 		=> $width,
+	 *					'height' 		=> $height,
+	 *					'new_width'		=> 40,
+	 *					'new_height'	=> ''
+	 *				  );
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	array
+	 */
+	function size_calculator($vals)
+	{
+		if ( ! is_array($vals))
+		{
+			return;
+		}
+
+		$allowed = array('new_width', 'new_height', 'width', 'height');
+
+		foreach ($allowed as $item)
+		{
+			if ( ! isset($vals[$item]) OR $vals[$item] == '')
+				$vals[$item] = 0;
+		}
+
+		if ($vals['width'] == 0 OR $vals['height'] == 0)
+		{
+			return $vals;
+		}
+
+		if ($vals['new_width'] == 0)
+		{
+			$vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
+		}
+		elseif ($vals['new_height'] == 0)
+		{
+			$vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
+		}
+
+		return $vals;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Explode source_image
+	 *
+	 * This is a helper function that extracts the extension
+	 * from the source_image.  This function lets us deal with
+	 * source_images with multiple periods, like:  my.cool.jpg
+	 * It returns an associative array with two elements:
+	 * $array['ext']  = '.jpg';
+	 * $array['name'] = 'my.cool';
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	array
+	 */
+	function explode_name($source_image)
+	{
+		$x = explode('.', $source_image);
+		$ret['ext'] = '.'.end($x);
+
+		$name = '';
+
+		$ct = count($x)-1;
+
+		for ($i = 0; $i < $ct; $i++)
+		{
+			$name .= $x[$i];
+
+			if ($i < ($ct - 1))
+			{
+				$name .= '.';
+			}
+		}
+
+		$ret['name'] = $name;
+
+		return $ret;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Is GD Installed?
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function gd_loaded()
+	{
+		if ( ! extension_loaded('gd'))
+		{
+			if ( ! dl('gd.so'))
+			{
+				return FALSE;
+			}
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get GD version
+	 *
+	 * @access	public
+	 * @return	mixed
+	 */
+	function gd_version()
+	{
+		if (function_exists('gd_info'))
+		{
+			$gd_version = @gd_info();
+			$gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);
+
+			return $gd_version;
+		}
+
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_error($msg)
+	{
+		$CI =& get_instance();
+		$CI->lang->load('imglib');
+
+		if (is_array($msg))
+		{
+			foreach ($msg as $val)
+			{
+
+				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
+				$this->error_msg[] = $msg;
+				log_message('error', $msg);
+			}
+		}
+		else
+		{
+			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
+			$this->error_msg[] = $msg;
+			log_message('error', $msg);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show error messages
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function display_errors($open = '<p>', $close = '</p>')
+	{
+		$str = '';
+		foreach ($this->error_msg as $val)
+		{
+			$str .= $open.$val.$close;
+		}
+
+		return $str;
+	}
+
+}
+// END Image_lib Class
+
+/* End of file Image_lib.php */
 /* Location: ./system/libraries/Image_lib.php */
\ No newline at end of file
diff --git a/system/libraries/Input.php b/system/libraries/Input.php
index fe76559..f26df75 100644
--- a/system/libraries/Input.php
+++ b/system/libraries/Input.php
@@ -1,1059 +1,1059 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Input Class

- *

- * Pre-processes global input data for security

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Input

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/input.html

- */

-class CI_Input {

-	var $use_xss_clean		= FALSE;

-	var $xss_hash			= '';

-	var $ip_address			= FALSE;

-	var $user_agent			= FALSE;

-	var $allow_get_array	= FALSE;

-

-	/* never allowed, string replacement */

-	var $never_allowed_str = array(

-									'document.cookie'	=> '[removed]',

-									'document.write'	=> '[removed]',

-									'.parentNode'		=> '[removed]',

-									'.innerHTML'		=> '[removed]',

-									'window.location'	=> '[removed]',

-									'-moz-binding'		=> '[removed]',

-									'<!--'				=> '&lt;!--',

-									'-->'				=> '--&gt;',

-									'<![CDATA['			=> '&lt;![CDATA['

-									);

-	/* never allowed, regex replacement */

-	var $never_allowed_regex = array(

-										"javascript\s*:"	=> '[removed]',

-										"expression\s*\("	=> '[removed]', // CSS and IE

-										"Redirect\s+302"	=> '[removed]'

-									);

-

-	/**

-	* Constructor

-	*

-	* Sets whether to globally enable the XSS processing

-	* and whether to allow the $_GET array

-	*

-	* @access	public

-	*/

-	function CI_Input()

-	{

-		log_message('debug', "Input Class Initialized");

-

-		$CFG =& load_class('Config');

-		$this->use_xss_clean	= ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE;

-		$this->allow_get_array	= ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE;

-		$this->_sanitize_globals();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Sanitize Globals

-	*

-	* This function does the following:

-	*

-	* Unsets $_GET data (if query strings are not enabled)

-	*

-	* Unsets all globals if register_globals is enabled

-	*

-	* Standardizes newline characters to \n

-	*

-	* @access	private

-	* @return	void

-	*/

-	function _sanitize_globals()

-	{

-		// Would kind of be "wrong" to unset any of these GLOBALS

-		$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',

-							'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN');

-

-		// Unset globals for security. 

-		// This is effectively the same as register_globals = off

-		foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global)

-		{

-			if ( ! is_array($global))

-			{

-				if ( ! in_array($global, $protected))

-				{

-					unset($GLOBALS[$global]);

-				}

-			}

-			else

-			{

-				foreach ($global as $key => $val)

-				{

-					if ( ! in_array($key, $protected))

-					{

-						unset($GLOBALS[$key]);

-					}

-

-					if (is_array($val))

-					{

-						foreach($val as $k => $v)

-						{

-							if ( ! in_array($k, $protected))

-							{

-								unset($GLOBALS[$k]);

-							}

-						}

-					}

-				}

-			}

-		}

-

-		// Is $_GET data allowed? If not we'll set the $_GET to an empty array

-		if ($this->allow_get_array == FALSE)

-		{

-			$_GET = array();

-		}

-		else

-		{

-			$_GET = $this->_clean_input_data($_GET);

-		}

-

-		// Clean $_POST Data

-		$_POST = $this->_clean_input_data($_POST);

-

-		// Clean $_COOKIE Data

-		// Also get rid of specially treated cookies that might be set by a server

-		// or silly application, that are of no use to a CI application anyway

-		// but that when present will trip our 'Disallowed Key Characters' alarm

-		// http://www.ietf.org/rfc/rfc2109.txt

-		// note that the key names below are single quoted strings, and are not PHP variables

-		unset($_COOKIE['$Version']);

-		unset($_COOKIE['$Path']);

-		unset($_COOKIE['$Domain']);

-		$_COOKIE = $this->_clean_input_data($_COOKIE);

-

-		log_message('debug', "Global POST and COOKIE data sanitized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Clean Input Data

-	*

-	* This is a helper function. It escapes data and

-	* standardizes newline characters to \n

-	*

-	* @access	private

-	* @param	string

-	* @return	string

-	*/

-	function _clean_input_data($str)

-	{

-		if (is_array($str))

-		{

-			$new_array = array();

-			foreach ($str as $key => $val)

-			{

-				$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);

-			}

-			return $new_array;

-		}

-

-		// We strip slashes if magic quotes is on to keep things consistent

-		if (get_magic_quotes_gpc())

-		{

-			$str = stripslashes($str);

-		}

-

-		// Should we filter the input data?

-		if ($this->use_xss_clean === TRUE)

-		{

-			$str = $this->xss_clean($str);

-		}

-

-		// Standardize newlines

-		if (strpos($str, "\r") !== FALSE)

-		{

-			$str = str_replace(array("\r\n", "\r"), "\n", $str);

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Clean Keys

-	*

-	* This is a helper function. To prevent malicious users

-	* from trying to exploit keys we make sure that keys are

-	* only named with alpha-numeric text and a few other items.

-	*

-	* @access	private

-	* @param	string

-	* @return	string

-	*/

-	function _clean_input_keys($str)

-	{

-		if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))

-		{

-			exit('Disallowed Key Characters.');

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch from array

-	*

-	* This is a helper function to retrieve values from global arrays

-	*

-	* @access	private

-	* @param	array

-	* @param	string

-	* @param	bool

-	* @return	string

-	*/

-	function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)

-	{

-		if ( ! isset($array[$index]))

-		{

-			return FALSE;

-		}

-

-		if ($xss_clean === TRUE)

-		{

-			return $this->xss_clean($array[$index]);

-		}

-

-		return $array[$index];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch an item from the GET array

-	*

-	* @access	public

-	* @param	string

-	* @param	bool

-	* @return	string

-	*/

-	function get($index = '', $xss_clean = FALSE)

-	{

-		return $this->_fetch_from_array($_GET, $index, $xss_clean);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch an item from the POST array

-	*

-	* @access	public

-	* @param	string

-	* @param	bool

-	* @return	string

-	*/

-	function post($index = '', $xss_clean = FALSE)

-	{

-		return $this->_fetch_from_array($_POST, $index, $xss_clean);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch an item from either the GET array or the POST

-	*

-	* @access	public

-	* @param	string	The index key

-	* @param	bool	XSS cleaning

-	* @return	string

-	*/

-	function get_post($index = '', $xss_clean = FALSE)

-	{

-		if ( ! isset($_POST[$index]) )

-		{

-			return $this->get($index, $xss_clean);

-		}

-		else

-		{

-			return $this->post($index, $xss_clean);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch an item from the COOKIE array

-	*

-	* @access	public

-	* @param	string

-	* @param	bool

-	* @return	string

-	*/

-	function cookie($index = '', $xss_clean = FALSE)

-	{

-		return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch an item from the SERVER array

-	*

-	* @access	public

-	* @param	string

-	* @param	bool

-	* @return	string

-	*/

-	function server($index = '', $xss_clean = FALSE)

-	{

-		return $this->_fetch_from_array($_SERVER, $index, $xss_clean);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Fetch the IP Address

-	*

-	* @access	public

-	* @return	string

-	*/

-	function ip_address()

-	{

-		if ($this->ip_address !== FALSE)

-		{

-			return $this->ip_address;

-		}

-

-		if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))

-		{

-			$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];

-		}

-		elseif ($this->server('REMOTE_ADDR'))

-		{

-			$this->ip_address = $_SERVER['REMOTE_ADDR'];

-		}

-		elseif ($this->server('HTTP_CLIENT_IP'))

-		{

-			$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];

-		}

-		elseif ($this->server('HTTP_X_FORWARDED_FOR'))

-		{

-			$this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];

-		}

-

-		if ($this->ip_address === FALSE)

-		{

-			$this->ip_address = '0.0.0.0';

-			return $this->ip_address;

-		}

-

-		if (strstr($this->ip_address, ','))

-		{

-			$x = explode(',', $this->ip_address);

-			$this->ip_address = end($x);

-		}

-

-		if ( ! $this->valid_ip($this->ip_address))

-		{

-			$this->ip_address = '0.0.0.0';

-		}

-

-		return $this->ip_address;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Validate IP Address

-	*

-	* Updated version suggested by Geert De Deckere

-	* 

-	* @access	public

-	* @param	string

-	* @return	string

-	*/

-	function valid_ip($ip)

-	{

-		$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;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* User Agent

-	*

-	* @access	public

-	* @return	string

-	*/

-	function user_agent()

-	{

-		if ($this->user_agent !== FALSE)

-		{

-			return $this->user_agent;

-		}

-

-		$this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];

-

-		return $this->user_agent;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Filename Security

-	*

-	* @access	public

-	* @param	string

-	* @return	string

-	*/

-	function filename_security($str)

-	{

-		$bad = array(

-						"../",

-						"./",

-						"<!--",

-						"-->",

-						"<",

-						">",

-						"'",

-						'"',

-						'&',

-						'$',

-						'#',

-						'{',

-						'}',

-						'[',

-						']',

-						'=',

-						';',

-						'?',

-						"%20",

-						"%22",

-						"%3c",		// <

-						"%253c", 	// <

-						"%3e", 		// >

-						"%0e", 		// >

-						"%28", 		// (  

-						"%29", 		// ) 

-						"%2528", 	// (

-						"%26", 		// &

-						"%24", 		// $

-						"%3f", 		// ?

-						"%3b", 		// ;

-						"%3d"		// =

-					);

-

-		return stripslashes(str_replace($bad, '', $str));

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* XSS Clean

-	*

-	* Sanitizes data so that Cross Site Scripting Hacks can be

-	* prevented.  This function does a fair amount of work but

-	* it is extremely thorough, designed to prevent even the

-	* most obscure XSS attempts.  Nothing is ever 100% foolproof,

-	* of course, but I haven't been able to get anything passed

-	* the filter.

-	*

-	* Note: This function should only be used to deal with data

-	* upon submission.  It's not something that should

-	* be used for general runtime processing.

-	*

-	* This function was based in part on some code and ideas I

-	* got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention

-	*

-	* To help develop this script I used this great list of

-	* vulnerabilities along with a few other hacks I've

-	* harvested from examining vulnerabilities in other programs:

-	* http://ha.ckers.org/xss.html

-	*

-	* @access	public

-	* @param	string

-	* @return	string

-	*/

-	function xss_clean($str, $is_image = FALSE)

-	{

-		/*

-		* Is the string an array?

-		*

-		*/

-		if (is_array($str))

-		{

-			while (list($key) = each($str))

-			{

-				$str[$key] = $this->xss_clean($str[$key]);

-			}

-

-			return $str;

-		}

-

-		/*

-		* Remove Invisible Characters

-		*/

-		$str = $this->_remove_invisible_characters($str);

-

-		/*

-		* Protect GET variables in URLs

-		*/

-

-		// 901119URL5918AMP18930PROTECT8198

-

-		$str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str);

-

-		/*

-		* Validate standard character entities

-		*

-		* Add a semicolon if missing.  We do this to enable

-		* the conversion of entities to ASCII later.

-		*

-		*/

-		$str = preg_replace('#(&\#?[0-9a-z]{2,})[\x00-\x20]*;?#i', "\\1;", $str);

-

-		/*

-		* Validate UTF16 two byte encoding (x00) 

-		*

-		* Just as above, adds a semicolon if missing.

-		*

-		*/

-		$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);

-

-		/*

-		* Un-Protect GET variables in URLs

-		*/

-		$str = str_replace($this->xss_hash(), '&', $str);

-

-		/*

-		* URL Decode

-		*

-		* Just in case stuff like this is submitted:

-		*

-		* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>

-		*

-		* Note: Use rawurldecode() so it does not remove plus signs

-		*

-		*/

-		$str = rawurldecode($str);

-

-		/*

-		* Convert character entities to ASCII 

-		*

-		* This permits our tests below to work reliably.

-		* We only convert entities that are within tags since

-		* these are the ones that will pose security problems.

-		*

-		*/

-

-		$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);

-

-		$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str);

-

-		/*

-		* Remove Invisible Characters Again!

-		*/

-		$str = $this->_remove_invisible_characters($str);

-

-		/*

-		* Convert all tabs to spaces

-		*

-		* This prevents strings like this: ja	vascript

-		* NOTE: we deal with spaces between characters later.

-		* NOTE: preg_replace was found to be amazingly slow here on large blocks of data,

-		* so we use str_replace.

-		*

-		*/

-

- 		if (strpos($str, "\t") !== FALSE)

-		{

-			$str = str_replace("\t", ' ', $str);

-		}

-

-		/*

-		* Capture converted string for later comparison

-		*/

-		$converted_string = $str;

-

-		/*

-		* Not Allowed Under Any Conditions

-		*/

-

-		foreach ($this->never_allowed_str as $key => $val)

-		{

-			$str = str_replace($key, $val, $str);   

-		}

-

-		foreach ($this->never_allowed_regex as $key => $val)

-		{

-			$str = preg_replace("#".$key."#i", $val, $str);   

-		}

-

-		/*

-		* Makes PHP tags safe

-		*

-		*  Note: XML tags are inadvertently replaced too:

-		*

-		*	<?xml

-		*

-		* But it doesn't seem to pose a problem.

-		*

-		*/

-		if ($is_image === TRUE)

-		{

-			// Images have a tendency to have the PHP short opening and closing tags every so often

-			// so we skip those and only do the long opening tags.

-			$str = str_replace(array('<?php', '<?PHP'),  array('&lt;?php', '&lt;?PHP'), $str);

-		}

-		else

-		{

-			$str = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);

-		}

-

-		/*

-		* Compact any exploded words

-		*

-		* This corrects words like:  j a v a s c r i p t

-		* These words are compacted back to their correct state.

-		*

-		*/

-		$words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');

-		foreach ($words as $word)

-		{

-			$temp = '';

-

-			for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)

-			{

-				$temp .= substr($word, $i, 1)."\s*";

-			}

-

-			// We only want to do this when it is followed by a non-word character

-			// That way valid stuff like "dealer to" does not become "dealerto"

-			$str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);

-		}

-

-		/*

-		* Remove disallowed Javascript in links or img tags

-		* We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared

-		* to these simplified non-capturing preg_match(), especially if the pattern exists in the string

-		*/

-		do

-		{

-			$original = $str;

-

-			if (preg_match("/<a/i", $str))

-			{

-				$str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);

-			}

-

-			if (preg_match("/<img/i", $str))

-			{

-				$str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);

-			}

-

-			if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))

-			{

-				$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);

-			}

-		}

-		while($original != $str);

-

-		unset($original);

-

-		/*

-		* Remove JavaScript Event Handlers

-		*

-		* Note: This code is a little blunt.  It removes

-		* the event handler and anything up to the closing >,

-		* but it's unlikely to be a problem.

-		*

-		*/

-		$event_handlers = array('[^a-z_\-]on\w*','xmlns');

-

-		if ($is_image === TRUE)

-		{

-			/*

-			* Adobe Photoshop puts XML metadata into JFIF images, including namespacing, 

-			* so we have to allow this for images. -Paul

-			*/

-			unset($event_handlers[array_search('xmlns', $event_handlers)]);

-		}

-

-		$str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str);

-

-		/*

-		* Sanitize naughty HTML elements

-		*

-		* If a tag containing any of the words in the list

-		* below is found, the tag gets converted to entities.

-		*

-		* So this: <blink>

-		* Becomes: &lt;blink&gt;

-		*

-		*/

-		$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';

-		$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);

-

-		/*

-		* Sanitize naughty scripting elements

-		*

-		* Similar to above, only instead of looking for

-		* tags it looks for PHP and JavaScript commands

-		* that are disallowed.  Rather than removing the

-		* code, it simply converts the parenthesis to entities

-		* rendering the code un-executable.

-		*

-		* For example:	eval('some code')

-		* Becomes:		eval&#40;'some code'&#41;

-		*

-		*/

-		$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);

-

-		/*

-		* Final clean up

-		*

-		* This adds a bit of extra precaution in case

-		* something got through the above filters

-		*

-		*/

-		foreach ($this->never_allowed_str as $key => $val)

-		{

-			$str = str_replace($key, $val, $str);   

-		}

-

-		foreach ($this->never_allowed_regex as $key => $val)

-		{

-			$str = preg_replace("#".$key."#i", $val, $str);

-		}

-

-		/*

-		*  Images are Handled in a Special Way

-		*  - Essentially, we want to know that after all of the character conversion is done whether

-		*  any unwanted, likely XSS, code was found.  If not, we return TRUE, as the image is clean.

-		*  However, if the string post-conversion does not matched the string post-removal of XSS,

-		*  then it fails, as there was unwanted XSS code found and removed/changed during processing.

-		*/

-

-		if ($is_image === TRUE)

-		{

-			if ($str == $converted_string)

-			{

-				return TRUE;

-			}

-			else

-			{

-				return FALSE;

-			}

-		}

-

-		log_message('debug', "XSS Filtering completed");

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Random Hash for protecting URLs

-	*

-	* @access	public

-	* @return	string

-	*/

-	function xss_hash()

-	{

-		if ($this->xss_hash == '')

-		{

-			if (phpversion() >= 4.2)

-				mt_srand();

-			else

-				mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);

-

-			$this->xss_hash = md5(time() + mt_rand(0, 1999999999));

-		}

-

-		return $this->xss_hash;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Remove Invisible Characters

-	*

-	* This prevents sandwiching null characters

-	* between ascii characters, like Java\0script.

-	*

-	* @access	public

-	* @param	string

-	* @return	string

-	*/

-	function _remove_invisible_characters($str)

-	{

-		static $non_displayables;

-

-		if ( ! isset($non_displayables))

-		{

-			// every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),

-			$non_displayables = array(

-										'/%0[0-8bcef]/',			// url encoded 00-08, 11, 12, 14, 15

-										'/%1[0-9a-f]/',				// url encoded 16-31

-										'/[\x00-\x08]/',			// 00-08

-										'/\x0b/', '/\x0c/',			// 11, 12

-										'/[\x0e-\x1f]/'				// 14-31

-									);

-		}

-

-		do

-		{

-			$cleaned = $str;

-			$str = preg_replace($non_displayables, '', $str);

-		}

-		while ($cleaned != $str);

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Compact Exploded Words

-	*

-	* Callback function for xss_clean() to remove whitespace from

-	* things like j a v a s c r i p t

-	*

-	* @access	public

-	* @param	type

-	* @return	type

-	*/

-	function _compact_exploded_words($matches)

-	{

-		return preg_replace('/\s+/s', '', $matches[1]).$matches[2];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Sanitize Naughty HTML

-	*

-	* Callback function for xss_clean() to remove naughty HTML elements

-	*

-	* @access	private

-	* @param	array

-	* @return	string

-	*/

-	function _sanitize_naughty_html($matches)

-	{

-		// encode opening brace

-		$str = '&lt;'.$matches[1].$matches[2].$matches[3];

-

-		// encode captured opening or closing brace to prevent recursive vectors

-		$str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* JS Link Removal

-	*

-	* Callback function for xss_clean() to sanitize links

-	* This limits the PCRE backtracks, making it more performance friendly

-	* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in

-	* PHP 5.2+ on link-heavy strings

-	*

-	* @access	private

-	* @param	array

-	* @return	string

-	*/

-	function _js_link_removal($match)

-	{

-		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));

-		return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);

-	}

-

-	/**

-	* JS Image Removal

-	*

-	* Callback function for xss_clean() to sanitize image tags

-	* This limits the PCRE backtracks, making it more performance friendly

-	* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in

-	* PHP 5.2+ on image tag heavy strings

-	*

-	* @access	private

-	* @param	array

-	* @return	string

-	*/

-	function _js_img_removal($match)

-	{

-		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));

-		return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Attribute Conversion

-	*

-	* Used as a callback for XSS Clean

-	*

-	* @access	public

-	* @param	array

-	* @return	string

-	*/

-	function _convert_attribute($match)

-	{

-		return str_replace(array('>', '<'), array('&gt;', '&lt;'), $match[0]);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* HTML Entity Decode Callback

-	*

-	* Used as a callback for XSS Clean

-	*

-	* @access	public

-	* @param	array

-	* @return	string

-	*/

-	function _html_entity_decode_callback($match)

-	{

-		$CFG =& load_class('Config');

-		$charset = $CFG->item('charset');

-

-		return $this->_html_entity_decode($match[0], strtoupper($charset));

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* HTML Entities Decode

-	*

-	* This function is a replacement for html_entity_decode()

-	*

-	* In some versions of PHP the native function does not work

-	* when UTF-8 is the specified character set, so this gives us

-	* a work-around.  More info here:

-	* http://bugs.php.net/bug.php?id=25670

-	*

-	* @access	private

-	* @param	string

-	* @param	string

-	* @return	string

-	*/

-	/* -------------------------------------------------

-	/*  Replacement for html_entity_decode()

-	/* -------------------------------------------------*/

-

-	/*

-	NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the

-	character set, and the PHP developers said they were not back porting the

-	fix to versions other than PHP 5.x.

-	*/

-	function _html_entity_decode($str, $charset='UTF-8')

-	{

-		if (stristr($str, '&') === FALSE) return $str;

-

-		// The reason we are not using html_entity_decode() by itself is because

-		// while it is not technically correct to leave out the semicolon

-		// at the end of an entity most browsers will still interpret the entity

-		// correctly.  html_entity_decode() does not convert entities without

-		// semicolons, so we are left with our own little solution here. Bummer.

-

-		if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>=')))

-		{

-			$str = html_entity_decode($str, ENT_COMPAT, $charset);

-			$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);

-			return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);

-		}

-

-		// Numeric Entities

-		$str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);

-		$str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);

-

-		// Literal Entities - Slightly slow so we do another check

-		if (stristr($str, '&') === FALSE)

-		{

-			$str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));

-		}

-

-		return $str;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	* Filter Attributes

-	*

-	* Filters tag attributes for consistency and safety

-	*

-	* @access	public

-	* @param	string

-	* @return	string

-	*/

-	function _filter_attributes($str)

-	{

-		$out = '';

-

-		if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))

-		{

-			foreach ($matches[0] as $match)

-			{

-				$out .= "{$match}";

-			}

-		}

-

-		return $out;

-	}

-

-	// --------------------------------------------------------------------

-

-}

-// END Input class

-

-/* End of file Input.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Input Class
+ *
+ * Pre-processes global input data for security
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Input
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/input.html
+ */
+class CI_Input {
+	var $use_xss_clean		= FALSE;
+	var $xss_hash			= '';
+	var $ip_address			= FALSE;
+	var $user_agent			= FALSE;
+	var $allow_get_array	= FALSE;
+
+	/* never allowed, string replacement */
+	var $never_allowed_str = array(
+									'document.cookie'	=> '[removed]',
+									'document.write'	=> '[removed]',
+									'.parentNode'		=> '[removed]',
+									'.innerHTML'		=> '[removed]',
+									'window.location'	=> '[removed]',
+									'-moz-binding'		=> '[removed]',
+									'<!--'				=> '&lt;!--',
+									'-->'				=> '--&gt;',
+									'<![CDATA['			=> '&lt;![CDATA['
+									);
+	/* never allowed, regex replacement */
+	var $never_allowed_regex = array(
+										"javascript\s*:"	=> '[removed]',
+										"expression\s*\("	=> '[removed]', // CSS and IE
+										"Redirect\s+302"	=> '[removed]'
+									);
+
+	/**
+	* Constructor
+	*
+	* Sets whether to globally enable the XSS processing
+	* and whether to allow the $_GET array
+	*
+	* @access	public
+	*/
+	function CI_Input()
+	{
+		log_message('debug', "Input Class Initialized");
+
+		$CFG =& load_class('Config');
+		$this->use_xss_clean	= ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE;
+		$this->allow_get_array	= ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE;
+		$this->_sanitize_globals();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Sanitize Globals
+	*
+	* This function does the following:
+	*
+	* Unsets $_GET data (if query strings are not enabled)
+	*
+	* Unsets all globals if register_globals is enabled
+	*
+	* Standardizes newline characters to \n
+	*
+	* @access	private
+	* @return	void
+	*/
+	function _sanitize_globals()
+	{
+		// Would kind of be "wrong" to unset any of these GLOBALS
+		$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
+							'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN');
+
+		// Unset globals for security. 
+		// This is effectively the same as register_globals = off
+		foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global)
+		{
+			if ( ! is_array($global))
+			{
+				if ( ! in_array($global, $protected))
+				{
+					unset($GLOBALS[$global]);
+				}
+			}
+			else
+			{
+				foreach ($global as $key => $val)
+				{
+					if ( ! in_array($key, $protected))
+					{
+						unset($GLOBALS[$key]);
+					}
+
+					if (is_array($val))
+					{
+						foreach($val as $k => $v)
+						{
+							if ( ! in_array($k, $protected))
+							{
+								unset($GLOBALS[$k]);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// Is $_GET data allowed? If not we'll set the $_GET to an empty array
+		if ($this->allow_get_array == FALSE)
+		{
+			$_GET = array();
+		}
+		else
+		{
+			$_GET = $this->_clean_input_data($_GET);
+		}
+
+		// Clean $_POST Data
+		$_POST = $this->_clean_input_data($_POST);
+
+		// Clean $_COOKIE Data
+		// Also get rid of specially treated cookies that might be set by a server
+		// or silly application, that are of no use to a CI application anyway
+		// but that when present will trip our 'Disallowed Key Characters' alarm
+		// http://www.ietf.org/rfc/rfc2109.txt
+		// note that the key names below are single quoted strings, and are not PHP variables
+		unset($_COOKIE['$Version']);
+		unset($_COOKIE['$Path']);
+		unset($_COOKIE['$Domain']);
+		$_COOKIE = $this->_clean_input_data($_COOKIE);
+
+		log_message('debug', "Global POST and COOKIE data sanitized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Clean Input Data
+	*
+	* This is a helper function. It escapes data and
+	* standardizes newline characters to \n
+	*
+	* @access	private
+	* @param	string
+	* @return	string
+	*/
+	function _clean_input_data($str)
+	{
+		if (is_array($str))
+		{
+			$new_array = array();
+			foreach ($str as $key => $val)
+			{
+				$new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+			}
+			return $new_array;
+		}
+
+		// We strip slashes if magic quotes is on to keep things consistent
+		if (get_magic_quotes_gpc())
+		{
+			$str = stripslashes($str);
+		}
+
+		// Should we filter the input data?
+		if ($this->use_xss_clean === TRUE)
+		{
+			$str = $this->xss_clean($str);
+		}
+
+		// Standardize newlines
+		if (strpos($str, "\r") !== FALSE)
+		{
+			$str = str_replace(array("\r\n", "\r"), "\n", $str);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Clean Keys
+	*
+	* This is a helper function. To prevent malicious users
+	* from trying to exploit keys we make sure that keys are
+	* only named with alpha-numeric text and a few other items.
+	*
+	* @access	private
+	* @param	string
+	* @return	string
+	*/
+	function _clean_input_keys($str)
+	{
+		if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
+		{
+			exit('Disallowed Key Characters.');
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch from array
+	*
+	* This is a helper function to retrieve values from global arrays
+	*
+	* @access	private
+	* @param	array
+	* @param	string
+	* @param	bool
+	* @return	string
+	*/
+	function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
+	{
+		if ( ! isset($array[$index]))
+		{
+			return FALSE;
+		}
+
+		if ($xss_clean === TRUE)
+		{
+			return $this->xss_clean($array[$index]);
+		}
+
+		return $array[$index];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch an item from the GET array
+	*
+	* @access	public
+	* @param	string
+	* @param	bool
+	* @return	string
+	*/
+	function get($index = '', $xss_clean = FALSE)
+	{
+		return $this->_fetch_from_array($_GET, $index, $xss_clean);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch an item from the POST array
+	*
+	* @access	public
+	* @param	string
+	* @param	bool
+	* @return	string
+	*/
+	function post($index = '', $xss_clean = FALSE)
+	{
+		return $this->_fetch_from_array($_POST, $index, $xss_clean);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch an item from either the GET array or the POST
+	*
+	* @access	public
+	* @param	string	The index key
+	* @param	bool	XSS cleaning
+	* @return	string
+	*/
+	function get_post($index = '', $xss_clean = FALSE)
+	{
+		if ( ! isset($_POST[$index]) )
+		{
+			return $this->get($index, $xss_clean);
+		}
+		else
+		{
+			return $this->post($index, $xss_clean);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch an item from the COOKIE array
+	*
+	* @access	public
+	* @param	string
+	* @param	bool
+	* @return	string
+	*/
+	function cookie($index = '', $xss_clean = FALSE)
+	{
+		return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch an item from the SERVER array
+	*
+	* @access	public
+	* @param	string
+	* @param	bool
+	* @return	string
+	*/
+	function server($index = '', $xss_clean = FALSE)
+	{
+		return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Fetch the IP Address
+	*
+	* @access	public
+	* @return	string
+	*/
+	function ip_address()
+	{
+		if ($this->ip_address !== FALSE)
+		{
+			return $this->ip_address;
+		}
+
+		if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
+		{
+			$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
+		}
+		elseif ($this->server('REMOTE_ADDR'))
+		{
+			$this->ip_address = $_SERVER['REMOTE_ADDR'];
+		}
+		elseif ($this->server('HTTP_CLIENT_IP'))
+		{
+			$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
+		}
+		elseif ($this->server('HTTP_X_FORWARDED_FOR'))
+		{
+			$this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
+		}
+
+		if ($this->ip_address === FALSE)
+		{
+			$this->ip_address = '0.0.0.0';
+			return $this->ip_address;
+		}
+
+		if (strstr($this->ip_address, ','))
+		{
+			$x = explode(',', $this->ip_address);
+			$this->ip_address = end($x);
+		}
+
+		if ( ! $this->valid_ip($this->ip_address))
+		{
+			$this->ip_address = '0.0.0.0';
+		}
+
+		return $this->ip_address;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Validate IP Address
+	*
+	* Updated version suggested by Geert De Deckere
+	* 
+	* @access	public
+	* @param	string
+	* @return	string
+	*/
+	function valid_ip($ip)
+	{
+		$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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* User Agent
+	*
+	* @access	public
+	* @return	string
+	*/
+	function user_agent()
+	{
+		if ($this->user_agent !== FALSE)
+		{
+			return $this->user_agent;
+		}
+
+		$this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
+
+		return $this->user_agent;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Filename Security
+	*
+	* @access	public
+	* @param	string
+	* @return	string
+	*/
+	function filename_security($str)
+	{
+		$bad = array(
+						"../",
+						"./",
+						"<!--",
+						"-->",
+						"<",
+						">",
+						"'",
+						'"',
+						'&',
+						'$',
+						'#',
+						'{',
+						'}',
+						'[',
+						']',
+						'=',
+						';',
+						'?',
+						"%20",
+						"%22",
+						"%3c",		// <
+						"%253c", 	// <
+						"%3e", 		// >
+						"%0e", 		// >
+						"%28", 		// (  
+						"%29", 		// ) 
+						"%2528", 	// (
+						"%26", 		// &
+						"%24", 		// $
+						"%3f", 		// ?
+						"%3b", 		// ;
+						"%3d"		// =
+					);
+
+		return stripslashes(str_replace($bad, '', $str));
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* XSS Clean
+	*
+	* Sanitizes data so that Cross Site Scripting Hacks can be
+	* prevented.  This function does a fair amount of work but
+	* it is extremely thorough, designed to prevent even the
+	* most obscure XSS attempts.  Nothing is ever 100% foolproof,
+	* of course, but I haven't been able to get anything passed
+	* the filter.
+	*
+	* Note: This function should only be used to deal with data
+	* upon submission.  It's not something that should
+	* be used for general runtime processing.
+	*
+	* This function was based in part on some code and ideas I
+	* got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention
+	*
+	* To help develop this script I used this great list of
+	* vulnerabilities along with a few other hacks I've
+	* harvested from examining vulnerabilities in other programs:
+	* http://ha.ckers.org/xss.html
+	*
+	* @access	public
+	* @param	string
+	* @return	string
+	*/
+	function xss_clean($str, $is_image = FALSE)
+	{
+		/*
+		* Is the string an array?
+		*
+		*/
+		if (is_array($str))
+		{
+			while (list($key) = each($str))
+			{
+				$str[$key] = $this->xss_clean($str[$key]);
+			}
+
+			return $str;
+		}
+
+		/*
+		* Remove Invisible Characters
+		*/
+		$str = $this->_remove_invisible_characters($str);
+
+		/*
+		* Protect GET variables in URLs
+		*/
+
+		// 901119URL5918AMP18930PROTECT8198
+
+		$str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str);
+
+		/*
+		* Validate standard character entities
+		*
+		* Add a semicolon if missing.  We do this to enable
+		* the conversion of entities to ASCII later.
+		*
+		*/
+		$str = preg_replace('#(&\#?[0-9a-z]{2,})[\x00-\x20]*;?#i', "\\1;", $str);
+
+		/*
+		* Validate UTF16 two byte encoding (x00) 
+		*
+		* Just as above, adds a semicolon if missing.
+		*
+		*/
+		$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
+
+		/*
+		* Un-Protect GET variables in URLs
+		*/
+		$str = str_replace($this->xss_hash(), '&', $str);
+
+		/*
+		* URL Decode
+		*
+		* Just in case stuff like this is submitted:
+		*
+		* <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
+		*
+		* Note: Use rawurldecode() so it does not remove plus signs
+		*
+		*/
+		$str = rawurldecode($str);
+
+		/*
+		* Convert character entities to ASCII 
+		*
+		* This permits our tests below to work reliably.
+		* We only convert entities that are within tags since
+		* these are the ones that will pose security problems.
+		*
+		*/
+
+		$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
+
+		$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str);
+
+		/*
+		* Remove Invisible Characters Again!
+		*/
+		$str = $this->_remove_invisible_characters($str);
+
+		/*
+		* Convert all tabs to spaces
+		*
+		* This prevents strings like this: ja	vascript
+		* NOTE: we deal with spaces between characters later.
+		* NOTE: preg_replace was found to be amazingly slow here on large blocks of data,
+		* so we use str_replace.
+		*
+		*/
+
+ 		if (strpos($str, "\t") !== FALSE)
+		{
+			$str = str_replace("\t", ' ', $str);
+		}
+
+		/*
+		* Capture converted string for later comparison
+		*/
+		$converted_string = $str;
+
+		/*
+		* Not Allowed Under Any Conditions
+		*/
+
+		foreach ($this->never_allowed_str as $key => $val)
+		{
+			$str = str_replace($key, $val, $str);   
+		}
+
+		foreach ($this->never_allowed_regex as $key => $val)
+		{
+			$str = preg_replace("#".$key."#i", $val, $str);   
+		}
+
+		/*
+		* Makes PHP tags safe
+		*
+		*  Note: XML tags are inadvertently replaced too:
+		*
+		*	<?xml
+		*
+		* But it doesn't seem to pose a problem.
+		*
+		*/
+		if ($is_image === TRUE)
+		{
+			// Images have a tendency to have the PHP short opening and closing tags every so often
+			// so we skip those and only do the long opening tags.
+			$str = str_replace(array('<?php', '<?PHP'),  array('&lt;?php', '&lt;?PHP'), $str);
+		}
+		else
+		{
+			$str = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+		}
+
+		/*
+		* Compact any exploded words
+		*
+		* This corrects words like:  j a v a s c r i p t
+		* These words are compacted back to their correct state.
+		*
+		*/
+		$words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');
+		foreach ($words as $word)
+		{
+			$temp = '';
+
+			for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++)
+			{
+				$temp .= substr($word, $i, 1)."\s*";
+			}
+
+			// We only want to do this when it is followed by a non-word character
+			// That way valid stuff like "dealer to" does not become "dealerto"
+			$str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str);
+		}
+
+		/*
+		* Remove disallowed Javascript in links or img tags
+		* We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared
+		* to these simplified non-capturing preg_match(), especially if the pattern exists in the string
+		*/
+		do
+		{
+			$original = $str;
+
+			if (preg_match("/<a/i", $str))
+			{
+				$str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
+			}
+
+			if (preg_match("/<img/i", $str))
+			{
+				$str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);
+			}
+
+			if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
+			{
+				$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
+			}
+		}
+		while($original != $str);
+
+		unset($original);
+
+		/*
+		* Remove JavaScript Event Handlers
+		*
+		* Note: This code is a little blunt.  It removes
+		* the event handler and anything up to the closing >,
+		* but it's unlikely to be a problem.
+		*
+		*/
+		$event_handlers = array('[^a-z_\-]on\w*','xmlns');
+
+		if ($is_image === TRUE)
+		{
+			/*
+			* Adobe Photoshop puts XML metadata into JFIF images, including namespacing, 
+			* so we have to allow this for images. -Paul
+			*/
+			unset($event_handlers[array_search('xmlns', $event_handlers)]);
+		}
+
+		$str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str);
+
+		/*
+		* Sanitize naughty HTML elements
+		*
+		* If a tag containing any of the words in the list
+		* below is found, the tag gets converted to entities.
+		*
+		* So this: <blink>
+		* Becomes: &lt;blink&gt;
+		*
+		*/
+		$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';
+		$str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
+
+		/*
+		* Sanitize naughty scripting elements
+		*
+		* Similar to above, only instead of looking for
+		* tags it looks for PHP and JavaScript commands
+		* that are disallowed.  Rather than removing the
+		* code, it simply converts the parenthesis to entities
+		* rendering the code un-executable.
+		*
+		* For example:	eval('some code')
+		* Becomes:		eval&#40;'some code'&#41;
+		*
+		*/
+		$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
+
+		/*
+		* Final clean up
+		*
+		* This adds a bit of extra precaution in case
+		* something got through the above filters
+		*
+		*/
+		foreach ($this->never_allowed_str as $key => $val)
+		{
+			$str = str_replace($key, $val, $str);   
+		}
+
+		foreach ($this->never_allowed_regex as $key => $val)
+		{
+			$str = preg_replace("#".$key."#i", $val, $str);
+		}
+
+		/*
+		*  Images are Handled in a Special Way
+		*  - Essentially, we want to know that after all of the character conversion is done whether
+		*  any unwanted, likely XSS, code was found.  If not, we return TRUE, as the image is clean.
+		*  However, if the string post-conversion does not matched the string post-removal of XSS,
+		*  then it fails, as there was unwanted XSS code found and removed/changed during processing.
+		*/
+
+		if ($is_image === TRUE)
+		{
+			if ($str == $converted_string)
+			{
+				return TRUE;
+			}
+			else
+			{
+				return FALSE;
+			}
+		}
+
+		log_message('debug', "XSS Filtering completed");
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Random Hash for protecting URLs
+	*
+	* @access	public
+	* @return	string
+	*/
+	function xss_hash()
+	{
+		if ($this->xss_hash == '')
+		{
+			if (phpversion() >= 4.2)
+				mt_srand();
+			else
+				mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);
+
+			$this->xss_hash = md5(time() + mt_rand(0, 1999999999));
+		}
+
+		return $this->xss_hash;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Remove Invisible Characters
+	*
+	* This prevents sandwiching null characters
+	* between ascii characters, like Java\0script.
+	*
+	* @access	public
+	* @param	string
+	* @return	string
+	*/
+	function _remove_invisible_characters($str)
+	{
+		static $non_displayables;
+
+		if ( ! isset($non_displayables))
+		{
+			// every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09),
+			$non_displayables = array(
+										'/%0[0-8bcef]/',			// url encoded 00-08, 11, 12, 14, 15
+										'/%1[0-9a-f]/',				// url encoded 16-31
+										'/[\x00-\x08]/',			// 00-08
+										'/\x0b/', '/\x0c/',			// 11, 12
+										'/[\x0e-\x1f]/'				// 14-31
+									);
+		}
+
+		do
+		{
+			$cleaned = $str;
+			$str = preg_replace($non_displayables, '', $str);
+		}
+		while ($cleaned != $str);
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Compact Exploded Words
+	*
+	* Callback function for xss_clean() to remove whitespace from
+	* things like j a v a s c r i p t
+	*
+	* @access	public
+	* @param	type
+	* @return	type
+	*/
+	function _compact_exploded_words($matches)
+	{
+		return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Sanitize Naughty HTML
+	*
+	* Callback function for xss_clean() to remove naughty HTML elements
+	*
+	* @access	private
+	* @param	array
+	* @return	string
+	*/
+	function _sanitize_naughty_html($matches)
+	{
+		// encode opening brace
+		$str = '&lt;'.$matches[1].$matches[2].$matches[3];
+
+		// encode captured opening or closing brace to prevent recursive vectors
+		$str .= str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* JS Link Removal
+	*
+	* Callback function for xss_clean() to sanitize links
+	* This limits the PCRE backtracks, making it more performance friendly
+	* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
+	* PHP 5.2+ on link-heavy strings
+	*
+	* @access	private
+	* @param	array
+	* @return	string
+	*/
+	function _js_link_removal($match)
+	{
+		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
+		return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+	}
+
+	/**
+	* JS Image Removal
+	*
+	* Callback function for xss_clean() to sanitize image tags
+	* This limits the PCRE backtracks, making it more performance friendly
+	* and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in
+	* PHP 5.2+ on image tag heavy strings
+	*
+	* @access	private
+	* @param	array
+	* @return	string
+	*/
+	function _js_img_removal($match)
+	{
+		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
+		return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Attribute Conversion
+	*
+	* Used as a callback for XSS Clean
+	*
+	* @access	public
+	* @param	array
+	* @return	string
+	*/
+	function _convert_attribute($match)
+	{
+		return str_replace(array('>', '<'), array('&gt;', '&lt;'), $match[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* HTML Entity Decode Callback
+	*
+	* Used as a callback for XSS Clean
+	*
+	* @access	public
+	* @param	array
+	* @return	string
+	*/
+	function _html_entity_decode_callback($match)
+	{
+		$CFG =& load_class('Config');
+		$charset = $CFG->item('charset');
+
+		return $this->_html_entity_decode($match[0], strtoupper($charset));
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* HTML Entities Decode
+	*
+	* This function is a replacement for html_entity_decode()
+	*
+	* In some versions of PHP the native function does not work
+	* when UTF-8 is the specified character set, so this gives us
+	* a work-around.  More info here:
+	* http://bugs.php.net/bug.php?id=25670
+	*
+	* @access	private
+	* @param	string
+	* @param	string
+	* @return	string
+	*/
+	/* -------------------------------------------------
+	/*  Replacement for html_entity_decode()
+	/* -------------------------------------------------*/
+
+	/*
+	NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the
+	character set, and the PHP developers said they were not back porting the
+	fix to versions other than PHP 5.x.
+	*/
+	function _html_entity_decode($str, $charset='UTF-8')
+	{
+		if (stristr($str, '&') === FALSE) return $str;
+
+		// The reason we are not using html_entity_decode() by itself is because
+		// while it is not technically correct to leave out the semicolon
+		// at the end of an entity most browsers will still interpret the entity
+		// correctly.  html_entity_decode() does not convert entities without
+		// semicolons, so we are left with our own little solution here. Bummer.
+
+		if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>=')))
+		{
+			$str = html_entity_decode($str, ENT_COMPAT, $charset);
+			$str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
+			return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
+		}
+
+		// Numeric Entities
+		$str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);
+		$str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);
+
+		// Literal Entities - Slightly slow so we do another check
+		if (stristr($str, '&') === FALSE)
+		{
+			$str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	* Filter Attributes
+	*
+	* Filters tag attributes for consistency and safety
+	*
+	* @access	public
+	* @param	string
+	* @return	string
+	*/
+	function _filter_attributes($str)
+	{
+		$out = '';
+
+		if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
+		{
+			foreach ($matches[0] as $match)
+			{
+				$out .= "{$match}";
+			}
+		}
+
+		return $out;
+	}
+
+	// --------------------------------------------------------------------
+
+}
+// END Input class
+
+/* End of file Input.php */
 /* Location: ./system/libraries/Input.php */
\ No newline at end of file
diff --git a/system/libraries/Language.php b/system/libraries/Language.php
index bc237e7..78f4143 100644
--- a/system/libraries/Language.php
+++ b/system/libraries/Language.php
@@ -1,123 +1,123 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Language Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Language

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/language.html

- */

-class CI_Language {

-

-	var $language	= array();

-	var $is_loaded	= array();

-

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 */

-	function CI_Language()

-	{

-		log_message('debug', "Language Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load a language file

-	 *

-	 * @access	public

-	 * @param	mixed	the name of the language file to be loaded. Can be an array

-	 * @param	string	the language (english, etc.)

-	 * @return	mixed

-	 */

-	function load($langfile = '', $idiom = '', $return = FALSE)

-	{

-		$langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;

-

-		if (in_array($langfile, $this->is_loaded, TRUE))

-		{

-			return;

-		}

-

-		if ($idiom == '')

-		{

-			$CI =& get_instance();

-			$deft_lang = $CI->config->item('language');

-			$idiom = ($deft_lang == '') ? 'english' : $deft_lang;

-		}

-

-		// Determine where the language file is and load it

-		if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))

-		{

-			include(APPPATH.'language/'.$idiom.'/'.$langfile);

-		}

-		else

-		{

-			if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))

-			{

-				include(BASEPATH.'language/'.$idiom.'/'.$langfile);

-			}

-			else

-			{

-				show_error('Unable to load the requested language file: language/'.$langfile);

-			}

-		}

-

-		if ( ! isset($lang))

-		{

-			log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);

-			return;

-		}

-

-		if ($return == TRUE)

-		{

-			return $lang;

-		}

-

-		$this->is_loaded[] = $langfile;

-		$this->language = array_merge($this->language, $lang);

-		unset($lang);

-

-		log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a single line of text from the language array

-	 *

-	 * @access	public

-	 * @param	string	$line 	the language line

-	 * @return	string

-	 */

-	function line($line = '')

-	{

-		$line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];

-		return $line;

-	}

-

-}

-// END Language Class

-

-/* End of file Language.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Language Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Language
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/language.html
+ */
+class CI_Language {
+
+	var $language	= array();
+	var $is_loaded	= array();
+
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 */
+	function CI_Language()
+	{
+		log_message('debug', "Language Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load a language file
+	 *
+	 * @access	public
+	 * @param	mixed	the name of the language file to be loaded. Can be an array
+	 * @param	string	the language (english, etc.)
+	 * @return	mixed
+	 */
+	function load($langfile = '', $idiom = '', $return = FALSE)
+	{
+		$langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;
+
+		if (in_array($langfile, $this->is_loaded, TRUE))
+		{
+			return;
+		}
+
+		if ($idiom == '')
+		{
+			$CI =& get_instance();
+			$deft_lang = $CI->config->item('language');
+			$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
+		}
+
+		// Determine where the language file is and load it
+		if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))
+		{
+			include(APPPATH.'language/'.$idiom.'/'.$langfile);
+		}
+		else
+		{
+			if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))
+			{
+				include(BASEPATH.'language/'.$idiom.'/'.$langfile);
+			}
+			else
+			{
+				show_error('Unable to load the requested language file: language/'.$langfile);
+			}
+		}
+
+		if ( ! isset($lang))
+		{
+			log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
+			return;
+		}
+
+		if ($return == TRUE)
+		{
+			return $lang;
+		}
+
+		$this->is_loaded[] = $langfile;
+		$this->language = array_merge($this->language, $lang);
+		unset($lang);
+
+		log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a single line of text from the language array
+	 *
+	 * @access	public
+	 * @param	string	$line 	the language line
+	 * @return	string
+	 */
+	function line($line = '')
+	{
+		$line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
+		return $line;
+	}
+
+}
+// END Language Class
+
+/* End of file Language.php */
 /* Location: ./system/libraries/Language.php */
\ No newline at end of file
diff --git a/system/libraries/Loader.php b/system/libraries/Loader.php
index da8d9e7..b58cc7d 100644
--- a/system/libraries/Loader.php
+++ b/system/libraries/Loader.php
@@ -1,1088 +1,1088 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Loader Class

- *

- * Loads views and files

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @author		ExpressionEngine Dev Team

- * @category	Loader

- * @link		http://codeigniter.com/user_guide/libraries/loader.html

- */

-class CI_Loader {

-

-	// All these are set automatically. Don't mess with them.

-	var $_ci_ob_level;

-	var $_ci_view_path		= '';

-	var $_ci_is_php5		= FALSE;

-	var $_ci_is_instance 	= FALSE; // Whether we should use $this or $CI =& get_instance()

-	var $_ci_cached_vars	= array();

-	var $_ci_classes		= array();

-	var $_ci_loaded_files	= array();

-	var $_ci_models			= array();

-	var $_ci_helpers		= array();

-	var $_ci_plugins		= array();

-	var $_ci_varmap			= array('unit_test' => 'unit', 'user_agent' => 'agent');

-	

-

-	/**

-	 * Constructor

-	 *

-	 * Sets the path to the view files and gets the initial output buffering level

-	 *

-	 * @access	public

-	 */

-	function CI_Loader()

-	{	

-		$this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;

-		$this->_ci_view_path = APPPATH.'views/';

-		$this->_ci_ob_level  = ob_get_level();

-				

-		log_message('debug', "Loader Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Class Loader

-	 *

-	 * This function lets users load and instantiate classes.

-	 * It is designed to be called from a user's app controllers.

-	 *

-	 * @access	public

-	 * @param	string	the name of the class

-	 * @param	mixed	the optional parameters

-	 * @param	string	an optional object name

-	 * @return	void

-	 */	

-	function library($library = '', $params = NULL, $object_name = NULL)

-	{

-		if ($library == '')

-		{

-			return FALSE;

-		}

-

-		if ( ! is_null($params) AND ! is_array($params))

-		{

-			$params = NULL;

-		}

-

-		if (is_array($library))

-		{

-			foreach ($library as $class)

-			{

-				$this->_ci_load_class($class, $params, $object_name);

-			}

-		}

-		else

-		{

-			$this->_ci_load_class($library, $params, $object_name);

-		}

-		

-		$this->_ci_assign_to_models();

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Model Loader

-	 *

-	 * This function lets users load and instantiate models.

-	 *

-	 * @access	public

-	 * @param	string	the name of the class

-	 * @param	string	name for the model

-	 * @param	bool	database connection

-	 * @return	void

-	 */	

-	function model($model, $name = '', $db_conn = FALSE)

-	{		

-		if (is_array($model))

-		{

-			foreach($model as $babe)

-			{

-				$this->model($babe);	

-			}

-			return;

-		}

-

-		if ($model == '')

-		{

-			return;

-		}

-	

-		// Is the model in a sub-folder? If so, parse out the filename and path.

-		if (strpos($model, '/') === FALSE)

-		{

-			$path = '';

-		}

-		else

-		{

-			$x = explode('/', $model);

-			$model = end($x);			

-			unset($x[count($x)-1]);

-			$path = implode('/', $x).'/';

-		}

-	

-		if ($name == '')

-		{

-			$name = $model;

-		}

-		

-		if (in_array($name, $this->_ci_models, TRUE))

-		{

-			return;

-		}

-		

-		$CI =& get_instance();

-		if (isset($CI->$name))

-		{

-			show_error('The model name you are loading is the name of a resource that is already being used: '.$name);

-		}

-	

-		$model = strtolower($model);

-		

-		if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))

-		{

-			show_error('Unable to locate the model you have specified: '.$model);

-		}

-				

-		if ($db_conn !== FALSE AND ! class_exists('CI_DB'))

-		{

-			if ($db_conn === TRUE)

-				$db_conn = '';

-		

-			$CI->load->database($db_conn, FALSE, TRUE);

-		}

-	

-		if ( ! class_exists('Model'))

-		{

-			load_class('Model', FALSE);

-		}

-

-		require_once(APPPATH.'models/'.$path.$model.EXT);

-

-		$model = ucfirst($model);

-				

-		$CI->$name = new $model();

-		$CI->$name->_assign_libraries();

-		

-		$this->_ci_models[] = $name;	

-	}

-		

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Database Loader

-	 *

-	 * @access	public

-	 * @param	string	the DB credentials

-	 * @param	bool	whether to return the DB object

-	 * @param	bool	whether to enable active record (this allows us to override the config setting)

-	 * @return	object

-	 */	

-	function database($params = '', $return = FALSE, $active_record = FALSE)

-	{

-		// Grab the super object

-		$CI =& get_instance();

-		

-		// Do we even need to load the database class?

-		if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))

-		{

-			return FALSE;

-		}	

-	

-		require_once(BASEPATH.'database/DB'.EXT);

-

-		if ($return === TRUE)

-		{

-			return DB($params, $active_record);

-		}

-		

-		// Initialize the db variable.  Needed to prevent   

-		// reference errors with some configurations

-		$CI->db = '';

-		

-		// Load the DB class

-		$CI->db =& DB($params, $active_record);	

-		

-		// Assign the DB object to any existing models

-		$this->_ci_assign_to_models();

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load the Utilities Class

-	 *

-	 * @access	public

-	 * @return	string		

-	 */		

-	function dbutil()

-	{

-		if ( ! class_exists('CI_DB'))

-		{

-			$this->database();

-		}

-		

-		$CI =& get_instance();

-

-		// for backwards compatibility, load dbforge so we can extend dbutils off it

-		// this use is deprecated and strongly discouraged

-		$CI->load->dbforge();

-	

-		require_once(BASEPATH.'database/DB_utility'.EXT);

-		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);

-		$class = 'CI_DB_'.$CI->db->dbdriver.'_utility';

-

-		$CI->dbutil =& new $class();

-

-		$CI->load->_ci_assign_to_models();

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load the Database Forge Class

-	 *

-	 * @access	public

-	 * @return	string		

-	 */		

-	function dbforge()

-	{

-		if ( ! class_exists('CI_DB'))

-		{

-			$this->database();

-		}

-		

-		$CI =& get_instance();

-	

-		require_once(BASEPATH.'database/DB_forge'.EXT);

-		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);

-		$class = 'CI_DB_'.$CI->db->dbdriver.'_forge';

-

-		$CI->dbforge = new $class();

-		

-		$CI->load->_ci_assign_to_models();

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load View

-	 *

-	 * This function is used to load a "view" file.  It has three parameters:

-	 *

-	 * 1. The name of the "view" file to be included.

-	 * 2. An associative array of data to be extracted for use in the view.

-	 * 3. TRUE/FALSE - whether to return the data or load it.  In

-	 * some cases it's advantageous to be able to return data so that

-	 * a developer can process it in some way.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	array

-	 * @param	bool

-	 * @return	void

-	 */

-	function view($view, $vars = array(), $return = FALSE)

-	{

-		return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load File

-	 *

-	 * This is a generic file loader

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	bool

-	 * @return	string

-	 */

-	function file($path, $return = FALSE)

-	{

-		return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Variables

-	 *

-	 * Once variables are set they become available within

-	 * the controller class and its "view" files.

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function vars($vars = array(), $val = '')

-	{

-		if ($val != '' AND is_string($vars))

-		{

-			$vars = array($vars => $val);

-		}

-	

-		$vars = $this->_ci_object_to_array($vars);

-	

-		if (is_array($vars) AND count($vars) > 0)

-		{

-			foreach ($vars as $key => $val)

-			{

-				$this->_ci_cached_vars[$key] = $val;

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load Helper

-	 *

-	 * This function loads the specified helper file.

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @return	void

-	 */

-	function helper($helpers = array())

-	{

-		if ( ! is_array($helpers))

-		{

-			$helpers = array($helpers);

-		}

-	

-		foreach ($helpers as $helper)

-		{		

-			$helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');

-

-			if (isset($this->_ci_helpers[$helper]))

-			{

-				continue;

-			}

-			

-			$ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;

-

-			// Is this a helper extension request?			

-			if (file_exists($ext_helper))

-			{

-				$base_helper = BASEPATH.'helpers/'.$helper.EXT;

-				

-				if ( ! file_exists($base_helper))

-				{

-					show_error('Unable to load the requested file: helpers/'.$helper.EXT);

-				}

-				

-				include_once($ext_helper);

-				include_once($base_helper);

-			}

-			elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))

-			{ 

-				include_once(APPPATH.'helpers/'.$helper.EXT);

-			}

-			else

-			{		

-				if (file_exists(BASEPATH.'helpers/'.$helper.EXT))

-				{

-					include_once(BASEPATH.'helpers/'.$helper.EXT);

-				}

-				else

-				{

-					show_error('Unable to load the requested file: helpers/'.$helper.EXT);

-				}

-			}

-

-			$this->_ci_helpers[$helper] = TRUE;

-			log_message('debug', 'Helper loaded: '.$helper);	

-		}		

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load Helpers

-	 *

-	 * This is simply an alias to the above function in case the

-	 * user has written the plural form of this function.

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function helpers($helpers = array())

-	{

-		$this->helper($helpers);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load Plugin

-	 *

-	 * This function loads the specified plugin.

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function plugin($plugins = array())

-	{

-		if ( ! is_array($plugins))

-		{

-			$plugins = array($plugins);

-		}

-	

-		foreach ($plugins as $plugin)

-		{	

-			$plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');		

-

-			if (isset($this->_ci_plugins[$plugin]))

-			{

-				continue;

-			}

-

-			if (file_exists(APPPATH.'plugins/'.$plugin.EXT))

-			{

-				include_once(APPPATH.'plugins/'.$plugin.EXT);	

-			}

-			else

-			{

-				if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))

-				{

-					include_once(BASEPATH.'plugins/'.$plugin.EXT);	

-				}

-				else

-				{

-					show_error('Unable to load the requested file: plugins/'.$plugin.EXT);

-				}

-			}

-			

-			$this->_ci_plugins[$plugin] = TRUE;

-			log_message('debug', 'Plugin loaded: '.$plugin);

-		}		

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Load Plugins

-	 *

-	 * This is simply an alias to the above function in case the

-	 * user has written the plural form of this function.

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function plugins($plugins = array())

-	{

-		$this->plugin($plugins);

-	}

-		

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Loads a language file

-	 *

-	 * @access	public

-	 * @param	array

-	 * @param	string

-	 * @return	void

-	 */

-	function language($file = array(), $lang = '')

-	{

-		$CI =& get_instance();

-

-		if ( ! is_array($file))

-		{

-			$file = array($file);

-		}

-

-		foreach ($file as $langfile)

-		{	

-			$CI->lang->load($langfile, $lang);

-		}

-	}

-

-	/**

-	 * Loads language files for scaffolding

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	arra

-	 */

-	function scaffold_language($file = '', $lang = '', $return = FALSE)

-	{

-		$CI =& get_instance();

-		return $CI->lang->load($file, $lang, $return);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Loads a config file

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)

-	{			

-		$CI =& get_instance();

-		$CI->config->load($file, $use_sections, $fail_gracefully);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Scaffolding Loader

-	 *

-	 * This initializing function works a bit different than the

-	 * others. It doesn't load the class.  Instead, it simply

-	 * sets a flag indicating that scaffolding is allowed to be

-	 * used.  The actual scaffolding function below is

-	 * called by the front controller based on whether the

-	 * second segment of the URL matches the "secret" scaffolding

-	 * word stored in the application/config/routes.php

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function scaffolding($table = '')

-	{		

-		if ($table === FALSE)

-		{

-			show_error('You must include the name of the table you would like to access when you initialize scaffolding');

-		}

-		

-		$CI =& get_instance();

-		$CI->_ci_scaffolding = TRUE;

-		$CI->_ci_scaff_table = $table;

-	}

-

-	// --------------------------------------------------------------------

-		

-	/**

-	 * Loader

-	 *

-	 * This function is used to load views and files.

-	 * Variables are prefixed with _ci_ to avoid symbol collision with

-	 * variables made available to view files

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	void

-	 */

-	function _ci_load($_ci_data)

-	{

-		// Set the default data variables

-		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)

-		{

-			$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];

-		}

-

-		// Set the path to the requested file

-		if ($_ci_path == '')

-		{

-			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);

-			$_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;

-			$_ci_path = $this->_ci_view_path.$_ci_file;

-		}

-		else

-		{

-			$_ci_x = explode('/', $_ci_path);

-			$_ci_file = end($_ci_x);

-		}

-		

-		if ( ! file_exists($_ci_path))

-		{

-			show_error('Unable to load the requested file: '.$_ci_file);

-		}

-	

-		// This allows anything loaded using $this->load (views, files, etc.)

-		// to become accessible from within the Controller and Model functions.

-		// Only needed when running PHP 5

-		

-		if ($this->_ci_is_instance())

-		{

-			$_ci_CI =& get_instance();

-			foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)

-			{

-				if ( ! isset($this->$_ci_key))

-				{

-					$this->$_ci_key =& $_ci_CI->$_ci_key;

-				}

-			}

-		}

-

-		/*

-		 * Extract and cache variables

-		 *

-		 * You can either set variables using the dedicated $this->load_vars()

-		 * function or via the second parameter of this function. We'll merge

-		 * the two types and cache them so that views that are embedded within

-		 * other views can have access to these variables.

-		 */	

-		if (is_array($_ci_vars))

-		{

-			$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);

-		}

-		extract($this->_ci_cached_vars);

-				

-		/*

-		 * Buffer the output

-		 *

-		 * We buffer the output for two reasons:

-		 * 1. Speed. You get a significant speed boost.

-		 * 2. So that the final rendered template can be

-		 * post-processed by the output class.  Why do we

-		 * need post processing?  For one thing, in order to

-		 * show the elapsed page load time.  Unless we

-		 * can intercept the content right before it's sent to

-		 * the browser and then stop the timer it won't be accurate.

-		 */

-		ob_start();

-				

-		// If the PHP installation does not support short tags we'll

-		// do a little string replacement, changing the short tags

-		// to standard PHP echo statements.

-		

-		if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)

-		{

-			echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));

-		}

-		else

-		{

-			include($_ci_path); // include() vs include_once() allows for multiple views with the same name

-		}

-		

-		log_message('debug', 'File loaded: '.$_ci_path);

-		

-		// Return the file data if requested

-		if ($_ci_return === TRUE)

-		{		

-			$buffer = ob_get_contents();

-			@ob_end_clean();

-			return $buffer;

-		}

-

-		/*

-		 * Flush the buffer... or buff the flusher?

-		 *

-		 * In order to permit views to be nested within

-		 * other views, we need to flush the content back out whenever

-		 * we are beyond the first level of output buffering so that

-		 * it can be seen and included properly by the first included

-		 * template and any subsequent ones. Oy!

-		 *

-		 */	

-		if (ob_get_level() > $this->_ci_ob_level + 1)

-		{

-			ob_end_flush();

-		}

-		else

-		{

-			// PHP 4 requires that we use a global

-			global $OUT;

-			$OUT->append_output(ob_get_contents());

-			@ob_end_clean();

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Load class

-	 *

-	 * This function loads the requested class.

-	 *

-	 * @access	private

-	 * @param 	string	the item that is being loaded

-	 * @param	mixed	any additional parameters

-	 * @param	string	an optional object name

-	 * @return 	void

-	 */

-	function _ci_load_class($class, $params = NULL, $object_name = NULL)

-	{	

-		// Get the class name, and while we're at it trim any slashes.  

-		// The directory path can be included as part of the class name, 

-		// but we don't want a leading slash

-		$class = str_replace(EXT, '', trim($class, '/'));

-	

-		// Was the path included with the class name?

-		// We look for a slash to determine this

-		$subdir = '';

-		if (strpos($class, '/') !== FALSE)

-		{

-			// explode the path so we can separate the filename from the path

-			$x = explode('/', $class);	

-			

-			// Reset the $class variable now that we know the actual filename

-			$class = end($x);

-			

-			// Kill the filename from the array

-			unset($x[count($x)-1]);

-			

-			// Glue the path back together, sans filename

-			$subdir = implode($x, '/').'/';

-		}

-

-		// We'll test for both lowercase and capitalized versions of the file name

-		foreach (array(ucfirst($class), strtolower($class)) as $class)

-		{

-			$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;

-

-			// Is this a class extension request?			

-			if (file_exists($subclass))

-			{

-				$baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;

-				

-				if ( ! file_exists($baseclass))

-				{

-					log_message('error', "Unable to load the requested class: ".$class);

-					show_error("Unable to load the requested class: ".$class);

-				}

-

-				// Safety:  Was the class already loaded by a previous call?

-				if (in_array($subclass, $this->_ci_loaded_files))

-				{

-					// Before we deem this to be a duplicate request, let's see

-					// if a custom object name is being supplied.  If so, we'll

-					// return a new instance of the object

-					if ( ! is_null($object_name))

-					{

-						$CI =& get_instance();

-						if ( ! isset($CI->$object_name))

-						{

-							return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);			

-						}

-					}

-					

-					$is_duplicate = TRUE;

-					log_message('debug', $class." class already loaded. Second attempt ignored.");

-					return;

-				}

-	

-				include_once($baseclass);				

-				include_once($subclass);

-				$this->_ci_loaded_files[] = $subclass;

-	

-				return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);			

-			}

-		

-			// Lets search for the requested library file and load it.

-			$is_duplicate = FALSE;		

-			for ($i = 1; $i < 3; $i++)

-			{

-				$path = ($i % 2) ? APPPATH : BASEPATH;	

-				$filepath = $path.'libraries/'.$subdir.$class.EXT;

-				

-				// Does the file exist?  No?  Bummer...

-				if ( ! file_exists($filepath))

-				{

-					continue;

-				}

-				

-				// Safety:  Was the class already loaded by a previous call?

-				if (in_array($filepath, $this->_ci_loaded_files))

-				{

-					// Before we deem this to be a duplicate request, let's see

-					// if a custom object name is being supplied.  If so, we'll

-					// return a new instance of the object

-					if ( ! is_null($object_name))

-					{

-						$CI =& get_instance();

-						if ( ! isset($CI->$object_name))

-						{

-							return $this->_ci_init_class($class, '', $params, $object_name);

-						}

-					}

-				

-					$is_duplicate = TRUE;

-					log_message('debug', $class." class already loaded. Second attempt ignored.");

-					return;

-				}

-				

-				include_once($filepath);

-				$this->_ci_loaded_files[] = $filepath;

-				return $this->_ci_init_class($class, '', $params, $object_name);

-			}

-		} // END FOREACH

-

-		// One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?

-		if ($subdir == '')

-		{

-			$path = strtolower($class).'/'.$class;

-			return $this->_ci_load_class($path, $params);

-		}

-		

-		// If we got this far we were unable to find the requested class.

-		// We do not issue errors if the load call failed due to a duplicate request

-		if ($is_duplicate == FALSE)

-		{

-			log_message('error', "Unable to load the requested class: ".$class);

-			show_error("Unable to load the requested class: ".$class);

-		}

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Instantiates a class

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @param	string	an optional object name

-	 * @return	null

-	 */

-	function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)

-	{	

-		// Is there an associated config file for this class?

-		if ($config === NULL)

-		{

-			// We test for both uppercase and lowercase, for servers that

-			// are case-sensitive with regard to file names

-			if (file_exists(APPPATH.'config/'.strtolower($class).EXT))

-			{

-				include_once(APPPATH.'config/'.strtolower($class).EXT);

-			}			

-			else

-			{

-				if (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))

-				{

-					include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);

-				}			

-			}

-		}

-		

-		if ($prefix == '')

-		{			

-			if (class_exists('CI_'.$class)) 

-			{

-				$name = 'CI_'.$class;

-			}

-			elseif (class_exists(config_item('subclass_prefix').$class)) 

-			{

-				$name = config_item('subclass_prefix').$class;

-			}

-			else

-			{

-				$name = $class;

-			}

-		}

-		else

-		{

-			$name = $prefix.$class;

-		}

-		

-		// Is the class name valid?

-		if ( ! class_exists($name))

-		{

-			log_message('error', "Non-existent class: ".$name);

-			show_error("Non-existent class: ".$class);

-		}

-		

-		// Set the variable name we will assign the class to

-		// Was a custom class name supplied?  If so we'll use it

-		$class = strtolower($class);

-		

-		if (is_null($object_name))

-		{

-			$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];

-		}

-		else

-		{

-			$classvar = $object_name;

-		}

-

-		// Save the class name and object name		

-		$this->_ci_classes[$class] = $classvar;

-

-		// Instantiate the class		

-		$CI =& get_instance();

-		if ($config !== NULL)

-		{

-			$CI->$classvar = new $name($config);

-		}

-		else

-		{		

-			$CI->$classvar = new $name;

-		}	

-	} 	

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Autoloader

-	 *

-	 * The config/autoload.php file contains an array that permits sub-systems,

-	 * libraries, plugins, and helpers to be loaded automatically.

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	void

-	 */

-	function _ci_autoloader()

-	{	

-		include_once(APPPATH.'config/autoload'.EXT);

-		

-		if ( ! isset($autoload))

-		{

-			return FALSE;

-		}

-		

-		// Load any custom config file

-		if (count($autoload['config']) > 0)

-		{			

-			$CI =& get_instance();

-			foreach ($autoload['config'] as $key => $val)

-			{

-				$CI->config->load($val);

-			}

-		}		

-

-		// Autoload plugins, helpers and languages

-		foreach (array('helper', 'plugin', 'language') as $type)

-		{			

-			if (isset($autoload[$type]) AND count($autoload[$type]) > 0)

-			{

-				$this->$type($autoload[$type]);

-			}		

-		}

-

-		// A little tweak to remain backward compatible

-		// The $autoload['core'] item was deprecated

-		if ( ! isset($autoload['libraries']))

-		{

-			$autoload['libraries'] = $autoload['core'];

-		}

-		

-		// Load libraries

-		if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)

-		{

-			// Load the database driver.

-			if (in_array('database', $autoload['libraries']))

-			{

-				$this->database();

-				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));

-			}

-

-			// Load scaffolding

-			if (in_array('scaffolding', $autoload['libraries']))

-			{

-				$this->scaffolding();

-				$autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));

-			}

-		

-			// Load all other libraries

-			foreach ($autoload['libraries'] as $item)

-			{

-				$this->library($item);

-			}

-		}		

-

-		// Autoload models

-		if (isset($autoload['model']))

-		{

-			$this->model($autoload['model']);

-		}

-

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Assign to Models

-	 *

-	 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)

-	 * will be available to models, if any exist.

-	 *

-	 * @access	private

-	 * @param	object

-	 * @return	array

-	 */

-	function _ci_assign_to_models()

-	{

-		if (count($this->_ci_models) == 0)

-		{

-			return;

-		}

-	

-		if ($this->_ci_is_instance())

-		{

-			$CI =& get_instance();

-			foreach ($this->_ci_models as $model)

-			{			

-				$CI->$model->_assign_libraries();

-			}

-		}

-		else

-		{		

-			foreach ($this->_ci_models as $model)

-			{			

-				$this->$model->_assign_libraries();

-			}

-		}

-	}  	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Object to Array

-	 *

-	 * Takes an object as input and converts the class variables to array key/vals

-	 *

-	 * @access	private

-	 * @param	object

-	 * @return	array

-	 */

-	function _ci_object_to_array($object)

-	{

-		return (is_object($object)) ? get_object_vars($object) : $object;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determines whether we should use the CI instance or $this

-	 *

-	 * @access	private

-	 * @return	bool

-	 */

-	function _ci_is_instance()

-	{

-		if ($this->_ci_is_php5 == TRUE)

-		{

-			return TRUE;

-		}

-	

-		global $CI;

-		return (is_object($CI)) ? TRUE : FALSE;

-	}

-

-}

-

-/* End of file Loader.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Loader Class
+ *
+ * Loads views and files
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @category	Loader
+ * @link		http://codeigniter.com/user_guide/libraries/loader.html
+ */
+class CI_Loader {
+
+	// All these are set automatically. Don't mess with them.
+	var $_ci_ob_level;
+	var $_ci_view_path		= '';
+	var $_ci_is_php5		= FALSE;
+	var $_ci_is_instance 	= FALSE; // Whether we should use $this or $CI =& get_instance()
+	var $_ci_cached_vars	= array();
+	var $_ci_classes		= array();
+	var $_ci_loaded_files	= array();
+	var $_ci_models			= array();
+	var $_ci_helpers		= array();
+	var $_ci_plugins		= array();
+	var $_ci_varmap			= array('unit_test' => 'unit', 'user_agent' => 'agent');
+	
+
+	/**
+	 * Constructor
+	 *
+	 * Sets the path to the view files and gets the initial output buffering level
+	 *
+	 * @access	public
+	 */
+	function CI_Loader()
+	{	
+		$this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
+		$this->_ci_view_path = APPPATH.'views/';
+		$this->_ci_ob_level  = ob_get_level();
+				
+		log_message('debug', "Loader Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Class Loader
+	 *
+	 * This function lets users load and instantiate classes.
+	 * It is designed to be called from a user's app controllers.
+	 *
+	 * @access	public
+	 * @param	string	the name of the class
+	 * @param	mixed	the optional parameters
+	 * @param	string	an optional object name
+	 * @return	void
+	 */	
+	function library($library = '', $params = NULL, $object_name = NULL)
+	{
+		if ($library == '')
+		{
+			return FALSE;
+		}
+
+		if ( ! is_null($params) AND ! is_array($params))
+		{
+			$params = NULL;
+		}
+
+		if (is_array($library))
+		{
+			foreach ($library as $class)
+			{
+				$this->_ci_load_class($class, $params, $object_name);
+			}
+		}
+		else
+		{
+			$this->_ci_load_class($library, $params, $object_name);
+		}
+		
+		$this->_ci_assign_to_models();
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Model Loader
+	 *
+	 * This function lets users load and instantiate models.
+	 *
+	 * @access	public
+	 * @param	string	the name of the class
+	 * @param	string	name for the model
+	 * @param	bool	database connection
+	 * @return	void
+	 */	
+	function model($model, $name = '', $db_conn = FALSE)
+	{		
+		if (is_array($model))
+		{
+			foreach($model as $babe)
+			{
+				$this->model($babe);	
+			}
+			return;
+		}
+
+		if ($model == '')
+		{
+			return;
+		}
+	
+		// Is the model in a sub-folder? If so, parse out the filename and path.
+		if (strpos($model, '/') === FALSE)
+		{
+			$path = '';
+		}
+		else
+		{
+			$x = explode('/', $model);
+			$model = end($x);			
+			unset($x[count($x)-1]);
+			$path = implode('/', $x).'/';
+		}
+	
+		if ($name == '')
+		{
+			$name = $model;
+		}
+		
+		if (in_array($name, $this->_ci_models, TRUE))
+		{
+			return;
+		}
+		
+		$CI =& get_instance();
+		if (isset($CI->$name))
+		{
+			show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
+		}
+	
+		$model = strtolower($model);
+		
+		if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
+		{
+			show_error('Unable to locate the model you have specified: '.$model);
+		}
+				
+		if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
+		{
+			if ($db_conn === TRUE)
+				$db_conn = '';
+		
+			$CI->load->database($db_conn, FALSE, TRUE);
+		}
+	
+		if ( ! class_exists('Model'))
+		{
+			load_class('Model', FALSE);
+		}
+
+		require_once(APPPATH.'models/'.$path.$model.EXT);
+
+		$model = ucfirst($model);
+				
+		$CI->$name = new $model();
+		$CI->$name->_assign_libraries();
+		
+		$this->_ci_models[] = $name;	
+	}
+		
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Database Loader
+	 *
+	 * @access	public
+	 * @param	string	the DB credentials
+	 * @param	bool	whether to return the DB object
+	 * @param	bool	whether to enable active record (this allows us to override the config setting)
+	 * @return	object
+	 */	
+	function database($params = '', $return = FALSE, $active_record = FALSE)
+	{
+		// Grab the super object
+		$CI =& get_instance();
+		
+		// Do we even need to load the database class?
+		if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
+		{
+			return FALSE;
+		}	
+	
+		require_once(BASEPATH.'database/DB'.EXT);
+
+		if ($return === TRUE)
+		{
+			return DB($params, $active_record);
+		}
+		
+		// Initialize the db variable.  Needed to prevent   
+		// reference errors with some configurations
+		$CI->db = '';
+		
+		// Load the DB class
+		$CI->db =& DB($params, $active_record);	
+		
+		// Assign the DB object to any existing models
+		$this->_ci_assign_to_models();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load the Utilities Class
+	 *
+	 * @access	public
+	 * @return	string		
+	 */		
+	function dbutil()
+	{
+		if ( ! class_exists('CI_DB'))
+		{
+			$this->database();
+		}
+		
+		$CI =& get_instance();
+
+		// for backwards compatibility, load dbforge so we can extend dbutils off it
+		// this use is deprecated and strongly discouraged
+		$CI->load->dbforge();
+	
+		require_once(BASEPATH.'database/DB_utility'.EXT);
+		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);
+		$class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
+
+		$CI->dbutil =& new $class();
+
+		$CI->load->_ci_assign_to_models();
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load the Database Forge Class
+	 *
+	 * @access	public
+	 * @return	string		
+	 */		
+	function dbforge()
+	{
+		if ( ! class_exists('CI_DB'))
+		{
+			$this->database();
+		}
+		
+		$CI =& get_instance();
+	
+		require_once(BASEPATH.'database/DB_forge'.EXT);
+		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);
+		$class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
+
+		$CI->dbforge = new $class();
+		
+		$CI->load->_ci_assign_to_models();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load View
+	 *
+	 * This function is used to load a "view" file.  It has three parameters:
+	 *
+	 * 1. The name of the "view" file to be included.
+	 * 2. An associative array of data to be extracted for use in the view.
+	 * 3. TRUE/FALSE - whether to return the data or load it.  In
+	 * some cases it's advantageous to be able to return data so that
+	 * a developer can process it in some way.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	array
+	 * @param	bool
+	 * @return	void
+	 */
+	function view($view, $vars = array(), $return = FALSE)
+	{
+		return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load File
+	 *
+	 * This is a generic file loader
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
+	function file($path, $return = FALSE)
+	{
+		return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Variables
+	 *
+	 * Once variables are set they become available within
+	 * the controller class and its "view" files.
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function vars($vars = array(), $val = '')
+	{
+		if ($val != '' AND is_string($vars))
+		{
+			$vars = array($vars => $val);
+		}
+	
+		$vars = $this->_ci_object_to_array($vars);
+	
+		if (is_array($vars) AND count($vars) > 0)
+		{
+			foreach ($vars as $key => $val)
+			{
+				$this->_ci_cached_vars[$key] = $val;
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load Helper
+	 *
+	 * This function loads the specified helper file.
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	void
+	 */
+	function helper($helpers = array())
+	{
+		if ( ! is_array($helpers))
+		{
+			$helpers = array($helpers);
+		}
+	
+		foreach ($helpers as $helper)
+		{		
+			$helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
+
+			if (isset($this->_ci_helpers[$helper]))
+			{
+				continue;
+			}
+			
+			$ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;
+
+			// Is this a helper extension request?			
+			if (file_exists($ext_helper))
+			{
+				$base_helper = BASEPATH.'helpers/'.$helper.EXT;
+				
+				if ( ! file_exists($base_helper))
+				{
+					show_error('Unable to load the requested file: helpers/'.$helper.EXT);
+				}
+				
+				include_once($ext_helper);
+				include_once($base_helper);
+			}
+			elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))
+			{ 
+				include_once(APPPATH.'helpers/'.$helper.EXT);
+			}
+			else
+			{		
+				if (file_exists(BASEPATH.'helpers/'.$helper.EXT))
+				{
+					include_once(BASEPATH.'helpers/'.$helper.EXT);
+				}
+				else
+				{
+					show_error('Unable to load the requested file: helpers/'.$helper.EXT);
+				}
+			}
+
+			$this->_ci_helpers[$helper] = TRUE;
+			log_message('debug', 'Helper loaded: '.$helper);	
+		}		
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load Helpers
+	 *
+	 * This is simply an alias to the above function in case the
+	 * user has written the plural form of this function.
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function helpers($helpers = array())
+	{
+		$this->helper($helpers);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load Plugin
+	 *
+	 * This function loads the specified plugin.
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function plugin($plugins = array())
+	{
+		if ( ! is_array($plugins))
+		{
+			$plugins = array($plugins);
+		}
+	
+		foreach ($plugins as $plugin)
+		{	
+			$plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');		
+
+			if (isset($this->_ci_plugins[$plugin]))
+			{
+				continue;
+			}
+
+			if (file_exists(APPPATH.'plugins/'.$plugin.EXT))
+			{
+				include_once(APPPATH.'plugins/'.$plugin.EXT);	
+			}
+			else
+			{
+				if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))
+				{
+					include_once(BASEPATH.'plugins/'.$plugin.EXT);	
+				}
+				else
+				{
+					show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
+				}
+			}
+			
+			$this->_ci_plugins[$plugin] = TRUE;
+			log_message('debug', 'Plugin loaded: '.$plugin);
+		}		
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Load Plugins
+	 *
+	 * This is simply an alias to the above function in case the
+	 * user has written the plural form of this function.
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function plugins($plugins = array())
+	{
+		$this->plugin($plugins);
+	}
+		
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Loads a language file
+	 *
+	 * @access	public
+	 * @param	array
+	 * @param	string
+	 * @return	void
+	 */
+	function language($file = array(), $lang = '')
+	{
+		$CI =& get_instance();
+
+		if ( ! is_array($file))
+		{
+			$file = array($file);
+		}
+
+		foreach ($file as $langfile)
+		{	
+			$CI->lang->load($langfile, $lang);
+		}
+	}
+
+	/**
+	 * Loads language files for scaffolding
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	arra
+	 */
+	function scaffold_language($file = '', $lang = '', $return = FALSE)
+	{
+		$CI =& get_instance();
+		return $CI->lang->load($file, $lang, $return);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Loads a config file
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+	{			
+		$CI =& get_instance();
+		$CI->config->load($file, $use_sections, $fail_gracefully);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Scaffolding Loader
+	 *
+	 * This initializing function works a bit different than the
+	 * others. It doesn't load the class.  Instead, it simply
+	 * sets a flag indicating that scaffolding is allowed to be
+	 * used.  The actual scaffolding function below is
+	 * called by the front controller based on whether the
+	 * second segment of the URL matches the "secret" scaffolding
+	 * word stored in the application/config/routes.php
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function scaffolding($table = '')
+	{		
+		if ($table === FALSE)
+		{
+			show_error('You must include the name of the table you would like to access when you initialize scaffolding');
+		}
+		
+		$CI =& get_instance();
+		$CI->_ci_scaffolding = TRUE;
+		$CI->_ci_scaff_table = $table;
+	}
+
+	// --------------------------------------------------------------------
+		
+	/**
+	 * Loader
+	 *
+	 * This function is used to load views and files.
+	 * Variables are prefixed with _ci_ to avoid symbol collision with
+	 * variables made available to view files
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	void
+	 */
+	function _ci_load($_ci_data)
+	{
+		// Set the default data variables
+		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
+		{
+			$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
+		}
+
+		// Set the path to the requested file
+		if ($_ci_path == '')
+		{
+			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
+			$_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
+			$_ci_path = $this->_ci_view_path.$_ci_file;
+		}
+		else
+		{
+			$_ci_x = explode('/', $_ci_path);
+			$_ci_file = end($_ci_x);
+		}
+		
+		if ( ! file_exists($_ci_path))
+		{
+			show_error('Unable to load the requested file: '.$_ci_file);
+		}
+	
+		// This allows anything loaded using $this->load (views, files, etc.)
+		// to become accessible from within the Controller and Model functions.
+		// Only needed when running PHP 5
+		
+		if ($this->_ci_is_instance())
+		{
+			$_ci_CI =& get_instance();
+			foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
+			{
+				if ( ! isset($this->$_ci_key))
+				{
+					$this->$_ci_key =& $_ci_CI->$_ci_key;
+				}
+			}
+		}
+
+		/*
+		 * Extract and cache variables
+		 *
+		 * You can either set variables using the dedicated $this->load_vars()
+		 * function or via the second parameter of this function. We'll merge
+		 * the two types and cache them so that views that are embedded within
+		 * other views can have access to these variables.
+		 */	
+		if (is_array($_ci_vars))
+		{
+			$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
+		}
+		extract($this->_ci_cached_vars);
+				
+		/*
+		 * Buffer the output
+		 *
+		 * We buffer the output for two reasons:
+		 * 1. Speed. You get a significant speed boost.
+		 * 2. So that the final rendered template can be
+		 * post-processed by the output class.  Why do we
+		 * need post processing?  For one thing, in order to
+		 * show the elapsed page load time.  Unless we
+		 * can intercept the content right before it's sent to
+		 * the browser and then stop the timer it won't be accurate.
+		 */
+		ob_start();
+				
+		// If the PHP installation does not support short tags we'll
+		// do a little string replacement, changing the short tags
+		// to standard PHP echo statements.
+		
+		if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
+		{
+			echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
+		}
+		else
+		{
+			include($_ci_path); // include() vs include_once() allows for multiple views with the same name
+		}
+		
+		log_message('debug', 'File loaded: '.$_ci_path);
+		
+		// Return the file data if requested
+		if ($_ci_return === TRUE)
+		{		
+			$buffer = ob_get_contents();
+			@ob_end_clean();
+			return $buffer;
+		}
+
+		/*
+		 * Flush the buffer... or buff the flusher?
+		 *
+		 * In order to permit views to be nested within
+		 * other views, we need to flush the content back out whenever
+		 * we are beyond the first level of output buffering so that
+		 * it can be seen and included properly by the first included
+		 * template and any subsequent ones. Oy!
+		 *
+		 */	
+		if (ob_get_level() > $this->_ci_ob_level + 1)
+		{
+			ob_end_flush();
+		}
+		else
+		{
+			// PHP 4 requires that we use a global
+			global $OUT;
+			$OUT->append_output(ob_get_contents());
+			@ob_end_clean();
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Load class
+	 *
+	 * This function loads the requested class.
+	 *
+	 * @access	private
+	 * @param 	string	the item that is being loaded
+	 * @param	mixed	any additional parameters
+	 * @param	string	an optional object name
+	 * @return 	void
+	 */
+	function _ci_load_class($class, $params = NULL, $object_name = NULL)
+	{	
+		// Get the class name, and while we're at it trim any slashes.  
+		// The directory path can be included as part of the class name, 
+		// but we don't want a leading slash
+		$class = str_replace(EXT, '', trim($class, '/'));
+	
+		// Was the path included with the class name?
+		// We look for a slash to determine this
+		$subdir = '';
+		if (strpos($class, '/') !== FALSE)
+		{
+			// explode the path so we can separate the filename from the path
+			$x = explode('/', $class);	
+			
+			// Reset the $class variable now that we know the actual filename
+			$class = end($x);
+			
+			// Kill the filename from the array
+			unset($x[count($x)-1]);
+			
+			// Glue the path back together, sans filename
+			$subdir = implode($x, '/').'/';
+		}
+
+		// We'll test for both lowercase and capitalized versions of the file name
+		foreach (array(ucfirst($class), strtolower($class)) as $class)
+		{
+			$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;
+
+			// Is this a class extension request?			
+			if (file_exists($subclass))
+			{
+				$baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;
+				
+				if ( ! file_exists($baseclass))
+				{
+					log_message('error', "Unable to load the requested class: ".$class);
+					show_error("Unable to load the requested class: ".$class);
+				}
+
+				// Safety:  Was the class already loaded by a previous call?
+				if (in_array($subclass, $this->_ci_loaded_files))
+				{
+					// Before we deem this to be a duplicate request, let's see
+					// if a custom object name is being supplied.  If so, we'll
+					// return a new instance of the object
+					if ( ! is_null($object_name))
+					{
+						$CI =& get_instance();
+						if ( ! isset($CI->$object_name))
+						{
+							return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);			
+						}
+					}
+					
+					$is_duplicate = TRUE;
+					log_message('debug', $class." class already loaded. Second attempt ignored.");
+					return;
+				}
+	
+				include_once($baseclass);				
+				include_once($subclass);
+				$this->_ci_loaded_files[] = $subclass;
+	
+				return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);			
+			}
+		
+			// Lets search for the requested library file and load it.
+			$is_duplicate = FALSE;		
+			for ($i = 1; $i < 3; $i++)
+			{
+				$path = ($i % 2) ? APPPATH : BASEPATH;	
+				$filepath = $path.'libraries/'.$subdir.$class.EXT;
+				
+				// Does the file exist?  No?  Bummer...
+				if ( ! file_exists($filepath))
+				{
+					continue;
+				}
+				
+				// Safety:  Was the class already loaded by a previous call?
+				if (in_array($filepath, $this->_ci_loaded_files))
+				{
+					// Before we deem this to be a duplicate request, let's see
+					// if a custom object name is being supplied.  If so, we'll
+					// return a new instance of the object
+					if ( ! is_null($object_name))
+					{
+						$CI =& get_instance();
+						if ( ! isset($CI->$object_name))
+						{
+							return $this->_ci_init_class($class, '', $params, $object_name);
+						}
+					}
+				
+					$is_duplicate = TRUE;
+					log_message('debug', $class." class already loaded. Second attempt ignored.");
+					return;
+				}
+				
+				include_once($filepath);
+				$this->_ci_loaded_files[] = $filepath;
+				return $this->_ci_init_class($class, '', $params, $object_name);
+			}
+		} // END FOREACH
+
+		// One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
+		if ($subdir == '')
+		{
+			$path = strtolower($class).'/'.$class;
+			return $this->_ci_load_class($path, $params);
+		}
+		
+		// If we got this far we were unable to find the requested class.
+		// We do not issue errors if the load call failed due to a duplicate request
+		if ($is_duplicate == FALSE)
+		{
+			log_message('error', "Unable to load the requested class: ".$class);
+			show_error("Unable to load the requested class: ".$class);
+		}
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Instantiates a class
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @param	string	an optional object name
+	 * @return	null
+	 */
+	function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
+	{	
+		// Is there an associated config file for this class?
+		if ($config === NULL)
+		{
+			// We test for both uppercase and lowercase, for servers that
+			// are case-sensitive with regard to file names
+			if (file_exists(APPPATH.'config/'.strtolower($class).EXT))
+			{
+				include_once(APPPATH.'config/'.strtolower($class).EXT);
+			}			
+			else
+			{
+				if (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))
+				{
+					include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);
+				}			
+			}
+		}
+		
+		if ($prefix == '')
+		{			
+			if (class_exists('CI_'.$class)) 
+			{
+				$name = 'CI_'.$class;
+			}
+			elseif (class_exists(config_item('subclass_prefix').$class)) 
+			{
+				$name = config_item('subclass_prefix').$class;
+			}
+			else
+			{
+				$name = $class;
+			}
+		}
+		else
+		{
+			$name = $prefix.$class;
+		}
+		
+		// Is the class name valid?
+		if ( ! class_exists($name))
+		{
+			log_message('error', "Non-existent class: ".$name);
+			show_error("Non-existent class: ".$class);
+		}
+		
+		// Set the variable name we will assign the class to
+		// Was a custom class name supplied?  If so we'll use it
+		$class = strtolower($class);
+		
+		if (is_null($object_name))
+		{
+			$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
+		}
+		else
+		{
+			$classvar = $object_name;
+		}
+
+		// Save the class name and object name		
+		$this->_ci_classes[$class] = $classvar;
+
+		// Instantiate the class		
+		$CI =& get_instance();
+		if ($config !== NULL)
+		{
+			$CI->$classvar = new $name($config);
+		}
+		else
+		{		
+			$CI->$classvar = new $name;
+		}	
+	} 	
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Autoloader
+	 *
+	 * The config/autoload.php file contains an array that permits sub-systems,
+	 * libraries, plugins, and helpers to be loaded automatically.
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	void
+	 */
+	function _ci_autoloader()
+	{	
+		include_once(APPPATH.'config/autoload'.EXT);
+		
+		if ( ! isset($autoload))
+		{
+			return FALSE;
+		}
+		
+		// Load any custom config file
+		if (count($autoload['config']) > 0)
+		{			
+			$CI =& get_instance();
+			foreach ($autoload['config'] as $key => $val)
+			{
+				$CI->config->load($val);
+			}
+		}		
+
+		// Autoload plugins, helpers and languages
+		foreach (array('helper', 'plugin', 'language') as $type)
+		{			
+			if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
+			{
+				$this->$type($autoload[$type]);
+			}		
+		}
+
+		// A little tweak to remain backward compatible
+		// The $autoload['core'] item was deprecated
+		if ( ! isset($autoload['libraries']))
+		{
+			$autoload['libraries'] = $autoload['core'];
+		}
+		
+		// Load libraries
+		if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
+		{
+			// Load the database driver.
+			if (in_array('database', $autoload['libraries']))
+			{
+				$this->database();
+				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
+			}
+
+			// Load scaffolding
+			if (in_array('scaffolding', $autoload['libraries']))
+			{
+				$this->scaffolding();
+				$autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));
+			}
+		
+			// Load all other libraries
+			foreach ($autoload['libraries'] as $item)
+			{
+				$this->library($item);
+			}
+		}		
+
+		// Autoload models
+		if (isset($autoload['model']))
+		{
+			$this->model($autoload['model']);
+		}
+
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Assign to Models
+	 *
+	 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
+	 * will be available to models, if any exist.
+	 *
+	 * @access	private
+	 * @param	object
+	 * @return	array
+	 */
+	function _ci_assign_to_models()
+	{
+		if (count($this->_ci_models) == 0)
+		{
+			return;
+		}
+	
+		if ($this->_ci_is_instance())
+		{
+			$CI =& get_instance();
+			foreach ($this->_ci_models as $model)
+			{			
+				$CI->$model->_assign_libraries();
+			}
+		}
+		else
+		{		
+			foreach ($this->_ci_models as $model)
+			{			
+				$this->$model->_assign_libraries();
+			}
+		}
+	}  	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Object to Array
+	 *
+	 * Takes an object as input and converts the class variables to array key/vals
+	 *
+	 * @access	private
+	 * @param	object
+	 * @return	array
+	 */
+	function _ci_object_to_array($object)
+	{
+		return (is_object($object)) ? get_object_vars($object) : $object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determines whether we should use the CI instance or $this
+	 *
+	 * @access	private
+	 * @return	bool
+	 */
+	function _ci_is_instance()
+	{
+		if ($this->_ci_is_php5 == TRUE)
+		{
+			return TRUE;
+		}
+	
+		global $CI;
+		return (is_object($CI)) ? TRUE : FALSE;
+	}
+
+}
+
+/* End of file Loader.php */
 /* Location: ./system/libraries/Loader.php */
\ No newline at end of file
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 811c873..326edaa 100644
--- a/system/libraries/Log.php
+++ b/system/libraries/Log.php
@@ -1,117 +1,117 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Logging Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Logging

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/general/errors.html

- */

-class CI_Log {

-

-	var $log_path;

-	var $_threshold	= 1;

-	var $_date_fmt	= 'Y-m-d H:i:s';

-	var $_enabled	= TRUE;

-	var $_levels	= array('ERROR' => '1', 'DEBUG' => '2',  'INFO' => '3', 'ALL' => '4');

-

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 */

-	function CI_Log()

-	{

-		$config =& get_config();

-		

-		$this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/';

-		

-		if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path))

-		{

-			$this->_enabled = FALSE;

-		}

-		

-		if (is_numeric($config['log_threshold']))

-		{

-			$this->_threshold = $config['log_threshold'];

-		}

-			

-		if ($config['log_date_format'] != '')

-		{

-			$this->_date_fmt = $config['log_date_format'];

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Write Log File

-	 *

-	 * Generally this function will be called using the global log_message() function

-	 *

-	 * @access	public

-	 * @param	string	the error level

-	 * @param	string	the error message

-	 * @param	bool	whether the error is a native PHP error

-	 * @return	bool

-	 */		

-	function write_log($level = 'error', $msg, $php_error = FALSE)

-	{		

-		if ($this->_enabled === FALSE)

-		{

-			return FALSE;

-		}

-	

-		$level = strtoupper($level);

-		

-		if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))

-		{

-			return FALSE;

-		}

-	

-		$filepath = $this->log_path.'log-'.date('Y-m-d').EXT;

-		$message  = '';

-		

-		if ( ! file_exists($filepath))

-		{

-			$message .= "<"."?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n";

-		}

-			

-		if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE))

-		{

-			return FALSE;

-		}

-

-		$message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n";

-		

-		flock($fp, LOCK_EX);	

-		fwrite($fp, $message);

-		flock($fp, LOCK_UN);

-		fclose($fp);

-	

-		@chmod($filepath, FILE_WRITE_MODE); 		

-		return TRUE;

-	}

-

-}

-// END Log Class

-

-/* End of file Log.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Logging Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Logging
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/general/errors.html
+ */
+class CI_Log {
+
+	var $log_path;
+	var $_threshold	= 1;
+	var $_date_fmt	= 'Y-m-d H:i:s';
+	var $_enabled	= TRUE;
+	var $_levels	= array('ERROR' => '1', 'DEBUG' => '2',  'INFO' => '3', 'ALL' => '4');
+
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 */
+	function CI_Log()
+	{
+		$config =& get_config();
+		
+		$this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/';
+		
+		if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path))
+		{
+			$this->_enabled = FALSE;
+		}
+		
+		if (is_numeric($config['log_threshold']))
+		{
+			$this->_threshold = $config['log_threshold'];
+		}
+			
+		if ($config['log_date_format'] != '')
+		{
+			$this->_date_fmt = $config['log_date_format'];
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Write Log File
+	 *
+	 * Generally this function will be called using the global log_message() function
+	 *
+	 * @access	public
+	 * @param	string	the error level
+	 * @param	string	the error message
+	 * @param	bool	whether the error is a native PHP error
+	 * @return	bool
+	 */		
+	function write_log($level = 'error', $msg, $php_error = FALSE)
+	{		
+		if ($this->_enabled === FALSE)
+		{
+			return FALSE;
+		}
+	
+		$level = strtoupper($level);
+		
+		if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
+		{
+			return FALSE;
+		}
+	
+		$filepath = $this->log_path.'log-'.date('Y-m-d').EXT;
+		$message  = '';
+		
+		if ( ! file_exists($filepath))
+		{
+			$message .= "<"."?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n";
+		}
+			
+		if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE))
+		{
+			return FALSE;
+		}
+
+		$message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n";
+		
+		flock($fp, LOCK_EX);	
+		fwrite($fp, $message);
+		flock($fp, LOCK_UN);
+		fclose($fp);
+	
+		@chmod($filepath, FILE_WRITE_MODE); 		
+		return TRUE;
+	}
+
+}
+// END Log Class
+
+/* End of file Log.php */
 /* Location: ./system/libraries/Log.php */
\ No newline at end of file
diff --git a/system/libraries/Model.php b/system/libraries/Model.php
index 1d3cbdf..c4cba56 100644
--- a/system/libraries/Model.php
+++ b/system/libraries/Model.php
@@ -1,83 +1,83 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Model Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/config.html

- */

-class Model {

-

-	var $_parent_name = '';

-

-	/**

-	 * Constructor

-	 *

-	 * @access public

-	 */

-	function Model()

-	{

-		// If the magic __get() or __set() methods are used in a Model references can't be used.

-		$this->_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE );

-		

-		// We don't want to assign the model object to itself when using the

-		// assign_libraries function below so we'll grab the name of the model parent

-		$this->_parent_name = ucfirst(get_class($this));

-		

-		log_message('debug', "Model Class Initialized");

-	}

-

-	/**

-	 * Assign Libraries

-	 *

-	 * Creates local references to all currently instantiated objects

-	 * so that any syntax that can be legally used in a controller

-	 * can be used within models.  

-	 *

-	 * @access private

-	 */	

-	function _assign_libraries($use_reference = TRUE)

-	{

-		$CI =& get_instance();				

-		foreach (array_keys(get_object_vars($CI)) as $key)

-		{

-			if ( ! isset($this->$key) AND $key != $this->_parent_name)

-			{			

-				// In some cases using references can cause

-				// problems so we'll conditionally use them

-				if ($use_reference == TRUE)

-				{

-					$this->$key = NULL; // Needed to prevent reference errors with some configurations

-					$this->$key =& $CI->$key;

-				}

-				else

-				{

-					$this->$key = $CI->$key;

-				}

-			}

-		}		

-	}

-

-}

-// END Model Class

-

-/* End of file Model.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Model Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/config.html
+ */
+class Model {
+
+	var $_parent_name = '';
+
+	/**
+	 * Constructor
+	 *
+	 * @access public
+	 */
+	function Model()
+	{
+		// If the magic __get() or __set() methods are used in a Model references can't be used.
+		$this->_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE );
+		
+		// We don't want to assign the model object to itself when using the
+		// assign_libraries function below so we'll grab the name of the model parent
+		$this->_parent_name = ucfirst(get_class($this));
+		
+		log_message('debug', "Model Class Initialized");
+	}
+
+	/**
+	 * Assign Libraries
+	 *
+	 * Creates local references to all currently instantiated objects
+	 * so that any syntax that can be legally used in a controller
+	 * can be used within models.  
+	 *
+	 * @access private
+	 */	
+	function _assign_libraries($use_reference = TRUE)
+	{
+		$CI =& get_instance();				
+		foreach (array_keys(get_object_vars($CI)) as $key)
+		{
+			if ( ! isset($this->$key) AND $key != $this->_parent_name)
+			{			
+				// In some cases using references can cause
+				// problems so we'll conditionally use them
+				if ($use_reference == TRUE)
+				{
+					$this->$key = NULL; // Needed to prevent reference errors with some configurations
+					$this->$key =& $CI->$key;
+				}
+				else
+				{
+					$this->$key = $CI->$key;
+				}
+			}
+		}		
+	}
+
+}
+// END Model Class
+
+/* End of file Model.php */
 /* Location: ./system/libraries/Model.php */
\ No newline at end of file
diff --git a/system/libraries/Output.php b/system/libraries/Output.php
index 98a941a..b93963a 100644
--- a/system/libraries/Output.php
+++ b/system/libraries/Output.php
@@ -1,478 +1,478 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Output Class

- *

- * Responsible for sending final output to browser

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Output

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/output.html

- */

-class CI_Output {

-

-	var $final_output;

-	var $cache_expiration	= 0;

-	var $headers 			= array();

-	var $enable_profiler 	= FALSE;

-

-

-	function CI_Output()

-	{

-		log_message('debug', "Output Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get Output

-	 *

-	 * Returns the current output string

-	 *

-	 * @access	public

-	 * @return	string

-	 */	

-	function get_output()

-	{

-		return $this->final_output;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Output

-	 *

-	 * Sets the output string

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_output($output)

-	{

-		$this->final_output = $output;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Append Output

-	 *

-	 * Appends data onto the output string

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function append_output($output)

-	{

-		if ($this->final_output == '')

-		{

-			$this->final_output = $output;

-		}

-		else

-		{

-			$this->final_output .= $output;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set Header

-	 *

-	 * Lets you set a server header which will be outputted with the final display.

-	 *

-	 * Note:  If a file is cached, headers will not be sent.  We need to figure out

-	 * how to permit header data to be saved with the cache data...

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_header($header, $replace = TRUE)

-	{

-		$this->headers[] = array($header, $replace);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set HTTP Status Header

-	 *

-	 * @access	public

-	 * @param	int 	the status code

-	 * @param	string	

-	 * @return	void

-	 */	

-	function set_status_header($code = '200', $text = '')

-	{

-		$stati = array(

-							'200'	=> 'OK',

-							'201'	=> 'Created',

-							'202'	=> 'Accepted',

-							'203'	=> 'Non-Authoritative Information',

-							'204'	=> 'No Content',

-							'205'	=> 'Reset Content',

-							'206'	=> 'Partial Content',

-							

-							'300'	=> 'Multiple Choices',

-							'301'	=> 'Moved Permanently',

-							'302'	=> 'Found',

-							'304'	=> 'Not Modified',

-							'305'	=> 'Use Proxy',

-							'307'	=> 'Temporary Redirect',

-							

-							'400'	=> 'Bad Request',

-							'401'	=> 'Unauthorized',

-							'403'	=> 'Forbidden',

-							'404'	=> 'Not Found',

-							'405'	=> 'Method Not Allowed',

-							'406'	=> 'Not Acceptable',

-							'407'	=> 'Proxy Authentication Required',

-							'408'	=> 'Request Timeout',

-							'409'	=> 'Conflict',

-							'410'	=> 'Gone',

-							'411'	=> 'Length Required',

-							'412'	=> 'Precondition Failed',

-							'413'	=> 'Request Entity Too Large',

-							'414'	=> 'Request-URI Too Long',

-							'415'	=> 'Unsupported Media Type',

-							'416'	=> 'Requested Range Not Satisfiable',

-							'417'	=> 'Expectation Failed',

-		

-							'500'	=> 'Internal Server Error',

-							'501'	=> 'Not Implemented',

-							'502'	=> 'Bad Gateway',

-							'503'	=> 'Service Unavailable',

-							'504'	=> 'Gateway Timeout',

-							'505'	=> 'HTTP Version Not Supported'

-						);

-

-		if ($code == '' OR ! is_numeric($code))

-		{

-			show_error('Status codes must be numeric');

-		}

-

-		if (isset($stati[$code]) AND $text == '')

-		{				

-			$text = $stati[$code];

-		}

-		

-		if ($text == '')

-		{

-			show_error('No status text available.  Please check your status code number or supply your own message text.');

-		}

-		

-		$server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;

-	

-		if (substr(php_sapi_name(), 0, 3) == 'cgi')

-		{

-			header("Status: {$code} {$text}", TRUE);

-		}

-		elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')

-		{

-			header($server_protocol." {$code} {$text}", TRUE, $code);

-		}

-		else

-		{

-			header("HTTP/1.1 {$code} {$text}", TRUE, $code);

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Enable/disable Profiler

-	 *

-	 * @access	public

-	 * @param	bool

-	 * @return	void

-	 */	

-	function enable_profiler($val = TRUE)

-	{

-		$this->enable_profiler = (is_bool($val)) ? $val : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Cache

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */	

-	function cache($time)

-	{

-		$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Display Output

-	 *

-	 * All "view" data is automatically put into this variable by the controller class:

-	 *

-	 * $this->final_output

-	 *

-	 * This function sends the finalized output data to the browser along

-	 * with any server headers and profile data.  It also stops the

-	 * benchmark timer so the page rendering speed and memory usage can be shown.

-	 *

-	 * @access	public

-	 * @return	mixed

-	 */		

-	function _display($output = '')

-	{	

-		// Note:  We use globals because we can't use $CI =& get_instance()

-		// since this function is sometimes called by the caching mechanism,

-		// which happens before the CI super object is available.

-		global $BM, $CFG;

-		

-		// --------------------------------------------------------------------

-		

-		// Set the output data

-		if ($output == '')

-		{

-			$output =& $this->final_output;

-		}

-		

-		// --------------------------------------------------------------------

-		

-		// Do we need to write a cache file?

-		if ($this->cache_expiration > 0)

-		{

-			$this->_write_cache($output);

-		}

-		

-		// --------------------------------------------------------------------

-

-		// Parse out the elapsed time and memory usage,

-		// then swap the pseudo-variables with the data

-

-		$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');		

-		$output = str_replace('{elapsed_time}', $elapsed, $output);

-		

-		$memory	 = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';

-		$output = str_replace('{memory_usage}', $memory, $output);		

-

-		// --------------------------------------------------------------------

-		

-		// Is compression requested?

-		if ($CFG->item('compress_output') === TRUE)

-		{

-			if (extension_loaded('zlib'))

-			{

-				if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)

-				{

-					ob_start('ob_gzhandler');

-				}

-			}

-		}

-

-		// --------------------------------------------------------------------

-		

-		// Are there any server headers to send?

-		if (count($this->headers) > 0)

-		{

-			foreach ($this->headers as $header)

-			{

-				@header($header[0], $header[1]);

-			}

-		}		

-

-		// --------------------------------------------------------------------

-		

-		// Does the get_instance() function exist?

-		// If not we know we are dealing with a cache file so we'll

-		// simply echo out the data and exit.

-		if ( ! function_exists('get_instance'))

-		{

-			echo $output;

-			log_message('debug', "Final output sent to browser");

-			log_message('debug', "Total execution time: ".$elapsed);

-			return TRUE;

-		}

-	

-		// --------------------------------------------------------------------

-

-		// Grab the super object.  We'll need it in a moment...

-		$CI =& get_instance();

-		

-		// Do we need to generate profile data?

-		// If so, load the Profile class and run it.

-		if ($this->enable_profiler == TRUE)

-		{

-			$CI->load->library('profiler');				

-										

-			// If the output data contains closing </body> and </html> tags

-			// we will remove them and add them back after we insert the profile data

-			if (preg_match("|</body>.*?</html>|is", $output))

-			{

-				$output  = preg_replace("|</body>.*?</html>|is", '', $output);

-				$output .= $CI->profiler->run();

-				$output .= '</body></html>';

-			}

-			else

-			{

-				$output .= $CI->profiler->run();

-			}

-		}

-		

-		// --------------------------------------------------------------------

-

-		// Does the controller contain a function named _output()?

-		// If so send the output there.  Otherwise, echo it.

-		if (method_exists($CI, '_output'))

-		{

-			$CI->_output($output);

-		}

-		else

-		{

-			echo $output;  // Send it to the browser!

-		}

-		

-		log_message('debug', "Final output sent to browser");

-		log_message('debug', "Total execution time: ".$elapsed);		

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Write a Cache File

-	 *

-	 * @access	public

-	 * @return	void

-	 */	

-	function _write_cache($output)

-	{

-		$CI =& get_instance();	

-		$path = $CI->config->item('cache_path');

-	

-		$cache_path = ($path == '') ? BASEPATH.'cache/' : $path;

-		

-		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))

-		{

-			return;

-		}

-		

-		$uri =	$CI->config->item('base_url').

-				$CI->config->item('index_page').

-				$CI->uri->uri_string();

-		

-		$cache_path .= md5($uri);

-

-		if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))

-		{

-			log_message('error', "Unable to write cache file: ".$cache_path);

-			return;

-		}

-		

-		$expire = time() + ($this->cache_expiration * 60);

-		

-		if (flock($fp, LOCK_EX))

-		{

-			fwrite($fp, $expire.'TS--->'.$output);

-			flock($fp, LOCK_UN);

-		}

-		else

-		{

-			log_message('error', "Unable to secure a file lock for file at: ".$cache_path);

-			return;

-		}

-		fclose($fp);

-		@chmod($cache_path, DIR_WRITE_MODE);

-

-		log_message('debug', "Cache file written: ".$cache_path);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Update/serve a cached file

-	 *

-	 * @access	public

-	 * @return	void

-	 */	

-	function _display_cache(&$CFG, &$URI)

-	{

-		$cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');

-			

-		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))

-		{

-			return FALSE;

-		}

-		

-		// Build the file path.  The file name is an MD5 hash of the full URI

-		$uri =	$CFG->item('base_url').

-				$CFG->item('index_page').

-				$URI->uri_string;

-				

-		$filepath = $cache_path.md5($uri);

-		

-		if ( ! @file_exists($filepath))

-		{

-			return FALSE;

-		}

-	

-		if ( ! $fp = @fopen($filepath, FOPEN_READ))

-		{

-			return FALSE;

-		}

-			

-		flock($fp, LOCK_SH);

-		

-		$cache = '';

-		if (filesize($filepath) > 0)

-		{

-			$cache = fread($fp, filesize($filepath));

-		}

-	

-		flock($fp, LOCK_UN);

-		fclose($fp);

-					

-		// Strip out the embedded timestamp		

-		if ( ! preg_match("/(\d+TS--->)/", $cache, $match))

-		{

-			return FALSE;

-		}

-		

-		// Has the file expired? If so we'll delete it.

-		if (time() >= trim(str_replace('TS--->', '', $match['1'])))

-		{ 		

-			@unlink($filepath);

-			log_message('debug', "Cache file has expired. File deleted");

-			return FALSE;

-		}

-

-		// Display the cache

-		$this->_display(str_replace($match['0'], '', $cache));

-		log_message('debug', "Cache file is current. Sending it to browser.");		

-		return TRUE;

-	}

-

-

-}

-// END Output Class

-

-/* End of file Output.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Output Class
+ *
+ * Responsible for sending final output to browser
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Output
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/output.html
+ */
+class CI_Output {
+
+	var $final_output;
+	var $cache_expiration	= 0;
+	var $headers 			= array();
+	var $enable_profiler 	= FALSE;
+
+
+	function CI_Output()
+	{
+		log_message('debug', "Output Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get Output
+	 *
+	 * Returns the current output string
+	 *
+	 * @access	public
+	 * @return	string
+	 */	
+	function get_output()
+	{
+		return $this->final_output;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Output
+	 *
+	 * Sets the output string
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_output($output)
+	{
+		$this->final_output = $output;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Append Output
+	 *
+	 * Appends data onto the output string
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function append_output($output)
+	{
+		if ($this->final_output == '')
+		{
+			$this->final_output = $output;
+		}
+		else
+		{
+			$this->final_output .= $output;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Header
+	 *
+	 * Lets you set a server header which will be outputted with the final display.
+	 *
+	 * Note:  If a file is cached, headers will not be sent.  We need to figure out
+	 * how to permit header data to be saved with the cache data...
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_header($header, $replace = TRUE)
+	{
+		$this->headers[] = array($header, $replace);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set HTTP Status Header
+	 *
+	 * @access	public
+	 * @param	int 	the status code
+	 * @param	string	
+	 * @return	void
+	 */	
+	function set_status_header($code = '200', $text = '')
+	{
+		$stati = array(
+							'200'	=> 'OK',
+							'201'	=> 'Created',
+							'202'	=> 'Accepted',
+							'203'	=> 'Non-Authoritative Information',
+							'204'	=> 'No Content',
+							'205'	=> 'Reset Content',
+							'206'	=> 'Partial Content',
+							
+							'300'	=> 'Multiple Choices',
+							'301'	=> 'Moved Permanently',
+							'302'	=> 'Found',
+							'304'	=> 'Not Modified',
+							'305'	=> 'Use Proxy',
+							'307'	=> 'Temporary Redirect',
+							
+							'400'	=> 'Bad Request',
+							'401'	=> 'Unauthorized',
+							'403'	=> 'Forbidden',
+							'404'	=> 'Not Found',
+							'405'	=> 'Method Not Allowed',
+							'406'	=> 'Not Acceptable',
+							'407'	=> 'Proxy Authentication Required',
+							'408'	=> 'Request Timeout',
+							'409'	=> 'Conflict',
+							'410'	=> 'Gone',
+							'411'	=> 'Length Required',
+							'412'	=> 'Precondition Failed',
+							'413'	=> 'Request Entity Too Large',
+							'414'	=> 'Request-URI Too Long',
+							'415'	=> 'Unsupported Media Type',
+							'416'	=> 'Requested Range Not Satisfiable',
+							'417'	=> 'Expectation Failed',
+		
+							'500'	=> 'Internal Server Error',
+							'501'	=> 'Not Implemented',
+							'502'	=> 'Bad Gateway',
+							'503'	=> 'Service Unavailable',
+							'504'	=> 'Gateway Timeout',
+							'505'	=> 'HTTP Version Not Supported'
+						);
+
+		if ($code == '' OR ! is_numeric($code))
+		{
+			show_error('Status codes must be numeric');
+		}
+
+		if (isset($stati[$code]) AND $text == '')
+		{				
+			$text = $stati[$code];
+		}
+		
+		if ($text == '')
+		{
+			show_error('No status text available.  Please check your status code number or supply your own message text.');
+		}
+		
+		$server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
+	
+		if (substr(php_sapi_name(), 0, 3) == 'cgi')
+		{
+			header("Status: {$code} {$text}", TRUE);
+		}
+		elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
+		{
+			header($server_protocol." {$code} {$text}", TRUE, $code);
+		}
+		else
+		{
+			header("HTTP/1.1 {$code} {$text}", TRUE, $code);
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Enable/disable Profiler
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	void
+	 */	
+	function enable_profiler($val = TRUE)
+	{
+		$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Cache
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */	
+	function cache($time)
+	{
+		$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Display Output
+	 *
+	 * All "view" data is automatically put into this variable by the controller class:
+	 *
+	 * $this->final_output
+	 *
+	 * This function sends the finalized output data to the browser along
+	 * with any server headers and profile data.  It also stops the
+	 * benchmark timer so the page rendering speed and memory usage can be shown.
+	 *
+	 * @access	public
+	 * @return	mixed
+	 */		
+	function _display($output = '')
+	{	
+		// Note:  We use globals because we can't use $CI =& get_instance()
+		// since this function is sometimes called by the caching mechanism,
+		// which happens before the CI super object is available.
+		global $BM, $CFG;
+		
+		// --------------------------------------------------------------------
+		
+		// Set the output data
+		if ($output == '')
+		{
+			$output =& $this->final_output;
+		}
+		
+		// --------------------------------------------------------------------
+		
+		// Do we need to write a cache file?
+		if ($this->cache_expiration > 0)
+		{
+			$this->_write_cache($output);
+		}
+		
+		// --------------------------------------------------------------------
+
+		// Parse out the elapsed time and memory usage,
+		// then swap the pseudo-variables with the data
+
+		$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');		
+		$output = str_replace('{elapsed_time}', $elapsed, $output);
+		
+		$memory	 = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
+		$output = str_replace('{memory_usage}', $memory, $output);		
+
+		// --------------------------------------------------------------------
+		
+		// Is compression requested?
+		if ($CFG->item('compress_output') === TRUE)
+		{
+			if (extension_loaded('zlib'))
+			{
+				if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
+				{
+					ob_start('ob_gzhandler');
+				}
+			}
+		}
+
+		// --------------------------------------------------------------------
+		
+		// Are there any server headers to send?
+		if (count($this->headers) > 0)
+		{
+			foreach ($this->headers as $header)
+			{
+				@header($header[0], $header[1]);
+			}
+		}		
+
+		// --------------------------------------------------------------------
+		
+		// Does the get_instance() function exist?
+		// If not we know we are dealing with a cache file so we'll
+		// simply echo out the data and exit.
+		if ( ! function_exists('get_instance'))
+		{
+			echo $output;
+			log_message('debug', "Final output sent to browser");
+			log_message('debug', "Total execution time: ".$elapsed);
+			return TRUE;
+		}
+	
+		// --------------------------------------------------------------------
+
+		// Grab the super object.  We'll need it in a moment...
+		$CI =& get_instance();
+		
+		// Do we need to generate profile data?
+		// If so, load the Profile class and run it.
+		if ($this->enable_profiler == TRUE)
+		{
+			$CI->load->library('profiler');				
+										
+			// If the output data contains closing </body> and </html> tags
+			// we will remove them and add them back after we insert the profile data
+			if (preg_match("|</body>.*?</html>|is", $output))
+			{
+				$output  = preg_replace("|</body>.*?</html>|is", '', $output);
+				$output .= $CI->profiler->run();
+				$output .= '</body></html>';
+			}
+			else
+			{
+				$output .= $CI->profiler->run();
+			}
+		}
+		
+		// --------------------------------------------------------------------
+
+		// Does the controller contain a function named _output()?
+		// If so send the output there.  Otherwise, echo it.
+		if (method_exists($CI, '_output'))
+		{
+			$CI->_output($output);
+		}
+		else
+		{
+			echo $output;  // Send it to the browser!
+		}
+		
+		log_message('debug', "Final output sent to browser");
+		log_message('debug', "Total execution time: ".$elapsed);		
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Write a Cache File
+	 *
+	 * @access	public
+	 * @return	void
+	 */	
+	function _write_cache($output)
+	{
+		$CI =& get_instance();	
+		$path = $CI->config->item('cache_path');
+	
+		$cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
+		
+		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
+		{
+			return;
+		}
+		
+		$uri =	$CI->config->item('base_url').
+				$CI->config->item('index_page').
+				$CI->uri->uri_string();
+		
+		$cache_path .= md5($uri);
+
+		if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
+		{
+			log_message('error', "Unable to write cache file: ".$cache_path);
+			return;
+		}
+		
+		$expire = time() + ($this->cache_expiration * 60);
+		
+		if (flock($fp, LOCK_EX))
+		{
+			fwrite($fp, $expire.'TS--->'.$output);
+			flock($fp, LOCK_UN);
+		}
+		else
+		{
+			log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
+			return;
+		}
+		fclose($fp);
+		@chmod($cache_path, DIR_WRITE_MODE);
+
+		log_message('debug', "Cache file written: ".$cache_path);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Update/serve a cached file
+	 *
+	 * @access	public
+	 * @return	void
+	 */	
+	function _display_cache(&$CFG, &$URI)
+	{
+		$cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
+			
+		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
+		{
+			return FALSE;
+		}
+		
+		// Build the file path.  The file name is an MD5 hash of the full URI
+		$uri =	$CFG->item('base_url').
+				$CFG->item('index_page').
+				$URI->uri_string;
+				
+		$filepath = $cache_path.md5($uri);
+		
+		if ( ! @file_exists($filepath))
+		{
+			return FALSE;
+		}
+	
+		if ( ! $fp = @fopen($filepath, FOPEN_READ))
+		{
+			return FALSE;
+		}
+			
+		flock($fp, LOCK_SH);
+		
+		$cache = '';
+		if (filesize($filepath) > 0)
+		{
+			$cache = fread($fp, filesize($filepath));
+		}
+	
+		flock($fp, LOCK_UN);
+		fclose($fp);
+					
+		// Strip out the embedded timestamp		
+		if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
+		{
+			return FALSE;
+		}
+		
+		// Has the file expired? If so we'll delete it.
+		if (time() >= trim(str_replace('TS--->', '', $match['1'])))
+		{ 		
+			@unlink($filepath);
+			log_message('debug', "Cache file has expired. File deleted");
+			return FALSE;
+		}
+
+		// Display the cache
+		$this->_display(str_replace($match['0'], '', $cache));
+		log_message('debug', "Cache file is current. Sending it to browser.");		
+		return TRUE;
+	}
+
+
+}
+// END Output Class
+
+/* End of file Output.php */
 /* Location: ./system/libraries/Output.php */
\ No newline at end of file
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index ed912d2..09b5bec 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -1,244 +1,244 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Pagination Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Pagination

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/pagination.html

- */

-class CI_Pagination {

-

-	var $base_url			= ''; // The page we are linking to

-	var $total_rows  		= ''; // Total number of items (database results)

-	var $per_page	 		= 10; // Max number of items you want shown per page

-	var $num_links			=  2; // Number of "digit" links to show before/after the currently viewed page

-	var $cur_page	 		=  0; // The current page being viewed

-	var $first_link   		= '&lsaquo; First';

-	var $next_link			= '&gt;';

-	var $prev_link			= '&lt;';

-	var $last_link			= 'Last &rsaquo;';

-	var $uri_segment		= 3;

-	var $full_tag_open		= '';

-	var $full_tag_close		= '';

-	var $first_tag_open		= '';

-	var $first_tag_close	= '&nbsp;';

-	var $last_tag_open		= '&nbsp;';

-	var $last_tag_close		= '';

-	var $cur_tag_open		= '&nbsp;<strong>';

-	var $cur_tag_close		= '</strong>';

-	var $next_tag_open		= '&nbsp;';

-	var $next_tag_close		= '&nbsp;';

-	var $prev_tag_open		= '&nbsp;';

-	var $prev_tag_close		= '';

-	var $num_tag_open		= '&nbsp;';

-	var $num_tag_close		= '';

-	var $page_query_string	= FALSE;

-	var $query_string_segment = 'per_page';

-

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 * @param	array	initialization parameters

-	 */

-	function CI_Pagination($params = array())

-	{

-		if (count($params) > 0)

-		{

-			$this->initialize($params);		

-		}

-		

-		log_message('debug', "Pagination Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Initialize Preferences

-	 *

-	 * @access	public

-	 * @param	array	initialization parameters

-	 * @return	void

-	 */

-	function initialize($params = array())

-	{

-		if (count($params) > 0)

-		{

-			foreach ($params as $key => $val)

-			{

-				if (isset($this->$key))

-				{

-					$this->$key = $val;

-				}

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Generate the pagination links

-	 *

-	 * @access	public

-	 * @return	string

-	 */	

-	function create_links()

-	{

-		// If our item count or per-page total is zero there is no need to continue.

-		if ($this->total_rows == 0 OR $this->per_page == 0)

-		{

-		   return '';

-		}

-

-		// Calculate the total number of pages

-		$num_pages = ceil($this->total_rows / $this->per_page);

-

-		// Is there only one page? Hm... nothing more to do here then.

-		if ($num_pages == 1)

-		{

-			return '';

-		}

-

-		// Determine the current page number.		

-		$CI =& get_instance();

-		

-		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)

-		{

-			if ($CI->input->get($this->query_string_segment) != 0)

-			{

-				$this->cur_page = $CI->input->get($this->query_string_segment);

-				

-				// Prep the current page - no funny business!

-				$this->cur_page = (int) $this->cur_page;

-			}

-		}

-		else

-		{

-			if ($CI->uri->segment($this->uri_segment) != 0)

-			{

-				$this->cur_page = $CI->uri->segment($this->uri_segment);

-				

-				// Prep the current page - no funny business!

-				$this->cur_page = (int) $this->cur_page;

-			}

-		}

-

-		$this->num_links = (int)$this->num_links;

-		

-		if ($this->num_links < 1)

-		{

-			show_error('Your number of links must be a positive number.');

-		}

-				

-		if ( ! is_numeric($this->cur_page))

-		{

-			$this->cur_page = 0;

-		}

-		

-		// Is the page number beyond the result range?

-		// If so we show the last page

-		if ($this->cur_page > $this->total_rows)

-		{

-			$this->cur_page = ($num_pages - 1) * $this->per_page;

-		}

-		

-		$uri_page_number = $this->cur_page;

-		$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);

-

-		// Calculate the start and end numbers. These determine

-		// which number to start and end the digit links with

-		$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;

-		$end   = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;

-

-		// Is pagination being used over GET or POST?  If get, add a per_page query

-		// string. If post, add a trailing slash to the base URL if needed

-		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)

-		{

-			$this->base_url = rtrim($this->base_url).'&amp;'.$this->query_string_segment.'=';

-		}

-		else

-		{

-			$this->base_url = rtrim($this->base_url, '/') .'/';

-		}

-

-  		// And here we go...

-		$output = '';

-

-		// Render the "First" link

-		if  ($this->cur_page > ($this->num_links + 1))

-		{

-			$output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;

-		}

-

-		// Render the "previous" link

-		if  ($this->cur_page != 1)

-		{

-			$i = $uri_page_number - $this->per_page;

-			if ($i == 0) $i = '';

-			$output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;

-		}

-

-		// Write the digit links

-		for ($loop = $start -1; $loop <= $end; $loop++)

-		{

-			$i = ($loop * $this->per_page) - $this->per_page;

-					

-			if ($i >= 0)

-			{

-				if ($this->cur_page == $loop)

-				{

-					$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page

-				}

-				else

-				{

-					$n = ($i == 0) ? '' : $i;

-					$output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;

-				}

-			}

-		}

-

-		// Render the "next" link

-		if ($this->cur_page < $num_pages)

-		{

-			$output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;

-		}

-

-		// Render the "Last" link

-		if (($this->cur_page + $this->num_links) < $num_pages)

-		{

-			$i = (($num_pages * $this->per_page) - $this->per_page);

-			$output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close;

-		}

-

-		// Kill double slashes.  Note: Sometimes we can end up with a double slash

-		// in the penultimate link so we'll kill all double slashes.

-		$output = preg_replace("#([^:])//+#", "\\1/", $output);

-

-		// Add the wrapper HTML if exists

-		$output = $this->full_tag_open.$output.$this->full_tag_close;

-		

-		return $output;		

-	}

-}

-// END Pagination Class

-

-/* End of file Pagination.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Pagination Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Pagination
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/pagination.html
+ */
+class CI_Pagination {
+
+	var $base_url			= ''; // The page we are linking to
+	var $total_rows  		= ''; // Total number of items (database results)
+	var $per_page	 		= 10; // Max number of items you want shown per page
+	var $num_links			=  2; // Number of "digit" links to show before/after the currently viewed page
+	var $cur_page	 		=  0; // The current page being viewed
+	var $first_link   		= '&lsaquo; First';
+	var $next_link			= '&gt;';
+	var $prev_link			= '&lt;';
+	var $last_link			= 'Last &rsaquo;';
+	var $uri_segment		= 3;
+	var $full_tag_open		= '';
+	var $full_tag_close		= '';
+	var $first_tag_open		= '';
+	var $first_tag_close	= '&nbsp;';
+	var $last_tag_open		= '&nbsp;';
+	var $last_tag_close		= '';
+	var $cur_tag_open		= '&nbsp;<strong>';
+	var $cur_tag_close		= '</strong>';
+	var $next_tag_open		= '&nbsp;';
+	var $next_tag_close		= '&nbsp;';
+	var $prev_tag_open		= '&nbsp;';
+	var $prev_tag_close		= '';
+	var $num_tag_open		= '&nbsp;';
+	var $num_tag_close		= '';
+	var $page_query_string	= FALSE;
+	var $query_string_segment = 'per_page';
+
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 * @param	array	initialization parameters
+	 */
+	function CI_Pagination($params = array())
+	{
+		if (count($params) > 0)
+		{
+			$this->initialize($params);		
+		}
+		
+		log_message('debug', "Pagination Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Initialize Preferences
+	 *
+	 * @access	public
+	 * @param	array	initialization parameters
+	 * @return	void
+	 */
+	function initialize($params = array())
+	{
+		if (count($params) > 0)
+		{
+			foreach ($params as $key => $val)
+			{
+				if (isset($this->$key))
+				{
+					$this->$key = $val;
+				}
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Generate the pagination links
+	 *
+	 * @access	public
+	 * @return	string
+	 */	
+	function create_links()
+	{
+		// If our item count or per-page total is zero there is no need to continue.
+		if ($this->total_rows == 0 OR $this->per_page == 0)
+		{
+		   return '';
+		}
+
+		// Calculate the total number of pages
+		$num_pages = ceil($this->total_rows / $this->per_page);
+
+		// Is there only one page? Hm... nothing more to do here then.
+		if ($num_pages == 1)
+		{
+			return '';
+		}
+
+		// Determine the current page number.		
+		$CI =& get_instance();
+		
+		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
+		{
+			if ($CI->input->get($this->query_string_segment) != 0)
+			{
+				$this->cur_page = $CI->input->get($this->query_string_segment);
+				
+				// Prep the current page - no funny business!
+				$this->cur_page = (int) $this->cur_page;
+			}
+		}
+		else
+		{
+			if ($CI->uri->segment($this->uri_segment) != 0)
+			{
+				$this->cur_page = $CI->uri->segment($this->uri_segment);
+				
+				// Prep the current page - no funny business!
+				$this->cur_page = (int) $this->cur_page;
+			}
+		}
+
+		$this->num_links = (int)$this->num_links;
+		
+		if ($this->num_links < 1)
+		{
+			show_error('Your number of links must be a positive number.');
+		}
+				
+		if ( ! is_numeric($this->cur_page))
+		{
+			$this->cur_page = 0;
+		}
+		
+		// Is the page number beyond the result range?
+		// If so we show the last page
+		if ($this->cur_page > $this->total_rows)
+		{
+			$this->cur_page = ($num_pages - 1) * $this->per_page;
+		}
+		
+		$uri_page_number = $this->cur_page;
+		$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
+
+		// Calculate the start and end numbers. These determine
+		// which number to start and end the digit links with
+		$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
+		$end   = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
+
+		// Is pagination being used over GET or POST?  If get, add a per_page query
+		// string. If post, add a trailing slash to the base URL if needed
+		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
+		{
+			$this->base_url = rtrim($this->base_url).'&amp;'.$this->query_string_segment.'=';
+		}
+		else
+		{
+			$this->base_url = rtrim($this->base_url, '/') .'/';
+		}
+
+  		// And here we go...
+		$output = '';
+
+		// Render the "First" link
+		if  ($this->cur_page > ($this->num_links + 1))
+		{
+			$output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
+		}
+
+		// Render the "previous" link
+		if  ($this->cur_page != 1)
+		{
+			$i = $uri_page_number - $this->per_page;
+			if ($i == 0) $i = '';
+			$output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
+		}
+
+		// Write the digit links
+		for ($loop = $start -1; $loop <= $end; $loop++)
+		{
+			$i = ($loop * $this->per_page) - $this->per_page;
+					
+			if ($i >= 0)
+			{
+				if ($this->cur_page == $loop)
+				{
+					$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
+				}
+				else
+				{
+					$n = ($i == 0) ? '' : $i;
+					$output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
+				}
+			}
+		}
+
+		// Render the "next" link
+		if ($this->cur_page < $num_pages)
+		{
+			$output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;
+		}
+
+		// Render the "Last" link
+		if (($this->cur_page + $this->num_links) < $num_pages)
+		{
+			$i = (($num_pages * $this->per_page) - $this->per_page);
+			$output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close;
+		}
+
+		// Kill double slashes.  Note: Sometimes we can end up with a double slash
+		// in the penultimate link so we'll kill all double slashes.
+		$output = preg_replace("#([^:])//+#", "\\1/", $output);
+
+		// Add the wrapper HTML if exists
+		$output = $this->full_tag_open.$output.$this->full_tag_close;
+		
+		return $output;		
+	}
+}
+// END Pagination Class
+
+/* End of file Pagination.php */
 /* Location: ./system/libraries/Pagination.php */
\ No newline at end of file
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index e276a0d..3d379b2 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -1,173 +1,173 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Parser Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Parser

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/parser.html

- */

-class CI_Parser {

-

-	var $l_delim = '{';

-	var $r_delim = '}';

-	var $object;

-		

-	/**

-	 *  Parse a template

-	 *

-	 * Parses pseudo-variables contained in the specified template,

-	 * replacing them with the data in the second param

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	array

-	 * @param	bool

-	 * @return	string

-	 */

-	function parse($template, $data, $return = FALSE)

-	{

-		$CI =& get_instance();

-		$template = $CI->load->view($template, $data, TRUE);

-		

-		if ($template == '')

-		{

-			return FALSE;

-		}

-		

-		foreach ($data as $key => $val)

-		{

-			if (is_array($val))

-			{

-				$template = $this->_parse_pair($key, $val, $template);		

-			}

-			else

-			{

-				$template = $this->_parse_single($key, (string)$val, $template);

-			}

-		}

-		

-		if ($return == FALSE)

-		{

-			$CI->output->append_output($template);

-		}

-		

-		return $template;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Set the left/right variable delimiters

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function set_delimiters($l = '{', $r = '}')

-	{

-		$this->l_delim = $l;

-		$this->r_delim = $r;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Parse a single key/value

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _parse_single($key, $val, $string)

-	{

-		return str_replace($this->l_delim.$key.$this->r_delim, $val, $string);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Parse a tag pair

-	 *

-	 * Parses tag pairs:  {some_tag} string... {/some_tag}

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	array

-	 * @param	string

-	 * @return	string

-	 */

-	function _parse_pair($variable, $data, $string)

-	{	

-		if (FALSE === ($match = $this->_match_pair($string, $variable)))

-		{

-			return $string;

-		}

-

-		$str = '';

-		foreach ($data as $row)

-		{

-			$temp = $match['1'];

-			foreach ($row as $key => $val)

-			{

-				if ( ! is_array($val))

-				{

-					$temp = $this->_parse_single($key, $val, $temp);

-				}

-				else

-				{

-					$temp = $this->_parse_pair($key, $val, $temp);

-				}

-			}

-			

-			$str .= $temp;

-		}

-		

-		return str_replace($match['0'], $str, $string);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Matches a variable pair

-	 *

-	 * @access	private

-	 * @param	string

-	 * @param	string

-	 * @return	mixed

-	 */

-	function _match_pair($string, $variable)

-	{

-		if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+?)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match))

-		{

-			return FALSE;

-		}

-		

-		return $match;

-	}

-

-}

-// END Parser Class

-

-/* End of file Parser.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parser Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Parser
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/parser.html
+ */
+class CI_Parser {
+
+	var $l_delim = '{';
+	var $r_delim = '}';
+	var $object;
+		
+	/**
+	 *  Parse a template
+	 *
+	 * Parses pseudo-variables contained in the specified template,
+	 * replacing them with the data in the second param
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	array
+	 * @param	bool
+	 * @return	string
+	 */
+	function parse($template, $data, $return = FALSE)
+	{
+		$CI =& get_instance();
+		$template = $CI->load->view($template, $data, TRUE);
+		
+		if ($template == '')
+		{
+			return FALSE;
+		}
+		
+		foreach ($data as $key => $val)
+		{
+			if (is_array($val))
+			{
+				$template = $this->_parse_pair($key, $val, $template);		
+			}
+			else
+			{
+				$template = $this->_parse_single($key, (string)$val, $template);
+			}
+		}
+		
+		if ($return == FALSE)
+		{
+			$CI->output->append_output($template);
+		}
+		
+		return $template;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Set the left/right variable delimiters
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function set_delimiters($l = '{', $r = '}')
+	{
+		$this->l_delim = $l;
+		$this->r_delim = $r;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Parse a single key/value
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _parse_single($key, $val, $string)
+	{
+		return str_replace($this->l_delim.$key.$this->r_delim, $val, $string);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Parse a tag pair
+	 *
+	 * Parses tag pairs:  {some_tag} string... {/some_tag}
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	array
+	 * @param	string
+	 * @return	string
+	 */
+	function _parse_pair($variable, $data, $string)
+	{	
+		if (FALSE === ($match = $this->_match_pair($string, $variable)))
+		{
+			return $string;
+		}
+
+		$str = '';
+		foreach ($data as $row)
+		{
+			$temp = $match['1'];
+			foreach ($row as $key => $val)
+			{
+				if ( ! is_array($val))
+				{
+					$temp = $this->_parse_single($key, $val, $temp);
+				}
+				else
+				{
+					$temp = $this->_parse_pair($key, $val, $temp);
+				}
+			}
+			
+			$str .= $temp;
+		}
+		
+		return str_replace($match['0'], $str, $string);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Matches a variable pair
+	 *
+	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	mixed
+	 */
+	function _match_pair($string, $variable)
+	{
+		if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+?)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match))
+		{
+			return FALSE;
+		}
+		
+		return $match;
+	}
+
+}
+// END Parser Class
+
+/* End of file Parser.php */
 /* Location: ./system/libraries/Parser.php */
\ No newline at end of file
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 7f869f4..5e9fa8b 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -1,392 +1,392 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * CodeIgniter Profiler Class

- *

- * This class enables you to display benchmark, query, and other data

- * in order to help with debugging and optimization.

- *

- * Note: At some point it would be good to move all the HTML in this class

- * into a set of template files in order to allow customization.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Libraries

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/general/profiling.html

- */

-class CI_Profiler {

-

-	var $CI;

- 	

- 	function CI_Profiler()

- 	{

- 		$this->CI =& get_instance();

- 		$this->CI->load->language('profiler');

- 	}

- 	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Auto Profiler

-	 *

-	 * This function cycles through the entire array of mark points and

-	 * matches any two points that are named identically (ending in "_start"

-	 * and "_end" respectively).  It then compiles the execution times for

-	 * all points and returns it as an array

-	 *

-	 * @access	private

-	 * @return	array

-	 */

- 	function _compile_benchmarks()

- 	{

-  		$profile = array();

- 		foreach ($this->CI->benchmark->marker as $key => $val)

- 		{

- 			// We match the "end" marker so that the list ends

- 			// up in the order that it was defined

- 			if (preg_match("/(.+?)_end/i", $key, $match))

- 			{ 			

- 				if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))

- 				{

- 					$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);

- 				}

- 			}

- 		}

-

-		// Build a table containing the profile data.

-		// Note: At some point we should turn this into a template that can

-		// be modified.  We also might want to make this data available to be logged

-	

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #990000;padding:6px 10px 10px 10px;margin:0 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#990000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";			

-		$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";

-		

-		foreach ($profile as $key => $val)

-		{

-			$key = ucwords(str_replace(array('_', '-'), ' ', $key));

-			$output .= "<tr><td width='50%' style='color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td width='50%' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";

-		}

-		

-		$output .= "</table>\n";

-		$output .= "</fieldset>";

- 		

- 		return $output;

- 	}

- 	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Compile Queries

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _compile_queries()

-	{

-		$dbs = array();

-		

-		// Let's determine which databases are currently connected to

-		foreach (get_object_vars($this->CI) as $CI_object)

-		{

-			if ( is_subclass_of(get_class($CI_object), 'CI_DB') )

-			{

-				$dbs[] = $CI_object;

-			}

-		}

-					

-		if (count($dbs) == 0)

-		{

-			$output  = "\n\n";

-			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-			$output .= "\n";

-			$output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';

-			$output .= "\n";		

-			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";

-			$output .="<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";

-			$output .= "</table>\n";

-			$output .= "</fieldset>";

-			

-			return $output;

-		}

-		

-		// Load the text helper so we can highlight the SQL

-		$this->CI->load->helper('text');

-

-		// Key words we want bolded

-		$highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');

-

-		$output  = "\n\n";

-			

-		foreach ($dbs as $db)

-		{

-			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-			$output .= "\n";

-			$output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($this->CI->db->queries).'&nbsp;&nbsp;&nbsp;</legend>';

-			$output .= "\n";		

-			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";

-		

-			if (count($db->queries) == 0)

-			{

-				$output .= "<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";

-			}

-			else

-			{				

-				foreach ($db->queries as $key => $val)

-				{					

-					$time = number_format($db->query_times[$key], 4);

-

-					$val = highlight_code($val, ENT_QUOTES);

-	

-					foreach ($highlight as $bold)

-					{

-						$val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);	

-					}

-					

-					$output .= "<tr><td width='1%' valign='top' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";

-				}

-			}

-			

-			$output .= "</table>\n";

-			$output .= "</fieldset>";

-			

-		}

-		

-		return $output;

-	}

-

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Compile $_GET Data

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _compile_get()

-	{	

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";

-				

-		if (count($_GET) == 0)

-		{

-			$output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";

-		}

-		else

-		{

-			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";

-		

-			foreach ($_GET as $key => $val)

-			{

-				if ( ! is_numeric($key))

-				{

-					$key = "'".$key."'";

-				}

-			

-				$output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#cd6e00;font-weight:normal;background-color:#ddd;'>";

-				if (is_array($val))

-				{

-					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";

-				}

-				else

-				{

-					$output .= htmlspecialchars(stripslashes($val));

-				}

-				$output .= "</td></tr>\n";

-			}

-			

-			$output .= "</table>\n";

-		}

-		$output .= "</fieldset>";

-

-		return $output;	

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Compile $_POST Data

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _compile_post()

-	{	

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";

-				

-		if (count($_POST) == 0)

-		{

-			$output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";

-		}

-		else

-		{

-			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";

-		

-			foreach ($_POST as $key => $val)

-			{

-				if ( ! is_numeric($key))

-				{

-					$key = "'".$key."'";

-				}

-			

-				$output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>";

-				if (is_array($val))

-				{

-					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";

-				}

-				else

-				{

-					$output .= htmlspecialchars(stripslashes($val));

-				}

-				$output .= "</td></tr>\n";

-			}

-			

-			$output .= "</table>\n";

-		}

-		$output .= "</fieldset>";

-

-		return $output;	

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Show query string

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _compile_uri_string()

-	{	

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";

-		

-		if ($this->CI->uri->uri_string == '')

-		{

-			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";

-		}

-		else

-		{

-			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";				

-		}

-		

-		$output .= "</fieldset>";

-

-		return $output;	

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Show the controller and function that were called

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _compile_controller_info()

-	{	

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";

-		

-		$output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";				

-

-		

-		$output .= "</fieldset>";

-

-		return $output;	

-	}

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Compile memory usage

-	 *

-	 * Display total used memory

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function _compile_memory_usage()

-	{

-		$output  = "\n\n";

-		$output .= '<fieldset style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';

-		$output .= "\n";

-		$output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';

-		$output .= "\n";

-		

-		if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')

-		{

-			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';

-		}

-		else

-		{

-			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>";				

-		}

-		

-		$output .= "</fieldset>";

-

-		return $output;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Run the Profiler

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function run()

-	{

-		$output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";

-

-		$output .= $this->_compile_uri_string();

-		$output .= $this->_compile_controller_info();

-		$output .= $this->_compile_memory_usage();

-		$output .= $this->_compile_benchmarks();

-		$output .= $this->_compile_get();

-		$output .= $this->_compile_post();

-		$output .= $this->_compile_queries();

-

-		$output .= '</div>';

-

-		return $output;

-	}

-

-}

-

-// END CI_Profiler class

-

-/* End of file Profiler.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Profiler Class
+ *
+ * This class enables you to display benchmark, query, and other data
+ * in order to help with debugging and optimization.
+ *
+ * Note: At some point it would be good to move all the HTML in this class
+ * into a set of template files in order to allow customization.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/general/profiling.html
+ */
+class CI_Profiler {
+
+	var $CI;
+ 	
+ 	function CI_Profiler()
+ 	{
+ 		$this->CI =& get_instance();
+ 		$this->CI->load->language('profiler');
+ 	}
+ 	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Auto Profiler
+	 *
+	 * This function cycles through the entire array of mark points and
+	 * matches any two points that are named identically (ending in "_start"
+	 * and "_end" respectively).  It then compiles the execution times for
+	 * all points and returns it as an array
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+ 	function _compile_benchmarks()
+ 	{
+  		$profile = array();
+ 		foreach ($this->CI->benchmark->marker as $key => $val)
+ 		{
+ 			// We match the "end" marker so that the list ends
+ 			// up in the order that it was defined
+ 			if (preg_match("/(.+?)_end/i", $key, $match))
+ 			{ 			
+ 				if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
+ 				{
+ 					$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
+ 				}
+ 			}
+ 		}
+
+		// Build a table containing the profile data.
+		// Note: At some point we should turn this into a template that can
+		// be modified.  We also might want to make this data available to be logged
+	
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #990000;padding:6px 10px 10px 10px;margin:0 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#990000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";			
+		$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
+		
+		foreach ($profile as $key => $val)
+		{
+			$key = ucwords(str_replace(array('_', '-'), ' ', $key));
+			$output .= "<tr><td width='50%' style='color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td width='50%' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+		}
+		
+		$output .= "</table>\n";
+		$output .= "</fieldset>";
+ 		
+ 		return $output;
+ 	}
+ 	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile Queries
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _compile_queries()
+	{
+		$dbs = array();
+		
+		// Let's determine which databases are currently connected to
+		foreach (get_object_vars($this->CI) as $CI_object)
+		{
+			if ( is_subclass_of(get_class($CI_object), 'CI_DB') )
+			{
+				$dbs[] = $CI_object;
+			}
+		}
+					
+		if (count($dbs) == 0)
+		{
+			$output  = "\n\n";
+			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+			$output .= "\n";
+			$output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';
+			$output .= "\n";		
+			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
+			$output .="<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";
+			$output .= "</table>\n";
+			$output .= "</fieldset>";
+			
+			return $output;
+		}
+		
+		// Load the text helper so we can highlight the SQL
+		$this->CI->load->helper('text');
+
+		// Key words we want bolded
+		$highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');
+
+		$output  = "\n\n";
+			
+		foreach ($dbs as $db)
+		{
+			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+			$output .= "\n";
+			$output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($this->CI->db->queries).'&nbsp;&nbsp;&nbsp;</legend>';
+			$output .= "\n";		
+			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
+		
+			if (count($db->queries) == 0)
+			{
+				$output .= "<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
+			}
+			else
+			{				
+				foreach ($db->queries as $key => $val)
+				{					
+					$time = number_format($db->query_times[$key], 4);
+
+					$val = highlight_code($val, ENT_QUOTES);
+	
+					foreach ($highlight as $bold)
+					{
+						$val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);	
+					}
+					
+					$output .= "<tr><td width='1%' valign='top' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+				}
+			}
+			
+			$output .= "</table>\n";
+			$output .= "</fieldset>";
+			
+		}
+		
+		return $output;
+	}
+
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile $_GET Data
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _compile_get()
+	{	
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";
+				
+		if (count($_GET) == 0)
+		{
+			$output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
+		}
+		else
+		{
+			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
+		
+			foreach ($_GET as $key => $val)
+			{
+				if ( ! is_numeric($key))
+				{
+					$key = "'".$key."'";
+				}
+			
+				$output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#cd6e00;font-weight:normal;background-color:#ddd;'>";
+				if (is_array($val))
+				{
+					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
+				}
+				else
+				{
+					$output .= htmlspecialchars(stripslashes($val));
+				}
+				$output .= "</td></tr>\n";
+			}
+			
+			$output .= "</table>\n";
+		}
+		$output .= "</fieldset>";
+
+		return $output;	
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Compile $_POST Data
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _compile_post()
+	{	
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";
+				
+		if (count($_POST) == 0)
+		{
+			$output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
+		}
+		else
+		{
+			$output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
+		
+			foreach ($_POST as $key => $val)
+			{
+				if ( ! is_numeric($key))
+				{
+					$key = "'".$key."'";
+				}
+			
+				$output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>";
+				if (is_array($val))
+				{
+					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
+				}
+				else
+				{
+					$output .= htmlspecialchars(stripslashes($val));
+				}
+				$output .= "</td></tr>\n";
+			}
+			
+			$output .= "</table>\n";
+		}
+		$output .= "</fieldset>";
+
+		return $output;	
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Show query string
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _compile_uri_string()
+	{	
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";
+		
+		if ($this->CI->uri->uri_string == '')
+		{
+			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";
+		}
+		else
+		{
+			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";				
+		}
+		
+		$output .= "</fieldset>";
+
+		return $output;	
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Show the controller and function that were called
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _compile_controller_info()
+	{	
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";
+		
+		$output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";				
+
+		
+		$output .= "</fieldset>";
+
+		return $output;	
+	}
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Compile memory usage
+	 *
+	 * Display total used memory
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function _compile_memory_usage()
+	{
+		$output  = "\n\n";
+		$output .= '<fieldset style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
+		$output .= "\n";
+		$output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';
+		$output .= "\n";
+		
+		if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
+		{
+			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';
+		}
+		else
+		{
+			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>";				
+		}
+		
+		$output .= "</fieldset>";
+
+		return $output;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Run the Profiler
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function run()
+	{
+		$output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";
+
+		$output .= $this->_compile_uri_string();
+		$output .= $this->_compile_controller_info();
+		$output .= $this->_compile_memory_usage();
+		$output .= $this->_compile_benchmarks();
+		$output .= $this->_compile_get();
+		$output .= $this->_compile_post();
+		$output .= $this->_compile_queries();
+
+		$output .= '</div>';
+
+		return $output;
+	}
+
+}
+
+// END CI_Profiler class
+
+/* End of file Profiler.php */
 /* Location: ./system/libraries/Profiler.php */
\ No newline at end of file
diff --git a/system/libraries/Router.php b/system/libraries/Router.php
index cf42516..32de58d 100644
--- a/system/libraries/Router.php
+++ b/system/libraries/Router.php
@@ -1,385 +1,385 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Router Class

- *

- * Parses URIs and determines routing

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @author		ExpressionEngine Dev Team

- * @category	Libraries

- * @link		http://codeigniter.com/user_guide/general/routing.html

- */

-class CI_Router {

-

-	var $config;	

-	var $routes 		= array();

-	var $error_routes	= array();

-	var $class			= '';

-	var $method			= 'index';

-	var $directory		= '';

-	var $uri_protocol 	= 'auto';

-	var $default_controller;

-	var $scaffolding_request = FALSE; // Must be set to FALSE

-	

-	/**

-	 * Constructor

-	 *

-	 * Runs the route mapping function.

-	 */

-	function CI_Router()

-	{

-		$this->config =& load_class('Config');

-		$this->uri =& load_class('URI');

-		$this->_set_routing();

-		log_message('debug', "Router Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the route mapping

-	 *

-	 * This function determines what should be served based on the URI request,

-	 * as well as any "routes" that have been set in the routing config file.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _set_routing()

-	{

-		// Are query strings enabled in the config file?

-		// If so, we're done since segment based URIs are not used with query strings.

-		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))

-		{

-			$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));

-

-			if (isset($_GET[$this->config->item('function_trigger')]))

-			{

-				$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));

-			}

-			

-			return;

-		}

-		

-		// Load the routes.php file.

-		@include(APPPATH.'config/routes'.EXT);

-		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;

-		unset($route);

-

-		// Set the default controller so we can display it in the event

-		// the URI doesn't correlated to a valid controller.

-		$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);	

-		

-		// Fetch the complete URI string

-		$this->uri->_fetch_uri_string();

-	

-		// Is there a URI string? If not, the default controller specified in the "routes" file will be shown.

-		if ($this->uri->uri_string == '')

-		{

-			if ($this->default_controller === FALSE)

-			{

-				show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");

-			}

-

-			// Turn the default route into an array.  We explode it in the event that

-			// the controller is located in a subfolder

-			$segments = $this->_validate_request(explode('/', $this->default_controller));

-

-			// Set the class and method

-			$this->set_class($segments[0]);

-			$this->set_method('index');

-			

-			// Assign the segments to the URI class

-			$this->uri->rsegments = $segments;

-			

-			// re-index the routed segments array so it starts with 1 rather than 0

-			$this->uri->_reindex_segments();

-			

-			log_message('debug', "No URI present. Default controller set.");

-			return;

-		}

-		unset($this->routes['default_controller']);

-		

-		// Do we need to remove the URL suffix?

-		$this->uri->_remove_url_suffix();

-		

-		// Compile the segments into an array

-		$this->uri->_explode_segments();

-		

-		// Parse any custom routing that may exist

-		$this->_parse_routes();		

-		

-		// Re-index the segment array so that it starts with 1 rather than 0

-		$this->uri->_reindex_segments();

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Route

-	 *

-	 * This function takes an array of URI segments as

-	 * input, and sets the current class/method

-	 *

-	 * @access	private

-	 * @param	array

-	 * @param	bool

-	 * @return	void

-	 */

-	function _set_request($segments = array())

-	{	

-		$segments = $this->_validate_request($segments);

-		

-		if (count($segments) == 0)

-		{

-			return;

-		}

-						

-		$this->set_class($segments[0]);

-		

-		if (isset($segments[1]))

-		{

-			// A scaffolding request. No funny business with the URL

-			if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding')

-			{

-				$this->scaffolding_request = TRUE;

-				unset($this->routes['scaffolding_trigger']);

-			}

-			else

-			{

-				// A standard method request

-				$this->set_method($segments[1]);

-			}

-		}

-		else

-		{

-			// This lets the "routed" segment array identify that the default

-			// index method is being used.

-			$segments[1] = 'index';

-		}

-		

-		// Update our "routed" segment array to contain the segments.

-		// Note: If there is no custom routing, this array will be

-		// identical to $this->uri->segments

-		$this->uri->rsegments = $segments;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validates the supplied segments.  Attempts to determine the path to

-	 * the controller.

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	array

-	 */	

-	function _validate_request($segments)

-	{

-		// Does the requested controller exist in the root folder?

-		if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))

-		{

-			return $segments;

-		}

-

-		// Is the controller in a sub-folder?

-		if (is_dir(APPPATH.'controllers/'.$segments[0]))

-		{		

-			// Set the directory and remove it from the segment array

-			$this->set_directory($segments[0]);

-			$segments = array_slice($segments, 1);

-			

-			if (count($segments) > 0)

-			{

-				// Does the requested controller exist in the sub-folder?

-				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))

-				{

-					show_404($this->fetch_directory().$segments[0]);

-				}

-			}

-			else

-			{

-				$this->set_class($this->default_controller);

-				$this->set_method('index');

-			

-				// Does the default controller exist in the sub-folder?

-				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))

-				{

-					$this->directory = '';

-					return array();

-				}

-			

-			}

-

-			return $segments;

-		}

-

-		// Can't find the requested controller...

-		show_404($segments[0]);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 *  Parse Routes

-	 *

-	 * This function matches any routes that may exist in

-	 * the config/routes.php file against the URI to

-	 * determine if the class/method need to be remapped.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _parse_routes()

-	{

-		// Do we even have any custom routing to deal with?

-		// There is a default scaffolding trigger, so we'll look just for 1

-		if (count($this->routes) == 1)

-		{

-			$this->_set_request($this->uri->segments);

-			return;

-		}

-

-		// Turn the segment array into a URI string

-		$uri = implode('/', $this->uri->segments);

-

-		// Is there a literal match?  If so we're done

-		if (isset($this->routes[$uri]))

-		{

-			$this->_set_request(explode('/', $this->routes[$uri]));		

-			return;

-		}

-				

-		// Loop through the route array looking for wild-cards

-		foreach ($this->routes as $key => $val)

-		{						

-			// Convert wild-cards to RegEx

-			$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));

-			

-			// Does the RegEx match?

-			if (preg_match('#^'.$key.'$#', $uri))

-			{			

-				// Do we have a back-reference?

-				if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)

-				{

-					$val = preg_replace('#^'.$key.'$#', $val, $uri);

-				}

-			

-				$this->_set_request(explode('/', $val));		

-				return;

-			}

-		}

-

-		// If we got this far it means we didn't encounter a

-		// matching route so we'll set the site default route

-		$this->_set_request($this->uri->segments);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the class name

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_class($class)

-	{

-		$this->class = $class;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Fetch the current class

-	 *

-	 * @access	public

-	 * @return	string

-	 */	

-	function fetch_class()

-	{

-		return $this->class;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Set the method name

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_method($method)

-	{

-		$this->method = $method;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Fetch the current method

-	 *

-	 * @access	public

-	 * @return	string

-	 */	

-	function fetch_method()

-	{

-		if ($this->method == $this->fetch_class())

-		{

-			return 'index';

-		}

-

-		return $this->method;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Set the directory name

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_directory($dir)

-	{

-		$this->directory = $dir.'/';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 *  Fetch the sub-directory (if any) that contains the requested controller class

-	 *

-	 * @access	public

-	 * @return	string

-	 */	

-	function fetch_directory()

-	{

-		return $this->directory;

-	}

-

-}

-// END Router Class

-

-/* End of file Router.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Router Class
+ *
+ * Parses URIs and determines routing
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @author		ExpressionEngine Dev Team
+ * @category	Libraries
+ * @link		http://codeigniter.com/user_guide/general/routing.html
+ */
+class CI_Router {
+
+	var $config;	
+	var $routes 		= array();
+	var $error_routes	= array();
+	var $class			= '';
+	var $method			= 'index';
+	var $directory		= '';
+	var $uri_protocol 	= 'auto';
+	var $default_controller;
+	var $scaffolding_request = FALSE; // Must be set to FALSE
+	
+	/**
+	 * Constructor
+	 *
+	 * Runs the route mapping function.
+	 */
+	function CI_Router()
+	{
+		$this->config =& load_class('Config');
+		$this->uri =& load_class('URI');
+		$this->_set_routing();
+		log_message('debug', "Router Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the route mapping
+	 *
+	 * This function determines what should be served based on the URI request,
+	 * as well as any "routes" that have been set in the routing config file.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _set_routing()
+	{
+		// Are query strings enabled in the config file?
+		// If so, we're done since segment based URIs are not used with query strings.
+		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
+		{
+			$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
+
+			if (isset($_GET[$this->config->item('function_trigger')]))
+			{
+				$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
+			}
+			
+			return;
+		}
+		
+		// Load the routes.php file.
+		@include(APPPATH.'config/routes'.EXT);
+		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
+		unset($route);
+
+		// Set the default controller so we can display it in the event
+		// the URI doesn't correlated to a valid controller.
+		$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);	
+		
+		// Fetch the complete URI string
+		$this->uri->_fetch_uri_string();
+	
+		// Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
+		if ($this->uri->uri_string == '')
+		{
+			if ($this->default_controller === FALSE)
+			{
+				show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
+			}
+
+			// Turn the default route into an array.  We explode it in the event that
+			// the controller is located in a subfolder
+			$segments = $this->_validate_request(explode('/', $this->default_controller));
+
+			// Set the class and method
+			$this->set_class($segments[0]);
+			$this->set_method('index');
+			
+			// Assign the segments to the URI class
+			$this->uri->rsegments = $segments;
+			
+			// re-index the routed segments array so it starts with 1 rather than 0
+			$this->uri->_reindex_segments();
+			
+			log_message('debug', "No URI present. Default controller set.");
+			return;
+		}
+		unset($this->routes['default_controller']);
+		
+		// Do we need to remove the URL suffix?
+		$this->uri->_remove_url_suffix();
+		
+		// Compile the segments into an array
+		$this->uri->_explode_segments();
+		
+		// Parse any custom routing that may exist
+		$this->_parse_routes();		
+		
+		// Re-index the segment array so that it starts with 1 rather than 0
+		$this->uri->_reindex_segments();
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Route
+	 *
+	 * This function takes an array of URI segments as
+	 * input, and sets the current class/method
+	 *
+	 * @access	private
+	 * @param	array
+	 * @param	bool
+	 * @return	void
+	 */
+	function _set_request($segments = array())
+	{	
+		$segments = $this->_validate_request($segments);
+		
+		if (count($segments) == 0)
+		{
+			return;
+		}
+						
+		$this->set_class($segments[0]);
+		
+		if (isset($segments[1]))
+		{
+			// A scaffolding request. No funny business with the URL
+			if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding')
+			{
+				$this->scaffolding_request = TRUE;
+				unset($this->routes['scaffolding_trigger']);
+			}
+			else
+			{
+				// A standard method request
+				$this->set_method($segments[1]);
+			}
+		}
+		else
+		{
+			// This lets the "routed" segment array identify that the default
+			// index method is being used.
+			$segments[1] = 'index';
+		}
+		
+		// Update our "routed" segment array to contain the segments.
+		// Note: If there is no custom routing, this array will be
+		// identical to $this->uri->segments
+		$this->uri->rsegments = $segments;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validates the supplied segments.  Attempts to determine the path to
+	 * the controller.
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	array
+	 */	
+	function _validate_request($segments)
+	{
+		// Does the requested controller exist in the root folder?
+		if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
+		{
+			return $segments;
+		}
+
+		// Is the controller in a sub-folder?
+		if (is_dir(APPPATH.'controllers/'.$segments[0]))
+		{		
+			// Set the directory and remove it from the segment array
+			$this->set_directory($segments[0]);
+			$segments = array_slice($segments, 1);
+			
+			if (count($segments) > 0)
+			{
+				// Does the requested controller exist in the sub-folder?
+				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
+				{
+					show_404($this->fetch_directory().$segments[0]);
+				}
+			}
+			else
+			{
+				$this->set_class($this->default_controller);
+				$this->set_method('index');
+			
+				// Does the default controller exist in the sub-folder?
+				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
+				{
+					$this->directory = '';
+					return array();
+				}
+			
+			}
+
+			return $segments;
+		}
+
+		// Can't find the requested controller...
+		show_404($segments[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 *  Parse Routes
+	 *
+	 * This function matches any routes that may exist in
+	 * the config/routes.php file against the URI to
+	 * determine if the class/method need to be remapped.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _parse_routes()
+	{
+		// Do we even have any custom routing to deal with?
+		// There is a default scaffolding trigger, so we'll look just for 1
+		if (count($this->routes) == 1)
+		{
+			$this->_set_request($this->uri->segments);
+			return;
+		}
+
+		// Turn the segment array into a URI string
+		$uri = implode('/', $this->uri->segments);
+
+		// Is there a literal match?  If so we're done
+		if (isset($this->routes[$uri]))
+		{
+			$this->_set_request(explode('/', $this->routes[$uri]));		
+			return;
+		}
+				
+		// Loop through the route array looking for wild-cards
+		foreach ($this->routes as $key => $val)
+		{						
+			// Convert wild-cards to RegEx
+			$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
+			
+			// Does the RegEx match?
+			if (preg_match('#^'.$key.'$#', $uri))
+			{			
+				// Do we have a back-reference?
+				if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
+				{
+					$val = preg_replace('#^'.$key.'$#', $val, $uri);
+				}
+			
+				$this->_set_request(explode('/', $val));		
+				return;
+			}
+		}
+
+		// If we got this far it means we didn't encounter a
+		// matching route so we'll set the site default route
+		$this->_set_request($this->uri->segments);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the class name
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_class($class)
+	{
+		$this->class = $class;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Fetch the current class
+	 *
+	 * @access	public
+	 * @return	string
+	 */	
+	function fetch_class()
+	{
+		return $this->class;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Set the method name
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_method($method)
+	{
+		$this->method = $method;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Fetch the current method
+	 *
+	 * @access	public
+	 * @return	string
+	 */	
+	function fetch_method()
+	{
+		if ($this->method == $this->fetch_class())
+		{
+			return 'index';
+		}
+
+		return $this->method;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Set the directory name
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_directory($dir)
+	{
+		$this->directory = $dir.'/';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 *  Fetch the sub-directory (if any) that contains the requested controller class
+	 *
+	 * @access	public
+	 * @return	string
+	 */	
+	function fetch_directory()
+	{
+		return $this->directory;
+	}
+
+}
+// END Router Class
+
+/* End of file Router.php */
 /* Location: ./system/libraries/Router.php */
\ No newline at end of file
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 25bf21f..660ce8f 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -1,758 +1,758 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Session Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Sessions

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/sessions.html

- */

-class CI_Session {

-

-	var $sess_encrypt_cookie		= FALSE;

-	var $sess_use_database			= FALSE;

-	var $sess_table_name			= '';

-	var $sess_expiration			= 7200;

-	var $sess_match_ip				= FALSE;

-	var $sess_match_useragent		= TRUE;

-	var $sess_cookie_name			= 'ci_session';

-	var $cookie_prefix				= '';

-	var $cookie_path				= '';

-	var $cookie_domain				= '';

-	var $sess_time_to_update		= 300;

-	var $encryption_key				= '';

-	var $flashdata_key 				= 'flash';

-	var $time_reference				= 'time';

-	var $gc_probability				= 5;

-	var $userdata					= array();

-	var $CI;

-	var $now;

-

-	/**

-	 * Session Constructor

-	 *

-	 * The constructor runs the session routines automatically

-	 * whenever the class is instantiated.

-	 */

-	function CI_Session($params = array())

-	{

-		log_message('debug', "Session Class Initialized");

-

-		// Set the super object to a local variable for use throughout the class

-		$this->CI =& get_instance();

-

-		// 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_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)

-		{

-			$this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);

-		}

-

-		// Load the string helper so we can use the strip_slashes() function

-		$this->CI->load->helper('string');

-

-		// Do we need encryption? If so, load the encryption class

-		if ($this->sess_encrypt_cookie == TRUE)

-		{

-			$this->CI->load->library('encrypt');

-		}

-

-		// Are we using a database?  If so, load it

-		if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')

-		{

-			$this->CI->load->database();

-		}

-

-		// Set the "now" time.  Can either be GMT or server time, based on the

-		// config prefs.  We use this to set the "last activity" time

-		$this->now = $this->_get_time();

-

-		// Set the session length. If the session expiration is

-		// set to zero we'll set the expiration two years from now.

-		if ($this->sess_expiration == 0)

-		{

-			$this->sess_expiration = (60*60*24*365*2);

-		}

-		 

-		// Set the cookie name

-		$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;

-

-		// Run the Session routine. If a session doesn't exist we'll

-		// create a new one.  If it does, we'll update it.

-		if ( ! $this->sess_read())

-		{

-			$this->sess_create();

-		}

-		else

-		{

-			$this->sess_update();

-		}

-

-		// Delete 'old' flashdata (from last request)

-	   	$this->_flashdata_sweep();

-

-		// Mark all new flashdata as old (data will be deleted before next request)

-	   	$this->_flashdata_mark();

-

-		// Delete expired sessions if necessary

-		$this->_sess_gc();

-

-		log_message('debug', "Session routines successfully run");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch the current session data if it exists

-	 *

-	 * @access	public

-	 * @return	bool

-	 */

-	function sess_read()

-	{

-		// Fetch the cookie

-		$session = $this->CI->input->cookie($this->sess_cookie_name);

-

-		// No cookie?  Goodbye cruel world!...

-		if ($session === FALSE)

-		{

-			log_message('debug', 'A session cookie was not found.');

-			return FALSE;

-		}

-

-		// Decrypt the cookie data

-		if ($this->sess_encrypt_cookie == TRUE)

-		{

-			$session = $this->CI->encrypt->decode($session);

-		}

-		else

-		{

-			// encryption was not used, so we need to check the md5 hash

-			$hash	 = substr($session, strlen($session)-32); // get last 32 chars

-			$session = substr($session, 0, strlen($session)-32);

-

-			// Does the md5 hash match?  This is to prevent manipulation of session data in userspace

-			if ($hash !==  md5($session.$this->encryption_key))

-			{

-				log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');

-				$this->sess_destroy();

-				return FALSE;

-			}

-		}

-

-		// Unserialize the session array

-		$session = $this->_unserialize($session);

-

-		// Is the session data we unserialized an array with the correct format?

-		if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))

-		{

-			$this->sess_destroy();

-			return FALSE;

-		}

-

-		// Is the session current?

-		if (($session['last_activity'] + $this->sess_expiration) < $this->now)

-		{

-			$this->sess_destroy();

-			return FALSE;

-		}

-

-		// Does the IP Match?

-		if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())

-		{

-			$this->sess_destroy();

-			return FALSE;

-		}

-

-		// Does the User Agent Match?

-		if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))

-		{

-			$this->sess_destroy();

-			return FALSE;

-		}

-

-		// Is there a corresponding session in the DB?

-		if ($this->sess_use_database === TRUE)

-		{

-			$this->CI->db->where('session_id', $session['session_id']);

-

-			if ($this->sess_match_ip == TRUE)

-			{

-				$this->CI->db->where('ip_address', $session['ip_address']);

-			}

-

-			if ($this->sess_match_useragent == TRUE)

-			{

-				$this->CI->db->where('user_agent', $session['user_agent']);

-			}

-

-			$query = $this->CI->db->get($this->sess_table_name);

-

-			// No result?  Kill it!

-			if ($query->num_rows() == 0)

-			{

-				$this->sess_destroy();

-				return FALSE;

-			}

-

-			// Is there custom data?  If so, add it to the main session array

-			$row = $query->row();

-			if (isset($row->user_data) AND $row->user_data != '')

-			{

-				$custom_data = $this->_unserialize($row->user_data);

-

-				if (is_array($custom_data))

-				{

-					foreach ($custom_data as $key => $val)

-					{

-						$session[$key] = $val;

-					}

-				}

-			}

-		}

-

-		// Session is valid!

-		$this->userdata = $session;

-		unset($session);

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write the session data

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function sess_write()

-	{

-		// Are we saving custom data to the DB?  If not, all we do is update the cookie

-		if ($this->sess_use_database === FALSE)

-		{

-			$this->_set_cookie();

-			return;

-		}

-

-		// set the custom userdata, the session data we will set in a second

-		$custom_userdata = $this->userdata;

-		$cookie_userdata = array();

-

-		// Before continuing, we need to determine if there is any custom data to deal with.

-		// Let's determine this by removing the default indexes to see if there's anything left in the array

-		// and set the session data while we're at it

-		foreach (array('session_id','ip_address','user_agent','last_activity') as $val)

-		{

-			unset($custom_userdata[$val]);

-			$cookie_userdata[$val] = $this->userdata[$val];

-		}

-

-		// Did we find any custom data?  If not, we turn the empty array into a string

-		// since there's no reason to serialize and store an empty array in the DB

-		if (count($custom_userdata) === 0)

-		{

-			$custom_userdata = '';

-		}

-		else

-		{

-			// Serialize the custom data array so we can store it

-			$custom_userdata = $this->_serialize($custom_userdata);

-		}

-

-		// Run the update query

-		$this->CI->db->where('session_id', $this->userdata['session_id']);

-		$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));

-

-		// Write the cookie.  Notice that we manually pass the cookie data array to the

-		// _set_cookie() function. Normally that function will store $this->userdata, but

-		// in this case that array contains custom data, which we do not want in the cookie.

-		$this->_set_cookie($cookie_userdata);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Create a new session

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function sess_create()

-	{

-		$sessid = '';

-		while (strlen($sessid) < 32)

-		{

-			$sessid .= mt_rand(0, mt_getrandmax());

-		}

-

-		// To make the session ID even more secure we'll combine it with the user's IP

-		$sessid .= $this->CI->input->ip_address();

-

-		$this->userdata = array(

-							'session_id' 	=> md5(uniqid($sessid, TRUE)),

-							'ip_address' 	=> $this->CI->input->ip_address(),

-							'user_agent' 	=> substr($this->CI->input->user_agent(), 0, 50),

-							'last_activity'	=> $this->now

-							);

-

-

-		// Save the data to the DB if needed

-		if ($this->sess_use_database === TRUE)

-		{

-			$this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));

-		}

-

-		// Write the cookie

-		$this->_set_cookie();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Update an existing session

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function sess_update()

-	{

-		// We only update the session every five minutes by default

-		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)

-		{

-			return;

-		}

-

-		// Save the old session id so we know which record to

-		// update in the database if we need it

-		$old_sessid = $this->userdata['session_id'];

-		$new_sessid = '';

-		while (strlen($new_sessid) < 32)

-		{

-			$new_sessid .= mt_rand(0, mt_getrandmax());

-		}

-

-		// To make the session ID even more secure we'll combine it with the user's IP

-		$new_sessid .= $this->CI->input->ip_address();

-

-		// Turn it into a hash

-		$new_sessid = md5(uniqid($new_sessid, TRUE));

-

-		// Update the session data in the session data array

-		$this->userdata['session_id'] = $new_sessid;

-		$this->userdata['last_activity'] = $this->now;

-

-		// _set_cookie() will handle this for us if we aren't using database sessions

-		// by pushing all userdata to the cookie.

-		$cookie_data = NULL;

-

-		// Update the session ID and last_activity field in the DB if needed

-		if ($this->sess_use_database === TRUE)

-		{

-			// set cookie explicitly to only have our session data

-			$cookie_data = array();

-			foreach (array('session_id','ip_address','user_agent','last_activity') as $val)

-			{

-				$cookie_data[$val] = $this->userdata[$val];

-			}

-

-			$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));

-		}

-

-		// Write the cookie

-		$this->_set_cookie($cookie_data);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Destroy the current session

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function sess_destroy()

-	{

-		// Kill the session DB row

-		if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))

-		{

-			$this->CI->db->where('session_id', $this->userdata['session_id']);

-			$this->CI->db->delete($this->sess_table_name);

-		}

-

-		// Kill the cookie

-		setcookie(

-					$this->sess_cookie_name,

-					addslashes(serialize(array())),

-					($this->now - 31500000),

-					$this->cookie_path,

-					$this->cookie_domain,

-					0

-				);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a specific item from the session array

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function userdata($item)

-	{

-		return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch all session data

-	 *

-	 * @access	public

-	 * @return	mixed

-	 */

-	function all_userdata()

-	{

-		return ( ! isset($this->userdata)) ? FALSE : $this->userdata;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add or change data in the "userdata" array

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @return	void

-	 */

-	function set_userdata($newdata = array(), $newval = '')

-	{

-		if (is_string($newdata))

-		{

-			$newdata = array($newdata => $newval);

-		}

-

-		if (count($newdata) > 0)

-		{

-			foreach ($newdata as $key => $val)

-			{

-				$this->userdata[$key] = $val;

-			}

-		}

-

-		$this->sess_write();

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Delete a session variable from the "userdata" array

-	 *

-	 * @access	array

-	 * @return	void

-	 */

-	function unset_userdata($newdata = array())

-	{

-		if (is_string($newdata))

-		{

-			$newdata = array($newdata => '');

-		}

-

-		if (count($newdata) > 0)

-		{

-			foreach ($newdata as $key => $val)

-			{

-				unset($this->userdata[$key]);

-			}

-		}

-

-		$this->sess_write();

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Add or change flashdata, only available

-	 * until the next request

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @return	void

-	 */

-	function set_flashdata($newdata = array(), $newval = '')

-	{

-		if (is_string($newdata))

-		{

-			$newdata = array($newdata => $newval);

-		}

-

-		if (count($newdata) > 0)

-		{

-			foreach ($newdata as $key => $val)

-			{

-				$flashdata_key = $this->flashdata_key.':new:'.$key;

-				$this->set_userdata($flashdata_key, $val);

-			}

-		}

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Keeps existing flashdata available to next request.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function keep_flashdata($key)

-	{

-		// 'old' flashdata gets removed.  Here we mark all

-		// flashdata as 'new' to preserve it from _flashdata_sweep()

-		// Note the function will return FALSE if the $key

-		// provided cannot be found

-		$old_flashdata_key = $this->flashdata_key.':old:'.$key;

-		$value = $this->userdata($old_flashdata_key);

-

-		$new_flashdata_key = $this->flashdata_key.':new:'.$key;

-		$this->set_userdata($new_flashdata_key, $value);

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Fetch a specific flashdata item from the session array

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function flashdata($key)

-	{

-		$flashdata_key = $this->flashdata_key.':old:'.$key;

-		return $this->userdata($flashdata_key);

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Identifies flashdata as 'old' for removal

-	 * when _flashdata_sweep() runs.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _flashdata_mark()

-	{

-		$userdata = $this->all_userdata();

-		foreach ($userdata as $name => $value)

-		{

-			$parts = explode(':new:', $name);

-			if (is_array($parts) && count($parts) === 2)

-			{

-				$new_name = $this->flashdata_key.':old:'.$parts[1];

-				$this->set_userdata($new_name, $value);

-				$this->unset_userdata($name);

-			}

-		}

-	}

-

-	// ------------------------------------------------------------------------

-

-	/**

-	 * Removes all flashdata marked as 'old'

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-

-	function _flashdata_sweep()

-	{

-		$userdata = $this->all_userdata();

-		foreach ($userdata as $key => $value)

-		{

-			if (strpos($key, ':old:'))

-			{

-				$this->unset_userdata($key);

-			}

-		}

-

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get the "now" time

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _get_time()

-	{

-		if (strtolower($this->time_reference) == 'gmt')

-		{

-			$now = time();

-			$time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));

-		}

-		else

-		{

-			$time = time();

-		}

-

-		return $time;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write the session cookie

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function _set_cookie($cookie_data = NULL)

-	{

-		if (is_null($cookie_data))

-		{

-			$cookie_data = $this->userdata;

-		}

-

-		// Serialize the userdata for the cookie

-		$cookie_data = $this->_serialize($cookie_data);

-

-		if ($this->sess_encrypt_cookie == TRUE)

-		{

-			$cookie_data = $this->CI->encrypt->encode($cookie_data);

-		}

-		else

-		{

-			// if encryption is not used, we provide an md5 hash to prevent userside tampering

-			$cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);

-		}

-

-		// Set the cookie

-		setcookie(

-					$this->sess_cookie_name,

-					$cookie_data,

-					$this->sess_expiration + time(),

-					$this->cookie_path,

-					$this->cookie_domain,

-					0

-				);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Serialize an array

-	 *

-	 * This function first converts any slashes found in the array to a temporary

-	 * marker, so when it gets unserialized the slashes will be preserved

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	string

-	 */

-	function _serialize($data)

-	{

-		if (is_array($data))

-		{

-			foreach ($data as $key => $val)

-			{

-				$data[$key] = str_replace('\\', '{{slash}}', $val);

-			}

-		}

-		else

-		{

-			$data = str_replace('\\', '{{slash}}', $data);

-		}

-

-		return serialize($data);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Unserialize

-	 *

-	 * This function unserializes a data string, then converts any

-	 * temporary slash markers back to actual slashes

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	string

-	 */

-	function _unserialize($data)

-	{

-		$data = @unserialize(strip_slashes($data));

-

-		if (is_array($data))

-		{

-			foreach ($data as $key => $val)

-			{

-				$data[$key] = str_replace('{{slash}}', '\\', $val);

-			}

-

-			return $data;

-		}

-

-		return str_replace('{{slash}}', '\\', $data);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Garbage collection

-	 *

-	 * This deletes expired session rows from database

-	 * if the probability percentage is met

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function _sess_gc()

-	{

-		if ($this->sess_use_database != TRUE)

-		{

-			return;

-		}

-

-		srand(time());

-		if ((rand() % 100) < $this->gc_probability)

-		{

-			$expire = $this->now - $this->sess_expiration;

-

-			$this->CI->db->where("last_activity < {$expire}");

-			$this->CI->db->delete($this->sess_table_name);

-

-			log_message('debug', 'Session garbage collection performed.');

-		}

-	}

-

-

-}

-// END Session Class

-

-/* End of file Session.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Session Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Sessions
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/sessions.html
+ */
+class CI_Session {
+
+	var $sess_encrypt_cookie		= FALSE;
+	var $sess_use_database			= FALSE;
+	var $sess_table_name			= '';
+	var $sess_expiration			= 7200;
+	var $sess_match_ip				= FALSE;
+	var $sess_match_useragent		= TRUE;
+	var $sess_cookie_name			= 'ci_session';
+	var $cookie_prefix				= '';
+	var $cookie_path				= '';
+	var $cookie_domain				= '';
+	var $sess_time_to_update		= 300;
+	var $encryption_key				= '';
+	var $flashdata_key 				= 'flash';
+	var $time_reference				= 'time';
+	var $gc_probability				= 5;
+	var $userdata					= array();
+	var $CI;
+	var $now;
+
+	/**
+	 * Session Constructor
+	 *
+	 * The constructor runs the session routines automatically
+	 * whenever the class is instantiated.
+	 */
+	function CI_Session($params = array())
+	{
+		log_message('debug', "Session Class Initialized");
+
+		// Set the super object to a local variable for use throughout the class
+		$this->CI =& get_instance();
+
+		// 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_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
+		{
+			$this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
+		}
+
+		// Load the string helper so we can use the strip_slashes() function
+		$this->CI->load->helper('string');
+
+		// Do we need encryption? If so, load the encryption class
+		if ($this->sess_encrypt_cookie == TRUE)
+		{
+			$this->CI->load->library('encrypt');
+		}
+
+		// Are we using a database?  If so, load it
+		if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
+		{
+			$this->CI->load->database();
+		}
+
+		// Set the "now" time.  Can either be GMT or server time, based on the
+		// config prefs.  We use this to set the "last activity" time
+		$this->now = $this->_get_time();
+
+		// Set the session length. If the session expiration is
+		// set to zero we'll set the expiration two years from now.
+		if ($this->sess_expiration == 0)
+		{
+			$this->sess_expiration = (60*60*24*365*2);
+		}
+		 
+		// Set the cookie name
+		$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
+
+		// Run the Session routine. If a session doesn't exist we'll
+		// create a new one.  If it does, we'll update it.
+		if ( ! $this->sess_read())
+		{
+			$this->sess_create();
+		}
+		else
+		{
+			$this->sess_update();
+		}
+
+		// Delete 'old' flashdata (from last request)
+	   	$this->_flashdata_sweep();
+
+		// Mark all new flashdata as old (data will be deleted before next request)
+	   	$this->_flashdata_mark();
+
+		// Delete expired sessions if necessary
+		$this->_sess_gc();
+
+		log_message('debug', "Session routines successfully run");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch the current session data if it exists
+	 *
+	 * @access	public
+	 * @return	bool
+	 */
+	function sess_read()
+	{
+		// Fetch the cookie
+		$session = $this->CI->input->cookie($this->sess_cookie_name);
+
+		// No cookie?  Goodbye cruel world!...
+		if ($session === FALSE)
+		{
+			log_message('debug', 'A session cookie was not found.');
+			return FALSE;
+		}
+
+		// Decrypt the cookie data
+		if ($this->sess_encrypt_cookie == TRUE)
+		{
+			$session = $this->CI->encrypt->decode($session);
+		}
+		else
+		{
+			// encryption was not used, so we need to check the md5 hash
+			$hash	 = substr($session, strlen($session)-32); // get last 32 chars
+			$session = substr($session, 0, strlen($session)-32);
+
+			// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
+			if ($hash !==  md5($session.$this->encryption_key))
+			{
+				log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
+				$this->sess_destroy();
+				return FALSE;
+			}
+		}
+
+		// Unserialize the session array
+		$session = $this->_unserialize($session);
+
+		// Is the session data we unserialized an array with the correct format?
+		if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Is the session current?
+		if (($session['last_activity'] + $this->sess_expiration) < $this->now)
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Does the IP Match?
+		if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Does the User Agent Match?
+		if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))
+		{
+			$this->sess_destroy();
+			return FALSE;
+		}
+
+		// Is there a corresponding session in the DB?
+		if ($this->sess_use_database === TRUE)
+		{
+			$this->CI->db->where('session_id', $session['session_id']);
+
+			if ($this->sess_match_ip == TRUE)
+			{
+				$this->CI->db->where('ip_address', $session['ip_address']);
+			}
+
+			if ($this->sess_match_useragent == TRUE)
+			{
+				$this->CI->db->where('user_agent', $session['user_agent']);
+			}
+
+			$query = $this->CI->db->get($this->sess_table_name);
+
+			// No result?  Kill it!
+			if ($query->num_rows() == 0)
+			{
+				$this->sess_destroy();
+				return FALSE;
+			}
+
+			// Is there custom data?  If so, add it to the main session array
+			$row = $query->row();
+			if (isset($row->user_data) AND $row->user_data != '')
+			{
+				$custom_data = $this->_unserialize($row->user_data);
+
+				if (is_array($custom_data))
+				{
+					foreach ($custom_data as $key => $val)
+					{
+						$session[$key] = $val;
+					}
+				}
+			}
+		}
+
+		// Session is valid!
+		$this->userdata = $session;
+		unset($session);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write the session data
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function sess_write()
+	{
+		// Are we saving custom data to the DB?  If not, all we do is update the cookie
+		if ($this->sess_use_database === FALSE)
+		{
+			$this->_set_cookie();
+			return;
+		}
+
+		// set the custom userdata, the session data we will set in a second
+		$custom_userdata = $this->userdata;
+		$cookie_userdata = array();
+
+		// Before continuing, we need to determine if there is any custom data to deal with.
+		// Let's determine this by removing the default indexes to see if there's anything left in the array
+		// and set the session data while we're at it
+		foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
+		{
+			unset($custom_userdata[$val]);
+			$cookie_userdata[$val] = $this->userdata[$val];
+		}
+
+		// Did we find any custom data?  If not, we turn the empty array into a string
+		// since there's no reason to serialize and store an empty array in the DB
+		if (count($custom_userdata) === 0)
+		{
+			$custom_userdata = '';
+		}
+		else
+		{
+			// Serialize the custom data array so we can store it
+			$custom_userdata = $this->_serialize($custom_userdata);
+		}
+
+		// Run the update query
+		$this->CI->db->where('session_id', $this->userdata['session_id']);
+		$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
+
+		// Write the cookie.  Notice that we manually pass the cookie data array to the
+		// _set_cookie() function. Normally that function will store $this->userdata, but
+		// in this case that array contains custom data, which we do not want in the cookie.
+		$this->_set_cookie($cookie_userdata);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create a new session
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function sess_create()
+	{
+		$sessid = '';
+		while (strlen($sessid) < 32)
+		{
+			$sessid .= mt_rand(0, mt_getrandmax());
+		}
+
+		// To make the session ID even more secure we'll combine it with the user's IP
+		$sessid .= $this->CI->input->ip_address();
+
+		$this->userdata = array(
+							'session_id' 	=> md5(uniqid($sessid, TRUE)),
+							'ip_address' 	=> $this->CI->input->ip_address(),
+							'user_agent' 	=> substr($this->CI->input->user_agent(), 0, 50),
+							'last_activity'	=> $this->now
+							);
+
+
+		// Save the data to the DB if needed
+		if ($this->sess_use_database === TRUE)
+		{
+			$this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));
+		}
+
+		// Write the cookie
+		$this->_set_cookie();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Update an existing session
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function sess_update()
+	{
+		// We only update the session every five minutes by default
+		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
+		{
+			return;
+		}
+
+		// Save the old session id so we know which record to
+		// update in the database if we need it
+		$old_sessid = $this->userdata['session_id'];
+		$new_sessid = '';
+		while (strlen($new_sessid) < 32)
+		{
+			$new_sessid .= mt_rand(0, mt_getrandmax());
+		}
+
+		// To make the session ID even more secure we'll combine it with the user's IP
+		$new_sessid .= $this->CI->input->ip_address();
+
+		// Turn it into a hash
+		$new_sessid = md5(uniqid($new_sessid, TRUE));
+
+		// Update the session data in the session data array
+		$this->userdata['session_id'] = $new_sessid;
+		$this->userdata['last_activity'] = $this->now;
+
+		// _set_cookie() will handle this for us if we aren't using database sessions
+		// by pushing all userdata to the cookie.
+		$cookie_data = NULL;
+
+		// Update the session ID and last_activity field in the DB if needed
+		if ($this->sess_use_database === TRUE)
+		{
+			// set cookie explicitly to only have our session data
+			$cookie_data = array();
+			foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
+			{
+				$cookie_data[$val] = $this->userdata[$val];
+			}
+
+			$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
+		}
+
+		// Write the cookie
+		$this->_set_cookie($cookie_data);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Destroy the current session
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function sess_destroy()
+	{
+		// Kill the session DB row
+		if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
+		{
+			$this->CI->db->where('session_id', $this->userdata['session_id']);
+			$this->CI->db->delete($this->sess_table_name);
+		}
+
+		// Kill the cookie
+		setcookie(
+					$this->sess_cookie_name,
+					addslashes(serialize(array())),
+					($this->now - 31500000),
+					$this->cookie_path,
+					$this->cookie_domain,
+					0
+				);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a specific item from the session array
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function userdata($item)
+	{
+		return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch all session data
+	 *
+	 * @access	public
+	 * @return	mixed
+	 */
+	function all_userdata()
+	{
+		return ( ! isset($this->userdata)) ? FALSE : $this->userdata;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add or change data in the "userdata" array
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
+	function set_userdata($newdata = array(), $newval = '')
+	{
+		if (is_string($newdata))
+		{
+			$newdata = array($newdata => $newval);
+		}
+
+		if (count($newdata) > 0)
+		{
+			foreach ($newdata as $key => $val)
+			{
+				$this->userdata[$key] = $val;
+			}
+		}
+
+		$this->sess_write();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Delete a session variable from the "userdata" array
+	 *
+	 * @access	array
+	 * @return	void
+	 */
+	function unset_userdata($newdata = array())
+	{
+		if (is_string($newdata))
+		{
+			$newdata = array($newdata => '');
+		}
+
+		if (count($newdata) > 0)
+		{
+			foreach ($newdata as $key => $val)
+			{
+				unset($this->userdata[$key]);
+			}
+		}
+
+		$this->sess_write();
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Add or change flashdata, only available
+	 * until the next request
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
+	function set_flashdata($newdata = array(), $newval = '')
+	{
+		if (is_string($newdata))
+		{
+			$newdata = array($newdata => $newval);
+		}
+
+		if (count($newdata) > 0)
+		{
+			foreach ($newdata as $key => $val)
+			{
+				$flashdata_key = $this->flashdata_key.':new:'.$key;
+				$this->set_userdata($flashdata_key, $val);
+			}
+		}
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Keeps existing flashdata available to next request.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function keep_flashdata($key)
+	{
+		// 'old' flashdata gets removed.  Here we mark all
+		// flashdata as 'new' to preserve it from _flashdata_sweep()
+		// Note the function will return FALSE if the $key
+		// provided cannot be found
+		$old_flashdata_key = $this->flashdata_key.':old:'.$key;
+		$value = $this->userdata($old_flashdata_key);
+
+		$new_flashdata_key = $this->flashdata_key.':new:'.$key;
+		$this->set_userdata($new_flashdata_key, $value);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Fetch a specific flashdata item from the session array
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function flashdata($key)
+	{
+		$flashdata_key = $this->flashdata_key.':old:'.$key;
+		return $this->userdata($flashdata_key);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Identifies flashdata as 'old' for removal
+	 * when _flashdata_sweep() runs.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _flashdata_mark()
+	{
+		$userdata = $this->all_userdata();
+		foreach ($userdata as $name => $value)
+		{
+			$parts = explode(':new:', $name);
+			if (is_array($parts) && count($parts) === 2)
+			{
+				$new_name = $this->flashdata_key.':old:'.$parts[1];
+				$this->set_userdata($new_name, $value);
+				$this->unset_userdata($name);
+			}
+		}
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Removes all flashdata marked as 'old'
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+
+	function _flashdata_sweep()
+	{
+		$userdata = $this->all_userdata();
+		foreach ($userdata as $key => $value)
+		{
+			if (strpos($key, ':old:'))
+			{
+				$this->unset_userdata($key);
+			}
+		}
+
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get the "now" time
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _get_time()
+	{
+		if (strtolower($this->time_reference) == 'gmt')
+		{
+			$now = time();
+			$time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
+		}
+		else
+		{
+			$time = time();
+		}
+
+		return $time;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write the session cookie
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function _set_cookie($cookie_data = NULL)
+	{
+		if (is_null($cookie_data))
+		{
+			$cookie_data = $this->userdata;
+		}
+
+		// Serialize the userdata for the cookie
+		$cookie_data = $this->_serialize($cookie_data);
+
+		if ($this->sess_encrypt_cookie == TRUE)
+		{
+			$cookie_data = $this->CI->encrypt->encode($cookie_data);
+		}
+		else
+		{
+			// if encryption is not used, we provide an md5 hash to prevent userside tampering
+			$cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
+		}
+
+		// Set the cookie
+		setcookie(
+					$this->sess_cookie_name,
+					$cookie_data,
+					$this->sess_expiration + time(),
+					$this->cookie_path,
+					$this->cookie_domain,
+					0
+				);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize an array
+	 *
+	 * This function first converts any slashes found in the array to a temporary
+	 * marker, so when it gets unserialized the slashes will be preserved
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	string
+	 */
+	function _serialize($data)
+	{
+		if (is_array($data))
+		{
+			foreach ($data as $key => $val)
+			{
+				$data[$key] = str_replace('\\', '{{slash}}', $val);
+			}
+		}
+		else
+		{
+			$data = str_replace('\\', '{{slash}}', $data);
+		}
+
+		return serialize($data);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Unserialize
+	 *
+	 * This function unserializes a data string, then converts any
+	 * temporary slash markers back to actual slashes
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	string
+	 */
+	function _unserialize($data)
+	{
+		$data = @unserialize(strip_slashes($data));
+
+		if (is_array($data))
+		{
+			foreach ($data as $key => $val)
+			{
+				$data[$key] = str_replace('{{slash}}', '\\', $val);
+			}
+
+			return $data;
+		}
+
+		return str_replace('{{slash}}', '\\', $data);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Garbage collection
+	 *
+	 * This deletes expired session rows from database
+	 * if the probability percentage is met
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function _sess_gc()
+	{
+		if ($this->sess_use_database != TRUE)
+		{
+			return;
+		}
+
+		srand(time());
+		if ((rand() % 100) < $this->gc_probability)
+		{
+			$expire = $this->now - $this->sess_expiration;
+
+			$this->CI->db->where("last_activity < {$expire}");
+			$this->CI->db->delete($this->sess_table_name);
+
+			log_message('debug', 'Session garbage collection performed.');
+		}
+	}
+
+
+}
+// END Session Class
+
+/* End of file Session.php */
 /* Location: ./system/libraries/Session.php */
\ No newline at end of file
diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php
index 282cdb2..93982bf 100644
--- a/system/libraries/Sha1.php
+++ b/system/libraries/Sha1.php
@@ -1,251 +1,251 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * SHA1 Encoding Class

- *

- * Purpose: Provides 160 bit hashing using The Secure Hash Algorithm

- * developed at the National Institute of Standards and Technology. The 40

- * character SHA1 message hash is computationally infeasible to crack.

- *

- * This class is a fallback for servers that are not running PHP greater than

- * 4.3, or do not have the MHASH library.

- *

- * This class is based on two scripts:

- *

- * Marcus Campbell's PHP implementation (GNU license)

- * http://www.tecknik.net/sha-1/

- *

- * ...which is based on Paul Johnston's JavaScript version

- * (BSD license). http://pajhome.org.uk/

- *

- * I encapsulated the functions and wrote one additional method to fix

- * a hex conversion bug. - Rick Ellis

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Encryption

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/general/encryption.html

- */

-class CI_SHA {

-

-	function CI_SHA()

-	{

-		log_message('debug', "SHA1 Class Initialized");

-	}

-

-	/**

-	 * Generate the Hash

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function generate($str)

-	{

-		$n = ((strlen($str) + 8) >> 6) + 1;

-

-		for ($i = 0; $i < $n * 16; $i++)

-		{

-			$x[$i] = 0;

-		}

-

-		for ($i = 0; $i < strlen($str); $i++)

-		{

-			$x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);

-		}

-

-		$x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);

-

-		$x[$n * 16 - 1] = strlen($str) * 8;

-

-		$a =  1732584193;

-		$b = -271733879;

-		$c = -1732584194;

-		$d =  271733878;

-		$e = -1009589776;

-

-		for ($i = 0; $i < sizeof($x); $i += 16)

-		{

-			$olda = $a;

-			$oldb = $b;

-			$oldc = $c;

-			$oldd = $d;

-			$olde = $e;

-

-			for($j = 0; $j < 80; $j++)

-			{

-				if ($j < 16)

-				{

-					$w[$j] = $x[$i + $j];

-				}

-				else

-				{

-					$w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);

-				}

-

-				$t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j)));

-

-				$e = $d;

-				$d = $c;

-				$c = $this->_rol($b, 30);

-				$b = $a;

-				$a = $t;

-			}

-

-			$a = $this->_safe_add($a, $olda);

-			$b = $this->_safe_add($b, $oldb);

-			$c = $this->_safe_add($c, $oldc);

-			$d = $this->_safe_add($d, $oldd);

-			$e = $this->_safe_add($e, $olde);

-		}

-

-		return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e);

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Convert a decimal to hex

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */	

-	function _hex($str)

-	{

-		$str = dechex($str);

-

-		if (strlen($str) == 7)

-		{

-			$str = '0'.$str;

-		}

-

-		return $str;

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 *  Return result based on iteration

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _ft($t, $b, $c, $d)

-	{

-		if ($t < 20)

-			return ($b & $c) | ((~$b) & $d);

-		if ($t < 40)

-			return $b ^ $c ^ $d;

-		if ($t < 60)

-			return ($b & $c) | ($b & $d) | ($c & $d);

-

-		return $b ^ $c ^ $d;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Determine the additive constant

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _kt($t)

-	{

-		if ($t < 20)

-		{

-			return 1518500249;

-		}

-		else if ($t < 40)

-		{

-			return 1859775393;

-		}

-		else if ($t < 60)

-		{

-			return -1894007588;

-		}

-		else

-		{

-			return -899497514;

-		}

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add integers, wrapping at 2^32

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _safe_add($x, $y)

-	{

-		$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);

-		$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);

-

-		return ($msw << 16) | ($lsw & 0xFFFF);

-	}

-  	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Bitwise rotate a 32-bit number

-	 *

-	 * @access	private

-	 * @return	integer

-	 */	

-	function _rol($num, $cnt)

-	{

-		return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Pad string with zero

-	 *

-	 * @access	private

-	 * @return	string

-	 */	

-	function _zero_fill($a, $b)

-	{

-		$bin = decbin($a);

-

-		if (strlen($bin) < $b)

-		{

-			$bin = 0;

-		}

-		else

-		{

-			$bin = substr($bin, 0, strlen($bin) - $b);

-		}

-

-		for ($i=0; $i < $b; $i++)

-		{

-			$bin = "0".$bin;

-		}

-

-		return bindec($bin);

-	}

-}

-// END CI_SHA

-

-/* End of file Sha1.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * SHA1 Encoding Class
+ *
+ * Purpose: Provides 160 bit hashing using The Secure Hash Algorithm
+ * developed at the National Institute of Standards and Technology. The 40
+ * character SHA1 message hash is computationally infeasible to crack.
+ *
+ * This class is a fallback for servers that are not running PHP greater than
+ * 4.3, or do not have the MHASH library.
+ *
+ * This class is based on two scripts:
+ *
+ * Marcus Campbell's PHP implementation (GNU license)
+ * http://www.tecknik.net/sha-1/
+ *
+ * ...which is based on Paul Johnston's JavaScript version
+ * (BSD license). http://pajhome.org.uk/
+ *
+ * I encapsulated the functions and wrote one additional method to fix
+ * a hex conversion bug. - Rick Ellis
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Encryption
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/general/encryption.html
+ */
+class CI_SHA {
+
+	function CI_SHA()
+	{
+		log_message('debug', "SHA1 Class Initialized");
+	}
+
+	/**
+	 * Generate the Hash
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function generate($str)
+	{
+		$n = ((strlen($str) + 8) >> 6) + 1;
+
+		for ($i = 0; $i < $n * 16; $i++)
+		{
+			$x[$i] = 0;
+		}
+
+		for ($i = 0; $i < strlen($str); $i++)
+		{
+			$x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);
+		}
+
+		$x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
+
+		$x[$n * 16 - 1] = strlen($str) * 8;
+
+		$a =  1732584193;
+		$b = -271733879;
+		$c = -1732584194;
+		$d =  271733878;
+		$e = -1009589776;
+
+		for ($i = 0; $i < sizeof($x); $i += 16)
+		{
+			$olda = $a;
+			$oldb = $b;
+			$oldc = $c;
+			$oldd = $d;
+			$olde = $e;
+
+			for($j = 0; $j < 80; $j++)
+			{
+				if ($j < 16)
+				{
+					$w[$j] = $x[$i + $j];
+				}
+				else
+				{
+					$w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);
+				}
+
+				$t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j)));
+
+				$e = $d;
+				$d = $c;
+				$c = $this->_rol($b, 30);
+				$b = $a;
+				$a = $t;
+			}
+
+			$a = $this->_safe_add($a, $olda);
+			$b = $this->_safe_add($b, $oldb);
+			$c = $this->_safe_add($c, $oldc);
+			$d = $this->_safe_add($d, $oldd);
+			$e = $this->_safe_add($e, $olde);
+		}
+
+		return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e);
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Convert a decimal to hex
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */	
+	function _hex($str)
+	{
+		$str = dechex($str);
+
+		if (strlen($str) == 7)
+		{
+			$str = '0'.$str;
+		}
+
+		return $str;
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 *  Return result based on iteration
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _ft($t, $b, $c, $d)
+	{
+		if ($t < 20)
+			return ($b & $c) | ((~$b) & $d);
+		if ($t < 40)
+			return $b ^ $c ^ $d;
+		if ($t < 60)
+			return ($b & $c) | ($b & $d) | ($c & $d);
+
+		return $b ^ $c ^ $d;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Determine the additive constant
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _kt($t)
+	{
+		if ($t < 20)
+		{
+			return 1518500249;
+		}
+		else if ($t < 40)
+		{
+			return 1859775393;
+		}
+		else if ($t < 60)
+		{
+			return -1894007588;
+		}
+		else
+		{
+			return -899497514;
+		}
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add integers, wrapping at 2^32
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _safe_add($x, $y)
+	{
+		$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
+		$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
+
+		return ($msw << 16) | ($lsw & 0xFFFF);
+	}
+  	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Bitwise rotate a 32-bit number
+	 *
+	 * @access	private
+	 * @return	integer
+	 */	
+	function _rol($num, $cnt)
+	{
+		return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Pad string with zero
+	 *
+	 * @access	private
+	 * @return	string
+	 */	
+	function _zero_fill($a, $b)
+	{
+		$bin = decbin($a);
+
+		if (strlen($bin) < $b)
+		{
+			$bin = 0;
+		}
+		else
+		{
+			$bin = substr($bin, 0, strlen($bin) - $b);
+		}
+
+		for ($i=0; $i < $b; $i++)
+		{
+			$bin = "0".$bin;
+		}
+
+		return bindec($bin);
+	}
+}
+// END CI_SHA
+
+/* End of file Sha1.php */
 /* Location: ./system/libraries/Sha1.php */
\ No newline at end of file
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 6940ece..1afc17c 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -1,440 +1,440 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.3.1

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * HTML Table Generating Class

- *

- * Lets you create tables manually or from database result objects, or arrays.

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	HTML Tables

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/uri.html

- */

-class CI_Table {

-

-	var $rows				= array();

-	var $heading			= array();

-	var $auto_heading		= TRUE;	

-	var $caption			= NULL;	

-	var $template 			= NULL;

-	var $newline			= "\n";

-	var $empty_cells		= "";

-	

-	

-	function CI_Table()

-	{

-		log_message('debug', "Table Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the template

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function set_template($template)

-	{

-		if ( ! is_array($template))

-		{

-			return FALSE;

-		}

-	

-		$this->template = $template;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set the table heading

-	 *

-	 * Can be passed as an array or discreet params

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @return	void

-	 */

-	function set_heading()

-	{

-		$args = func_get_args();

-		$this->heading = (is_array($args[0])) ? $args[0] : $args;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set columns.  Takes a one-dimensional array as input and creates

-	 * a multi-dimensional array with a depth equal to the number of

-	 * columns.  This allows a single array with many elements to  be

-	 * displayed in a table that has a fixed column count.

-	 *

-	 * @access	public

-	 * @param	array

-	 * @param	int

-	 * @return	void

-	 */

-	function make_columns($array = array(), $col_limit = 0)

-	{

-		if ( ! is_array($array) OR count($array) == 0)

-		{

-			return FALSE;

-		}

-		

-		// Turn off the auto-heading feature since it's doubtful we 

-		// will want headings from a one-dimensional array

-		$this->auto_heading = FALSE;

-		

-		if ($col_limit == 0)

-		{

-			return $array;

-		}

-	

-		$new = array();

-		while(count($array) > 0)

-		{	

-			$temp = array_splice($array, 0, $col_limit);

-			

-			if (count($temp) < $col_limit)

-			{

-				for ($i = count($temp); $i < $col_limit; $i++)

-				{

-					$temp[] = '&nbsp;';

-				}

-			}

-			

-			$new[] = $temp;

-		}

-		

-		return $new;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set "empty" cells

-	 *

-	 * Can be passed as an array or discreet params

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @return	void

-	 */

-	function set_empty($value)

-	{

-		$this->empty_cells = $value;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add a table row

-	 *

-	 * Can be passed as an array or discreet params

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @return	void

-	 */

-	function add_row()

-	{

-		$args = func_get_args();

-		$this->rows[] = (is_array($args[0])) ? $args[0] : $args;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add a table caption

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */

-	function set_caption($caption)

-	{

-		$this->caption = $caption;

-	}	

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate the table

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @return	string

-	 */

-	function generate($table_data = NULL)

-	{

-		// The table data can optionally be passed to this function

-		// either as a database result object or an array

-		if ( ! is_null($table_data))

-		{

-			if (is_object($table_data))

-			{

-				$this->_set_from_object($table_data);

-			}

-			elseif (is_array($table_data))

-			{

-				$set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;

-				$this->_set_from_array($table_data, $set_heading);

-			}

-		}

-	

-		// Is there anything to display?  No?  Smite them!

-		if (count($this->heading) == 0 AND count($this->rows) == 0)

-		{

-			return 'Undefined table data';

-		}

-	

-		// Compile and validate the template date

-		$this->_compile_template();

-	

-	

-		// Build the table!

-		

-		$out = $this->template['table_open'];

-		$out .= $this->newline;		

-

-		// Add any caption here

-		if ($this->caption)

-		{

-			$out .= $this->newline;

-			$out .= '<caption>' . $this->caption . '</caption>';

-			$out .= $this->newline;

-		}

-

-		// Is there a table heading to display?

-		if (count($this->heading) > 0)

-		{

-			$out .= $this->template['heading_row_start'];

-			$out .= $this->newline;		

-

-			foreach($this->heading as $heading)

-			{

-				$out .= $this->template['heading_cell_start'];

-				$out .= $heading;

-				$out .= $this->template['heading_cell_end'];

-			}

-

-			$out .= $this->template['heading_row_end'];

-			$out .= $this->newline;				

-		}

-

-		// Build the table rows

-		if (count($this->rows) > 0)

-		{

-			$i = 1;

-			foreach($this->rows as $row)

-			{

-				if ( ! is_array($row))

-				{

-					break;

-				}

-			

-				// We use modulus to alternate the row colors

-				$name = (fmod($i++, 2)) ? '' : 'alt_';

-			

-				$out .= $this->template['row_'.$name.'start'];

-				$out .= $this->newline;		

-	

-				foreach($row as $cell)

-				{

-					$out .= $this->template['cell_'.$name.'start'];

-					

-					if ($cell === "")

-					{

-						$out .= $this->empty_cells;

-					}

-					else

-					{

-						$out .= $cell;

-					}

-					

-					$out .= $this->template['cell_'.$name.'end'];

-				}

-	

-				$out .= $this->template['row_'.$name.'end'];

-				$out .= $this->newline;	

-			}

-		}

-

-		$out .= $this->template['table_close'];

-	

-		return $out;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Clears the table arrays.  Useful if multiple tables are being generated

-	 *

-	 * @access	public

-	 * @return	void

-	 */

-	function clear()

-	{

-		$this->rows				= array();

-		$this->heading			= array();

-		$this->auto_heading		= TRUE;	

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set table data from a database result object

-	 *

-	 * @access	public

-	 * @param	object

-	 * @return	void

-	 */

-	function _set_from_object($query)

-	{

-		if ( ! is_object($query))

-		{

-			return FALSE;

-		}

-		

-		// First generate the headings from the table column names

-		if (count($this->heading) == 0)

-		{

-			if ( ! method_exists($query, 'list_fields'))

-			{

-				return FALSE;

-			}

-			

-			$this->heading = $query->list_fields();

-		}

-				

-		// Next blast through the result array and build out the rows

-		

-		if ($query->num_rows() > 0)

-		{

-			foreach ($query->result_array() as $row)

-			{

-				$this->rows[] = $row;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Set table data from an array

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */

-	function _set_from_array($data, $set_heading = TRUE)

-	{

-		if ( ! is_array($data) OR count($data) == 0)

-		{

-			return FALSE;

-		}

-		

-		$i = 0;

-		foreach ($data as $row)

-		{

-			if ( ! is_array($row))

-			{

-				$this->rows[] = $data;

-				break;

-			}

-						

-			// If a heading hasn't already been set we'll use the first row of the array as the heading

-			if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE)

-			{

-				$this->heading = $row;

-			}

-			else

-			{

-				$this->rows[] = $row;

-			}

-			

-			$i++;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Compile Template

-	 *

-	 * @access	private

-	 * @return	void

-	 */

- 	function _compile_template()

- 	{ 	

- 		if ($this->template == NULL)

- 		{

- 			$this->template = $this->_default_template();

- 			return;

- 		}

-		

-		$this->temp = $this->_default_template();

-		foreach (array('table_open','heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val)

-		{

-			if ( ! isset($this->template[$val]))

-			{

-				$this->template[$val] = $this->temp[$val];

-			}

-		} 	

- 	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Default Template

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _default_template()

-	{

-		return  array (

-						'table_open' 			=> '<table border="0" cellpadding="4" cellspacing="0">',

-

-						'heading_row_start' 	=> '<tr>',

-						'heading_row_end' 		=> '</tr>',

-						'heading_cell_start'	=> '<th>',

-						'heading_cell_end'		=> '</th>',

-

-						'row_start' 			=> '<tr>',

-						'row_end' 				=> '</tr>',

-						'cell_start'			=> '<td>',

-						'cell_end'				=> '</td>',

-

-						'row_alt_start' 		=> '<tr>',

-						'row_alt_end' 			=> '</tr>',

-						'cell_alt_start'		=> '<td>',

-						'cell_alt_end'			=> '</td>',

-

-						'table_close' 			=> '</table>'

-					);	

-	}

-	

-

-}

-

-

-/* End of file Table.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.3.1
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * HTML Table Generating Class
+ *
+ * Lets you create tables manually or from database result objects, or arrays.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	HTML Tables
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/uri.html
+ */
+class CI_Table {
+
+	var $rows				= array();
+	var $heading			= array();
+	var $auto_heading		= TRUE;	
+	var $caption			= NULL;	
+	var $template 			= NULL;
+	var $newline			= "\n";
+	var $empty_cells		= "";
+	
+	
+	function CI_Table()
+	{
+		log_message('debug', "Table Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the template
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function set_template($template)
+	{
+		if ( ! is_array($template))
+		{
+			return FALSE;
+		}
+	
+		$this->template = $template;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set the table heading
+	 *
+	 * Can be passed as an array or discreet params
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	void
+	 */
+	function set_heading()
+	{
+		$args = func_get_args();
+		$this->heading = (is_array($args[0])) ? $args[0] : $args;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set columns.  Takes a one-dimensional array as input and creates
+	 * a multi-dimensional array with a depth equal to the number of
+	 * columns.  This allows a single array with many elements to  be
+	 * displayed in a table that has a fixed column count.
+	 *
+	 * @access	public
+	 * @param	array
+	 * @param	int
+	 * @return	void
+	 */
+	function make_columns($array = array(), $col_limit = 0)
+	{
+		if ( ! is_array($array) OR count($array) == 0)
+		{
+			return FALSE;
+		}
+		
+		// Turn off the auto-heading feature since it's doubtful we 
+		// will want headings from a one-dimensional array
+		$this->auto_heading = FALSE;
+		
+		if ($col_limit == 0)
+		{
+			return $array;
+		}
+	
+		$new = array();
+		while(count($array) > 0)
+		{	
+			$temp = array_splice($array, 0, $col_limit);
+			
+			if (count($temp) < $col_limit)
+			{
+				for ($i = count($temp); $i < $col_limit; $i++)
+				{
+					$temp[] = '&nbsp;';
+				}
+			}
+			
+			$new[] = $temp;
+		}
+		
+		return $new;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set "empty" cells
+	 *
+	 * Can be passed as an array or discreet params
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	void
+	 */
+	function set_empty($value)
+	{
+		$this->empty_cells = $value;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add a table row
+	 *
+	 * Can be passed as an array or discreet params
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	void
+	 */
+	function add_row()
+	{
+		$args = func_get_args();
+		$this->rows[] = (is_array($args[0])) ? $args[0] : $args;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add a table caption
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function set_caption($caption)
+	{
+		$this->caption = $caption;
+	}	
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate the table
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	string
+	 */
+	function generate($table_data = NULL)
+	{
+		// The table data can optionally be passed to this function
+		// either as a database result object or an array
+		if ( ! is_null($table_data))
+		{
+			if (is_object($table_data))
+			{
+				$this->_set_from_object($table_data);
+			}
+			elseif (is_array($table_data))
+			{
+				$set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
+				$this->_set_from_array($table_data, $set_heading);
+			}
+		}
+	
+		// Is there anything to display?  No?  Smite them!
+		if (count($this->heading) == 0 AND count($this->rows) == 0)
+		{
+			return 'Undefined table data';
+		}
+	
+		// Compile and validate the template date
+		$this->_compile_template();
+	
+	
+		// Build the table!
+		
+		$out = $this->template['table_open'];
+		$out .= $this->newline;		
+
+		// Add any caption here
+		if ($this->caption)
+		{
+			$out .= $this->newline;
+			$out .= '<caption>' . $this->caption . '</caption>';
+			$out .= $this->newline;
+		}
+
+		// Is there a table heading to display?
+		if (count($this->heading) > 0)
+		{
+			$out .= $this->template['heading_row_start'];
+			$out .= $this->newline;		
+
+			foreach($this->heading as $heading)
+			{
+				$out .= $this->template['heading_cell_start'];
+				$out .= $heading;
+				$out .= $this->template['heading_cell_end'];
+			}
+
+			$out .= $this->template['heading_row_end'];
+			$out .= $this->newline;				
+		}
+
+		// Build the table rows
+		if (count($this->rows) > 0)
+		{
+			$i = 1;
+			foreach($this->rows as $row)
+			{
+				if ( ! is_array($row))
+				{
+					break;
+				}
+			
+				// We use modulus to alternate the row colors
+				$name = (fmod($i++, 2)) ? '' : 'alt_';
+			
+				$out .= $this->template['row_'.$name.'start'];
+				$out .= $this->newline;		
+	
+				foreach($row as $cell)
+				{
+					$out .= $this->template['cell_'.$name.'start'];
+					
+					if ($cell === "")
+					{
+						$out .= $this->empty_cells;
+					}
+					else
+					{
+						$out .= $cell;
+					}
+					
+					$out .= $this->template['cell_'.$name.'end'];
+				}
+	
+				$out .= $this->template['row_'.$name.'end'];
+				$out .= $this->newline;	
+			}
+		}
+
+		$out .= $this->template['table_close'];
+	
+		return $out;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Clears the table arrays.  Useful if multiple tables are being generated
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function clear()
+	{
+		$this->rows				= array();
+		$this->heading			= array();
+		$this->auto_heading		= TRUE;	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set table data from a database result object
+	 *
+	 * @access	public
+	 * @param	object
+	 * @return	void
+	 */
+	function _set_from_object($query)
+	{
+		if ( ! is_object($query))
+		{
+			return FALSE;
+		}
+		
+		// First generate the headings from the table column names
+		if (count($this->heading) == 0)
+		{
+			if ( ! method_exists($query, 'list_fields'))
+			{
+				return FALSE;
+			}
+			
+			$this->heading = $query->list_fields();
+		}
+				
+		// Next blast through the result array and build out the rows
+		
+		if ($query->num_rows() > 0)
+		{
+			foreach ($query->result_array() as $row)
+			{
+				$this->rows[] = $row;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set table data from an array
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */
+	function _set_from_array($data, $set_heading = TRUE)
+	{
+		if ( ! is_array($data) OR count($data) == 0)
+		{
+			return FALSE;
+		}
+		
+		$i = 0;
+		foreach ($data as $row)
+		{
+			if ( ! is_array($row))
+			{
+				$this->rows[] = $data;
+				break;
+			}
+						
+			// If a heading hasn't already been set we'll use the first row of the array as the heading
+			if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE)
+			{
+				$this->heading = $row;
+			}
+			else
+			{
+				$this->rows[] = $row;
+			}
+			
+			$i++;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Compile Template
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+ 	function _compile_template()
+ 	{ 	
+ 		if ($this->template == NULL)
+ 		{
+ 			$this->template = $this->_default_template();
+ 			return;
+ 		}
+		
+		$this->temp = $this->_default_template();
+		foreach (array('table_open','heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val)
+		{
+			if ( ! isset($this->template[$val]))
+			{
+				$this->template[$val] = $this->temp[$val];
+			}
+		} 	
+ 	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Default Template
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _default_template()
+	{
+		return  array (
+						'table_open' 			=> '<table border="0" cellpadding="4" cellspacing="0">',
+
+						'heading_row_start' 	=> '<tr>',
+						'heading_row_end' 		=> '</tr>',
+						'heading_cell_start'	=> '<th>',
+						'heading_cell_end'		=> '</th>',
+
+						'row_start' 			=> '<tr>',
+						'row_end' 				=> '</tr>',
+						'cell_start'			=> '<td>',
+						'cell_end'				=> '</td>',
+
+						'row_alt_start' 		=> '<tr>',
+						'row_alt_end' 			=> '</tr>',
+						'cell_alt_start'		=> '<td>',
+						'cell_alt_end'			=> '</td>',
+
+						'table_close' 			=> '</table>'
+					);	
+	}
+	
+
+}
+
+
+/* End of file Table.php */
 /* Location: ./system/libraries/Table.php */
\ No newline at end of file
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 9988492..844e503 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -1,550 +1,550 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Trackback Class

- *

- * Trackback Sending/Receiving Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Trackbacks

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/trackback.html

- */

-class CI_Trackback {

-		

-	var $time_format	= 'local';

-	var $charset		= 'UTF-8';

-	var $data			= array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => '');

-	var $convert_ascii	= TRUE;

-	var $response		= '';

-	var $error_msg		= array();

-

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 */

-	function CI_Trackback()

-	{

-		log_message('debug', "Trackback Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Send Trackback

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	bool

-	 */	

-	function send($tb_data)

-	{		

-		if ( ! is_array($tb_data))

-		{

-			$this->set_error('The send() method must be passed an array');

-			return FALSE;

-		}

-		

-		// Pre-process the Trackback Data

-		foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item)

-		{

-			if ( ! isset($tb_data[$item]))

-			{

-				$this->set_error('Required item missing: '.$item);

-				return FALSE;

-			}

-			

-			switch ($item)

-			{

-				case 'ping_url'	: $$item = $this->extract_urls($tb_data[$item]);

-					break;

-				case 'excerpt'	: $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));

-					break;

-				case 'url'	 	: $$item = str_replace('&#45;', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));

-					break;

-				default			: $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item])));

-					break;

-			}

-

-			// Convert High ASCII Characters

-			if ($this->convert_ascii == TRUE)

-			{

-				if ($item == 'excerpt')

-				{

-					$$item = $this->convert_ascii($$item);

-				}

-				elseif ($item == 'title')

-				{

-					$$item = $this->convert_ascii($$item);

-				}

-				elseif($item == 'blog_name')

-				{

-					$$item = $this->convert_ascii($$item);

-				}

-			}

-		}

-

-		// Build the Trackback data string

-		$charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];

-		

-		$data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);

-				

-		// Send Trackback(s)

-		$return = TRUE;

-		if (count($ping_url) > 0)

-		{

-			foreach ($ping_url as $url)

-			{

-				if ($this->process($url, $data) == FALSE)

-				{

-					$return = FALSE;

-				}

-			}	

-		}

-

-		return $return;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Receive Trackback  Data

-	 *

-	 * This function simply validates the incoming TB data.

-	 * It returns false on failure and true on success.

-	 * If the data is valid it is set to the $this->data array

-	 * so that it can be inserted into a database.

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function receive()

-	{  					

-		foreach (array('url', 'title', 'blog_name', 'excerpt') as $val)

-		{

-			if ( ! isset($_POST[$val]) OR $_POST[$val] == '')

-			{

-				$this->set_error('The following required POST variable is missing: '.$val);

-				return FALSE;

-			}

-			

-			$this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));

-	

-			if ($val != 'url' && function_exists('mb_convert_encoding'))

-			{

-				$_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);

-			}

-			

-			$_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);

-			

-			if ($val == 'excerpt')

-			{

-				$_POST['excerpt'] = $this->limit_characters($_POST['excerpt']);

-			}

-			

-			$this->data[$val] = $_POST[$val];

-		}

-

-		return TRUE;

-	}	

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Send Trackback Error Message

-	 *

-	 * Allows custom errors to be set.  By default it

-	 * sends the "incomplete information" error, as that's

-	 * the most common one.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function send_error($message = 'Incomplete Information')

-	{

-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";

-		exit;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Send Trackback Success Message

-	 *

-	 * This should be called when a trackback has been

-	 * successfully received and inserted.

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function send_success()

-	{

-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";

-		exit;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Fetch a particular item

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function data($item)

-	{

-		return ( ! isset($this->data[$item])) ? '' : $this->data[$item];

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Process Trackback

-	 *

-	 * Opens a socket connection and passes the data to

-	 * the server.  Returns true on success, false on failure

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	bool

-	 */	

-	function process($url, $data)

-	{

-		$target = parse_url($url);

-	

-		// Open the socket

-		if ( ! $fp = @fsockopen($target['host'], 80))

-		{

-			$this->set_error('Invalid Connection: '.$url);

-			return FALSE;

-		}

-

-		// Build the path

-		$ppath = ( ! isset($target['path'])) ? $url : $target['path'];

-		

-		$path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;

-

-		// Add the Trackback ID to the data string

-		if ($id = $this->get_id($url))

-		{

-			$data = "tb_id=".$id."&".$data;

-		}

-

-		// Transfer the data

-		fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );

-		fputs ($fp, "Host: " . $target['host'] . "\r\n" );

-		fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );

-		fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );

-		fputs ($fp, "Connection: close\r\n\r\n" );

-		fputs ($fp, $data);

-

-		// Was it successful?

-		$this->response = "";

-		

-		while( ! feof($fp))

-		{

-			$this->response .= fgets($fp, 128);

-		}

-		@fclose($fp);

-		

-		if ( ! eregi("<error>0</error>", $this->response))

-		{

-			$message = 'An unknown error was encountered';

-			

-			if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))

-			{

-				$message = trim($match['1']);

-			}

-			

-			$this->set_error($message);

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Extract Trackback URLs

-	 *

-	 * This function lets multiple trackbacks be sent.

-	 * It takes a string of URLs (separated by comma or

-	 * space) and puts each URL into an array

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function extract_urls($urls)

-	{		

-		// Remove the pesky white space and replace with a comma.

-		$urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);

-		

-		// If they use commas get rid of the doubles.

-		$urls = str_replace(",,", ",", $urls);

-		

-		// Remove any comma that might be at the end

-		if (substr($urls, -1) == ",")

-		{

-			$urls = substr($urls, 0, -1);

-		}

-				

-		// Break into an array via commas

-		$urls = preg_split('/[,]/', $urls);

-		

-		// Removes duplicates

-		$urls = array_unique($urls);

-		

-		array_walk($urls, array($this, 'validate_url'));

-		

-		return $urls;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validate URL

-	 *

-	 * Simply adds "http://" if missing

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function validate_url($url)

-	{

-		$url = trim($url);

-

-		if (substr($url, 0, 4) != "http")

-		{

-			$url = "http://".$url;

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Find the Trackback URL's ID

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function get_id($url)

-	{	

-		$tb_id = "";

-		

-		if (strstr($url, '?'))

-		{

-			$tb_array = explode('/', $url);

-			$tb_end   = $tb_array[count($tb_array)-1];

-			

-			if ( ! is_numeric($tb_end))

-			{

-				$tb_end  = $tb_array[count($tb_array)-2];

-			}

-			

-			$tb_array = explode('=', $tb_end);

-			$tb_id	= $tb_array[count($tb_array)-1];

-		}

-		else

-		{

-			if (ereg("/$", $url))

-			{

-				$url = substr($url, 0, -1);

-			}

-				

-			$tb_array = explode('/', $url);

-			$tb_id	= $tb_array[count($tb_array)-1];

-			

-			if ( ! is_numeric($tb_id))

-			{

-				$tb_id  = $tb_array[count($tb_array)-2];

-			}

-		}	

-				

-		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))

-		{

-			return false;

-		}

-		else

-		{

-			return $tb_id;

-		}		

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Convert Reserved XML characters to Entities

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function convert_xml($str)

-	{

-		$temp = '__TEMP_AMPERSANDS__';

-		

-		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);

-		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);

-		

-		$str = str_replace(array("&","<",">","\"", "'", "-"),

-						   array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),

-						   $str);

-			

-		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);

-		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);

-			

-		return $str;

-	}	

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Character limiter

-	 *

-	 * Limits the string based on the character count. Will preserve complete words.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	integer

-	 * @param	string

-	 * @return	string

-	 */

-	function limit_characters($str, $n = 500, $end_char = '&#8230;')

-	{

-		if (strlen($str) < $n)

-		{

-			return $str;

-		}

-

-		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));

-	

-		if (strlen($str) <= $n)

-		{

-			return $str;

-		}

-										

-		$out = "";

-		foreach (explode(' ', trim($str)) as $val)

-		{

-			$out .= $val.' ';			

-			if (strlen($out) >= $n)

-			{

-				return trim($out).$end_char;

-			}		

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * High ASCII to Entities

-	 *

-	 * Converts Hight ascii text and MS Word special chars

-	 * to character entities

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function convert_ascii($str)

-	{

-	   $count	= 1;

-	   $out	= '';

-	   $temp	= array();

-		

-	   for ($i = 0, $s = strlen($str); $i < $s; $i++)

-	   {

-		   $ordinal = ord($str[$i]);

-		

-		   if ($ordinal < 128)

-		   {

-			   $out .= $str[$i];			

-		   }

-		   else

-		   {

-			   if (count($temp) == 0)

-			   {

-				   $count = ($ordinal < 224) ? 2 : 3;

-			   }

-			

-			   $temp[] = $ordinal;

-			

-			   if (count($temp) == $count)

-			   {

-				   $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);

-	

-				   $out .= '&#'.$number.';';

-				   $count = 1;

-				   $temp = array();

-			   }

-		   }

-	   }

-	

-	   return $out;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_error($msg)

-	{

-		log_message('error', $msg);

-		$this->error_msg[] = $msg;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Show error messages

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function display_errors($open = '<p>', $close = '</p>')

-	{	

-		$str = '';

-		foreach ($this->error_msg as $val)

-		{

-			$str .= $open.$val.$close;

-		}

-	

-		return $str;

-	}

-

-}

-// END Trackback Class

-

-/* End of file Trackback.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Trackback Class
+ *
+ * Trackback Sending/Receiving Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Trackbacks
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/trackback.html
+ */
+class CI_Trackback {
+		
+	var $time_format	= 'local';
+	var $charset		= 'UTF-8';
+	var $data			= array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => '');
+	var $convert_ascii	= TRUE;
+	var $response		= '';
+	var $error_msg		= array();
+
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 */
+	function CI_Trackback()
+	{
+		log_message('debug', "Trackback Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Send Trackback
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	bool
+	 */	
+	function send($tb_data)
+	{		
+		if ( ! is_array($tb_data))
+		{
+			$this->set_error('The send() method must be passed an array');
+			return FALSE;
+		}
+		
+		// Pre-process the Trackback Data
+		foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item)
+		{
+			if ( ! isset($tb_data[$item]))
+			{
+				$this->set_error('Required item missing: '.$item);
+				return FALSE;
+			}
+			
+			switch ($item)
+			{
+				case 'ping_url'	: $$item = $this->extract_urls($tb_data[$item]);
+					break;
+				case 'excerpt'	: $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));
+					break;
+				case 'url'	 	: $$item = str_replace('&#45;', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))));
+					break;
+				default			: $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item])));
+					break;
+			}
+
+			// Convert High ASCII Characters
+			if ($this->convert_ascii == TRUE)
+			{
+				if ($item == 'excerpt')
+				{
+					$$item = $this->convert_ascii($$item);
+				}
+				elseif ($item == 'title')
+				{
+					$$item = $this->convert_ascii($$item);
+				}
+				elseif($item == 'blog_name')
+				{
+					$$item = $this->convert_ascii($$item);
+				}
+			}
+		}
+
+		// Build the Trackback data string
+		$charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];
+		
+		$data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);
+				
+		// Send Trackback(s)
+		$return = TRUE;
+		if (count($ping_url) > 0)
+		{
+			foreach ($ping_url as $url)
+			{
+				if ($this->process($url, $data) == FALSE)
+				{
+					$return = FALSE;
+				}
+			}	
+		}
+
+		return $return;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Receive Trackback  Data
+	 *
+	 * This function simply validates the incoming TB data.
+	 * It returns false on failure and true on success.
+	 * If the data is valid it is set to the $this->data array
+	 * so that it can be inserted into a database.
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function receive()
+	{  					
+		foreach (array('url', 'title', 'blog_name', 'excerpt') as $val)
+		{
+			if ( ! isset($_POST[$val]) OR $_POST[$val] == '')
+			{
+				$this->set_error('The following required POST variable is missing: '.$val);
+				return FALSE;
+			}
+			
+			$this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));
+	
+			if ($val != 'url' && function_exists('mb_convert_encoding'))
+			{
+				$_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
+			}
+			
+			$_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);
+			
+			if ($val == 'excerpt')
+			{
+				$_POST['excerpt'] = $this->limit_characters($_POST['excerpt']);
+			}
+			
+			$this->data[$val] = $_POST[$val];
+		}
+
+		return TRUE;
+	}	
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Send Trackback Error Message
+	 *
+	 * Allows custom errors to be set.  By default it
+	 * sends the "incomplete information" error, as that's
+	 * the most common one.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function send_error($message = 'Incomplete Information')
+	{
+		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
+		exit;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Send Trackback Success Message
+	 *
+	 * This should be called when a trackback has been
+	 * successfully received and inserted.
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function send_success()
+	{
+		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";
+		exit;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Fetch a particular item
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function data($item)
+	{
+		return ( ! isset($this->data[$item])) ? '' : $this->data[$item];
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Process Trackback
+	 *
+	 * Opens a socket connection and passes the data to
+	 * the server.  Returns true on success, false on failure
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	bool
+	 */	
+	function process($url, $data)
+	{
+		$target = parse_url($url);
+	
+		// Open the socket
+		if ( ! $fp = @fsockopen($target['host'], 80))
+		{
+			$this->set_error('Invalid Connection: '.$url);
+			return FALSE;
+		}
+
+		// Build the path
+		$ppath = ( ! isset($target['path'])) ? $url : $target['path'];
+		
+		$path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;
+
+		// Add the Trackback ID to the data string
+		if ($id = $this->get_id($url))
+		{
+			$data = "tb_id=".$id."&".$data;
+		}
+
+		// Transfer the data
+		fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );
+		fputs ($fp, "Host: " . $target['host'] . "\r\n" );
+		fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );
+		fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );
+		fputs ($fp, "Connection: close\r\n\r\n" );
+		fputs ($fp, $data);
+
+		// Was it successful?
+		$this->response = "";
+		
+		while( ! feof($fp))
+		{
+			$this->response .= fgets($fp, 128);
+		}
+		@fclose($fp);
+		
+		if ( ! eregi("<error>0</error>", $this->response))
+		{
+			$message = 'An unknown error was encountered';
+			
+			if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))
+			{
+				$message = trim($match['1']);
+			}
+			
+			$this->set_error($message);
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Extract Trackback URLs
+	 *
+	 * This function lets multiple trackbacks be sent.
+	 * It takes a string of URLs (separated by comma or
+	 * space) and puts each URL into an array
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function extract_urls($urls)
+	{		
+		// Remove the pesky white space and replace with a comma.
+		$urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);
+		
+		// If they use commas get rid of the doubles.
+		$urls = str_replace(",,", ",", $urls);
+		
+		// Remove any comma that might be at the end
+		if (substr($urls, -1) == ",")
+		{
+			$urls = substr($urls, 0, -1);
+		}
+				
+		// Break into an array via commas
+		$urls = preg_split('/[,]/', $urls);
+		
+		// Removes duplicates
+		$urls = array_unique($urls);
+		
+		array_walk($urls, array($this, 'validate_url'));
+		
+		return $urls;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate URL
+	 *
+	 * Simply adds "http://" if missing
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function validate_url($url)
+	{
+		$url = trim($url);
+
+		if (substr($url, 0, 4) != "http")
+		{
+			$url = "http://".$url;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Find the Trackback URL's ID
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function get_id($url)
+	{	
+		$tb_id = "";
+		
+		if (strstr($url, '?'))
+		{
+			$tb_array = explode('/', $url);
+			$tb_end   = $tb_array[count($tb_array)-1];
+			
+			if ( ! is_numeric($tb_end))
+			{
+				$tb_end  = $tb_array[count($tb_array)-2];
+			}
+			
+			$tb_array = explode('=', $tb_end);
+			$tb_id	= $tb_array[count($tb_array)-1];
+		}
+		else
+		{
+			if (ereg("/$", $url))
+			{
+				$url = substr($url, 0, -1);
+			}
+				
+			$tb_array = explode('/', $url);
+			$tb_id	= $tb_array[count($tb_array)-1];
+			
+			if ( ! is_numeric($tb_id))
+			{
+				$tb_id  = $tb_array[count($tb_array)-2];
+			}
+		}	
+				
+		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
+		{
+			return false;
+		}
+		else
+		{
+			return $tb_id;
+		}		
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Convert Reserved XML characters to Entities
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function convert_xml($str)
+	{
+		$temp = '__TEMP_AMPERSANDS__';
+		
+		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
+		$str = preg_replace("/&(\w+);/",  "$temp\\1;", $str);
+		
+		$str = str_replace(array("&","<",">","\"", "'", "-"),
+						   array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
+						   $str);
+			
+		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
+		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);
+			
+		return $str;
+	}	
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Character limiter
+	 *
+	 * Limits the string based on the character count. Will preserve complete words.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	integer
+	 * @param	string
+	 * @return	string
+	 */
+	function limit_characters($str, $n = 500, $end_char = '&#8230;')
+	{
+		if (strlen($str) < $n)
+		{
+			return $str;
+		}
+
+		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+	
+		if (strlen($str) <= $n)
+		{
+			return $str;
+		}
+										
+		$out = "";
+		foreach (explode(' ', trim($str)) as $val)
+		{
+			$out .= $val.' ';			
+			if (strlen($out) >= $n)
+			{
+				return trim($out).$end_char;
+			}		
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * High ASCII to Entities
+	 *
+	 * Converts Hight ascii text and MS Word special chars
+	 * to character entities
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function convert_ascii($str)
+	{
+	   $count	= 1;
+	   $out	= '';
+	   $temp	= array();
+		
+	   for ($i = 0, $s = strlen($str); $i < $s; $i++)
+	   {
+		   $ordinal = ord($str[$i]);
+		
+		   if ($ordinal < 128)
+		   {
+			   $out .= $str[$i];			
+		   }
+		   else
+		   {
+			   if (count($temp) == 0)
+			   {
+				   $count = ($ordinal < 224) ? 2 : 3;
+			   }
+			
+			   $temp[] = $ordinal;
+			
+			   if (count($temp) == $count)
+			   {
+				   $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+	
+				   $out .= '&#'.$number.';';
+				   $count = 1;
+				   $temp = array();
+			   }
+		   }
+	   }
+	
+	   return $out;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_error($msg)
+	{
+		log_message('error', $msg);
+		$this->error_msg[] = $msg;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Show error messages
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function display_errors($open = '<p>', $close = '</p>')
+	{	
+		$str = '';
+		foreach ($this->error_msg as $val)
+		{
+			$str .= $open.$val.$close;
+		}
+	
+		return $str;
+	}
+
+}
+// END Trackback Class
+
+/* End of file Trackback.php */
 /* Location: ./system/libraries/Trackback.php */
\ No newline at end of file
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index 3ff0d2f..29b871e 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -1,385 +1,385 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Typography Class

- *

- *

- * @access		private

- * @category	Helpers

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/helpers/

- */

-class CI_Typography {

-

-	// Block level elements that should not be wrapped inside <p> tags

-	var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul';

-	

-	// Elements that should not have <p> and <br /> tags within them.

-	var $skip_elements	= 'p|pre|ol|ul|dl|object|table';

-	

-	// Tags we want the parser to completely ignore when splitting the string.

-	var $inline_elements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var';

-

-	// whether or not to protect quotes within { curly braces }

-	var $protect_braced_quotes = FALSE;

-	

-	/**

-	 * Nothing to do here...

-	 *

-	 */

-	function CI_Typography()

-	{

-	}

-

-	/**

-	 * Auto Typography

-	 *

-	 * This function converts text, making it typographically correct:

-	 * 	- Converts double spaces into paragraphs.

-	 * 	- Converts single line breaks into <br /> tags

-	 * 	- Converts single and double quotes into correctly facing curly quote entities.

-	 * 	- Converts three dots into ellipsis.

-	 * 	- Converts double dashes into em-dashes.

-	 *  - Converts two spaces into entities

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	bool	whether to reduce more then two consecutive newlines to two

-	 * @return	string

-	 */

-	function auto_typography($str, $reduce_linebreaks = FALSE)

-	{

-		if ($str == '')

-		{

-			return '';

-		}

-

-		// Standardize Newlines to make matching easier

-		if (strpos($str, "\r") !== FALSE)

-		{

-			$str = str_replace(array("\r\n", "\r"), "\n", $str);			

-		}

-			

-		// Reduce line breaks.  If there are more than two consecutive linebreaks

-		// we'll compress them down to a maximum of two since there's no benefit to more.

-		if ($reduce_linebreaks === TRUE)

-		{

-			$str = preg_replace("/\n\n+/", "\n\n", $str);

-		} 

-

-		// Convert quotes within tags to temporary markers. We don't want quotes converted 

-		// within tags so we'll temporarily convert them to {@DQ} and {@SQ}

-		// and we don't want double dashes converted to emdash entities, so they are marked with {@DD}

-		// likewise double spaces are converted to {@NBS} to prevent entity conversion

-		if (preg_match_all("#\<.+?>#si", $str, $matches))

-		{

-			for ($i = 0, $total = count($matches[0]); $i < $total; $i++)

-			{

-				$str = str_replace($matches[0][$i],

-									str_replace(array("'",'"','--','  '), array('{@SQ}', '{@DQ}', '{@DD}', '{@NBS}'), $matches[0][$i]),

-									$str);

-			}

-		}

-		

-		if ($this->protect_braced_quotes === TRUE)

-		{

-			if (preg_match_all("#\{.+?}#si", $str, $matches))

-			{

-				for ($i = 0, $total = count($matches[0]); $i < $total; $i++)

-				{

-					$str = str_replace($matches[0][$i],

-										str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches[0][$i]),

-										$str);

-				}

-			}			

-		}

-		

-		// Convert "ignore" tags to temporary marker.  The parser splits out the string at every tag 

-		// it encounters.  Certain inline tags, like image tags, links, span tags, etc. will be 

-		// adversely affected if they are split out so we'll convert the opening bracket < temporarily to: {@TAG}

-		$str = preg_replace("#<(/*)(".$this->inline_elements.")([ >])#i", "{@TAG}\\1\\2\\3", $str);

-

-		// Split the string at every tag.  This expression creates an array with this prototype:

-		// 

-		// 	[array]

-		// 	{

-		// 		[0] = <opening tag>

-		// 		[1] = Content...

-		// 		[2] = <closing tag>

-		// 		Etc...

-		// 	}	

-		$chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);

-		

-		// Build our finalized string.  We cycle through the array, skipping tags, and processing the contained text	

-		$str = '';

-		$process = TRUE;

-		$paragraph = FALSE;

-		foreach ($chunks as $chunk)

-		{

-			// Are we dealing with a tag? If so, we'll skip the processing for this cycle.

-			// Well also set the "process" flag which allows us to skip <pre> tags and a few other things.

-			if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunk, $match))

-			{

-				if (preg_match("#".$this->skip_elements."#", $match[2]))

-				{

-					$process =  ($match[1] == '/') ? TRUE : FALSE;

-				}

-				

-				$str .= $chunk;

-				continue;

-			}

-			elseif (preg_match('/<(\/?)([a-z]*).*?>/s', $chunk, $tagmatch))

-			{

-				if ($tagmatch[1] == '/' && $tagmatch[2] == $this->last_tag)

-				{

-					$process = FALSE;

-				}

-				else

-				{

-					$process = TRUE;

-					$this->last_tag = $tagmatch[2];					

-				}

-			}

-

-			if ($process == FALSE)

-			{

-				$str .= $chunk;

-				continue;

-			}

-			

-			//  Convert Newlines into <p> and <br /> tags

-			$str .= $this->format_characters($this->_format_newlines($chunk));			

-		}

-

-		// is the whole of the content inside a block level element?

-		if ( ! preg_match("/^<(?:".$this->block_elements.")/i", $str, $match))

-		{

-			$str = "<p>{$str}</p>";

-		}

-

-

-		// some special linebreak cleanup

-		$str = preg_replace_callback('#<(?!/|'.$this->block_elements.')([^>]*)><p>(.*?)</p><(\w*)#si', array($this, '_linebreak_cleanup'), $str);

-		

-		// and cleanup empty paragraph tags sitting between two closing tags

-		$str = preg_replace('#(</\w+>)<p>(\s*)</p>(</\w+>)#si', '$1$2$3', $str);

-		

-		// Final clean up

-		$table = array(

-		

-						// If the user submitted their own paragraph tags within the text

-						// we will retain them instead of using our tags.

-						'/(<p[^>*?]>)<p>/'	=> '$1', // <?php BBEdit syntax coloring bug fix

-						

-						// Reduce multiple instances of opening/closing paragraph tags to a single one

-						'#(</p>)+#'			=> '</p>',

-						'/(<p>\W*<p>)+/'	=> '<p>',

-						

-						// Clean up stray paragraph tags that appear before block level elements

-						'#<p></p><('.$this->block_elements.')#'	=> '<$1',

-						

-						// Clean up open paragraph tags that appear before block level elements

-						'#<p>(\W)<('.$this->block_elements.')#'	=> '<p></p>$1<$2',

-

-						// Clean up stray non-breaking spaces preceeding block elements

-						'#[&nbsp; ]+<('.$this->block_elements.')#'	=> '  <$1',

-			

-						// Replace the temporary markers we added earlier

-						'/\{@TAG\}/'		=> '<',

-						'/\{@DQ\}/'			=> '"',

-						'/\{@SQ\}/'			=> "'",

-						'/\{@DD\}/'			=> '--',

-						'/\{@NBS\}/'		=> '  '

-

-						);

-

-		// Do we need to reduce empty lines?

-		if ($reduce_linebreaks === TRUE)

-		{

-			$table['#<p>\n*</p>#'] = '';

-		}

-		else

-		{

-			// If we have empty paragraph tags we add a non-breaking space

-			// otherwise most browsers won't treat them as true paragraphs

-			$table['#<p></p>#'] = '<p>&nbsp;</p>';

-		}

-	

-		return preg_replace(array_keys($table), $table, $str);

-

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Linebreak Cleanup

-	 *

-	 * Removes paragraph and line break tags inserted inbetween

-	 * inline content and a new opening block level element

-	 *

-	 * @access	private

-	 * @param	array

-	 * @return	string

-	 */

-	function _linebreak_cleanup($match)

-	{

-		if (in_array($match[3], explode('|', $this->block_elements)))

-		{

-			return "<{$match[1]}>".str_replace('<br />', '', $match[2])."<{$match[3]}";

-		}

-		else

-		{

-			return $match[0];

-		}

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Format Characters

-	 *

-	 * This function mainly converts double and single quotes

-	 * to curly entities, but it also converts em-dashes,

-	 * double spaces, and ampersands

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function format_characters($str)

-	{

-		static $table;

-		

-		if ( ! isset($table))

-		{

-	        $table = array(					

-							// nested smart quotes, opening and closing

-							// note that rules for grammar (English) allow only for two levels deep

-							// and that single quotes are _supposed_ to always be on the outside

-							// but we'll accommodate both

-							'/(^|\W|\s)\'"/'				=> '$1&#8216;&#8220;',

-							'/\'"(\s|\W|$)/'				=> '&#8217;&#8221;$1',

-							'/(^|\W|\s)"\'/'				=> '$1&#8220;&#8216;',

-							'/"\'(\s|\W|$)/'				=> '&#8221;&#8217;$1',

-

-							// single quote smart quotes

-							'/\'(\s|\W|$)/'					=> '&#8217;$1',

-							'/(^|\W|\s)\'/'					=> '$1&#8216;',

-

-							// double quote smart quotes

-							'/"(\s|\W|$)/'					=> '&#8221;$1',

-							'/(^|\W|\s)"/'					=> '$1&#8220;',

-

-							// apostrophes

-							"/(\w)'(\w)/"       	    	=> '$1&#8217;$2',

-

-							// Em dash and ellipses dots

-							'/\s?\-\-\s?/'					=> '&#8212;',

-							'/(\w)\.{3}/'					=> '$1&#8230;',

-

-							// double space after sentences

-							'/(\W)  /'						=> '$1&nbsp; ',

-

-							// ampersands, if not a character entity

-							'/&(?!#?[a-zA-Z0-9]{2,};)/'		=> '&amp;'

-	        			);			

-		}	

-

-		return preg_replace(array_keys($table), $table, $str);

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Format Newlines

-	 *

-	 * Converts newline characters into either <p> tags or <br />

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function _format_newlines($str)

-	{

-		if ($str == '')

-		{

-			return $str;

-		}

-

-		if (strpos($str, "\n") === FALSE)

-		{

-			return $str;

-		}

-		

-		// Convert two consecutive newlines to paragraphs

-		$str = str_replace("\n\n", "</p>\n\n<p>", $str);

-		

-		// Convert single spaces to <br /> tags

-		$str = preg_replace("/([^\n])(\n)([^\n])/", "\\1<br />\\2\\3", $str);

-		

-		// Wrap the whole enchilada in enclosing paragraphs

-		if ($str != "\n")

-		{

-			$str =  '<p>'.$str.'</p>';

-		}

-

-		// Remove empty paragraphs if they are on the first line, as this

-		// is a potential unintended consequence of the previous code

-		$str = preg_replace("/<p><\/p>(.*)/", "\\1", $str, 1);

-		

-		return $str;

-	}

-	

-	// ------------------------------------------------------------------------

-	

-	/**

-	 * Convert newlines to HTML line breaks except within PRE tags

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */		

-	function nl2br_except_pre($str)

-	{

-		$ex = explode("pre>",$str);

-		$ct = count($ex);

-	

-		$newstr = "";

-		for ($i = 0; $i < $ct; $i++)

-		{

-			if (($i % 2) == 0)

-			{

-				$newstr .= nl2br($ex[$i]);

-			}

-			else

-			{

-				$newstr .= $ex[$i];

-			}

-		

-			if ($ct - 1 != $i)

-				$newstr .= "pre>";

-		}

-	

-		return $newstr;

-	}

-	

-}

-// END Typography Class

-

-/* End of file Typography.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Typography Class
+ *
+ *
+ * @access		private
+ * @category	Helpers
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/helpers/
+ */
+class CI_Typography {
+
+	// Block level elements that should not be wrapped inside <p> tags
+	var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul';
+	
+	// Elements that should not have <p> and <br /> tags within them.
+	var $skip_elements	= 'p|pre|ol|ul|dl|object|table';
+	
+	// Tags we want the parser to completely ignore when splitting the string.
+	var $inline_elements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var';
+
+	// whether or not to protect quotes within { curly braces }
+	var $protect_braced_quotes = FALSE;
+	
+	/**
+	 * Nothing to do here...
+	 *
+	 */
+	function CI_Typography()
+	{
+	}
+
+	/**
+	 * Auto Typography
+	 *
+	 * This function converts text, making it typographically correct:
+	 * 	- Converts double spaces into paragraphs.
+	 * 	- Converts single line breaks into <br /> tags
+	 * 	- Converts single and double quotes into correctly facing curly quote entities.
+	 * 	- Converts three dots into ellipsis.
+	 * 	- Converts double dashes into em-dashes.
+	 *  - Converts two spaces into entities
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	bool	whether to reduce more then two consecutive newlines to two
+	 * @return	string
+	 */
+	function auto_typography($str, $reduce_linebreaks = FALSE)
+	{
+		if ($str == '')
+		{
+			return '';
+		}
+
+		// Standardize Newlines to make matching easier
+		if (strpos($str, "\r") !== FALSE)
+		{
+			$str = str_replace(array("\r\n", "\r"), "\n", $str);			
+		}
+			
+		// Reduce line breaks.  If there are more than two consecutive linebreaks
+		// we'll compress them down to a maximum of two since there's no benefit to more.
+		if ($reduce_linebreaks === TRUE)
+		{
+			$str = preg_replace("/\n\n+/", "\n\n", $str);
+		} 
+
+		// Convert quotes within tags to temporary markers. We don't want quotes converted 
+		// within tags so we'll temporarily convert them to {@DQ} and {@SQ}
+		// and we don't want double dashes converted to emdash entities, so they are marked with {@DD}
+		// likewise double spaces are converted to {@NBS} to prevent entity conversion
+		if (preg_match_all("#\<.+?>#si", $str, $matches))
+		{
+			for ($i = 0, $total = count($matches[0]); $i < $total; $i++)
+			{
+				$str = str_replace($matches[0][$i],
+									str_replace(array("'",'"','--','  '), array('{@SQ}', '{@DQ}', '{@DD}', '{@NBS}'), $matches[0][$i]),
+									$str);
+			}
+		}
+		
+		if ($this->protect_braced_quotes === TRUE)
+		{
+			if (preg_match_all("#\{.+?}#si", $str, $matches))
+			{
+				for ($i = 0, $total = count($matches[0]); $i < $total; $i++)
+				{
+					$str = str_replace($matches[0][$i],
+										str_replace(array("'",'"'), array('{@SQ}', '{@DQ}'), $matches[0][$i]),
+										$str);
+				}
+			}			
+		}
+		
+		// Convert "ignore" tags to temporary marker.  The parser splits out the string at every tag 
+		// it encounters.  Certain inline tags, like image tags, links, span tags, etc. will be 
+		// adversely affected if they are split out so we'll convert the opening bracket < temporarily to: {@TAG}
+		$str = preg_replace("#<(/*)(".$this->inline_elements.")([ >])#i", "{@TAG}\\1\\2\\3", $str);
+
+		// Split the string at every tag.  This expression creates an array with this prototype:
+		// 
+		// 	[array]
+		// 	{
+		// 		[0] = <opening tag>
+		// 		[1] = Content...
+		// 		[2] = <closing tag>
+		// 		Etc...
+		// 	}	
+		$chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
+		
+		// Build our finalized string.  We cycle through the array, skipping tags, and processing the contained text	
+		$str = '';
+		$process = TRUE;
+		$paragraph = FALSE;
+		foreach ($chunks as $chunk)
+		{
+			// Are we dealing with a tag? If so, we'll skip the processing for this cycle.
+			// Well also set the "process" flag which allows us to skip <pre> tags and a few other things.
+			if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunk, $match))
+			{
+				if (preg_match("#".$this->skip_elements."#", $match[2]))
+				{
+					$process =  ($match[1] == '/') ? TRUE : FALSE;
+				}
+				
+				$str .= $chunk;
+				continue;
+			}
+			elseif (preg_match('/<(\/?)([a-z]*).*?>/s', $chunk, $tagmatch))
+			{
+				if ($tagmatch[1] == '/' && $tagmatch[2] == $this->last_tag)
+				{
+					$process = FALSE;
+				}
+				else
+				{
+					$process = TRUE;
+					$this->last_tag = $tagmatch[2];					
+				}
+			}
+
+			if ($process == FALSE)
+			{
+				$str .= $chunk;
+				continue;
+			}
+			
+			//  Convert Newlines into <p> and <br /> tags
+			$str .= $this->format_characters($this->_format_newlines($chunk));			
+		}
+
+		// is the whole of the content inside a block level element?
+		if ( ! preg_match("/^<(?:".$this->block_elements.")/i", $str, $match))
+		{
+			$str = "<p>{$str}</p>";
+		}
+
+
+		// some special linebreak cleanup
+		$str = preg_replace_callback('#<(?!/|'.$this->block_elements.')([^>]*)><p>(.*?)</p><(\w*)#si', array($this, '_linebreak_cleanup'), $str);
+		
+		// and cleanup empty paragraph tags sitting between two closing tags
+		$str = preg_replace('#(</\w+>)<p>(\s*)</p>(</\w+>)#si', '$1$2$3', $str);
+		
+		// Final clean up
+		$table = array(
+		
+						// If the user submitted their own paragraph tags within the text
+						// we will retain them instead of using our tags.
+						'/(<p[^>*?]>)<p>/'	=> '$1', // <?php BBEdit syntax coloring bug fix
+						
+						// Reduce multiple instances of opening/closing paragraph tags to a single one
+						'#(</p>)+#'			=> '</p>',
+						'/(<p>\W*<p>)+/'	=> '<p>',
+						
+						// Clean up stray paragraph tags that appear before block level elements
+						'#<p></p><('.$this->block_elements.')#'	=> '<$1',
+						
+						// Clean up open paragraph tags that appear before block level elements
+						'#<p>(\W)<('.$this->block_elements.')#'	=> '<p></p>$1<$2',
+
+						// Clean up stray non-breaking spaces preceeding block elements
+						'#[&nbsp; ]+<('.$this->block_elements.')#'	=> '  <$1',
+			
+						// Replace the temporary markers we added earlier
+						'/\{@TAG\}/'		=> '<',
+						'/\{@DQ\}/'			=> '"',
+						'/\{@SQ\}/'			=> "'",
+						'/\{@DD\}/'			=> '--',
+						'/\{@NBS\}/'		=> '  '
+
+						);
+
+		// Do we need to reduce empty lines?
+		if ($reduce_linebreaks === TRUE)
+		{
+			$table['#<p>\n*</p>#'] = '';
+		}
+		else
+		{
+			// If we have empty paragraph tags we add a non-breaking space
+			// otherwise most browsers won't treat them as true paragraphs
+			$table['#<p></p>#'] = '<p>&nbsp;</p>';
+		}
+	
+		return preg_replace(array_keys($table), $table, $str);
+
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Linebreak Cleanup
+	 *
+	 * Removes paragraph and line break tags inserted inbetween
+	 * inline content and a new opening block level element
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	string
+	 */
+	function _linebreak_cleanup($match)
+	{
+		if (in_array($match[3], explode('|', $this->block_elements)))
+		{
+			return "<{$match[1]}>".str_replace('<br />', '', $match[2])."<{$match[3]}";
+		}
+		else
+		{
+			return $match[0];
+		}
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Format Characters
+	 *
+	 * This function mainly converts double and single quotes
+	 * to curly entities, but it also converts em-dashes,
+	 * double spaces, and ampersands
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function format_characters($str)
+	{
+		static $table;
+		
+		if ( ! isset($table))
+		{
+	        $table = array(					
+							// nested smart quotes, opening and closing
+							// note that rules for grammar (English) allow only for two levels deep
+							// and that single quotes are _supposed_ to always be on the outside
+							// but we'll accommodate both
+							'/(^|\W|\s)\'"/'				=> '$1&#8216;&#8220;',
+							'/\'"(\s|\W|$)/'				=> '&#8217;&#8221;$1',
+							'/(^|\W|\s)"\'/'				=> '$1&#8220;&#8216;',
+							'/"\'(\s|\W|$)/'				=> '&#8221;&#8217;$1',
+
+							// single quote smart quotes
+							'/\'(\s|\W|$)/'					=> '&#8217;$1',
+							'/(^|\W|\s)\'/'					=> '$1&#8216;',
+
+							// double quote smart quotes
+							'/"(\s|\W|$)/'					=> '&#8221;$1',
+							'/(^|\W|\s)"/'					=> '$1&#8220;',
+
+							// apostrophes
+							"/(\w)'(\w)/"       	    	=> '$1&#8217;$2',
+
+							// Em dash and ellipses dots
+							'/\s?\-\-\s?/'					=> '&#8212;',
+							'/(\w)\.{3}/'					=> '$1&#8230;',
+
+							// double space after sentences
+							'/(\W)  /'						=> '$1&nbsp; ',
+
+							// ampersands, if not a character entity
+							'/&(?!#?[a-zA-Z0-9]{2,};)/'		=> '&amp;'
+	        			);			
+		}	
+
+		return preg_replace(array_keys($table), $table, $str);
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Format Newlines
+	 *
+	 * Converts newline characters into either <p> tags or <br />
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function _format_newlines($str)
+	{
+		if ($str == '')
+		{
+			return $str;
+		}
+
+		if (strpos($str, "\n") === FALSE)
+		{
+			return $str;
+		}
+		
+		// Convert two consecutive newlines to paragraphs
+		$str = str_replace("\n\n", "</p>\n\n<p>", $str);
+		
+		// Convert single spaces to <br /> tags
+		$str = preg_replace("/([^\n])(\n)([^\n])/", "\\1<br />\\2\\3", $str);
+		
+		// Wrap the whole enchilada in enclosing paragraphs
+		if ($str != "\n")
+		{
+			$str =  '<p>'.$str.'</p>';
+		}
+
+		// Remove empty paragraphs if they are on the first line, as this
+		// is a potential unintended consequence of the previous code
+		$str = preg_replace("/<p><\/p>(.*)/", "\\1", $str, 1);
+		
+		return $str;
+	}
+	
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Convert newlines to HTML line breaks except within PRE tags
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */		
+	function nl2br_except_pre($str)
+	{
+		$ex = explode("pre>",$str);
+		$ct = count($ex);
+	
+		$newstr = "";
+		for ($i = 0; $i < $ct; $i++)
+		{
+			if (($i % 2) == 0)
+			{
+				$newstr .= nl2br($ex[$i]);
+			}
+			else
+			{
+				$newstr .= $ex[$i];
+			}
+		
+			if ($ct - 1 != $i)
+				$newstr .= "pre>";
+		}
+	
+		return $newstr;
+	}
+	
+}
+// END Typography Class
+
+/* End of file Typography.php */
 /* Location: ./system/libraries/Typography.php */
\ No newline at end of file
diff --git a/system/libraries/URI.php b/system/libraries/URI.php
index b27dfa3..aa2d71e 100644
--- a/system/libraries/URI.php
+++ b/system/libraries/URI.php
@@ -1,585 +1,585 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * URI Class

- *

- * Parses URIs and determines routing

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	URI

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/uri.html

- */

-class CI_URI {

-

-	var	$keyval	= array();

-	var $uri_string;

-	var $segments		= array();

-	var $rsegments		= array();

-

-	/**

-	 * Constructor

-	 *

-	 * Simply globalizes the $RTR object.  The front

-	 * loads the Router class early on so it's not available

-	 * normally as other classes are.

-	 *

-	 * @access	public

-	 */

-	function CI_URI()

-	{

-		$this->config =& load_class('Config');

-		log_message('debug', "URI Class Initialized");

-	}

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get the URI String

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _fetch_uri_string()

-	{

-		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')

-		{

-			// If the URL has a question mark then it's simplest to just

-			// build the URI string from the zero index of the $_GET array.

-			// This avoids having to deal with $_SERVER variables, which

-			// can be unreliable in some environments

-			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')

-			{

-				$this->uri_string = key($_GET);

-				return;

-			}

-

-			// Is there a PATH_INFO variable?

-			// Note: some servers seem to have trouble with getenv() so we'll test it two ways

-			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');

-			if (trim($path, '/') != '' && $path != "/".SELF)

-			{

-				$this->uri_string = $path;

-				return;

-			}

-

-			// No PATH_INFO?... What about QUERY_STRING?

-			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');

-			if (trim($path, '/') != '')

-			{

-				$this->uri_string = $path;

-				return;

-			}

-

-			// No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?

-			$path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');

-			if (trim($path, '/') != '' && $path != "/".SELF)

-			{

-				// remove path and script information so we have good URI data

-				$this->uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $path);

-				return;

-			}

-

-			// We've exhausted all our options...

-			$this->uri_string = '';

-		}

-		else

-		{

-			$uri = strtoupper($this->config->item('uri_protocol'));

-

-			if ($uri == 'REQUEST_URI')

-			{

-				$this->uri_string = $this->_parse_request_uri();

-				return;

-			}

-

-			$this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);

-		}

-

-		// If the URI contains only a slash we'll kill it

-		if ($this->uri_string == '/')

-		{

-			$this->uri_string = '';

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Parse the REQUEST_URI

-	 *

-	 * Due to the way REQUEST_URI works it usually contains path info

-	 * that makes it unusable as URI data.  We'll trim off the unnecessary

-	 * data, hopefully arriving at a valid URI that we can use.

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _parse_request_uri()

-	{

-		if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')

-		{

-			return '';

-		}

-

-		$request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));

-

-		if ($request_uri == '' OR $request_uri == SELF)

-		{

-			return '';

-		}

-

-		$fc_path = FCPATH;

-		if (strpos($request_uri, '?') !== FALSE)

-		{

-			$fc_path .= '?';

-		}

-

-		$parsed_uri = explode("/", $request_uri);

-

-		$i = 0;

-		foreach(explode("/", $fc_path) as $segment)

-		{

-			if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])

-			{

-				$i++;

-			}

-		}

-

-		$parsed_uri = implode("/", array_slice($parsed_uri, $i));

-

-		if ($parsed_uri != '')

-		{

-			$parsed_uri = '/'.$parsed_uri;

-		}

-

-		return $parsed_uri;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Filter segments for malicious characters

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _filter_uri($str)

-	{

-		if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)

-		{

-			if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str))

-			{

-				header('HTTP/1.1 400 Bad Request');

-				exit('The URI you submitted has disallowed characters.');

-			}

-		}

-

-		// Convert programatic characters to entities

-		$bad	= array('$', 		'(', 		')',	 	'%28', 		'%29');

-		$good	= array('&#36;',	'&#40;',	'&#41;',	'&#40;',	'&#41;');

-

-		return str_replace($bad, $good, $str);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Remove the suffix from the URL if needed

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _remove_url_suffix()

-	{

-		if  ($this->config->item('url_suffix') != "")

-		{

-			$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Explode the URI Segments. The individual segments will

-	 * be stored in the $this->segments array.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _explode_segments()

-	{

-		foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)

-		{

-			// Filter segments for security

-			$val = trim($this->_filter_uri($val));

-

-			if ($val != '')

-			{

-				$this->segments[] = $val;

-			}

-		}

-	}

-

-	// --------------------------------------------------------------------

-	/**

-	 * Re-index Segments

-	 *

-	 * This function re-indexes the $this->segment array so that it

-	 * starts at 1 rather than 0.  Doing so makes it simpler to

-	 * use functions like $this->uri->segment(n) since there is

-	 * a 1:1 relationship between the segment array and the actual segments.

-	 *

-	 * @access	private

-	 * @return	void

-	 */

-	function _reindex_segments()

-	{

-		array_unshift($this->segments, NULL);

-		array_unshift($this->rsegments, NULL);

-		unset($this->segments[0]);

-		unset($this->rsegments[0]);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a URI Segment

-	 *

-	 * This function returns the URI segment based on the number provided.

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @param	bool

-	 * @return	string

-	 */

-	function segment($n, $no_result = FALSE)

-	{

-		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a URI "routed" Segment

-	 *

-	 * This function returns the re-routed URI segment (assuming routing rules are used)

-	 * based on the number provided.  If there is no routing this function returns the

-	 * same result as $this->segment()

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @param	bool

-	 * @return	string

-	 */

-	function rsegment($n, $no_result = FALSE)

-	{

-		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate a key value pair from the URI string

-	 *

-	 * This function generates and associative array of URI data starting

-	 * at the supplied segment. For example, if this is your URI:

-	 *

-	 *	example.com/user/search/name/joe/location/UK/gender/male

-	 *

-	 * You can use this function to generate an array with this prototype:

-	 *

-	 * array (

-	 *			name => joe

-	 *			location => UK

-	 *			gender => male

-	 *		 )

-	 *

-	 * @access	public

-	 * @param	integer	the starting segment number

-	 * @param	array	an array of default values

-	 * @return	array

-	 */

-	function uri_to_assoc($n = 3, $default = array())

-	{

-	 	return $this->_uri_to_assoc($n, $default, 'segment');

-	}

-	/**

-	 * Identical to above only it uses the re-routed segment array

-	 *

-	 */

-	function ruri_to_assoc($n = 3, $default = array())

-	{

-	 	return $this->_uri_to_assoc($n, $default, 'rsegment');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate a key value pair from the URI string or Re-routed URI string

-	 *

-	 * @access	private

-	 * @param	integer	the starting segment number

-	 * @param	array	an array of default values

-	 * @param	string	which array we should use

-	 * @return	array

-	 */

-	function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')

-	{

-		if ($which == 'segment')

-		{

-			$total_segments = 'total_segments';

-			$segment_array = 'segment_array';

-		}

-		else

-		{

-			$total_segments = 'total_rsegments';

-			$segment_array = 'rsegment_array';

-		}

-

-		if ( ! is_numeric($n))

-		{

-			return $default;

-		}

-

-		if (isset($this->keyval[$n]))

-		{

-			return $this->keyval[$n];

-		}

-

-		if ($this->$total_segments() < $n)

-		{

-			if (count($default) == 0)

-			{

-				return array();

-			}

-

-			$retval = array();

-			foreach ($default as $val)

-			{

-				$retval[$val] = FALSE;

-			}

-			return $retval;

-		}

-

-		$segments = array_slice($this->$segment_array(), ($n - 1));

-

-		$i = 0;

-		$lastval = '';

-		$retval  = array();

-		foreach ($segments as $seg)

-		{

-			if ($i % 2)

-			{

-				$retval[$lastval] = $seg;

-			}

-			else

-			{

-				$retval[$seg] = FALSE;

-				$lastval = $seg;

-			}

-

-			$i++;

-		}

-

-		if (count($default) > 0)

-		{

-			foreach ($default as $val)

-			{

-				if ( ! array_key_exists($val, $retval))

-				{

-					$retval[$val] = FALSE;

-				}

-			}

-		}

-

-		// Cache the array for reuse

-		$this->keyval[$n] = $retval;

-		return $retval;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Generate a URI string from an associative array

-	 *

-	 *

-	 * @access	public

-	 * @param	array	an associative array of key/values

-	 * @return	array

-	 */

-	function assoc_to_uri($array)

-	{

-		$temp = array();

-		foreach ((array)$array as $key => $val)

-		{

-			$temp[] = $key;

-			$temp[] = $val;

-		}

-

-		return implode('/', $temp);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a URI Segment and add a trailing slash

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @param	string

-	 * @return	string

-	 */

-	function slash_segment($n, $where = 'trailing')

-	{

-		return $this->_slash_segment($n, $where, 'segment');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a URI Segment and add a trailing slash

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @param	string

-	 * @return	string

-	 */

-	function slash_rsegment($n, $where = 'trailing')

-	{

-		return $this->_slash_segment($n, $where, 'rsegment');

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch a URI Segment and add a trailing slash - helper function

-	 *

-	 * @access	private

-	 * @param	integer

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function _slash_segment($n, $where = 'trailing', $which = 'segment')

-	{

-		if ($where == 'trailing')

-		{

-			$trailing	= '/';

-			$leading	= '';

-		}

-		elseif ($where == 'leading')

-		{

-			$leading	= '/';

-			$trailing	= '';

-		}

-		else

-		{

-			$leading	= '/';

-			$trailing	= '/';

-		}

-		return $leading.$this->$which($n).$trailing;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Segment Array

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function segment_array()

-	{

-		return $this->segments;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Routed Segment Array

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function rsegment_array()

-	{

-		return $this->rsegments;

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Total number of segments

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function total_segments()

-	{

-		return count($this->segments);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Total number of routed segments

-	 *

-	 * @access	public

-	 * @return	integer

-	 */

-	function total_rsegments()

-	{

-		return count($this->rsegments);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch the entire URI string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function uri_string()

-	{

-		return $this->uri_string;

-	}

-

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Fetch the entire Re-routed URI string

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function ruri_string()

-	{

-		return '/'.implode('/', $this->rsegment_array()).'/';

-	}

-

-}

-// END URI Class

-

-/* End of file URI.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * URI Class
+ *
+ * Parses URIs and determines routing
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	URI
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/uri.html
+ */
+class CI_URI {
+
+	var	$keyval	= array();
+	var $uri_string;
+	var $segments		= array();
+	var $rsegments		= array();
+
+	/**
+	 * Constructor
+	 *
+	 * Simply globalizes the $RTR object.  The front
+	 * loads the Router class early on so it's not available
+	 * normally as other classes are.
+	 *
+	 * @access	public
+	 */
+	function CI_URI()
+	{
+		$this->config =& load_class('Config');
+		log_message('debug', "URI Class Initialized");
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get the URI String
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _fetch_uri_string()
+	{
+		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
+		{
+			// If the URL has a question mark then it's simplest to just
+			// build the URI string from the zero index of the $_GET array.
+			// This avoids having to deal with $_SERVER variables, which
+			// can be unreliable in some environments
+			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
+			{
+				$this->uri_string = key($_GET);
+				return;
+			}
+
+			// Is there a PATH_INFO variable?
+			// Note: some servers seem to have trouble with getenv() so we'll test it two ways
+			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
+			if (trim($path, '/') != '' && $path != "/".SELF)
+			{
+				$this->uri_string = $path;
+				return;
+			}
+
+			// No PATH_INFO?... What about QUERY_STRING?
+			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
+			if (trim($path, '/') != '')
+			{
+				$this->uri_string = $path;
+				return;
+			}
+
+			// No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
+			$path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');
+			if (trim($path, '/') != '' && $path != "/".SELF)
+			{
+				// remove path and script information so we have good URI data
+				$this->uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $path);
+				return;
+			}
+
+			// We've exhausted all our options...
+			$this->uri_string = '';
+		}
+		else
+		{
+			$uri = strtoupper($this->config->item('uri_protocol'));
+
+			if ($uri == 'REQUEST_URI')
+			{
+				$this->uri_string = $this->_parse_request_uri();
+				return;
+			}
+
+			$this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
+		}
+
+		// If the URI contains only a slash we'll kill it
+		if ($this->uri_string == '/')
+		{
+			$this->uri_string = '';
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Parse the REQUEST_URI
+	 *
+	 * Due to the way REQUEST_URI works it usually contains path info
+	 * that makes it unusable as URI data.  We'll trim off the unnecessary
+	 * data, hopefully arriving at a valid URI that we can use.
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _parse_request_uri()
+	{
+		if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')
+		{
+			return '';
+		}
+
+		$request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));
+
+		if ($request_uri == '' OR $request_uri == SELF)
+		{
+			return '';
+		}
+
+		$fc_path = FCPATH;
+		if (strpos($request_uri, '?') !== FALSE)
+		{
+			$fc_path .= '?';
+		}
+
+		$parsed_uri = explode("/", $request_uri);
+
+		$i = 0;
+		foreach(explode("/", $fc_path) as $segment)
+		{
+			if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
+			{
+				$i++;
+			}
+		}
+
+		$parsed_uri = implode("/", array_slice($parsed_uri, $i));
+
+		if ($parsed_uri != '')
+		{
+			$parsed_uri = '/'.$parsed_uri;
+		}
+
+		return $parsed_uri;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Filter segments for malicious characters
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _filter_uri($str)
+	{
+		if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
+		{
+			if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str))
+			{
+				header('HTTP/1.1 400 Bad Request');
+				exit('The URI you submitted has disallowed characters.');
+			}
+		}
+
+		// Convert programatic characters to entities
+		$bad	= array('$', 		'(', 		')',	 	'%28', 		'%29');
+		$good	= array('&#36;',	'&#40;',	'&#41;',	'&#40;',	'&#41;');
+
+		return str_replace($bad, $good, $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Remove the suffix from the URL if needed
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _remove_url_suffix()
+	{
+		if  ($this->config->item('url_suffix') != "")
+		{
+			$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Explode the URI Segments. The individual segments will
+	 * be stored in the $this->segments array.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _explode_segments()
+	{
+		foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+		{
+			// Filter segments for security
+			$val = trim($this->_filter_uri($val));
+
+			if ($val != '')
+			{
+				$this->segments[] = $val;
+			}
+		}
+	}
+
+	// --------------------------------------------------------------------
+	/**
+	 * Re-index Segments
+	 *
+	 * This function re-indexes the $this->segment array so that it
+	 * starts at 1 rather than 0.  Doing so makes it simpler to
+	 * use functions like $this->uri->segment(n) since there is
+	 * a 1:1 relationship between the segment array and the actual segments.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	function _reindex_segments()
+	{
+		array_unshift($this->segments, NULL);
+		array_unshift($this->rsegments, NULL);
+		unset($this->segments[0]);
+		unset($this->rsegments[0]);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a URI Segment
+	 *
+	 * This function returns the URI segment based on the number provided.
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @param	bool
+	 * @return	string
+	 */
+	function segment($n, $no_result = FALSE)
+	{
+		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a URI "routed" Segment
+	 *
+	 * This function returns the re-routed URI segment (assuming routing rules are used)
+	 * based on the number provided.  If there is no routing this function returns the
+	 * same result as $this->segment()
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @param	bool
+	 * @return	string
+	 */
+	function rsegment($n, $no_result = FALSE)
+	{
+		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate a key value pair from the URI string
+	 *
+	 * This function generates and associative array of URI data starting
+	 * at the supplied segment. For example, if this is your URI:
+	 *
+	 *	example.com/user/search/name/joe/location/UK/gender/male
+	 *
+	 * You can use this function to generate an array with this prototype:
+	 *
+	 * array (
+	 *			name => joe
+	 *			location => UK
+	 *			gender => male
+	 *		 )
+	 *
+	 * @access	public
+	 * @param	integer	the starting segment number
+	 * @param	array	an array of default values
+	 * @return	array
+	 */
+	function uri_to_assoc($n = 3, $default = array())
+	{
+	 	return $this->_uri_to_assoc($n, $default, 'segment');
+	}
+	/**
+	 * Identical to above only it uses the re-routed segment array
+	 *
+	 */
+	function ruri_to_assoc($n = 3, $default = array())
+	{
+	 	return $this->_uri_to_assoc($n, $default, 'rsegment');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate a key value pair from the URI string or Re-routed URI string
+	 *
+	 * @access	private
+	 * @param	integer	the starting segment number
+	 * @param	array	an array of default values
+	 * @param	string	which array we should use
+	 * @return	array
+	 */
+	function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
+	{
+		if ($which == 'segment')
+		{
+			$total_segments = 'total_segments';
+			$segment_array = 'segment_array';
+		}
+		else
+		{
+			$total_segments = 'total_rsegments';
+			$segment_array = 'rsegment_array';
+		}
+
+		if ( ! is_numeric($n))
+		{
+			return $default;
+		}
+
+		if (isset($this->keyval[$n]))
+		{
+			return $this->keyval[$n];
+		}
+
+		if ($this->$total_segments() < $n)
+		{
+			if (count($default) == 0)
+			{
+				return array();
+			}
+
+			$retval = array();
+			foreach ($default as $val)
+			{
+				$retval[$val] = FALSE;
+			}
+			return $retval;
+		}
+
+		$segments = array_slice($this->$segment_array(), ($n - 1));
+
+		$i = 0;
+		$lastval = '';
+		$retval  = array();
+		foreach ($segments as $seg)
+		{
+			if ($i % 2)
+			{
+				$retval[$lastval] = $seg;
+			}
+			else
+			{
+				$retval[$seg] = FALSE;
+				$lastval = $seg;
+			}
+
+			$i++;
+		}
+
+		if (count($default) > 0)
+		{
+			foreach ($default as $val)
+			{
+				if ( ! array_key_exists($val, $retval))
+				{
+					$retval[$val] = FALSE;
+				}
+			}
+		}
+
+		// Cache the array for reuse
+		$this->keyval[$n] = $retval;
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Generate a URI string from an associative array
+	 *
+	 *
+	 * @access	public
+	 * @param	array	an associative array of key/values
+	 * @return	array
+	 */
+	function assoc_to_uri($array)
+	{
+		$temp = array();
+		foreach ((array)$array as $key => $val)
+		{
+			$temp[] = $key;
+			$temp[] = $val;
+		}
+
+		return implode('/', $temp);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a URI Segment and add a trailing slash
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @param	string
+	 * @return	string
+	 */
+	function slash_segment($n, $where = 'trailing')
+	{
+		return $this->_slash_segment($n, $where, 'segment');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a URI Segment and add a trailing slash
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @param	string
+	 * @return	string
+	 */
+	function slash_rsegment($n, $where = 'trailing')
+	{
+		return $this->_slash_segment($n, $where, 'rsegment');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch a URI Segment and add a trailing slash - helper function
+	 *
+	 * @access	private
+	 * @param	integer
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function _slash_segment($n, $where = 'trailing', $which = 'segment')
+	{
+		if ($where == 'trailing')
+		{
+			$trailing	= '/';
+			$leading	= '';
+		}
+		elseif ($where == 'leading')
+		{
+			$leading	= '/';
+			$trailing	= '';
+		}
+		else
+		{
+			$leading	= '/';
+			$trailing	= '/';
+		}
+		return $leading.$this->$which($n).$trailing;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Segment Array
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function segment_array()
+	{
+		return $this->segments;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Routed Segment Array
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function rsegment_array()
+	{
+		return $this->rsegments;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Total number of segments
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function total_segments()
+	{
+		return count($this->segments);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Total number of routed segments
+	 *
+	 * @access	public
+	 * @return	integer
+	 */
+	function total_rsegments()
+	{
+		return count($this->rsegments);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch the entire URI string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function uri_string()
+	{
+		return $this->uri_string;
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch the entire Re-routed URI string
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function ruri_string()
+	{
+		return '/'.implode('/', $this->rsegment_array()).'/';
+	}
+
+}
+// END URI Class
+
+/* End of file URI.php */
 /* Location: ./system/libraries/URI.php */
\ No newline at end of file
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 5ed048b..a5aa381 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -1,347 +1,347 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.3.1

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Unit Testing Class

- *

- * Simple testing class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	UnitTesting

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/uri.html

- */

-class CI_Unit_test {

-

-	var $active			= TRUE;

-	var $results 		= array();

-	var $strict			= FALSE;

-	var $_template 		= NULL;

-	var $_template_rows	= NULL;

-

-	function CI_Unit_test()

-	{

-		log_message('debug', "Unit Testing Class Initialized");

-	}	

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Run the tests

-	 *

-	 * Runs the supplied tests

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	mixed

-	 * @param	string

-	 * @return	string

-	 */	

-	function run($test, $expected = TRUE, $test_name = 'undefined')

-	{

-		if ($this->active == FALSE)

-		{

-			return FALSE;

-		}

-	

-		if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))

-		{

-			$expected = str_replace('is_float', 'is_double', $expected);

-			$result = ($expected($test)) ? TRUE : FALSE;	

-			$extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));

-		}

-		else

-		{

-			if ($this->strict == TRUE)

-				$result = ($test === $expected) ? TRUE : FALSE;	

-			else

-				$result = ($test == $expected) ? TRUE : FALSE;	

-			

-			$extype = gettype($expected);

-		}

-				

-		$back = $this->_backtrace();

-	

-		$report[] = array (

-							'test_name'			=> $test_name,

-							'test_datatype'		=> gettype($test),

-							'res_datatype'		=> $extype,

-							'result'			=> ($result === TRUE) ? 'passed' : 'failed',

-							'file'				=> $back['file'],

-							'line'				=> $back['line']

-						);

-

-		$this->results[] = $report;		

-				

-		return($this->report($this->result($report)));

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Generate a report

-	 *

-	 * Displays a table with the test data

-	 *

-	 * @access	public

-	 * @return	string

-	 */

-	function report($result = array())

-	{

-		if (count($result) == 0)

-		{

-			$result = $this->result();

-		}

-

-		$CI =& get_instance();

-		$CI->load->language('unit_test');

-

-		$this->_parse_template();

-

-		$r = '';

-		foreach ($result as $res)

-		{

-			$table = '';

-

-			foreach ($res as $key => $val)

-			{

-

-				if ($key == $CI->lang->line('ut_result'))

-				{

-					if ($val == $CI->lang->line('ut_passed'))

-					{

-						$val = '<span style="color: #0C0;">'.$val.'</span>';

-					}

-					elseif ($val == $CI->lang->line('ut_failed'))

-					{

-						$val = '<span style="color: #C00;">'.$val.'</span>';

-					}

-				}

-

-				$temp = $this->_template_rows;

-				$temp = str_replace('{item}', $key, $temp);

-				$temp = str_replace('{result}', $val, $temp);

-				$table .= $temp;

-			}

-

-			$r .= str_replace('{rows}', $table, $this->_template);

-		}

-

-		return $r;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Use strict comparison

-	 *

-	 * Causes the evaluation to use === rather than ==

-	 *

-	 * @access	public

-	 * @param	bool

-	 * @return	null

-	 */

-	function use_strict($state = TRUE)

-	{

-		$this->strict = ($state == FALSE) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Make Unit testing active

-	 *

-	 * Enables/disables unit testing

-	 *

-	 * @access	public

-	 * @param	bool

-	 * @return	null

-	 */

-	function active($state = TRUE)

-	{

-		$this->active = ($state == FALSE) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Result Array

-	 *

-	 * Returns the raw result data

-	 *

-	 * @access	public

-	 * @return	array

-	 */

-	function result($results = array())

-	{	

-		$CI =& get_instance();

-		$CI->load->language('unit_test');

-		

-		if (count($results) == 0)

-		{

-			$results = $this->results;

-		}

-		

-		$retval = array();

-		foreach ($results as $result)

-		{

-			$temp = array();

-			foreach ($result as $key => $val)

-			{

-				if (is_array($val))

-				{

-					foreach ($val as $k => $v)

-					{

-						if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))

-						{

-							$v = $line;

-						}				

-						$temp[$CI->lang->line('ut_'.$k)] = $v;					

-					}

-				}

-				else

-				{

-					if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val))))

-					{

-						$val = $line;

-					}				

-					$temp[$CI->lang->line('ut_'.$key)] = $val;

-				}

-			}

-			

-			$retval[] = $temp;

-		}

-	

-		return $retval;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the template

-	 *

-	 * This lets us set the template to be used to display results

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_template($template)

-	{

-		$this->_template = $template;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Generate a backtrace

-	 *

-	 * This lets us show file names and line numbers

-	 *

-	 * @access	private

-	 * @return	array

-	 */

-	function _backtrace()

-	{

-		if (function_exists('debug_backtrace'))

-		{

-			$back = debug_backtrace();

-			

-			$file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];

-			$line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];

-						

-			return array('file' => $file, 'line' => $line);

-		}

-		return array('file' => 'Unknown', 'line' => 'Unknown');

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get Default Template

-	 *

-	 * @access	private

-	 * @return	string

-	 */

-	function _default_template()

-	{	

-		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">';

-		$this->_template .= '{rows}';

-		$this->_template .= "\n".'</table>';

-		

-		$this->_template_rows = "\n\t".'<tr>';

-		$this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>';

-		$this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>';

-		$this->_template_rows .= "\n\t".'</tr>';	

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Parse Template

-	 *

-	 * Harvests the data within the template {pseudo-variables}

-	 *

-	 * @access	private

-	 * @return	void

-	 */

- 	function _parse_template()

- 	{

- 		if ( ! is_null($this->_template_rows))

- 		{

- 			return;

- 		}

- 		

- 		if (is_null($this->_template))

- 		{

- 			$this->_default_template();

- 			return;

- 		}

- 		

-		if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))

-		{

- 			$this->_default_template();

- 			return;

-		}

-

-		$this->_template_rows = $match['1'];

-		$this->_template = str_replace($match['0'], '{rows}', $this->_template); 	

- 	}

- 	

-}

-// END Unit_test Class

-

-/**

- * Helper functions to test boolean true/false

- *

- *

- * @access	private

- * @return	bool

- */

-function is_true($test)

-{

-	return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;

-}

-function is_false($test)

-{

-	return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;

-}

-

-

-/* End of file Unit_test.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.3.1
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Unit Testing Class
+ *
+ * Simple testing class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	UnitTesting
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/uri.html
+ */
+class CI_Unit_test {
+
+	var $active			= TRUE;
+	var $results 		= array();
+	var $strict			= FALSE;
+	var $_template 		= NULL;
+	var $_template_rows	= NULL;
+
+	function CI_Unit_test()
+	{
+		log_message('debug', "Unit Testing Class Initialized");
+	}	
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Run the tests
+	 *
+	 * Runs the supplied tests
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	string
+	 */	
+	function run($test, $expected = TRUE, $test_name = 'undefined')
+	{
+		if ($this->active == FALSE)
+		{
+			return FALSE;
+		}
+	
+		if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
+		{
+			$expected = str_replace('is_float', 'is_double', $expected);
+			$result = ($expected($test)) ? TRUE : FALSE;	
+			$extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));
+		}
+		else
+		{
+			if ($this->strict == TRUE)
+				$result = ($test === $expected) ? TRUE : FALSE;	
+			else
+				$result = ($test == $expected) ? TRUE : FALSE;	
+			
+			$extype = gettype($expected);
+		}
+				
+		$back = $this->_backtrace();
+	
+		$report[] = array (
+							'test_name'			=> $test_name,
+							'test_datatype'		=> gettype($test),
+							'res_datatype'		=> $extype,
+							'result'			=> ($result === TRUE) ? 'passed' : 'failed',
+							'file'				=> $back['file'],
+							'line'				=> $back['line']
+						);
+
+		$this->results[] = $report;		
+				
+		return($this->report($this->result($report)));
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Generate a report
+	 *
+	 * Displays a table with the test data
+	 *
+	 * @access	public
+	 * @return	string
+	 */
+	function report($result = array())
+	{
+		if (count($result) == 0)
+		{
+			$result = $this->result();
+		}
+
+		$CI =& get_instance();
+		$CI->load->language('unit_test');
+
+		$this->_parse_template();
+
+		$r = '';
+		foreach ($result as $res)
+		{
+			$table = '';
+
+			foreach ($res as $key => $val)
+			{
+
+				if ($key == $CI->lang->line('ut_result'))
+				{
+					if ($val == $CI->lang->line('ut_passed'))
+					{
+						$val = '<span style="color: #0C0;">'.$val.'</span>';
+					}
+					elseif ($val == $CI->lang->line('ut_failed'))
+					{
+						$val = '<span style="color: #C00;">'.$val.'</span>';
+					}
+				}
+
+				$temp = $this->_template_rows;
+				$temp = str_replace('{item}', $key, $temp);
+				$temp = str_replace('{result}', $val, $temp);
+				$table .= $temp;
+			}
+
+			$r .= str_replace('{rows}', $table, $this->_template);
+		}
+
+		return $r;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Use strict comparison
+	 *
+	 * Causes the evaluation to use === rather than ==
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	null
+	 */
+	function use_strict($state = TRUE)
+	{
+		$this->strict = ($state == FALSE) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Make Unit testing active
+	 *
+	 * Enables/disables unit testing
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	null
+	 */
+	function active($state = TRUE)
+	{
+		$this->active = ($state == FALSE) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Result Array
+	 *
+	 * Returns the raw result data
+	 *
+	 * @access	public
+	 * @return	array
+	 */
+	function result($results = array())
+	{	
+		$CI =& get_instance();
+		$CI->load->language('unit_test');
+		
+		if (count($results) == 0)
+		{
+			$results = $this->results;
+		}
+		
+		$retval = array();
+		foreach ($results as $result)
+		{
+			$temp = array();
+			foreach ($result as $key => $val)
+			{
+				if (is_array($val))
+				{
+					foreach ($val as $k => $v)
+					{
+						if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v))))
+						{
+							$v = $line;
+						}				
+						$temp[$CI->lang->line('ut_'.$k)] = $v;					
+					}
+				}
+				else
+				{
+					if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val))))
+					{
+						$val = $line;
+					}				
+					$temp[$CI->lang->line('ut_'.$key)] = $val;
+				}
+			}
+			
+			$retval[] = $temp;
+		}
+	
+		return $retval;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the template
+	 *
+	 * This lets us set the template to be used to display results
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_template($template)
+	{
+		$this->_template = $template;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Generate a backtrace
+	 *
+	 * This lets us show file names and line numbers
+	 *
+	 * @access	private
+	 * @return	array
+	 */
+	function _backtrace()
+	{
+		if (function_exists('debug_backtrace'))
+		{
+			$back = debug_backtrace();
+			
+			$file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];
+			$line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];
+						
+			return array('file' => $file, 'line' => $line);
+		}
+		return array('file' => 'Unknown', 'line' => 'Unknown');
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get Default Template
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	function _default_template()
+	{	
+		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">';
+		$this->_template .= '{rows}';
+		$this->_template .= "\n".'</table>';
+		
+		$this->_template_rows = "\n\t".'<tr>';
+		$this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>';
+		$this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>';
+		$this->_template_rows .= "\n\t".'</tr>';	
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Parse Template
+	 *
+	 * Harvests the data within the template {pseudo-variables}
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+ 	function _parse_template()
+ 	{
+ 		if ( ! is_null($this->_template_rows))
+ 		{
+ 			return;
+ 		}
+ 		
+ 		if (is_null($this->_template))
+ 		{
+ 			$this->_default_template();
+ 			return;
+ 		}
+ 		
+		if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
+		{
+ 			$this->_default_template();
+ 			return;
+		}
+
+		$this->_template_rows = $match['1'];
+		$this->_template = str_replace($match['0'], '{rows}', $this->_template); 	
+ 	}
+ 	
+}
+// END Unit_test Class
+
+/**
+ * Helper functions to test boolean true/false
+ *
+ *
+ * @access	private
+ * @return	bool
+ */
+function is_true($test)
+{
+	return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
+}
+function is_false($test)
+{
+	return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
+}
+
+
+/* End of file Unit_test.php */
 /* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 3832dab..54124bc 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -1,931 +1,931 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * File Uploading Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Uploads

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/file_uploading.html

- */

-class CI_Upload {

-	

-	var $max_size		= 0;

-	var $max_width		= 0;

-	var $max_height		= 0;

-	var $max_filename	= 0;

-	var $allowed_types	= "";

-	var $file_temp		= "";

-	var $file_name		= "";

-	var $orig_name		= "";

-	var $file_type		= "";

-	var $file_size		= "";

-	var $file_ext		= "";

-	var $upload_path	= "";

-	var $overwrite		= FALSE;

-	var $encrypt_name	= FALSE;

-	var $is_image		= FALSE;

-	var $image_width	= '';

-	var $image_height	= '';

-	var $image_type		= '';

-	var $image_size_str	= '';

-	var $error_msg		= array();

-	var $mimes			= array();

-	var $remove_spaces	= TRUE;

-	var $xss_clean		= FALSE;

-	var $temp_prefix	= "temp_file_";

-		

-	/**

-	 * Constructor

-	 *

-	 * @access	public

-	 */

-	function CI_Upload($props = array())

-	{

-		if (count($props) > 0)

-		{

-			$this->initialize($props);

-		}

-		

-		log_message('debug', "Upload Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Initialize preferences

-	 *

-	 * @access	public

-	 * @param	array

-	 * @return	void

-	 */	

-	function initialize($config = array())

-	{

-		$defaults = array(

-							'max_size'			=> 0,

-							'max_width'			=> 0,

-							'max_height'		=> 0,

-							'max_filename'		=> 0,

-							'allowed_types'		=> "",

-							'file_temp'			=> "",

-							'file_name'			=> "",

-							'orig_name'			=> "",

-							'file_type'			=> "",

-							'file_size'			=> "",

-							'file_ext'			=> "",

-							'upload_path'		=> "",

-							'overwrite'			=> FALSE,

-							'encrypt_name'		=> FALSE,

-							'is_image'			=> FALSE,

-							'image_width'		=> '',

-							'image_height'		=> '',

-							'image_type'		=> '',

-							'image_size_str'	=> '',

-							'error_msg'			=> array(),

-							'mimes'				=> array(),

-							'remove_spaces'		=> TRUE,

-							'xss_clean'			=> FALSE,

-							'temp_prefix'		=> "temp_file_"

-						);	

-	

-	

-		foreach ($defaults as $key => $val)

-		{

-			if (isset($config[$key]))

-			{

-				$method = 'set_'.$key;

-				if (method_exists($this, $method))

-				{

-					$this->$method($config[$key]);

-				}

-				else

-				{

-					$this->$key = $config[$key];

-				}			

-			}

-			else

-			{

-				$this->$key = $val;

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Perform the file upload

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function do_upload($field = 'userfile')

-	{

-		// Is $_FILES[$field] set? If not, no reason to continue.

-		if ( ! isset($_FILES[$field]))

-		{

-			$this->set_error('upload_no_file_selected');

-			return FALSE;

-		}

-		

-		// Is the upload path valid?

-		if ( ! $this->validate_upload_path())

-		{

-			// errors will already be set by validate_upload_path() so just return FALSE

-			return FALSE;

-		}

-

-		// Was the file able to be uploaded? If not, determine the reason why.

-		if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))

-		{

-			$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];

-

-			switch($error)

-			{

-				case 1:	// UPLOAD_ERR_INI_SIZE

-					$this->set_error('upload_file_exceeds_limit');

-					break;

-				case 2: // UPLOAD_ERR_FORM_SIZE

-					$this->set_error('upload_file_exceeds_form_limit');

-					break;

-				case 3: // UPLOAD_ERR_PARTIAL

-				   $this->set_error('upload_file_partial');

-					break;

-				case 4: // UPLOAD_ERR_NO_FILE

-				   $this->set_error('upload_no_file_selected');

-					break;

-				case 6: // UPLOAD_ERR_NO_TMP_DIR

-					$this->set_error('upload_no_temp_directory');

-					break;

-				case 7: // UPLOAD_ERR_CANT_WRITE

-					$this->set_error('upload_unable_to_write_file');

-					break;

-				case 8: // UPLOAD_ERR_EXTENSION

-					$this->set_error('upload_stopped_by_extension');

-					break;

-				default :   $this->set_error('upload_no_file_selected');

-					break;

-			}

-

-			return FALSE;

-		}

-

-		// Set the uploaded data as class variables

-		$this->file_temp = $_FILES[$field]['tmp_name'];		

-		$this->file_name = $this->_prep_filename($_FILES[$field]['name']);

-		$this->file_size = $_FILES[$field]['size'];		

-		$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);

-		$this->file_type = strtolower($this->file_type);

-		$this->file_ext	 = $this->get_extension($_FILES[$field]['name']);

-		

-		// Convert the file size to kilobytes

-		if ($this->file_size > 0)

-		{

-			$this->file_size = round($this->file_size/1024, 2);

-		}

-

-		// Is the file type allowed to be uploaded?

-		if ( ! $this->is_allowed_filetype())

-		{

-			$this->set_error('upload_invalid_filetype');

-			return FALSE;

-		}

-

-		// Is the file size within the allowed maximum?

-		if ( ! $this->is_allowed_filesize())

-		{

-			$this->set_error('upload_invalid_filesize');

-			return FALSE;

-		}

-

-		// Are the image dimensions within the allowed size?

-		// Note: This can fail if the server has an open_basdir restriction.

-		if ( ! $this->is_allowed_dimensions())

-		{

-			$this->set_error('upload_invalid_dimensions');

-			return FALSE;

-		}

-

-		// Sanitize the file name for security

-		$this->file_name = $this->clean_file_name($this->file_name);

-		

-		// Truncate the file name if it's too long

-		if ($this->max_filename > 0)

-		{

-			$this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);

-		}

-

-		// Remove white spaces in the name

-		if ($this->remove_spaces == TRUE)

-		{

-			$this->file_name = preg_replace("/\s+/", "_", $this->file_name);

-		}

-

-		/*

-		 * Validate the file name

-		 * This function appends an number onto the end of

-		 * the file if one with the same name already exists.

-		 * If it returns false there was a problem.

-		 */

-		$this->orig_name = $this->file_name;

-

-		if ($this->overwrite == FALSE)

-		{

-			$this->file_name = $this->set_filename($this->upload_path, $this->file_name);

-			

-			if ($this->file_name === FALSE)

-			{

-				return FALSE;

-			}

-		}

-

-		/*

-		 * Move the file to the final destination

-		 * To deal with different server configurations

-		 * we'll attempt to use copy() first.  If that fails

-		 * we'll use move_uploaded_file().  One of the two should

-		 * reliably work in most environments

-		 */

-		if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))

-		{

-			if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))

-			{

-				 $this->set_error('upload_destination_error');

-				 return FALSE;

-			}

-		}

-		

-		/*

-		 * Run the file through the XSS hacking filter

-		 * This helps prevent malicious code from being

-		 * embedded within a file.  Scripts can easily

-		 * be disguised as images or other file types.

-		 */

-		if ($this->xss_clean == TRUE)

-		{

-			$this->do_xss_clean();

-		}

-

-		/*

-		 * Set the finalized image dimensions

-		 * This sets the image width/height (assuming the

-		 * file was an image).  We use this information

-		 * in the "data" function.

-		 */

-		$this->set_image_properties($this->upload_path.$this->file_name);

-

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Finalized Data Array

-	 *	

-	 * Returns an associative array containing all of the information

-	 * related to the upload, allowing the developer easy access in one array.

-	 *

-	 * @access	public

-	 * @return	array

-	 */	

-	function data()

-	{

-		return array (

-						'file_name'			=> $this->file_name,

-						'file_type'			=> $this->file_type,

-						'file_path'			=> $this->upload_path,

-						'full_path'			=> $this->upload_path.$this->file_name,

-						'raw_name'			=> str_replace($this->file_ext, '', $this->file_name),

-						'orig_name'			=> $this->orig_name,

-						'file_ext'			=> $this->file_ext,

-						'file_size'			=> $this->file_size,

-						'is_image'			=> $this->is_image(),

-						'image_width'		=> $this->image_width,

-						'image_height'		=> $this->image_height,

-						'image_type'		=> $this->image_type,

-						'image_size_str'	=> $this->image_size_str,

-					);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Upload Path

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_upload_path($path)

-	{

-		// Make sure it has a trailing slash

-		$this->upload_path = rtrim($path, '/').'/';

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the file name

-	 *

-	 * This function takes a filename/path as input and looks for the

-	 * existence of a file with the same name. If found, it will append a

-	 * number to the end of the filename to avoid overwriting a pre-existing file.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_filename($path, $filename)

-	{

-		if ($this->encrypt_name == TRUE)

-		{		

-			mt_srand();

-			$filename = md5(uniqid(mt_rand())).$this->file_ext;	

-		}

-	

-		if ( ! file_exists($path.$filename))

-		{

-			return $filename;

-		}

-	

-		$filename = str_replace($this->file_ext, '', $filename);

-		

-		$new_filename = '';

-		for ($i = 1; $i < 100; $i++)

-		{			

-			if ( ! file_exists($path.$filename.$i.$this->file_ext))

-			{

-				$new_filename = $filename.$i.$this->file_ext;

-				break;

-			}

-		}

-

-		if ($new_filename == '')

-		{

-			$this->set_error('upload_bad_filename');

-			return FALSE;

-		}

-		else

-		{

-			return $new_filename;

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Maximum File Size

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */	

-	function set_max_filesize($n)

-	{

-		$this->max_size = ((int) $n < 0) ? 0: (int) $n;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Maximum File Name Length

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */	

-	function set_max_filename($n)

-	{

-		$this->max_filename = ((int) $n < 0) ? 0: (int) $n;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Maximum Image Width

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */	

-	function set_max_width($n)

-	{

-		$this->max_width = ((int) $n < 0) ? 0: (int) $n;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Maximum Image Height

-	 *

-	 * @access	public

-	 * @param	integer

-	 * @return	void

-	 */	

-	function set_max_height($n)

-	{

-		$this->max_height = ((int) $n < 0) ? 0: (int) $n;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Allowed File Types

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_allowed_types($types)

-	{

-		$this->allowed_types = explode('|', $types);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Image Properties

-	 *

-	 * Uses GD to determine the width/height/type of image

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_image_properties($path = '')

-	{

-		if ( ! $this->is_image())

-		{

-			return;

-		}

-

-		if (function_exists('getimagesize'))

-		{

-			if (FALSE !== ($D = @getimagesize($path)))

-			{	

-				$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');

-

-				$this->image_width		= $D['0'];

-				$this->image_height		= $D['1'];

-				$this->image_type		= ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];

-				$this->image_size_str	= $D['3'];  // string containing height and width

-			}

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set XSS Clean

-	 *

-	 * Enables the XSS flag so that the file that was uploaded

-	 * will be run through the XSS filter.

-	 *

-	 * @access	public

-	 * @param	bool

-	 * @return	void

-	 */

-	function set_xss_clean($flag = FALSE)

-	{

-		$this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validate the image

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function is_image()

-	{

-		// IE will sometimes return odd mime-types during upload, so here we just standardize all

-		// jpegs or pngs to the same file type.

-

-		$png_mimes  = array('image/x-png');

-		$jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');

-		

-		if (in_array($this->file_type, $png_mimes))

-		{

-			$this->file_type = 'image/png';

-		}

-		

-		if (in_array($this->file_type, $jpeg_mimes))

-		{

-			$this->file_type = 'image/jpeg';

-		}

-

-		$img_mimes = array(

-							'image/gif',

-							'image/jpeg',

-							'image/png',

-						   );

-

-		return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Verify that the filetype is allowed

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function is_allowed_filetype()

-	{

-		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))

-		{

-			$this->set_error('upload_no_file_types');

-			return FALSE;

-		}

-			 	

-		foreach ($this->allowed_types as $val)

-		{

-			$mime = $this->mimes_types(strtolower($val));

-		

-			if (is_array($mime))

-			{

-				if (in_array($this->file_type, $mime, TRUE))

-				{

-					return TRUE;

-				}

-			}

-			else

-			{

-				if ($mime == $this->file_type)

-				{

-					return TRUE;

-				}	

-			}		

-		}

-		

-		return FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Verify that the file is within the allowed size

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function is_allowed_filesize()

-	{

-		if ($this->max_size != 0  AND  $this->file_size > $this->max_size)

-		{

-			return FALSE;

-		}

-		else

-		{

-			return TRUE;

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Verify that the image is within the allowed width/height

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function is_allowed_dimensions()

-	{

-		if ( ! $this->is_image())

-		{

-			return TRUE;

-		}

-

-		if (function_exists('getimagesize'))

-		{

-			$D = @getimagesize($this->file_temp);

-

-			if ($this->max_width > 0 AND $D['0'] > $this->max_width)

-			{

-				return FALSE;

-			}

-

-			if ($this->max_height > 0 AND $D['1'] > $this->max_height)

-			{

-				return FALSE;

-			}

-

-			return TRUE;

-		}

-

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validate Upload Path

-	 *

-	 * Verifies that it is a valid upload path with proper permissions.

-	 *

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function validate_upload_path()

-	{

-		if ($this->upload_path == '')

-		{

-			$this->set_error('upload_no_filepath');

-			return FALSE;

-		}

-		

-		if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)

-		{

-			$this->upload_path = str_replace("\\", "/", realpath($this->upload_path));

-		}

-

-		if ( ! @is_dir($this->upload_path))

-		{

-			$this->set_error('upload_no_filepath');

-			return FALSE;

-		}

-

-		if ( ! is_really_writable($this->upload_path))

-		{

-			$this->set_error('upload_not_writable');

-			return FALSE;

-		}

-

-		$this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/",  $this->upload_path);

-		return TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Extract the file extension

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function get_extension($filename)

-	{

-		$x = explode('.', $filename);

-		return '.'.end($x);

-	}	

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Clean the file name for security

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */		

-	function clean_file_name($filename)

-	{

-		$bad = array(

-						"<!--",

-						"-->",

-						"'",

-						"<",

-						">",

-						'"',

-						'&',

-						'$',

-						'=',

-						';',

-						'?',

-						'/',

-						"%20",

-						"%22",

-						"%3c",		// <

-						"%253c", 	// <

-						"%3e", 		// >

-						"%0e", 		// >

-						"%28", 		// (

-						"%29", 		// )

-						"%2528", 	// (

-						"%26", 		// &

-						"%24", 		// $

-						"%3f", 		// ?

-						"%3b", 		// ;

-						"%3d"		// =

-					);

-					

-		$filename = str_replace($bad, '', $filename);

-

-		return stripslashes($filename);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Limit the File Name Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */		

-	function limit_filename_length($filename, $length)

-	{

-		if (strlen($filename) < $length)

-		{

-			return $filename;

-		}

-	

-		$ext = '';

-		if (strpos($filename, '.') !== FALSE)

-		{

-			$parts		= explode('.', $filename);

-			$ext		= '.'.array_pop($parts);

-			$filename	= implode('.', $parts);

-		}

-	

-		return substr($filename, 0, ($length - strlen($ext))).$ext;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Runs the file through the XSS clean function

-	 *

-	 * This prevents people from embedding malicious code in their files.

-	 * I'm not sure that it won't negatively affect certain files in unexpected ways,

-	 * but so far I haven't found that it causes trouble.

-	 *

-	 * @access	public

-	 * @return	void

-	 */	

-	function do_xss_clean()

-	{		

-		$file = $this->upload_path.$this->file_name;

-		

-		if (filesize($file) == 0)

-		{

-			return FALSE;

-		}

-

-		if (($data = @file_get_contents($file)) === FALSE)

-		{

-			return FALSE;

-		}

-		

-		if ( ! $fp = @fopen($file, FOPEN_READ_WRITE))

-		{

-			return FALSE;

-		}

-

-		$CI =& get_instance();	

-		$data = $CI->input->xss_clean($data);

-		

-		flock($fp, LOCK_EX);

-		fwrite($fp, $data);

-		flock($fp, LOCK_UN);

-		fclose($fp);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set an error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_error($msg)

-	{

-		$CI =& get_instance();	

-		$CI->lang->load('upload');

-		

-		if (is_array($msg))

-		{

-			foreach ($msg as $val)

-			{

-				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);				

-				$this->error_msg[] = $msg;

-				log_message('error', $msg);

-			}		

-		}

-		else

-		{

-			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);

-			$this->error_msg[] = $msg;

-			log_message('error', $msg);

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Display the error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function display_errors($open = '<p>', $close = '</p>')

-	{

-		$str = '';

-		foreach ($this->error_msg as $val)

-		{

-			$str .= $open.$val.$close;

-		}

-	

-		return $str;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * List of Mime Types

-	 *

-	 * This is a list of mime types.  We use it to validate

-	 * the "allowed types" set by the developer

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function mimes_types($mime)

-	{

-		global $mimes;

-	

-		if (count($this->mimes) == 0)

-		{

-			if (@require_once(APPPATH.'config/mimes'.EXT))

-			{

-				$this->mimes = $mimes;

-				unset($mimes);

-			}

-		}

-	

-		return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep Filename

-	 *

-	 * Prevents possible script execution from Apache's handling of files multiple extensions

-	 * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext

-	 *

-	 * @access	private

-	 * @param	string

-	 * @return	string

-	 */

-	function _prep_filename($filename)

-	{

-		if (strpos($filename, '.') === FALSE)

-		{

-			return $filename;

-		}

-		

-		$parts		= explode('.', $filename);

-		$ext		= array_pop($parts);

-		$filename	= array_shift($parts);

-				

-		foreach ($parts as $part)

-		{

-			if ($this->mimes_types(strtolower($part)) === FALSE)

-			{

-				$filename .= '.'.$part.'_';

-			}

-			else

-			{

-				$filename .= '.'.$part;

-			}

-		}

-		

-		$filename .= '.'.$ext;

-		

-		return $filename;

-	}

-

-	// --------------------------------------------------------------------

-

-}

-// END Upload Class

-

-/* End of file Upload.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * File Uploading Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Uploads
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/file_uploading.html
+ */
+class CI_Upload {
+	
+	var $max_size		= 0;
+	var $max_width		= 0;
+	var $max_height		= 0;
+	var $max_filename	= 0;
+	var $allowed_types	= "";
+	var $file_temp		= "";
+	var $file_name		= "";
+	var $orig_name		= "";
+	var $file_type		= "";
+	var $file_size		= "";
+	var $file_ext		= "";
+	var $upload_path	= "";
+	var $overwrite		= FALSE;
+	var $encrypt_name	= FALSE;
+	var $is_image		= FALSE;
+	var $image_width	= '';
+	var $image_height	= '';
+	var $image_type		= '';
+	var $image_size_str	= '';
+	var $error_msg		= array();
+	var $mimes			= array();
+	var $remove_spaces	= TRUE;
+	var $xss_clean		= FALSE;
+	var $temp_prefix	= "temp_file_";
+		
+	/**
+	 * Constructor
+	 *
+	 * @access	public
+	 */
+	function CI_Upload($props = array())
+	{
+		if (count($props) > 0)
+		{
+			$this->initialize($props);
+		}
+		
+		log_message('debug', "Upload Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Initialize preferences
+	 *
+	 * @access	public
+	 * @param	array
+	 * @return	void
+	 */	
+	function initialize($config = array())
+	{
+		$defaults = array(
+							'max_size'			=> 0,
+							'max_width'			=> 0,
+							'max_height'		=> 0,
+							'max_filename'		=> 0,
+							'allowed_types'		=> "",
+							'file_temp'			=> "",
+							'file_name'			=> "",
+							'orig_name'			=> "",
+							'file_type'			=> "",
+							'file_size'			=> "",
+							'file_ext'			=> "",
+							'upload_path'		=> "",
+							'overwrite'			=> FALSE,
+							'encrypt_name'		=> FALSE,
+							'is_image'			=> FALSE,
+							'image_width'		=> '',
+							'image_height'		=> '',
+							'image_type'		=> '',
+							'image_size_str'	=> '',
+							'error_msg'			=> array(),
+							'mimes'				=> array(),
+							'remove_spaces'		=> TRUE,
+							'xss_clean'			=> FALSE,
+							'temp_prefix'		=> "temp_file_"
+						);	
+	
+	
+		foreach ($defaults as $key => $val)
+		{
+			if (isset($config[$key]))
+			{
+				$method = 'set_'.$key;
+				if (method_exists($this, $method))
+				{
+					$this->$method($config[$key]);
+				}
+				else
+				{
+					$this->$key = $config[$key];
+				}			
+			}
+			else
+			{
+				$this->$key = $val;
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Perform the file upload
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function do_upload($field = 'userfile')
+	{
+		// Is $_FILES[$field] set? If not, no reason to continue.
+		if ( ! isset($_FILES[$field]))
+		{
+			$this->set_error('upload_no_file_selected');
+			return FALSE;
+		}
+		
+		// Is the upload path valid?
+		if ( ! $this->validate_upload_path())
+		{
+			// errors will already be set by validate_upload_path() so just return FALSE
+			return FALSE;
+		}
+
+		// Was the file able to be uploaded? If not, determine the reason why.
+		if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))
+		{
+			$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
+
+			switch($error)
+			{
+				case 1:	// UPLOAD_ERR_INI_SIZE
+					$this->set_error('upload_file_exceeds_limit');
+					break;
+				case 2: // UPLOAD_ERR_FORM_SIZE
+					$this->set_error('upload_file_exceeds_form_limit');
+					break;
+				case 3: // UPLOAD_ERR_PARTIAL
+				   $this->set_error('upload_file_partial');
+					break;
+				case 4: // UPLOAD_ERR_NO_FILE
+				   $this->set_error('upload_no_file_selected');
+					break;
+				case 6: // UPLOAD_ERR_NO_TMP_DIR
+					$this->set_error('upload_no_temp_directory');
+					break;
+				case 7: // UPLOAD_ERR_CANT_WRITE
+					$this->set_error('upload_unable_to_write_file');
+					break;
+				case 8: // UPLOAD_ERR_EXTENSION
+					$this->set_error('upload_stopped_by_extension');
+					break;
+				default :   $this->set_error('upload_no_file_selected');
+					break;
+			}
+
+			return FALSE;
+		}
+
+		// Set the uploaded data as class variables
+		$this->file_temp = $_FILES[$field]['tmp_name'];		
+		$this->file_name = $this->_prep_filename($_FILES[$field]['name']);
+		$this->file_size = $_FILES[$field]['size'];		
+		$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
+		$this->file_type = strtolower($this->file_type);
+		$this->file_ext	 = $this->get_extension($_FILES[$field]['name']);
+		
+		// Convert the file size to kilobytes
+		if ($this->file_size > 0)
+		{
+			$this->file_size = round($this->file_size/1024, 2);
+		}
+
+		// Is the file type allowed to be uploaded?
+		if ( ! $this->is_allowed_filetype())
+		{
+			$this->set_error('upload_invalid_filetype');
+			return FALSE;
+		}
+
+		// Is the file size within the allowed maximum?
+		if ( ! $this->is_allowed_filesize())
+		{
+			$this->set_error('upload_invalid_filesize');
+			return FALSE;
+		}
+
+		// Are the image dimensions within the allowed size?
+		// Note: This can fail if the server has an open_basdir restriction.
+		if ( ! $this->is_allowed_dimensions())
+		{
+			$this->set_error('upload_invalid_dimensions');
+			return FALSE;
+		}
+
+		// Sanitize the file name for security
+		$this->file_name = $this->clean_file_name($this->file_name);
+		
+		// Truncate the file name if it's too long
+		if ($this->max_filename > 0)
+		{
+			$this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
+		}
+
+		// Remove white spaces in the name
+		if ($this->remove_spaces == TRUE)
+		{
+			$this->file_name = preg_replace("/\s+/", "_", $this->file_name);
+		}
+
+		/*
+		 * Validate the file name
+		 * This function appends an number onto the end of
+		 * the file if one with the same name already exists.
+		 * If it returns false there was a problem.
+		 */
+		$this->orig_name = $this->file_name;
+
+		if ($this->overwrite == FALSE)
+		{
+			$this->file_name = $this->set_filename($this->upload_path, $this->file_name);
+			
+			if ($this->file_name === FALSE)
+			{
+				return FALSE;
+			}
+		}
+
+		/*
+		 * Move the file to the final destination
+		 * To deal with different server configurations
+		 * we'll attempt to use copy() first.  If that fails
+		 * we'll use move_uploaded_file().  One of the two should
+		 * reliably work in most environments
+		 */
+		if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))
+		{
+			if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))
+			{
+				 $this->set_error('upload_destination_error');
+				 return FALSE;
+			}
+		}
+		
+		/*
+		 * Run the file through the XSS hacking filter
+		 * This helps prevent malicious code from being
+		 * embedded within a file.  Scripts can easily
+		 * be disguised as images or other file types.
+		 */
+		if ($this->xss_clean == TRUE)
+		{
+			$this->do_xss_clean();
+		}
+
+		/*
+		 * Set the finalized image dimensions
+		 * This sets the image width/height (assuming the
+		 * file was an image).  We use this information
+		 * in the "data" function.
+		 */
+		$this->set_image_properties($this->upload_path.$this->file_name);
+
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Finalized Data Array
+	 *	
+	 * Returns an associative array containing all of the information
+	 * related to the upload, allowing the developer easy access in one array.
+	 *
+	 * @access	public
+	 * @return	array
+	 */	
+	function data()
+	{
+		return array (
+						'file_name'			=> $this->file_name,
+						'file_type'			=> $this->file_type,
+						'file_path'			=> $this->upload_path,
+						'full_path'			=> $this->upload_path.$this->file_name,
+						'raw_name'			=> str_replace($this->file_ext, '', $this->file_name),
+						'orig_name'			=> $this->orig_name,
+						'file_ext'			=> $this->file_ext,
+						'file_size'			=> $this->file_size,
+						'is_image'			=> $this->is_image(),
+						'image_width'		=> $this->image_width,
+						'image_height'		=> $this->image_height,
+						'image_type'		=> $this->image_type,
+						'image_size_str'	=> $this->image_size_str,
+					);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Upload Path
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_upload_path($path)
+	{
+		// Make sure it has a trailing slash
+		$this->upload_path = rtrim($path, '/').'/';
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the file name
+	 *
+	 * This function takes a filename/path as input and looks for the
+	 * existence of a file with the same name. If found, it will append a
+	 * number to the end of the filename to avoid overwriting a pre-existing file.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_filename($path, $filename)
+	{
+		if ($this->encrypt_name == TRUE)
+		{		
+			mt_srand();
+			$filename = md5(uniqid(mt_rand())).$this->file_ext;	
+		}
+	
+		if ( ! file_exists($path.$filename))
+		{
+			return $filename;
+		}
+	
+		$filename = str_replace($this->file_ext, '', $filename);
+		
+		$new_filename = '';
+		for ($i = 1; $i < 100; $i++)
+		{			
+			if ( ! file_exists($path.$filename.$i.$this->file_ext))
+			{
+				$new_filename = $filename.$i.$this->file_ext;
+				break;
+			}
+		}
+
+		if ($new_filename == '')
+		{
+			$this->set_error('upload_bad_filename');
+			return FALSE;
+		}
+		else
+		{
+			return $new_filename;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Maximum File Size
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */	
+	function set_max_filesize($n)
+	{
+		$this->max_size = ((int) $n < 0) ? 0: (int) $n;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Maximum File Name Length
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */	
+	function set_max_filename($n)
+	{
+		$this->max_filename = ((int) $n < 0) ? 0: (int) $n;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Maximum Image Width
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */	
+	function set_max_width($n)
+	{
+		$this->max_width = ((int) $n < 0) ? 0: (int) $n;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Maximum Image Height
+	 *
+	 * @access	public
+	 * @param	integer
+	 * @return	void
+	 */	
+	function set_max_height($n)
+	{
+		$this->max_height = ((int) $n < 0) ? 0: (int) $n;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Allowed File Types
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_allowed_types($types)
+	{
+		$this->allowed_types = explode('|', $types);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Image Properties
+	 *
+	 * Uses GD to determine the width/height/type of image
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_image_properties($path = '')
+	{
+		if ( ! $this->is_image())
+		{
+			return;
+		}
+
+		if (function_exists('getimagesize'))
+		{
+			if (FALSE !== ($D = @getimagesize($path)))
+			{	
+				$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
+
+				$this->image_width		= $D['0'];
+				$this->image_height		= $D['1'];
+				$this->image_type		= ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
+				$this->image_size_str	= $D['3'];  // string containing height and width
+			}
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set XSS Clean
+	 *
+	 * Enables the XSS flag so that the file that was uploaded
+	 * will be run through the XSS filter.
+	 *
+	 * @access	public
+	 * @param	bool
+	 * @return	void
+	 */
+	function set_xss_clean($flag = FALSE)
+	{
+		$this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate the image
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function is_image()
+	{
+		// IE will sometimes return odd mime-types during upload, so here we just standardize all
+		// jpegs or pngs to the same file type.
+
+		$png_mimes  = array('image/x-png');
+		$jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');
+		
+		if (in_array($this->file_type, $png_mimes))
+		{
+			$this->file_type = 'image/png';
+		}
+		
+		if (in_array($this->file_type, $jpeg_mimes))
+		{
+			$this->file_type = 'image/jpeg';
+		}
+
+		$img_mimes = array(
+							'image/gif',
+							'image/jpeg',
+							'image/png',
+						   );
+
+		return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Verify that the filetype is allowed
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function is_allowed_filetype()
+	{
+		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
+		{
+			$this->set_error('upload_no_file_types');
+			return FALSE;
+		}
+			 	
+		foreach ($this->allowed_types as $val)
+		{
+			$mime = $this->mimes_types(strtolower($val));
+		
+			if (is_array($mime))
+			{
+				if (in_array($this->file_type, $mime, TRUE))
+				{
+					return TRUE;
+				}
+			}
+			else
+			{
+				if ($mime == $this->file_type)
+				{
+					return TRUE;
+				}	
+			}		
+		}
+		
+		return FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Verify that the file is within the allowed size
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function is_allowed_filesize()
+	{
+		if ($this->max_size != 0  AND  $this->file_size > $this->max_size)
+		{
+			return FALSE;
+		}
+		else
+		{
+			return TRUE;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Verify that the image is within the allowed width/height
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function is_allowed_dimensions()
+	{
+		if ( ! $this->is_image())
+		{
+			return TRUE;
+		}
+
+		if (function_exists('getimagesize'))
+		{
+			$D = @getimagesize($this->file_temp);
+
+			if ($this->max_width > 0 AND $D['0'] > $this->max_width)
+			{
+				return FALSE;
+			}
+
+			if ($this->max_height > 0 AND $D['1'] > $this->max_height)
+			{
+				return FALSE;
+			}
+
+			return TRUE;
+		}
+
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate Upload Path
+	 *
+	 * Verifies that it is a valid upload path with proper permissions.
+	 *
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function validate_upload_path()
+	{
+		if ($this->upload_path == '')
+		{
+			$this->set_error('upload_no_filepath');
+			return FALSE;
+		}
+		
+		if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)
+		{
+			$this->upload_path = str_replace("\\", "/", realpath($this->upload_path));
+		}
+
+		if ( ! @is_dir($this->upload_path))
+		{
+			$this->set_error('upload_no_filepath');
+			return FALSE;
+		}
+
+		if ( ! is_really_writable($this->upload_path))
+		{
+			$this->set_error('upload_not_writable');
+			return FALSE;
+		}
+
+		$this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/",  $this->upload_path);
+		return TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Extract the file extension
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function get_extension($filename)
+	{
+		$x = explode('.', $filename);
+		return '.'.end($x);
+	}	
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Clean the file name for security
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */		
+	function clean_file_name($filename)
+	{
+		$bad = array(
+						"<!--",
+						"-->",
+						"'",
+						"<",
+						">",
+						'"',
+						'&',
+						'$',
+						'=',
+						';',
+						'?',
+						'/',
+						"%20",
+						"%22",
+						"%3c",		// <
+						"%253c", 	// <
+						"%3e", 		// >
+						"%0e", 		// >
+						"%28", 		// (
+						"%29", 		// )
+						"%2528", 	// (
+						"%26", 		// &
+						"%24", 		// $
+						"%3f", 		// ?
+						"%3b", 		// ;
+						"%3d"		// =
+					);
+					
+		$filename = str_replace($bad, '', $filename);
+
+		return stripslashes($filename);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Limit the File Name Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */		
+	function limit_filename_length($filename, $length)
+	{
+		if (strlen($filename) < $length)
+		{
+			return $filename;
+		}
+	
+		$ext = '';
+		if (strpos($filename, '.') !== FALSE)
+		{
+			$parts		= explode('.', $filename);
+			$ext		= '.'.array_pop($parts);
+			$filename	= implode('.', $parts);
+		}
+	
+		return substr($filename, 0, ($length - strlen($ext))).$ext;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Runs the file through the XSS clean function
+	 *
+	 * This prevents people from embedding malicious code in their files.
+	 * I'm not sure that it won't negatively affect certain files in unexpected ways,
+	 * but so far I haven't found that it causes trouble.
+	 *
+	 * @access	public
+	 * @return	void
+	 */	
+	function do_xss_clean()
+	{		
+		$file = $this->upload_path.$this->file_name;
+		
+		if (filesize($file) == 0)
+		{
+			return FALSE;
+		}
+
+		if (($data = @file_get_contents($file)) === FALSE)
+		{
+			return FALSE;
+		}
+		
+		if ( ! $fp = @fopen($file, FOPEN_READ_WRITE))
+		{
+			return FALSE;
+		}
+
+		$CI =& get_instance();	
+		$data = $CI->input->xss_clean($data);
+		
+		flock($fp, LOCK_EX);
+		fwrite($fp, $data);
+		flock($fp, LOCK_UN);
+		fclose($fp);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set an error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_error($msg)
+	{
+		$CI =& get_instance();	
+		$CI->lang->load('upload');
+		
+		if (is_array($msg))
+		{
+			foreach ($msg as $val)
+			{
+				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);				
+				$this->error_msg[] = $msg;
+				log_message('error', $msg);
+			}		
+		}
+		else
+		{
+			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
+			$this->error_msg[] = $msg;
+			log_message('error', $msg);
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Display the error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function display_errors($open = '<p>', $close = '</p>')
+	{
+		$str = '';
+		foreach ($this->error_msg as $val)
+		{
+			$str .= $open.$val.$close;
+		}
+	
+		return $str;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * List of Mime Types
+	 *
+	 * This is a list of mime types.  We use it to validate
+	 * the "allowed types" set by the developer
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function mimes_types($mime)
+	{
+		global $mimes;
+	
+		if (count($this->mimes) == 0)
+		{
+			if (@require_once(APPPATH.'config/mimes'.EXT))
+			{
+				$this->mimes = $mimes;
+				unset($mimes);
+			}
+		}
+	
+		return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep Filename
+	 *
+	 * Prevents possible script execution from Apache's handling of files multiple extensions
+	 * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
+	 *
+	 * @access	private
+	 * @param	string
+	 * @return	string
+	 */
+	function _prep_filename($filename)
+	{
+		if (strpos($filename, '.') === FALSE)
+		{
+			return $filename;
+		}
+		
+		$parts		= explode('.', $filename);
+		$ext		= array_pop($parts);
+		$filename	= array_shift($parts);
+				
+		foreach ($parts as $part)
+		{
+			if ($this->mimes_types(strtolower($part)) === FALSE)
+			{
+				$filename .= '.'.$part.'_';
+			}
+			else
+			{
+				$filename .= '.'.$part;
+			}
+		}
+		
+		$filename .= '.'.$ext;
+		
+		return $filename;
+	}
+
+	// --------------------------------------------------------------------
+
+}
+// END Upload Class
+
+/* End of file Upload.php */
 /* Location: ./system/libraries/Upload.php */
\ No newline at end of file
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index c7cf870..78178d0 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -1,502 +1,502 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * User Agent Class

- *

- * Identifies the platform, browser, robot, or mobile devise of the browsing agent

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	User Agent

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/user_agent.html

- */

-class CI_User_agent {

-

-	var $agent		= NULL;

-	

-	var $is_browser	= FALSE;

-	var $is_robot	= FALSE;

-	var $is_mobile	= FALSE;

-

-	var $languages	= array();

-	var $charsets	= array();

-	

-	var $platforms	= array();

-	var $browsers	= array();

-	var $mobiles	= array();

-	var $robots		= array();

-	

-	var $platform	= '';

-	var $browser	= '';

-	var $version	= '';

-	var $mobile		= '';

-	var $robot		= '';

-	

-	/**

-	 * Constructor

-	 *

-	 * Sets the User Agent and runs the compilation routine

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function CI_User_agent()

-	{

-		if (isset($_SERVER['HTTP_USER_AGENT']))

-		{

-			$this->agent = trim($_SERVER['HTTP_USER_AGENT']);

-		}

-		

-		if ( ! is_null($this->agent))

-		{

-			if ($this->_load_agent_file())

-			{

-				$this->_compile_data();

-			}

-		}

-		

-		log_message('debug', "User Agent Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Compile the User Agent Data

-	 *

-	 * @access	private

-	 * @return	bool

-	 */		

-	function _load_agent_file()

-	{

-		if ( ! @include(APPPATH.'config/user_agents'.EXT))

-		{

-			return FALSE;

-		}

-		

-		$return = FALSE;

-		

-		if (isset($platforms))

-		{

-			$this->platforms = $platforms;

-			unset($platforms);

-			$return = TRUE;

-		}

-

-		if (isset($browsers))

-		{

-			$this->browsers = $browsers;

-			unset($browsers);

-			$return = TRUE;

-		}

-

-		if (isset($mobiles))

-		{

-			$this->mobiles = $mobiles;

-			unset($mobiles);

-			$return = TRUE;

-		}

-		

-		if (isset($robots))

-		{

-			$this->robots = $robots;

-			unset($robots);

-			$return = TRUE;

-		}

-

-		return $return;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Compile the User Agent Data

-	 *

-	 * @access	private

-	 * @return	bool

-	 */		

-	function _compile_data()

-	{

-		$this->_set_platform();

-	

-		foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function)

-		{

-			if ($this->$function() === TRUE)

-			{

-				break;

-			}

-		}	

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Platform

-	 *

-	 * @access	private

-	 * @return	mixed

-	 */		

-	function _set_platform()

-	{

-		if (is_array($this->platforms) AND count($this->platforms) > 0)

-		{

-			foreach ($this->platforms as $key => $val)

-			{

-				if (preg_match("|".preg_quote($key)."|i", $this->agent))

-				{

-					$this->platform = $val;

-					return TRUE;

-				}

-			}

-		}

-		$this->platform = 'Unknown Platform';

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Browser

-	 *

-	 * @access	private

-	 * @return	bool

-	 */		

-	function _set_browser()

-	{

-		if (is_array($this->browsers) AND count($this->browsers) > 0)

-		{

-			foreach ($this->browsers as $key => $val)

-			{		

-				if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match))

-				{

-					$this->is_browser = TRUE;

-					$this->version = $match[1];

-					$this->browser = $val;

-					$this->_set_mobile();

-					return TRUE;

-				}

-			}

-		}

-		return FALSE;

-	}

-			

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Robot

-	 *

-	 * @access	private

-	 * @return	bool

-	 */		

-	function _set_robot()

-	{

-		if (is_array($this->robots) AND count($this->robots) > 0)

-		{		

-			foreach ($this->robots as $key => $val)

-			{

-				if (preg_match("|".preg_quote($key)."|i", $this->agent))

-				{

-					$this->is_robot = TRUE;

-					$this->robot = $val;

-					return TRUE;

-				}

-			}

-		}

-		return FALSE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the Mobile Device

-	 *

-	 * @access	private

-	 * @return	bool

-	 */		

-	function _set_mobile()

-	{

-		if (is_array($this->mobiles) AND count($this->mobiles) > 0)

-		{		

-			foreach ($this->mobiles as $key => $val)

-			{

-				if (FALSE !== (strpos(strtolower($this->agent), $key)))

-				{

-					$this->is_mobile = TRUE;

-					$this->mobile = $val;

-					return TRUE;

-				}

-			}

-		}	

-		return FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the accepted languages

-	 *

-	 * @access	private

-	 * @return	void

-	 */			

-	function _set_languages()

-	{

-		if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')

-		{

-			$languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])));

-			

-			$this->languages = explode(',', $languages);

-		}

-		

-		if (count($this->languages) == 0)

-		{

-			$this->languages = array('Undefined');

-		}	

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set the accepted character sets

-	 *

-	 * @access	private

-	 * @return	void

-	 */			

-	function _set_charsets()

-	{	

-		if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')

-		{

-			$charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])));

-			

-			$this->charsets = explode(',', $charsets);

-		}

-		

-		if (count($this->charsets) == 0)

-		{

-			$this->charsets = array('Undefined');

-		}	

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Is Browser

-	 *

-	 * @access	public

-	 * @return	bool

-	 */		

-	function is_browser()

-	{

-		return $this->is_browser;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Is Robot

-	 *

-	 * @access	public

-	 * @return	bool

-	 */		

-	function is_robot()

-	{

-		return $this->is_robot;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Is Mobile

-	 *

-	 * @access	public

-	 * @return	bool

-	 */		

-	function is_mobile()

-	{

-		return $this->is_mobile;

-	}	

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Is this a referral from another site?

-	 *

-	 * @access	public

-	 * @return	bool

-	 */			

-	function is_referral()

-	{

-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Agent String

-	 *

-	 * @access	public

-	 * @return	string

-	 */			

-	function agent_string()

-	{

-		return $this->agent;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get Platform

-	 *

-	 * @access	public

-	 * @return	string

-	 */			

-	function platform()

-	{

-		return $this->platform;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get Browser Name

-	 *

-	 * @access	public

-	 * @return	string

-	 */			

-	function browser()

-	{

-		return $this->browser;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the Browser Version

-	 *

-	 * @access	public

-	 * @return	string

-	 */			

-	function version()

-	{

-		return $this->version;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get The Robot Name

-	 *

-	 * @access	public

-	 * @return	string

-	 */				

-	function robot()

-	{

-		return $this->robot;

-	}

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the Mobile Device

-	 *

-	 * @access	public

-	 * @return	string

-	 */			

-	function mobile()

-	{

-		return $this->mobile;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the referrer

-	 *

-	 * @access	public

-	 * @return	bool

-	 */			

-	function referrer()

-	{

-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the accepted languages

-	 *

-	 * @access	public

-	 * @return	array

-	 */			

-	function languages()

-	{

-		if (count($this->languages) == 0)

-		{

-			$this->_set_languages();

-		}

-	

-		return $this->languages;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Get the accepted Character Sets

-	 *

-	 * @access	public

-	 * @return	array

-	 */			

-	function charsets()

-	{

-		if (count($this->charsets) == 0)

-		{

-			$this->_set_charsets();

-		}

-	

-		return $this->charsets;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Test for a particular language

-	 *

-	 * @access	public

-	 * @return	bool

-	 */			

-	function accept_lang($lang = 'en')

-	{

-		return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Test for a particular character set

-	 *

-	 * @access	public

-	 * @return	bool

-	 */			

-	function accept_charset($charset = 'utf-8')

-	{

-		return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE;

-	}

-	

-	

-}

-

-

-/* End of file User_agent.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * User Agent Class
+ *
+ * Identifies the platform, browser, robot, or mobile devise of the browsing agent
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	User Agent
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/user_agent.html
+ */
+class CI_User_agent {
+
+	var $agent		= NULL;
+	
+	var $is_browser	= FALSE;
+	var $is_robot	= FALSE;
+	var $is_mobile	= FALSE;
+
+	var $languages	= array();
+	var $charsets	= array();
+	
+	var $platforms	= array();
+	var $browsers	= array();
+	var $mobiles	= array();
+	var $robots		= array();
+	
+	var $platform	= '';
+	var $browser	= '';
+	var $version	= '';
+	var $mobile		= '';
+	var $robot		= '';
+	
+	/**
+	 * Constructor
+	 *
+	 * Sets the User Agent and runs the compilation routine
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function CI_User_agent()
+	{
+		if (isset($_SERVER['HTTP_USER_AGENT']))
+		{
+			$this->agent = trim($_SERVER['HTTP_USER_AGENT']);
+		}
+		
+		if ( ! is_null($this->agent))
+		{
+			if ($this->_load_agent_file())
+			{
+				$this->_compile_data();
+			}
+		}
+		
+		log_message('debug', "User Agent Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Compile the User Agent Data
+	 *
+	 * @access	private
+	 * @return	bool
+	 */		
+	function _load_agent_file()
+	{
+		if ( ! @include(APPPATH.'config/user_agents'.EXT))
+		{
+			return FALSE;
+		}
+		
+		$return = FALSE;
+		
+		if (isset($platforms))
+		{
+			$this->platforms = $platforms;
+			unset($platforms);
+			$return = TRUE;
+		}
+
+		if (isset($browsers))
+		{
+			$this->browsers = $browsers;
+			unset($browsers);
+			$return = TRUE;
+		}
+
+		if (isset($mobiles))
+		{
+			$this->mobiles = $mobiles;
+			unset($mobiles);
+			$return = TRUE;
+		}
+		
+		if (isset($robots))
+		{
+			$this->robots = $robots;
+			unset($robots);
+			$return = TRUE;
+		}
+
+		return $return;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Compile the User Agent Data
+	 *
+	 * @access	private
+	 * @return	bool
+	 */		
+	function _compile_data()
+	{
+		$this->_set_platform();
+	
+		foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function)
+		{
+			if ($this->$function() === TRUE)
+			{
+				break;
+			}
+		}	
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Platform
+	 *
+	 * @access	private
+	 * @return	mixed
+	 */		
+	function _set_platform()
+	{
+		if (is_array($this->platforms) AND count($this->platforms) > 0)
+		{
+			foreach ($this->platforms as $key => $val)
+			{
+				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				{
+					$this->platform = $val;
+					return TRUE;
+				}
+			}
+		}
+		$this->platform = 'Unknown Platform';
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Browser
+	 *
+	 * @access	private
+	 * @return	bool
+	 */		
+	function _set_browser()
+	{
+		if (is_array($this->browsers) AND count($this->browsers) > 0)
+		{
+			foreach ($this->browsers as $key => $val)
+			{		
+				if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match))
+				{
+					$this->is_browser = TRUE;
+					$this->version = $match[1];
+					$this->browser = $val;
+					$this->_set_mobile();
+					return TRUE;
+				}
+			}
+		}
+		return FALSE;
+	}
+			
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Robot
+	 *
+	 * @access	private
+	 * @return	bool
+	 */		
+	function _set_robot()
+	{
+		if (is_array($this->robots) AND count($this->robots) > 0)
+		{		
+			foreach ($this->robots as $key => $val)
+			{
+				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				{
+					$this->is_robot = TRUE;
+					$this->robot = $val;
+					return TRUE;
+				}
+			}
+		}
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the Mobile Device
+	 *
+	 * @access	private
+	 * @return	bool
+	 */		
+	function _set_mobile()
+	{
+		if (is_array($this->mobiles) AND count($this->mobiles) > 0)
+		{		
+			foreach ($this->mobiles as $key => $val)
+			{
+				if (FALSE !== (strpos(strtolower($this->agent), $key)))
+				{
+					$this->is_mobile = TRUE;
+					$this->mobile = $val;
+					return TRUE;
+				}
+			}
+		}	
+		return FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the accepted languages
+	 *
+	 * @access	private
+	 * @return	void
+	 */			
+	function _set_languages()
+	{
+		if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')
+		{
+			$languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
+			
+			$this->languages = explode(',', $languages);
+		}
+		
+		if (count($this->languages) == 0)
+		{
+			$this->languages = array('Undefined');
+		}	
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set the accepted character sets
+	 *
+	 * @access	private
+	 * @return	void
+	 */			
+	function _set_charsets()
+	{	
+		if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')
+		{
+			$charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])));
+			
+			$this->charsets = explode(',', $charsets);
+		}
+		
+		if (count($this->charsets) == 0)
+		{
+			$this->charsets = array('Undefined');
+		}	
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Is Browser
+	 *
+	 * @access	public
+	 * @return	bool
+	 */		
+	function is_browser()
+	{
+		return $this->is_browser;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Is Robot
+	 *
+	 * @access	public
+	 * @return	bool
+	 */		
+	function is_robot()
+	{
+		return $this->is_robot;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Is Mobile
+	 *
+	 * @access	public
+	 * @return	bool
+	 */		
+	function is_mobile()
+	{
+		return $this->is_mobile;
+	}	
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Is this a referral from another site?
+	 *
+	 * @access	public
+	 * @return	bool
+	 */			
+	function is_referral()
+	{
+		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Agent String
+	 *
+	 * @access	public
+	 * @return	string
+	 */			
+	function agent_string()
+	{
+		return $this->agent;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get Platform
+	 *
+	 * @access	public
+	 * @return	string
+	 */			
+	function platform()
+	{
+		return $this->platform;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get Browser Name
+	 *
+	 * @access	public
+	 * @return	string
+	 */			
+	function browser()
+	{
+		return $this->browser;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the Browser Version
+	 *
+	 * @access	public
+	 * @return	string
+	 */			
+	function version()
+	{
+		return $this->version;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get The Robot Name
+	 *
+	 * @access	public
+	 * @return	string
+	 */				
+	function robot()
+	{
+		return $this->robot;
+	}
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the Mobile Device
+	 *
+	 * @access	public
+	 * @return	string
+	 */			
+	function mobile()
+	{
+		return $this->mobile;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the referrer
+	 *
+	 * @access	public
+	 * @return	bool
+	 */			
+	function referrer()
+	{
+		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the accepted languages
+	 *
+	 * @access	public
+	 * @return	array
+	 */			
+	function languages()
+	{
+		if (count($this->languages) == 0)
+		{
+			$this->_set_languages();
+		}
+	
+		return $this->languages;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Get the accepted Character Sets
+	 *
+	 * @access	public
+	 * @return	array
+	 */			
+	function charsets()
+	{
+		if (count($this->charsets) == 0)
+		{
+			$this->_set_charsets();
+		}
+	
+		return $this->charsets;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Test for a particular language
+	 *
+	 * @access	public
+	 * @return	bool
+	 */			
+	function accept_lang($lang = 'en')
+	{
+		return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Test for a particular character set
+	 *
+	 * @access	public
+	 * @return	bool
+	 */			
+	function accept_charset($charset = 'utf-8')
+	{
+		return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE;
+	}
+	
+	
+}
+
+
+/* End of file User_agent.php */
 /* Location: ./system/libraries/User_agent.php */
\ No newline at end of file
diff --git a/system/libraries/Validation.php b/system/libraries/Validation.php
index a463202..4baf78b 100644
--- a/system/libraries/Validation.php
+++ b/system/libraries/Validation.php
@@ -1,875 +1,875 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Validation Class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Validation

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/validation.html

- */

-class CI_Validation {

-	

-	var $CI;

-	var $error_string		= '';

-	var $_error_array		= array();

-	var $_rules				= array();

-	var $_fields			= array();

-	var $_error_messages	= array();

-	var $_current_field  	= '';

-	var $_safe_form_data 	= FALSE;

-	var $_error_prefix		= '<p>';

-	var $_error_suffix		= '</p>';

-

-	

-

-	/**

-	 * Constructor

-	 *

-	 */	

-	function CI_Validation()

-	{	

-		$this->CI =& get_instance();

-		

-		if (function_exists('mb_internal_encoding'))

-		{

-			mb_internal_encoding($this->CI->config->item('charset'));

-		}

-		

-		log_message('debug', "Validation Class Initialized");

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Fields

-	 *

-	 * This function takes an array of field names as input

-	 * and generates class variables with the same name, which will

-	 * either be blank or contain the $_POST value corresponding to it

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */

-	function set_fields($data = '', $field = '')

-	{	

-		if ($data == '')

-		{

-			if (count($this->_fields) == 0)

-			{

-				return FALSE;

-			}

-		}

-		else

-		{

-			if ( ! is_array($data))

-			{

-				$data = array($data => $field);

-			}

-			

-			if (count($data) > 0)

-			{

-				$this->_fields = $data;

-			}

-		}		

-			

-		foreach($this->_fields as $key => $val)

-		{

-			$this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);

-			

-			$error = $key.'_error';

-			if ( ! isset($this->$error))

-			{

-				$this->$error = '';

-			}

-		}		

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Rules

-	 *

-	 * This function takes an array of field names and validation

-	 * rules as input ad simply stores is for use later.

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @return	void

-	 */

-	function set_rules($data, $rules = '')

-	{

-		if ( ! is_array($data))

-		{

-			if ($rules == '')

-				return;

-				

-			$data = array($data => $rules);

-		}

-	

-		foreach ($data as $key => $val)

-		{

-			$this->_rules[$key] = $val;

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Error Message

-	 *

-	 * Lets users set their own error messages on the fly.  Note:  The key

-	 * name has to match the  function name that it corresponds to.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */

-	function set_message($lang, $val = '')

-	{

-		if ( ! is_array($lang))

-		{

-			$lang = array($lang => $val);

-		}

-	

-		$this->_error_messages = array_merge($this->_error_messages, $lang);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set The Error Delimiter

-	 *

-	 * Permits a prefix/suffix to be added to each error message

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	void

-	 */	

-	function set_error_delimiters($prefix = '<p>', $suffix = '</p>')

-	{

-		$this->_error_prefix = $prefix;

-		$this->_error_suffix = $suffix;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Run the Validator

-	 *

-	 * This function does all the work.

-	 *

-	 * @access	public

-	 * @return	bool

-	 */		

-	function run()

-	{

-		// Do we even have any data to process?  Mm?

-		if (count($_POST) == 0 OR count($this->_rules) == 0)

-		{

-			return FALSE;

-		}

-	

-		// Load the language file containing error messages

-		$this->CI->lang->load('validation');

-							

-		// Cycle through the rules and test for errors

-		foreach ($this->_rules as $field => $rules)

-		{

-			//Explode out the rules!

-			$ex = explode('|', $rules);

-

-			// Is the field required?  If not, if the field is blank  we'll move on to the next test

-			if ( ! in_array('required', $ex, TRUE))

-			{

-				if ( ! isset($_POST[$field]) OR $_POST[$field] == '')

-				{

-					continue;

-				}

-			}

-			

-			/*

-			 * Are we dealing with an "isset" rule?

-			 *

-			 * Before going further, we'll see if one of the rules

-			 * is to check whether the item is set (typically this

-			 * applies only to checkboxes).  If so, we'll

-			 * test for it here since there's not reason to go

-			 * further

-			 */

-			if ( ! isset($_POST[$field]))

-			{			

-				if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))

-				{

-					if ( ! isset($this->_error_messages['isset']))

-					{

-						if (FALSE === ($line = $this->CI->lang->line('isset')))

-						{

-							$line = 'The field was not set';

-						}							

-					}

-					else

-					{

-						$line = $this->_error_messages['isset'];

-					}

-					

-					// Build the error message

-					$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];

-					$message = sprintf($line, $mfield);

-

-					// Set the error variable.  Example: $this->username_error

-					$error = $field.'_error';

-					$this->$error = $this->_error_prefix.$message.$this->_error_suffix;

-					$this->_error_array[] = $message;

-				}

-						

-				continue;

-			}

-	

-			/*

-			 * Set the current field

-			 *

-			 * The various prepping functions need to know the

-			 * current field name so they can do this:

-			 *

-			 * $_POST[$this->_current_field] == 'bla bla';

-			 */

-			$this->_current_field = $field;

-

-			// Cycle through the rules!

-			foreach ($ex As $rule)

-			{

-				// Is the rule a callback?			

-				$callback = FALSE;

-				if (substr($rule, 0, 9) == 'callback_')

-				{

-					$rule = substr($rule, 9);

-					$callback = TRUE;

-				}

-				

-				// Strip the parameter (if exists) from the rule

-				// Rules can contain a parameter: max_length[5]

-				$param = FALSE;

-				if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))

-				{

-					$rule	= $match[1];

-					$param	= $match[2];

-				}

-				

-				// Call the function that corresponds to the rule

-				if ($callback === TRUE)

-				{

-					if ( ! method_exists($this->CI, $rule))

-					{ 		

-						continue;

-					}

-					

-					$result = $this->CI->$rule($_POST[$field], $param);	

-					

-					// If the field isn't required and we just processed a callback we'll move on...

-					if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)

-					{

-						continue 2;

-					}

-					

-				}

-				else

-				{				

-					if ( ! method_exists($this, $rule))

-					{

-						/*

-						 * Run the native PHP function if called for

-						 *

-						 * If our own wrapper function doesn't exist we see

-						 * if a native PHP function does. Users can use

-						 * any native PHP function call that has one param.

-						 */

-						if (function_exists($rule))

-						{

-							$_POST[$field] = $rule($_POST[$field]);

-							$this->$field = $_POST[$field];

-						}

-											

-						continue;

-					}

-					

-					$result = $this->$rule($_POST[$field], $param);

-				}

-								

-				// Did the rule test negatively?  If so, grab the error.

-				if ($result === FALSE)

-				{

-					if ( ! isset($this->_error_messages[$rule]))

-					{

-						if (FALSE === ($line = $this->CI->lang->line($rule)))

-						{

-							$line = 'Unable to access an error message corresponding to your field name.';

-						}						

-					}

-					else

-					{

-						$line = $this->_error_messages[$rule];

-					}				

-

-					// Build the error message

-					$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];

-					$mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];

-					$message = sprintf($line, $mfield, $mparam);

-					

-					// Set the error variable.  Example: $this->username_error

-					$error = $field.'_error';

-					$this->$error = $this->_error_prefix.$message.$this->_error_suffix;

-

-					// Add the error to the error array

-					$this->_error_array[] = $message;				

-					continue 2;

-				}				

-			}

-			

-		}

-		

-		$total_errors = count($this->_error_array);

-

-		/*

-		 * Recompile the class variables

-		 *

-		 * If any prepping functions were called the $_POST data

-		 * might now be different then the corresponding class

-		 * variables so we'll set them anew.

-		 */	

-		if ($total_errors > 0)

-		{

-			$this->_safe_form_data = TRUE;

-		}

-		

-		$this->set_fields();

-

-		// Did we end up with any errors?

-		if ($total_errors == 0)

-		{

-			return TRUE;

-		}

-		

-		// Generate the error string

-		foreach ($this->_error_array as $val)

-		{

-			$this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";

-		}

-

-		return FALSE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Required

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function required($str)

-	{

-		if ( ! is_array($str))

-		{

-			return (trim($str) == '') ? FALSE : TRUE;

-		}

-		else

-		{

-			return ( ! empty($str));

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Match one field to another

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	field

-	 * @return	bool

-	 */

-	function matches($str, $field)

-	{

-		if ( ! isset($_POST[$field]))

-		{

-			return FALSE;

-		}

-		

-		return ($str !== $_POST[$field]) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Minimum Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function min_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) < $val) ? FALSE : TRUE;		

-		}

-

-		return (strlen($str) < $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Max Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function max_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-		

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) > $val) ? FALSE : TRUE;		

-		}

-

-		return (strlen($str) > $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Exact Length

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	value

-	 * @return	bool

-	 */	

-	function exact_length($str, $val)

-	{

-		if (preg_match("/[^0-9]/", $val))

-		{

-			return FALSE;

-		}

-	

-		if (function_exists('mb_strlen'))

-		{

-			return (mb_strlen($str) != $val) ? FALSE : TRUE;		

-		}

-

-		return (strlen($str) != $val) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Email

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function valid_email($str)

-	{

-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Emails

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function valid_emails($str)

-	{

-		if (strpos($str, ',') === FALSE)

-		{

-			return $this->valid_email(trim($str));

-		}

-		

-		foreach(explode(',', $str) as $email)

-		{

-			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)

-			{

-				return FALSE;

-			}

-		}

-		

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Validate IP Address

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function valid_ip($ip)

-	{

-		return $this->CI->input->valid_ip($ip);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */		

-	function alpha($str)

-	{

-		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha-numeric

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function alpha_numeric($str)

-	{

-		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Alpha-numeric with underscores and dashes

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function alpha_dash($str)

-	{

-		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Numeric

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function numeric($str)

-	{

-		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);

-

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Is Numeric

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-  	function is_numeric($str)

-	{

-		return ( ! is_numeric($str)) ? FALSE : TRUE;

-	} 

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Integer

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */	

-	function integer($str)

-	{

-		return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Is a Natural number  (0,1,2,3, etc.)

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function is_natural($str)

-	{   

-   		return (bool)preg_match( '/^[0-9]+$/', $str);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Is a Natural number, but not a zero  (1,2,3, etc.)

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function is_natural_no_zero($str)

-	{   

-		if ( ! preg_match( '/^[0-9]+$/', $str))

-		{

-			return FALSE;

-		}

-	

-		if ($str == 0)

-		{

-			return FALSE;

-		}

-

-		return TRUE;

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Valid Base64

-	 *

-	 * Tests a string for characters outside of the Base64 alphabet

-	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	bool

-	 */

-	function valid_base64($str)

-	{

-		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);

-	}

-

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Select

-	 *

-	 * Enables pull-down lists to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_select($field = '', $value = '')

-	{

-		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))

-		{

-			return '';

-		}

-			

-		if ($_POST[$field] == $value)

-		{

-			return ' selected="selected"';

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Radio

-	 *

-	 * Enables radio buttons to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_radio($field = '', $value = '')

-	{

-		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))

-		{

-			return '';

-		}

-			

-		if ($_POST[$field] == $value)

-		{

-			return ' checked="checked"';

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Set Checkbox

-	 *

-	 * Enables checkboxes to be set to the value the user

-	 * selected in the event of an error

-	 *

-	 * @access	public

-	 * @param	string

-	 * @param	string

-	 * @return	string

-	 */	

-	function set_checkbox($field = '', $value = '')

-	{

-		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))

-		{

-			return '';

-		}

-			

-		if ($_POST[$field] == $value)

-		{

-			return ' checked="checked"';

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep data for form

-	 *

-	 * This function allows HTML to be safely shown in a form.

-	 * Special characters are converted.

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */

-	function prep_for_form($data = '')

-	{

-		if (is_array($data))

-		{

-			foreach ($data as $key => $val)

-			{

-				$data[$key] = $this->prep_for_form($val);

-			}

-			

-			return $data;

-		}

-		

-		if ($this->_safe_form_data == FALSE OR $data == '')

-		{

-			return $data;

-		}

-

-		return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Prep URL

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function prep_url($str = '')

-	{

-		if ($str == 'http://' OR $str == '')

-		{

-			$_POST[$this->_current_field] = '';

-			return;

-		}

-		

-		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')

-		{

-			$str = 'http://'.$str;

-		}

-		

-		$_POST[$this->_current_field] = $str;

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Strip Image Tags

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function strip_image_tags($str)

-	{

-		$_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * XSS Clean

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function xss_clean($str)

-	{

-		$_POST[$this->_current_field] = $this->CI->input->xss_clean($str);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Convert PHP tags to entities

-	 *

-	 * @access	public

-	 * @param	string

-	 * @return	string

-	 */	

-	function encode_php_tags($str)

-	{

-		$_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);

-	}

-

-}

-// END Validation Class

-

-/* End of file Validation.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validation Class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Validation
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/validation.html
+ */
+class CI_Validation {
+	
+	var $CI;
+	var $error_string		= '';
+	var $_error_array		= array();
+	var $_rules				= array();
+	var $_fields			= array();
+	var $_error_messages	= array();
+	var $_current_field  	= '';
+	var $_safe_form_data 	= FALSE;
+	var $_error_prefix		= '<p>';
+	var $_error_suffix		= '</p>';
+
+	
+
+	/**
+	 * Constructor
+	 *
+	 */	
+	function CI_Validation()
+	{	
+		$this->CI =& get_instance();
+		
+		if (function_exists('mb_internal_encoding'))
+		{
+			mb_internal_encoding($this->CI->config->item('charset'));
+		}
+		
+		log_message('debug', "Validation Class Initialized");
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Fields
+	 *
+	 * This function takes an array of field names as input
+	 * and generates class variables with the same name, which will
+	 * either be blank or contain the $_POST value corresponding to it
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	function set_fields($data = '', $field = '')
+	{	
+		if ($data == '')
+		{
+			if (count($this->_fields) == 0)
+			{
+				return FALSE;
+			}
+		}
+		else
+		{
+			if ( ! is_array($data))
+			{
+				$data = array($data => $field);
+			}
+			
+			if (count($data) > 0)
+			{
+				$this->_fields = $data;
+			}
+		}		
+			
+		foreach($this->_fields as $key => $val)
+		{
+			$this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]);
+			
+			$error = $key.'_error';
+			if ( ! isset($this->$error))
+			{
+				$this->$error = '';
+			}
+		}		
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Rules
+	 *
+	 * This function takes an array of field names and validation
+	 * rules as input ad simply stores is for use later.
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
+	function set_rules($data, $rules = '')
+	{
+		if ( ! is_array($data))
+		{
+			if ($rules == '')
+				return;
+				
+			$data = array($data => $rules);
+		}
+	
+		foreach ($data as $key => $val)
+		{
+			$this->_rules[$key] = $val;
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Error Message
+	 *
+	 * Lets users set their own error messages on the fly.  Note:  The key
+	 * name has to match the  function name that it corresponds to.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
+	function set_message($lang, $val = '')
+	{
+		if ( ! is_array($lang))
+		{
+			$lang = array($lang => $val);
+		}
+	
+		$this->_error_messages = array_merge($this->_error_messages, $lang);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set The Error Delimiter
+	 *
+	 * Permits a prefix/suffix to be added to each error message
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */	
+	function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
+	{
+		$this->_error_prefix = $prefix;
+		$this->_error_suffix = $suffix;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Run the Validator
+	 *
+	 * This function does all the work.
+	 *
+	 * @access	public
+	 * @return	bool
+	 */		
+	function run()
+	{
+		// Do we even have any data to process?  Mm?
+		if (count($_POST) == 0 OR count($this->_rules) == 0)
+		{
+			return FALSE;
+		}
+	
+		// Load the language file containing error messages
+		$this->CI->lang->load('validation');
+							
+		// Cycle through the rules and test for errors
+		foreach ($this->_rules as $field => $rules)
+		{
+			//Explode out the rules!
+			$ex = explode('|', $rules);
+
+			// Is the field required?  If not, if the field is blank  we'll move on to the next test
+			if ( ! in_array('required', $ex, TRUE))
+			{
+				if ( ! isset($_POST[$field]) OR $_POST[$field] == '')
+				{
+					continue;
+				}
+			}
+			
+			/*
+			 * Are we dealing with an "isset" rule?
+			 *
+			 * Before going further, we'll see if one of the rules
+			 * is to check whether the item is set (typically this
+			 * applies only to checkboxes).  If so, we'll
+			 * test for it here since there's not reason to go
+			 * further
+			 */
+			if ( ! isset($_POST[$field]))
+			{			
+				if (in_array('isset', $ex, TRUE) OR in_array('required', $ex))
+				{
+					if ( ! isset($this->_error_messages['isset']))
+					{
+						if (FALSE === ($line = $this->CI->lang->line('isset')))
+						{
+							$line = 'The field was not set';
+						}							
+					}
+					else
+					{
+						$line = $this->_error_messages['isset'];
+					}
+					
+					// Build the error message
+					$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
+					$message = sprintf($line, $mfield);
+
+					// Set the error variable.  Example: $this->username_error
+					$error = $field.'_error';
+					$this->$error = $this->_error_prefix.$message.$this->_error_suffix;
+					$this->_error_array[] = $message;
+				}
+						
+				continue;
+			}
+	
+			/*
+			 * Set the current field
+			 *
+			 * The various prepping functions need to know the
+			 * current field name so they can do this:
+			 *
+			 * $_POST[$this->_current_field] == 'bla bla';
+			 */
+			$this->_current_field = $field;
+
+			// Cycle through the rules!
+			foreach ($ex As $rule)
+			{
+				// Is the rule a callback?			
+				$callback = FALSE;
+				if (substr($rule, 0, 9) == 'callback_')
+				{
+					$rule = substr($rule, 9);
+					$callback = TRUE;
+				}
+				
+				// Strip the parameter (if exists) from the rule
+				// Rules can contain a parameter: max_length[5]
+				$param = FALSE;
+				if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
+				{
+					$rule	= $match[1];
+					$param	= $match[2];
+				}
+				
+				// Call the function that corresponds to the rule
+				if ($callback === TRUE)
+				{
+					if ( ! method_exists($this->CI, $rule))
+					{ 		
+						continue;
+					}
+					
+					$result = $this->CI->$rule($_POST[$field], $param);	
+					
+					// If the field isn't required and we just processed a callback we'll move on...
+					if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE)
+					{
+						continue 2;
+					}
+					
+				}
+				else
+				{				
+					if ( ! method_exists($this, $rule))
+					{
+						/*
+						 * Run the native PHP function if called for
+						 *
+						 * If our own wrapper function doesn't exist we see
+						 * if a native PHP function does. Users can use
+						 * any native PHP function call that has one param.
+						 */
+						if (function_exists($rule))
+						{
+							$_POST[$field] = $rule($_POST[$field]);
+							$this->$field = $_POST[$field];
+						}
+											
+						continue;
+					}
+					
+					$result = $this->$rule($_POST[$field], $param);
+				}
+								
+				// Did the rule test negatively?  If so, grab the error.
+				if ($result === FALSE)
+				{
+					if ( ! isset($this->_error_messages[$rule]))
+					{
+						if (FALSE === ($line = $this->CI->lang->line($rule)))
+						{
+							$line = 'Unable to access an error message corresponding to your field name.';
+						}						
+					}
+					else
+					{
+						$line = $this->_error_messages[$rule];
+					}				
+
+					// Build the error message
+					$mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field];
+					$mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param];
+					$message = sprintf($line, $mfield, $mparam);
+					
+					// Set the error variable.  Example: $this->username_error
+					$error = $field.'_error';
+					$this->$error = $this->_error_prefix.$message.$this->_error_suffix;
+
+					// Add the error to the error array
+					$this->_error_array[] = $message;				
+					continue 2;
+				}				
+			}
+			
+		}
+		
+		$total_errors = count($this->_error_array);
+
+		/*
+		 * Recompile the class variables
+		 *
+		 * If any prepping functions were called the $_POST data
+		 * might now be different then the corresponding class
+		 * variables so we'll set them anew.
+		 */	
+		if ($total_errors > 0)
+		{
+			$this->_safe_form_data = TRUE;
+		}
+		
+		$this->set_fields();
+
+		// Did we end up with any errors?
+		if ($total_errors == 0)
+		{
+			return TRUE;
+		}
+		
+		// Generate the error string
+		foreach ($this->_error_array as $val)
+		{
+			$this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n";
+		}
+
+		return FALSE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Required
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function required($str)
+	{
+		if ( ! is_array($str))
+		{
+			return (trim($str) == '') ? FALSE : TRUE;
+		}
+		else
+		{
+			return ( ! empty($str));
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Match one field to another
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	field
+	 * @return	bool
+	 */
+	function matches($str, $field)
+	{
+		if ( ! isset($_POST[$field]))
+		{
+			return FALSE;
+		}
+		
+		return ($str !== $_POST[$field]) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Minimum Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function min_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) < $val) ? FALSE : TRUE;		
+		}
+
+		return (strlen($str) < $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Max Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function max_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+		
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) > $val) ? FALSE : TRUE;		
+		}
+
+		return (strlen($str) > $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Exact Length
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	value
+	 * @return	bool
+	 */	
+	function exact_length($str, $val)
+	{
+		if (preg_match("/[^0-9]/", $val))
+		{
+			return FALSE;
+		}
+	
+		if (function_exists('mb_strlen'))
+		{
+			return (mb_strlen($str) != $val) ? FALSE : TRUE;		
+		}
+
+		return (strlen($str) != $val) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Email
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function valid_email($str)
+	{
+		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Emails
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function valid_emails($str)
+	{
+		if (strpos($str, ',') === FALSE)
+		{
+			return $this->valid_email(trim($str));
+		}
+		
+		foreach(explode(',', $str) as $email)
+		{
+			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
+			{
+				return FALSE;
+			}
+		}
+		
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Validate IP Address
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function valid_ip($ip)
+	{
+		return $this->CI->input->valid_ip($ip);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */		
+	function alpha($str)
+	{
+		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha-numeric
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function alpha_numeric($str)
+	{
+		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Alpha-numeric with underscores and dashes
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function alpha_dash($str)
+	{
+		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Numeric
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function numeric($str)
+	{
+		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
+
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Is Numeric
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+  	function is_numeric($str)
+	{
+		return ( ! is_numeric($str)) ? FALSE : TRUE;
+	} 
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Integer
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */	
+	function integer($str)
+	{
+		return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Is a Natural number  (0,1,2,3, etc.)
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function is_natural($str)
+	{   
+   		return (bool)preg_match( '/^[0-9]+$/', $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Is a Natural number, but not a zero  (1,2,3, etc.)
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function is_natural_no_zero($str)
+	{   
+		if ( ! preg_match( '/^[0-9]+$/', $str))
+		{
+			return FALSE;
+		}
+	
+		if ($str == 0)
+		{
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Valid Base64
+	 *
+	 * Tests a string for characters outside of the Base64 alphabet
+	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function valid_base64($str)
+	{
+		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
+	}
+
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Select
+	 *
+	 * Enables pull-down lists to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_select($field = '', $value = '')
+	{
+		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
+		{
+			return '';
+		}
+			
+		if ($_POST[$field] == $value)
+		{
+			return ' selected="selected"';
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Radio
+	 *
+	 * Enables radio buttons to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_radio($field = '', $value = '')
+	{
+		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
+		{
+			return '';
+		}
+			
+		if ($_POST[$field] == $value)
+		{
+			return ' checked="checked"';
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Set Checkbox
+	 *
+	 * Enables checkboxes to be set to the value the user
+	 * selected in the event of an error
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */	
+	function set_checkbox($field = '', $value = '')
+	{
+		if ($field == '' OR $value == '' OR  ! isset($_POST[$field]))
+		{
+			return '';
+		}
+			
+		if ($_POST[$field] == $value)
+		{
+			return ' checked="checked"';
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep data for form
+	 *
+	 * This function allows HTML to be safely shown in a form.
+	 * Special characters are converted.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */
+	function prep_for_form($data = '')
+	{
+		if (is_array($data))
+		{
+			foreach ($data as $key => $val)
+			{
+				$data[$key] = $this->prep_for_form($val);
+			}
+			
+			return $data;
+		}
+		
+		if ($this->_safe_form_data == FALSE OR $data == '')
+		{
+			return $data;
+		}
+
+		return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep URL
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function prep_url($str = '')
+	{
+		if ($str == 'http://' OR $str == '')
+		{
+			$_POST[$this->_current_field] = '';
+			return;
+		}
+		
+		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
+		{
+			$str = 'http://'.$str;
+		}
+		
+		$_POST[$this->_current_field] = $str;
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Strip Image Tags
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function strip_image_tags($str)
+	{
+		$_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * XSS Clean
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function xss_clean($str)
+	{
+		$_POST[$this->_current_field] = $this->CI->input->xss_clean($str);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Convert PHP tags to entities
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	string
+	 */	
+	function encode_php_tags($str)
+	{
+		$_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+	}
+
+}
+// END Validation Class
+
+/* End of file Validation.php */
 /* Location: ./system/libraries/Validation.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index c9e7972..b077d3d 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -1,1421 +1,1421 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-if ( ! function_exists('xml_parser_create'))

-{	

-	show_error('Your PHP installation does not support XML');

-}

-

-

-// ------------------------------------------------------------------------

-

-/**

- * XML-RPC request handler class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class CI_Xmlrpc {

-

-	var $debug			= FALSE; 	// Debugging on or off	

-	var $xmlrpcI4		= 'i4';

-	var $xmlrpcInt		= 'int';

-	var $xmlrpcBoolean	= 'boolean';

-	var $xmlrpcDouble	= 'double';	

-	var $xmlrpcString	= 'string';

-	var $xmlrpcDateTime	= 'datetime.iso8601';

-	var $xmlrpcBase64	= 'base64';

-	var $xmlrpcArray	= 'array';

-	var $xmlrpcStruct	= 'struct';

-	

-	var $xmlrpcTypes	= array();

-	var $valid_parents	= array();

-	var $xmlrpcerr		= array();	// Response numbers

-	var $xmlrpcstr		= array();  // Response strings

-	

-	var $xmlrpc_defencoding = 'UTF-8';

-	var $xmlrpcName			= 'XML-RPC for CodeIgniter';

-	var $xmlrpcVersion		= '1.1';

-	var $xmlrpcerruser		= 800; // Start of user errors

-	var $xmlrpcerrxml		= 100; // Start of XML Parse errors

-	var $xmlrpc_backslash	= ''; // formulate backslashes for escaping regexp

-	

-	var $client;

-	var $method;

-	var $data;

-	var $message			= '';

-	var $error				= '';  		// Error string for request

-	var $result;

-	var $response			= array();  // Response from remote server

-

-

-	//-------------------------------------

-	//  VALUES THAT MULTIPLE CLASSES NEED

-	//-------------------------------------

-

-	function CI_Xmlrpc ($config = array())

-	{

-		$this->xmlrpcName 		= $this->xmlrpcName;

-		$this->xmlrpc_backslash = chr(92).chr(92);

-		

-		// Types for info sent back and forth

-		$this->xmlrpcTypes = array(

-			$this->xmlrpcI4	   => '1',

-			$this->xmlrpcInt	  => '1',

-			$this->xmlrpcBoolean  => '1',

-			$this->xmlrpcString   => '1',

-			$this->xmlrpcDouble   => '1',

-			$this->xmlrpcDateTime => '1',

-			$this->xmlrpcBase64   => '1',

-			$this->xmlrpcArray	=> '2',

-			$this->xmlrpcStruct   => '3'

-			);

-			

-		// Array of Valid Parents for Various XML-RPC elements

-		$this->valid_parents = array('BOOLEAN'			=> array('VALUE'),

-									 'I4'				=> array('VALUE'),

-									 'INT'				=> array('VALUE'),

-									 'STRING'			=> array('VALUE'),

-									 'DOUBLE'			=> array('VALUE'),

-									 'DATETIME.ISO8601'	=> array('VALUE'),

-									 'BASE64'			=> array('VALUE'),

-									 'ARRAY'			=> array('VALUE'),

-									 'STRUCT'			=> array('VALUE'),

-									 'PARAM'			=> array('PARAMS'),

-									 'METHODNAME'		=> array('METHODCALL'),

-									 'PARAMS'			=> array('METHODCALL', 'METHODRESPONSE'),

-									 'MEMBER'			=> array('STRUCT'),

-									 'NAME'				=> array('MEMBER'),

-									 'DATA'				=> array('ARRAY'),

-									 'FAULT'			=> array('METHODRESPONSE'),

-									 'VALUE'			=> array('MEMBER', 'DATA', 'PARAM', 'FAULT')

-									 );

-			

-			

-		// XML-RPC Responses

-		$this->xmlrpcerr['unknown_method'] = '1';

-		$this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';

-		$this->xmlrpcerr['invalid_return'] = '2';

-		$this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC.  Turn on debugging to examine the XML data further.';

-		$this->xmlrpcerr['incorrect_params'] = '3';

-		$this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';

-		$this->xmlrpcerr['introspect_unknown'] = '4';

-		$this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";

-		$this->xmlrpcerr['http_error'] = '5';

-		$this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";

-		$this->xmlrpcerr['no_data'] = '6';

-		$this->xmlrpcstr['no_data'] ='No data received from server.';

-		

-		$this->initialize($config);

-		

-		log_message('debug', "XML-RPC Class Initialized");

-	}

-	

-	

-	//-------------------------------------

-	//  Initialize Prefs

-	//-------------------------------------

-

-	function initialize($config = array())

-	{

-		if (sizeof($config) > 0)

-		{

-			foreach ($config as $key => $val)

-			{

-				if (isset($this->$key))

-				{

-					$this->$key = $val;			

-				}

-			}

-		}

-	}

-	// END

-	

-	//-------------------------------------

-	//  Take URL and parse it

-	//-------------------------------------

-

-	function server($url, $port=80)

-	{

-		if (substr($url, 0, 4) != "http")

-		{

-			$url = "http://".$url;

-		}

-		

-		$parts = parse_url($url);

-		

-		$path = ( ! isset($parts['path'])) ? '/' : $parts['path'];

-		

-		if (isset($parts['query']) && $parts['query'] != '')

-		{

-			$path .= '?'.$parts['query'];

-		}	

-		

-		$this->client = new XML_RPC_Client($path, $parts['host'], $port);

-	}

-	// END

-	

-	//-------------------------------------

-	//  Set Timeout

-	//-------------------------------------

-

-	function timeout($seconds=5)

-	{

-		if ( ! is_null($this->client) && is_int($seconds))

-		{

-			$this->client->timeout = $seconds;

-		}

-	}

-	// END

-	

-	//-------------------------------------

-	//  Set Methods

-	//-------------------------------------

-

-	function method($function)

-	{

-		$this->method = $function;

-	}

-	// END

-	

-	//-------------------------------------

-	//  Take Array of Data and Create Objects

-	//-------------------------------------

-

-	function request($incoming)

-	{

-		if ( ! is_array($incoming))

-		{

-			// Send Error

-		}

-		

-		$this->data = array();

-		

-		foreach($incoming as $key => $value)

-		{

-			$this->data[$key] = $this->values_parsing($value);

-		}

-	}

-	// END

-	

-	

-	//-------------------------------------

-	//  Set Debug

-	//-------------------------------------

-

-	function set_debug($flag = TRUE)

-	{

-		$this->debug = ($flag == TRUE) ? TRUE : FALSE;

-	}

-	

-	//-------------------------------------

-	//  Values Parsing

-	//-------------------------------------

-

-	function values_parsing($value, $return = FALSE)

-	{

-		if (is_array($value) && isset($value['0']))

-		{

-			if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])]))

-			{

-				if (is_array($value[0]))

-				{

-					$temp = new XML_RPC_Values($value['0'], 'array');

-				}

-				else

-				{

-					$temp = new XML_RPC_Values($value['0'], 'string');

-				}

-			}

-			elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))

-			{

-				while (list($k) = each($value['0']))

-				{

-					$value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);

-				}

-				

-				$temp = new XML_RPC_Values($value['0'], $value['1']);

-			}

-			else

-			{

-				$temp = new XML_RPC_Values($value['0'], $value['1']);

-			}

-		}

-		else

-		{

-			$temp = new XML_RPC_Values($value, 'string');

-		}

-

-		return $temp;

-	}

-	// END

-

-

-	//-------------------------------------

-	//  Sends XML-RPC Request

-	//-------------------------------------

-

-	function send_request()

-	{

-		$this->message = new XML_RPC_Message($this->method,$this->data);

-		$this->message->debug = $this->debug;

-	

-		if ( ! $this->result = $this->client->send($this->message))

-		{

-			$this->error = $this->result->errstr;

-			return FALSE;

-		}

-		elseif( ! is_object($this->result->val))

-		{

-			$this->error = $this->result->errstr;

-			return FALSE;

-		}

-		

-		$this->response = $this->result->decode();

-		

-		return TRUE;

-	}

-	// END

-	

-	//-------------------------------------

-	//  Returns Error

-	//-------------------------------------

-

-	function display_error()

-	{

-		return $this->error;

-	}

-	// END

-	

-	//-------------------------------------

-	//  Returns Remote Server Response

-	//-------------------------------------

-

-	function display_response()

-	{

-		return $this->response;

-	}

-	// END

-	

-	//-------------------------------------

-	//  Sends an Error Message for Server Request

-	//-------------------------------------

-	

-	function send_error_message($number, $message)

-	{

-		return new XML_RPC_Response('0',$number, $message);

-	}

-	// END

-	

-	

-	//-------------------------------------

-	//  Send Response for Server Request

-	//-------------------------------------

-	

-	function send_response($response)

-	{

-		// $response should be array of values, which will be parsed

-		// based on their data and type into a valid group of XML-RPC values

-		

-		$response = $this->values_parsing($response);

-	

-		return new XML_RPC_Response($response);

-	}

-	// END

-	

-} // END XML_RPC Class

-

-	

-	

-/**

- * XML-RPC Client class

- *

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class XML_RPC_Client extends CI_Xmlrpc

-{

-	var $path			= '';

-	var $server			= '';

-	var $port			= 80;

-	var $errno			= '';

-	var $errstring		= '';

-	var $timeout		= 5;

-	var $no_multicall	= false;

-

-	function XML_RPC_Client($path, $server, $port=80)

-	{

-		parent::CI_Xmlrpc();

-		

-		$this->port = $port;

-		$this->server = $server;

-		$this->path = $path;

-	}

-	

-	function send($msg)

-	{

-		if (is_array($msg))

-		{

-			// Multi-call disabled

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);

-			return $r;

-		}

-

-		return $this->sendPayload($msg);

-	}

-

-	function sendPayload($msg)

-	{	

-		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);

-		

-		if ( ! is_resource($fp))

-		{

-			error_log($this->xmlrpcstr['http_error']);

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);

-			return $r;

-		}

-		

-		if(empty($msg->payload))

-		{

-			// $msg = XML_RPC_Messages

-			$msg->createPayload();

-		}

-		

-		$r = "\r\n";

-		$op  = "POST {$this->path} HTTP/1.0$r";

-		$op .= "Host: {$this->server}$r";

-		$op .= "Content-Type: text/xml$r";

-		$op .= "User-Agent: {$this->xmlrpcName}$r";

-		$op .= "Content-Length: ".strlen($msg->payload). "$r$r";

-		$op .= $msg->payload;

-		

-

-		if ( ! fputs($fp, $op, strlen($op)))

-		{

-			error_log($this->xmlrpcstr['http_error']);

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);

-			return $r;

-		}

-		$resp = $msg->parseResponse($fp);

-		fclose($fp);

-		return $resp;

-	}

-

-} // end class XML_RPC_Client

-

-

-/**

- * XML-RPC Response class

- *

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class XML_RPC_Response

-{

-	var $val = 0;

-	var $errno = 0;

-	var $errstr = '';

-	var $headers = array();

-

-	function XML_RPC_Response($val, $code = 0, $fstr = '')

-	{	

-		if ($code != 0)

-		{

-			// error

-			$this->errno = $code;

-			$this->errstr = htmlentities($fstr);

-		}

-		else if ( ! is_object($val))

-		{

-			// programmer error, not an object

-			error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");

-			$this->val = new XML_RPC_Values();

-		}

-		else

-		{

-			$this->val = $val;

-		}

-	}

-

-	function faultCode()

-	{

-		return $this->errno;

-	}

-

-	function faultString()

-	{

-		return $this->errstr;

-	}

-

-	function value()

-	{

-		return $this->val;

-	}

-	

-	function prepare_response()

-	{

-		$result = "<methodResponse>\n";

-		if ($this->errno)

-		{

-			$result .= '<fault>

-	<value>

-		<struct>

-			<member>

-				<name>faultCode</name>

-				<value><int>' . $this->errno . '</int></value>

-			</member>

-			<member>

-				<name>faultString</name>

-				<value><string>' . $this->errstr . '</string></value>

-			</member>

-		</struct>

-	</value>

-</fault>';

-		}

-		else

-		{

-			$result .= "<params>\n<param>\n" .

-					$this->val->serialize_class() .

-					"</param>\n</params>";

-		}

-		$result .= "\n</methodResponse>";

-		return $result;

-	}

-	

-	function decode($array=FALSE)

-	{

-		$CI =& get_instance();

-

-		if ($array !== FALSE && is_array($array))

-		{

-			while (list($key) = each($array))

-			{

-				if (is_array($array[$key]))

-				{

-					$array[$key] = $this->decode($array[$key]);

-				}

-				else

-				{

-					$array[$key] = $CI->input->xss_clean($array[$key]);

-				}

-			}

-			

-			$result = $array;

-		}

-		else

-		{

-			$result = $this->xmlrpc_decoder($this->val);

-			

-			if (is_array($result))

-			{

-				$result = $this->decode($result);

-			}

-			else

-			{

-				$result = $CI->input->xss_clean($result);

-			}

-		}

-		

-		return $result;

-	}

-

-	

-	

-	//-------------------------------------

-	//  XML-RPC Object to PHP Types

-	//-------------------------------------

-

-	function xmlrpc_decoder($xmlrpc_val)

-	{

-		$kind = $xmlrpc_val->kindOf();

-

-		if($kind == 'scalar')

-		{

-			return $xmlrpc_val->scalarval();

-		}

-		elseif($kind == 'array')

-		{

-			reset($xmlrpc_val->me);

-			list($a,$b) = each($xmlrpc_val->me);

-			$size = sizeof($b);

-			

-			$arr = array();

-

-			for($i = 0; $i < $size; $i++)

-			{

-				$arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);

-			}

-			return $arr;

-		}

-		elseif($kind == 'struct')

-		{

-			reset($xmlrpc_val->me['struct']);

-			$arr = array();

-

-			while(list($key,$value) = each($xmlrpc_val->me['struct']))

-			{

-				$arr[$key] = $this->xmlrpc_decoder($value);

-			}

-			return $arr;

-		}

-	}

-	

-	

-	//-------------------------------------

-	//  ISO-8601 time to server or UTC time

-	//-------------------------------------

-

-	function iso8601_decode($time, $utc=0)

-	{

-		// return a timet in the localtime, or UTC

-		$t = 0;

-		if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))

-		{

-			if ($utc == 1)

-				$t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);

-			else

-				$t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);

-		}

-		return $t;

-	}

-	

-} // End Response Class

-

-

-

-/**

- * XML-RPC Message class

- *

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class XML_RPC_Message extends CI_Xmlrpc

-{

-	var $payload;

-	var $method_name;

-	var $params			= array();

-	var $xh 			= array();

-

-	function XML_RPC_Message($method, $pars=0)

-	{

-		parent::CI_Xmlrpc();

-		

-		$this->method_name = $method;

-		if (is_array($pars) && sizeof($pars) > 0)

-		{

-			for($i=0; $i<sizeof($pars); $i++)

-			{

-				// $pars[$i] = XML_RPC_Values

-				$this->params[] = $pars[$i];

-			}

-		}

-	}

-	

-	//-------------------------------------

-	//  Create Payload to Send

-	//-------------------------------------

-	

-	function createPayload()

-	{

-		$this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";

-		$this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";

-		$this->payload .= "<params>\r\n";

-		

-		for($i=0; $i<sizeof($this->params); $i++)

-		{

-			// $p = XML_RPC_Values

-			$p = $this->params[$i];

-			$this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";

-		}

-		

-		$this->payload .= "</params>\r\n</methodCall>\r\n";

-	}

-	

-	//-------------------------------------

-	//  Parse External XML-RPC Server's Response

-	//-------------------------------------

-	

-	function parseResponse($fp)

-	{

-		$data = '';

-		

-		while($datum = fread($fp, 4096))

-		{

-			$data .= $datum;

-		}

-		

-		//-------------------------------------

-		//  DISPLAY HTTP CONTENT for DEBUGGING

-		//-------------------------------------

-		

-		if ($this->debug === TRUE)

-		{

-			echo "<pre>";

-			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";

-			echo "</pre>";

-		}

-		

-		//-------------------------------------

-		//  Check for data

-		//-------------------------------------

-

-		if($data == "")

-		{

-			error_log($this->xmlrpcstr['no_data']);

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);

-			return $r;

-		}

-		

-		

-		//-------------------------------------

-		//  Check for HTTP 200 Response

-		//-------------------------------------

-		

-		if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))

-		{

-			$errstr= substr($data, 0, strpos($data, "\n")-1);

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');

-			return $r;

-		}

-		

-		//-------------------------------------

-		//  Create and Set Up XML Parser

-		//-------------------------------------

-	

-		$parser = xml_parser_create($this->xmlrpc_defencoding);

-

-		$this->xh[$parser]				 = array();

-		$this->xh[$parser]['isf']		 = 0;

-		$this->xh[$parser]['ac']		 = '';

-		$this->xh[$parser]['headers'] 	 = array();

-		$this->xh[$parser]['stack']		 = array();

-		$this->xh[$parser]['valuestack'] = array();

-		$this->xh[$parser]['isf_reason'] = 0;

-

-		xml_set_object($parser, $this);

-		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);

-		xml_set_element_handler($parser, 'open_tag', 'closing_tag');

-		xml_set_character_data_handler($parser, 'character_data');

-		//xml_set_default_handler($parser, 'default_handler');

-

-

-		//-------------------------------------

-		//  GET HEADERS

-		//-------------------------------------

-		

-		$lines = explode("\r\n", $data);

-		while (($line = array_shift($lines)))

-		{

-			if (strlen($line) < 1)

-			{

-				break;

-			}

-			$this->xh[$parser]['headers'][] = $line;

-		}

-		$data = implode("\r\n", $lines);

-		

-		

-		//-------------------------------------

-		//  PARSE XML DATA

-		//-------------------------------------  	

-

-		if ( ! xml_parse($parser, $data, sizeof($data)))

-		{

-			$errstr = sprintf('XML error: %s at line %d',

-					xml_error_string(xml_get_error_code($parser)),

-					xml_get_current_line_number($parser));

-			//error_log($errstr);

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);

-			xml_parser_free($parser);

-			return $r;

-		}

-		xml_parser_free($parser);

-		

-		// ---------------------------------------

-		//  Got Ourselves Some Badness, It Seems

-		// ---------------------------------------

-		

-		if ($this->xh[$parser]['isf'] > 1)

-		{

-			if ($this->debug === TRUE)

-			{

-				echo "---Invalid Return---\n";

-				echo $this->xh[$parser]['isf_reason'];

-				echo "---Invalid Return---\n\n";

-			}

-				

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);

-			return $r;

-		}

-		elseif ( ! is_object($this->xh[$parser]['value']))

-		{

-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);

-			return $r;

-		}

-		

-		//-------------------------------------

-		//  DISPLAY XML CONTENT for DEBUGGING

-		//-------------------------------------  	

-		

-		if ($this->debug === TRUE)

-		{

-			echo "<pre>";

-			

-			if (count($this->xh[$parser]['headers'] > 0))

-			{

-				echo "---HEADERS---\n";

-				foreach ($this->xh[$parser]['headers'] as $header)

-				{

-					echo "$header\n";

-				}

-				echo "---END HEADERS---\n\n";

-			}

-			

-			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";

-			

-			echo "---PARSED---\n" ;

-			var_dump($this->xh[$parser]['value']);

-			echo "\n---END PARSED---</pre>";

-		}

-		

-		//-------------------------------------

-		//  SEND RESPONSE

-		//-------------------------------------

-		

-		$v = $this->xh[$parser]['value'];

-			

-		if ($this->xh[$parser]['isf'])

-		{

-			$errno_v = $v->me['struct']['faultCode'];

-			$errstr_v = $v->me['struct']['faultString'];

-			$errno = $errno_v->scalarval();

-

-			if ($errno == 0)

-			{

-				// FAULT returned, errno needs to reflect that

-				$errno = -1;

-			}

-

-			$r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());

-		}

-		else

-		{

-			$r = new XML_RPC_Response($v);

-		}

-

-		$r->headers = $this->xh[$parser]['headers'];

-		return $r;

-	}

-	

-	// ------------------------------------

-	//  Begin Return Message Parsing section

-	// ------------------------------------

-	

-	// quick explanation of components:

-	//   ac - used to accumulate values

-	//   isf - used to indicate a fault

-	//   lv - used to indicate "looking for a value": implements

-	//		the logic to allow values with no types to be strings

-	//   params - used to store parameters in method calls

-	//   method - used to store method name

-	//	 stack - array with parent tree of the xml element,

-	//			 used to validate the nesting of elements

-

-	//-------------------------------------

-	//  Start Element Handler

-	//-------------------------------------

-

-	function open_tag($the_parser, $name, $attrs)

-	{

-		// If invalid nesting, then return

-		if ($this->xh[$the_parser]['isf'] > 1) return;

-		

-		// Evaluate and check for correct nesting of XML elements

-		

-		if (count($this->xh[$the_parser]['stack']) == 0)

-		{

-			if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')

-			{

-				$this->xh[$the_parser]['isf'] = 2;

-				$this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';

-				return;

-			}

-		}

-		else

-		{

-			// not top level element: see if parent is OK

-			if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))

-			{

-				$this->xh[$the_parser]['isf'] = 2;

-				$this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];

-				return;

-			}

-		}

-		

-		switch($name)

-		{

-			case 'STRUCT':

-			case 'ARRAY':

-				// Creates array for child elements

-				

-				$cur_val = array('value' => array(),

-								 'type'	 => $name);

-								

-				array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);

-			break;

-			case 'METHODNAME':

-			case 'NAME':

-				$this->xh[$the_parser]['ac'] = '';

-			break;

-			case 'FAULT':

-				$this->xh[$the_parser]['isf'] = 1;

-			break;

-			case 'PARAM':

-				$this->xh[$the_parser]['value'] = null;

-			break;

-			case 'VALUE':

-				$this->xh[$the_parser]['vt'] = 'value';

-				$this->xh[$the_parser]['ac'] = '';

-				$this->xh[$the_parser]['lv'] = 1;

-			break;

-			case 'I4':

-			case 'INT':

-			case 'STRING':

-			case 'BOOLEAN':

-			case 'DOUBLE':

-			case 'DATETIME.ISO8601':

-			case 'BASE64':

-				if ($this->xh[$the_parser]['vt'] != 'value')

-				{

-					//two data elements inside a value: an error occurred!

-					$this->xh[$the_parser]['isf'] = 2;

-					$this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";

-					return;

-				}

-				

-				$this->xh[$the_parser]['ac'] = '';

-			break;

-			case 'MEMBER':

-				// Set name of <member> to nothing to prevent errors later if no <name> is found

-				$this->xh[$the_parser]['valuestack'][0]['name'] = '';

-				

-				// Set NULL value to check to see if value passed for this param/member

-				$this->xh[$the_parser]['value'] = null;

-			break;

-			case 'DATA':

-			case 'METHODCALL':

-			case 'METHODRESPONSE':

-			case 'PARAMS':

-				// valid elements that add little to processing

-			break;

-			default:

-				/// An Invalid Element is Found, so we have trouble

-				$this->xh[$the_parser]['isf'] = 2;

-				$this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";

-			break;

-		}

-		

-		// Add current element name to stack, to allow validation of nesting

-		array_unshift($this->xh[$the_parser]['stack'], $name);

-

-		if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;

-	}

-	// END

-

-

-	//-------------------------------------

-	//  End Element Handler

-	//-------------------------------------

-

-	function closing_tag($the_parser, $name)

-	{

-		if ($this->xh[$the_parser]['isf'] > 1) return;

-		

-		// Remove current element from stack and set variable

-		// NOTE: If the XML validates, then we do not have to worry about

-		// the opening and closing of elements.  Nesting is checked on the opening

-		// tag so we be safe there as well.

-		

-		$curr_elem = array_shift($this->xh[$the_parser]['stack']);

-	

-		switch($name)

-		{

-			case 'STRUCT':

-			case 'ARRAY':

-				$cur_val = array_shift($this->xh[$the_parser]['valuestack']);

-				$this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];

-				$this->xh[$the_parser]['vt']	= strtolower($name);

-			break;

-			case 'NAME':

-				$this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];

-			break;

-			case 'BOOLEAN':

-			case 'I4':

-			case 'INT':

-			case 'STRING':

-			case 'DOUBLE':

-			case 'DATETIME.ISO8601':

-			case 'BASE64':

-				$this->xh[$the_parser]['vt'] = strtolower($name);

-				

-				if ($name == 'STRING')

-				{

-					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];

-				}

-				elseif ($name=='DATETIME.ISO8601')

-				{

-					$this->xh[$the_parser]['vt']	= $this->xmlrpcDateTime;

-					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];

-				}

-				elseif ($name=='BASE64')

-				{

-					$this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);

-				}

-				elseif ($name=='BOOLEAN')

-				{

-					// Translated BOOLEAN values to TRUE AND FALSE

-					if ($this->xh[$the_parser]['ac'] == '1')

-					{

-						$this->xh[$the_parser]['value'] = TRUE;

-					}

-					else

-					{

-						$this->xh[$the_parser]['value'] = FALSE;

-					}

-				}

-				elseif ($name=='DOUBLE')

-				{

-					// we have a DOUBLE

-					// we must check that only 0123456789-.<space> are characters here

-					if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))

-					{

-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';

-					}

-					else

-					{

-						$this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];

-					}

-				}

-				else

-				{

-					// we have an I4/INT

-					// we must check that only 0123456789-<space> are characters here

-					if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))

-					{

-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';

-					}

-					else

-					{

-						$this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];

-					}

-				}

-				$this->xh[$the_parser]['ac'] = '';

-				$this->xh[$the_parser]['lv'] = 3; // indicate we've found a value

-			break;

-			case 'VALUE':

-				// This if() detects if no scalar was inside <VALUE></VALUE>

-				if ($this->xh[$the_parser]['vt']=='value')

-				{

-					$this->xh[$the_parser]['value']	= $this->xh[$the_parser]['ac'];

-					$this->xh[$the_parser]['vt']	= $this->xmlrpcString;

-				}

-				

-				// build the XML-RPC value out of the data received, and substitute it

-				$temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);

-				

-				if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')

-				{

-					// Array

-					$this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;

-				}

-				else

-				{

-					// Struct

-					$this->xh[$the_parser]['value'] = $temp;

-				}

-			break;

-			case 'MEMBER':

-				$this->xh[$the_parser]['ac']='';

-				

-				// If value add to array in the stack for the last element built

-				if ($this->xh[$the_parser]['value'])

-				{

-					$this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];

-				}

-			break;

-			case 'DATA':

-				$this->xh[$the_parser]['ac']='';

-			break;

-			case 'PARAM':

-				if ($this->xh[$the_parser]['value'])

-				{

-					$this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];

-				}

-			break;

-			case 'METHODNAME':

-				$this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);

-			break;

-			case 'PARAMS':

-			case 'FAULT':

-			case 'METHODCALL':

-			case 'METHORESPONSE':

-				// We're all good kids with nuthin' to do

-			break;

-			default:

-				// End of an Invalid Element.  Taken care of during the opening tag though

-			break;

-		}

-	}

-

-	//-------------------------------------

-	//  Parses Character Data

-	//-------------------------------------

-

-	function character_data($the_parser, $data)

-	{

-		if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already

-		

-		// If a value has not been found

-		if ($this->xh[$the_parser]['lv'] != 3)

-		{

-			if ($this->xh[$the_parser]['lv'] == 1)

-			{

-				$this->xh[$the_parser]['lv'] = 2; // Found a value

-			}

-				

-			if( ! @isset($this->xh[$the_parser]['ac']))

-			{

-				$this->xh[$the_parser]['ac'] = '';

-			}

-				

-			$this->xh[$the_parser]['ac'] .= $data;

-		}

-	}

-	

-	

-	function addParam($par) { $this->params[]=$par; }

-	

-	function output_parameters($array=FALSE)

-	{

-		$CI =& get_instance();	

-

-		if ($array !== FALSE && is_array($array))

-		{

-			while (list($key) = each($array))

-			{

-				if (is_array($array[$key]))

-				{

-					$array[$key] = $this->output_parameters($array[$key]);

-				}

-				else

-				{

-					$array[$key] = $CI->input->xss_clean($array[$key]);

-				}

-			}

-			

-			$parameters = $array;

-		}

-		else

-		{

-			$parameters = array();

-		

-			for ($i = 0; $i < sizeof($this->params); $i++)

-			{

-				$a_param = $this->decode_message($this->params[$i]);

-				

-				if (is_array($a_param))

-				{

-					$parameters[] = $this->output_parameters($a_param);

-				}

-				else

-				{

-					$parameters[] = $CI->input->xss_clean($a_param);

-				}

-			}	

-		}

-		

-		return $parameters;

-	}

-	

-	

-	function decode_message($param)

-	{

-		$kind = $param->kindOf();

-

-		if($kind == 'scalar')

-		{

-			return $param->scalarval();

-		}

-		elseif($kind == 'array')

-		{

-			reset($param->me);

-			list($a,$b) = each($param->me);

-			

-			$arr = array();

-

-			for($i = 0; $i < sizeof($b); $i++)

-			{

-				$arr[] = $this->decode_message($param->me['array'][$i]);

-			}

-			

-			return $arr;

-		}

-		elseif($kind == 'struct')

-		{

-			reset($param->me['struct']);

-			

-			$arr = array();

-

-			while(list($key,$value) = each($param->me['struct']))

-			{

-				$arr[$key] = $this->decode_message($value);

-			}

-			

-			return $arr;

-		}

-	}

-	

-} // End XML_RPC_Messages class

-

-

-

-/**

- * XML-RPC Values class

- *

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class XML_RPC_Values extends CI_Xmlrpc

-{

-	var $me 	= array();

-	var $mytype	= 0;

-

-	function XML_RPC_Values($val=-1, $type='')

-	{	

-		parent::CI_Xmlrpc();

-		

-		if ($val != -1 OR $type != '')

-		{

-			$type = $type == '' ? 'string' : $type;

-			

-			if ($this->xmlrpcTypes[$type] == 1)

-			{

-				$this->addScalar($val,$type);

-			}

-			elseif ($this->xmlrpcTypes[$type] == 2)

-			{

-				$this->addArray($val);

-			}

-			elseif ($this->xmlrpcTypes[$type] == 3)

-			{

-				$this->addStruct($val);

-			}

-		}

-	}

-

-	function addScalar($val, $type='string')

-	{

-		$typeof = $this->xmlrpcTypes[$type];

-		

-		if ($this->mytype==1)

-		{

-			echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';

-			return 0;

-		}

-		

-		if ($typeof != 1)

-		{

-			echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';

-			return 0;

-		}

-

-		if ($type == $this->xmlrpcBoolean)

-		{

-			if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))

-			{

-				$val = 1;

-			}

-			else

-			{

-				$val=0;

-			}

-		}

-

-		if ($this->mytype == 2)

-		{

-			// adding to an array here

-			$ar = $this->me['array'];

-			$ar[] = new XML_RPC_Values($val, $type);

-			$this->me['array'] = $ar;

-		}

-		else

-		{

-			// a scalar, so set the value and remember we're scalar

-			$this->me[$type] = $val;

-			$this->mytype = $typeof;

-		}

-		return 1;

-	}

-

-	function addArray($vals)

-	{

-		if ($this->mytype != 0)

-		{

-			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';

-			return 0;

-		}

-

-		$this->mytype = $this->xmlrpcTypes['array'];

-		$this->me['array'] = $vals;

-		return 1;

-	}

-

-	function addStruct($vals)

-	{

-		if ($this->mytype != 0)

-		{

-			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';

-			return 0;

-		}

-		$this->mytype = $this->xmlrpcTypes['struct'];

-		$this->me['struct'] = $vals;

-		return 1;

-	}

-

-	function kindOf()

-	{

-		switch($this->mytype)

-		{

-			case 3:

-				return 'struct';

-				break;

-			case 2:

-				return 'array';

-				break;

-			case 1:

-				return 'scalar';

-				break;

-			default:

-				return 'undef';

-		}

-	}

-

-	function serializedata($typ, $val)

-	{

-		$rs = '';

-		

-		switch($this->xmlrpcTypes[$typ])

-		{

-			case 3:

-				// struct

-				$rs .= "<struct>\n";

-				reset($val);

-				while(list($key2, $val2) = each($val))

-				{

-					$rs .= "<member>\n<name>{$key2}</name>\n";

-					$rs .= $this->serializeval($val2);

-					$rs .= "</member>\n";

-				}

-				$rs .= '</struct>';

-			break;

-			case 2:

-				// array

-				$rs .= "<array>\n<data>\n";

-				for($i=0; $i < sizeof($val); $i++)

-				{

-					$rs .= $this->serializeval($val[$i]);

-				}

-				$rs.="</data>\n</array>\n";

-				break;

-			case 1:

-				// others

-				switch ($typ)

-				{

-					case $this->xmlrpcBase64:

-						$rs .= "<{$typ}>" . base64_encode($val) . "</{$typ}>\n";

-					break;

-					case $this->xmlrpcBoolean:

-						$rs .= "<{$typ}>" . ($val ? '1' : '0') . "</{$typ}>\n";

-					break;

-					case $this->xmlrpcString:

-						$rs .= "<{$typ}>" . htmlspecialchars($val). "</{$typ}>\n";

-					break;

-					default:

-						$rs .= "<{$typ}>{$val}</{$typ}>\n";

-					break;

-				}

-			default:

-			break;

-		}

-		return $rs;

-	}

-

-	function serialize_class()

-	{

-		return $this->serializeval($this);

-	}

-

-	function serializeval($o)

-	{

-		$ar = $o->me;

-		reset($ar);

-		

-		list($typ, $val) = each($ar);

-		$rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";

-		return $rs;

-	}

-	

-	function scalarval()

-	{

-		reset($this->me);

-		list($a,$b) = each($this->me);

-		return $b;

-	}

-

-

-	//-------------------------------------

-	// Encode time in ISO-8601 form.

-	//-------------------------------------

-	

-	// Useful for sending time in XML-RPC

-

-	function iso8601_encode($time, $utc=0)

-	{	

-		if ($utc == 1)

-		{

-			$t = strftime("%Y%m%dT%H:%M:%S", $time);

-		}

-		else

-		{

-			if (function_exists('gmstrftime'))

-				$t = gmstrftime("%Y%m%dT%H:%M:%S", $time);

-			else

-				$t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z'));

-		}

-		return $t;

-	}

-	

-}

-// END XML_RPC_Values Class

-

-/* End of file Xmlrpc.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+if ( ! function_exists('xml_parser_create'))
+{	
+	show_error('Your PHP installation does not support XML');
+}
+
+
+// ------------------------------------------------------------------------
+
+/**
+ * XML-RPC request handler class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class CI_Xmlrpc {
+
+	var $debug			= FALSE; 	// Debugging on or off	
+	var $xmlrpcI4		= 'i4';
+	var $xmlrpcInt		= 'int';
+	var $xmlrpcBoolean	= 'boolean';
+	var $xmlrpcDouble	= 'double';	
+	var $xmlrpcString	= 'string';
+	var $xmlrpcDateTime	= 'datetime.iso8601';
+	var $xmlrpcBase64	= 'base64';
+	var $xmlrpcArray	= 'array';
+	var $xmlrpcStruct	= 'struct';
+	
+	var $xmlrpcTypes	= array();
+	var $valid_parents	= array();
+	var $xmlrpcerr		= array();	// Response numbers
+	var $xmlrpcstr		= array();  // Response strings
+	
+	var $xmlrpc_defencoding = 'UTF-8';
+	var $xmlrpcName			= 'XML-RPC for CodeIgniter';
+	var $xmlrpcVersion		= '1.1';
+	var $xmlrpcerruser		= 800; // Start of user errors
+	var $xmlrpcerrxml		= 100; // Start of XML Parse errors
+	var $xmlrpc_backslash	= ''; // formulate backslashes for escaping regexp
+	
+	var $client;
+	var $method;
+	var $data;
+	var $message			= '';
+	var $error				= '';  		// Error string for request
+	var $result;
+	var $response			= array();  // Response from remote server
+
+
+	//-------------------------------------
+	//  VALUES THAT MULTIPLE CLASSES NEED
+	//-------------------------------------
+
+	function CI_Xmlrpc ($config = array())
+	{
+		$this->xmlrpcName 		= $this->xmlrpcName;
+		$this->xmlrpc_backslash = chr(92).chr(92);
+		
+		// Types for info sent back and forth
+		$this->xmlrpcTypes = array(
+			$this->xmlrpcI4	   => '1',
+			$this->xmlrpcInt	  => '1',
+			$this->xmlrpcBoolean  => '1',
+			$this->xmlrpcString   => '1',
+			$this->xmlrpcDouble   => '1',
+			$this->xmlrpcDateTime => '1',
+			$this->xmlrpcBase64   => '1',
+			$this->xmlrpcArray	=> '2',
+			$this->xmlrpcStruct   => '3'
+			);
+			
+		// Array of Valid Parents for Various XML-RPC elements
+		$this->valid_parents = array('BOOLEAN'			=> array('VALUE'),
+									 'I4'				=> array('VALUE'),
+									 'INT'				=> array('VALUE'),
+									 'STRING'			=> array('VALUE'),
+									 'DOUBLE'			=> array('VALUE'),
+									 'DATETIME.ISO8601'	=> array('VALUE'),
+									 'BASE64'			=> array('VALUE'),
+									 'ARRAY'			=> array('VALUE'),
+									 'STRUCT'			=> array('VALUE'),
+									 'PARAM'			=> array('PARAMS'),
+									 'METHODNAME'		=> array('METHODCALL'),
+									 'PARAMS'			=> array('METHODCALL', 'METHODRESPONSE'),
+									 'MEMBER'			=> array('STRUCT'),
+									 'NAME'				=> array('MEMBER'),
+									 'DATA'				=> array('ARRAY'),
+									 'FAULT'			=> array('METHODRESPONSE'),
+									 'VALUE'			=> array('MEMBER', 'DATA', 'PARAM', 'FAULT')
+									 );
+			
+			
+		// XML-RPC Responses
+		$this->xmlrpcerr['unknown_method'] = '1';
+		$this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
+		$this->xmlrpcerr['invalid_return'] = '2';
+		$this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC.  Turn on debugging to examine the XML data further.';
+		$this->xmlrpcerr['incorrect_params'] = '3';
+		$this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
+		$this->xmlrpcerr['introspect_unknown'] = '4';
+		$this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";
+		$this->xmlrpcerr['http_error'] = '5';
+		$this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
+		$this->xmlrpcerr['no_data'] = '6';
+		$this->xmlrpcstr['no_data'] ='No data received from server.';
+		
+		$this->initialize($config);
+		
+		log_message('debug', "XML-RPC Class Initialized");
+	}
+	
+	
+	//-------------------------------------
+	//  Initialize Prefs
+	//-------------------------------------
+
+	function initialize($config = array())
+	{
+		if (sizeof($config) > 0)
+		{
+			foreach ($config as $key => $val)
+			{
+				if (isset($this->$key))
+				{
+					$this->$key = $val;			
+				}
+			}
+		}
+	}
+	// END
+	
+	//-------------------------------------
+	//  Take URL and parse it
+	//-------------------------------------
+
+	function server($url, $port=80)
+	{
+		if (substr($url, 0, 4) != "http")
+		{
+			$url = "http://".$url;
+		}
+		
+		$parts = parse_url($url);
+		
+		$path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
+		
+		if (isset($parts['query']) && $parts['query'] != '')
+		{
+			$path .= '?'.$parts['query'];
+		}	
+		
+		$this->client = new XML_RPC_Client($path, $parts['host'], $port);
+	}
+	// END
+	
+	//-------------------------------------
+	//  Set Timeout
+	//-------------------------------------
+
+	function timeout($seconds=5)
+	{
+		if ( ! is_null($this->client) && is_int($seconds))
+		{
+			$this->client->timeout = $seconds;
+		}
+	}
+	// END
+	
+	//-------------------------------------
+	//  Set Methods
+	//-------------------------------------
+
+	function method($function)
+	{
+		$this->method = $function;
+	}
+	// END
+	
+	//-------------------------------------
+	//  Take Array of Data and Create Objects
+	//-------------------------------------
+
+	function request($incoming)
+	{
+		if ( ! is_array($incoming))
+		{
+			// Send Error
+		}
+		
+		$this->data = array();
+		
+		foreach($incoming as $key => $value)
+		{
+			$this->data[$key] = $this->values_parsing($value);
+		}
+	}
+	// END
+	
+	
+	//-------------------------------------
+	//  Set Debug
+	//-------------------------------------
+
+	function set_debug($flag = TRUE)
+	{
+		$this->debug = ($flag == TRUE) ? TRUE : FALSE;
+	}
+	
+	//-------------------------------------
+	//  Values Parsing
+	//-------------------------------------
+
+	function values_parsing($value, $return = FALSE)
+	{
+		if (is_array($value) && isset($value['0']))
+		{
+			if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])]))
+			{
+				if (is_array($value[0]))
+				{
+					$temp = new XML_RPC_Values($value['0'], 'array');
+				}
+				else
+				{
+					$temp = new XML_RPC_Values($value['0'], 'string');
+				}
+			}
+			elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
+			{
+				while (list($k) = each($value['0']))
+				{
+					$value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);
+				}
+				
+				$temp = new XML_RPC_Values($value['0'], $value['1']);
+			}
+			else
+			{
+				$temp = new XML_RPC_Values($value['0'], $value['1']);
+			}
+		}
+		else
+		{
+			$temp = new XML_RPC_Values($value, 'string');
+		}
+
+		return $temp;
+	}
+	// END
+
+
+	//-------------------------------------
+	//  Sends XML-RPC Request
+	//-------------------------------------
+
+	function send_request()
+	{
+		$this->message = new XML_RPC_Message($this->method,$this->data);
+		$this->message->debug = $this->debug;
+	
+		if ( ! $this->result = $this->client->send($this->message))
+		{
+			$this->error = $this->result->errstr;
+			return FALSE;
+		}
+		elseif( ! is_object($this->result->val))
+		{
+			$this->error = $this->result->errstr;
+			return FALSE;
+		}
+		
+		$this->response = $this->result->decode();
+		
+		return TRUE;
+	}
+	// END
+	
+	//-------------------------------------
+	//  Returns Error
+	//-------------------------------------
+
+	function display_error()
+	{
+		return $this->error;
+	}
+	// END
+	
+	//-------------------------------------
+	//  Returns Remote Server Response
+	//-------------------------------------
+
+	function display_response()
+	{
+		return $this->response;
+	}
+	// END
+	
+	//-------------------------------------
+	//  Sends an Error Message for Server Request
+	//-------------------------------------
+	
+	function send_error_message($number, $message)
+	{
+		return new XML_RPC_Response('0',$number, $message);
+	}
+	// END
+	
+	
+	//-------------------------------------
+	//  Send Response for Server Request
+	//-------------------------------------
+	
+	function send_response($response)
+	{
+		// $response should be array of values, which will be parsed
+		// based on their data and type into a valid group of XML-RPC values
+		
+		$response = $this->values_parsing($response);
+	
+		return new XML_RPC_Response($response);
+	}
+	// END
+	
+} // END XML_RPC Class
+
+	
+	
+/**
+ * XML-RPC Client class
+ *
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Client extends CI_Xmlrpc
+{
+	var $path			= '';
+	var $server			= '';
+	var $port			= 80;
+	var $errno			= '';
+	var $errstring		= '';
+	var $timeout		= 5;
+	var $no_multicall	= false;
+
+	function XML_RPC_Client($path, $server, $port=80)
+	{
+		parent::CI_Xmlrpc();
+		
+		$this->port = $port;
+		$this->server = $server;
+		$this->path = $path;
+	}
+	
+	function send($msg)
+	{
+		if (is_array($msg))
+		{
+			// Multi-call disabled
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
+			return $r;
+		}
+
+		return $this->sendPayload($msg);
+	}
+
+	function sendPayload($msg)
+	{	
+		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
+		
+		if ( ! is_resource($fp))
+		{
+			error_log($this->xmlrpcstr['http_error']);
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
+			return $r;
+		}
+		
+		if(empty($msg->payload))
+		{
+			// $msg = XML_RPC_Messages
+			$msg->createPayload();
+		}
+		
+		$r = "\r\n";
+		$op  = "POST {$this->path} HTTP/1.0$r";
+		$op .= "Host: {$this->server}$r";
+		$op .= "Content-Type: text/xml$r";
+		$op .= "User-Agent: {$this->xmlrpcName}$r";
+		$op .= "Content-Length: ".strlen($msg->payload). "$r$r";
+		$op .= $msg->payload;
+		
+
+		if ( ! fputs($fp, $op, strlen($op)))
+		{
+			error_log($this->xmlrpcstr['http_error']);
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
+			return $r;
+		}
+		$resp = $msg->parseResponse($fp);
+		fclose($fp);
+		return $resp;
+	}
+
+} // end class XML_RPC_Client
+
+
+/**
+ * XML-RPC Response class
+ *
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Response
+{
+	var $val = 0;
+	var $errno = 0;
+	var $errstr = '';
+	var $headers = array();
+
+	function XML_RPC_Response($val, $code = 0, $fstr = '')
+	{	
+		if ($code != 0)
+		{
+			// error
+			$this->errno = $code;
+			$this->errstr = htmlentities($fstr);
+		}
+		else if ( ! is_object($val))
+		{
+			// programmer error, not an object
+			error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");
+			$this->val = new XML_RPC_Values();
+		}
+		else
+		{
+			$this->val = $val;
+		}
+	}
+
+	function faultCode()
+	{
+		return $this->errno;
+	}
+
+	function faultString()
+	{
+		return $this->errstr;
+	}
+
+	function value()
+	{
+		return $this->val;
+	}
+	
+	function prepare_response()
+	{
+		$result = "<methodResponse>\n";
+		if ($this->errno)
+		{
+			$result .= '<fault>
+	<value>
+		<struct>
+			<member>
+				<name>faultCode</name>
+				<value><int>' . $this->errno . '</int></value>
+			</member>
+			<member>
+				<name>faultString</name>
+				<value><string>' . $this->errstr . '</string></value>
+			</member>
+		</struct>
+	</value>
+</fault>';
+		}
+		else
+		{
+			$result .= "<params>\n<param>\n" .
+					$this->val->serialize_class() .
+					"</param>\n</params>";
+		}
+		$result .= "\n</methodResponse>";
+		return $result;
+	}
+	
+	function decode($array=FALSE)
+	{
+		$CI =& get_instance();
+
+		if ($array !== FALSE && is_array($array))
+		{
+			while (list($key) = each($array))
+			{
+				if (is_array($array[$key]))
+				{
+					$array[$key] = $this->decode($array[$key]);
+				}
+				else
+				{
+					$array[$key] = $CI->input->xss_clean($array[$key]);
+				}
+			}
+			
+			$result = $array;
+		}
+		else
+		{
+			$result = $this->xmlrpc_decoder($this->val);
+			
+			if (is_array($result))
+			{
+				$result = $this->decode($result);
+			}
+			else
+			{
+				$result = $CI->input->xss_clean($result);
+			}
+		}
+		
+		return $result;
+	}
+
+	
+	
+	//-------------------------------------
+	//  XML-RPC Object to PHP Types
+	//-------------------------------------
+
+	function xmlrpc_decoder($xmlrpc_val)
+	{
+		$kind = $xmlrpc_val->kindOf();
+
+		if($kind == 'scalar')
+		{
+			return $xmlrpc_val->scalarval();
+		}
+		elseif($kind == 'array')
+		{
+			reset($xmlrpc_val->me);
+			list($a,$b) = each($xmlrpc_val->me);
+			$size = sizeof($b);
+			
+			$arr = array();
+
+			for($i = 0; $i < $size; $i++)
+			{
+				$arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
+			}
+			return $arr;
+		}
+		elseif($kind == 'struct')
+		{
+			reset($xmlrpc_val->me['struct']);
+			$arr = array();
+
+			while(list($key,$value) = each($xmlrpc_val->me['struct']))
+			{
+				$arr[$key] = $this->xmlrpc_decoder($value);
+			}
+			return $arr;
+		}
+	}
+	
+	
+	//-------------------------------------
+	//  ISO-8601 time to server or UTC time
+	//-------------------------------------
+
+	function iso8601_decode($time, $utc=0)
+	{
+		// return a timet in the localtime, or UTC
+		$t = 0;
+		if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
+		{
+			if ($utc == 1)
+				$t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+			else
+				$t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+		}
+		return $t;
+	}
+	
+} // End Response Class
+
+
+
+/**
+ * XML-RPC Message class
+ *
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Message extends CI_Xmlrpc
+{
+	var $payload;
+	var $method_name;
+	var $params			= array();
+	var $xh 			= array();
+
+	function XML_RPC_Message($method, $pars=0)
+	{
+		parent::CI_Xmlrpc();
+		
+		$this->method_name = $method;
+		if (is_array($pars) && sizeof($pars) > 0)
+		{
+			for($i=0; $i<sizeof($pars); $i++)
+			{
+				// $pars[$i] = XML_RPC_Values
+				$this->params[] = $pars[$i];
+			}
+		}
+	}
+	
+	//-------------------------------------
+	//  Create Payload to Send
+	//-------------------------------------
+	
+	function createPayload()
+	{
+		$this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";
+		$this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
+		$this->payload .= "<params>\r\n";
+		
+		for($i=0; $i<sizeof($this->params); $i++)
+		{
+			// $p = XML_RPC_Values
+			$p = $this->params[$i];
+			$this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
+		}
+		
+		$this->payload .= "</params>\r\n</methodCall>\r\n";
+	}
+	
+	//-------------------------------------
+	//  Parse External XML-RPC Server's Response
+	//-------------------------------------
+	
+	function parseResponse($fp)
+	{
+		$data = '';
+		
+		while($datum = fread($fp, 4096))
+		{
+			$data .= $datum;
+		}
+		
+		//-------------------------------------
+		//  DISPLAY HTTP CONTENT for DEBUGGING
+		//-------------------------------------
+		
+		if ($this->debug === TRUE)
+		{
+			echo "<pre>";
+			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
+			echo "</pre>";
+		}
+		
+		//-------------------------------------
+		//  Check for data
+		//-------------------------------------
+
+		if($data == "")
+		{
+			error_log($this->xmlrpcstr['no_data']);
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
+			return $r;
+		}
+		
+		
+		//-------------------------------------
+		//  Check for HTTP 200 Response
+		//-------------------------------------
+		
+		if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
+		{
+			$errstr= substr($data, 0, strpos($data, "\n")-1);
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
+			return $r;
+		}
+		
+		//-------------------------------------
+		//  Create and Set Up XML Parser
+		//-------------------------------------
+	
+		$parser = xml_parser_create($this->xmlrpc_defencoding);
+
+		$this->xh[$parser]				 = array();
+		$this->xh[$parser]['isf']		 = 0;
+		$this->xh[$parser]['ac']		 = '';
+		$this->xh[$parser]['headers'] 	 = array();
+		$this->xh[$parser]['stack']		 = array();
+		$this->xh[$parser]['valuestack'] = array();
+		$this->xh[$parser]['isf_reason'] = 0;
+
+		xml_set_object($parser, $this);
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
+		xml_set_element_handler($parser, 'open_tag', 'closing_tag');
+		xml_set_character_data_handler($parser, 'character_data');
+		//xml_set_default_handler($parser, 'default_handler');
+
+
+		//-------------------------------------
+		//  GET HEADERS
+		//-------------------------------------
+		
+		$lines = explode("\r\n", $data);
+		while (($line = array_shift($lines)))
+		{
+			if (strlen($line) < 1)
+			{
+				break;
+			}
+			$this->xh[$parser]['headers'][] = $line;
+		}
+		$data = implode("\r\n", $lines);
+		
+		
+		//-------------------------------------
+		//  PARSE XML DATA
+		//-------------------------------------  	
+
+		if ( ! xml_parse($parser, $data, sizeof($data)))
+		{
+			$errstr = sprintf('XML error: %s at line %d',
+					xml_error_string(xml_get_error_code($parser)),
+					xml_get_current_line_number($parser));
+			//error_log($errstr);
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
+			xml_parser_free($parser);
+			return $r;
+		}
+		xml_parser_free($parser);
+		
+		// ---------------------------------------
+		//  Got Ourselves Some Badness, It Seems
+		// ---------------------------------------
+		
+		if ($this->xh[$parser]['isf'] > 1)
+		{
+			if ($this->debug === TRUE)
+			{
+				echo "---Invalid Return---\n";
+				echo $this->xh[$parser]['isf_reason'];
+				echo "---Invalid Return---\n\n";
+			}
+				
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+			return $r;
+		}
+		elseif ( ! is_object($this->xh[$parser]['value']))
+		{
+			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+			return $r;
+		}
+		
+		//-------------------------------------
+		//  DISPLAY XML CONTENT for DEBUGGING
+		//-------------------------------------  	
+		
+		if ($this->debug === TRUE)
+		{
+			echo "<pre>";
+			
+			if (count($this->xh[$parser]['headers'] > 0))
+			{
+				echo "---HEADERS---\n";
+				foreach ($this->xh[$parser]['headers'] as $header)
+				{
+					echo "$header\n";
+				}
+				echo "---END HEADERS---\n\n";
+			}
+			
+			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
+			
+			echo "---PARSED---\n" ;
+			var_dump($this->xh[$parser]['value']);
+			echo "\n---END PARSED---</pre>";
+		}
+		
+		//-------------------------------------
+		//  SEND RESPONSE
+		//-------------------------------------
+		
+		$v = $this->xh[$parser]['value'];
+			
+		if ($this->xh[$parser]['isf'])
+		{
+			$errno_v = $v->me['struct']['faultCode'];
+			$errstr_v = $v->me['struct']['faultString'];
+			$errno = $errno_v->scalarval();
+
+			if ($errno == 0)
+			{
+				// FAULT returned, errno needs to reflect that
+				$errno = -1;
+			}
+
+			$r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
+		}
+		else
+		{
+			$r = new XML_RPC_Response($v);
+		}
+
+		$r->headers = $this->xh[$parser]['headers'];
+		return $r;
+	}
+	
+	// ------------------------------------
+	//  Begin Return Message Parsing section
+	// ------------------------------------
+	
+	// quick explanation of components:
+	//   ac - used to accumulate values
+	//   isf - used to indicate a fault
+	//   lv - used to indicate "looking for a value": implements
+	//		the logic to allow values with no types to be strings
+	//   params - used to store parameters in method calls
+	//   method - used to store method name
+	//	 stack - array with parent tree of the xml element,
+	//			 used to validate the nesting of elements
+
+	//-------------------------------------
+	//  Start Element Handler
+	//-------------------------------------
+
+	function open_tag($the_parser, $name, $attrs)
+	{
+		// If invalid nesting, then return
+		if ($this->xh[$the_parser]['isf'] > 1) return;
+		
+		// Evaluate and check for correct nesting of XML elements
+		
+		if (count($this->xh[$the_parser]['stack']) == 0)
+		{
+			if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
+			{
+				$this->xh[$the_parser]['isf'] = 2;
+				$this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
+				return;
+			}
+		}
+		else
+		{
+			// not top level element: see if parent is OK
+			if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
+			{
+				$this->xh[$the_parser]['isf'] = 2;
+				$this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
+				return;
+			}
+		}
+		
+		switch($name)
+		{
+			case 'STRUCT':
+			case 'ARRAY':
+				// Creates array for child elements
+				
+				$cur_val = array('value' => array(),
+								 'type'	 => $name);
+								
+				array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
+			break;
+			case 'METHODNAME':
+			case 'NAME':
+				$this->xh[$the_parser]['ac'] = '';
+			break;
+			case 'FAULT':
+				$this->xh[$the_parser]['isf'] = 1;
+			break;
+			case 'PARAM':
+				$this->xh[$the_parser]['value'] = null;
+			break;
+			case 'VALUE':
+				$this->xh[$the_parser]['vt'] = 'value';
+				$this->xh[$the_parser]['ac'] = '';
+				$this->xh[$the_parser]['lv'] = 1;
+			break;
+			case 'I4':
+			case 'INT':
+			case 'STRING':
+			case 'BOOLEAN':
+			case 'DOUBLE':
+			case 'DATETIME.ISO8601':
+			case 'BASE64':
+				if ($this->xh[$the_parser]['vt'] != 'value')
+				{
+					//two data elements inside a value: an error occurred!
+					$this->xh[$the_parser]['isf'] = 2;
+					$this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
+					return;
+				}
+				
+				$this->xh[$the_parser]['ac'] = '';
+			break;
+			case 'MEMBER':
+				// Set name of <member> to nothing to prevent errors later if no <name> is found
+				$this->xh[$the_parser]['valuestack'][0]['name'] = '';
+				
+				// Set NULL value to check to see if value passed for this param/member
+				$this->xh[$the_parser]['value'] = null;
+			break;
+			case 'DATA':
+			case 'METHODCALL':
+			case 'METHODRESPONSE':
+			case 'PARAMS':
+				// valid elements that add little to processing
+			break;
+			default:
+				/// An Invalid Element is Found, so we have trouble
+				$this->xh[$the_parser]['isf'] = 2;
+				$this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
+			break;
+		}
+		
+		// Add current element name to stack, to allow validation of nesting
+		array_unshift($this->xh[$the_parser]['stack'], $name);
+
+		if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
+	}
+	// END
+
+
+	//-------------------------------------
+	//  End Element Handler
+	//-------------------------------------
+
+	function closing_tag($the_parser, $name)
+	{
+		if ($this->xh[$the_parser]['isf'] > 1) return;
+		
+		// Remove current element from stack and set variable
+		// NOTE: If the XML validates, then we do not have to worry about
+		// the opening and closing of elements.  Nesting is checked on the opening
+		// tag so we be safe there as well.
+		
+		$curr_elem = array_shift($this->xh[$the_parser]['stack']);
+	
+		switch($name)
+		{
+			case 'STRUCT':
+			case 'ARRAY':
+				$cur_val = array_shift($this->xh[$the_parser]['valuestack']);
+				$this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
+				$this->xh[$the_parser]['vt']	= strtolower($name);
+			break;
+			case 'NAME':
+				$this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
+			break;
+			case 'BOOLEAN':
+			case 'I4':
+			case 'INT':
+			case 'STRING':
+			case 'DOUBLE':
+			case 'DATETIME.ISO8601':
+			case 'BASE64':
+				$this->xh[$the_parser]['vt'] = strtolower($name);
+				
+				if ($name == 'STRING')
+				{
+					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
+				}
+				elseif ($name=='DATETIME.ISO8601')
+				{
+					$this->xh[$the_parser]['vt']	= $this->xmlrpcDateTime;
+					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
+				}
+				elseif ($name=='BASE64')
+				{
+					$this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
+				}
+				elseif ($name=='BOOLEAN')
+				{
+					// Translated BOOLEAN values to TRUE AND FALSE
+					if ($this->xh[$the_parser]['ac'] == '1')
+					{
+						$this->xh[$the_parser]['value'] = TRUE;
+					}
+					else
+					{
+						$this->xh[$the_parser]['value'] = FALSE;
+					}
+				}
+				elseif ($name=='DOUBLE')
+				{
+					// we have a DOUBLE
+					// we must check that only 0123456789-.<space> are characters here
+					if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
+					{
+						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
+					}
+					else
+					{
+						$this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
+					}
+				}
+				else
+				{
+					// we have an I4/INT
+					// we must check that only 0123456789-<space> are characters here
+					if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
+					{
+						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
+					}
+					else
+					{
+						$this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
+					}
+				}
+				$this->xh[$the_parser]['ac'] = '';
+				$this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
+			break;
+			case 'VALUE':
+				// This if() detects if no scalar was inside <VALUE></VALUE>
+				if ($this->xh[$the_parser]['vt']=='value')
+				{
+					$this->xh[$the_parser]['value']	= $this->xh[$the_parser]['ac'];
+					$this->xh[$the_parser]['vt']	= $this->xmlrpcString;
+				}
+				
+				// build the XML-RPC value out of the data received, and substitute it
+				$temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
+				
+				if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
+				{
+					// Array
+					$this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
+				}
+				else
+				{
+					// Struct
+					$this->xh[$the_parser]['value'] = $temp;
+				}
+			break;
+			case 'MEMBER':
+				$this->xh[$the_parser]['ac']='';
+				
+				// If value add to array in the stack for the last element built
+				if ($this->xh[$the_parser]['value'])
+				{
+					$this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
+				}
+			break;
+			case 'DATA':
+				$this->xh[$the_parser]['ac']='';
+			break;
+			case 'PARAM':
+				if ($this->xh[$the_parser]['value'])
+				{
+					$this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
+				}
+			break;
+			case 'METHODNAME':
+				$this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
+			break;
+			case 'PARAMS':
+			case 'FAULT':
+			case 'METHODCALL':
+			case 'METHORESPONSE':
+				// We're all good kids with nuthin' to do
+			break;
+			default:
+				// End of an Invalid Element.  Taken care of during the opening tag though
+			break;
+		}
+	}
+
+	//-------------------------------------
+	//  Parses Character Data
+	//-------------------------------------
+
+	function character_data($the_parser, $data)
+	{
+		if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
+		
+		// If a value has not been found
+		if ($this->xh[$the_parser]['lv'] != 3)
+		{
+			if ($this->xh[$the_parser]['lv'] == 1)
+			{
+				$this->xh[$the_parser]['lv'] = 2; // Found a value
+			}
+				
+			if( ! @isset($this->xh[$the_parser]['ac']))
+			{
+				$this->xh[$the_parser]['ac'] = '';
+			}
+				
+			$this->xh[$the_parser]['ac'] .= $data;
+		}
+	}
+	
+	
+	function addParam($par) { $this->params[]=$par; }
+	
+	function output_parameters($array=FALSE)
+	{
+		$CI =& get_instance();	
+
+		if ($array !== FALSE && is_array($array))
+		{
+			while (list($key) = each($array))
+			{
+				if (is_array($array[$key]))
+				{
+					$array[$key] = $this->output_parameters($array[$key]);
+				}
+				else
+				{
+					$array[$key] = $CI->input->xss_clean($array[$key]);
+				}
+			}
+			
+			$parameters = $array;
+		}
+		else
+		{
+			$parameters = array();
+		
+			for ($i = 0; $i < sizeof($this->params); $i++)
+			{
+				$a_param = $this->decode_message($this->params[$i]);
+				
+				if (is_array($a_param))
+				{
+					$parameters[] = $this->output_parameters($a_param);
+				}
+				else
+				{
+					$parameters[] = $CI->input->xss_clean($a_param);
+				}
+			}	
+		}
+		
+		return $parameters;
+	}
+	
+	
+	function decode_message($param)
+	{
+		$kind = $param->kindOf();
+
+		if($kind == 'scalar')
+		{
+			return $param->scalarval();
+		}
+		elseif($kind == 'array')
+		{
+			reset($param->me);
+			list($a,$b) = each($param->me);
+			
+			$arr = array();
+
+			for($i = 0; $i < sizeof($b); $i++)
+			{
+				$arr[] = $this->decode_message($param->me['array'][$i]);
+			}
+			
+			return $arr;
+		}
+		elseif($kind == 'struct')
+		{
+			reset($param->me['struct']);
+			
+			$arr = array();
+
+			while(list($key,$value) = each($param->me['struct']))
+			{
+				$arr[$key] = $this->decode_message($value);
+			}
+			
+			return $arr;
+		}
+	}
+	
+} // End XML_RPC_Messages class
+
+
+
+/**
+ * XML-RPC Values class
+ *
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Values extends CI_Xmlrpc
+{
+	var $me 	= array();
+	var $mytype	= 0;
+
+	function XML_RPC_Values($val=-1, $type='')
+	{	
+		parent::CI_Xmlrpc();
+		
+		if ($val != -1 OR $type != '')
+		{
+			$type = $type == '' ? 'string' : $type;
+			
+			if ($this->xmlrpcTypes[$type] == 1)
+			{
+				$this->addScalar($val,$type);
+			}
+			elseif ($this->xmlrpcTypes[$type] == 2)
+			{
+				$this->addArray($val);
+			}
+			elseif ($this->xmlrpcTypes[$type] == 3)
+			{
+				$this->addStruct($val);
+			}
+		}
+	}
+
+	function addScalar($val, $type='string')
+	{
+		$typeof = $this->xmlrpcTypes[$type];
+		
+		if ($this->mytype==1)
+		{
+			echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
+			return 0;
+		}
+		
+		if ($typeof != 1)
+		{
+			echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
+			return 0;
+		}
+
+		if ($type == $this->xmlrpcBoolean)
+		{
+			if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))
+			{
+				$val = 1;
+			}
+			else
+			{
+				$val=0;
+			}
+		}
+
+		if ($this->mytype == 2)
+		{
+			// adding to an array here
+			$ar = $this->me['array'];
+			$ar[] = new XML_RPC_Values($val, $type);
+			$this->me['array'] = $ar;
+		}
+		else
+		{
+			// a scalar, so set the value and remember we're scalar
+			$this->me[$type] = $val;
+			$this->mytype = $typeof;
+		}
+		return 1;
+	}
+
+	function addArray($vals)
+	{
+		if ($this->mytype != 0)
+		{
+			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+			return 0;
+		}
+
+		$this->mytype = $this->xmlrpcTypes['array'];
+		$this->me['array'] = $vals;
+		return 1;
+	}
+
+	function addStruct($vals)
+	{
+		if ($this->mytype != 0)
+		{
+			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+			return 0;
+		}
+		$this->mytype = $this->xmlrpcTypes['struct'];
+		$this->me['struct'] = $vals;
+		return 1;
+	}
+
+	function kindOf()
+	{
+		switch($this->mytype)
+		{
+			case 3:
+				return 'struct';
+				break;
+			case 2:
+				return 'array';
+				break;
+			case 1:
+				return 'scalar';
+				break;
+			default:
+				return 'undef';
+		}
+	}
+
+	function serializedata($typ, $val)
+	{
+		$rs = '';
+		
+		switch($this->xmlrpcTypes[$typ])
+		{
+			case 3:
+				// struct
+				$rs .= "<struct>\n";
+				reset($val);
+				while(list($key2, $val2) = each($val))
+				{
+					$rs .= "<member>\n<name>{$key2}</name>\n";
+					$rs .= $this->serializeval($val2);
+					$rs .= "</member>\n";
+				}
+				$rs .= '</struct>';
+			break;
+			case 2:
+				// array
+				$rs .= "<array>\n<data>\n";
+				for($i=0; $i < sizeof($val); $i++)
+				{
+					$rs .= $this->serializeval($val[$i]);
+				}
+				$rs.="</data>\n</array>\n";
+				break;
+			case 1:
+				// others
+				switch ($typ)
+				{
+					case $this->xmlrpcBase64:
+						$rs .= "<{$typ}>" . base64_encode($val) . "</{$typ}>\n";
+					break;
+					case $this->xmlrpcBoolean:
+						$rs .= "<{$typ}>" . ($val ? '1' : '0') . "</{$typ}>\n";
+					break;
+					case $this->xmlrpcString:
+						$rs .= "<{$typ}>" . htmlspecialchars($val). "</{$typ}>\n";
+					break;
+					default:
+						$rs .= "<{$typ}>{$val}</{$typ}>\n";
+					break;
+				}
+			default:
+			break;
+		}
+		return $rs;
+	}
+
+	function serialize_class()
+	{
+		return $this->serializeval($this);
+	}
+
+	function serializeval($o)
+	{
+		$ar = $o->me;
+		reset($ar);
+		
+		list($typ, $val) = each($ar);
+		$rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";
+		return $rs;
+	}
+	
+	function scalarval()
+	{
+		reset($this->me);
+		list($a,$b) = each($this->me);
+		return $b;
+	}
+
+
+	//-------------------------------------
+	// Encode time in ISO-8601 form.
+	//-------------------------------------
+	
+	// Useful for sending time in XML-RPC
+
+	function iso8601_encode($time, $utc=0)
+	{	
+		if ($utc == 1)
+		{
+			$t = strftime("%Y%m%dT%H:%M:%S", $time);
+		}
+		else
+		{
+			if (function_exists('gmstrftime'))
+				$t = gmstrftime("%Y%m%dT%H:%M:%S", $time);
+			else
+				$t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z'));
+		}
+		return $t;
+	}
+	
+}
+// END XML_RPC_Values Class
+
+/* End of file Xmlrpc.php */
 /* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index a210183..cdbdee9 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -1,536 +1,536 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-if ( ! function_exists('xml_parser_create'))

-{	

-	show_error('Your PHP installation does not support XML');

-}

-

-if ( ! class_exists('CI_Xmlrpc'))

-{

-	show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');

-}

-

-// ------------------------------------------------------------------------

-

-/**

- * XML-RPC server class

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	XML-RPC

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html

- */

-class CI_Xmlrpcs extends CI_Xmlrpc

-{

-	var $methods		= array(); 	//array of methods mapped to function names and signatures

-	var $debug_msg		= '';		// Debug Message

-	var $system_methods = array(); // XML RPC Server methods

-	var $controller_obj;

-

-	var $object			= FALSE;

-	

-	

-	//-------------------------------------

-	//  Constructor, more or less

-	//-------------------------------------

-

-	function CI_Xmlrpcs($config=array())

-	{	

-		parent::CI_Xmlrpc();

-		$this->set_system_methods();

-	

-		if (isset($config['functions']) && is_array($config['functions']))

-		{

-			$this->methods = array_merge($this->methods, $config['functions']);

-		}

-		

-		log_message('debug', "XML-RPC Server Class Initialized");

-	}

-	

-	//-------------------------------------

-	//  Initialize Prefs and Serve

-	//-------------------------------------

-	

-	function initialize($config=array())

-	{	

-		if (isset($config['functions']) && is_array($config['functions']))

-		{

-			$this->methods = array_merge($this->methods, $config['functions']);

-		}

-		

-		if (isset($config['debug']))

-		{

-			$this->debug = $config['debug'];

-		}

-		

-		if (isset($config['object']) && is_object($config['object']))

-		{

-			$this->object = $config['object'];

-		}

-	}

-	

-	//-------------------------------------

-	//  Setting of System Methods

-	//-------------------------------------

-	

-	function set_system_methods ()

-	{

-		$this->methods = array(

-					'system.listMethods'	 => array(

-													'function' => 'this.listMethods',

-													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),

-													'docstring' => 'Returns an array of available methods on this server'),

-					'system.methodHelp'		 => array(

-													'function' => 'this.methodHelp',

-													'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),

-													'docstring' => 'Returns a documentation string for the specified method'),

-					'system.methodSignature' => array(

-													'function' => 'this.methodSignature',

-													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),

-													'docstring' => 'Returns an array describing the return type and required parameters of a method'),

-					'system.multicall'		 => array(

-												'function' => 'this.multicall',

-												'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),

-												'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')

-					);

-	}

-

-

-	//-------------------------------------

-	//  Main Server Function

-	//-------------------------------------

-	

-	function serve()

-	{

-		$r = $this->parseRequest();

-		$payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";

-		$payload .= $this->debug_msg;

-		$payload .= $r->prepare_response();

-		

-		header("Content-Type: text/xml");

-		header("Content-Length: ".strlen($payload));

-		echo $payload;

-	}

-

-	//-------------------------------------

-	//  Add Method to Class

-	//-------------------------------------

-	

-	function add_to_map($methodname,$function,$sig,$doc)

-	{

-		$this->methods[$methodname] = array(

-			'function'  => $function,

-			'signature' => $sig,

-			'docstring' => $doc

-		);

-	}

-

-

-	//-------------------------------------

-	//  Parse Server Request

-	//-------------------------------------

-	

-	function parseRequest($data='')

-	{

-		global $HTTP_RAW_POST_DATA;

-		

-		//-------------------------------------

-		//  Get Data

-		//-------------------------------------

-

-		if ($data == '')

-		{

-			$data = $HTTP_RAW_POST_DATA;

-		}

-

-		//-------------------------------------

-		//  Set up XML Parser

-		//-------------------------------------

-		

-		$parser = xml_parser_create($this->xmlrpc_defencoding);

-		$parser_object = new XML_RPC_Message("filler");

-		

-		$parser_object->xh[$parser]					= array();

-		$parser_object->xh[$parser]['isf']			= 0;

-		$parser_object->xh[$parser]['isf_reason']	= '';

-		$parser_object->xh[$parser]['params']		= array();

-		$parser_object->xh[$parser]['stack']		= array();

-		$parser_object->xh[$parser]['valuestack']	= array();

-		$parser_object->xh[$parser]['method']		= '';

-

-		xml_set_object($parser, $parser_object);

-		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);

-		xml_set_element_handler($parser, 'open_tag', 'closing_tag');

-		xml_set_character_data_handler($parser, 'character_data');

-		//xml_set_default_handler($parser, 'default_handler');

-		

-		

-		//-------------------------------------

-		//  PARSE + PROCESS XML DATA

-		//-------------------------------------  	

-		

-		if ( ! xml_parse($parser, $data, 1))

-		{

-			// return XML error as a faultCode

-			$r = new XML_RPC_Response(0,

-			$this->xmlrpcerrxml + xml_get_error_code($parser),

-			sprintf('XML error: %s at line %d',

-				xml_error_string(xml_get_error_code($parser)),

-				xml_get_current_line_number($parser)));

-			xml_parser_free($parser);

-		}

-		elseif($parser_object->xh[$parser]['isf'])

-		{

-			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);

-		}

-		else

-		{

-			xml_parser_free($parser);

-			

-			$m = new XML_RPC_Message($parser_object->xh[$parser]['method']);

-			$plist='';

-			

-			for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++)

-			{

-				if ($this->debug === TRUE)

-				{

-					$plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";

-				}

-				

-				$m->addParam($parser_object->xh[$parser]['params'][$i]);

-			}

-			

-			if ($this->debug === TRUE)

-			{

-				echo "<pre>";

-				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";

-				echo "</pre>";

-			}

-			

-			$r = $this->_execute($m);

-		}

-		

-		//-------------------------------------

-		//  SET DEBUGGING MESSAGE

-		//-------------------------------------  	

-		

-		if ($this->debug === TRUE)

-		{

-			$this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";

-		}

-		

-		return $r;

-	}

-

-	//-------------------------------------

-	//  Executes the Method

-	//-------------------------------------

-	

-	function _execute($m)

-	{

-		$methName = $m->method_name;

-		

-		// Check to see if it is a system call

-		$system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;

-		

-		//-------------------------------------

-		//  Valid Method

-		//-------------------------------------

-		

-		if ( ! isset($this->methods[$methName]['function']))

-		{

-			return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);

-		}

-		

-		//-------------------------------------

-		//  Check for Method (and Object)

-		//-------------------------------------

-			

-		$method_parts = explode(".", $this->methods[$methName]['function']);

-		$objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;

-		

-		if ($system_call === TRUE)

-		{

-			if ( ! is_callable(array($this,$method_parts['1'])))

-			{

-				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);

-			}

-		}

-		else

-		{

-			if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))

-			{

-				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);

-			}

-			elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))

-			{

-				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);

-			}

-		}

-		

-		//-------------------------------------

-		//  Checking Methods Signature

-		//-------------------------------------

-		

-		if (isset($this->methods[$methName]['signature']))

-		{

-			$sig = $this->methods[$methName]['signature'];

-			for($i=0; $i<sizeof($sig); $i++)

-			{

-				$current_sig = $sig[$i];

-		

-				if (sizeof($current_sig) == sizeof($m->params)+1)

-				{

-					for($n=0; $n < sizeof($m->params); $n++)

-					{

-						$p = $m->params[$n];

-						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();

-						

-						if ($pt != $current_sig[$n+1])

-						{

-							$pno = $n+1;

-							$wanted = $current_sig[$n+1];

-							

-							return new XML_RPC_Response(0,

-								$this->xmlrpcerr['incorrect_params'],

-								$this->xmlrpcstr['incorrect_params'] .

-								": Wanted {$wanted}, got {$pt} at param {$pno})");

-						}

-					}

-				}

-			}

-		}

-

-		//-------------------------------------

-		//  Calls the Function

-		//-------------------------------------

-

-		if ($objectCall === TRUE)

-		{

-			if ($method_parts[0] == "this" && $system_call == TRUE)

-			{

-				return call_user_func(array($this, $method_parts[1]), $m);

-			}

-			else

-			{

-				if ($this->object === FALSE)

-				{

-					$CI =& get_instance();

-					return $CI->$method_parts['1']($m);

-				}

-				else

-				{

-					return $this->object->$method_parts['1']($m);

-					//return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);

-				}

-			}

-		}

-		else

-		{

-			return call_user_func($this->methods[$methName]['function'], $m);

-		}

-	}

-	

-	

-	//-------------------------------------

-	//  Server Function:  List Methods

-	//-------------------------------------

-	

-	function listMethods($m)

-	{

-		$v = new XML_RPC_Values();

-		$output = array();

-		

-		foreach($this->methods as $key => $value)

-		{

-			$output[] = new XML_RPC_Values($key, 'string');

-		}

-		

-		foreach($this->system_methods as $key => $value)

-		{

-			$output[]= new XML_RPC_Values($key, 'string');

-		}

-

-		$v->addArray($output);

-		return new XML_RPC_Response($v);

-	}

-	

-	//-------------------------------------

-	//  Server Function:  Return Signature for Method

-	//-------------------------------------

-		

-	function methodSignature($m)

-	{

-		$parameters = $m->output_parameters();

-		$method_name = $parameters[0];

-		

-		if (isset($this->methods[$method_name]))

-		{

-			if ($this->methods[$method_name]['signature'])

-			{

-				$sigs = array();

-				$signature = $this->methods[$method_name]['signature'];

-				

-				for($i=0; $i < sizeof($signature); $i++)

-				{

-					$cursig = array();

-					$inSig = $signature[$i];

-					for($j=0; $j<sizeof($inSig); $j++)

-					{

-						$cursig[]= new XML_RPC_Values($inSig[$j], 'string');

-					}

-					$sigs[]= new XML_RPC_Values($cursig, 'array');

-				}

-				$r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));

-			}

-			else

-			{

-				$r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));

-			}

-		}

-		else

-		{

-			$r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);

-		}

-		return $r;

-	}

-	

-	//-------------------------------------

-	//  Server Function:  Doc String for Method

-	//-------------------------------------

-	

-	function methodHelp($m)

-	{

-		$parameters = $m->output_parameters();

-		$method_name = $parameters[0];

-	

-		if (isset($this->methods[$method_name]))

-		{

-			$docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';

-			

-			return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));

-		}

-		else

-		{

-			return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);

-		}

-	}

-

-	//-------------------------------------

-	//  Server Function:  Multi-call

-	//-------------------------------------

-

-	function multicall($m)

-	{

-		// Disabled

-		return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);

-		

-		$parameters = $m->output_parameters();

-		$calls = $parameters[0];

-

-		$result = array();

-

-		foreach ($calls as $value)

-		{

-			//$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));

-			

-			$m = new XML_RPC_Message($value[0]);

-			$plist='';

-			

-			for($i=0; $i < sizeof($value[1]); $i++)

-			{

-				$m->addParam(new XML_RPC_Values($value[1][$i], 'string'));

-			}

-			

-			$attempt = $this->_execute($m);

-

-			if ($attempt->faultCode() != 0)

-			{

-				return $attempt;

-			}

-

-			$result[] = new XML_RPC_Values(array($attempt->value()), 'array');

-		}

-

-		return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));

-	}

-	

-	

-	//-------------------------------------

-	//  Multi-call Function:  Error Handling

-	//-------------------------------------

-

-	function multicall_error($err)

-	{

-		$str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();

-		$code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();

-		

-		$struct['faultCode'] = new XML_RPC_Values($code, 'int');

-		$struct['faultString'] = new XML_RPC_Values($str, 'string');

-	

-		return new XML_RPC_Values($struct, 'struct');

-	}

-	

-	

-	//-------------------------------------

-	//  Multi-call Function:  Processes method

-	//-------------------------------------

-	

-	function do_multicall($call)

-	{

-		if ($call->kindOf() != 'struct')

-			return $this->multicall_error('notstruct');

-		elseif ( ! $methName = $call->me['struct']['methodName'])

-			return $this->multicall_error('nomethod');

-		

-		list($scalar_type,$scalar_value)=each($methName->me);

-		$scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;

-			

-		if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')

-			return $this->multicall_error('notstring');

-		elseif ($scalar_value == 'system.multicall')

-			return $this->multicall_error('recursion');

-		elseif ( ! $params = $call->me['struct']['params'])

-			return $this->multicall_error('noparams');

-		elseif ($params->kindOf() != 'array')

-			return $this->multicall_error('notarray');

-			

-		list($a,$b)=each($params->me);

-		$numParams = sizeof($b);

-

-		$msg = new XML_RPC_Message($scalar_value);

-		for ($i = 0; $i < $numParams; $i++)

-		{

-			$msg->params[] = $params->me['array'][$i];

-		}

-

-		$result = $this->_execute($msg);

-

-		if ($result->faultCode() != 0)

-		{

-			return $this->multicall_error($result);

-		}

-

-		return new XML_RPC_Values(array($result->value()), 'array');

-	}	

-	

-}

-// END XML_RPC_Server class

-

-

-/* End of file Xmlrpcs.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+if ( ! function_exists('xml_parser_create'))
+{	
+	show_error('Your PHP installation does not support XML');
+}
+
+if ( ! class_exists('CI_Xmlrpc'))
+{
+	show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * XML-RPC server class
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	XML-RPC
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class CI_Xmlrpcs extends CI_Xmlrpc
+{
+	var $methods		= array(); 	//array of methods mapped to function names and signatures
+	var $debug_msg		= '';		// Debug Message
+	var $system_methods = array(); // XML RPC Server methods
+	var $controller_obj;
+
+	var $object			= FALSE;
+	
+	
+	//-------------------------------------
+	//  Constructor, more or less
+	//-------------------------------------
+
+	function CI_Xmlrpcs($config=array())
+	{	
+		parent::CI_Xmlrpc();
+		$this->set_system_methods();
+	
+		if (isset($config['functions']) && is_array($config['functions']))
+		{
+			$this->methods = array_merge($this->methods, $config['functions']);
+		}
+		
+		log_message('debug', "XML-RPC Server Class Initialized");
+	}
+	
+	//-------------------------------------
+	//  Initialize Prefs and Serve
+	//-------------------------------------
+	
+	function initialize($config=array())
+	{	
+		if (isset($config['functions']) && is_array($config['functions']))
+		{
+			$this->methods = array_merge($this->methods, $config['functions']);
+		}
+		
+		if (isset($config['debug']))
+		{
+			$this->debug = $config['debug'];
+		}
+		
+		if (isset($config['object']) && is_object($config['object']))
+		{
+			$this->object = $config['object'];
+		}
+	}
+	
+	//-------------------------------------
+	//  Setting of System Methods
+	//-------------------------------------
+	
+	function set_system_methods ()
+	{
+		$this->methods = array(
+					'system.listMethods'	 => array(
+													'function' => 'this.listMethods',
+													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
+													'docstring' => 'Returns an array of available methods on this server'),
+					'system.methodHelp'		 => array(
+													'function' => 'this.methodHelp',
+													'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
+													'docstring' => 'Returns a documentation string for the specified method'),
+					'system.methodSignature' => array(
+													'function' => 'this.methodSignature',
+													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
+													'docstring' => 'Returns an array describing the return type and required parameters of a method'),
+					'system.multicall'		 => array(
+												'function' => 'this.multicall',
+												'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
+												'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
+					);
+	}
+
+
+	//-------------------------------------
+	//  Main Server Function
+	//-------------------------------------
+	
+	function serve()
+	{
+		$r = $this->parseRequest();
+		$payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";
+		$payload .= $this->debug_msg;
+		$payload .= $r->prepare_response();
+		
+		header("Content-Type: text/xml");
+		header("Content-Length: ".strlen($payload));
+		echo $payload;
+	}
+
+	//-------------------------------------
+	//  Add Method to Class
+	//-------------------------------------
+	
+	function add_to_map($methodname,$function,$sig,$doc)
+	{
+		$this->methods[$methodname] = array(
+			'function'  => $function,
+			'signature' => $sig,
+			'docstring' => $doc
+		);
+	}
+
+
+	//-------------------------------------
+	//  Parse Server Request
+	//-------------------------------------
+	
+	function parseRequest($data='')
+	{
+		global $HTTP_RAW_POST_DATA;
+		
+		//-------------------------------------
+		//  Get Data
+		//-------------------------------------
+
+		if ($data == '')
+		{
+			$data = $HTTP_RAW_POST_DATA;
+		}
+
+		//-------------------------------------
+		//  Set up XML Parser
+		//-------------------------------------
+		
+		$parser = xml_parser_create($this->xmlrpc_defencoding);
+		$parser_object = new XML_RPC_Message("filler");
+		
+		$parser_object->xh[$parser]					= array();
+		$parser_object->xh[$parser]['isf']			= 0;
+		$parser_object->xh[$parser]['isf_reason']	= '';
+		$parser_object->xh[$parser]['params']		= array();
+		$parser_object->xh[$parser]['stack']		= array();
+		$parser_object->xh[$parser]['valuestack']	= array();
+		$parser_object->xh[$parser]['method']		= '';
+
+		xml_set_object($parser, $parser_object);
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
+		xml_set_element_handler($parser, 'open_tag', 'closing_tag');
+		xml_set_character_data_handler($parser, 'character_data');
+		//xml_set_default_handler($parser, 'default_handler');
+		
+		
+		//-------------------------------------
+		//  PARSE + PROCESS XML DATA
+		//-------------------------------------  	
+		
+		if ( ! xml_parse($parser, $data, 1))
+		{
+			// return XML error as a faultCode
+			$r = new XML_RPC_Response(0,
+			$this->xmlrpcerrxml + xml_get_error_code($parser),
+			sprintf('XML error: %s at line %d',
+				xml_error_string(xml_get_error_code($parser)),
+				xml_get_current_line_number($parser)));
+			xml_parser_free($parser);
+		}
+		elseif($parser_object->xh[$parser]['isf'])
+		{
+			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
+		}
+		else
+		{
+			xml_parser_free($parser);
+			
+			$m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
+			$plist='';
+			
+			for($i=0; $i < sizeof($parser_object->xh[$parser]['params']); $i++)
+			{
+				if ($this->debug === TRUE)
+				{
+					$plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
+				}
+				
+				$m->addParam($parser_object->xh[$parser]['params'][$i]);
+			}
+			
+			if ($this->debug === TRUE)
+			{
+				echo "<pre>";
+				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
+				echo "</pre>";
+			}
+			
+			$r = $this->_execute($m);
+		}
+		
+		//-------------------------------------
+		//  SET DEBUGGING MESSAGE
+		//-------------------------------------  	
+		
+		if ($this->debug === TRUE)
+		{
+			$this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
+		}
+		
+		return $r;
+	}
+
+	//-------------------------------------
+	//  Executes the Method
+	//-------------------------------------
+	
+	function _execute($m)
+	{
+		$methName = $m->method_name;
+		
+		// Check to see if it is a system call
+		$system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;
+		
+		//-------------------------------------
+		//  Valid Method
+		//-------------------------------------
+		
+		if ( ! isset($this->methods[$methName]['function']))
+		{
+			return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
+		}
+		
+		//-------------------------------------
+		//  Check for Method (and Object)
+		//-------------------------------------
+			
+		$method_parts = explode(".", $this->methods[$methName]['function']);
+		$objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;
+		
+		if ($system_call === TRUE)
+		{
+			if ( ! is_callable(array($this,$method_parts['1'])))
+			{
+				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
+			}
+		}
+		else
+		{
+			if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))
+			{
+				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
+			}
+			elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
+			{
+				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
+			}
+		}
+		
+		//-------------------------------------
+		//  Checking Methods Signature
+		//-------------------------------------
+		
+		if (isset($this->methods[$methName]['signature']))
+		{
+			$sig = $this->methods[$methName]['signature'];
+			for($i=0; $i<sizeof($sig); $i++)
+			{
+				$current_sig = $sig[$i];
+		
+				if (sizeof($current_sig) == sizeof($m->params)+1)
+				{
+					for($n=0; $n < sizeof($m->params); $n++)
+					{
+						$p = $m->params[$n];
+						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
+						
+						if ($pt != $current_sig[$n+1])
+						{
+							$pno = $n+1;
+							$wanted = $current_sig[$n+1];
+							
+							return new XML_RPC_Response(0,
+								$this->xmlrpcerr['incorrect_params'],
+								$this->xmlrpcstr['incorrect_params'] .
+								": Wanted {$wanted}, got {$pt} at param {$pno})");
+						}
+					}
+				}
+			}
+		}
+
+		//-------------------------------------
+		//  Calls the Function
+		//-------------------------------------
+
+		if ($objectCall === TRUE)
+		{
+			if ($method_parts[0] == "this" && $system_call == TRUE)
+			{
+				return call_user_func(array($this, $method_parts[1]), $m);
+			}
+			else
+			{
+				if ($this->object === FALSE)
+				{
+					$CI =& get_instance();
+					return $CI->$method_parts['1']($m);
+				}
+				else
+				{
+					return $this->object->$method_parts['1']($m);
+					//return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
+				}
+			}
+		}
+		else
+		{
+			return call_user_func($this->methods[$methName]['function'], $m);
+		}
+	}
+	
+	
+	//-------------------------------------
+	//  Server Function:  List Methods
+	//-------------------------------------
+	
+	function listMethods($m)
+	{
+		$v = new XML_RPC_Values();
+		$output = array();
+		
+		foreach($this->methods as $key => $value)
+		{
+			$output[] = new XML_RPC_Values($key, 'string');
+		}
+		
+		foreach($this->system_methods as $key => $value)
+		{
+			$output[]= new XML_RPC_Values($key, 'string');
+		}
+
+		$v->addArray($output);
+		return new XML_RPC_Response($v);
+	}
+	
+	//-------------------------------------
+	//  Server Function:  Return Signature for Method
+	//-------------------------------------
+		
+	function methodSignature($m)
+	{
+		$parameters = $m->output_parameters();
+		$method_name = $parameters[0];
+		
+		if (isset($this->methods[$method_name]))
+		{
+			if ($this->methods[$method_name]['signature'])
+			{
+				$sigs = array();
+				$signature = $this->methods[$method_name]['signature'];
+				
+				for($i=0; $i < sizeof($signature); $i++)
+				{
+					$cursig = array();
+					$inSig = $signature[$i];
+					for($j=0; $j<sizeof($inSig); $j++)
+					{
+						$cursig[]= new XML_RPC_Values($inSig[$j], 'string');
+					}
+					$sigs[]= new XML_RPC_Values($cursig, 'array');
+				}
+				$r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
+			}
+			else
+			{
+				$r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
+			}
+		}
+		else
+		{
+			$r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
+		}
+		return $r;
+	}
+	
+	//-------------------------------------
+	//  Server Function:  Doc String for Method
+	//-------------------------------------
+	
+	function methodHelp($m)
+	{
+		$parameters = $m->output_parameters();
+		$method_name = $parameters[0];
+	
+		if (isset($this->methods[$method_name]))
+		{
+			$docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
+			
+			return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
+		}
+		else
+		{
+			return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
+		}
+	}
+
+	//-------------------------------------
+	//  Server Function:  Multi-call
+	//-------------------------------------
+
+	function multicall($m)
+	{
+		// Disabled
+		return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
+		
+		$parameters = $m->output_parameters();
+		$calls = $parameters[0];
+
+		$result = array();
+
+		foreach ($calls as $value)
+		{
+			//$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
+			
+			$m = new XML_RPC_Message($value[0]);
+			$plist='';
+			
+			for($i=0; $i < sizeof($value[1]); $i++)
+			{
+				$m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
+			}
+			
+			$attempt = $this->_execute($m);
+
+			if ($attempt->faultCode() != 0)
+			{
+				return $attempt;
+			}
+
+			$result[] = new XML_RPC_Values(array($attempt->value()), 'array');
+		}
+
+		return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
+	}
+	
+	
+	//-------------------------------------
+	//  Multi-call Function:  Error Handling
+	//-------------------------------------
+
+	function multicall_error($err)
+	{
+		$str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
+		$code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
+		
+		$struct['faultCode'] = new XML_RPC_Values($code, 'int');
+		$struct['faultString'] = new XML_RPC_Values($str, 'string');
+	
+		return new XML_RPC_Values($struct, 'struct');
+	}
+	
+	
+	//-------------------------------------
+	//  Multi-call Function:  Processes method
+	//-------------------------------------
+	
+	function do_multicall($call)
+	{
+		if ($call->kindOf() != 'struct')
+			return $this->multicall_error('notstruct');
+		elseif ( ! $methName = $call->me['struct']['methodName'])
+			return $this->multicall_error('nomethod');
+		
+		list($scalar_type,$scalar_value)=each($methName->me);
+		$scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
+			
+		if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
+			return $this->multicall_error('notstring');
+		elseif ($scalar_value == 'system.multicall')
+			return $this->multicall_error('recursion');
+		elseif ( ! $params = $call->me['struct']['params'])
+			return $this->multicall_error('noparams');
+		elseif ($params->kindOf() != 'array')
+			return $this->multicall_error('notarray');
+			
+		list($a,$b)=each($params->me);
+		$numParams = sizeof($b);
+
+		$msg = new XML_RPC_Message($scalar_value);
+		for ($i = 0; $i < $numParams; $i++)
+		{
+			$msg->params[] = $params->me['array'][$i];
+		}
+
+		$result = $this->_execute($msg);
+
+		if ($result->faultCode() != 0)
+		{
+			return $this->multicall_error($result);
+		}
+
+		return new XML_RPC_Values(array($result->value()), 'array');
+	}	
+	
+}
+// END XML_RPC_Server class
+
+
+/* End of file Xmlrpcs.php */
 /* Location: ./system/libraries/Xmlrpcs.php */
\ No newline at end of file
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index c15255a..7318815 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -1,359 +1,359 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Zip Compression Class

- *

- * This class is based on a library I found at Zend:

- * http://www.zend.com/codex.php?id=696&single=1

- *

- * The original library is a little rough around the edges so I

- * refactored it and added several additional methods -- Rick Ellis

- *

- * @package		CodeIgniter

- * @subpackage	Libraries

- * @category	Encryption

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/libraries/zip.html

- */

-class CI_Zip  {

-

-	var $zipdata 	= '';

-	var $directory 	= '';

-	var $entries 	= 0;

-	var $file_num 	= 0;

-	var $offset		= 0;

-

-	function CI_Zip()

-	{

-		log_message('debug', "Zip Compression Class Initialized");

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Directory

-	 *

-	 * Lets you add a virtual directory into which you can place files.

-	 *

-	 * @access	public

-	 * @param	mixed	the directory name. Can be string or array

-	 * @return	void

-	 */

-	function add_dir($directory)

-	{

-		foreach ((array)$directory as $dir)

-		{

-			if ( ! preg_match("|.+/$|", $dir))

-			{

-				$dir .= '/';

-			}

-

-			$this->_add_dir($dir);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Directory

-	 *

-	 * @access	private

-	 * @param	string	the directory name

-	 * @return	void

-	 */

-	function _add_dir($dir)

-	{

-		$dir = str_replace("\\", "/", $dir);

-

-		$this->zipdata .=

-			"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"

-			.pack('V', 0) // crc32

-			.pack('V', 0) // compressed filesize

-			.pack('V', 0) // uncompressed filesize

-			.pack('v', strlen($dir)) // length of pathname

-			.pack('v', 0) // extra field length

-			.$dir

-			// below is "data descriptor" segment

-			.pack('V', 0) // crc32

-			.pack('V', 0) // compressed filesize

-			.pack('V', 0); // uncompressed filesize

-

-		$this->directory .=

-			"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"

-			.pack('V',0) // crc32

-			.pack('V',0) // compressed filesize

-			.pack('V',0) // uncompressed filesize

-			.pack('v', strlen($dir)) // length of pathname

-			.pack('v', 0) // extra field length

-			.pack('v', 0) // file comment length

-			.pack('v', 0) // disk number start

-			.pack('v', 0) // internal file attributes

-			.pack('V', 16) // external file attributes - 'directory' bit set

-			.pack('V', $this->offset) // relative offset of local header

-			.$dir;

-

-		$this->offset = strlen($this->zipdata);

-		$this->entries++;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Data to Zip

-	 *

-	 * Lets you add files to the archive. If the path is included

-	 * in the filename it will be placed within a directory.  Make

-	 * sure you use add_dir() first to create the folder.

-	 *

-	 * @access	public

-	 * @param	mixed

-	 * @param	string

-	 * @return	void

-	 */	

-	function add_data($filepath, $data = NULL)

-	{

-		if (is_array($filepath))

-		{

-			foreach ($filepath as $path => $data)

-			{

-				$this->_add_data($path, $data);

-			}

-		}

-		else

-		{

-			$this->_add_data($filepath, $data);

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Add Data to Zip

-	 *

-	 * @access	private

-	 * @param	string	the file name/path

-	 * @param	string	the data to be encoded

-	 * @return	void

-	 */	

-	function _add_data($filepath, $data)

-	{

-		$filepath = str_replace("\\", "/", $filepath);

-

-		$uncompressed_size = strlen($data);

-		$crc32  = crc32($data);

-

-		$gzdata = gzcompress($data);

-		$gzdata = substr($gzdata, 2, -4);

-		$compressed_size = strlen($gzdata);

-

-		$this->zipdata .=

-			"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"

-			.pack('V', $crc32)

-			.pack('V', $compressed_size)

-			.pack('V', $uncompressed_size)

-			.pack('v', strlen($filepath)) // length of filename

-			.pack('v', 0) // extra field length

-			.$filepath

-			.$gzdata; // "file data" segment

-

-		$this->directory .=

-			"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"

-			.pack('V', $crc32)

-			.pack('V', $compressed_size)

-			.pack('V', $uncompressed_size)

-			.pack('v', strlen($filepath)) // length of filename

-			.pack('v', 0) // extra field length

-			.pack('v', 0) // file comment length

-			.pack('v', 0) // disk number start

-			.pack('v', 0) // internal file attributes

-			.pack('V', 32) // external file attributes - 'archive' bit set

-			.pack('V', $this->offset) // relative offset of local header

-			.$filepath;

-

-		$this->offset = strlen($this->zipdata);

-		$this->entries++;

-		$this->file_num++;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Read the contents of a file and add it to the zip

-	 *

-	 * @access	public

-	 * @return	bool

-	 */	

-	function read_file($path, $preserve_filepath = FALSE)

-	{

-		if ( ! file_exists($path))

-		{

-			return FALSE;

-		}

-

-		if (FALSE !== ($data = file_get_contents($path)))

-		{

-			$name = str_replace("\\", "/", $path);

-			

-			if ($preserve_filepath === FALSE)

-			{

-				$name = preg_replace("|.*/(.+)|", "\\1", $name);

-			}

-

-			$this->add_data($name, $data);

-			return TRUE;

-		}

-		return FALSE;

-	}

-

-	// ------------------------------------------------------------------------

-	

-	/**

-	 * Read a directory and add it to the zip.

-	 *

-	 * This function recursively reads a folder and everything it contains (including

-	 * sub-folders) and creates a zip based on it.  Whatever directory structure

-	 * is in the original file path will be recreated in the zip file.

-	 *

-	 * @access	public

-	 * @param	string	path to source

-	 * @return	bool

-	 */	

-	function read_dir($path)

-	{	

-		if ($fp = @opendir($path))

-		{

-			while (FALSE !== ($file = readdir($fp)))

-			{

-				if (@is_dir($path.$file) && substr($file, 0, 1) != '.')

-				{					

-					$this->read_dir($path.$file."/");

-				}

-				elseif (substr($file, 0, 1) != ".")

-				{

-					if (FALSE !== ($data = file_get_contents($path.$file)))

-					{						

-						$this->add_data(str_replace("\\", "/", $path).$file, $data);

-					}

-				}

-			}

-			return TRUE;

-		}

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Get the Zip file

-	 *

-	 * @access	public

-	 * @return	binary string

-	 */	

-	function get_zip()

-	{

-		// Is there any data to return?

-		if ($this->entries == 0)

-		{

-			return FALSE;

-		}

-

-		$zip_data = $this->zipdata;

-		$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";

-		$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"

-		$zip_data .= pack('v', $this->entries); // total # of entries overall

-		$zip_data .= pack('V', strlen($this->directory)); // size of central dir

-		$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir

-		$zip_data .= "\x00\x00"; // .zip file comment length

-

-		return $zip_data;

-	}

-	

-	// --------------------------------------------------------------------

-

-	/**

-	 * Write File to the specified directory

-	 *

-	 * Lets you write a file

-	 *

-	 * @access	public

-	 * @param	string	the file name

-	 * @return	bool

-	 */	

-	function archive($filepath)

-	{

-		if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))

-		{

-			return FALSE;

-		}

-

-		flock($fp, LOCK_EX);	

-		fwrite($fp, $this->get_zip());

-		flock($fp, LOCK_UN);

-		fclose($fp);

-

-		return TRUE;	

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Download

-	 *

-	 * @access	public

-	 * @param	string	the file name

-	 * @param	string	the data to be encoded

-	 * @return	bool

-	 */

-	function download($filename = 'backup.zip')

-	{

-		if ( ! preg_match("|.+?\.zip$|", $filename))

-		{

-			$filename .= '.zip';

-		}

-

-		$zip_content =& $this->get_zip();

-

-		$CI =& get_instance();

-		$CI->load->helper('download');

-

-		force_download($filename, $zip_content);

-	}

-

-	// --------------------------------------------------------------------

-

-	/**

-	 * Initialize Data

-	 *

-	 * Lets you clear current zip data.  Useful if you need to create

-	 * multiple zips with different data.

-	 *

-	 * @access	public

-	 * @return	void

-	 */		

-	function clear_data()

-	{

-		$this->zipdata		= '';

-		$this->directory	= '';

-		$this->entries		= 0;

-		$this->file_num		= 0;

-		$this->offset		= 0;

-	}

-	

-}

-

-/* End of file Zip.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Zip Compression Class
+ *
+ * This class is based on a library I found at Zend:
+ * http://www.zend.com/codex.php?id=696&single=1
+ *
+ * The original library is a little rough around the edges so I
+ * refactored it and added several additional methods -- Rick Ellis
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Encryption
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/libraries/zip.html
+ */
+class CI_Zip  {
+
+	var $zipdata 	= '';
+	var $directory 	= '';
+	var $entries 	= 0;
+	var $file_num 	= 0;
+	var $offset		= 0;
+
+	function CI_Zip()
+	{
+		log_message('debug', "Zip Compression Class Initialized");
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Directory
+	 *
+	 * Lets you add a virtual directory into which you can place files.
+	 *
+	 * @access	public
+	 * @param	mixed	the directory name. Can be string or array
+	 * @return	void
+	 */
+	function add_dir($directory)
+	{
+		foreach ((array)$directory as $dir)
+		{
+			if ( ! preg_match("|.+/$|", $dir))
+			{
+				$dir .= '/';
+			}
+
+			$this->_add_dir($dir);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Directory
+	 *
+	 * @access	private
+	 * @param	string	the directory name
+	 * @return	void
+	 */
+	function _add_dir($dir)
+	{
+		$dir = str_replace("\\", "/", $dir);
+
+		$this->zipdata .=
+			"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+			.pack('V', 0) // crc32
+			.pack('V', 0) // compressed filesize
+			.pack('V', 0) // uncompressed filesize
+			.pack('v', strlen($dir)) // length of pathname
+			.pack('v', 0) // extra field length
+			.$dir
+			// below is "data descriptor" segment
+			.pack('V', 0) // crc32
+			.pack('V', 0) // compressed filesize
+			.pack('V', 0); // uncompressed filesize
+
+		$this->directory .=
+			"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+			.pack('V',0) // crc32
+			.pack('V',0) // compressed filesize
+			.pack('V',0) // uncompressed filesize
+			.pack('v', strlen($dir)) // length of pathname
+			.pack('v', 0) // extra field length
+			.pack('v', 0) // file comment length
+			.pack('v', 0) // disk number start
+			.pack('v', 0) // internal file attributes
+			.pack('V', 16) // external file attributes - 'directory' bit set
+			.pack('V', $this->offset) // relative offset of local header
+			.$dir;
+
+		$this->offset = strlen($this->zipdata);
+		$this->entries++;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Data to Zip
+	 *
+	 * Lets you add files to the archive. If the path is included
+	 * in the filename it will be placed within a directory.  Make
+	 * sure you use add_dir() first to create the folder.
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */	
+	function add_data($filepath, $data = NULL)
+	{
+		if (is_array($filepath))
+		{
+			foreach ($filepath as $path => $data)
+			{
+				$this->_add_data($path, $data);
+			}
+		}
+		else
+		{
+			$this->_add_data($filepath, $data);
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add Data to Zip
+	 *
+	 * @access	private
+	 * @param	string	the file name/path
+	 * @param	string	the data to be encoded
+	 * @return	void
+	 */	
+	function _add_data($filepath, $data)
+	{
+		$filepath = str_replace("\\", "/", $filepath);
+
+		$uncompressed_size = strlen($data);
+		$crc32  = crc32($data);
+
+		$gzdata = gzcompress($data);
+		$gzdata = substr($gzdata, 2, -4);
+		$compressed_size = strlen($gzdata);
+
+		$this->zipdata .=
+			"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"
+			.pack('V', $crc32)
+			.pack('V', $compressed_size)
+			.pack('V', $uncompressed_size)
+			.pack('v', strlen($filepath)) // length of filename
+			.pack('v', 0) // extra field length
+			.$filepath
+			.$gzdata; // "file data" segment
+
+		$this->directory .=
+			"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"
+			.pack('V', $crc32)
+			.pack('V', $compressed_size)
+			.pack('V', $uncompressed_size)
+			.pack('v', strlen($filepath)) // length of filename
+			.pack('v', 0) // extra field length
+			.pack('v', 0) // file comment length
+			.pack('v', 0) // disk number start
+			.pack('v', 0) // internal file attributes
+			.pack('V', 32) // external file attributes - 'archive' bit set
+			.pack('V', $this->offset) // relative offset of local header
+			.$filepath;
+
+		$this->offset = strlen($this->zipdata);
+		$this->entries++;
+		$this->file_num++;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Read the contents of a file and add it to the zip
+	 *
+	 * @access	public
+	 * @return	bool
+	 */	
+	function read_file($path, $preserve_filepath = FALSE)
+	{
+		if ( ! file_exists($path))
+		{
+			return FALSE;
+		}
+
+		if (FALSE !== ($data = file_get_contents($path)))
+		{
+			$name = str_replace("\\", "/", $path);
+			
+			if ($preserve_filepath === FALSE)
+			{
+				$name = preg_replace("|.*/(.+)|", "\\1", $name);
+			}
+
+			$this->add_data($name, $data);
+			return TRUE;
+		}
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Read a directory and add it to the zip.
+	 *
+	 * This function recursively reads a folder and everything it contains (including
+	 * sub-folders) and creates a zip based on it.  Whatever directory structure
+	 * is in the original file path will be recreated in the zip file.
+	 *
+	 * @access	public
+	 * @param	string	path to source
+	 * @return	bool
+	 */	
+	function read_dir($path)
+	{	
+		if ($fp = @opendir($path))
+		{
+			while (FALSE !== ($file = readdir($fp)))
+			{
+				if (@is_dir($path.$file) && substr($file, 0, 1) != '.')
+				{					
+					$this->read_dir($path.$file."/");
+				}
+				elseif (substr($file, 0, 1) != ".")
+				{
+					if (FALSE !== ($data = file_get_contents($path.$file)))
+					{						
+						$this->add_data(str_replace("\\", "/", $path).$file, $data);
+					}
+				}
+			}
+			return TRUE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get the Zip file
+	 *
+	 * @access	public
+	 * @return	binary string
+	 */	
+	function get_zip()
+	{
+		// Is there any data to return?
+		if ($this->entries == 0)
+		{
+			return FALSE;
+		}
+
+		$zip_data = $this->zipdata;
+		$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";
+		$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"
+		$zip_data .= pack('v', $this->entries); // total # of entries overall
+		$zip_data .= pack('V', strlen($this->directory)); // size of central dir
+		$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir
+		$zip_data .= "\x00\x00"; // .zip file comment length
+
+		return $zip_data;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Write File to the specified directory
+	 *
+	 * Lets you write a file
+	 *
+	 * @access	public
+	 * @param	string	the file name
+	 * @return	bool
+	 */	
+	function archive($filepath)
+	{
+		if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))
+		{
+			return FALSE;
+		}
+
+		flock($fp, LOCK_EX);	
+		fwrite($fp, $this->get_zip());
+		flock($fp, LOCK_UN);
+		fclose($fp);
+
+		return TRUE;	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Download
+	 *
+	 * @access	public
+	 * @param	string	the file name
+	 * @param	string	the data to be encoded
+	 * @return	bool
+	 */
+	function download($filename = 'backup.zip')
+	{
+		if ( ! preg_match("|.+?\.zip$|", $filename))
+		{
+			$filename .= '.zip';
+		}
+
+		$zip_content =& $this->get_zip();
+
+		$CI =& get_instance();
+		$CI->load->helper('download');
+
+		force_download($filename, $zip_content);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Initialize Data
+	 *
+	 * Lets you clear current zip data.  Useful if you need to create
+	 * multiple zips with different data.
+	 *
+	 * @access	public
+	 * @return	void
+	 */		
+	function clear_data()
+	{
+		$this->zipdata		= '';
+		$this->directory	= '';
+		$this->entries		= 0;
+		$this->file_num		= 0;
+		$this->offset		= 0;
+	}
+	
+}
+
+/* End of file Zip.php */
 /* Location: ./system/libraries/Zip.php */
\ No newline at end of file
diff --git a/system/libraries/index.html b/system/libraries/index.html
index 065d2da..c942a79 100644
--- a/system/libraries/index.html
+++ b/system/libraries/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/logs/index.html b/system/logs/index.html
index 065d2da..c942a79 100644
--- a/system/logs/index.html
+++ b/system/logs/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/plugins/captcha_pi.php b/system/plugins/captcha_pi.php
index 0484a6f..4a09dcb 100644
--- a/system/plugins/captcha_pi.php
+++ b/system/plugins/captcha_pi.php
@@ -1,356 +1,356 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/*

-Instructions:

-

-Load the plugin using:

-

- 	$this->load->plugin('captcha');

-

-Once loaded you can generate a captcha like this:

-	

-	$vals = array(

-					'word'		 => 'Random word',

-					'img_path'	 => './captcha/',

-					'img_url'	 => 'http://example.com/captcha/',

-					'font_path'	 => './system/fonts/texb.ttf',

-					'img_width'	 => '150',

-					'img_height' => 30,

-					'expiration' => 7200

-				);

-	

-	$cap = create_captcha($vals);

-	echo $cap['image'];

-	

-

-NOTES:

-	

-	The captcha function requires the GD image library.

-	

-	Only the img_path and img_url are required.

-	

-	If a "word" is not supplied, the function will generate a random

-	ASCII string.  You might put together your own word library that

-	you can draw randomly from.

-	

-	If you do not specify a path to a TRUE TYPE font, the native ugly GD

-	font will be used.

-	

-	The "captcha" folder must be writable (666, or 777)

-	

-	The "expiration" (in seconds) signifies how long an image will

-	remain in the captcha folder before it will be deleted.  The default

-	is two hours.

-

-RETURNED DATA

-

-The create_captcha() function returns an associative array with this data:

-

-  [array]

-  (

-	'image' => IMAGE TAG

-	'time'	=> TIMESTAMP (in microtime)

-	'word'	=> CAPTCHA WORD

-  )

-

-The "image" is the actual image tag:

-<img src="http://example.com/captcha/12345.jpg" width="140" height="50" />

-

-The "time" is the micro timestamp used as the image name without the file

-extension.  It will be a number like this:  1139612155.3422

-

-The "word" is the word that appears in the captcha image, which if not

-supplied to the function, will be a random string.

-

-

-ADDING A DATABASE

-

-In order for the captcha function to prevent someone from posting, you will need

-to add the information returned from create_captcha() function to your database.

-Then, when the data from the form is submitted by the user you will need to verify

-that the data exists in the database and has not expired.

-

-Here is a table prototype:

-

-	CREATE TABLE captcha (

-	 captcha_id bigint(13) unsigned NOT NULL auto_increment,

-	 captcha_time int(10) unsigned NOT NULL,

-	 ip_address varchar(16) default '0' NOT NULL,

-	 word varchar(20) NOT NULL,

-	 PRIMARY KEY `captcha_id` (`captcha_id`),

-	 KEY `word` (`word`)

-	)

-

-

-Here is an example of usage with a DB.

-

-On the page where the captcha will be shown you'll have something like this:

-

-	$this->load->plugin('captcha');

-	$vals = array(

-					'img_path'	 => './captcha/',

-					'img_url'	 => 'http://example.com/captcha/'

-				);

-	

-	$cap = create_captcha($vals);

-

-	$data = array(

-					'captcha_id'	=> '',

-					'captcha_time'	=> $cap['time'],

-					'ip_address'	=> $this->input->ip_address(),

-					'word'			=> $cap['word']

-				);

-

-	$query = $this->db->insert_string('captcha', $data);

-	$this->db->query($query);

-		

-	echo 'Submit the word you see below:';

-	echo $cap['image'];

-	echo '<input type="text" name="captcha" value="" />';

-

-

-Then, on the page that accepts the submission you'll have something like this:

-

-	// First, delete old captchas

-	$expiration = time()-7200; // Two hour limit

-	$DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration);		

-

-	// Then see if a captcha exists:

-	$sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?";

-	$binds = array($_POST['captcha'], $this->input->ip_address(), $expiration);

-	$query = $this->db->query($sql, $binds);

-	$row = $query->row();

-

-	if ($row->count == 0)

-	{

-		echo "You must submit the word that appears in the image";

-	}

-

-*/

-

-

-	

-/**

-|==========================================================

-| Create Captcha

-|==========================================================

-|

-*/

-function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')

-{		

-	$defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);		

-	

-	foreach ($defaults as $key => $val)

-	{

-		if ( ! is_array($data))

-		{

-			if ( ! isset($$key) OR $$key == '')

-			{

-				$$key = $val;

-			}

-		}

-		else

-		{			

-			$$key = ( ! isset($data[$key])) ? $val : $data[$key];

-		}

-	}

-	

-	if ($img_path == '' OR $img_url == '')

-	{

-		return FALSE;

-	}

-

-	if ( ! @is_dir($img_path))

-	{

-		return FALSE;

-	}

-	

-	if ( ! is_really_writable($img_path))

-	{

-		return FALSE;

-	}

-			

-	if ( ! extension_loaded('gd'))

-	{

-		return FALSE;

-	}		

-	

-	// -----------------------------------

-	// Remove old images	

-	// -----------------------------------

-			

-	list($usec, $sec) = explode(" ", microtime());

-	$now = ((float)$usec + (float)$sec);

-			

-	$current_dir = @opendir($img_path);

-	

-	while($filename = @readdir($current_dir))

-	{

-		if ($filename != "." and $filename != ".." and $filename != "index.html")

-		{

-			$name = str_replace(".jpg", "", $filename);

-		

-			if (($name + $expiration) < $now)

-			{

-				@unlink($img_path.$filename);

-			}

-		}

-	}

-	

-	@closedir($current_dir);

-

-	// -----------------------------------

-	// Do we have a "word" yet?

-	// -----------------------------------

-	

-   if ($word == '')

-   {

-		$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

-

-		$str = '';

-		for ($i = 0; $i < 8; $i++)

-		{

-			$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);

-		}

-		

-		$word = $str;

-   }

-	

-	// -----------------------------------

-	// Determine angle and position	

-	// -----------------------------------

-	

-	$length	= strlen($word);

-	$angle	= ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;

-	$x_axis	= rand(6, (360/$length)-16);			

-	$y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);

-	

-	// -----------------------------------

-	// Create image

-	// -----------------------------------

-			

-	// PHP.net recommends imagecreatetruecolor(), but it isn't always available

-	if (function_exists('imagecreatetruecolor'))

-	{

-		$im = imagecreatetruecolor($img_width, $img_height);

-	}

-	else

-	{

-		$im = imagecreate($img_width, $img_height);

-	}

-			

-	// -----------------------------------

-	//  Assign colors

-	// -----------------------------------

-	

-	$bg_color		= imagecolorallocate ($im, 255, 255, 255);

-	$border_color	= imagecolorallocate ($im, 153, 102, 102);

-	$text_color		= imagecolorallocate ($im, 204, 153, 153);

-	$grid_color		= imagecolorallocate($im, 255, 182, 182);

-	$shadow_color	= imagecolorallocate($im, 255, 240, 240);

-

-	// -----------------------------------

-	//  Create the rectangle

-	// -----------------------------------

-	

-	ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);

-	

-	// -----------------------------------

-	//  Create the spiral pattern

-	// -----------------------------------

-	

-	$theta		= 1;

-	$thetac		= 7;

-	$radius		= 16;

-	$circles	= 20;

-	$points		= 32;

-

-	for ($i = 0; $i < ($circles * $points) - 1; $i++)

-	{

-		$theta = $theta + $thetac;

-		$rad = $radius * ($i / $points );

-		$x = ($rad * cos($theta)) + $x_axis;

-		$y = ($rad * sin($theta)) + $y_axis;

-		$theta = $theta + $thetac;

-		$rad1 = $radius * (($i + 1) / $points);

-		$x1 = ($rad1 * cos($theta)) + $x_axis;

-		$y1 = ($rad1 * sin($theta )) + $y_axis;

-		imageline($im, $x, $y, $x1, $y1, $grid_color);

-		$theta = $theta - $thetac;

-	}

-

-	// -----------------------------------

-	//  Write the text

-	// -----------------------------------

-	

-	$use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE;

-		

-	if ($use_font == FALSE)

-	{

-		$font_size = 5;

-		$x = rand(0, $img_width/($length/3));

-		$y = 0;

-	}

-	else

-	{

-		$font_size	= 16;

-		$x = rand(0, $img_width/($length/1.5));

-		$y = $font_size+2;

-	}

-

-	for ($i = 0; $i < strlen($word); $i++)

-	{

-		if ($use_font == FALSE)

-		{

-			$y = rand(0 , $img_height/2);

-			imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);

-			$x += ($font_size*2);

-		}

-		else

-		{		

-			$y = rand($img_height/2, $img_height-3);

-			imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));

-			$x += $font_size;

-		}

-	}

-	

-

-	// -----------------------------------

-	//  Create the border

-	// -----------------------------------

-

-	imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);		

-

-	// -----------------------------------

-	//  Generate the image

-	// -----------------------------------

-	

-	$img_name = $now.'.jpg';

-

-	ImageJPEG($im, $img_path.$img_name);

-	

-	$img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";

-	

-	ImageDestroy($im);

-		

-	return array('word' => $word, 'time' => $now, 'image' => $img);

-}

-

-

-/* End of file captcha_pi.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/*
+Instructions:
+
+Load the plugin using:
+
+ 	$this->load->plugin('captcha');
+
+Once loaded you can generate a captcha like this:
+	
+	$vals = array(
+					'word'		 => 'Random word',
+					'img_path'	 => './captcha/',
+					'img_url'	 => 'http://example.com/captcha/',
+					'font_path'	 => './system/fonts/texb.ttf',
+					'img_width'	 => '150',
+					'img_height' => 30,
+					'expiration' => 7200
+				);
+	
+	$cap = create_captcha($vals);
+	echo $cap['image'];
+	
+
+NOTES:
+	
+	The captcha function requires the GD image library.
+	
+	Only the img_path and img_url are required.
+	
+	If a "word" is not supplied, the function will generate a random
+	ASCII string.  You might put together your own word library that
+	you can draw randomly from.
+	
+	If you do not specify a path to a TRUE TYPE font, the native ugly GD
+	font will be used.
+	
+	The "captcha" folder must be writable (666, or 777)
+	
+	The "expiration" (in seconds) signifies how long an image will
+	remain in the captcha folder before it will be deleted.  The default
+	is two hours.
+
+RETURNED DATA
+
+The create_captcha() function returns an associative array with this data:
+
+  [array]
+  (
+	'image' => IMAGE TAG
+	'time'	=> TIMESTAMP (in microtime)
+	'word'	=> CAPTCHA WORD
+  )
+
+The "image" is the actual image tag:
+<img src="http://example.com/captcha/12345.jpg" width="140" height="50" />
+
+The "time" is the micro timestamp used as the image name without the file
+extension.  It will be a number like this:  1139612155.3422
+
+The "word" is the word that appears in the captcha image, which if not
+supplied to the function, will be a random string.
+
+
+ADDING A DATABASE
+
+In order for the captcha function to prevent someone from posting, you will need
+to add the information returned from create_captcha() function to your database.
+Then, when the data from the form is submitted by the user you will need to verify
+that the data exists in the database and has not expired.
+
+Here is a table prototype:
+
+	CREATE TABLE captcha (
+	 captcha_id bigint(13) unsigned NOT NULL auto_increment,
+	 captcha_time int(10) unsigned NOT NULL,
+	 ip_address varchar(16) default '0' NOT NULL,
+	 word varchar(20) NOT NULL,
+	 PRIMARY KEY `captcha_id` (`captcha_id`),
+	 KEY `word` (`word`)
+	)
+
+
+Here is an example of usage with a DB.
+
+On the page where the captcha will be shown you'll have something like this:
+
+	$this->load->plugin('captcha');
+	$vals = array(
+					'img_path'	 => './captcha/',
+					'img_url'	 => 'http://example.com/captcha/'
+				);
+	
+	$cap = create_captcha($vals);
+
+	$data = array(
+					'captcha_id'	=> '',
+					'captcha_time'	=> $cap['time'],
+					'ip_address'	=> $this->input->ip_address(),
+					'word'			=> $cap['word']
+				);
+
+	$query = $this->db->insert_string('captcha', $data);
+	$this->db->query($query);
+		
+	echo 'Submit the word you see below:';
+	echo $cap['image'];
+	echo '<input type="text" name="captcha" value="" />';
+
+
+Then, on the page that accepts the submission you'll have something like this:
+
+	// First, delete old captchas
+	$expiration = time()-7200; // Two hour limit
+	$DB->query("DELETE FROM captcha WHERE captcha_time < ".$expiration);		
+
+	// Then see if a captcha exists:
+	$sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip_address = ? AND date > ?";
+	$binds = array($_POST['captcha'], $this->input->ip_address(), $expiration);
+	$query = $this->db->query($sql, $binds);
+	$row = $query->row();
+
+	if ($row->count == 0)
+	{
+		echo "You must submit the word that appears in the image";
+	}
+
+*/
+
+
+	
+/**
+|==========================================================
+| Create Captcha
+|==========================================================
+|
+*/
+function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
+{		
+	$defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);		
+	
+	foreach ($defaults as $key => $val)
+	{
+		if ( ! is_array($data))
+		{
+			if ( ! isset($$key) OR $$key == '')
+			{
+				$$key = $val;
+			}
+		}
+		else
+		{			
+			$$key = ( ! isset($data[$key])) ? $val : $data[$key];
+		}
+	}
+	
+	if ($img_path == '' OR $img_url == '')
+	{
+		return FALSE;
+	}
+
+	if ( ! @is_dir($img_path))
+	{
+		return FALSE;
+	}
+	
+	if ( ! is_really_writable($img_path))
+	{
+		return FALSE;
+	}
+			
+	if ( ! extension_loaded('gd'))
+	{
+		return FALSE;
+	}		
+	
+	// -----------------------------------
+	// Remove old images	
+	// -----------------------------------
+			
+	list($usec, $sec) = explode(" ", microtime());
+	$now = ((float)$usec + (float)$sec);
+			
+	$current_dir = @opendir($img_path);
+	
+	while($filename = @readdir($current_dir))
+	{
+		if ($filename != "." and $filename != ".." and $filename != "index.html")
+		{
+			$name = str_replace(".jpg", "", $filename);
+		
+			if (($name + $expiration) < $now)
+			{
+				@unlink($img_path.$filename);
+			}
+		}
+	}
+	
+	@closedir($current_dir);
+
+	// -----------------------------------
+	// Do we have a "word" yet?
+	// -----------------------------------
+	
+   if ($word == '')
+   {
+		$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+		$str = '';
+		for ($i = 0; $i < 8; $i++)
+		{
+			$str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+		}
+		
+		$word = $str;
+   }
+	
+	// -----------------------------------
+	// Determine angle and position	
+	// -----------------------------------
+	
+	$length	= strlen($word);
+	$angle	= ($length >= 6) ? rand(-($length-6), ($length-6)) : 0;
+	$x_axis	= rand(6, (360/$length)-16);			
+	$y_axis = ($angle >= 0 ) ? rand($img_height, $img_width) : rand(6, $img_height);
+	
+	// -----------------------------------
+	// Create image
+	// -----------------------------------
+			
+	// PHP.net recommends imagecreatetruecolor(), but it isn't always available
+	if (function_exists('imagecreatetruecolor'))
+	{
+		$im = imagecreatetruecolor($img_width, $img_height);
+	}
+	else
+	{
+		$im = imagecreate($img_width, $img_height);
+	}
+			
+	// -----------------------------------
+	//  Assign colors
+	// -----------------------------------
+	
+	$bg_color		= imagecolorallocate ($im, 255, 255, 255);
+	$border_color	= imagecolorallocate ($im, 153, 102, 102);
+	$text_color		= imagecolorallocate ($im, 204, 153, 153);
+	$grid_color		= imagecolorallocate($im, 255, 182, 182);
+	$shadow_color	= imagecolorallocate($im, 255, 240, 240);
+
+	// -----------------------------------
+	//  Create the rectangle
+	// -----------------------------------
+	
+	ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $bg_color);
+	
+	// -----------------------------------
+	//  Create the spiral pattern
+	// -----------------------------------
+	
+	$theta		= 1;
+	$thetac		= 7;
+	$radius		= 16;
+	$circles	= 20;
+	$points		= 32;
+
+	for ($i = 0; $i < ($circles * $points) - 1; $i++)
+	{
+		$theta = $theta + $thetac;
+		$rad = $radius * ($i / $points );
+		$x = ($rad * cos($theta)) + $x_axis;
+		$y = ($rad * sin($theta)) + $y_axis;
+		$theta = $theta + $thetac;
+		$rad1 = $radius * (($i + 1) / $points);
+		$x1 = ($rad1 * cos($theta)) + $x_axis;
+		$y1 = ($rad1 * sin($theta )) + $y_axis;
+		imageline($im, $x, $y, $x1, $y1, $grid_color);
+		$theta = $theta - $thetac;
+	}
+
+	// -----------------------------------
+	//  Write the text
+	// -----------------------------------
+	
+	$use_font = ($font_path != '' AND file_exists($font_path) AND function_exists('imagettftext')) ? TRUE : FALSE;
+		
+	if ($use_font == FALSE)
+	{
+		$font_size = 5;
+		$x = rand(0, $img_width/($length/3));
+		$y = 0;
+	}
+	else
+	{
+		$font_size	= 16;
+		$x = rand(0, $img_width/($length/1.5));
+		$y = $font_size+2;
+	}
+
+	for ($i = 0; $i < strlen($word); $i++)
+	{
+		if ($use_font == FALSE)
+		{
+			$y = rand(0 , $img_height/2);
+			imagestring($im, $font_size, $x, $y, substr($word, $i, 1), $text_color);
+			$x += ($font_size*2);
+		}
+		else
+		{		
+			$y = rand($img_height/2, $img_height-3);
+			imagettftext($im, $font_size, $angle, $x, $y, $text_color, $font_path, substr($word, $i, 1));
+			$x += $font_size;
+		}
+	}
+	
+
+	// -----------------------------------
+	//  Create the border
+	// -----------------------------------
+
+	imagerectangle($im, 0, 0, $img_width-1, $img_height-1, $border_color);		
+
+	// -----------------------------------
+	//  Generate the image
+	// -----------------------------------
+	
+	$img_name = $now.'.jpg';
+
+	ImageJPEG($im, $img_path.$img_name);
+	
+	$img = "<img src=\"$img_url$img_name\" width=\"$img_width\" height=\"$img_height\" style=\"border:0;\" alt=\" \" />";
+	
+	ImageDestroy($im);
+		
+	return array('word' => $word, 'time' => $now, 'image' => $img);
+}
+
+
+/* End of file captcha_pi.php */
 /* Location: ./system/plugins/captcha_pi.php */
\ No newline at end of file
diff --git a/system/plugins/index.html b/system/plugins/index.html
index 065d2da..c942a79 100644
--- a/system/plugins/index.html
+++ b/system/plugins/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/plugins/js_calendar_pi.php b/system/plugins/js_calendar_pi.php
index e165c54..6dadd4a 100644
--- a/system/plugins/js_calendar_pi.php
+++ b/system/plugins/js_calendar_pi.php
@@ -1,629 +1,629 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/*

-Instructions:

-

-Load the plugin using:

-

- 	$this->load->plugin('js_calendar');

-

-Once loaded you'll add the calendar script to the <head> of your page like this:

-

-<?php echo js_calendar_script('my_form');  ?>

-

-The above function will be passed the name of your form.

-

-Then to show the actual calendar you'll do this:

-

-<?php echo js_calendar_write('entry_date', time(), true);?>

-<form name="my_form">

-<input type="text" name="entry_date" value="" onblur="update_calendar(this.name, this.value);" />

-<p><a href="javascript:void(0);" onClick="set_to_time('entry_date', '<?php echo time();?>')" >Today</a></p>

-</form>

-

-

-Note:  The first parameter is the name of the field containing your date, the second parameter contains the "now" time,

-and the third tells the calendar whether to highlight the current day or not.

-

-Lastly, you'll need some CSS for your calendar:

-

-.calendar {

-	border: 1px #6975A3 solid;

-	background-color: transparent;

-}

-.calheading {

-	background-color: #7C8BC0;

-	color: #fff;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 11px;

-	font-weight: bold;

-	text-align: center;

-}

-.calnavleft {

-	background-color: #7C8BC0;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 10px;

-	font-weight: bold;

-	color: #fff;

-	padding: 4px;

-	cursor: pointer;

-}

-.calnavright {

-	background-color: #7C8BC0;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 10px;

-	font-weight: bold;

-	color: #fff;

-	text-align:  right;

-	padding: 4px;

-	cursor: pointer;

-}

-.caldayheading {

-	background-color: #000;

-	color: #fff;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 10px;

-	text-align: center;

-	padding: 6px 2px 6px 2px;

-}

-.caldaycells{

-	color: #000;

-	background-color: #D1D7E6;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 11px;

-	text-align: center;

-	padding: 4px;

-	border: 1px #E0E5F1 solid;

-	cursor: pointer;

-}

-.caldaycellhover{

-	color: #fff;

-	background-color: #B3BCD4;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 11px;

-	text-align: center;

-	padding: 4px;

-	border: 1px #B3BCD4 solid;

-	cursor: pointer;

-}

-.caldayselected{

-	background-color: #737FAC;

-	color:	#fff;

-	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

-	font-size: 11px;

-	font-weight: bold;

-	text-align: center;

-	border: 1px #566188 solid;

-	padding: 3px;

-	cursor: pointer;

-}

-.calblanktop {

-	background-color: #fff;

-	padding: 4px;

-}

-.calblankbot {

-	background-color: #fff;

-	padding: 4px;

-}

-

-

-*/

-

-function js_calendar_script($form_name = 'entryform')

-{		

-$CI =& get_instance();

-$CI->load->language('calendar');

-ob_start();

-?>

-<script type="text/javascript">

-<!--

-var form_name	= "<?php echo $form_name; ?>";

-var format		= 'us'; // eu or us

-var days		= new Array(

-					'<?php echo $CI->lang->line('cal_su');?>', // Sunday, short name

-					'<?php echo $CI->lang->line('cal_mo');?>', // Monday, short name

-					'<?php echo $CI->lang->line('cal_tu');?>', // Tuesday, short name

-					'<?php echo $CI->lang->line('cal_wed');?>', // Wednesday, short name

-					'<?php echo $CI->lang->line('cal_thu');?>', // Thursday, short name

-					'<?php echo $CI->lang->line('cal_fri');?>', // Friday, short name

-					'<?php echo $CI->lang->line('cal_sat');?>' // Saturday, short name

-				);

-var months		= new Array(

-					'<?php echo $CI->lang->line('cal_january');?>',

-					'<?php echo $CI->lang->line('cal_february');?>',

-					'<?php echo $CI->lang->line('cal_march');?>',

-					'<?php echo $CI->lang->line('cal_april');?>',

-					'<?php echo $CI->lang->line('cal_mayl');?>',

-					'<?php echo $CI->lang->line('cal_june');?>',

-					'<?php echo $CI->lang->line('cal_july');?>',

-					'<?php echo $CI->lang->line('cal_august');?>',

-					'<?php echo $CI->lang->line('cal_september');?>',

-					'<?php echo $CI->lang->line('cal_october');?>',

-					'<?php echo $CI->lang->line('cal_november');?>',

-					'<?php echo $CI->lang->line('cal_december');?>'

-				);

-var last_click	= new Array();

-var current_month  = '';

-var current_year   = '';

-var last_date  = '';

-	

-function calendar(id, d, highlight, adjusted)

-{		

-	if (adjusted == undefined)

-	{	

-		var d = new Date(d * 1000);

-	}

-

-	this.id			= id;

-	this.highlight	= highlight;

-	this.date_obj	= d;

-	this.write		= build_calendar;

-	this.total_days	= total_days;

-	this.month		= d.getMonth();

-	this.date		= d.getDate();

-	this.day		= d.getDay();

-	this.year		= d.getFullYear();

-	this.hours		= d.getHours();

-	this.minutes	= d.getMinutes();

-	this.seconds	= d.getSeconds();

-	this.date_str	= date_str;

-				

-	if (highlight == false)

-	{

-		this.selected_date = '';

-	}

-	else

-	{

-		this.selected_date = this.year + '' + this.month + '' + this.date;

-	}

-			

-	//	Set the "selected date"

-	d.setDate(1);

-	this.firstDay = d.getDay();

-	

-	//then reset the date object to the correct date

-	d.setDate(this.date);

-}

-		

-//	Build the body of the calendar

-function build_calendar()

-{

-	var str = '';

-	

-	//	Calendar Heading

-	

-	str += '<div id="cal' + this.id + '">';

-	str += '<table class="calendar" cellspacing="0" cellpadding="0" border="0" >';

-	str += '<tr>';

-	str += '<td class="calnavleft" onClick="change_month(-1, \'' + this.id + '\')">&lt;&lt;<\/td>';

-	str += '<td colspan="5" class="calheading">' + months[this.month] + ' ' + this.year + '<\/td>';

-	str += '<td class="calnavright" onClick="change_month(1, \'' + this.id + '\')">&gt;&gt;<\/td>';

-	str += '<\/tr>';

-	

-	//	Day Names

-	

-	str += '<tr>';

-	

-	for (i = 0; i < 7; i++)

-	{

-		str += '<td class="caldayheading">' + days[i] + '<\/td>';

-	}

-	

-	str += '<\/tr>';

-	

-	//	Day Cells

-		

-	str += '<tr>';

-	

-	selDate = (last_date != '') ? last_date : this.date;

-	

-	for (j = 0; j < 42; j++)

-	{

-		var displayNum = (j - this.firstDay + 1);

-		

-		if (j < this.firstDay) // leading empty cells

-		{

-			str += '<td class="calblanktop">&nbsp;<\/td>';

-		}

-		else if (displayNum == selDate && this.highlight == true) // Selected date

-		{

-			str += '<td id="' + this.id +'selected" class="caldayselected" onClick="set_date(this,\'' + this.id + '\')">' + displayNum + '<\/td>';

-		}

-		else if (displayNum > this.total_days())

-		{

-			str += '<td class="calblankbot">&nbsp;<\/td>'; // trailing empty cells

-		}

-		else  // Unselected days

-		{

-			str += '<td id="" class="caldaycells" onClick="set_date(this,\'' + this.id + '\'); return false;"  onMouseOver="javascript:cell_highlight(this,\'' + displayNum + '\',\'' + this.id + '\');" onMouseOut="javascript:cell_reset(this,\'' + displayNum + '\',\'' + this.id + '\');" >' + displayNum + '<\/td>';

-		}

-		

-		if (j % 7 == 6)

-		{

-			str += '<\/tr><tr>';

-		}

-	}

-

-	str += '<\/tr>';	

-	str += '<\/table>';

-	str += '<\/div>';

-	

-	return str;

-}

-

-//	Total number of days in a month

-function total_days()

-{	

-	switch(this.month)

-	{

-		case 1: // Check for leap year

-			if ((  this.date_obj.getFullYear() % 4 == 0

-				&& this.date_obj.getFullYear() % 100 != 0)

-				|| this.date_obj.getFullYear() % 400 == 0)

-				return 29;

-			else

-				return 28;

-		case 3:

-			return 30;

-		case 5:

-			return 30;

-		case 8:

-			return 30;

-		case 10:

-			return 30

-		default:

-			return 31;

-	}

-}

-

-//	Highlight Cell on Mouseover

-function cell_highlight(td, num, cal)

-{

-	cal = eval(cal);

-

-	if (last_click[cal.id]  != num)

-	{

-		td.className = "caldaycellhover";

-	}

-}		

-

-//	Reset Cell on MouseOut

-function cell_reset(td, num, cal)

-{	

-	cal = eval(cal);

-

-	if (last_click[cal.id] == num)

-	{

-		td.className = "caldayselected";

-	}

-	else

-	{

-		td.className = "caldaycells";

-	}

-}		

-

-//	Clear Field

-function clear_field(id)

-{				

-	eval("document." + form_name + "." + id + ".value = ''");

-	

-	document.getElementById(id + "selected").className = "caldaycells";

-	document.getElementById(id + "selected").id = "";	

-	

-	cal = eval(id);

-	cal.selected_date = '';		

-}		

-

-

-//	Set date to specified time

-function set_to_time(id, raw)

-{			

-	if (document.getElementById(id + "selected"))

-	{			

-		document.getElementById(id + "selected").className = "caldaycells";

-		document.getElementById(id + "selected").id = "";	

-	}

-	

-	document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';				

-		

-	var nowDate = new Date();

-	nowDate.setTime = raw * 1000;

-	

-	current_month	= nowDate.getMonth();

-	current_year	= nowDate.getFullYear();

-	current_date	= nowDate.getDate();

-	

-	oldcal = eval(id);

-	oldcal.selected_date = current_year + '' + current_month + '' + current_date;				

-

-	cal = new calendar(id, nowDate, true, true);		

-	cal.selected_date = current_year + '' + current_month + '' + current_date;	

-	

-	last_date = cal.date;

-	

-	document.getElementById('tempcal'+id).innerHTML = cal.write();	

-	

-	insert_date(cal);

-}

-

-//	Set date to what is in the field

-var lastDates = new Array();

-

-function update_calendar(id, dateValue)

-{

-	if (lastDates[id] == dateValue) return;

-	

-	lastDates[id] = dateValue;

-	

-	var fieldString = dateValue.replace(/\s+/g, ' ');

-	

-	while (fieldString.substring(0,1) == ' ')

-	{

-		fieldString = fieldString.substring(1, fieldString.length);

-	}

-	

-	var dateString = fieldString.split(' ');

-	var dateParts = dateString[0].split('-')

-

-	if (dateParts.length < 3) return;

-	var newYear  = dateParts[0];

-	var newMonth = dateParts[1];

-	var newDay   = dateParts[2];

-	

-	if (isNaN(newDay)  || newDay < 1 || (newDay.length != 1 && newDay.length != 2)) return;

-	if (isNaN(newYear) || newYear < 1 || newYear.length != 4) return;

-	if (isNaN(newMonth) || newMonth < 1 || (newMonth.length != 1 && newMonth.length != 2)) return;

-	

-	if (newMonth > 12) newMonth = 12;

-	

-	if (newDay > 28)

-	{

-		switch(newMonth - 1)

-		{

-			case 1: // Check for leap year

-				if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)

-				{

-					if (newDay > 29) newDay = 29;

-				}

-				else

-				{

-					if (newDay > 28) newDay = 28;

-				}

-			case 3:

-				if (newDay > 30) newDay = 30;

-			case 5:

-				if (newDay > 30) newDay = 30;

-			case 8:

-				if (newDay > 30) newDay = 30;

-			case 10:

-				if (newDay > 30) newDay = 30;

-			default:

-				if (newDay > 31) newDay = 31;

-		}

-	}

-	

-	if (document.getElementById(id + "selected"))

-	{			

-		document.getElementById(id + "selected").className = "caldaycells";

-		document.getElementById(id + "selected").id = "";	

-	}

-	

-	document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';				

-		

-	var nowDate = new Date();

-	nowDate.setDate(newDay);

-	nowDate.setMonth(newMonth - 1);

-	nowDate.setYear(newYear);

-	nowDate.setHours(12);

-	

-	current_month	= nowDate.getMonth();

-	current_year	= nowDate.getFullYear();

-

-	cal = new calendar(id, nowDate, true, true);						

-	document.getElementById('tempcal'+id).innerHTML = cal.write();	

-}

-

-//	Set the date

-function set_date(td, cal)

-{					

-

-	cal = eval(cal);

-	

-	// If the user is clicking a cell that is already

-	// selected we'll de-select it and clear the form field

-	

-	if (last_click[cal.id] == td.firstChild.nodeValue)

-	{

-		td.className = "caldaycells";

-		last_click[cal.id] = '';

-		remove_date(cal);

-		cal.selected_date =  '';

-		return;

-	}

-				

-	// Onward!

-	if (document.getElementById(cal.id + "selected"))

-	{

-		document.getElementById(cal.id + "selected").className = "caldaycells";

-		document.getElementById(cal.id + "selected").id = "";

-	}

-									

-	td.className = "caldayselected";

-	td.id = cal.id + "selected";

-

-	cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;			

-	cal.date_obj.setDate(td.firstChild.nodeValue);

-	cal = new calendar(cal.id, cal.date_obj, true, true);

-	cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;			

-	

-	last_date = cal.date;

-

-	//cal.date

-	last_click[cal.id] = cal.date;

-				

-	// Insert the date into the form

-	insert_date(cal);

-}

-/*

-//	Insert the date into the form field

-function insert_date(cal)

-{

-	cal = eval(cal);

-	fval = eval("document." + form_name + "." + cal.id);	

-	

-	if (fval.value == '')

-	{

-		fval.value = cal.date_str('y');

-	}

-	else

-	{

-		time = fval.value.substring(10);

-		new_date = cal.date_str('n') + time;

-		fval.value = new_date;

-	}	

-}

-*/		

-//	Remove the date from the form field

-function remove_date(cal)

-{

-	cal = eval(cal);

-	fval = eval("document." + form_name + "." + cal.id);	

-	fval.value = '';

-}

-

-//	Change to a new month

-function change_month(mo, cal)

-{		

-	cal = eval(cal);

-

-	if (current_month != '')

-	{

-		cal.date_obj.setMonth(current_month);

-		cal.date_obj.setYear(current_year);

-	

-		current_month	= '';

-		current_year	= '';

-	}

-				

-	var newMonth = cal.date_obj.getMonth() + mo;

-	var newDate  = cal.date_obj.getDate();

-	

-	if (newMonth == 12)

-	{

-		cal.date_obj.setYear(cal.date_obj.getFullYear() + 1)

-		newMonth = 0;

-	}

-	else if (newMonth == -1)

-	{

-		cal.date_obj.setYear(cal.date_obj.getFullYear() - 1)

-		newMonth = 11;

-	}

-	

-	if (newDate > 28)

-	{

-		var newYear = cal.date_obj.getFullYear();

-		

-		switch(newMonth)

-		{

-			case 1: // Check for leap year

-				if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)

-				{

-					if (newDate > 29) newDate = 29;

-				}

-				else

-				{

-					if (newDate > 28) newDate = 28;

-				}

-			case 3:

-				if (newDate > 30) newDate = 30;

-			case 5:

-				if (newDate > 30) newDate = 30;

-			case 8:

-				if (newDate > 30) newDate = 30;

-			case 10:

-				if (newDate > 30) newDate = 30;

-			default:

-				if (newDate > 31) newDate = 31;

-		}

-	}

-	

-	cal.date_obj.setDate(newDate);

-	cal.date_obj.setMonth(newMonth);

-	new_mdy	= cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;

-	

-	highlight = (cal.selected_date == new_mdy) ? true : false;			

-	cal = new calendar(cal.id, cal.date_obj, highlight, true); 			

-	document.getElementById('cal' + cal.id).innerHTML = cal.write();	

-}

-

-//	Finalize the date string

-function date_str(time)

-{

-	var month = this.month + 1;

-	if (month < 10)

-		month = '0' + month;

-		

-	var day		= (this.date  < 10) 	?  '0' + this.date		: this.date;

-	var minutes	= (this.minutes  < 10)	?  '0' + this.minutes	: this.minutes;

-		

-	if (format == 'us')

-	{

-		var hours	= (this.hours > 12) ? this.hours - 12 : this.hours;

-		var ampm	= (this.hours > 11) ? 'PM' : 'AM'

-	}

-	else

-	{

-		var hours	= this.hours;

-		var ampm	= '';

-	}

-	

-	if (time == 'y')

-	{

-		return this.year + '-' + month + '-' + day + '  ' + hours + ':' + minutes + ' ' + ampm;		

-	}

-	else

-	{

-		return this.year + '-' + month + '-' + day;

-	}

-}

-

-//-->

-</script>

-<?php

-

-$r = ob_get_contents();

-ob_end_clean();

-return $r;

-}

-

-

-function js_calendar_write($field_id, $time = '', $highlight = TRUE)

-{

-	if ($time == '')

-		$time = time();

-

-	return

-	'<script type="text/javascript">

-		var '.$field_id.' = new calendar("'.$field_id.'", '.$time.', '.(($highlight == TRUE) ? 'true' : 'false').');

-		document.write('.$field_id.'.write());

-	</script>';	

-}	

-

-

-/* End of file js_calendar_pi.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/*
+Instructions:
+
+Load the plugin using:
+
+ 	$this->load->plugin('js_calendar');
+
+Once loaded you'll add the calendar script to the <head> of your page like this:
+
+<?php echo js_calendar_script('my_form');  ?>
+
+The above function will be passed the name of your form.
+
+Then to show the actual calendar you'll do this:
+
+<?php echo js_calendar_write('entry_date', time(), true);?>
+<form name="my_form">
+<input type="text" name="entry_date" value="" onblur="update_calendar(this.name, this.value);" />
+<p><a href="javascript:void(0);" onClick="set_to_time('entry_date', '<?php echo time();?>')" >Today</a></p>
+</form>
+
+
+Note:  The first parameter is the name of the field containing your date, the second parameter contains the "now" time,
+and the third tells the calendar whether to highlight the current day or not.
+
+Lastly, you'll need some CSS for your calendar:
+
+.calendar {
+	border: 1px #6975A3 solid;
+	background-color: transparent;
+}
+.calheading {
+	background-color: #7C8BC0;
+	color: #fff;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 11px;
+	font-weight: bold;
+	text-align: center;
+}
+.calnavleft {
+	background-color: #7C8BC0;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 10px;
+	font-weight: bold;
+	color: #fff;
+	padding: 4px;
+	cursor: pointer;
+}
+.calnavright {
+	background-color: #7C8BC0;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 10px;
+	font-weight: bold;
+	color: #fff;
+	text-align:  right;
+	padding: 4px;
+	cursor: pointer;
+}
+.caldayheading {
+	background-color: #000;
+	color: #fff;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 10px;
+	text-align: center;
+	padding: 6px 2px 6px 2px;
+}
+.caldaycells{
+	color: #000;
+	background-color: #D1D7E6;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 11px;
+	text-align: center;
+	padding: 4px;
+	border: 1px #E0E5F1 solid;
+	cursor: pointer;
+}
+.caldaycellhover{
+	color: #fff;
+	background-color: #B3BCD4;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 11px;
+	text-align: center;
+	padding: 4px;
+	border: 1px #B3BCD4 solid;
+	cursor: pointer;
+}
+.caldayselected{
+	background-color: #737FAC;
+	color:	#fff;
+	font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+	font-size: 11px;
+	font-weight: bold;
+	text-align: center;
+	border: 1px #566188 solid;
+	padding: 3px;
+	cursor: pointer;
+}
+.calblanktop {
+	background-color: #fff;
+	padding: 4px;
+}
+.calblankbot {
+	background-color: #fff;
+	padding: 4px;
+}
+
+
+*/
+
+function js_calendar_script($form_name = 'entryform')
+{		
+$CI =& get_instance();
+$CI->load->language('calendar');
+ob_start();
+?>
+<script type="text/javascript">
+<!--
+var form_name	= "<?php echo $form_name; ?>";
+var format		= 'us'; // eu or us
+var days		= new Array(
+					'<?php echo $CI->lang->line('cal_su');?>', // Sunday, short name
+					'<?php echo $CI->lang->line('cal_mo');?>', // Monday, short name
+					'<?php echo $CI->lang->line('cal_tu');?>', // Tuesday, short name
+					'<?php echo $CI->lang->line('cal_wed');?>', // Wednesday, short name
+					'<?php echo $CI->lang->line('cal_thu');?>', // Thursday, short name
+					'<?php echo $CI->lang->line('cal_fri');?>', // Friday, short name
+					'<?php echo $CI->lang->line('cal_sat');?>' // Saturday, short name
+				);
+var months		= new Array(
+					'<?php echo $CI->lang->line('cal_january');?>',
+					'<?php echo $CI->lang->line('cal_february');?>',
+					'<?php echo $CI->lang->line('cal_march');?>',
+					'<?php echo $CI->lang->line('cal_april');?>',
+					'<?php echo $CI->lang->line('cal_mayl');?>',
+					'<?php echo $CI->lang->line('cal_june');?>',
+					'<?php echo $CI->lang->line('cal_july');?>',
+					'<?php echo $CI->lang->line('cal_august');?>',
+					'<?php echo $CI->lang->line('cal_september');?>',
+					'<?php echo $CI->lang->line('cal_october');?>',
+					'<?php echo $CI->lang->line('cal_november');?>',
+					'<?php echo $CI->lang->line('cal_december');?>'
+				);
+var last_click	= new Array();
+var current_month  = '';
+var current_year   = '';
+var last_date  = '';
+	
+function calendar(id, d, highlight, adjusted)
+{		
+	if (adjusted == undefined)
+	{	
+		var d = new Date(d * 1000);
+	}
+
+	this.id			= id;
+	this.highlight	= highlight;
+	this.date_obj	= d;
+	this.write		= build_calendar;
+	this.total_days	= total_days;
+	this.month		= d.getMonth();
+	this.date		= d.getDate();
+	this.day		= d.getDay();
+	this.year		= d.getFullYear();
+	this.hours		= d.getHours();
+	this.minutes	= d.getMinutes();
+	this.seconds	= d.getSeconds();
+	this.date_str	= date_str;
+				
+	if (highlight == false)
+	{
+		this.selected_date = '';
+	}
+	else
+	{
+		this.selected_date = this.year + '' + this.month + '' + this.date;
+	}
+			
+	//	Set the "selected date"
+	d.setDate(1);
+	this.firstDay = d.getDay();
+	
+	//then reset the date object to the correct date
+	d.setDate(this.date);
+}
+		
+//	Build the body of the calendar
+function build_calendar()
+{
+	var str = '';
+	
+	//	Calendar Heading
+	
+	str += '<div id="cal' + this.id + '">';
+	str += '<table class="calendar" cellspacing="0" cellpadding="0" border="0" >';
+	str += '<tr>';
+	str += '<td class="calnavleft" onClick="change_month(-1, \'' + this.id + '\')">&lt;&lt;<\/td>';
+	str += '<td colspan="5" class="calheading">' + months[this.month] + ' ' + this.year + '<\/td>';
+	str += '<td class="calnavright" onClick="change_month(1, \'' + this.id + '\')">&gt;&gt;<\/td>';
+	str += '<\/tr>';
+	
+	//	Day Names
+	
+	str += '<tr>';
+	
+	for (i = 0; i < 7; i++)
+	{
+		str += '<td class="caldayheading">' + days[i] + '<\/td>';
+	}
+	
+	str += '<\/tr>';
+	
+	//	Day Cells
+		
+	str += '<tr>';
+	
+	selDate = (last_date != '') ? last_date : this.date;
+	
+	for (j = 0; j < 42; j++)
+	{
+		var displayNum = (j - this.firstDay + 1);
+		
+		if (j < this.firstDay) // leading empty cells
+		{
+			str += '<td class="calblanktop">&nbsp;<\/td>';
+		}
+		else if (displayNum == selDate && this.highlight == true) // Selected date
+		{
+			str += '<td id="' + this.id +'selected" class="caldayselected" onClick="set_date(this,\'' + this.id + '\')">' + displayNum + '<\/td>';
+		}
+		else if (displayNum > this.total_days())
+		{
+			str += '<td class="calblankbot">&nbsp;<\/td>'; // trailing empty cells
+		}
+		else  // Unselected days
+		{
+			str += '<td id="" class="caldaycells" onClick="set_date(this,\'' + this.id + '\'); return false;"  onMouseOver="javascript:cell_highlight(this,\'' + displayNum + '\',\'' + this.id + '\');" onMouseOut="javascript:cell_reset(this,\'' + displayNum + '\',\'' + this.id + '\');" >' + displayNum + '<\/td>';
+		}
+		
+		if (j % 7 == 6)
+		{
+			str += '<\/tr><tr>';
+		}
+	}
+
+	str += '<\/tr>';	
+	str += '<\/table>';
+	str += '<\/div>';
+	
+	return str;
+}
+
+//	Total number of days in a month
+function total_days()
+{	
+	switch(this.month)
+	{
+		case 1: // Check for leap year
+			if ((  this.date_obj.getFullYear() % 4 == 0
+				&& this.date_obj.getFullYear() % 100 != 0)
+				|| this.date_obj.getFullYear() % 400 == 0)
+				return 29;
+			else
+				return 28;
+		case 3:
+			return 30;
+		case 5:
+			return 30;
+		case 8:
+			return 30;
+		case 10:
+			return 30
+		default:
+			return 31;
+	}
+}
+
+//	Highlight Cell on Mouseover
+function cell_highlight(td, num, cal)
+{
+	cal = eval(cal);
+
+	if (last_click[cal.id]  != num)
+	{
+		td.className = "caldaycellhover";
+	}
+}		
+
+//	Reset Cell on MouseOut
+function cell_reset(td, num, cal)
+{	
+	cal = eval(cal);
+
+	if (last_click[cal.id] == num)
+	{
+		td.className = "caldayselected";
+	}
+	else
+	{
+		td.className = "caldaycells";
+	}
+}		
+
+//	Clear Field
+function clear_field(id)
+{				
+	eval("document." + form_name + "." + id + ".value = ''");
+	
+	document.getElementById(id + "selected").className = "caldaycells";
+	document.getElementById(id + "selected").id = "";	
+	
+	cal = eval(id);
+	cal.selected_date = '';		
+}		
+
+
+//	Set date to specified time
+function set_to_time(id, raw)
+{			
+	if (document.getElementById(id + "selected"))
+	{			
+		document.getElementById(id + "selected").className = "caldaycells";
+		document.getElementById(id + "selected").id = "";	
+	}
+	
+	document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';				
+		
+	var nowDate = new Date();
+	nowDate.setTime = raw * 1000;
+	
+	current_month	= nowDate.getMonth();
+	current_year	= nowDate.getFullYear();
+	current_date	= nowDate.getDate();
+	
+	oldcal = eval(id);
+	oldcal.selected_date = current_year + '' + current_month + '' + current_date;				
+
+	cal = new calendar(id, nowDate, true, true);		
+	cal.selected_date = current_year + '' + current_month + '' + current_date;	
+	
+	last_date = cal.date;
+	
+	document.getElementById('tempcal'+id).innerHTML = cal.write();	
+	
+	insert_date(cal);
+}
+
+//	Set date to what is in the field
+var lastDates = new Array();
+
+function update_calendar(id, dateValue)
+{
+	if (lastDates[id] == dateValue) return;
+	
+	lastDates[id] = dateValue;
+	
+	var fieldString = dateValue.replace(/\s+/g, ' ');
+	
+	while (fieldString.substring(0,1) == ' ')
+	{
+		fieldString = fieldString.substring(1, fieldString.length);
+	}
+	
+	var dateString = fieldString.split(' ');
+	var dateParts = dateString[0].split('-')
+
+	if (dateParts.length < 3) return;
+	var newYear  = dateParts[0];
+	var newMonth = dateParts[1];
+	var newDay   = dateParts[2];
+	
+	if (isNaN(newDay)  || newDay < 1 || (newDay.length != 1 && newDay.length != 2)) return;
+	if (isNaN(newYear) || newYear < 1 || newYear.length != 4) return;
+	if (isNaN(newMonth) || newMonth < 1 || (newMonth.length != 1 && newMonth.length != 2)) return;
+	
+	if (newMonth > 12) newMonth = 12;
+	
+	if (newDay > 28)
+	{
+		switch(newMonth - 1)
+		{
+			case 1: // Check for leap year
+				if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)
+				{
+					if (newDay > 29) newDay = 29;
+				}
+				else
+				{
+					if (newDay > 28) newDay = 28;
+				}
+			case 3:
+				if (newDay > 30) newDay = 30;
+			case 5:
+				if (newDay > 30) newDay = 30;
+			case 8:
+				if (newDay > 30) newDay = 30;
+			case 10:
+				if (newDay > 30) newDay = 30;
+			default:
+				if (newDay > 31) newDay = 31;
+		}
+	}
+	
+	if (document.getElementById(id + "selected"))
+	{			
+		document.getElementById(id + "selected").className = "caldaycells";
+		document.getElementById(id + "selected").id = "";	
+	}
+	
+	document.getElementById('cal' + id).innerHTML = '<div id="tempcal'+id+'">&nbsp;<'+'/div>';				
+		
+	var nowDate = new Date();
+	nowDate.setDate(newDay);
+	nowDate.setMonth(newMonth - 1);
+	nowDate.setYear(newYear);
+	nowDate.setHours(12);
+	
+	current_month	= nowDate.getMonth();
+	current_year	= nowDate.getFullYear();
+
+	cal = new calendar(id, nowDate, true, true);						
+	document.getElementById('tempcal'+id).innerHTML = cal.write();	
+}
+
+//	Set the date
+function set_date(td, cal)
+{					
+
+	cal = eval(cal);
+	
+	// If the user is clicking a cell that is already
+	// selected we'll de-select it and clear the form field
+	
+	if (last_click[cal.id] == td.firstChild.nodeValue)
+	{
+		td.className = "caldaycells";
+		last_click[cal.id] = '';
+		remove_date(cal);
+		cal.selected_date =  '';
+		return;
+	}
+				
+	// Onward!
+	if (document.getElementById(cal.id + "selected"))
+	{
+		document.getElementById(cal.id + "selected").className = "caldaycells";
+		document.getElementById(cal.id + "selected").id = "";
+	}
+									
+	td.className = "caldayselected";
+	td.id = cal.id + "selected";
+
+	cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;			
+	cal.date_obj.setDate(td.firstChild.nodeValue);
+	cal = new calendar(cal.id, cal.date_obj, true, true);
+	cal.selected_date = cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;			
+	
+	last_date = cal.date;
+
+	//cal.date
+	last_click[cal.id] = cal.date;
+				
+	// Insert the date into the form
+	insert_date(cal);
+}
+/*
+//	Insert the date into the form field
+function insert_date(cal)
+{
+	cal = eval(cal);
+	fval = eval("document." + form_name + "." + cal.id);	
+	
+	if (fval.value == '')
+	{
+		fval.value = cal.date_str('y');
+	}
+	else
+	{
+		time = fval.value.substring(10);
+		new_date = cal.date_str('n') + time;
+		fval.value = new_date;
+	}	
+}
+*/		
+//	Remove the date from the form field
+function remove_date(cal)
+{
+	cal = eval(cal);
+	fval = eval("document." + form_name + "." + cal.id);	
+	fval.value = '';
+}
+
+//	Change to a new month
+function change_month(mo, cal)
+{		
+	cal = eval(cal);
+
+	if (current_month != '')
+	{
+		cal.date_obj.setMonth(current_month);
+		cal.date_obj.setYear(current_year);
+	
+		current_month	= '';
+		current_year	= '';
+	}
+				
+	var newMonth = cal.date_obj.getMonth() + mo;
+	var newDate  = cal.date_obj.getDate();
+	
+	if (newMonth == 12)
+	{
+		cal.date_obj.setYear(cal.date_obj.getFullYear() + 1)
+		newMonth = 0;
+	}
+	else if (newMonth == -1)
+	{
+		cal.date_obj.setYear(cal.date_obj.getFullYear() - 1)
+		newMonth = 11;
+	}
+	
+	if (newDate > 28)
+	{
+		var newYear = cal.date_obj.getFullYear();
+		
+		switch(newMonth)
+		{
+			case 1: // Check for leap year
+				if ((newYear % 4 == 0 && newYear % 100 != 0) || newYear % 400 == 0)
+				{
+					if (newDate > 29) newDate = 29;
+				}
+				else
+				{
+					if (newDate > 28) newDate = 28;
+				}
+			case 3:
+				if (newDate > 30) newDate = 30;
+			case 5:
+				if (newDate > 30) newDate = 30;
+			case 8:
+				if (newDate > 30) newDate = 30;
+			case 10:
+				if (newDate > 30) newDate = 30;
+			default:
+				if (newDate > 31) newDate = 31;
+		}
+	}
+	
+	cal.date_obj.setDate(newDate);
+	cal.date_obj.setMonth(newMonth);
+	new_mdy	= cal.date_obj.getFullYear() + '' + cal.date_obj.getMonth() + '' + cal.date;
+	
+	highlight = (cal.selected_date == new_mdy) ? true : false;			
+	cal = new calendar(cal.id, cal.date_obj, highlight, true); 			
+	document.getElementById('cal' + cal.id).innerHTML = cal.write();	
+}
+
+//	Finalize the date string
+function date_str(time)
+{
+	var month = this.month + 1;
+	if (month < 10)
+		month = '0' + month;
+		
+	var day		= (this.date  < 10) 	?  '0' + this.date		: this.date;
+	var minutes	= (this.minutes  < 10)	?  '0' + this.minutes	: this.minutes;
+		
+	if (format == 'us')
+	{
+		var hours	= (this.hours > 12) ? this.hours - 12 : this.hours;
+		var ampm	= (this.hours > 11) ? 'PM' : 'AM'
+	}
+	else
+	{
+		var hours	= this.hours;
+		var ampm	= '';
+	}
+	
+	if (time == 'y')
+	{
+		return this.year + '-' + month + '-' + day + '  ' + hours + ':' + minutes + ' ' + ampm;		
+	}
+	else
+	{
+		return this.year + '-' + month + '-' + day;
+	}
+}
+
+//-->
+</script>
+<?php
+
+$r = ob_get_contents();
+ob_end_clean();
+return $r;
+}
+
+
+function js_calendar_write($field_id, $time = '', $highlight = TRUE)
+{
+	if ($time == '')
+		$time = time();
+
+	return
+	'<script type="text/javascript">
+		var '.$field_id.' = new calendar("'.$field_id.'", '.$time.', '.(($highlight == TRUE) ? 'true' : 'false').');
+		document.write('.$field_id.'.write());
+	</script>';	
+}	
+
+
+/* End of file js_calendar_pi.php */
 /* Location: ./system/plugins/js_calendar_pi.php */
\ No newline at end of file
diff --git a/system/scaffolding/Scaffolding.php b/system/scaffolding/Scaffolding.php
index 28172ca..1d52670 100644
--- a/system/scaffolding/Scaffolding.php
+++ b/system/scaffolding/Scaffolding.php
@@ -1,291 +1,291 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

-/**

- * CodeIgniter

- *

- * An open source application development framework for PHP 4.3.2 or newer

- *

- * @package		CodeIgniter

- * @author		ExpressionEngine Dev Team

- * @copyright	Copyright (c) 2008, EllisLab, Inc.

- * @license		http://codeigniter.com/user_guide/license.html

- * @link		http://codeigniter.com

- * @since		Version 1.0

- * @filesource

- */

-

-// ------------------------------------------------------------------------

-

-/**

- * Scaffolding Class

- *

- * Provides the Scaffolding framework

- *

- * @package		CodeIgniter

- * @subpackage	Scaffolding

- * @author		ExpressionEngine Dev Team

- * @link		http://codeigniter.com/user_guide/general/scaffolding.html

- */

-class Scaffolding {

-

-	var $CI;

-	var $current_table;

-	var $base_url = '';

-	var $lang = array();

-

-	function Scaffolding($db_table)

-	{

-		$this->CI =& get_instance();

-		

-		$this->CI->load->database("", FALSE, TRUE);			

-		$this->CI->load->library('pagination');

-		

-		// Turn off caching

-		$this->CI->db->cache_off();

-				

-		/**

-		 * Set the current table name

-		 * This is done when initializing scaffolding:

-		 * $this->load->scaffolding('table_name')

-		 *

-		 */

-		$this->current_table = $db_table;

-		

-		/**

-		 * Set the path to the "view" files

-		 * We'll manually override the "view" path so that

-		 * the load->view function knows where to look.

-		 */

-		

-		$this->CI->load->_ci_view_path = BASEPATH.'scaffolding/views/';

-

-		// Set the base URL

-		$this->base_url = $this->CI->config->site_url().'/'.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'both');

-		$this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'leading');

-

-		// Set a few globals

-		$data = array(

-						'image_url'	=> $this->CI->config->system_url().'scaffolding/images/',

-						'base_uri'  => $this->base_uri,

-						'base_url'	=> $this->base_url,

-						'title'		=> $this->current_table

-					);

-		

-		$this->CI->load->vars($data);

-		

-		// Load the language file and create variables

-		$this->lang = $this->CI->load->scaffold_language('scaffolding', '', TRUE);

-		$this->CI->load->vars($this->lang);

-				

-		//  Load the helper files we plan to use

-		$this->CI->load->helper(array('url', 'form'));

-		

-				

-		log_message('debug', 'Scaffolding Class Initialized');

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * "Add" Page

-	 *

-	 * Shows a form representing the currently selected DB

-	 * so that data can be inserted

-	 *

-	 * @access	public

-	 * @return	string	the HTML "add" page

-	 */

-	function add()

-	{	

-		$data = array(

-						'title'	=>  ( ! isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'],

-						'fields' => $this->CI->db->field_data($this->current_table),

-						'action' => $this->base_uri.'/insert'

-					);

-	

-		$this->CI->load->view('add', $data);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Insert the data

-	 *

-	 * @access	public

-	 * @return	void	redirects to the view page

-	 */

-	function insert()

-	{		

-		if ($this->CI->db->insert($this->current_table, $_POST) === FALSE)

-		{

-			$this->add();

-		}

-		else

-		{

-			redirect($this->base_uri.'/view/');

-		}

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * "View" Page

-	 *

-	 * Shows a table containing the data in the currently

-	 * selected DB

-	 *

-	 * @access	public

-	 * @return	string	the HTML "view" page

-	 */

-	function view()

-	{

-		// Fetch the total number of DB rows

-		$total_rows = $this->CI->db->count_all($this->current_table);

-		

-		if ($total_rows < 1)

-		{

-			return $this->CI->load->view('no_data');

-		}

-		

-		// Set the query limit/offset

-		$per_page = 20;

-		$offset = $this->CI->uri->segment(4, 0);

-		

-		// Run the query

-		$query = $this->CI->db->get($this->current_table, $per_page, $offset);

-

-		// Now let's get the field names				

-		$fields = $this->CI->db->list_fields($this->current_table);

-		

-		// We assume that the column in the first position is the primary field.

-		$primary = current($fields);

-

-		// Pagination!

-		$this->CI->pagination->initialize(

-							array(

-									'base_url'		 => $this->base_url.'/view',

-									'total_rows'	 => $total_rows,

-									'per_page'		 => $per_page,

-									'uri_segment'	 => 4,

-									'full_tag_open'	 => '<p>',

-									'full_tag_close' => '</p>'

-									)

-								);	

-

-		$data = array(

-						'title'	=>  ( ! isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'],

-						'query'		=> $query,

-						'fields'	=> $fields,

-						'primary'	=> $primary,

-						'paginate'	=> $this->CI->pagination->create_links()

-					);

-						

-		$this->CI->load->view('view', $data);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * "Edit" Page

-	 *

-	 * Shows a form representing the currently selected DB

-	 * so that data can be edited

-	 *

-	 * @access	public

-	 * @return	string	the HTML "edit" page

-	 */

-	function edit()

-	{

-		if (FALSE === ($id = $this->CI->uri->segment(4)))

-		{

-			return $this->view();

-		}

-

-		// Fetch the primary field name

-		$primary = $this->CI->db->primary($this->current_table);				

-

-		// Run the query

-		$query = $this->CI->db->get_where($this->current_table, array($primary => $id));

-

-		$data = array(

-						'title'	=>  ( ! isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'],

-						'fields'	=> $query->field_data(),

-						'query'		=> $query->row(),

-						'action'	=> $this->base_uri.'/update/'.$this->CI->uri->segment(4)

-					);

-	

-		$this->CI->load->view('edit', $data);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Update

-	 *

-	 * @access	public

-	 * @return	void	redirects to the view page

-	 */

-	function update()

-	{	

-		// Fetch the primary key

-		$primary = $this->CI->db->primary($this->current_table);				

-

-		// Now do the query

-		$this->CI->db->update($this->current_table, $_POST, array($primary => $this->CI->uri->segment(4)));

-		

-		redirect($this->base_uri.'/view/');

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Delete Confirmation

-	 *

-	 * @access	public

-	 * @return	string	the HTML "delete confirm" page

-	 */

-	function delete()

-	{

-		if ( ! isset($this->lang['scaff_del_confirm']))

-		{

-			$message = 'Are you sure you want to delete the following row: '.$this->CI->uri->segment(4);

-		}

-		else

-		{

-			$message = $this->lang['scaff_del_confirm'].' '.$this->CI->uri->segment(4);

-		}

-		

-		$data = array(

-						'title'		=> ( ! isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'],

-						'message'	=> $message,

-						'no'		=> anchor(array($this->base_uri, 'view'), ( ! isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']),

-						'yes'		=> anchor(array($this->base_uri, 'do_delete', $this->CI->uri->segment(4)), ( ! isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes'])

-					);

-	

-		$this->CI->load->view('delete', $data);

-	}

-	

-	// --------------------------------------------------------------------

-	

-	/**

-	 * Delete

-	 *

-	 * @access	public

-	 * @return	void	redirects to the view page

-	 */

-	function do_delete()

-	{		

-		// Fetch the primary key

-		$primary = $this->CI->db->primary($this->current_table);				

-

-		// Now do the query

-		$this->CI->db->where($primary, $this->CI->uri->segment(4));

-		$this->CI->db->delete($this->current_table);

-

-		header("Refresh:0;url=".site_url(array($this->base_uri, 'view')));

-		exit;

-	}

-

-}

-

-/* End of file Scaffolding.php */

+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2008, EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Scaffolding Class
+ *
+ * Provides the Scaffolding framework
+ *
+ * @package		CodeIgniter
+ * @subpackage	Scaffolding
+ * @author		ExpressionEngine Dev Team
+ * @link		http://codeigniter.com/user_guide/general/scaffolding.html
+ */
+class Scaffolding {
+
+	var $CI;
+	var $current_table;
+	var $base_url = '';
+	var $lang = array();
+
+	function Scaffolding($db_table)
+	{
+		$this->CI =& get_instance();
+		
+		$this->CI->load->database("", FALSE, TRUE);			
+		$this->CI->load->library('pagination');
+		
+		// Turn off caching
+		$this->CI->db->cache_off();
+				
+		/**
+		 * Set the current table name
+		 * This is done when initializing scaffolding:
+		 * $this->load->scaffolding('table_name')
+		 *
+		 */
+		$this->current_table = $db_table;
+		
+		/**
+		 * Set the path to the "view" files
+		 * We'll manually override the "view" path so that
+		 * the load->view function knows where to look.
+		 */
+		
+		$this->CI->load->_ci_view_path = BASEPATH.'scaffolding/views/';
+
+		// Set the base URL
+		$this->base_url = $this->CI->config->site_url().'/'.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'both');
+		$this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, 'leading');
+
+		// Set a few globals
+		$data = array(
+						'image_url'	=> $this->CI->config->system_url().'scaffolding/images/',
+						'base_uri'  => $this->base_uri,
+						'base_url'	=> $this->base_url,
+						'title'		=> $this->current_table
+					);
+		
+		$this->CI->load->vars($data);
+		
+		// Load the language file and create variables
+		$this->lang = $this->CI->load->scaffold_language('scaffolding', '', TRUE);
+		$this->CI->load->vars($this->lang);
+				
+		//  Load the helper files we plan to use
+		$this->CI->load->helper(array('url', 'form'));
+		
+				
+		log_message('debug', 'Scaffolding Class Initialized');
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * "Add" Page
+	 *
+	 * Shows a form representing the currently selected DB
+	 * so that data can be inserted
+	 *
+	 * @access	public
+	 * @return	string	the HTML "add" page
+	 */
+	function add()
+	{	
+		$data = array(
+						'title'	=>  ( ! isset($this->lang['scaff_add'])) ? 'Add Data' : $this->lang['scaff_add'],
+						'fields' => $this->CI->db->field_data($this->current_table),
+						'action' => $this->base_uri.'/insert'
+					);
+	
+		$this->CI->load->view('add', $data);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Insert the data
+	 *
+	 * @access	public
+	 * @return	void	redirects to the view page
+	 */
+	function insert()
+	{		
+		if ($this->CI->db->insert($this->current_table, $_POST) === FALSE)
+		{
+			$this->add();
+		}
+		else
+		{
+			redirect($this->base_uri.'/view/');
+		}
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * "View" Page
+	 *
+	 * Shows a table containing the data in the currently
+	 * selected DB
+	 *
+	 * @access	public
+	 * @return	string	the HTML "view" page
+	 */
+	function view()
+	{
+		// Fetch the total number of DB rows
+		$total_rows = $this->CI->db->count_all($this->current_table);
+		
+		if ($total_rows < 1)
+		{
+			return $this->CI->load->view('no_data');
+		}
+		
+		// Set the query limit/offset
+		$per_page = 20;
+		$offset = $this->CI->uri->segment(4, 0);
+		
+		// Run the query
+		$query = $this->CI->db->get($this->current_table, $per_page, $offset);
+
+		// Now let's get the field names				
+		$fields = $this->CI->db->list_fields($this->current_table);
+		
+		// We assume that the column in the first position is the primary field.
+		$primary = current($fields);
+
+		// Pagination!
+		$this->CI->pagination->initialize(
+							array(
+									'base_url'		 => $this->base_url.'/view',
+									'total_rows'	 => $total_rows,
+									'per_page'		 => $per_page,
+									'uri_segment'	 => 4,
+									'full_tag_open'	 => '<p>',
+									'full_tag_close' => '</p>'
+									)
+								);	
+
+		$data = array(
+						'title'	=>  ( ! isset($this->lang['scaff_view'])) ? 'View Data' : $this->lang['scaff_view'],
+						'query'		=> $query,
+						'fields'	=> $fields,
+						'primary'	=> $primary,
+						'paginate'	=> $this->CI->pagination->create_links()
+					);
+						
+		$this->CI->load->view('view', $data);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * "Edit" Page
+	 *
+	 * Shows a form representing the currently selected DB
+	 * so that data can be edited
+	 *
+	 * @access	public
+	 * @return	string	the HTML "edit" page
+	 */
+	function edit()
+	{
+		if (FALSE === ($id = $this->CI->uri->segment(4)))
+		{
+			return $this->view();
+		}
+
+		// Fetch the primary field name
+		$primary = $this->CI->db->primary($this->current_table);				
+
+		// Run the query
+		$query = $this->CI->db->get_where($this->current_table, array($primary => $id));
+
+		$data = array(
+						'title'	=>  ( ! isset($this->lang['scaff_edit'])) ? 'Edit Data' : $this->lang['scaff_edit'],
+						'fields'	=> $query->field_data(),
+						'query'		=> $query->row(),
+						'action'	=> $this->base_uri.'/update/'.$this->CI->uri->segment(4)
+					);
+	
+		$this->CI->load->view('edit', $data);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Update
+	 *
+	 * @access	public
+	 * @return	void	redirects to the view page
+	 */
+	function update()
+	{	
+		// Fetch the primary key
+		$primary = $this->CI->db->primary($this->current_table);				
+
+		// Now do the query
+		$this->CI->db->update($this->current_table, $_POST, array($primary => $this->CI->uri->segment(4)));
+		
+		redirect($this->base_uri.'/view/');
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Delete Confirmation
+	 *
+	 * @access	public
+	 * @return	string	the HTML "delete confirm" page
+	 */
+	function delete()
+	{
+		if ( ! isset($this->lang['scaff_del_confirm']))
+		{
+			$message = 'Are you sure you want to delete the following row: '.$this->CI->uri->segment(4);
+		}
+		else
+		{
+			$message = $this->lang['scaff_del_confirm'].' '.$this->CI->uri->segment(4);
+		}
+		
+		$data = array(
+						'title'		=> ( ! isset($this->lang['scaff_delete'])) ? 'Delete Data' : $this->lang['scaff_delete'],
+						'message'	=> $message,
+						'no'		=> anchor(array($this->base_uri, 'view'), ( ! isset($this->lang['scaff_no'])) ? 'No' : $this->lang['scaff_no']),
+						'yes'		=> anchor(array($this->base_uri, 'do_delete', $this->CI->uri->segment(4)), ( ! isset($this->lang['scaff_yes'])) ? 'Yes' : $this->lang['scaff_yes'])
+					);
+	
+		$this->CI->load->view('delete', $data);
+	}
+	
+	// --------------------------------------------------------------------
+	
+	/**
+	 * Delete
+	 *
+	 * @access	public
+	 * @return	void	redirects to the view page
+	 */
+	function do_delete()
+	{		
+		// Fetch the primary key
+		$primary = $this->CI->db->primary($this->current_table);				
+
+		// Now do the query
+		$this->CI->db->where($primary, $this->CI->uri->segment(4));
+		$this->CI->db->delete($this->current_table);
+
+		header("Refresh:0;url=".site_url(array($this->base_uri, 'view')));
+		exit;
+	}
+
+}
+
+/* End of file Scaffolding.php */
 /* Location: ./system/scaffolding/Scaffolding.php */
\ No newline at end of file
diff --git a/system/scaffolding/images/index.html b/system/scaffolding/images/index.html
index 065d2da..c942a79 100644
--- a/system/scaffolding/images/index.html
+++ b/system/scaffolding/images/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/scaffolding/index.html b/system/scaffolding/index.html
index 065d2da..c942a79 100644
--- a/system/scaffolding/index.html
+++ b/system/scaffolding/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/scaffolding/views/add.php b/system/scaffolding/views/add.php
index cac255a..cbb12f6 100644
--- a/system/scaffolding/views/add.php
+++ b/system/scaffolding/views/add.php
@@ -1,32 +1,32 @@
-<?php  $this->load->view('header');  ?>

-

-<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all); ?></p>

-

-

-<?php echo form_open($action); ?>

-

-<table border="0" cellpadding="3" cellspacing="1">

-<?php foreach($fields as $field): ?>

-

-<?php if ($field->primary_key == 1) continue; ?>

-

-<tr>

-	<td><?php echo $field->name; echo ' '.$field->default; ?></td>

-	

-	<?php if ($field->type == 'blob'): ?>

-	<td><textarea class="textarea" name="<?php echo $field->name; ?>" cols="60" rows="10" ><?php echo form_prep($field->default); ?></textarea></td>

-	<?php else : ?>

-	<td><input class="input" name="<?php echo $field->name; ?>" value="<?php echo form_prep($field->default); ?>" size="60" /></td>

-	<?php endif; ?>

-	

-</tr>

-<?php endforeach; ?>

-</table>

-

-<input type="submit" class="submit" value="Insert" />

-

-</form>

-

-<?php $this->load->view('footer'); 

-/* End of file add.php */

-/* Location: ./system/scaffolding/views/add.php */

+<?php  $this->load->view('header');  ?>
+
+<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all); ?></p>
+
+
+<?php echo form_open($action); ?>
+
+<table border="0" cellpadding="3" cellspacing="1">
+<?php foreach($fields as $field): ?>
+
+<?php if ($field->primary_key == 1) continue; ?>
+
+<tr>
+	<td><?php echo $field->name; echo ' '.$field->default; ?></td>
+	
+	<?php if ($field->type == 'blob'): ?>
+	<td><textarea class="textarea" name="<?php echo $field->name; ?>" cols="60" rows="10" ><?php echo form_prep($field->default); ?></textarea></td>
+	<?php else : ?>
+	<td><input class="input" name="<?php echo $field->name; ?>" value="<?php echo form_prep($field->default); ?>" size="60" /></td>
+	<?php endif; ?>
+	
+</tr>
+<?php endforeach; ?>
+</table>
+
+<input type="submit" class="submit" value="Insert" />
+
+</form>
+
+<?php $this->load->view('footer'); 
+/* End of file add.php */
+/* Location: ./system/scaffolding/views/add.php */
diff --git a/system/scaffolding/views/delete.php b/system/scaffolding/views/delete.php
index 87b59be..d195421 100644
--- a/system/scaffolding/views/delete.php
+++ b/system/scaffolding/views/delete.php
@@ -1,9 +1,9 @@
-<?php  $this->load->view('header');  ?>

-

-<p><?php echo $message; ?></p>

-

-<p><?php echo $no; ?>&nbsp;&nbsp;|&nbsp;&nbsp;<?php echo $yes; ?>

-

-<?php $this->load->view('footer'); 

-/* End of file delete.php */

-/* Location: ./system/scaffolding/views/delete.php */

+<?php  $this->load->view('header');  ?>
+
+<p><?php echo $message; ?></p>
+
+<p><?php echo $no; ?>&nbsp;&nbsp;|&nbsp;&nbsp;<?php echo $yes; ?>
+
+<?php $this->load->view('footer'); 
+/* End of file delete.php */
+/* Location: ./system/scaffolding/views/delete.php */
diff --git a/system/scaffolding/views/edit.php b/system/scaffolding/views/edit.php
index c66259d..fe553e5 100644
--- a/system/scaffolding/views/edit.php
+++ b/system/scaffolding/views/edit.php
@@ -1,33 +1,33 @@
-<?php $this->load->view('header');  ?>

-

-

-<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all);?></p>

-

-

-<?php echo form_open($action); ?>

-

-<table border="0" cellpadding="3" cellspacing="1">

-<?php foreach($fields as $field): ?>

-

-<?php if ($field->primary_key == 1) continue; ?>

-

-<tr>

-	<td><?php echo  $field->name; ?></td>

-	

-	<?php if ($field->type == 'blob'): ?>

-	<td><textarea class="textarea" name="<?php echo $field->name;?>" cols="60" rows="10" ><?php $f = $field->name; echo form_prep($query->$f); ?></textarea></td>

-	<?php else : ?>

-	<td><input class="input" value="<?php $f = $field->name; echo form_prep($query->$f); ?>" name="<?php echo $field->name; ?>" size="60" /></td>

-	<?php endif; ?>

-	

-</tr>

-<?php endforeach; ?>

-</table>

-

-<input type="submit" class="submit" value="Update" />

-

-</form>

-

-<?php $this->load->view('footer'); 

-/* End of file edit.php */

+<?php $this->load->view('header');  ?>
+
+
+<p><?php echo anchor(array($base_uri, 'view'), '&lt; '.$scaff_view_all);?></p>
+
+
+<?php echo form_open($action); ?>
+
+<table border="0" cellpadding="3" cellspacing="1">
+<?php foreach($fields as $field): ?>
+
+<?php if ($field->primary_key == 1) continue; ?>
+
+<tr>
+	<td><?php echo  $field->name; ?></td>
+	
+	<?php if ($field->type == 'blob'): ?>
+	<td><textarea class="textarea" name="<?php echo $field->name;?>" cols="60" rows="10" ><?php $f = $field->name; echo form_prep($query->$f); ?></textarea></td>
+	<?php else : ?>
+	<td><input class="input" value="<?php $f = $field->name; echo form_prep($query->$f); ?>" name="<?php echo $field->name; ?>" size="60" /></td>
+	<?php endif; ?>
+	
+</tr>
+<?php endforeach; ?>
+</table>
+
+<input type="submit" class="submit" value="Update" />
+
+</form>
+
+<?php $this->load->view('footer'); 
+/* End of file edit.php */
 /* Location: ./system/scaffolding/views/edit.php */
\ No newline at end of file
diff --git a/system/scaffolding/views/footer.php b/system/scaffolding/views/footer.php
index a287664..0e71401 100644
--- a/system/scaffolding/views/footer.php
+++ b/system/scaffolding/views/footer.php
@@ -1,10 +1,10 @@
-

-</div>

-

-<div id="footer">

-<p><a href="http://codeigniter.com/">CodeIgniter</a>, by <a href="http://www.EllisLab.com">EllisLab</a> -  Version <?php echo CI_VERSION ?></p>

-<p>Page rendered in {elapsed_time}</p>

-</div>

-

-</body>

+
+</div>
+
+<div id="footer">
+<p><a href="http://codeigniter.com/">CodeIgniter</a>, by <a href="http://www.EllisLab.com">EllisLab</a> -  Version <?php echo CI_VERSION ?></p>
+<p>Page rendered in {elapsed_time}</p>
+</div>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/scaffolding/views/header.php b/system/scaffolding/views/header.php
index a1621ff..50f234a 100644
--- a/system/scaffolding/views/header.php
+++ b/system/scaffolding/views/header.php
@@ -1,29 +1,29 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

-<html>

-<head>

-

-<title><?php echo $title; ?></title>

-

-<style type='text/css'>

-<?php $this->file(BASEPATH.'scaffolding/views/stylesheet.css'); ?>

-</style>

-

-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

-<meta http-equiv='expires' content='-1' />

-<meta http-equiv= 'pragma' content='no-cache' />

-

-</head>

-<body>

-

-<div id="header">

-<div id="header_left">

-<h3>Scaffolding:&nbsp; <?php echo $title; ?></h3>

-</div>

-<div id="header_right">

-<?php echo anchor(array($base_uri, 'view'), $scaff_view_records); ?> &nbsp;&nbsp;|&nbsp;&nbsp;

-<?php echo anchor(array($base_uri, 'add'),  $scaff_create_record); ?>

-</div>

-</div>

-

-<br clear="all">

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+
+<title><?php echo $title; ?></title>
+
+<style type='text/css'>
+<?php $this->file(BASEPATH.'scaffolding/views/stylesheet.css'); ?>
+</style>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta http-equiv='expires' content='-1' />
+<meta http-equiv= 'pragma' content='no-cache' />
+
+</head>
+<body>
+
+<div id="header">
+<div id="header_left">
+<h3>Scaffolding:&nbsp; <?php echo $title; ?></h3>
+</div>
+<div id="header_right">
+<?php echo anchor(array($base_uri, 'view'), $scaff_view_records); ?> &nbsp;&nbsp;|&nbsp;&nbsp;
+<?php echo anchor(array($base_uri, 'add'),  $scaff_create_record); ?>
+</div>
+</div>
+
+<br clear="all">
 <div id="outer">
\ No newline at end of file
diff --git a/system/scaffolding/views/index.html b/system/scaffolding/views/index.html
index 065d2da..c942a79 100644
--- a/system/scaffolding/views/index.html
+++ b/system/scaffolding/views/index.html
@@ -1,10 +1,10 @@
-<html>

-<head>

-	<title>403 Forbidden</title>

-</head>

-<body>

-

-<p>Directory access is forbidden.</p>

-

-</body>

+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
 </html>
\ No newline at end of file
diff --git a/system/scaffolding/views/no_data.php b/system/scaffolding/views/no_data.php
index 963341b..bc81e74 100644
--- a/system/scaffolding/views/no_data.php
+++ b/system/scaffolding/views/no_data.php
@@ -1,8 +1,8 @@
-<?php  $this->load->view('header');  ?>

-

-<p><?php echo $scaff_no_data; ?></p>

-<p><?php echo anchor(array($base_uri, 'add'), $scaff_create_record); ?></p>

-

-<?php $this->load->view('footer'); 

-/* End of file no_data.php */

+<?php  $this->load->view('header');  ?>
+
+<p><?php echo $scaff_no_data; ?></p>
+<p><?php echo anchor(array($base_uri, 'add'), $scaff_create_record); ?></p>
+
+<?php $this->load->view('footer'); 
+/* End of file no_data.php */
 /* Location: ./system/scaffolding/views/no_data.php */
\ No newline at end of file
diff --git a/system/scaffolding/views/stylesheet.css b/system/scaffolding/views/stylesheet.css
index ba6ee0a..3f487dd 100644
--- a/system/scaffolding/views/stylesheet.css
+++ b/system/scaffolding/views/stylesheet.css
@@ -1,143 +1,143 @@
-body {

- margin: 0;

- padding: 0;

- font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

- font-size: 11px;

- color: #4F5155;

- background: #fff url(<?php echo $image_url; ?>background.jpg) repeat-x left top;

-}

-

-a {

- color: #8B0D00;

- background-color: transparent;

- text-decoration: none;

- font-weight: bold;

-}

-

-a:visited {

- color: #8B0D00;

- background-color: transparent;

- text-decoration: none;

-}

-

-a:hover {

- color: #000;

- text-decoration: none;

- background-color: transparent;

-}

-

-

-#header {

- margin: 0;

- padding: 0;

-}

-

-#header_left {

- background-color: transparent;

- float: left;

- padding: 21px 0 0 32px;

- margin: 0

-}

-

-#header_right {

- background-color: transparent;

- float: right;

- text-align: right;

- padding: 35px 50px 20px 0;

- margin: 0

-}

-

-#footer {

- margin: 20px 0 15px 0;

- padding: 0;

-}

-

-#footer p {

- font-size: 10px;

- color: #999;

- text-align: center;

-}

-

-#outer {

- margin: 30px 40px 0 40px;

-}

-

-img {

- padding:0;

- border: 0;

- margin: 0;

-}

-

-.nopad {

- padding:0;

- border: 0;

- margin: 0;

-}

-

-table {

- background-color: #efefef;

-}

-

-th {

- background-color: #eee;

- font-weight: bold;

- padding: 6px;

- text-align: left;

-}

-

-td {

- background-color: #fff;

- padding: 6px;

-}

-

-

-form {

- margin: 0;

- padding: 0;

-}

-

-.input {

- font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

- font-size: 11px;

- width: 600px;

- color: #333;

- border: 1px solid #B3B4BD;

- font-size: 11px;

- height: 2em;

- padding: 0;

- margin: 0;

-}

-

-.textarea {

- font-family: Lucida Grande, Verdana, Geneva, Sans-serif;

- font-size: 12px;

- width: 600px;

- color: #333;

- border: 1px solid #B3B4BD;

- padding: 0;

- margin: 0;

-}

-

-.select {

- background-color: #fff;

- font-size:  11px;

- font-weight: normal;

- color: #333;

- padding: 0;

- margin: 0 0 3px 0;

-}

-

-.checkbox {

- background-color: transparent;

- padding: 0;

- border: 0;

-}

-

-.submit {

- background-color: #8B0D00;

- color: #FFF;

- font-weight: normal;

- border: 1px solid #000;

- margin: 6px 0 0 0;

- padding: 1px 5px 1px 5px;

-}

+body {
+ margin: 0;
+ padding: 0;
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+ font-size: 11px;
+ color: #4F5155;
+ background: #fff url(<?php echo $image_url; ?>background.jpg) repeat-x left top;
+}
+
+a {
+ color: #8B0D00;
+ background-color: transparent;
+ text-decoration: none;
+ font-weight: bold;
+}
+
+a:visited {
+ color: #8B0D00;
+ background-color: transparent;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #000;
+ text-decoration: none;
+ background-color: transparent;
+}
+
+
+#header {
+ margin: 0;
+ padding: 0;
+}
+
+#header_left {
+ background-color: transparent;
+ float: left;
+ padding: 21px 0 0 32px;
+ margin: 0
+}
+
+#header_right {
+ background-color: transparent;
+ float: right;
+ text-align: right;
+ padding: 35px 50px 20px 0;
+ margin: 0
+}
+
+#footer {
+ margin: 20px 0 15px 0;
+ padding: 0;
+}
+
+#footer p {
+ font-size: 10px;
+ color: #999;
+ text-align: center;
+}
+
+#outer {
+ margin: 30px 40px 0 40px;
+}
+
+img {
+ padding:0;
+ border: 0;
+ margin: 0;
+}
+
+.nopad {
+ padding:0;
+ border: 0;
+ margin: 0;
+}
+
+table {
+ background-color: #efefef;
+}
+
+th {
+ background-color: #eee;
+ font-weight: bold;
+ padding: 6px;
+ text-align: left;
+}
+
+td {
+ background-color: #fff;
+ padding: 6px;
+}
+
+
+form {
+ margin: 0;
+ padding: 0;
+}
+
+.input {
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+ font-size: 11px;
+ width: 600px;
+ color: #333;
+ border: 1px solid #B3B4BD;
+ font-size: 11px;
+ height: 2em;
+ padding: 0;
+ margin: 0;
+}
+
+.textarea {
+ font-family: Lucida Grande, Verdana, Geneva, Sans-serif;
+ font-size: 12px;
+ width: 600px;
+ color: #333;
+ border: 1px solid #B3B4BD;
+ padding: 0;
+ margin: 0;
+}
+
+.select {
+ background-color: #fff;
+ font-size:  11px;
+ font-weight: normal;
+ color: #333;
+ padding: 0;
+ margin: 0 0 3px 0;
+}
+
+.checkbox {
+ background-color: transparent;
+ padding: 0;
+ border: 0;
+}
+
+.submit {
+ background-color: #8B0D00;
+ color: #FFF;
+ font-weight: normal;
+ border: 1px solid #000;
+ margin: 6px 0 0 0;
+ padding: 1px 5px 1px 5px;
+}
diff --git a/system/scaffolding/views/view.php b/system/scaffolding/views/view.php
index 69c1f45..a81241d 100644
--- a/system/scaffolding/views/view.php
+++ b/system/scaffolding/views/view.php
@@ -1,27 +1,27 @@
-<?php  $this->load->view('header');  ?>

-

-<table border="0" cellpadding="0" cellspacing="1" style="width:100%">

- <tr>

-	<th>Edit</th>

-	<th>Delete</th>

-	<?php foreach($fields as $field): ?>

-	<th><?php echo $field; ?></th>

-	<?php endforeach; ?>

-</tr>

-

-<?php foreach($query->result() as $row): ?>

- <tr>

-	<td>&nbsp;<?php echo anchor(array($base_uri, 'edit', $row->$primary), $scaff_edit); ?>&nbsp;</td>

- 	<td><?php echo anchor(array($base_uri, 'delete', $row->$primary), $scaff_delete); ?></td>

- 	<?php foreach($fields as $field): ?>	

-	<td><?php echo form_prep($row->$field);?></td>

-	<?php endforeach; ?>

- </tr>

-<?php endforeach; ?>

-</table>

-

-<?php echo $paginate; ?>

-

-<?php $this->load->view('footer'); 

-/* End of file view.php */

+<?php  $this->load->view('header');  ?>
+
+<table border="0" cellpadding="0" cellspacing="1" style="width:100%">
+ <tr>
+	<th>Edit</th>
+	<th>Delete</th>
+	<?php foreach($fields as $field): ?>
+	<th><?php echo $field; ?></th>
+	<?php endforeach; ?>
+</tr>
+
+<?php foreach($query->result() as $row): ?>
+ <tr>
+	<td>&nbsp;<?php echo anchor(array($base_uri, 'edit', $row->$primary), $scaff_edit); ?>&nbsp;</td>
+ 	<td><?php echo anchor(array($base_uri, 'delete', $row->$primary), $scaff_delete); ?></td>
+ 	<?php foreach($fields as $field): ?>	
+	<td><?php echo form_prep($row->$field);?></td>
+	<?php endforeach; ?>
+ </tr>
+<?php endforeach; ?>
+</table>
+
+<?php echo $paginate; ?>
+
+<?php $this->load->view('footer'); 
+/* End of file view.php */
 /* Location: ./system/scaffolding/views/view.php */
\ No newline at end of file