Automated merge with http://hg.ellislab.com/CodeIgniter2
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 40afadb..4be371e 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -46,50 +46,9 @@
 {
 	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);
+		$CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix);
 	}
 }
 	
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 2be06ac..274c4ad 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -125,7 +125,7 @@
 			
 		if ( ! $current_dir = @opendir($path))
 		{
-			return TRUE;			
+			return FALSE;			
 		}
 	
 		while(FALSE !== ($filename = @readdir($current_dir)))
@@ -218,7 +218,7 @@
  *
  * @access	public
  * @param	string	path to source
- * @param	bool	whether to include the path as part of the filename
+ * @param	bool	Look only at the top level directory specified?
  * @param	bool	internal variable to determine recursion status - do not use in calls
  * @return	array
  */	
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 3b7dcc6..af85e65 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -23,7 +23,7 @@
 		$this->CI =& get_instance();
 
 		// load the requested js library
-		$this->CI->load->library($js_library_driver, array('autoload' => $autoload));
+		$this->CI->load->library('javsacript/'.$js_library_driver, array('autoload' => $autoload));
 		// make js to refer to current library
 		$this->js =& $this->CI->$js_library_driver;
 		
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 6d36121..1f920ea 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -35,7 +35,7 @@
 	var $template 			= NULL;
 	var $newline			= "\n";
 	var $empty_cells		= "";
-	
+	var	$function			= FALSE;
 	
 	function CI_Table()
 	{
@@ -75,7 +75,7 @@
 	function set_heading()
 	{
 		$args = func_get_args();
-		$this->heading = (is_array($args[0])) ? $args[0] : $args;
+		$this->heading = $this->_prep_args($args);
 	}
 
 	// --------------------------------------------------------------------
@@ -110,7 +110,7 @@
 		$new = array();
 		while(count($array) > 0)
 		{	
-			$temp = array_splice($array, 0, $col_limit);
+			$temp = array_splice($array, 0, $col_limit);	
 			
 			if (count($temp) < $col_limit)
 			{
@@ -156,11 +156,59 @@
 	function add_row()
 	{
 		$args = func_get_args();
-		$this->rows[] = (is_array($args[0])) ? $args[0] : $args;
+		$this->rows[] = $this->_prep_args($args);
 	}
 
 	// --------------------------------------------------------------------
+	
+	/**
+	 * Prep Args
+	 *
+	 * Ensures a standard associative array format for all cell data
+	 *
+	 * @access	public
+	 * @param	type
+	 * @return	type
+	 */
+	function _prep_args($args)
+	{
+		// If there is no $args[0], skip this and treat as an associative array
+		// This can happen if there is only a single key, for example this is passed to table->generate
+		// array(array('foo'=>'bar'))
+		if (isset($args[0]) AND (count($args) == 1 && is_array($args[0])))
+		{
+			// args sent as indexed array
+			if ( ! isset($args[0]['data']))
+			{
+				foreach ($args[0] as $key => $val)
+				{
+					if (is_array($val) && isset($val['data']))
+					{
+						$args[$key] = $val;
+					}
+					else
+					{
+						$args[$key] = array('data' => $val);						
+					}
+				}				
+			}
+		}
+		else
+		{
+			foreach ($args as $key => $val)
+			{
+				if ( ! is_array($val))
+				{
+					$args[$key] = array('data' => $val);
+				}
+			}
+		}
+		
+		return $args;
+	}
 
+	// --------------------------------------------------------------------
+	
 	/**
 	 * Add a table caption
 	 *
@@ -208,7 +256,9 @@
 		// Compile and validate the template date
 		$this->_compile_template();
 	
-	
+		// set a custom cell manipulation function to a locally scoped variable so its callable
+		$function = $this->function;
+			
 		// Build the table!
 		
 		$out = $this->template['table_open'];
@@ -225,23 +275,40 @@
 		// Is there a table heading to display?
 		if (count($this->heading) > 0)
 		{
+			$out .= $this->template['thead_open'];
+			$out .= $this->newline;
 			$out .= $this->template['heading_row_start'];
-			$out .= $this->newline;		
+			$out .= $this->newline;
 
 			foreach($this->heading as $heading)
 			{
-				$out .= $this->template['heading_cell_start'];
-				$out .= $heading;
+				$temp = $this->template['heading_cell_start'];
+										
+				foreach ($heading as $key => $val)
+				{
+					if ($key != 'data')
+					{
+						$temp = str_replace('<th', "<th $key='$val'", $temp);
+					}							
+				}
+
+				$out .= $temp;				
+				$out .= isset($heading['data']) ? $heading['data'] : '';
 				$out .= $this->template['heading_cell_end'];
 			}
 
 			$out .= $this->template['heading_row_end'];
-			$out .= $this->newline;				
+			$out .= $this->newline;
+			$out .= $this->template['thead_close'];
+			$out .= $this->newline;
 		}
-
+				
 		// Build the table rows
 		if (count($this->rows) > 0)
 		{
+			$out .= $this->template['tbody_open'];
+			$out .= $this->newline;
+			
 			$i = 1;
 			foreach($this->rows as $row)
 			{
@@ -258,15 +325,33 @@
 	
 				foreach($row as $cell)
 				{
-					$out .= $this->template['cell_'.$name.'start'];
+					$temp = $this->template['cell_'.$name.'start'];
+											
+					foreach ($cell as $key => $val)
+					{
+						if ($key != 'data')
+						{
+							$temp = str_replace('<td', "<td $key='$val'", $temp);
+						}							
+					}
 					
+					$cell = isset($cell['data']) ? $cell['data'] : '';
+					$out .= $temp;
+
 					if ($cell === "" OR $cell === NULL)
 					{
 						$out .= $this->empty_cells;
 					}
 					else
 					{
-						$out .= $cell;
+						if ($function !== FALSE && is_callable($function))
+						{
+							$out .= $function($cell);
+						}
+						else
+						{
+							$out .= $cell;
+						}
 					}
 					
 					$out .= $this->template['cell_'.$name.'end'];
@@ -275,6 +360,9 @@
 				$out .= $this->template['row_'.$name.'end'];
 				$out .= $this->newline;	
 			}
+			
+			$out .= $this->template['tbody_close'];
+			$out .= $this->newline;
 		}
 
 		$out .= $this->template['table_close'];
@@ -321,7 +409,7 @@
 				return FALSE;
 			}
 			
-			$this->heading = $query->list_fields();
+			$this->heading = $this->_prep_args($query->list_fields());
 		}
 				
 		// Next blast through the result array and build out the rows
@@ -330,7 +418,7 @@
 		{
 			foreach ($query->result_array() as $row)
 			{
-				$this->rows[] = $row;
+				$this->rows[] = $this->_prep_args($row);
 			}
 		}
 	}
@@ -353,21 +441,15 @@
 		
 		$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;
+				$this->heading = $this->_prep_args($row);
 			}
 			else
 			{
-				$this->rows[] = $row;
+				$this->rows[] = $this->_prep_args($row);
 			}
 			
 			$i++;
@@ -391,7 +473,7 @@
  		}
 		
 		$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)
+		foreach (array('table_open', 'thead_open', 'thead_close', 'heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'tbody_open', 'tbody_close', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val)
 		{
 			if ( ! isset($this->template[$val]))
 			{
@@ -412,12 +494,18 @@
 	{
 		return  array (
 						'table_open' 			=> '<table border="0" cellpadding="4" cellspacing="0">',
-
+						
+						'thead_open'			=> '<thead>',
+						'thead_close'			=> '</thead>',
+						
 						'heading_row_start' 	=> '<tr>',
 						'heading_row_end' 		=> '</tr>',
 						'heading_cell_start'	=> '<th>',
 						'heading_cell_end'		=> '</th>',
 
+						'tbody_open'			=> '<tbody>',
+						'tbody_close'			=> '</tbody>',
+						
 						'row_start' 			=> '<tr>',
 						'row_end' 				=> '</tr>',
 						'cell_start'			=> '<td>',
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 9b1737c..a604c0b 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -128,7 +128,7 @@
 	 * Receive Trackback  Data
 	 *
 	 * This function simply validates the incoming TB data.
-	 * It returns false on failure and true on success.
+	 * 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.
 	 *
@@ -221,7 +221,7 @@
 	 * Process Trackback
 	 *
 	 * Opens a socket connection and passes the data to
-	 * the server.  Returns true on success, false on failure
+	 * the server.  Returns TRUE on success, FALSE on failure
 	 *
 	 * @access	public
 	 * @param	string
@@ -267,6 +267,7 @@
 		}
 		@fclose($fp);
 		
+		
 		if (stristr($this->response, '<error>0</error>') === FALSE)
 		{
 			$message = 'An unknown error was encountered';
@@ -383,7 +384,7 @@
 				
 		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
 		{
-			return false;
+			return FALSE;
 		}
 		else
 		{
@@ -436,7 +437,7 @@
 		{
 			return $str;
 		}
-
+			
 		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
 	
 		if (strlen($str) <= $n)
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 5ff4782..ac9323c 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -454,6 +454,11 @@
 	 */	
 	function set_allowed_types($types)
 	{
+		if ( ! is_array($types) && $types == '*')
+		{
+			$this->allowed_types = '*';
+			return;
+		}
 		$this->allowed_types = explode('|', $types);
 	}
 	
@@ -551,6 +556,11 @@
 	 */	
 	function is_allowed_filetype()
 	{
+		if ($this->allowed_types == '*')
+		{
+			return TRUE;
+		}
+		
 		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
 		{
 			$this->set_error('upload_no_file_types');
@@ -805,7 +815,7 @@
 		}
 
 		$CI =& get_instance();	
-		$data = $CI->input->xss_clean($data);
+		$data = $CI->security->xss_clean($data);
 		
 		flock($fp, LOCK_EX);
 		fwrite($fp, $data);
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 5a82391..c46d52c 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -513,7 +513,7 @@
 				}
 				else
 				{
-					$array[$key] = $CI->input->xss_clean($array[$key]);
+					$array[$key] = $CI->security->xss_clean($array[$key]);
 				}
 			}
 			
@@ -529,7 +529,7 @@
 			}
 			else
 			{
-				$result = $CI->input->xss_clean($result);
+				$result = $CI->security->xss_clean($result);
 			}
 		}
 		
@@ -1127,7 +1127,9 @@
 				}
 				else
 				{
-					$array[$key] = $CI->input->xss_clean($array[$key]);
+					// 'bits' is for the MetaWeblog API image bits
+					// @todo - this needs to be made more general purpose
+					$array[$key] = ($key == 'bits') ? $array[$key] : $CI->security->xss_clean($array[$key]);
 				}
 			}
 			
@@ -1147,7 +1149,7 @@
 				}
 				else
 				{
-					$parameters[] = $CI->input->xss_clean($a_param);
+					$parameters[] = $CI->security->xss_clean($a_param);
 				}
 			}	
 		}
@@ -1322,7 +1324,7 @@
 	function serializedata($typ, $val)
 	{
 		$rs = '';
-		
+
 		switch($this->xmlrpcTypes[$typ])
 		{
 			case 3:
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 429ab84..fe1c99b 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -40,10 +40,10 @@
 	var $debug_msg		= '';		// Debug Message
 	var $system_methods = array(); // XML RPC Server methods
 	var $controller_obj;
-
+	
 	var $object			= FALSE;
-	
-	
+
+
 	//-------------------------------------
 	//  Constructor, more or less
 	//-------------------------------------
diff --git a/system/libraries/Jquery.php b/system/libraries/javascript/Jquery.php
similarity index 99%
rename from system/libraries/Jquery.php
rename to system/libraries/javascript/Jquery.php
index c63a742..f6b8dce 100644
--- a/system/libraries/Jquery.php
+++ b/system/libraries/javascript/Jquery.php
@@ -24,7 +24,7 @@
  * @link		http://www.codeigniter.com/user_guide/libraries/jquery.html
  */
  
-class Jquery extends CI_Javascript {
+class CI_Jquery extends CI_Javascript {
 
 	var $_javascript_folder = 'js';
 	var $jquery_code_for_load = array();
diff --git a/user_guide/libraries/table.html b/user_guide/libraries/table.html
index 1c67e4b..b233dbf 100644
--- a/user_guide/libraries/table.html
+++ b/user_guide/libraries/table.html
@@ -2,17 +2,16 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
 
+<title>CodeIgniter User Guide : HTML Table Class</title>
+
+<link rel='stylesheet' type='text/css' media='all' href='http://codeigniter.com/user_guide/userguide.css' />
+
+<script type="text/javascript" src="http://codeigniter.com/user_guide/nav/nav.js"></script>
+<script type="text/javascript" src="http://codeigniter.com/user_guide/nav/prototype.lite.js"></script>
+<script type="text/javascript" src="http://codeigniter.com/user_guide/nav/moo.fx.js"></script>
+<script type="text/javascript" src="http://codeigniter.com/user_guide/nav/user_guide_menu.js"></script>
+
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>HTML Table Class : CodeIgniter User Guide</title>
-
-<style type='text/css' media='all'>@import url('../userguide.css');</style>
-<link rel='stylesheet' type='text/css' media='all' href='../userguide.css' />
-
-<script type="text/javascript" src="../nav/nav.js"></script>
-<script type="text/javascript" src="../nav/prototype.lite.js"></script>
-<script type="text/javascript" src="../nav/moo.fx.js"></script>
-<script type="text/javascript" src="../nav/user_guide_menu.js"></script>
-
 <meta http-equiv='expires' content='-1' />
 <meta http-equiv= 'pragma' content='no-cache' />
 <meta name='robots' content='all' />
@@ -24,7 +23,7 @@
 
 <!-- START NAVIGATION -->
 <div id="nav"><div id="nav_inner"><script type="text/javascript">create_menu('../');</script></div></div>
-<div id="nav2"><a name="top"></a><a href="javascript:void(0);" onclick="myHeight.toggle();"><img src="../images/nav_toggle_darker.jpg" width="154" height="43" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div>
+<div id="nav2"><a name="top"></a><a href="javascript:void(0);" onclick="myHeight.toggle();"><img src="http://codeigniter.com/user_guide/images/nav_toggle.jpg" width="153" height="44" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div>
 <div id="masthead">
 <table cellpadding="0" cellspacing="0" border="0" style="width:100%">
 <tr>
@@ -199,6 +198,14 @@
 <code>$this->table->add_row('Blue', 'Red', 'Green');</code>
 <code>$this->table->add_row(array('Blue', 'Red', 'Green'));</code>
 
+<p>If you would like to set an individual cell's tag attributes, you can use an associative array for that cell.  The associative key <dfn>'data'</dfn> defines the cell's data.  Any other key =&gt; val pairs are added as <dfn>key='val'</dfn> attributes to the tag:</p>
+
+<code>$cell = array('data' => 'Blue', 'class' => 'highlight', 'colspan' => 2);<br />
+$this->table->add_row($cell, 'Red', 'Green');<br />
+<br />
+// generates<br />
+// &lt;td class='highlight' colspan='2'&gt;Blue&lt;/td&gt;&lt;td&gt;Red&lt;/td&gt;&lt;td&gt;Green&lt;/td&gt;
+</code>
 
 <h2>$this->table->make_columns()</h2>
 
@@ -274,6 +281,22 @@
 echo $this->table->generate();
 </code>
 
+<h2>$this->table->function</h2>
+
+<p>Allows you to specify a native PHP function or a valid function array object to be applied to all cell data.</p>
+
+<code>$this->load->library('table');<br />
+<br />
+$this->table->set_heading('Name', 'Color', 'Size');<br />
+$this->table->add_row('Fred', '&lt;strong&gt;Blue&lt;/strong&gt;', 'Small');<br />
+<br />
+$this->table->function = 'htmlspecialchars';<br />
+echo $this->table->generate();<br />
+</code>
+
+<p>In the above example, all cell data would be ran through PHP's <dfn>htmlspecialchars()</dfn> function, resulting in:</p>
+
+<code>&lt;td&gt;Fred&lt;/td&gt;&lt;td&gt;&amp;lt;strong&amp;gt;Blue&amp;lt;/strong&amp;gt;&lt;/td&gt;&lt;td&gt;Small&lt;/td&gt;</code>
 </div>
 <!-- END CONTENT -->