diff -ruN 2.0.5/index.php 2.2.2/index.php
--- 2.0.5/index.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/index.php	2006-11-19 01:56:05.000000000 -0600
@@ -1,4 +1,4 @@
-<?php 
+<?php
 /* Short and sweet */
 define('WP_USE_THEMES', true);
 require('./wp-blog-header.php');
diff -ruN 2.0.5/readme.html 2.2.2/readme.html
--- 2.0.5/readme.html	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/readme.html	2007-04-20 21:20:09.000000000 -0500
@@ -1,112 +1,83 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-<title>WordPress &rsaquo; ReadMe</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<style type="text/css" media="screen">
-	<!--
-	html {
-		background: #eee;
-	}
-	body {
-		background: #fff;
-		color: #000;
-		font-family: Georgia, "Times New Roman", Times, serif;
-		margin-left: 25%;
-		margin-right: 25%;
-		padding: .2em 2em;
-	}
-	
-	h1 {
-		color: #006;
-		font-size: 18px;
-		font-weight: lighter;
-	}
-	
-	h2 {
-		font-size: 16px;
-	}
-	
-	p, li, dt {
-		line-height: 140%;
-		padding-bottom: 2px;
-	}
-
-	ul, ol {
-		padding: 5px 5px 5px 20px;
-	}
-	-->
-	</style>
+	<title>WordPress &rsaquo; ReadMe</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<link rel="stylesheet" href="wp-admin/install.css" type="text/css" />
 </head>
 <body>
-<h1 style="text-align: center"><img alt="WordPress" src="http://wordpress.org/images/wordpress.gif" /> <br />
-	Version 2.0</h1>
-<p style="text-align: center"> Semantic Personal Publishing Platform </p>
+<h1 id="logo" style="text-align: center">
+	<img alt="WordPress" src="wp-admin/images/wordpress-logo.png" />
+	<br /> Version 2.2
+</h1>
+<p style="text-align: center">Semantic Personal Publishing Platform</p>
+
 <h1>First Things First</h1>
 <p>Welcome. WordPress is a very special project to me. Every developer and contributor adds something unique to the mix, and together we create something beautiful that I'm proud to be a part of. Thousands of hours have gone into WordPress, and we're dedicated to making it better every day. Thank you for making it part of your world.</p>
-<p style="text-align: right;">&#8212; Matt Mullenweg </p>
+<p style="text-align: right;">&#8212; Matt Mullenweg</p>
 
-<h1 id="installation">Installation: Famous 5-minute install</h1>
+<h1>Installation: Famous 5-minute install</h1>
 <ol>
-	<li>Unzip the package in an empty directory</li>
-	<li>Open up <code>wp-config-sample.php</code> with a text editor like WordPad or similar and fill in your database connection details</li>
-	<li>Save the file as <code>wp-config.php</code> </li>
+	<li>Unzip the package in an empty directory.</li>
+	<li>Open up <code>wp-config-sample.php</code> with a text editor like WordPad or similar and fill in your database connection details.</li>
+	<li>Save the file as <code>wp-config.php</code></li>
 	<li>Upload everything.</li>
-	<li>Open <span class="file"><a href="wp-admin/install.php">/wp-admin/install.php</a></span> in your browser. This should setup the tables needed for your blog. If there is an error, double check your <span class="file">wp-config.php</span> file, and try again. If it fails again, please go to the <a href="http://wordpress.org/support/">support forums</a> with as much data as you can gather. </li>
+	<li>Open <span class="file"><a href="wp-admin/install.php">/wp-admin/install.php</a></span> in your browser. This should setup the tables needed for your blog. If there is an error, double check your <span class="file">wp-config.php</span> file, and try again. If it fails again, please go to the <a href="http://wordpress.org/support/">support forums</a> with as much data as you can gather.</li>
 	<li><strong>Note the password given to you.</strong></li>
 	<li> The install script should then send you to the <a href="wp-login.php">login page</a>. Sign in with the username <code>admin</code> and the password generated during the installation. You can then click on 'Profile' to change the password.</li>
 </ol>
 
 <h1>Upgrading</h1>
 <p>Before you upgrade anything, make sure you have backup copies of any files you may have modified such as <code>index.php</code>.</p>
-<h2>Upgrading from any previous WordPress to 2.0:</h2>
+<h2>Upgrading from any previous WordPress to 2.2:</h2>
 <ol>
-	<li>Delete your old WP files, saving ones you've modified </li>
-	<li>Upload the new files</li>
-	<li>Point your browser to <span class="file"><a href="wp-admin/upgrade.php">/wp-admin/upgrade.php</a></span></li>
+	<li>Delete your old WP files, saving ones you've modified.</li>
+	<li>Upload the new files.</li>
+	<li>Point your browser to <span class="file"><a href="wp-admin/upgrade.php">/wp-admin/upgrade.php</a>.</span></li>
 	<li>You wanted more, perhaps? That's it!</li>
 </ol>
 <h2>Template Changes</h2>
 <p>If you have customized your templates you will probably have to make some changes to them. If you're converting your 1.2 or earlier templates, <a href="http://codex.wordpress.org/Upgrade_1.2_to_1.5">we've created a special guide for you</a>. </p>
+
 <h1>Online Resources</h1>
 <p>If you have any questions that aren't addressed in this document, please take advantage of WordPress' numerous online resources:</p>
 <dl>
 	<dt><a href="http://codex.wordpress.org/">The WordPress Codex </a></dt>
-	<dd>The Codex is the encyclopedia of all things WordPress. It is the most comprehensive source of information for WordPress available. </dd>
+		<dd>The Codex is the encyclopedia of all things WordPress. It is the most comprehensive source of information for WordPress available.</dd>
 	<dt><a href="http://wordpress.org/development/">The Development Blog</a></dt>
-	<dd>This is where you'll find the latest updates and news related to WordPress. Bookmark and check often. </dd>
+		<dd>This is where you'll find the latest updates and news related to WordPress. Bookmark and check often.</dd>
 	<dt><a href="http://planet.wordpress.org/">WordPress Planet </a></dt>
-	<dd>The WordPress Planet is a news aggregator that brings together posts from WordPress blogs around the web. </dd>
+		<dd>The WordPress Planet is a news aggregator that brings together posts from WordPress blogs around the web.</dd>
 	<dt><a href="http://wordpress.org/support/">WordPress Support Forums</a></dt>
-	<dd>If you've looked everywhere and still can't find an answer, the support forums are very active and have a large community ready to help. To help them help you be sure to use a descriptive thread title and describe your question in as much detail as possible. </dd>
+		<dd>If you've looked everywhere and still can't find an answer, the support forums are very active and have a large community ready to help. To help them help you be sure to use a descriptive thread title and describe your question in as much detail as possible.</dd>
 	<dt><a href="http://codex.wordpress.org/IRC">WordPress IRC Channel</a></dt>
-	<dd>Finally, there is an online chat channel that is used for discussion amoung people who use WordPress and occasionally support topics. The above wiki page should point you in the right direction. (irc.freenode.net #wordpresss) </dd>
+		<dd>Finally, there is an online chat channel that is used for discussion among people who use WordPress and occasionally support topics. The above wiki page should point you in the right direction. (<a href="irc://irc.freenode.net/wordpress">irc.freenode.net #wordpress</a>)</dd>
 </dl>
 
-<h1 id="requirements">System Recommendations</h1>
+<h1>System Recommendations</h1>
 <ul>
-	<li>PHP version <strong>4.1</strong> or higher</li>
-	<li>MySQL version <strong>3.23.23</strong> or higher</li>
+	<li>PHP version <strong>4.2</strong> or higher.</li>
+	<li>MySQL version <strong>4.0</strong> or higher.</li>
 	<li>... and a link to <a href="http://wordpress.org/">http://wordpress.org</a> on your site.</li>
 </ul>
-<p>WordPress is the official continuation of <a href="http://cafelog.com/">b2/caf&eacute;log</a>, which came from Michel V. The work has been continued by the <a href="http://wordpress.org/about/">WordPress developers</a>. If you would like to support WordPress, please consider <a href="http://wordpress.org/donate/">donating</a>. </p>
+<p>WordPress is the official continuation of <a href="http://cafelog.com/">b2/caf&eacute;log</a>, which came from Michel V. The work has been continued by the <a href="http://wordpress.org/about/">WordPress developers</a>. If you would like to support WordPress, please consider <a href="http://wordpress.org/donate/">donating</a>.</p>
 
 <h1>Upgrading from another system</h1>
-<p>WordPress can <a href="http://codex.wordpress.org/Importing_from_other_blogging_software">import from a number of systems</a>. First you need to get WordPress installed and working as described above.</p>
+<p>WordPress can <a href="http://codex.wordpress.org/Importing_Content">import from a number of systems</a>. First you need to get WordPress installed and working as described above.</p>
 
-<h1 id="templates">XML-RPC Interface</h1>
-<p>You can now post to your WordPress blog with tools like <a href="http://ecto.kung-foo.tv/">Ecto</a>, <a href="http://blogbuddy.sourceforge.net">BlogBuddy</a>, <a href="http://bloggar.com/">Bloggar</a>, <a href="http://www.ubique.ch/wapblogger/">WapBlogger</a> (post from your Wap cellphone!), <a href="http://radio.userland.com">Radio Userland</a> (which means you can use Radio's email-to-blog feature), <a href="http://www.zempt.com/">Zempt</a>, <a href="http://www.newzcrawler.com/">NewzCrawler</a>, and other tools that support the Blogging APIs! :) You can read more about <a href="http://codex.wordpress.org/XML-RPC_Support">XML-RPC support on the Codex</a>.</p>
+<h1>XML-RPC and Atom Interface</h1>
+<p>You can now post to your WordPress blog with tools like <a href="http://windowslivewriter.spaces.live.com/">Windows Live Writer</a>, <a href="http://ecto.kung-foo.tv/">Ecto</a>, <a href="http://bloggar.com/">Bloggar</a>, <a href="http://radio.userland.com">Radio Userland</a> (which means you can use Radio's email-to-blog feature), <a href="http://www.newzcrawler.com/">NewzCrawler</a>, and other tools that support the Blogging APIs! :) You can read more about <a href="http://codex.wordpress.org/XML-RPC_Support">XML-RPC support on the Codex</a>.</p>
 
 <h1>Post via Email</h1>
-<p>You can post from an email client! To set this up go to your &quot;Writing&quot; options screen and fill in the connection details for your secret POP3 account. Then you need to set up <code>wp-mail.php</code> to execute periodically to check the mailbox for new posts. You can do it with Cron-jobs, or if your host doesn't support it you can look into the various website-monitoring services, and make them check your <code>wp-mail.php</code> URL. </p>
-<p> Posting is easy: Any email sent to the address you specify will be posted, with the subject as the title. It is best to keep the address dicrete. The script will <i>delete</i> emails that are successfully posted. </p>
-<h1 id="roles">User Roles </h1>
+<p>You can post from an email client! To set this up go to your &quot;Writing&quot; options screen and fill in the connection details for your secret POP3 account. Then you need to set up <code>wp-mail.php</code> to execute periodically to check the mailbox for new posts. You can do it with Cron-jobs, or if your host doesn't support it you can look into the various website-monitoring services, and make them check your <code>wp-mail.php</code> URL.</p>
+<p>Posting is easy: Any email sent to the address you specify will be posted, with the subject as the title. It is best to keep the address dicrete. The script will <i>delete</i> emails that are successfully posted.</p>
 
+<h1>User Roles</h1>
 <p>We've eliminated user levels in order to make way for the much more flexible roles system introduced in 2.0. You can <a href="http://codex.wordpress.org/Roles_and_Capabilities">read more about Roles and Capabilities on the Codex</a>.</p>
 
 <h1> Final notes</h1>
 <ul>
-	<li>If you have any suggestions, ideas, comments, or if you (gasp!) found a bug, join us in the <a href="http://wordpress.org/support/">Support Forums</a></li>
+	<li>If you have any suggestions, ideas, comments, or if you (gasp!) found a bug, join us in the <a href="http://wordpress.org/support/">Support Forums</a>.</li>
 	<li>WordPress now has a robust plugin API that makes extending the code easy. If you are a developer interested in utilizing this see the <a href="http://codex.wordpress.org/Plugin_API">plugin documentation in the Codex</a>. In most all cases you shouldn't modify any of the core code.</li>
 </ul>
 
@@ -117,4 +88,4 @@
 <p>WordPress is released under the <abbr title="GNU Public License">GPL</abbr> (see <a href="license.txt">license.txt</a>).</p>
 
 </body>
-</html>
\ No newline at end of file
+</html>
Binary files 2.0.5/wp-admin/.DS_Store and 2.2.2/wp-admin/.DS_Store differ
diff -ruN 2.0.5/wp-admin/admin-ajax.php 2.2.2/wp-admin/admin-ajax.php
--- 2.0.5/wp-admin/admin-ajax.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/admin-ajax.php	2007-03-27 16:20:16.000000000 -0500
@@ -0,0 +1,296 @@
+<?php
+require_once('../wp-config.php');
+require_once('admin-functions.php');
+require_once('admin-db.php');
+
+define('DOING_AJAX', true);
+
+check_ajax_referer();
+if ( !is_user_logged_in() )
+	die('-1');
+
+function get_out_now() { exit; }
+add_action( 'shutdown', 'get_out_now', -1 );
+
+function wp_ajax_meta_row( $pid, $mid, $key, $value ) {
+	$value = attribute_escape($value);
+	$key_js = addslashes(wp_specialchars($key, 'double'));
+	$key = attribute_escape($key);
+	$r .= "<tr id='meta-$mid'><td valign='top'>";
+	$r .= "<input name='meta[$mid][key]' tabindex='6' onkeypress='return killSubmit(\"theList.ajaxUpdater(&#039;meta&#039;,&#039;meta-$mid&#039;);\",event);' type='text' size='20' value='$key' />";
+	$r .= "</td><td><textarea name='meta[$mid][value]' tabindex='6' rows='2' cols='30'>$value</textarea></td><td align='center'>";
+	$r .= "<input name='updatemeta' type='button' class='updatemeta' tabindex='6' value='".attribute_escape(__('Update'))."' onclick='return theList.ajaxUpdater(&#039;meta&#039;,&#039;meta-$mid&#039;);' /><br />";
+	$r .= "<input name='deletemeta[$mid]' type='submit' onclick=\"return deleteSomething( 'meta', $mid, '";
+	$r .= js_escape(sprintf(__("You are about to delete the '%s' custom field on this post.\n'OK' to delete, 'Cancel' to stop."), $key_js));
+	$r .= "' );\" class='deletemeta' tabindex='6' value='".attribute_escape(__('Delete'))."' /></td></tr>";
+	return $r;
+}
+
+$id = (int) $_POST['id'];
+switch ( $_POST['action'] ) :
+case 'delete-comment' :
+	if ( !$comment = get_comment( $id ) )
+		die('0');
+	if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
+		die('-1');
+
+	if ( wp_delete_comment( $comment->comment_ID ) )
+		die('1');
+	else	die('0');
+	break;
+case 'delete-comment-as-spam' :
+	if ( !$comment = get_comment( $id ) )
+		die('0');
+	if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
+		die('-1');
+
+	if ( wp_set_comment_status( $comment->comment_ID, 'spam' ) )
+		die('1');
+	else	die('0');
+	break;
+case 'delete-cat' :
+	if ( !current_user_can( 'manage_categories' ) )
+		die('-1');
+
+	if ( wp_delete_category( $id ) )
+		die('1');
+	else	die('0');
+	break;
+case 'delete-link' :
+	if ( !current_user_can( 'manage_links' ) )
+		die('-1');
+
+	if ( wp_delete_link( $id ) )
+		die('1');
+	else	die('0');
+	break;
+case 'delete-meta' :
+	if ( !$meta = get_post_meta_by_id( $id ) )
+		die('0');
+	if ( !current_user_can( 'edit_post', $meta->post_id ) )
+		die('-1');
+	if ( delete_meta( $meta->meta_id ) )
+		die('1');
+	die('0');
+	break;
+case 'delete-post' :
+	if ( !current_user_can( 'delete_post', $id ) )
+		die('-1');
+
+	if ( wp_delete_post( $id ) )
+		die('1');
+	else	die('0');
+	break;
+case 'delete-page' :
+	if ( !current_user_can( 'delete_page', $id ) )
+		die('-1');
+
+	if ( wp_delete_post( $id ) )
+		die('1');
+	else	die('0');
+	break;
+case 'dim-comment' :
+	if ( !$comment = get_comment( $id ) )
+		die('0');
+	if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
+		die('-1');
+	if ( !current_user_can( 'moderate_comments' ) )
+		die('-1');
+
+	if ( 'unapproved' == wp_get_comment_status($comment->comment_ID) ) {
+		if ( wp_set_comment_status( $comment->comment_ID, 'approve' ) )
+			die('1');
+	} else {
+		if ( wp_set_comment_status( $comment->comment_ID, 'hold' ) )
+			die('1');
+	}
+	die('0');
+	break;
+case 'add-category' : // On the Fly
+	if ( !current_user_can( 'manage_categories' ) )
+		die('-1');
+	$names = explode(',', $_POST['newcat']);
+	$x = new WP_Ajax_Response();
+	foreach ( $names as $cat_name ) {
+		$cat_name = trim($cat_name);
+		if ( !$category_nicename = sanitize_title($cat_name) )
+			die('0');
+		if ( !$cat_id = category_exists( $cat_name ) )
+			$cat_id = wp_create_category( $cat_name );
+		$cat_name = wp_specialchars(stripslashes($cat_name));
+		$x->add( array(
+			'what' => 'category',
+			'id' => $cat_id,
+			'data' => "<li id='category-$cat_id'><label for='in-category-$cat_id' class='selectit'><input value='$cat_id' type='checkbox' checked='checked' name='post_category[]' id='in-category-$cat_id'/> $cat_name</label></li>"
+		) );
+	}
+	$x->send();
+	break;
+case 'add-cat' : // From Manage->Categories
+	if ( !current_user_can( 'manage_categories' ) )
+		die('-1');
+	if ( !$cat = wp_insert_category( $_POST ) )
+		die('0');
+	if ( !$cat = get_category( $cat ) )
+		die('0');
+	$level = 0;
+	$cat_full_name = $cat->cat_name;
+	$_cat = $cat;
+	while ( $_cat->category_parent ) {
+		$_cat = get_category( $_cat->category_parent );
+		$cat_full_name = $_cat->cat_name . ' &#8212; ' . $cat_full_name;
+		$level++;
+	}
+	$cat_full_name = attribute_escape($cat_full_name);
+
+	$x = new WP_Ajax_Response( array(
+		'what' => 'cat',
+		'id' => $cat->cat_ID,
+		'data' => _cat_row( $cat, $level, $cat_full_name ),
+		'supplemental' => array('name' => $cat_full_name, 'show-link' => sprintf(__( 'Category <a href="#%s">%s</a> added' ), "cat-$cat->cat_ID", $cat_full_name))
+	) );
+	$x->send();
+	break;
+case 'add-comment' :
+	if ( !current_user_can( 'edit_post', $id ) )
+		die('-1');
+	$search = isset($_POST['s']) ? $_POST['s'] : false;
+	$start = isset($_POST['page']) ? intval($_POST['page']) * 25 : 25;
+
+	list($comments, $total) = _wp_get_comment_list( $search, $start, 1 );
+
+	if ( !$comments )
+		die('1');
+	$x = new WP_Ajax_Response();
+	foreach ( (array) $comments as $comment ) {
+		get_comment( $comment );
+		ob_start();
+			_wp_comment_list_item( $comment->comment_ID );
+			$comment_list_item = ob_get_contents();
+		ob_end_clean();
+		$x->add( array(
+			'what' => 'comment',
+			'id' => $comment->comment_ID,
+			'data' => $comment_list_item
+		) );
+	}
+	$x->send();
+	break;
+case 'add-meta' :
+	if ( !current_user_can( 'edit_post', $id ) )
+		die('-1');
+	if ( $id < 0 ) {
+		$now = current_time('timestamp', 1);
+		if ( $pid = wp_insert_post( array(
+			'post_title' => sprintf('Draft created on %s at %s', date(get_option('date_format'), $now), date(get_option('time_format'), $now))
+		) ) )
+			$mid = add_meta( $pid );
+		else
+			die('0');
+	} else if ( !$mid = add_meta( $id ) ) {
+		die('0');
+	}
+
+	$meta = get_post_meta_by_id( $mid );
+	$key = $meta->meta_key;
+	$value = $meta->meta_value;
+	$pid = (int) $meta->post_id;
+
+	$x = new WP_Ajax_Response( array(
+		'what' => 'meta',
+		'id' => $mid,
+		'data' => wp_ajax_meta_row( $pid, $mid, $key, $value ),
+		'supplemental' => array('postid' => $pid)
+	) );
+	$x->send();
+	break;
+case 'update-meta' :
+	$mid = (int) array_pop(array_keys($_POST['meta']));
+	$key = $_POST['meta'][$mid]['key'];
+	$value = $_POST['meta'][$mid]['value'];
+	if ( !$meta = get_post_meta_by_id( $mid ) )
+		die('0'); // if meta doesn't exist
+	if ( !current_user_can( 'edit_post', $meta->post_id ) )
+		die('-1');
+	if ( $u = update_meta( $mid, $key, $value ) ) {
+		$key = stripslashes($key);
+		$value = stripslashes($value);
+		$x = new WP_Ajax_Response( array(
+			'what' => 'meta',
+			'id' => $mid,
+			'data' => wp_ajax_meta_row( $meta->post_id, $mid, $key, $value ),
+			'supplemental' => array('postid' => $meta->post_id)
+		) );
+		$x->send();
+	}
+	die('1'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
+	break;
+case 'add-user' :
+	if ( !current_user_can('edit_users') )
+		die('-1');
+	require_once(ABSPATH . WPINC . '/registration.php');
+	if ( !$user_id = add_user() )
+		die('0');
+	elseif ( is_wp_error( $user_id ) ) {
+		foreach( $user_id->get_error_messages() as $message )
+			echo "<p>$message<p>";
+		exit;
+	}
+	$user_object = new WP_User( $user_id );
+	$x = new WP_Ajax_Response( array(
+		'what' => 'user',
+		'id' => $user_id,
+		'data' => user_row( $user_object ),
+		'supplemental' => array('show-link' => sprintf(__( 'User <a href="#%s">%s</a> added' ), "user-$user_id", $user_object->user_login))
+	) );
+	$x->send();
+	break;
+case 'autosave' : // The name of this action is hardcoded in edit_post()
+	$_POST['post_content'] = $_POST['content'];
+	$_POST['post_excerpt'] = $_POST['excerpt'];
+	$_POST['post_status'] = 'draft';
+	$_POST['post_category'] = explode(",", $_POST['catslist']);
+	if($_POST['post_type'] == 'page' || empty($_POST['post_category']))
+		unset($_POST['post_category']);
+
+	if($_POST['post_ID'] < 0) {
+		$_POST['temp_ID'] = $_POST['post_ID'];
+		$id = wp_write_post();
+		if( is_wp_error($id) )
+			die($id->get_error_message());
+		else
+			die("$id");
+	} else {
+		$post_ID = (int) $_POST['post_ID'];
+		$_POST['ID'] = $post_ID;
+		$post = get_post($post_ID);
+		if ( 'page' == $post->post_type ) {
+			if ( !current_user_can('edit_page', $post_ID) )
+				die(__('You are not allowed to edit this page.'));
+		} else {
+			if ( !current_user_can('edit_post', $post_ID) )
+				die(__('You are not allowed to edit this post.'));
+		}
+		wp_update_post($_POST);
+	}
+	die('0');
+break;
+case 'autosave-generate-nonces' :
+	$ID = (int) $_POST['post_ID'];
+	if($_POST['post_type'] == 'post') {
+		if(current_user_can('edit_post', $ID))
+			die(wp_create_nonce('update-post_' . $ID));
+	}
+	if($_POST['post_type'] == 'page') {
+		if(current_user_can('edit_page', $ID)) {
+			die(wp_create_nonce('update-page_' . $ID));
+		}
+	}
+	die($_POST['post_type']);
+break;
+default :
+	do_action( 'wp_ajax_' . $_POST['action'] );
+	die('0');
+	break;
+endswitch;
+?>
diff -ruN 2.0.5/wp-admin/admin-db.php 2.2.2/wp-admin/admin-db.php
--- 2.0.5/wp-admin/admin-db.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/admin-db.php	2007-07-13 13:30:06.000000000 -0500
@@ -3,7 +3,7 @@
 function get_users_drafts( $user_id ) {
 	global $wpdb;
 	$user_id = (int) $user_id;
-	$query = "SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'draft' AND post_author = $user_id ORDER BY ID DESC";
+	$query = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'draft' AND post_author = $user_id ORDER BY ID DESC";
 	$query = apply_filters('get_users_drafts', $query);
 	return $wpdb->get_results( $query );
 }
@@ -14,12 +14,12 @@
 	$level_key = $wpdb->prefix . 'user_level';
 
 	$editable = get_editable_user_ids( $user_id );
-	
+
 	if( !$editable ) {
 		$other_drafts = '';
 	} else {
 		$editable = join(',', $editable);
-		$other_drafts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'draft' AND post_author IN ($editable) AND post_author != '$user_id' ");
+		$other_drafts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'draft' AND post_author IN ($editable) AND post_author != '$user_id' ");
 	}
 
 	return apply_filters('get_others_drafts', $other_drafts);
@@ -42,13 +42,13 @@
 
 function get_editable_user_ids( $user_id, $exclude_zeros = true ) {
 	global $wpdb;
-	
+
 	$user = new WP_User( $user_id );
-	
+
 	if ( ! $user->has_cap('edit_others_posts') ) {
 		if ( $user->has_cap('edit_posts') || $exclude_zeros == false )
 			return array($user->id);
-		else 
+		else
 			return false;
 	}
 
@@ -57,7 +57,7 @@
 	$query = "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '$level_key'";
 	if ( $exclude_zeros )
 		$query .= " AND meta_value != '0'";
-		
+
 	return $wpdb->get_col( $query );
 }
 
@@ -82,7 +82,10 @@
 function wp_insert_category($catarr) {
 	global $wpdb;
 
-	extract($catarr);
+	extract($catarr, EXTR_SKIP);
+
+	if( trim( $cat_name ) == '' )
+		return 0;
 
 	$cat_ID = (int) $cat_ID;
 
@@ -93,7 +96,7 @@
 		$update = false;
 
 	$cat_name = apply_filters('pre_category_name', $cat_name);
-	
+
 	if (empty ($category_nicename))
 		$category_nicename = sanitize_title($cat_name);
 	else
@@ -105,31 +108,51 @@
 	$category_description = apply_filters('pre_category_description', $category_description);
 
 	$category_parent = (int) $category_parent;
-	if (empty ($category_parent))
+	if ( empty($category_parent) || !get_category( $category_parent ) || ($cat_ID && cat_is_ancestor_of($cat_ID, $category_parent) ) )
 		$category_parent = 0;
 
+	if ( isset($posts_private) )
+		$posts_private = (int) $posts_private;
+	else
+		$posts_private = 0;
+
+	if ( isset($links_private) )
+		$links_private = (int) $links_private;
+	else
+		$links_private = 0;
+
 	if (!$update) {
-		$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_description, category_parent) VALUES ('0', '$cat_name', '$category_nicename', '$category_description', '$category_parent')");
-		$cat_ID = $wpdb->insert_id;
+		$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_description, category_parent, links_private, posts_private) VALUES ('0', '$cat_name', '$category_nicename', '$category_description', '$category_parent', '$links_private', '$posts_private')");
+		$cat_ID = (int) $wpdb->insert_id;
 	} else {
-		$wpdb->query ("UPDATE $wpdb->categories SET cat_name = '$cat_name', category_nicename = '$category_nicename', category_description = '$category_description', category_parent = '$category_parent' WHERE cat_ID = '$cat_ID'");
+		$wpdb->query ("UPDATE $wpdb->categories SET cat_name = '$cat_name', category_nicename = '$category_nicename', category_description = '$category_description', category_parent = '$category_parent', links_private = '$links_private', posts_private = '$posts_private' WHERE cat_ID = '$cat_ID'");
 	}
-	
+
 	if ( $category_nicename == '' ) {
 		$category_nicename = sanitize_title($cat_name, $cat_ID );
 		$wpdb->query( "UPDATE $wpdb->categories SET category_nicename = '$category_nicename' WHERE cat_ID = '$cat_ID'" );
 	}
 
-	wp_cache_delete($cat_ID, 'category');
+	// Keep in mind when using this filter and altering the cat_ID that the two queries above
+	// have already taken place with the OLD cat_ID
+	// Also note that you may have post2cat entries with the old cat_ID if this is an update
 
 	if ($update) {
 		do_action('edit_category', $cat_ID);
 	} else {
-		wp_cache_delete('all_category_ids', 'category');
 		do_action('create_category', $cat_ID);
 		do_action('add_category', $cat_ID);
 	}
 
+	$cat_ID = apply_filters('cat_id_filter', $cat_ID, $update);
+
+	clean_category_cache($cat_ID);
+
+	if ($update)
+		do_action('edited_category', $cat_ID);
+	else
+		do_action('created_category', $cat_ID);
+	
 	return $cat_ID;
 }
 
@@ -138,6 +161,9 @@
 
 	$cat_ID = (int) $catarr['cat_ID'];
 
+	if( $cat_ID == $catarr['category_parent'] )
+		return false;
+
 	// First, get all of the original fields
 	$category = get_category($cat_ID, ARRAY_A);
 
@@ -154,30 +180,47 @@
 	global $wpdb;
 
 	$cat_ID = (int) $cat_ID;
+	$default_cat = get_option('default_category');
+	$default_link_cat = get_option('default_link_category');
 
-	// Don't delete the default cat.
-	if ($cat_ID == get_option('default_category'))
+	// Don't delete either of the default cats
+	if ( $cat_ID == $default_cat || $cat_ID == $default_link_cat )
 		return 0;
 
 	$category = get_category($cat_ID);
 
 	$parent = $category->category_parent;
 
-	// Delete the category.
-	$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'");
+	// Delete the category
+	if ( !$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'") )
+		return 0;
 
-	// Update children to point to new parent.
+	// Update children to point to new parent
 	$wpdb->query("UPDATE $wpdb->categories SET category_parent = '$parent' WHERE category_parent = '$cat_ID'");
 
-	// TODO: Only set categories to general if they're not in another category already
-	$default_cat = get_option('default_category');
-	$wpdb->query("UPDATE $wpdb->post2cat SET category_id='$default_cat' WHERE category_id='$cat_ID'");
+	// Only set posts and links to the default category if they're not in another category already
+	$posts = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE category_id='$cat_ID'");
+	foreach ( (array) $posts as $post_id ) {
+		$cats = wp_get_post_categories($post_id);
+		if ( 1 == count($cats) )
+			$cats = array($default_cat);
+		else
+			$cats = array_diff($cats, array($cat_ID));
+		wp_set_post_categories($post_id, $cats);
+	}
 
-	wp_cache_delete($cat_ID, 'category');
-	wp_cache_delete('all_category_ids', 'category');
+	$links = $wpdb->get_col("SELECT link_id FROM $wpdb->link2cat WHERE category_id='$cat_ID'");
+	foreach ( (array) $links as $link_id ) {
+		$cats = wp_get_link_cats($link_id);
+		if ( 1 == count($cats) )
+			$cats = array($default_link_cat);
+		else
+			$cats = array_diff($cats, array($cat_ID));
+		wp_set_link_cats($link_id, $cats);
+	}
 
+	clean_category_cache($cat_ID);
 	do_action('delete_category', $cat_ID);
-
 	return 1;
 }
 
@@ -197,7 +240,7 @@
 	}
 
 	if ($post_id)
-		wp_set_post_cats('', $post_id, $cat_ids);
+		wp_set_post_categories($post_id, $cat_ids);
 
 	return $cat_ids;
 }
@@ -207,7 +250,7 @@
 	if (!$category_nicename = sanitize_title($cat_name))
 		return 0;
 
-	return $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE category_nicename = '$category_nicename'");
+	return (int) $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE category_nicename = '$category_nicename'");
 }
 
 function wp_delete_user($id, $reassign = 'novalue') {
@@ -233,43 +276,36 @@
 	}
 
 	// FINALLY, delete user
+	do_action('delete_user', $id);
+
 	$wpdb->query("DELETE FROM $wpdb->users WHERE ID = $id");
 	$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$id'");
 
 	wp_cache_delete($id, 'users');
 	wp_cache_delete($user->user_login, 'userlogins');
 
-	do_action('delete_user', $id);
-
 	return true;
 }
 
-function get_link($link_id, $output = OBJECT) {
-	global $wpdb;
-	
-	$link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = '$link_id'");
+function wp_revoke_user($id) {
+	$id = (int) $id;
 
-	if ( $output == OBJECT ) {
-		return $link;
-	} elseif ( $output == ARRAY_A ) {
-		return get_object_vars($link);
-	} elseif ( $output == ARRAY_N ) {
-		return array_values(get_object_vars($link));
-	} else {
-		return $link;
-	}
+	$user = new WP_User($id);
+	$user->remove_all_caps();
 }
 
 function wp_insert_link($linkdata) {
 	global $wpdb, $current_user;
-	
-	extract($linkdata);
+
+	extract($linkdata, EXTR_SKIP);
 
 	$update = false;
 
 	if ( !empty($link_id) )
 		$update = true;
 
+	$link_id = (int) $link_id;
+
 	if( trim( $link_name ) == '' )
 		return 0;
 	$link_name = apply_filters('pre_link_name', $link_name);
@@ -279,7 +315,7 @@
 	$link_url = apply_filters('pre_link_url', $link_url);
 
 	if ( empty($link_rating) )
-		$link_rating = 0;	
+		$link_rating = 0;
 	else
 		$link_rating = (int) $link_rating;
 
@@ -288,7 +324,7 @@
 	$link_image = apply_filters('pre_link_image', $link_image);
 
 	if ( empty($link_target) )
-		$link_target = '';	
+		$link_target = '';
 	$link_target = apply_filters('pre_link_target', $link_target);
 
 	if ( empty($link_visible) )
@@ -316,19 +352,26 @@
 		$link_rel = '';
 	$link_rel = apply_filters('pre_link_rel', $link_rel);
 
+	// Make sure we set a valid category
+	if (0 == count($link_category) || !is_array($link_category)) {
+		$link_category = array(get_option('default_link_category'));
+	}
+
 	if ( $update ) {
 		$wpdb->query("UPDATE $wpdb->links SET link_url='$link_url',
 			link_name='$link_name', link_image='$link_image',
-			link_target='$link_target', link_category='$link_category',
+			link_target='$link_target',
 			link_visible='$link_visible', link_description='$link_description',
 			link_rating='$link_rating', link_rel='$link_rel',
 			link_notes='$link_notes', link_rss = '$link_rss'
 			WHERE link_id='$link_id'");
 	} else {
-		$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_image, link_target, link_category, link_description, link_visible, link_owner, link_rating, link_rel, link_notes, link_rss) VALUES('$link_url','$link_name', '$link_image', '$link_target', '$link_category', '$link_description', '$link_visible', '$link_owner', '$link_rating', '$link_rel', '$link_notes', '$link_rss')");
-		$link_id = $wpdb->insert_id;
+		$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_image, link_target, link_description, link_visible, link_owner, link_rating, link_rel, link_notes, link_rss) VALUES('$link_url','$link_name', '$link_image', '$link_target', '$link_description', '$link_visible', '$link_owner', '$link_rating', '$link_rel', '$link_notes', '$link_rss')");
+		$link_id = (int) $wpdb->insert_id;
 	}
-	
+
+	wp_set_link_cats($link_id, $link_category);
+
 	if ( $update )
 		do_action('edit_link', $link_id);
 	else
@@ -341,14 +384,22 @@
 	global $wpdb;
 
 	$link_id = (int) $linkdata['link_id'];
-	
+
 	$link = get_link($link_id, ARRAY_A);
-	
+
 	// Escape data pulled from DB.
 	$link = add_magic_quotes($link);
-	
+
+	// Passed link category list overwrites existing category list if not empty.
+	if ( isset($linkdata['link_category']) && is_array($linkdata['link_category'])
+			 && 0 != count($linkdata['link_category']) )
+		$link_cats = $linkdata['link_category'];
+	else
+		$link_cats = $link['link_category'];
+
 	// Merge old and new fields with new fields overwriting old ones.
 	$linkdata = array_merge($link, $linkdata);
+	$linkdata['link_category'] = $link_cats;
 
 	return wp_insert_link($linkdata);
 }
@@ -357,9 +408,98 @@
 	global $wpdb;
 
 	do_action('delete_link', $link_id);
-	return $wpdb->query("DELETE FROM $wpdb->links WHERE link_id = '$link_id'");	
+
+	$categories = wp_get_link_cats($link_id);
+	if( is_array( $categories ) ) {
+		foreach ( $categories as $category ) {
+			$wpdb->query("UPDATE $wpdb->categories SET link_count = link_count - 1 WHERE cat_ID = '$category'");
+			wp_cache_delete($category, 'category');
+			do_action('edit_category', $cat_id);
+		}
+	}
+
+	$wpdb->query("DELETE FROM $wpdb->link2cat WHERE link_id = '$link_id'");
+	$wpdb->query("DELETE FROM $wpdb->links WHERE link_id = '$link_id'");
+	
+	do_action('deleted_link', $link_id);
+
+	return true;
+}
+
+function wp_get_link_cats($link_ID = 0) {
+	global $wpdb;
+
+	$sql = "SELECT category_id
+		FROM $wpdb->link2cat
+		WHERE link_id = $link_ID
+		ORDER BY category_id";
+
+	$result = $wpdb->get_col($sql);
+
+	if ( !$result )
+		$result = array();
+
+	return array_unique($result);
 }
 
+function wp_set_link_cats($link_ID = 0, $link_categories = array()) {
+	global $wpdb;
+	// If $link_categories isn't already an array, make it one:
+	if (!is_array($link_categories) || 0 == count($link_categories))
+		$link_categories = array(get_option('default_link_category'));
+
+	$link_categories = array_unique($link_categories);
+
+	// First the old categories
+	$old_categories = $wpdb->get_col("
+		SELECT category_id
+		FROM $wpdb->link2cat
+		WHERE link_id = '$link_ID'");
+
+	if (!$old_categories) {
+		$old_categories = array();
+	} else {
+		$old_categories = array_unique($old_categories);
+	}
+
+	// Delete any?
+	$delete_cats = array_diff($old_categories,$link_categories);
+
+	if ($delete_cats) {
+		foreach ($delete_cats as $del) {
+			$del = (int) $del;
+			$wpdb->query("
+				DELETE FROM $wpdb->link2cat
+				WHERE category_id = '$del'
+					AND link_id = '$link_ID'
+				");
+		}
+	}
+
+	// Add any?
+	$add_cats = array_diff($link_categories, $old_categories);
+
+	if ($add_cats) {
+		foreach ($add_cats as $new_cat) {
+			$new_cat = (int) $new_cat;
+			if ( !empty($new_cat) )
+				$wpdb->query("
+					INSERT INTO $wpdb->link2cat (link_id, category_id)
+					VALUES ('$link_ID', '$new_cat')");
+		}
+	}
+
+	// Update category counts.
+	$all_affected_cats = array_unique(array_merge($link_categories, $old_categories));
+	foreach ( $all_affected_cats as $cat_id ) {
+		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->link2cat, $wpdb->links WHERE $wpdb->links.link_id = $wpdb->link2cat.link_id AND category_id = '$cat_id'");
+		$wpdb->query("UPDATE $wpdb->categories SET link_count = '$count' WHERE cat_ID = '$cat_id'");
+		wp_cache_delete($cat_id, 'category');
+		do_action('edit_category', $cat_id);
+	}
+
+}	// wp_set_link_cats()
+
 function post_exists($title, $content = '', $post_date = '') {
 	global $wpdb;
 
diff -ruN 2.0.5/wp-admin/admin-footer.php 2.2.2/wp-admin/admin-footer.php
--- 2.0.5/wp-admin/admin-footer.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/admin-footer.php	2006-10-05 20:14:47.000000000 -0500
@@ -1,19 +1,10 @@
 
-<div id="footer"><p><a href="http://wordpress.org/" id="wordpress-logo"><img src="images/wordpress-logo.png" alt="WordPress" /></a></p>
-<p>
-<a href="http://codex.wordpress.org/"><?php _e('Documentation'); ?></a> &#8212; <a href="http://wordpress.org/support/"><?php _e('Support Forums'); ?></a> <br />
-<?php bloginfo('version'); ?> &#8212; <?php printf(__('%s seconds'), timer_stop(0, 2)); ?>
-</p>
-
+<div id="footer">
+<p class="logo"><a href="http://wordpress.org/" id="wordpress-logo"><img src="images/wordpress-logo.png" alt="WordPress" /></a></p>
+<p class="docs"><?php _e('<a href="http://codex.wordpress.org/">Documentation</a>'); ?> &#8212; <?php _e('<a href="http://wordpress.org/support/">Support Forums</a>'); ?><br />
+<?php bloginfo('version'); ?> &#8212; <?php printf(__('%s seconds'), timer_stop(0, 2)); ?></p>
 </div>
 <?php do_action('admin_footer', ''); ?>
 <script type="text/javascript">if(typeof wpOnload=='function')wpOnload();</script>
-
-<?php
-if ( (substr(php_sapi_name(), 0, 3) == 'cgi') && spawn_pinger() ) {
-	echo '<iframe id="pingcheck" src="' . get_settings('siteurl') .'/wp-admin/execute-pings.php?time=' . time() . '" style="border:none;width:1px;height:1px;"></iframe>';
-}
-?>
-
 </body>
-</html>
+</html>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/admin-functions.php 2.2.2/wp-admin/admin-functions.php
--- 2.0.5/wp-admin/admin-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/admin-functions.php	2007-08-02 09:58:15.000000000 -0500
@@ -1,11 +1,43 @@
 <?php
 
-// Creates a new post from the "Write Post" form using $_POST information.
 function write_post() {
+	$result = wp_write_post();
+	if( is_wp_error( $result ) )
+		wp_die( $result->get_error_message() );
+	else
+		return $result;
+}
+
+// Creates a new post from the "Write Post" form using $_POST information.
+function wp_write_post() {
 	global $user_ID;
 
-	if (!current_user_can('edit_posts'))
-		die(__('You are not allowed to create posts or drafts on this blog.'));
+	if ( 'page' == $_POST['post_type'] ) {
+		if ( !current_user_can( 'edit_pages' ) )
+			return new WP_Error( 'edit_pages', __( 'You are not allowed to create pages on this blog.' ) );
+	} else {
+		if ( !current_user_can( 'edit_posts' ) )
+			return new WP_Error( 'edit_posts', __( 'You are not allowed to create posts or drafts on this blog.' ) );
+	}
+
+
+	// Check for autosave collisions
+	$temp_id = false;
+	if ( isset($_POST['temp_ID']) ) {
+		$temp_id = (int) $_POST['temp_ID'];
+		if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
+			$draft_ids = array();
+		foreach ( $draft_ids as $temp => $real )
+			if ( time() + $temp > 86400 ) // 1 day: $temp is equal to -1 * time( then )
+				unset($draft_ids[$temp]);
+
+		if ( isset($draft_ids[$temp_id]) ) { // Edit, don't write
+			$_POST['post_ID'] = $draft_ids[$temp_id];
+			unset($_POST['temp_ID']);
+			update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
+			return edit_post();
+		}
+	}
 
 	// Rename.
 	$_POST['post_content'] = $_POST['content'];
@@ -13,119 +45,140 @@
 	$_POST['post_parent'] = $_POST['parent_id'];
 	$_POST['to_ping'] = $_POST['trackback_url'];
 
-	if (!empty ($_POST['post_author_override'])) {
+	if (!empty ( $_POST['post_author_override'] ) ) {
 		$_POST['post_author'] = (int) $_POST['post_author_override'];
-	} else
-		if (!empty ($_POST['post_author'])) {
+	} else {
+		if (!empty ( $_POST['post_author'] ) ) {
 			$_POST['post_author'] = (int) $_POST['post_author'];
 		} else {
 			$_POST['post_author'] = (int) $_POST['user_ID'];
 		}
 
-	if (($_POST['post_author'] != $_POST['user_ID']) && !current_user_can('edit_others_posts'))
-		die(__('You cannot post as this user.'));
+	}
+
+	if ( $_POST['post_author'] != $_POST['user_ID'] ) {
+		if ( 'page' == $_POST['post_type'] ) {
+			if ( !current_user_can( 'edit_others_pages' ) )
+				return new WP_Error( 'edit_others_pages', __( 'You are not allowed to create pages as this user.' ) );
+		} else {
+			if ( !current_user_can( 'edit_others_posts' ) )
+				return new WP_Error( 'edit_others_posts', __( 'You are not allowed to post as this user.' ) );
+
+		}
+	}
 
 	// What to do based on which button they pressed
-	if ('' != $_POST['saveasdraft'])
+	if ('' != $_POST['saveasdraft'] )
 		$_POST['post_status'] = 'draft';
-	if ('' != $_POST['saveasprivate'])
+	if ('' != $_POST['saveasprivate'] )
 		$_POST['post_status'] = 'private';
-	if ('' != $_POST['publish'])
+	if ('' != $_POST['publish'] )
 		$_POST['post_status'] = 'publish';
-	if ('' != $_POST['advanced'])
-		$_POST['post_status'] = 'draft';
-	if ('' != $_POST['savepage'])
-		$_POST['post_status'] = 'static';
-
-	if ('publish' == $_POST['post_status'] && !current_user_can('publish_posts'))
+	if ('' != $_POST['advanced'] )
 		$_POST['post_status'] = 'draft';
 
-	if ('static' == $_POST['post_status'] && !current_user_can('edit_pages'))
-		die(__('This user cannot edit pages.'));
+	if ( 'page' == $_POST['post_type'] ) {
+		if ('publish' == $_POST['post_status'] && !current_user_can( 'publish_pages' ) )
+			$_POST['post_status'] = 'draft';
+	} else {
+		if ('publish' == $_POST['post_status'] && !current_user_can( 'publish_posts' ) )
+			$_POST['post_status'] = 'draft';
+	}
 
-	if (!isset ($_POST['comment_status']))
+	if (!isset( $_POST['comment_status'] ))
 		$_POST['comment_status'] = 'closed';
 
-	if (!isset ($_POST['ping_status']))
+	if (!isset( $_POST['ping_status'] ))
 		$_POST['ping_status'] = 'closed';
 
-	if (!empty ($_POST['edit_date'])) {
+	if (!empty ( $_POST['edit_date'] ) ) {
 		$aa = $_POST['aa'];
 		$mm = $_POST['mm'];
 		$jj = $_POST['jj'];
 		$hh = $_POST['hh'];
 		$mn = $_POST['mn'];
 		$ss = $_POST['ss'];
-		$jj = ($jj > 31) ? 31 : $jj;
-		$hh = ($hh > 23) ? $hh -24 : $hh;
-		$mn = ($mn > 59) ? $mn -60 : $mn;
-		$ss = ($ss > 59) ? $ss -60 : $ss;
-		$_POST['post_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
-		$_POST['post_date_gmt'] = get_gmt_from_date("$aa-$mm-$jj $hh:$mn:$ss");
+		$jj = ($jj > 31 ) ? 31 : $jj;
+		$hh = ($hh > 23 ) ? $hh -24 : $hh;
+		$mn = ($mn > 59 ) ? $mn -60 : $mn;
+		$ss = ($ss > 59 ) ? $ss -60 : $ss;
+		$_POST['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss );
+		$_POST['post_date_gmt'] = get_gmt_from_date( $_POST['post_date'] );
 	}
 
 	// Create the post.
-	$post_ID = wp_insert_post($_POST);
-	add_meta($post_ID);
+	$post_ID = wp_insert_post( $_POST );
+
+	add_meta( $post_ID );
 
 	// Reunite any orphaned attachments with their parent
-	if ( $_POST['temp_ID'] )
-		relocate_children($_POST['temp_ID'], $post_ID);
+	if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
+		$draft_ids = array();
+	if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
+		relocate_children( $draft_temp_id, $post_ID );
+	if ( $temp_id && $temp_id != $draft_temp_id )
+		relocate_children( $temp_id, $post_ID );
+
+	// Update autosave collision detection
+	if ( $temp_id ) {
+		$draft_ids[$temp_id] = $post_ID;
+		update_user_option( $user_ID, 'autosave_draft_ids', $draft_ids );
+	}
 
 	// Now that we have an ID we can fix any attachment anchor hrefs
-	fix_attachment_links($post_ID);
+	fix_attachment_links( $post_ID );
 
 	return $post_ID;
 }
 
 // Move child posts to a new parent
-function relocate_children($old_ID, $new_ID) {
+function relocate_children( $old_ID, $new_ID ) {
 	global $wpdb;
 	$old_ID = (int) $old_ID;
 	$new_ID = (int) $new_ID;
-	return $wpdb->query("UPDATE $wpdb->posts SET post_parent = $new_ID WHERE post_parent = $old_ID");
+	return $wpdb->query( "UPDATE $wpdb->posts SET post_parent = $new_ID WHERE post_parent = $old_ID" );
 }
 
 // Replace hrefs of attachment anchors with up-to-date permalinks.
-function fix_attachment_links($post_ID) {
+function fix_attachment_links( $post_ID ) {
 	global $wp_rewrite;
 
-	$post = & get_post($post_ID, ARRAY_A);
+	$post = & get_post( $post_ID, ARRAY_A );
 
 	$search = "#<a[^>]+rel=('|\")[^'\"]*attachment[^>]*>#ie";
 
 	// See if we have any rel="attachment" links
-	if ( 0 == preg_match_all($search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER) )
+	if ( 0 == preg_match_all( $search, $post['post_content'], $anchor_matches, PREG_PATTERN_ORDER ) )
 		return;
 
 	$i = 0;
-	$search = "# id=(\"|')p(\d+)\\1#i";
+	$search = "#[\s]+rel=(\"|')(.*?)wp-att-(\d+)\\1#i";
 	foreach ( $anchor_matches[0] as $anchor ) {
-		if ( 0 == preg_match($search, $anchor, $id_matches) )
+		if ( 0 == preg_match( $search, $anchor, $id_matches ) )
 			continue;
 
-		$id = $id_matches[2];
+		$id = (int) $id_matches[3];
 
 		// While we have the attachment ID, let's adopt any orphans.
-		$attachment = & get_post($id, ARRAY_A);
-		if ( ! empty($attachment) && ! is_object(get_post($attachment['post_parent'])) ) {
+		$attachment = & get_post( $id, ARRAY_A );
+		if ( ! empty( $attachment) && ! is_object( get_post( $attachment['post_parent'] ) ) ) {
 			$attachment['post_parent'] = $post_ID;
 			// Escape data pulled from DB.
-			$attachment = add_magic_quotes($attachment);
-			wp_update_post($attachment);
+			$attachment = add_magic_quotes( $attachment);
+			wp_update_post( $attachment);
 		}
 
 		$post_search[$i] = $anchor;
-		$post_replace[$i] = preg_replace("#href=(\"|')[^'\"]*\\1#e", "stripslashes('href=\\1').get_attachment_link($id).stripslashes('\\1')", $anchor);
+		$post_replace[$i] = preg_replace( "#href=(\"|')[^'\"]*\\1#e", "stripslashes( 'href=\\1' ).get_attachment_link( $id ).stripslashes( '\\1' )", $anchor );
 		++$i;
 	}
 
-	$post['post_content'] = str_replace($post_search, $post_replace, $post['post_content']);
+	$post['post_content'] = str_replace( $post_search, $post_replace, $post['post_content'] );
 
 	// Escape data pulled from DB.
-	$post = add_magic_quotes($post);
+	$post = add_magic_quotes( $post);
 
-	return wp_update_post($post);
+	return wp_update_post( $post);
 }
 
 // Update an existing post with values provided in $_POST.
@@ -134,8 +187,24 @@
 
 	$post_ID = (int) $_POST['post_ID'];
 
-	if (!current_user_can('edit_post', $post_ID))
-		die(__('You are not allowed to edit this post.'));
+	if ( 'page' == $_POST['post_type'] ) {
+		if ( !current_user_can( 'edit_page', $post_ID ) )
+			wp_die( __('You are not allowed to edit this page.' ));
+	} else {
+		if ( !current_user_can( 'edit_post', $post_ID ) )
+			wp_die( __('You are not allowed to edit this post.' ));
+	}
+
+	// Autosave shouldn't save too soon after a real save
+	if ( 'autosave' == $_POST['action'] ) {
+		$post =& get_post( $post_ID );
+		$now = time();
+		$then = strtotime($post->post_date_gmt . ' +0000');
+		// Keep autosave_interval in sync with autosave-js.php.
+		$delta = apply_filters( 'autosave_interval', 120 ) / 2;
+		if ( ($now - $then) < $delta )
+			return $post_ID;
+	}
 
 	// Rename.
 	$_POST['ID'] = (int) $_POST['post_ID'];
@@ -144,74 +213,88 @@
 	$_POST['post_parent'] = $_POST['parent_id'];
 	$_POST['to_ping'] = $_POST['trackback_url'];
 
-	if (!empty ($_POST['post_author_override'])) {
+	if (!empty ( $_POST['post_author_override'] ) ) {
 		$_POST['post_author'] = (int) $_POST['post_author_override'];
 	} else
-		if (!empty ($_POST['post_author'])) {
+		if (!empty ( $_POST['post_author'] ) ) {
 			$_POST['post_author'] = (int) $_POST['post_author'];
 		} else {
 			$_POST['post_author'] = (int) $_POST['user_ID'];
 		}
 
-	if (($_POST['post_author'] != $_POST['user_ID']) && !current_user_can('edit_others_posts'))
-		die(__('You cannot post as this user.'));
+	if ( $_POST['post_author'] != $_POST['user_ID'] ) {
+		if ( 'page' == $_POST['post_type'] ) {
+			if ( !current_user_can( 'edit_others_pages' ) )
+				wp_die( __('You are not allowed to edit pages as this user.' ));
+		} else {
+			if ( !current_user_can( 'edit_others_posts' ) )
+				wp_die( __('You are not allowed to edit posts as this user.' ));
+
+		}
+	}
 
 	// What to do based on which button they pressed
-	if ('' != $_POST['saveasdraft'])
+	if ('' != $_POST['saveasdraft'] )
 		$_POST['post_status'] = 'draft';
-	if ('' != $_POST['saveasprivate'])
+	if ('' != $_POST['saveasprivate'] )
 		$_POST['post_status'] = 'private';
-	if ('' != $_POST['publish'])
+	if ('' != $_POST['publish'] )
 		$_POST['post_status'] = 'publish';
-	if ('' != $_POST['advanced'])
-		$_POST['post_status'] = 'draft';
-	if ('' != $_POST['savepage'])
-		$_POST['post_status'] = 'static';
-
-	if ('publish' == $_POST['post_status'] && !current_user_can('publish_posts'))
+	if ('' != $_POST['advanced'] )
 		$_POST['post_status'] = 'draft';
 
-	if ('static' == $_POST['post_status'] && !current_user_can('edit_pages'))
-		die(__('This user cannot edit pages.'));
+	if ( 'page' == $_POST['post_type'] ) {
+		if ('publish' == $_POST['post_status'] && !current_user_can( 'edit_published_pages' ))
+			$_POST['post_status'] = 'draft';
+	} else {
+		if ('publish' == $_POST['post_status'] && !current_user_can( 'edit_published_posts' ))
+			$_POST['post_status'] = 'draft';
+	}
 
-	if (!isset ($_POST['comment_status']))
+	if (!isset( $_POST['comment_status'] ))
 		$_POST['comment_status'] = 'closed';
 
-	if (!isset ($_POST['ping_status']))
+	if (!isset( $_POST['ping_status'] ))
 		$_POST['ping_status'] = 'closed';
 
-	if (!empty ($_POST['edit_date'])) {
+	if (!empty ( $_POST['edit_date'] ) ) {
 		$aa = $_POST['aa'];
 		$mm = $_POST['mm'];
 		$jj = $_POST['jj'];
 		$hh = $_POST['hh'];
 		$mn = $_POST['mn'];
 		$ss = $_POST['ss'];
-		$jj = ($jj > 31) ? 31 : $jj;
-		$hh = ($hh > 23) ? $hh -24 : $hh;
-		$mn = ($mn > 59) ? $mn -60 : $mn;
-		$ss = ($ss > 59) ? $ss -60 : $ss;
+		$jj = ($jj > 31 ) ? 31 : $jj;
+		$hh = ($hh > 23 ) ? $hh -24 : $hh;
+		$mn = ($mn > 59 ) ? $mn -60 : $mn;
+		$ss = ($ss > 59 ) ? $ss -60 : $ss;
 		$_POST['post_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
-		$_POST['post_date_gmt'] = get_gmt_from_date("$aa-$mm-$jj $hh:$mn:$ss");
+		$_POST['post_date_gmt'] = get_gmt_from_date( "$aa-$mm-$jj $hh:$mn:$ss" );
 	}
 
 	// Meta Stuff
-	if ($_POST['meta']) {
-		foreach ($_POST['meta'] as $key => $value)
-			update_meta($key, $value['key'], $value['value']);
+	if ( $_POST['meta'] ) {
+		foreach ( $_POST['meta'] as $key => $value )
+			update_meta( $key, $value['key'], $value['value'] );
 	}
-	
-	if ($_POST['deletemeta']) {
-		foreach ($_POST['deletemeta'] as $key => $value)
-			delete_meta($key);
+
+	if ( $_POST['deletemeta'] ) {
+		foreach ( $_POST['deletemeta'] as $key => $value )
+			delete_meta( $key );
 	}
 
-	add_meta($post_ID);
+	add_meta( $post_ID );
+
+	wp_update_post( $_POST );
 
-	wp_update_post($_POST);
+	// Reunite any orphaned attachments with their parent
+	if ( !$draft_ids = get_user_option( 'autosave_draft_ids' ) )
+		$draft_ids = array();
+	if ( $draft_temp_id = (int) array_search( $post_ID, $draft_ids ) )
+		relocate_children( $draft_temp_id, $post_ID );
 
 	// Now that we have an ID we can fix any attachment anchor hrefs
-	fix_attachment_links($post_ID);
+	fix_attachment_links( $post_ID );
 
 	return $post_ID;
 }
@@ -222,8 +305,8 @@
 	$comment_ID = (int) $_POST['comment_ID'];
 	$comment_post_ID = (int) $_POST['comment_post_ID'];
 
-	if (!current_user_can('edit_post', $comment_post_ID))
-		die(__('You are not allowed to edit comments on this post, so you cannot edit this comment.'));
+	if (!current_user_can( 'edit_post', $comment_post_ID ))
+		wp_die( __('You are not allowed to edit comments on this post, so you cannot edit this comment.' ));
 
 	$_POST['comment_author'] = $_POST['newcomment_author'];
 	$_POST['comment_author_email'] = $_POST['newcomment_author_email'];
@@ -232,80 +315,80 @@
 	$_POST['comment_content'] = $_POST['content'];
 	$_POST['comment_ID'] = (int) $_POST['comment_ID'];
 
-	if (!empty ($_POST['edit_date'])) {
+	if (!empty ( $_POST['edit_date'] ) ) {
 		$aa = $_POST['aa'];
 		$mm = $_POST['mm'];
 		$jj = $_POST['jj'];
 		$hh = $_POST['hh'];
 		$mn = $_POST['mn'];
 		$ss = $_POST['ss'];
-		$jj = ($jj > 31) ? 31 : $jj;
-		$hh = ($hh > 23) ? $hh -24 : $hh;
-		$mn = ($mn > 59) ? $mn -60 : $mn;
-		$ss = ($ss > 59) ? $ss -60 : $ss;
+		$jj = ($jj > 31 ) ? 31 : $jj;
+		$hh = ($hh > 23 ) ? $hh -24 : $hh;
+		$mn = ($mn > 59 ) ? $mn -60 : $mn;
+		$ss = ($ss > 59 ) ? $ss -60 : $ss;
 		$_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
 	}
 
-	wp_update_comment($_POST);
+	wp_update_comment( $_POST);
 }
 
 // Get an existing post and format it for editing.
-function get_post_to_edit($id) {
-	global $richedit;
-	$richedit = ( 'true' == get_user_option('rich_editing') ) ? true : false;
+function get_post_to_edit( $id ) {
 
-	$post = get_post($id);
+	$post = get_post( $id );
 
-	$post->post_content = format_to_edit($post->post_content, $richedit);
-	$post->post_content = apply_filters('content_edit_pre', $post->post_content);
+	$post->post_content = format_to_edit( $post->post_content, user_can_richedit() );
+	$post->post_content = apply_filters( 'content_edit_pre', $post->post_content);
 
-	$post->post_excerpt = format_to_edit($post->post_excerpt);
-	$post->post_excerpt = apply_filters('excerpt_edit_pre', $post->post_excerpt);
+	$post->post_excerpt = format_to_edit( $post->post_excerpt);
+	$post->post_excerpt = apply_filters( 'excerpt_edit_pre', $post->post_excerpt);
 
-	$post->post_title = format_to_edit($post->post_title);
-	$post->post_title = apply_filters('title_edit_pre', $post->post_title);
+	$post->post_title = format_to_edit( $post->post_title );
+	$post->post_title = apply_filters( 'title_edit_pre', $post->post_title );
 
-    $post->post_password = format_to_edit($post->post_password); 
+	$post->post_password = format_to_edit( $post->post_password );
+	
+	$post->menu_order = (int) $post->menu_order;
 
-	if ($post->post_status == 'static')
-		$post->page_template = get_post_meta($id, '_wp_page_template', true);
+	if ( $post->post_type == 'page' )
+		$post->page_template = get_post_meta( $id, '_wp_page_template', true );
 
 	return $post;
 }
 
 // Default post information to use when populating the "Write Post" form.
 function get_default_post_to_edit() {
-	if ( !empty($_REQUEST['post_title']) )
-		$post_title = wp_specialchars(stripslashes($_REQUEST['post_title']));
-	else if ( !empty($_REQUEST['popuptitle']) ) {
-		$post_title = wp_specialchars(stripslashes($_REQUEST['popuptitle']));
-		$post_title = funky_javascript_fix($post_title);
+	if ( !empty( $_REQUEST['post_title'] ) )
+		$post_title = wp_specialchars( stripslashes( $_REQUEST['post_title'] ));
+	else if ( !empty( $_REQUEST['popuptitle'] ) ) {
+		$post_title = wp_specialchars( stripslashes( $_REQUEST['popuptitle'] ));
+		$post_title = funky_javascript_fix( $post_title );
 	} else {
 		$post_title = '';
 	}
 
-	if ( !empty($_REQUEST['content']) )
-		$post_content = wp_specialchars(stripslashes($_REQUEST['content']));
-	else if ( !empty($post_title) ) {
-		$text       = wp_specialchars(stripslashes(urldecode($_REQUEST['text'])));
-		$text       = funky_javascript_fix($text);
-		$popupurl   = wp_specialchars($_REQUEST['popupurl']);
+	if ( !empty( $_REQUEST['content'] ) )
+		$post_content = wp_specialchars( stripslashes( $_REQUEST['content'] ));
+	else if ( !empty( $post_title ) ) {
+		$text       = wp_specialchars( stripslashes( urldecode( $_REQUEST['text'] ) ) );
+		$text       = funky_javascript_fix( $text);
+		$popupurl   = clean_url($_REQUEST['popupurl']);
         $post_content = '<a href="'.$popupurl.'">'.$post_title.'</a>'."\n$text";
     }
 
-	if ( !empty($_REQUEST['excerpt']) )
-		$post_excerpt = wp_specialchars(stripslashes($_REQUEST['excerpt']));
+	if ( !empty( $_REQUEST['excerpt'] ) )
+		$post_excerpt = wp_specialchars( stripslashes( $_REQUEST['excerpt'] ));
 	else
 		$post_excerpt = '';
 
 	$post->post_status = 'draft';
-	$post->comment_status = get_settings('default_comment_status');
-	$post->ping_status = get_settings('default_ping_status');
-	$post->post_pingback = get_settings('default_pingback_flag');
-	$post->post_category = get_settings('default_category');
-	$post->post_content = apply_filters('default_content', $post_content);
-	$post->post_title = apply_filters('default_title', $post_title);
-	$post->post_excerpt = apply_filters('default_excerpt', $post_excerpt);
+	$post->comment_status = get_option( 'default_comment_status' );
+	$post->ping_status = get_option( 'default_ping_status' );
+	$post->post_pingback = get_option( 'default_pingback_flag' );
+	$post->post_category = get_option( 'default_category' );
+	$post->post_content = apply_filters( 'default_content', $post_content);
+	$post->post_title = apply_filters( 'default_title', $post_title );
+	$post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt);
 	$post->page_template = 'default';
 	$post->post_parent = 0;
 	$post->menu_order = 0;
@@ -313,41 +396,57 @@
 	return $post;
 }
 
-function get_comment_to_edit($id) {
-	global $richedit;
-	$richedit = ( 'true' == get_user_option('rich_editing') ) ? true : false;
-
-	$comment = get_comment($id);
-
-	$comment->comment_content = format_to_edit($comment->comment_content, $richedit);
-	$comment->comment_content = apply_filters('comment_edit_pre', $comment->comment_content);
-
-	$comment->comment_author = format_to_edit($comment->comment_author);
-	$comment->comment_author_email = format_to_edit($comment->comment_author_email);
-	$comment->comment_author_url = format_to_edit($comment->comment_author_url);
+function get_comment_to_edit( $id ) {
+	$comment = get_comment( $id );
+	
+	$comment->comment_ID = (int) $comment->comment_ID;
+	$comment->comment_post_ID = (int) $comment->comment_post_ID;
+
+	$comment->comment_content = format_to_edit( $comment->comment_content );
+	$comment->comment_content = apply_filters( 'comment_edit_pre', $comment->comment_content);
+
+	$comment->comment_author = format_to_edit( $comment->comment_author );
+	$comment->comment_author_email = format_to_edit( $comment->comment_author_email );
+	$comment->comment_author_url = clean_url($comment->comment_author_url);
+	$comment->comment_author_url = format_to_edit( $comment->comment_author_url );
 
 	return $comment;
 }
 
-function get_category_to_edit($id) {
-	$category = get_category($id);
+function get_category_to_edit( $id ) {
+	$category = get_category( $id );
+	
+	$category->term_id = (int) $category->term_id;
+	$category->parent = (int) $category->parent;
 
 	return $category;
 }
 
-function get_user_to_edit($user_id) {
-	$user = new WP_User($user_id);
-	$user->user_login = wp_specialchars($user->user_login, 1);
-	$user->user_email = wp_specialchars($user->user_email, 1);
-	$user->user_url = wp_specialchars($user->user_url, 1);
-	$user->first_name = wp_specialchars($user->first_name, 1);
-	$user->last_name = wp_specialchars($user->last_name, 1);
-	$user->display_name = wp_specialchars($user->display_name, 1);
-	$user->nickname = wp_specialchars($user->nickname, 1);
-	$user->aim = wp_specialchars($user->aim, 1);
-	$user->yim = wp_specialchars($user->yim, 1);
-	$user->jabber = wp_specialchars($user->jabber, 1);
-	$user->description = wp_specialchars($user->description);
+function wp_dropdown_roles( $default = false ) {
+	global $wp_roles;
+	$r = '';
+	foreach( $wp_roles->role_names as $role => $name )
+		if ( $default == $role ) // Make default first in list
+			$p = "\n\t<option selected='selected' value='$role'>$name</option>";
+		else
+			$r .= "\n\t<option value='$role'>$name</option>";
+	echo $p . $r;
+}
+
+
+function get_user_to_edit( $user_id ) {
+	$user = new WP_User( $user_id );
+	$user->user_login   = attribute_escape($user->user_login);
+	$user->user_email   = attribute_escape($user->user_email);
+	$user->user_url     = clean_url($user->user_url);
+	$user->first_name   = attribute_escape($user->first_name);
+	$user->last_name    = attribute_escape($user->last_name);
+	$user->display_name = attribute_escape($user->display_name);
+	$user->nickname     = attribute_escape($user->nickname);
+	$user->aim          = attribute_escape($user->aim);
+	$user->yim          = attribute_escape($user->yim);
+	$user->jabber       = attribute_escape($user->jabber);
+	$user->description  =  wp_specialchars($user->description);
 
 	return $user;
 }
@@ -355,504 +454,577 @@
 // Creates a new user from the "Users" form using $_POST information.
 
 function add_user() {
-	return edit_user();
+	if ( func_num_args() ) { // The hackiest hack that ever did hack
+		global $current_user, $wp_roles;
+		$user_id = (int) func_get_arg( 0 );
+
+		if ( isset( $_POST['role'] ) ) {
+			if( $user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap( 'edit_users' ) ) {
+				$user = new WP_User( $user_id );
+				$user->set_role( $_POST['role'] );
+			}
+		}
+	} else {
+		add_action( 'user_register', 'add_user' ); // See above
+		return edit_user();
+	}
 }
 
-function edit_user($user_id = 0) {
+function edit_user( $user_id = 0 ) {
 	global $current_user, $wp_roles, $wpdb;
-
-	if ($user_id != 0) {
+	if ( $user_id != 0 ) {
 		$update = true;
-		$user->ID = $user_id;
-		$userdata = get_userdata($user_id);
-		$user->user_login = $wpdb->escape($userdata->user_login);
+		$user->ID = (int) $user_id;
+		$userdata = get_userdata( $user_id );
+		$user->user_login = $wpdb->escape( $userdata->user_login );
 	} else {
 		$update = false;
 		$user = '';
 	}
 
-	if (isset ($_POST['user_login']))
-		$user->user_login = wp_specialchars(trim($_POST['user_login']));
+	if ( isset( $_POST['user_login'] ))
+		$user->user_login = wp_specialchars( trim( $_POST['user_login'] ));
 
 	$pass1 = $pass2 = '';
-	if (isset ($_POST['pass1']))
+	if ( isset( $_POST['pass1'] ))
 		$pass1 = $_POST['pass1'];
-	if (isset ($_POST['pass2']))
+	if ( isset( $_POST['pass2'] ))
 		$pass2 = $_POST['pass2'];
 
-	if (isset ($_POST['role']) && current_user_can('edit_users')) {
-		if($user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap('edit_users'))
+	if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) { 
+		if( $user_id != $current_user->id || $wp_roles->role_objects[$_POST['role']]->has_cap( 'edit_users' ))
 			$user->role = $_POST['role'];
 	}
 
-	if (isset ($_POST['email']))
-		$user->user_email = wp_specialchars(trim($_POST['email']));
-	if (isset ($_POST['url'])) {
-		$user->user_url = wp_specialchars(trim($_POST['url']));
-		$user->user_url = preg_match('/^(https?|ftps?|mailto|news|gopher):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url;
-	}
-	if (isset ($_POST['first_name']))
-		$user->first_name = wp_specialchars(trim($_POST['first_name']));
-	if (isset ($_POST['last_name']))
-		$user->last_name = wp_specialchars(trim($_POST['last_name']));
-	if (isset ($_POST['nickname']))
-		$user->nickname = wp_specialchars(trim($_POST['nickname']));
-	if (isset ($_POST['display_name']))
-		$user->display_name = wp_specialchars(trim($_POST['display_name']));
-	if (isset ($_POST['description']))
-		$user->description = trim($_POST['description']);
-	if (isset ($_POST['jabber']))
-		$user->jabber = wp_specialchars(trim($_POST['jabber']));
-	if (isset ($_POST['aim']))
-		$user->aim = wp_specialchars(trim($_POST['aim']));
-	if (isset ($_POST['yim']))
-		$user->yim = wp_specialchars(trim($_POST['yim']));
+	if ( isset( $_POST['email'] ))
+		$user->user_email = wp_specialchars( trim( $_POST['email'] ));
+	if ( isset( $_POST['url'] ) ) {
+		$user->user_url = clean_url( trim( $_POST['url'] ));
+		$user->user_url = preg_match('/^(https?|ftps?|mailto|news|irc|gopher|nntp|feed|telnet):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url;
+	}
+	if ( isset( $_POST['first_name'] ))
+		$user->first_name = wp_specialchars( trim( $_POST['first_name'] ));
+	if ( isset( $_POST['last_name'] ))
+		$user->last_name = wp_specialchars( trim( $_POST['last_name'] ));
+	if ( isset( $_POST['nickname'] ))
+		$user->nickname = wp_specialchars( trim( $_POST['nickname'] ));
+	if ( isset( $_POST['display_name'] ))
+		$user->display_name = wp_specialchars( trim( $_POST['display_name'] ));
+	if ( isset( $_POST['description'] ))
+		$user->description = trim( $_POST['description'] );
+	if ( isset( $_POST['jabber'] ))
+		$user->jabber = wp_specialchars( trim( $_POST['jabber'] ));
+	if ( isset( $_POST['aim'] ))
+		$user->aim = wp_specialchars( trim( $_POST['aim'] ));
+	if ( isset( $_POST['yim'] ))
+		$user->yim = wp_specialchars( trim( $_POST['yim'] ));
+	if ( !$update )
+		$user->rich_editing = 'true';  // Default to true for new users.
+	else if ( isset( $_POST['rich_editing'] ) )
+		$user->rich_editing = $_POST['rich_editing'];
+	else
+		$user->rich_editing = 'false';
 
-	$errors = array ();
+	$errors = new WP_Error();
 
 	/* checking that username has been typed */
-	if ($user->user_login == '')
-		$errors['user_login'] = __('<strong>ERROR</strong>: Please enter a username.');
+	if ( $user->user_login == '' )
+		$errors->add( 'user_login', __( '<strong>ERROR</strong>: Please enter a username.' ));
 
 	/* checking the password has been typed twice */
-	do_action('check_passwords', array ($user->user_login, & $pass1, & $pass2));
+	do_action_ref_array( 'check_passwords', array ( $user->user_login, & $pass1, & $pass2 ));
 
-	if (!$update) {
-		if ($pass1 == '' || $pass2 == '')
-			$errors['pass'] = __('<strong>ERROR</strong>: Please enter your password twice.');
+	if (!$update ) {
+		if ( $pass1 == '' || $pass2 == '' )
+			$errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter your password twice.' ));
 	} else {
-		if ((empty ($pass1) && !empty ($pass2)) || (empty ($pass2) && !empty ($pass1)))
-			$errors['pass'] = __("<strong>ERROR</strong>: you typed your new password only once.");
+		if ((empty ( $pass1 ) && !empty ( $pass2 ) ) || (empty ( $pass2 ) && !empty ( $pass1 ) ) )
+			$errors->add( 'pass', __( "<strong>ERROR</strong>: you typed your new password only once." ));
 	}
 
 	/* Check for "\" in password */
 	if( strpos( " ".$pass1, "\\" ) )
-		$errors['pass'] = __('<strong>ERROR</strong>: Passwords may not contain the character "\\".');
+		$errors->add( 'pass', __( '<strong>ERROR</strong>: Passwords may not contain the character "\\".' ));
 
 	/* checking the password has been typed twice the same */
-	if ($pass1 != $pass2)
-		$errors['pass'] = __('<strong>ERROR</strong>: Please type the same password in the two password fields.');
+	if ( $pass1 != $pass2 )
+		$errors->add( 'pass', __( '<strong>ERROR</strong>: Please type the same password in the two password fields.' ));
 
-	if (!empty ($pass1))
+	if (!empty ( $pass1 ))
 		$user->user_pass = $pass1;
 
-	if ( !validate_username($user->user_login) )
-		$errors['user_login'] = __('<strong>ERROR</strong>: This username is invalid.  Please enter a valid username.');
+	if ( !$update && !validate_username( $user->user_login ) )
+		$errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is invalid.  Please enter a valid username.' ));
 
-	if (!$update && username_exists($user->user_login))
-		$errors['user_login'] = __('<strong>ERROR</strong>: This username is already registered, please choose another one.');
+	if (!$update && username_exists( $user->user_login ))
+		$errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is already registered, please choose another one.' ));
 
 	/* checking e-mail address */
-	if (empty ($user->user_email)) {
-		$errors['user_email'] = __("<strong>ERROR</strong>: please type an e-mail address");
+	if ( empty ( $user->user_email ) ) {
+		$errors->add( 'user_email', __( "<strong>ERROR</strong>: please type an e-mail address" ));
 	} else
-		if (!is_email($user->user_email)) {
-			$errors['user_email'] = __("<strong>ERROR</strong>: the email address isn't correct");
+		if (!is_email( $user->user_email ) ) {
+			$errors->add( 'user_email', __( "<strong>ERROR</strong>: the email address isn't correct" ));
 		}
 
-	if (count($errors) != 0)
+	if ( $errors->get_error_codes() )
 		return $errors;
 
-	if ($update) {
-		$user_id = wp_update_user(get_object_vars($user));
+	if ( $update ) {
+		$user_id = wp_update_user( get_object_vars( $user ));
 	} else {
-		$user_id = wp_insert_user(get_object_vars($user));
-		wp_new_user_notification($user_id);
+		$user_id = wp_insert_user( get_object_vars( $user ));
+		wp_new_user_notification( $user_id );
 	}
-
-	return $errors;
+	return $user_id;
 }
 
 
-function get_link_to_edit($link_id) {
-	$link = get_link($link_id);
+function get_link_to_edit( $link_id ) {
+	$link = get_link( $link_id );
 
-	$link->link_url = wp_specialchars($link->link_url, 1);
-	$link->link_name = wp_specialchars($link->link_name, 1);
-	$link->link_image = wp_specialchars($link->link_image, 1);
-	$link->link_description = wp_specialchars($link->link_description, 1);
-	$link->link_notes = wp_specialchars($link->link_notes);
-	$link->link_rss = wp_specialchars($link->link_rss, 1);
-	$link->link_rel = wp_specialchars($link->link_rel, 1);
-	$link->post_category = $link->link_category;
+	$link->link_url         = clean_url($link->link_url);
+	$link->link_name        = attribute_escape($link->link_name);
+	$link->link_image       = attribute_escape($link->link_image);
+	$link->link_description = attribute_escape($link->link_description);
+	$link->link_rss         = clean_url($link->link_rss);
+	$link->link_rel         = attribute_escape($link->link_rel);
+	$link->link_notes       =  wp_specialchars($link->link_notes);
+	$link->post_category    = $link->link_category;
 
 	return $link;
 }
 
 function get_default_link_to_edit() {
-	if ( isset($_GET['linkurl']) )
-		$link->link_url = wp_specialchars($_GET['linkurl'], 1);
+	if ( isset( $_GET['linkurl'] ) )
+		$link->link_url = clean_url( $_GET['linkurl']);
 	else
 		$link->link_url = '';
-	
-	if ( isset($_GET['name']) )
-		$link->link_name = wp_specialchars($_GET['name'], 1);
+
+	if ( isset( $_GET['name'] ) )
+		$link->link_name = attribute_escape( $_GET['name']);
 	else
 		$link->link_name = '';
-		
+
+	$link->link_visible = 'Y';
+
 	return $link;
 }
 
 function add_link() {
-	return edit_link();	
+	return edit_link();
 }
 
-function edit_link($link_id = '') {
-	if (!current_user_can('manage_links'))
-		die(__("Cheatin' uh ?"));
-
-	$_POST['link_url'] = wp_specialchars($_POST['link_url']);
-	$_POST['link_url'] = preg_match('/^(https?|ftps?|mailto|news|gopher):/is', $_POST['link_url']) ? $_POST['link_url'] : 'http://' . $_POST['link_url'];
-	$_POST['link_name'] = wp_specialchars($_POST['link_name']);
-	$_POST['link_image'] = wp_specialchars($_POST['link_image']);
-	$_POST['link_rss'] = wp_specialchars($_POST['link_rss']);
-	$auto_toggle = get_autotoggle($_POST['link_category']);
-	
-	// if we are in an auto toggle category and this one is visible then we
-	// need to make the others invisible before we add this new one.
-	// FIXME Add category toggle func.
-	//if (($auto_toggle == 'Y') && ($link_visible == 'Y')) {
-	//	$wpdb->query("UPDATE $wpdb->links set link_visible = 'N' WHERE link_category = $link_category");
-	//}
+function edit_link( $link_id = '' ) {
+	if (!current_user_can( 'manage_links' ))
+		wp_die( __( 'Cheatin&#8217; uh?' ));
+
+	$_POST['link_url'] = wp_specialchars( $_POST['link_url'] );
+	$_POST['link_url'] = clean_url($_POST['link_url']);
+	$_POST['link_name'] = wp_specialchars( $_POST['link_name'] );
+	$_POST['link_image'] = wp_specialchars( $_POST['link_image'] );
+	$_POST['link_rss'] = clean_url($_POST['link_rss']);
+	$_POST['link_category'] = $_POST['post_category'];
 
-	if ( !empty($link_id) ) {
+	if ( !empty( $link_id ) ) {
 		$_POST['link_id'] = $link_id;
-		return wp_update_link($_POST);
+		return wp_update_link( $_POST);
 	} else {
-		return wp_insert_link($_POST);
+		return wp_insert_link( $_POST);
 	}
 }
 
-function url_shorten($url) {
-	$short_url = str_replace('http://', '', stripslashes($url));
-	$short_url = str_replace('www.', '', $short_url);
-	if ('/' == substr($short_url, -1))
-		$short_url = substr($short_url, 0, -1);
-	if (strlen($short_url) > 35)
-		$short_url = substr($short_url, 0, 32).'...';
+function url_shorten( $url ) {
+	$short_url = str_replace( 'http://', '', stripslashes( $url ));
+	$short_url = str_replace( 'www.', '', $short_url );
+	if ('/' == substr( $short_url, -1 ))
+		$short_url = substr( $short_url, 0, -1 );
+	if ( strlen( $short_url ) > 35 )
+		$short_url = substr( $short_url, 0, 32 ).'...';
 	return $short_url;
 }
 
-function selected($selected, $current) {
-	if ($selected == $current)
+function selected( $selected, $current) {
+	if ( $selected == $current)
 		echo ' selected="selected"';
 }
 
-function checked($checked, $current) {
-	if ($checked == $current)
+function checked( $checked, $current) {
+	if ( $checked == $current)
 		echo ' checked="checked"';
 }
 
-function return_categories_list($parent = 0) {
+function return_categories_list( $parent = 0 ) {
 	global $wpdb;
-	return $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent ORDER BY category_count DESC");
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( link_count = 0 OR category_count != 0 OR ( link_count = 0 AND category_count = 0 ) ) ORDER BY category_count DESC" );
 }
 
-function sort_cats($cat1, $cat2) {
-	return strcasecmp($cat1['cat_name'], $cat2['cat_name']);
+function sort_cats( $cat1, $cat2 ) {
+	if ( $cat1['checked'] || $cat2['checked'] )
+		return ( $cat1['checked'] && !$cat2['checked'] ) ? -1 : 1;
+	else
+		return strcasecmp( $cat1['cat_name'], $cat2['cat_name'] );
 }
 
-function get_nested_categories($default = 0, $parent = 0) {
-	global $post_ID, $mode, $wpdb;
+function get_nested_categories( $default = 0, $parent = 0 ) {
+	global $post_ID, $link_id, $mode, $wpdb;
 
-	if ($post_ID) {
-		$checked_categories = $wpdb->get_col("
+	if ( $post_ID ) {
+		$checked_categories = $wpdb->get_col( "
 		     SELECT category_id
 		     FROM $wpdb->categories, $wpdb->post2cat
 		     WHERE $wpdb->post2cat.category_id = cat_ID AND $wpdb->post2cat.post_id = '$post_ID'
-		     ");
+		     " );
 
-		if (count($checked_categories) == 0) {
+		if ( count( $checked_categories ) == 0 ) {
 			// No selected categories, strange
 			$checked_categories[] = $default;
 		}
+	} else if ( $link_id ) {
+		$checked_categories = $wpdb->get_col( "
+		     SELECT category_id
+		     FROM $wpdb->categories, $wpdb->link2cat
+		     WHERE $wpdb->link2cat.category_id = cat_ID AND $wpdb->link2cat.link_id = '$link_id'
+		     " );
 
+		if ( count( $checked_categories ) == 0 ) {
+			// No selected categories, strange
+			$checked_categories[] = $default;
+		}
 	} else {
 		$checked_categories[] = $default;
 	}
 
-	$cats = return_categories_list($parent);
+	$cats = return_categories_list( $parent);
 	$result = array ();
 
-	if (is_array($cats)) {
-		foreach ($cats as $cat) {
-			$result[$cat]['children'] = get_nested_categories($default, $cat);
+	if ( is_array( $cats ) ) {
+		foreach ( $cats as $cat) {
+			$result[$cat]['children'] = get_nested_categories( $default, $cat);
 			$result[$cat]['cat_ID'] = $cat;
-			$result[$cat]['checked'] = in_array($cat, $checked_categories);
-			$result[$cat]['cat_name'] = get_the_category_by_ID($cat);
+			$result[$cat]['checked'] = in_array( $cat, $checked_categories );
+			$result[$cat]['cat_name'] = get_the_category_by_ID( $cat);
 		}
 	}
-	
-	usort($result, 'sort_cats');
+
+	usort( $result, 'sort_cats' );
 
 	return $result;
 }
 
-function write_nested_categories($categories) {
-	foreach ($categories as $category) {
-		echo '<label for="category-', $category['cat_ID'], '" class="selectit"><input value="', $category['cat_ID'], '" type="checkbox" name="post_category[]" id="category-', $category['cat_ID'], '"', ($category['checked'] ? ' checked="checked"' : ""), '/> ', wp_specialchars($category['cat_name']), "</label>\n";
+function write_nested_categories( $categories ) {
+	foreach ( $categories as $category ) {
+		echo '<li id="category-', $category['cat_ID'], '"><label for="in-category-', $category['cat_ID'], '" class="selectit"><input value="', $category['cat_ID'], '" type="checkbox" name="post_category[]" id="in-category-', $category['cat_ID'], '"', ($category['checked'] ? ' checked="checked"' : "" ), '/> ', wp_specialchars( apply_filters('the_category', $category['cat_name'] )), "</label></li>";
 
-		if (isset ($category['children'])) {
-			echo "\n<span class='cat-nest'>\n";
-			write_nested_categories($category['children']);
-			echo "</span>\n";
+		if ( $category['children'] ) {
+			echo "<ul>\n";
+			write_nested_categories( $category['children'] );
+			echo "</ul>\n";
 		}
 	}
 }
 
-function dropdown_categories($default = 0) {
-	write_nested_categories(get_nested_categories($default));
+function dropdown_categories( $default = 0 ) {
+	write_nested_categories( get_nested_categories( $default) );
 }
 
-// Dandy new recursive multiple category stuff.
-function cat_rows($parent = 0, $level = 0, $categories = 0) {
-	global $wpdb, $class;
+function return_link_categories_list( $parent = 0 ) {
+	global $wpdb;
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( category_count = 0  OR link_count != 0 OR ( link_count = 0 AND category_count = 0 ) ) ORDER BY link_count DESC" );
+}
 
-	if (!$categories)
-		$categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");
+function get_nested_link_categories( $default = 0, $parent = 0 ) {
+	global $post_ID, $link_id, $mode, $wpdb;
 
-	if ($categories) {
-		foreach ($categories as $category) {
-			if ($category->category_parent == $parent) {
-				$category->cat_name = wp_specialchars($category->cat_name);
-				$pad = str_repeat('&#8212; ', $level);
-				if ( current_user_can('manage_categories') ) {
-					$edit = "<a href='categories.php?action=edit&amp;cat_ID=$category->cat_ID' class='edit'>".__('Edit')."</a></td>";
-					$default_cat_id = get_option('default_category');
+	if ( $link_id ) {
+		$checked_categories = $wpdb->get_col( "
+		     SELECT category_id
+		     FROM $wpdb->categories, $wpdb->link2cat
+		     WHERE $wpdb->link2cat.category_id = cat_ID AND $wpdb->link2cat.link_id = '$link_id'
+		     " );
 
-					if ($category->cat_ID != $default_cat_id)
-						$edit .= "<td><a href='" . wp_nonce_url("categories.php?action=delete&amp;cat_ID=$category->cat_ID", 'delete-category_' . $category->cat_ID ) . "' onclick=\"return deleteSomething( 'cat', $category->cat_ID, '" . sprintf(__("You are about to delete the category &quot;%s&quot;.  All of its posts will go to the default category.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape($category->cat_name))."' );\" class='delete'>".__('Delete')."</a>";
-					else
-						$edit .= "<td style='text-align:center'>".__("Default");
-				}
-				else
-					$edit = '';
+		if ( count( $checked_categories ) == 0 ) {
+			// No selected categories, strange
+			$checked_categories[] = $default;
+		}
+	} else {
+		$checked_categories[] = $default;
+	}
+
+	$cats = return_link_categories_list( $parent);
+	$result = array ();
+
+	if ( is_array( $cats ) ) {
+		foreach ( $cats as $cat) {
+			$result[$cat]['children'] = get_nested_link_categories( $default, $cat);
+			$result[$cat]['cat_ID'] = $cat;
+			$result[$cat]['checked'] = in_array( $cat, $checked_categories );
+			$result[$cat]['cat_name'] = get_the_category_by_ID( $cat);
+		}
+	}
+
+	usort( $result, 'sort_cats' );
 
-				$class = ('alternate' == $class) ? '' : 'alternate';
-				echo "<tr id='cat-$category->cat_ID' class='$class'><th scope='row'>$category->cat_ID</th><td>$pad $category->cat_name</td>
-								<td>$category->category_description</td>
-								<td>$category->category_count</td>
-								<td>$edit</td>
-								</tr>";
-				cat_rows($category->cat_ID, $level +1, $categories);
+	return $result;
+}
+
+function dropdown_link_categories( $default = 0 ) {
+	write_nested_categories( get_nested_link_categories( $default) );
+}
+
+// Dandy new recursive multiple category stuff.
+function cat_rows( $parent = 0, $level = 0, $categories = 0 ) {
+	if (!$categories )
+		$categories = get_categories( 'hide_empty=0' );
+
+	$children = _get_category_hierarchy();
+
+	if ( $categories ) {
+		ob_start();
+		foreach ( $categories as $category ) {
+			if ( $category->category_parent == $parent) {
+				echo "\t" . _cat_row( $category, $level );
+				if ( isset($children[$category->cat_ID]) )
+					cat_rows( $category->cat_ID, $level +1, $categories );
 			}
 		}
+		$output = ob_get_contents();
+		ob_end_clean();
+
+		$output = apply_filters('cat_rows', $output);
+
+		echo $output;
 	} else {
 		return false;
 	}
 }
 
-function page_rows($parent = 0, $level = 0, $pages = 0) {
+function _cat_row( $category, $level, $name_override = false ) {
+	global $class;
+
+	$pad = str_repeat( '&#8212; ', $level );
+	if ( current_user_can( 'manage_categories' ) ) {
+		$edit = "<a href='categories.php?action=edit&amp;cat_ID=$category->cat_ID' class='edit'>".__( 'Edit' )."</a></td>";
+		$default_cat_id = (int) get_option( 'default_category' );
+		$default_link_cat_id = (int) get_option( 'default_link_category' );
+
+		if ( ($category->cat_ID != $default_cat_id ) && ($category->cat_ID != $default_link_cat_id ) )
+			$edit .= "<td><a href='" . wp_nonce_url( "categories.php?action=delete&amp;cat_ID=$category->cat_ID", 'delete-category_' . $category->cat_ID ) . "' onclick=\"return deleteSomething( 'cat', $category->cat_ID, '" . js_escape(sprintf( __("You are about to delete the category '%s'.\nAll posts that were only assigned to this category will be assigned to the '%s' category.\nAll links that were only assigned to this category will be assigned to the '%s' category.\n'OK' to delete, 'Cancel' to stop." ), $category->cat_name, get_catname( $default_cat_id ), get_catname( $default_link_cat_id ) )) . "' );\" class='delete'>".__( 'Delete' )."</a>";
+		else
+			$edit .= "<td style='text-align:center'>".__( "Default" );
+	} else
+		$edit = '';
+
+	$class = ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || " class='alternate'" == $class ) ? '' : " class='alternate'";
+
+	$category->category_count = number_format( $category->category_count );
+	$category->link_count = number_format( $category->link_count );
+	$posts_count = ( $category->category_count > 0 ) ? "<a href='edit.php?cat=$category->cat_ID'>$category->category_count</a>" : $category->category_count;
+	return "<tr id='cat-$category->cat_ID'$class>
+		<th scope='row' style='text-align: center'>$category->cat_ID</th>
+		<td>" . ( $name_override ? $name_override : $pad . ' ' . $category->cat_name ) . "</td>
+		<td>$category->category_description</td>
+		<td align='center'>$posts_count</td>
+		<td align='center'>$category->link_count</td>
+		<td>$edit</td>\n\t</tr>\n";
+}
+
+function page_rows( $parent = 0, $level = 0, $pages = 0, $hierarchy = true ) {
 	global $wpdb, $class, $post;
-	if (!$pages)
-		$pages = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'static' ORDER BY menu_order");
 
-	if ($pages) {
-		foreach ($pages as $post) {
-			start_wp();
-			if ($post->post_parent == $parent) {
-				$post->post_title = wp_specialchars($post->post_title);
-				$pad = str_repeat('&#8212; ', $level);
-				$id = $post->ID;
-				$class = ('alternate' == $class) ? '' : 'alternate';
+	if (!$pages )
+		$pages = get_pages( 'sort_column=menu_order' );
+
+	if (! $pages )
+		return false;
+
+	foreach ( $pages as $post) {
+		setup_postdata( $post);
+		if ( $hierarchy && ($post->post_parent != $parent) )
+			continue;
+
+		$post->post_title = wp_specialchars( $post->post_title );
+		$pad = str_repeat( '&#8212; ', $level );
+		$id = (int) $post->ID;
+		$class = ('alternate' == $class ) ? '' : 'alternate';
 ?>
   <tr id='page-<?php echo $id; ?>' class='<?php echo $class; ?>'> 
-    <th scope="row"><?php echo $post->ID; ?></th> 
+    <th scope="row" style="text-align: center"><?php echo $post->ID; ?></th> 
     <td>
-      <?php echo $pad; ?><?php the_title() ?> 
+      <?php echo $pad; ?><?php the_title() ?>
     </td> 
     <td><?php the_author() ?></td>
-    <td><?php echo mysql2date('Y-m-d g:i a', $post->post_modified); ?></td> 
-	<td><a href="<?php the_permalink(); ?>" rel="permalink" class="edit"><?php _e('View'); ?></a></td>
-    <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='post.php?action=edit&amp;post=$id' class='edit'>" . __('Edit') . "</a>"; } ?></td> 
-    <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='" . wp_nonce_url("post.php?action=delete&amp;post=$id", 'delete-post_' . $id) .  "' class='delete' onclick=\"return deleteSomething( 'page', " . $id . ", '" . sprintf(__("You are about to delete the &quot;%s&quot; page.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape(get_the_title()) ) . "' );\">" . __('Delete') . "</a>"; } ?></td> 
+    <td><?php if ( '0000-00-00 00:00:00' ==$post->post_modified ) _e('Unpublished'); else echo mysql2date( __('Y-m-d g:i a'), $post->post_modified ); ?></td> 
+	<td><a href="<?php the_permalink(); ?>" rel="permalink" class="edit"><?php _e( 'View' ); ?></a></td>
+    <td><?php if ( current_user_can( 'edit_page', $id ) ) { echo "<a href='page.php?action=edit&amp;post=$id' class='edit'>" . __( 'Edit' ) . "</a>"; } ?></td> 
+    <td><?php if ( current_user_can( 'delete_page', $id ) ) { echo "<a href='" . wp_nonce_url( "page.php?action=delete&amp;post=$id", 'delete-page_' . $id ) .  "' class='delete' onclick=\"return deleteSomething( 'page', " . $id . ", '" . js_escape(sprintf( __("You are about to delete the '%s' page.\n'OK' to delete, 'Cancel' to stop." ), get_the_title() ) ) . "' );\">" . __( 'Delete' ) . "</a>"; } ?></td> 
   </tr> 
 
 <?php
-
-				page_rows($id, $level +1, $pages);
-			}
-		}
-	} else {
-		return false;
+		if ( $hierarchy ) page_rows( $id, $level + 1, $pages );
 	}
 }
 
-function wp_dropdown_cats($currentcat = 0, $currentparent = 0, $parent = 0, $level = 0, $categories = 0) {
-	global $wpdb, $bgcolor;
-	if (!$categories) {
-		$categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");
-	}
-	if ($categories) {
-		foreach ($categories as $category) {
-			if ($currentcat != $category->cat_ID && $parent == $category->category_parent) {
-				$count = $wpdb->get_var("SELECT COUNT(post_id) FROM $wpdb->post2cat WHERE category_id = $category->cat_ID");
-				$pad = str_repeat('&#8211; ', $level);
-				$category->cat_name = wp_specialchars($category->cat_name);
-				echo "\n\t<option value='$category->cat_ID'";
-				if ($currentparent == $category->cat_ID)
-					echo " selected='selected'";
-				echo ">$pad$category->cat_name</option>";
-				wp_dropdown_cats($currentcat, $currentparent, $category->cat_ID, $level +1, $categories);
-			}
-		}
-	} else {
-		return false;
+function user_row( $user_object, $style = '' ) {
+	if ( !(is_object( $user_object) && is_a( $user_object, 'WP_User' ) ) )
+		$user_object = new WP_User( (int) $user_object );
+	$email = $user_object->user_email;
+	$url = $user_object->user_url;
+	$short_url = str_replace( 'http://', '', $url );
+	$short_url = str_replace( 'www.', '', $short_url );
+	if ('/' == substr( $short_url, -1 ))
+		$short_url = substr( $short_url, 0, -1 );
+	if ( strlen( $short_url ) > 35 )
+		$short_url =  substr( $short_url, 0, 32 ).'...';
+	$numposts = get_usernumposts( $user_object->ID );
+	$r = "<tr id='user-$user_object->ID'$style>
+		<td><input type='checkbox' name='users[]' id='user_{$user_object->ID}' value='{$user_object->ID}' /> <label for='user_{$user_object->ID}'>{$user_object->ID}</label></td>
+		<td><label for='user_{$user_object->ID}'><strong>$user_object->user_login</strong></label></td>
+		<td><label for='user_{$user_object->ID}'>$user_object->first_name $user_object->last_name</label></td>
+		<td><a href='mailto:$email' title='" . sprintf( __('e-mail: %s' ), $email ) . "'>$email</a></td>
+		<td><a href='$url' title='website: $url'>$short_url</a></td>";
+	$r .= "\n\t\t<td align='center'>";
+	if ( $numposts > 0 ) {
+		$r .= "<a href='edit.php?author=$user_object->ID' title='" . __( 'View posts by this author' ) . "' class='edit'>";
+		$r .= sprintf(__ngettext( 'View %s post', 'View %s posts', $numposts ), $numposts);
+		$r .= '</a>';
+	}
+	$r .= "</td>\n\t\t<td>";
+	if ( current_user_can( 'edit_user', $user_object->ID ) ) {
+		$edit_link = add_query_arg( 'wp_http_referer', urlencode( clean_url( stripslashes( $_SERVER['REQUEST_URI'] ) ) ), "user-edit.php?user_id=$user_object->ID" );
+		$r .= "<a href='$edit_link' class='edit'>".__( 'Edit' )."</a>";
 	}
+	$r .= "</td>\n\t</tr>";
+	return $r;
 }
 
-function link_category_dropdown($fieldname, $selected = 0) {
+function _wp_get_comment_list( $s = false, $start, $num ) {
 	global $wpdb;
-	
-	$results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
-	echo "\n<select name='$fieldname' size='1'>\n";
-	foreach ($results as $row) {
-		echo "\n\t<option value='$row->cat_id'";
-		if ($row->cat_id == $selected)
-			echo " selected='selected'";
-		echo ">$row->cat_id : " . wp_specialchars($row->cat_name);
-		if ($row->auto_toggle == 'Y')
-			echo ' (auto toggle)';
-		echo "</option>";
-	}
-	echo "\n</select>\n";
-}
-
-function wp_create_thumbnail($file, $max_side, $effect = '') {
-
-		// 1 = GIF, 2 = JPEG, 3 = PNG
-
-	if (file_exists($file)) {
-		$type = getimagesize($file);
-
-		// if the associated function doesn't exist - then it's not
-		// handle. duh. i hope.
-
-		if (!function_exists('imagegif') && $type[2] == 1) {
-			$error = __('Filetype not supported. Thumbnail not created.');
-		}
-		elseif (!function_exists('imagejpeg') && $type[2] == 2) {
-			$error = __('Filetype not supported. Thumbnail not created.');
-		}
-		elseif (!function_exists('imagepng') && $type[2] == 3) {
-			$error = __('Filetype not supported. Thumbnail not created.');
-		} else {
-
-			// create the initial copy from the original file
-			if ($type[2] == 1) {
-				$image = imagecreatefromgif($file);
-			}
-			elseif ($type[2] == 2) {
-				$image = imagecreatefromjpeg($file);
-			}
-			elseif ($type[2] == 3) {
-				$image = imagecreatefrompng($file);
-			}
-
-			if (function_exists('imageantialias'))
-				imageantialias($image, TRUE);
 
-			$image_attr = getimagesize($file);
+	$start = abs( (int) $start );
+	$num = (int) $num;
 
-			// figure out the longest side
+	if ( $s ) {
+		$s = $wpdb->escape($s);
+		$comments = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->comments WHERE
+			(comment_author LIKE '%$s%' OR
+			comment_author_email LIKE '%$s%' OR
+			comment_author_url LIKE ('%$s%') OR
+			comment_author_IP LIKE ('%$s%') OR
+			comment_content LIKE ('%$s%') ) AND
+			comment_approved != 'spam'
+			ORDER BY comment_date DESC LIMIT $start, $num");
+	} else {
+		$comments = $wpdb->get_results( "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->comments WHERE comment_approved = '0' OR comment_approved = '1' ORDER BY comment_date DESC LIMIT $start, $num" );
+	}
 
-			if ($image_attr[0] > $image_attr[1]) {
-				$image_width = $image_attr[0];
-				$image_height = $image_attr[1];
-				$image_new_width = $max_side;
+	$total = $wpdb->get_var( "SELECT FOUND_ROWS()" );
 
-				$image_ratio = $image_width / $image_new_width;
-				$image_new_height = $image_height / $image_ratio;
-				//width is > height
-			} else {
-				$image_width = $image_attr[0];
-				$image_height = $image_attr[1];
-				$image_new_height = $max_side;
+	return array($comments, $total);
+}
 
-				$image_ratio = $image_height / $image_new_height;
-				$image_new_width = $image_width / $image_ratio;
-				//height > width
-			}
+function _wp_comment_list_item( $id, $alt = 0 ) {
+	global $authordata, $comment, $wpdb;
+	$id = (int) $id;
+	$comment =& get_comment( $id );
+	$class = '';
+	$authordata = get_userdata($wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $comment->comment_post_ID"));
+	$comment_status = wp_get_comment_status($comment->comment_ID);
+	if ( 'unapproved' == $comment_status )
+		$class .= ' unapproved';
+	if ( $alt % 2 )
+		$class .= ' alternate';
+	echo "<li id='comment-$comment->comment_ID' class='$class'>";
+?>
+<p><strong><?php comment_author(); ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
 
-			$thumbnail = imagecreatetruecolor($image_new_width, $image_new_height);
-			@ imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $image_new_width, $image_new_height, $image_attr[0], $image_attr[1]);
+<?php comment_text() ?>
 
-			// If no filters change the filename, we'll do a default transformation.
-			if ( basename($file) == $thumb = apply_filters('thumbnail_filename', basename($file)) )
-				$thumb = preg_replace('!(\.[^.]+)?$!', __('.thumbnail').'$1', basename($file), 1);
+<p><?php comment_date(__('M j, g:i A'));  ?> &#8212; [
+<?php
+if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
+	echo " <a href='comment.php?action=editcomment&amp;c=".$comment->comment_ID."'>" .  __('Edit') . '</a>';
+	echo ' | <a href="' . wp_nonce_url('comment.php?action=deletecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . '" onclick="return deleteSomething( \'comment\', ' . $comment->comment_ID . ', \'' . js_escape(sprintf(__("You are about to delete this comment by '%s'.\n'Cancel' to stop, 'OK' to delete."), $comment->comment_author)) . "', theCommentList );\">" . __('Delete') . '</a> ';
+	if ( ('none' != $comment_status) && ( current_user_can('moderate_comments') ) ) {
+		echo '<span class="unapprove"> | <a href="' . wp_nonce_url('comment.php?action=unapprovecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'unapprove-comment_' . $comment->comment_ID) . '" onclick="return dimSomething( \'comment\', ' . $comment->comment_ID . ', \'unapproved\', theCommentList );">' . __('Unapprove') . '</a> </span>';
+		echo '<span class="approve"> | <a href="' . wp_nonce_url('comment.php?action=approvecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'approve-comment_' . $comment->comment_ID) . '" onclick="return dimSomething( \'comment\', ' . $comment->comment_ID . ', \'unapproved\', theCommentList );">' . __('Approve') . '</a> </span>';
+	}
+	echo " | <a href=\"" . wp_nonce_url("comment.php?action=deletecomment&amp;dt=spam&amp;p=" . $comment->comment_post_ID . "&amp;c=" . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . "\" onclick=\"return deleteSomething( 'comment-as-spam', $comment->comment_ID, '" . js_escape(sprintf(__("You are about to mark as spam this comment by '%s'.\n'Cancel' to stop, 'OK' to mark as spam."), $comment->comment_author))  . "', theCommentList );\">" . __('Spam') . "</a> ";
+}
+$post = get_post($comment->comment_post_ID);
+$post_title = wp_specialchars( $post->post_title, 'double' );
+$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
+?>
+ ] &#8212; <a href="<?php echo get_permalink($comment->comment_post_ID); ?>"><?php echo $post_title; ?></a></p>
+		</li>
+<?php
+}
 
-			$thumbpath = str_replace(basename($file), $thumb, $file);
+function wp_dropdown_cats( $currentcat = 0, $currentparent = 0, $parent = 0, $level = 0, $categories = 0 ) {
+	global $wpdb;
+	if (!$categories )
+		$categories = get_categories( 'hide_empty=0' );
 
-			// move the thumbnail to it's final destination
-			if ($type[2] == 1) {
-				if (!imagegif($thumbnail, $thumbpath)) {
-					$error = __("Thumbnail path invalid");
-				}
-			}
-			elseif ($type[2] == 2) {
-				if (!imagejpeg($thumbnail, $thumbpath)) {
-					$error = __("Thumbnail path invalid");
-				}
-			}
-			elseif ($type[2] == 3) {
-				if (!imagepng($thumbnail, $thumbpath)) {
-					$error = __("Thumbnail path invalid");
-				}
+	if ( $categories ) {
+		foreach ( $categories as $category ) {
+			if ( $currentcat != $category->cat_ID && $parent == $category->category_parent) {
+				$pad = str_repeat( '&#8211; ', $level );
+				$category->cat_name = wp_specialchars( $category->cat_name );
+				echo "\n\t<option value='$category->cat_ID'";
+				if ( $currentparent == $category->cat_ID )
+					echo " selected='selected'";
+				echo ">$pad$category->cat_name</option>";
+				wp_dropdown_cats( $currentcat, $currentparent, $category->cat_ID, $level +1, $categories );
 			}
-
 		}
 	} else {
-		$error = __('File not found');
-	}
-
-	if (!empty ($error)) {
-		return $error;
-	} else {
-		return $thumbpath;
+		return false;
 	}
 }
 
 // Some postmeta stuff
-function has_meta($postid) {
+function has_meta( $postid ) {
 	global $wpdb;
 
-	return $wpdb->get_results("
+	return $wpdb->get_results( "
 			SELECT meta_key, meta_value, meta_id, post_id
 			FROM $wpdb->postmeta
 			WHERE post_id = '$postid'
-			ORDER BY meta_key,meta_id", ARRAY_A);
+			ORDER BY meta_key,meta_id", ARRAY_A );
 
 }
 
-function list_meta($meta) {
+function list_meta( $meta ) {
 	global $post_ID;
 	// Exit if no meta
-	if (!$meta)
+	if (!$meta ) {
+		echo '<tbody id="the-list"><tr style="display: none;"><td>&nbsp;</td></tr></tbody>'; //TBODY needed for list-manipulation JS
 		return;
+	}
 	$count = 0;
 ?>
-<table id='meta-list' cellpadding="3">
+	<thead>
 	<tr>
-		<th><?php _e('Key') ?></th>
-		<th><?php _e('Value') ?></th>
-		<th colspan='2'><?php _e('Action') ?></th>
+		<th><?php _e( 'Key' ) ?></th>
+		<th><?php _e( 'Value' ) ?></th>
+		<th colspan='2'><?php _e( 'Action' ) ?></th>
 	</tr>
+	</thead>
 <?php
-
-
-	foreach ($meta as $entry) {
+	$r ="\n\t<tbody id='the-list'>";
+	foreach ( $meta as $entry ) {
 		++ $count;
-		if ($count % 2)
+		if ( $count % 2 )
 			$style = 'alternate';
 		else
 			$style = '';
-		if ('_' == $entry['meta_key'] { 0 })
+		if ('_' == $entry['meta_key'] { 0 } )
 			$style .= ' hidden';
 
-		if ( is_serialized($entry['meta_value']) ) {
-			if ( is_serialized_string($entry['meta_value']) ) {
+		if ( is_serialized( $entry['meta_value'] ) ) {
+			if ( is_serialized_string( $entry['meta_value'] ) ) {
 				// this is a serialized string, so we should display it
-				$entry['meta_value'] = maybe_unserialize($entry['meta_value']);
+				$entry['meta_value'] = maybe_unserialize( $entry['meta_value'] );
 			} else {
 				// this is a serialized array/object so we should NOT display it
 				--$count;
@@ -860,63 +1032,67 @@
 			}
 		}
 
-		$entry['meta_key'] = wp_specialchars( $entry['meta_key'], true );
-		$entry['meta_value'] = wp_specialchars( $entry['meta_value'], true );
-		echo "
-			<tr class='$style'>
-				<td valign='top'><input name='meta[{$entry['meta_id']}][key]' tabindex='6' type='text' size='20' value='{$entry['meta_key']}' /></td>
-				<td><textarea name='meta[{$entry['meta_id']}][value]' tabindex='6' rows='2' cols='30'>{$entry['meta_value']}</textarea></td>
-				<td align='center'><input name='updatemeta' type='submit' class='updatemeta' tabindex='6' value='".__('Update')."' /><br />
-				<input name='deletemeta[{$entry['meta_id']}]' type='submit' class='deletemeta' tabindex='6' value='".__('Delete')."' /></td>
-			</tr>
-		";
-	}
-	echo "
-		</table>
-	";
+		$key_js = js_escape( $entry['meta_key'] );
+		$entry['meta_key']   = attribute_escape($entry['meta_key']);
+		$entry['meta_value'] = attribute_escape($entry['meta_value']);
+		$entry['meta_id'] = (int) $entry['meta_id'];
+		$r .= "\n\t<tr id='meta-{$entry['meta_id']}' class='$style'>";
+		$r .= "\n\t\t<td valign='top'><input name='meta[{$entry['meta_id']}][key]' tabindex='6' type='text' size='20' value='{$entry['meta_key']}' /></td>";
+		$r .= "\n\t\t<td><textarea name='meta[{$entry['meta_id']}][value]' tabindex='6' rows='2' cols='30'>{$entry['meta_value']}</textarea></td>";
+		$r .= "\n\t\t<td align='center'><input name='updatemeta' type='submit' class='updatemeta' tabindex='6' value='".attribute_escape(__( 'Update' ))."' /><br />";
+		$r .= "\n\t\t<input name='deletemeta[{$entry['meta_id']}]' type='submit' onclick=\"return deleteSomething( 'meta', {$entry['meta_id']}, '";
+		$r .= js_escape(sprintf( __("You are about to delete the '%s' custom field on this post.\n'OK' to delete, 'Cancel' to stop." ), $key_js ) );
+		$r .= "' );\" class='deletemeta' tabindex='6' value='".attribute_escape(__( 'Delete' ))."' /></td>";
+		$r .= "\n\t</tr>";
+	}
+	echo $r;
+	echo "\n\t</tbody>";
 }
 
 // Get a list of previously defined keys
 function get_meta_keys() {
 	global $wpdb;
 
-	$keys = $wpdb->get_col("
+	$keys = $wpdb->get_col( "
 			SELECT meta_key
 			FROM $wpdb->postmeta
 			GROUP BY meta_key
-			ORDER BY meta_key");
+			ORDER BY meta_key" );
 
 	return $keys;
 }
 
 function meta_form() {
 	global $wpdb;
-	$keys = $wpdb->get_col("
-			SELECT meta_key
-			FROM $wpdb->postmeta
-			GROUP BY meta_key
-			ORDER BY meta_id DESC
-			LIMIT 10");
+	$limit = (int) apply_filters( 'postmeta_form_limit', 30 );
+	$keys = $wpdb->get_col( "
+		SELECT meta_key
+		FROM $wpdb->postmeta
+		GROUP BY meta_key
+		ORDER BY meta_id DESC
+		LIMIT $limit" );
+	if ( $keys )
+		natcasesort($keys);
 ?>
-<h3><?php _e('Add a new custom field:') ?></h3>
-<table cellspacing="3" cellpadding="3">
+<h3><?php _e( 'Add a new custom field:' ) ?></h3>
+<table id="newmeta" cellspacing="3" cellpadding="3">
 	<tr>
-<th colspan="2"><?php _e('Key') ?></th>
-<th><?php _e('Value') ?></th>
+<th colspan="2"><?php _e( 'Key' ) ?></th>
+<th><?php _e( 'Value' ) ?></th>
 </tr>
 	<tr valign="top">
 		<td align="right" width="18%">
-<?php if ($keys) : ?>
+<?php if ( $keys ) : ?>
 <select id="metakeyselect" name="metakeyselect" tabindex="7">
-<option value="#NONE#"><?php _e('- Select -'); ?></option>
+<option value="#NONE#"><?php _e( '- Select -' ); ?></option>
 <?php
 
-	foreach ($keys as $key) {
-		$key = wp_specialchars($key, 1);
+	foreach ( $keys as $key ) {
+		$key = attribute_escape( $key );
 		echo "\n\t<option value='$key'>$key</option>";
 	}
 ?>
-</select> <?php _e('or'); ?>
+</select> <?php _e( 'or' ); ?>
 <?php endif; ?>
 </td>
 <td><input type="text" id="metakeyinput" name="metakeyinput" tabindex="7" /></td>
@@ -924,91 +1100,110 @@
 	</tr>
 
 </table>
-<p class="submit"><input type="submit" name="updatemeta" tabindex="9" value="<?php _e('Add Custom Field &raquo;') ?>" /></p>
+<p class="submit"><input type="submit" id="updatemetasub" name="updatemeta" tabindex="9" value="<?php _e( 'Add Custom Field &raquo;' ) ?>" /></p>
 <?php
 
 }
 
-function add_meta($post_ID) {
+function add_meta( $post_ID ) {
 	global $wpdb;
+	$post_ID = (int) $post_ID;
+
+	$protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
 
-	$metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
-	$metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
-	$metavalue = maybe_serialize(stripslashes((trim($_POST['metavalue']))));
-	$metavalue = $wpdb->escape($metavalue);
+	$metakeyselect = $wpdb->escape( stripslashes( trim( $_POST['metakeyselect'] ) ) );
+	$metakeyinput = $wpdb->escape( stripslashes( trim( $_POST['metakeyinput'] ) ) );
+	$metavalue = maybe_serialize( stripslashes( (trim( $_POST['metavalue'] ) ) ));
+	$metavalue = $wpdb->escape( $metavalue );
 
-	if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
+	if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
 		// We have a key/value pair. If both the select and the 
 		// input for the key have data, the input takes precedence:
 
-		if ('#NONE#' != $metakeyselect)
+ 		if ('#NONE#' != $metakeyselect)
 			$metakey = $metakeyselect;
 
-		if ($metakeyinput)
+		if ( $metakeyinput)
 			$metakey = $metakeyinput; // default
 
-		$result = $wpdb->query("
+		if ( in_array($metakey, $protected) )
+			return false;
+
+		$result = $wpdb->query( "
 						INSERT INTO $wpdb->postmeta 
-						(post_id,meta_key,meta_value) 
-						VALUES ('$post_ID','$metakey','$metavalue')
-					");
+						(post_id,meta_key,meta_value ) 
+						VALUES ('$post_ID','$metakey','$metavalue' )
+					" );
+		return $wpdb->insert_id;
 	}
+	return false;
 } // add_meta
 
-function delete_meta($mid) {
+function delete_meta( $mid ) {
 	global $wpdb;
+	$mid = (int) $mid;
 
-	$result = $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_id = '$mid'");
+	return $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_id = '$mid'" );
 }
 
-function update_meta($mid, $mkey, $mvalue) {
+function update_meta( $mid, $mkey, $mvalue ) {
 	global $wpdb;
-	$mvalue = maybe_serialize(stripslashes($mvalue));
-	$mvalue = $wpdb->escape($mvalue);
+
+	$protected = array( '_wp_attached_file', '_wp_attachment_metadata', '_wp_old_slug', '_wp_page_template' );
+
+	if ( in_array($mkey, $protected) )
+		return false;
+
+	$mvalue = maybe_serialize( stripslashes( $mvalue ));
+	$mvalue = $wpdb->escape( $mvalue );
 	$mid = (int) $mid;
-	return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
+	return $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'" );
 }
 
-function touch_time($edit = 1, $for_post = 1) {
-	global $month, $post, $comment;
+function get_post_meta_by_id( $mid ) {
+	global $wpdb;
+	$mid = (int) $mid;
+
+	$meta = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_id = '$mid'" );
+	if ( is_serialized_string( $meta->meta_value ) )
+		$meta->meta_value = maybe_unserialize( $meta->meta_value );
+	return $meta;
+}
+
+function touch_time( $edit = 1, $for_post = 1 ) {
+	global $wp_locale, $post, $comment;
 
 	if ( $for_post )
-		$edit = ( ('draft' == $post->post_status) && (!$post->post_date || '0000-00-00 00:00:00' == $post->post_date) ) ? false : true;
+		$edit = ( ('draft' == $post->post_status ) && (!$post->post_date || '0000-00-00 00:00:00' == $post->post_date ) ) ? false : true;
  
-	echo '<fieldset><legend><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp" /> <label for="timestamp">'.__('Edit timestamp').'</label></legend>';
+	echo '<fieldset><legend><input type="checkbox" class="checkbox" name="edit_date" value="1" id="timestamp" /> <label for="timestamp">'.__( 'Edit timestamp' ).'</label></legend>';
 
-	$time_adj = time() + (get_settings('gmt_offset') * 3600);
+	$time_adj = time() + (get_option( 'gmt_offset' ) * 3600 );
 	$post_date = ($for_post) ? $post->post_date : $comment->comment_date;
-	$jj = ($edit) ? mysql2date('d', $post_date) : gmdate('d', $time_adj);
-	$mm = ($edit) ? mysql2date('m', $post_date) : gmdate('m', $time_adj);
-	$aa = ($edit) ? mysql2date('Y', $post_date) : gmdate('Y', $time_adj);
-	$hh = ($edit) ? mysql2date('H', $post_date) : gmdate('H', $time_adj);
-	$mn = ($edit) ? mysql2date('i', $post_date) : gmdate('i', $time_adj);
-	$ss = ($edit) ? mysql2date('s', $post_date) : gmdate('s', $time_adj);
+	$jj = ($edit) ? mysql2date( 'd', $post_date ) : gmdate( 'd', $time_adj );
+	$mm = ($edit) ? mysql2date( 'm', $post_date ) : gmdate( 'm', $time_adj );
+	$aa = ($edit) ? mysql2date( 'Y', $post_date ) : gmdate( 'Y', $time_adj );
+	$hh = ($edit) ? mysql2date( 'H', $post_date ) : gmdate( 'H', $time_adj );
+	$mn = ($edit) ? mysql2date( 'i', $post_date ) : gmdate( 'i', $time_adj );
+	$ss = ($edit) ? mysql2date( 's', $post_date ) : gmdate( 's', $time_adj );
 
-	echo "<select name=\"mm\">\n";
-	for ($i = 1; $i < 13; $i = $i +1) {
+	echo "<select name=\"mm\" onchange=\"edit_date.checked=true\">\n";
+	for ( $i = 1; $i < 13; $i = $i +1 ) {
 		echo "\t\t\t<option value=\"$i\"";
-		if ($i == $mm)
-			echo " selected='selected'";
-		if ($i < 10) {
-			$ii = "0".$i;
-		} else {
-			$ii = "$i";
-		}
-		echo ">".$month["$ii"]."</option>\n";
+		if ( $i == $mm )
+			echo ' selected="selected"';
+		echo '>' . $wp_locale->get_month( $i ) . "</option>\n";
 	}
 ?>
 </select>
-<input type="text" id="jj" name="jj" value="<?php echo $jj; ?>" size="2" maxlength="2" />
-<input type="text" id="aa" name="aa" value="<?php echo $aa ?>" size="4" maxlength="5" /> @ 
-<input type="text" id="hh" name="hh" value="<?php echo $hh ?>" size="2" maxlength="2" /> : 
-<input type="text" id="mn" name="mn" value="<?php echo $mn ?>" size="2" maxlength="2" /> 
-<input type="hidden" id="ss" name="ss" value="<?php echo $ss ?>" size="2" maxlength="2" /> 
+<input type="text" id="jj" name="jj" value="<?php echo $jj; ?>" size="2" maxlength="2" onchange="edit_date.checked=true"/>
+<input type="text" id="aa" name="aa" value="<?php echo $aa ?>" size="4" maxlength="5" onchange="edit_date.checked=true" /> @
+<input type="text" id="hh" name="hh" value="<?php echo $hh ?>" size="2" maxlength="2" onchange="edit_date.checked=true" /> :
+<input type="text" id="mn" name="mn" value="<?php echo $mn ?>" size="2" maxlength="2" onchange="edit_date.checked=true" />
+<input type="hidden" id="ss" name="ss" value="<?php echo $ss ?>" size="2" maxlength="2" onchange="edit_date.checked=true" />
 <?php
 	if ( $edit ) {
-		_e('Existing timestamp');
-		echo ": {$month[$mm]} $jj, $aa @ $hh:$mn";
+		printf( __('Existing timestamp: %1$s %2$s, %3$s @ %4$s:%5$s' ), $wp_locale->get_month( $mm ), $jj, $aa, $hh, $mn );
 	}
 ?>
 </fieldset>
@@ -1017,45 +1212,49 @@
 }
 
 // insert_with_markers: Owen Winkler, fixed by Eric Anderson
-// Inserts an array of strings into a file (.htaccess), placing it between
+// Inserts an array of strings into a file (.htaccess ), placing it between
 // BEGIN and END markers.  Replaces existing marked info.  Retains surrounding
 // data.  Creates file if none exists.
 // Returns true on write success, false on failure.
-function insert_with_markers($filename, $marker, $insertion) {
-	if (!file_exists($filename) || is_writeable($filename)) {
-		if (!file_exists($filename)) {
+function insert_with_markers( $filename, $marker, $insertion ) {
+	if (!file_exists( $filename ) || is_writeable( $filename ) ) {
+		if (!file_exists( $filename ) ) {
 			$markerdata = '';
 		} else {
-			$markerdata = explode("\n", implode('', file($filename)));
+			$markerdata = explode( "\n", implode( '', file( $filename ) ) );
 		}
 
-		$f = fopen($filename, 'w');
+		$f = fopen( $filename, 'w' );
 		$foundit = false;
-		if ($markerdata) {
+		if ( $markerdata ) {
 			$state = true;
-			foreach ($markerdata as $markerline) {
-				if (strstr($markerline, "# BEGIN {$marker}"))
+			foreach ( $markerdata as $n => $markerline ) {
+				if (strpos($markerline, '# BEGIN ' . $marker) !== false)
 					$state = false;
-				if ($state)
-					fwrite($f, "{$markerline}\n");
-				if (strstr($markerline, "# END {$marker}")) {
-					fwrite($f, "# BEGIN {$marker}\n");
-					if (is_array($insertion))
-						foreach ($insertion as $insertline)
-							fwrite($f, "{$insertline}\n");
-					fwrite($f, "# END {$marker}\n");
+				if ( $state ) {
+					if ( $n + 1 < count( $markerdata ) )
+						fwrite( $f, "{$markerline}\n" );
+					else
+						fwrite( $f, "{$markerline}" );
+				}
+				if (strpos($markerline, '# END ' . $marker) !== false) {
+					fwrite( $f, "# BEGIN {$marker}\n" );
+					if ( is_array( $insertion ))
+						foreach ( $insertion as $insertline )
+							fwrite( $f, "{$insertline}\n" );
+					fwrite( $f, "# END {$marker}\n" );
 					$state = true;
 					$foundit = true;
 				}
 			}
 		}
 		if (!$foundit) {
-			fwrite($f, "# BEGIN {$marker}\n");
-			foreach ($insertion as $insertline)
-				fwrite($f, "{$insertline}\n");
-			fwrite($f, "# END {$marker}\n");
+			fwrite( $f, "# BEGIN {$marker}\n" );
+			foreach ( $insertion as $insertline )
+				fwrite( $f, "{$insertline}\n" );
+			fwrite( $f, "# END {$marker}\n" );
 		}
-		fclose($f);
+		fclose( $f );
 		return true;
 	} else {
 		return false;
@@ -1063,24 +1262,24 @@
 }
 
 // extract_from_markers: Owen Winkler
-// Returns an array of strings from a file (.htaccess) from between BEGIN
+// Returns an array of strings from a file (.htaccess ) from between BEGIN
 // and END markers.
-function extract_from_markers($filename, $marker) {
+function extract_from_markers( $filename, $marker ) {
 	$result = array ();
 
-	if (!file_exists($filename)) {
+	if (!file_exists( $filename ) ) {
 		return $result;
 	}
 
-	if ($markerdata = explode("\n", implode('', file($filename))));
+	if ( $markerdata = explode( "\n", implode( '', file( $filename ) ) ));
 	{
 		$state = false;
-		foreach ($markerdata as $markerline) {
-			if (strstr($markerline, "# END {$marker}"))
+		foreach ( $markerdata as $markerline ) {
+			if (strpos($markerline, '# END ' . $marker) !== false)
 				$state = false;
-			if ($state)
+			if ( $state )
 				$result[] = $markerline;
-			if (strstr($markerline, "# BEGIN {$marker}"))
+			if (strpos($markerline, '# BEGIN ' . $marker) !== false)
 				$state = true;
 		}
 	}
@@ -1095,8 +1294,8 @@
 	if ( !$is_apache )
 		return false;
 
-	if ( function_exists('apache_get_modules') ) {
-		if ( !in_array('mod_rewrite', apache_get_modules()) )
+	if ( function_exists( 'apache_get_modules' ) ) {
+		if ( !in_array( 'mod_rewrite', apache_get_modules() ) )
 			return false;
 	}
 
@@ -1107,79 +1306,17 @@
 	global $is_apache, $wp_rewrite;
 	$home_path = get_home_path();
 
-	if (!$wp_rewrite->using_mod_rewrite_permalinks())
-		return;
-
-	if (!((!file_exists($home_path.'.htaccess') && is_writable($home_path)) || is_writable($home_path.'.htaccess')))
-		return;
-
-	if (! got_mod_rewrite())
-		return;
-
-	$rules = explode("\n", $wp_rewrite->mod_rewrite_rules());
-	insert_with_markers($home_path.'.htaccess', 'WordPress', $rules);
-}
+	if (!$wp_rewrite->using_mod_rewrite_permalinks() )
+		return false;
 
-function the_quicktags() {
-	// Browser detection sucks, but until Safari supports the JS needed for this to work people just assume it's a bug in WP
-	if (!strstr($_SERVER['HTTP_USER_AGENT'], 'Safari'))
-		echo '
-		<div id="quicktags">
-			<script src="../wp-includes/js/quicktags.js" type="text/javascript"></script>
-			<script type="text/javascript">if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 ) edToolbar();</script>
-		</div>
-';
-	else echo '
-<script type="text/javascript">
-function edInsertContent(myField, myValue) {
-	//IE support
-	if (document.selection) {
-		myField.focus();
-		sel = document.selection.createRange();
-		sel.text = myValue;
-		myField.focus();
-	}
-	//MOZILLA/NETSCAPE support
-	else if (myField.selectionStart || myField.selectionStart == "0") {
-		var startPos = myField.selectionStart;
-		var endPos = myField.selectionEnd;
-		myField.value = myField.value.substring(0, startPos)
-		              + myValue 
-                      + myField.value.substring(endPos, myField.value.length);
-		myField.focus();
-		myField.selectionStart = startPos + myValue.length;
-		myField.selectionEnd = startPos + myValue.length;
-	} else {
-		myField.value += myValue;
-		myField.focus();
-	}
-}
-</script>
-';
-}
-
-function validate_current_theme() {
-	$theme_loc = 'wp-content/themes';
-	$theme_root = ABSPATH.$theme_loc;
-
-	$template = get_settings('template');
-	$stylesheet = get_settings('stylesheet');
-
-	if (($template != 'default') && (!file_exists("$theme_root/$template/index.php"))) {
-		update_option('template', 'default');
-		update_option('stylesheet', 'default');
-		do_action('switch_theme', 'Default');
+	if (!((!file_exists( $home_path.'.htaccess' ) && is_writable( $home_path ) ) || is_writable( $home_path.'.htaccess' ) ) )
 		return false;
-	}
 
-	if (($stylesheet != 'default') && (!file_exists("$theme_root/$stylesheet/style.css"))) {
-		update_option('template', 'default');
-		update_option('stylesheet', 'default');
-		do_action('switch_theme', 'Default');
+	if (! got_mod_rewrite() )
 		return false;
-	}
 
-	return true;
+	$rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() );
+	return insert_with_markers( $home_path.'.htaccess', 'WordPress', $rules );
 }
 
 function get_broken_themes() {
@@ -1195,17 +1332,17 @@
 	$templates = $themes[$theme]['Template Files'];
 	$page_templates = array ();
 
-	if (is_array($templates)) {
-		foreach ($templates as $template) {
-			$template_data = implode('', file(ABSPATH.$template));
-			preg_match("|Template Name:(.*)|i", $template_data, $name);
-			preg_match("|Description:(.*)|i", $template_data, $description);
+	if ( is_array( $templates ) ) {
+		foreach ( $templates as $template ) {
+			$template_data = implode( '', file( ABSPATH.$template ));
+			preg_match( "|Template Name:(.*)|i", $template_data, $name );
+			preg_match( "|Description:(.*)|i", $template_data, $description );
 
 			$name = $name[1];
 			$description = $description[1];
 
-			if (!empty ($name)) {
-				$page_templates[trim($name)] = basename($template);
+			if (!empty ( $name ) ) {
+				$page_templates[trim( $name )] = basename( $template );
 			}
 		}
 	}
@@ -1213,10 +1350,10 @@
 	return $page_templates;
 }
 
-function page_template_dropdown($default = '') {
+function page_template_dropdown( $default = '' ) {
 	$templates = get_page_templates();
-	foreach (array_keys($templates) as $template)
-		: if ($default == $templates[$template])
+	foreach (array_keys( $templates ) as $template )
+		: if ( $default == $templates[$template] )
 			$selected = " selected='selected'";
 		else
 			$selected = '';
@@ -1224,26 +1361,26 @@
 	endforeach;
 }
 
-function parent_dropdown($default = 0, $parent = 0, $level = 0) {
+function parent_dropdown( $default = 0, $parent = 0, $level = 0 ) {
 	global $wpdb, $post_ID;
-	$items = $wpdb->get_results("SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = $parent AND post_status = 'static' ORDER BY menu_order");
+	$items = $wpdb->get_results( "SELECT ID, post_parent, post_title FROM $wpdb->posts WHERE post_parent = $parent AND post_type = 'page' ORDER BY menu_order" );
 
-	if ($items) {
-		foreach ($items as $item) {
-			// A page cannot be it's own parent.
-			if (!empty ($post_ID)) {
-				if ($item->ID == $post_ID) {
+	if ( $items ) {
+		foreach ( $items as $item ) {
+			// A page cannot be its own parent.
+			if (!empty ( $post_ID ) ) {
+				if ( $item->ID == $post_ID ) {
 					continue;
 				}
 			}
-			$pad = str_repeat('&nbsp;', $level * 3);
-			if ($item->ID == $default)
+			$pad = str_repeat( '&nbsp;', $level * 3 );
+			if ( $item->ID == $default)
 				$current = ' selected="selected"';
 			else
 				$current = '';
 
 			echo "\n\t<option value='$item->ID'$current>$pad $item->post_title</option>";
-			parent_dropdown($default, $item->ID, $level +1);
+			parent_dropdown( $default, $item->ID, $level +1 );
 		}
 	} else {
 		return false;
@@ -1254,41 +1391,59 @@
 	global $pagenow;
 	global $menu;
 	global $submenu;
+	global $_wp_menu_nopriv;
+	global $_wp_submenu_nopriv;
 	global $plugin_page;
 
 	$parent = get_admin_page_parent();
 
-	foreach ($menu as $menu_array) {
-		//echo "parent array: " . $menu_array[2];
-		if ($menu_array[2] == $parent) {
-			if (!current_user_can($menu_array[1])) {
+	if ( isset( $_wp_submenu_nopriv[$parent][$pagenow] ) )
+		return false;
+
+	if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$parent][$plugin_page] ) )
+		return false;
+
+	if ( empty( $parent) ) {
+		if ( isset( $_wp_menu_nopriv[$pagenow] ) )
+			return false;
+		if ( isset( $_wp_submenu_nopriv[$pagenow][$pagenow] ) )
+			return false;
+		if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) )
+			return false;
+		foreach (array_keys( $_wp_submenu_nopriv ) as $key ) {
+			if ( isset( $_wp_submenu_nopriv[$key][$pagenow] ) )
 				return false;
-			} else {
-				break;
-			}
+			if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$key][$plugin_page] ) )
+			return false;
 		}
+		return true;
 	}
 
-	if (isset ($submenu[$parent])) {
-		if ( isset($plugin_page) ) {
-			foreach ($submenu[$parent] as $submenu_array) {
-				if ( $submenu_array[2] == $plugin_page ) {
-					if (!current_user_can($submenu_array[1]))
-						return false;
-				}
-			}
-		}
-
-		foreach ($submenu[$parent] as $submenu_array) {		
-			if ($submenu_array[2] == $pagenow) {
-				if (!current_user_can($submenu_array[1]))
-					return false;
+	if ( isset( $submenu[$parent] ) ) {
+		foreach ( $submenu[$parent] as $submenu_array ) {
+			if ( isset( $plugin_page ) && ( $submenu_array[2] == $plugin_page ) ) {
+				if ( current_user_can( $submenu_array[1] ))
+					return true;
 				else
+					return false;
+			} else if ( $submenu_array[2] == $pagenow ) {
+				if ( current_user_can( $submenu_array[1] ))
 					return true;
+				else
+					return false;
 			}
 		}
 	}
 
+	foreach ( $menu as $menu_array ) {
+		if ( $menu_array[2] == $parent) {
+			if ( current_user_can( $menu_array[1] ))
+				return true;
+			else
+				return false;
+		}
+	}
+
 	return true;
 }
 
@@ -1299,44 +1454,55 @@
 	global $pagenow;
 	global $plugin_page;
 
-	if (isset ($title) && !empty ($title)) {
+	if ( isset( $title ) && !empty ( $title ) ) {
 		return $title;
 	}
 
-	$hook = get_plugin_page_hook($plugin_page, $pagenow);
+	$hook = get_plugin_page_hook( $plugin_page, $pagenow );
 
 	$parent = $parent1 = get_admin_page_parent();
-	if (empty ($parent)) {
-		foreach ($menu as $menu_array) {
-			if (isset ($menu_array[3])) {
-				if ($menu_array[2] == $pagenow) {
+	if ( empty ( $parent) ) {
+		foreach ( $menu as $menu_array ) {
+			if ( isset( $menu_array[3] ) ) {
+				if ( $menu_array[2] == $pagenow ) {
 					$title = $menu_array[3];
 					return $menu_array[3];
 				} else
-					if (isset ($plugin_page) && ($plugin_page == $menu_array[2]) && ($hook == $menu_array[3])) {
+					if ( isset( $plugin_page ) && ($plugin_page == $menu_array[2] ) && ($hook == $menu_array[3] ) ) {
 						$title = $menu_array[3];
 						return $menu_array[3];
 					}
+			} else {
+				$title = $menu_array[0];
+				return $title;
 			}
 		}
 	} else {
-		foreach (array_keys($submenu) as $parent) {
-			foreach ($submenu[$parent] as $submenu_array) {
-				if (isset ($submenu_array[3])) {
-					if ($submenu_array[2] == $pagenow) {
+		foreach (array_keys( $submenu ) as $parent) {
+			foreach ( $submenu[$parent] as $submenu_array ) {
+				if ( isset( $plugin_page ) && 
+					($plugin_page == $submenu_array[2] ) && 
+					(($parent == $pagenow ) || ($parent == $plugin_page ) || ($plugin_page == $hook ) || (($pagenow == 'admin.php' ) && ($parent1 != $submenu_array[2] ) ) )
+					) {
 						$title = $submenu_array[3];
 						return $submenu_array[3];
-					} else
-						if (isset ($plugin_page) && ($plugin_page == $submenu_array[2]) && (($parent == $pagenow) || ($parent == $plugin_page) || ($plugin_page == $hook) || (($pagenow == 'admin.php') && ($parent1 != $submenu_array[2])))) {
-							$title = $submenu_array[3];
-							return $submenu_array[3];
-						}
+					}
+
+				if ( $submenu_array[2] != $pagenow || isset( $_GET['page'] ) ) // not the current page
+					continue;
+
+				if ( isset( $submenu_array[3] ) ) {
+					$title = $submenu_array[3];
+					return $submenu_array[3];
+				} else {
+					$title = $submenu_array[0];
+					return $title;
 				}
 			}
 		}
 	}
 
-	return '';
+	return $title;
 }
 
 function get_admin_page_parent() {
@@ -1345,27 +1511,50 @@
 	global $submenu;
 	global $pagenow;
 	global $plugin_page;
+	global $_wp_real_parent_file;
+	global $_wp_menu_nopriv;
+	global $_wp_submenu_nopriv;
+
+	if ( !empty ( $parent_file ) ) {
+		if ( isset( $_wp_real_parent_file[$parent_file] ) )
+			$parent_file = $_wp_real_parent_file[$parent_file];
 
-	if (isset ($parent_file) && !empty ($parent_file)) {
 		return $parent_file;
 	}
 
-	if ($pagenow == 'admin.php' && isset ($plugin_page)) {
-		foreach ($menu as $parent_menu) {
-			if ($parent_menu[2] == $plugin_page) {
+	if ( $pagenow == 'admin.php' && isset( $plugin_page ) ) {
+		foreach ( $menu as $parent_menu ) {
+			if ( $parent_menu[2] == $plugin_page ) {
 				$parent_file = $plugin_page;
-				return $plugin_page;
+				if ( isset( $_wp_real_parent_file[$parent_file] ) )
+					$parent_file = $_wp_real_parent_file[$parent_file];
+				return $parent_file;
 			}
 		}
+		if ( isset( $_wp_menu_nopriv[$plugin_page] ) ) {
+			$parent_file = $plugin_page;
+			if ( isset( $_wp_real_parent_file[$parent_file] ) )
+					$parent_file = $_wp_real_parent_file[$parent_file];
+			return $parent_file;
+		}
+	}
+
+	if ( isset( $plugin_page ) && isset( $_wp_submenu_nopriv[$pagenow][$plugin_page] ) ) {
+		$parent_file = $pagenow;
+		if ( isset( $_wp_real_parent_file[$parent_file] ) )
+			$parent_file = $_wp_real_parent_file[$parent_file];
+		return $parent_file;
 	}
 
-	foreach (array_keys($submenu) as $parent) {
-		foreach ($submenu[$parent] as $submenu_array) {
-			if ($submenu_array[2] == $pagenow) {
+	foreach (array_keys( $submenu ) as $parent) {
+		foreach ( $submenu[$parent] as $submenu_array ) {
+			if ( isset( $_wp_real_parent_file[$parent] ) )
+				$parent = $_wp_real_parent_file[$parent];
+			if ( $submenu_array[2] == $pagenow ) {
 				$parent_file = $parent;
 				return $parent;
 			} else
-				if (isset ($plugin_page) && ($plugin_page == $submenu_array[2])) {
+				if ( isset( $plugin_page ) && ($plugin_page == $submenu_array[2] ) ) {
 					$parent_file = $parent;
 					return $parent;
 				}
@@ -1376,102 +1565,120 @@
 	return '';
 }
 
-function add_menu_page($page_title, $menu_title, $access_level, $file, $function = '') {
+function add_menu_page( $page_title, $menu_title, $access_level, $file, $function = '' ) {
 	global $menu, $admin_page_hooks;
 
-	$file = plugin_basename($file);
+	$file = plugin_basename( $file );
 
-	$menu[] = array ($menu_title, $access_level, $file, $page_title);
+	$menu[] = array ( $menu_title, $access_level, $file, $page_title );
 
-	$admin_page_hooks[$file] = sanitize_title($menu_title);
+	$admin_page_hooks[$file] = sanitize_title( $menu_title );
 
-	$hookname = get_plugin_page_hookname($file, '');
-	if (!empty ($function) && !empty ($hookname))
-		add_action($hookname, $function);
+	$hookname = get_plugin_page_hookname( $file, '' );
+	if (!empty ( $function ) && !empty ( $hookname ))
+		add_action( $hookname, $function );
 
 	return $hookname;
 }
 
-function add_submenu_page($parent, $page_title, $menu_title, $access_level, $file, $function = '') {
+function add_submenu_page( $parent, $page_title, $menu_title, $access_level, $file, $function = '' ) {
 	global $submenu;
 	global $menu;
+	global $_wp_real_parent_file;
+	global $_wp_submenu_nopriv;
+	global $_wp_menu_nopriv;
+
+	$file = plugin_basename( $file );
+
+	$parent = plugin_basename( $parent);
+	if ( isset( $_wp_real_parent_file[$parent] ) )
+		$parent = $_wp_real_parent_file[$parent];
 
-	$parent = plugin_basename($parent);
-	$file = plugin_basename($file);
+	if ( !current_user_can( $access_level ) ) {
+		$_wp_submenu_nopriv[$parent][$file] = true;
+		return false;
+	}
 
 	// If the parent doesn't already have a submenu, add a link to the parent
 	// as the first item in the submenu.  If the submenu file is the same as the
 	// parent file someone is trying to link back to the parent manually.  In
 	// this case, don't automatically add a link back to avoid duplication.
-	if (!isset ($submenu[$parent]) && $file != $parent) {
-		foreach ($menu as $parent_menu) {
-			if ($parent_menu[2] == $parent) {
+	if (!isset( $submenu[$parent] ) && $file != $parent  ) {
+		foreach ( $menu as $parent_menu ) {
+			if ( $parent_menu[2] == $parent && current_user_can( $parent_menu[1] ) )
 				$submenu[$parent][] = $parent_menu;
-			}
 		}
 	}
 
-	$submenu[$parent][] = array ($menu_title, $access_level, $file, $page_title);
+	$submenu[$parent][] = array ( $menu_title, $access_level, $file, $page_title );
 
-	$hookname = get_plugin_page_hookname($file, $parent);
-	if (!empty ($function) && !empty ($hookname))
-		add_action($hookname, $function);
+	$hookname = get_plugin_page_hookname( $file, $parent);
+	if (!empty ( $function ) && !empty ( $hookname ))
+		add_action( $hookname, $function );
 
 	return $hookname;
 }
 
-function add_options_page($page_title, $menu_title, $access_level, $file, $function = '') {
-	return add_submenu_page('options-general.php', $page_title, $menu_title, $access_level, $file, $function);
+function add_options_page( $page_title, $menu_title, $access_level, $file, $function = '' ) {
+	return add_submenu_page( 'options-general.php', $page_title, $menu_title, $access_level, $file, $function );
 }
 
-function add_management_page($page_title, $menu_title, $access_level, $file, $function = '') {
-	return add_submenu_page('edit.php', $page_title, $menu_title, $access_level, $file, $function);
+function add_management_page( $page_title, $menu_title, $access_level, $file, $function = '' ) {
+	return add_submenu_page( 'edit.php', $page_title, $menu_title, $access_level, $file, $function );
 }
 
-function add_theme_page($page_title, $menu_title, $access_level, $file, $function = '') {
-	return add_submenu_page('themes.php', $page_title, $menu_title, $access_level, $file, $function);
+function add_theme_page( $page_title, $menu_title, $access_level, $file, $function = '' ) {
+	return add_submenu_page( 'themes.php', $page_title, $menu_title, $access_level, $file, $function );
+}
+
+function add_users_page( $page_title, $menu_title, $access_level, $file, $function = '' ) {
+	if ( current_user_can('edit_users') )
+		$parent = 'users.php';
+	else
+		$parent = 'profile.php';
+	return add_submenu_page( $parent, $page_title, $menu_title, $access_level, $file, $function );
 }
 
-function validate_file($file, $allowed_files = '') {
-	if (false !== strpos($file, './'))
+function validate_file( $file, $allowed_files = '' ) {
+	if ( false !== strpos( $file, './' ))
 		return 1;
 
-	if (':' == substr($file, 1, 1))
+	if (':' == substr( $file, 1, 1 ))
 		return 2;
 
-	if (!empty ($allowed_files) && (!in_array($file, $allowed_files)))
+	if (!empty ( $allowed_files ) && (!in_array( $file, $allowed_files ) ) )
 		return 3;
 
 	return 0;
 }
 
-function validate_file_to_edit($file, $allowed_files = '') {
-	$file = stripslashes($file);
+function validate_file_to_edit( $file, $allowed_files = '' ) {
+	$file = stripslashes( $file );
 
-	$code = validate_file($file, $allowed_files);
+	$code = validate_file( $file, $allowed_files );
 
-	if (!$code)
+	if (!$code )
 		return $file;
 
-	switch ($code) {
+	switch ( $code ) {
 		case 1 :
-			die(__('Sorry, can&#8217;t edit files with ".." in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.'));
+			wp_die( __('Sorry, can&#8217;t edit files with ".." in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.' ));
 
 		case 2 :
-			die(__('Sorry, can&#8217;t call files with their real path.'));
+			wp_die( __('Sorry, can&#8217;t call files with their real path.' ));
 
 		case 3 :
-			die(__('Sorry, that file cannot be edited.'));
+			wp_die( __('Sorry, that file cannot be edited.' ));
 	}
 }
 
 function get_home_path() {
-	$home = get_settings('home');
-	if ($home != '' && $home != get_settings('siteurl')) {
-		$home_path = parse_url($home);
+	$home = get_option( 'home' );
+	if ( $home != '' && $home != get_option( 'siteurl' ) ) {
+		$home_path = parse_url( $home );
 		$home_path = $home_path['path'];
-		$root = str_replace($_SERVER["PHP_SELF"], '', $_SERVER["SCRIPT_FILENAME"]);
-		$home_path = trailingslashit($root.$home_path);
+		$root = str_replace( $_SERVER["PHP_SELF"], '', $_SERVER["SCRIPT_FILENAME"] );
+		$home_path = trailingslashit( $root.$home_path );
 	} else {
 		$home_path = ABSPATH;
 	}
@@ -1479,8 +1686,8 @@
 	return $home_path;
 }
 
-function get_real_file_to_edit($file) {
-	if ('index.php' == $file || '.htaccess' == $file) {
+function get_real_file_to_edit( $file ) {
+	if ('index.php' == $file || '.htaccess' == $file ) {
 		$real_file = get_home_path().$file;
 	} else {
 		$real_file = ABSPATH.$file;
@@ -1489,99 +1696,98 @@
 	return $real_file;
 }
 
-$wp_file_descriptions = array ('index.php' => __('Main Index Template'), 'style.css' => __('Stylesheet'), 'comments.php' => __('Comments'), 'comments-popup.php' => __('Popup Comments'), 'footer.php' => __('Footer'), 'header.php' => __('Header'), 'sidebar.php' => __('Sidebar'), 'archive.php' => __('Archives'), 'category.php' => __('Category Template'), 'page.php' => __('Page Template'), 'search.php' => __('Search Results'), 'single.php' => __('Single Post'), '404.php' => __('404 Template'), 'my-hacks.php' => __('my-hacks.php (legacy hacks support)'), '.htaccess' => __('.htaccess (for rewrite rules)'),
+$wp_file_descriptions = array ('index.php' => __( 'Main Index Template' ), 'style.css' => __( 'Stylesheet' ), 'comments.php' => __( 'Comments' ), 'comments-popup.php' => __( 'Popup Comments' ), 'footer.php' => __( 'Footer' ), 'header.php' => __( 'Header' ), 'sidebar.php' => __( 'Sidebar' ), 'archive.php' => __( 'Archives' ), 'category.php' => __( 'Category Template' ), 'page.php' => __( 'Page Template' ), 'search.php' => __( 'Search Results' ), 'single.php' => __( 'Single Post' ), '404.php' => __( '404 Template' ), 'my-hacks.php' => __( 'my-hacks.php (legacy hacks support)' ), '.htaccess' => __( '.htaccess (for rewrite rules )' ),
 	// Deprecated files
-	'wp-layout.css' => __('Stylesheet'), 'wp-comments.php' => __('Comments Template'), 'wp-comments-popup.php' => __('Popup Comments Template'));
+	'wp-layout.css' => __( 'Stylesheet' ), 'wp-comments.php' => __( 'Comments Template' ), 'wp-comments-popup.php' => __( 'Popup Comments Template' ));
 
-function get_file_description($file) {
+function get_file_description( $file ) {
 	global $wp_file_descriptions;
 
-	if (isset ($wp_file_descriptions[basename($file)])) {
-		return $wp_file_descriptions[basename($file)];
+	if ( isset( $wp_file_descriptions[basename( $file )] ) ) {
+		return $wp_file_descriptions[basename( $file )];
 	}
-	elseif (file_exists(ABSPATH.$file)) {
-		$template_data = implode('', file(ABSPATH.$file));
-		if (preg_match("|Template Name:(.*)|i", $template_data, $name))
+	elseif ( file_exists( ABSPATH . $file ) && is_file( ABSPATH . $file ) ) {
+		$template_data = implode( '', file( ABSPATH . $file ) );
+		if ( preg_match( "|Template Name:(.*)|i", $template_data, $name ))
 			return $name[1];
 	}
 
-	return basename($file);
+	return basename( $file );
 }
 
-function update_recently_edited($file) {
-	$oldfiles = (array) get_option('recently_edited');
-	if ($oldfiles) {
-		$oldfiles = array_reverse($oldfiles);
+function update_recently_edited( $file ) {
+	$oldfiles = (array ) get_option( 'recently_edited' );
+	if ( $oldfiles ) {
+		$oldfiles = array_reverse( $oldfiles );
 		$oldfiles[] = $file;
-		$oldfiles = array_reverse($oldfiles);
-		$oldfiles = array_unique($oldfiles);
-		if (5 < count($oldfiles))
-			array_pop($oldfiles);
+		$oldfiles = array_reverse( $oldfiles );
+		$oldfiles = array_unique( $oldfiles );
+		if ( 5 < count( $oldfiles ))
+			array_pop( $oldfiles );
 	} else {
 		$oldfiles[] = $file;
 	}
-	update_option('recently_edited', $oldfiles);
+	update_option( 'recently_edited', $oldfiles );
 }
 
-function get_plugin_data($plugin_file) {
-	$plugin_data = implode('', file($plugin_file));
-	preg_match("|Plugin Name:(.*)|i", $plugin_data, $plugin_name);
-	preg_match("|Plugin URI:(.*)|i", $plugin_data, $plugin_uri);
-	preg_match("|Description:(.*)|i", $plugin_data, $description);
-	preg_match("|Author:(.*)|i", $plugin_data, $author_name);
-	preg_match("|Author URI:(.*)|i", $plugin_data, $author_uri);
-	if (preg_match("|Version:(.*)|i", $plugin_data, $version))
-		$version = trim($version[1]);
+function get_plugin_data( $plugin_file ) {
+	$plugin_data = implode( '', file( $plugin_file ));
+	preg_match( "|Plugin Name:(.*)|i", $plugin_data, $plugin_name );
+	preg_match( "|Plugin URI:(.*)|i", $plugin_data, $plugin_uri );
+	preg_match( "|Description:(.*)|i", $plugin_data, $description );
+	preg_match( "|Author:(.*)|i", $plugin_data, $author_name );
+	preg_match( "|Author URI:(.*)|i", $plugin_data, $author_uri );
+	if ( preg_match( "|Version:(.*)|i", $plugin_data, $version ))
+		$version = trim( $version[1] );
 	else
 		$version = '';
 
-	$description = wptexturize(trim($description[1]));
+	$description = wptexturize( trim( $description[1] ));
 
 	$name = $plugin_name[1];
-	$name = trim($name);
+	$name = trim( $name );
 	$plugin = $name;
-	if ('' != $plugin_uri[1] && '' != $name) {
-		$plugin = '<a href="' . trim($plugin_uri[1]) . '" title="'.__('Visit plugin homepage').'">'.$plugin.'</a>';
+	if ('' != $plugin_uri[1] && '' != $name ) {
+		$plugin = '<a href="' . trim( $plugin_uri[1] ) . '" title="'.__( 'Visit plugin homepage' ).'">'.$plugin.'</a>';
 	}
 
-	if ('' == $author_uri[1]) {
-		$author = trim($author_name[1]);
+	if ('' == $author_uri[1] ) {
+		$author = trim( $author_name[1] );
 	} else {
-		$author = '<a href="' . trim($author_uri[1]) . '" title="'.__('Visit author homepage').'">' . trim($author_name[1]) . '</a>';
+		$author = '<a href="' . trim( $author_uri[1] ) . '" title="'.__( 'Visit author homepage' ).'">' . trim( $author_name[1] ) . '</a>';
 	}
 
-	return array ('Name' => $name, 'Title' => $plugin, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template[1]);
+	return array('Name' => $name, 'Title' => $plugin, 'Description' => $description, 'Author' => $author, 'Version' => $version);
 }
 
 function get_plugins() {
 	global $wp_plugins;
 
-	if (isset ($wp_plugins)) {
+	if ( isset( $wp_plugins ) ) {
 		return $wp_plugins;
 	}
 
 	$wp_plugins = array ();
-	$plugin_loc = 'wp-content/plugins';
-	$plugin_root = ABSPATH.$plugin_loc;
+	$plugin_root = ABSPATH . PLUGINDIR;
 
 	// Files in wp-content/plugins directory
-	$plugins_dir = @ dir($plugin_root);
-	if ($plugins_dir) {
-		while (($file = $plugins_dir->read()) !== false) {
-			if (preg_match('|^\.+$|', $file))
+	$plugins_dir = @ dir( $plugin_root);
+	if ( $plugins_dir ) {
+		while (($file = $plugins_dir->read() ) !== false ) {
+			if ( substr($file, 0, 1) == '.' )
 				continue;
-			if (is_dir($plugin_root.'/'.$file)) {
-				$plugins_subdir = @ dir($plugin_root.'/'.$file);
-				if ($plugins_subdir) {
-					while (($subfile = $plugins_subdir->read()) !== false) {
-						if (preg_match('|^\.+$|', $subfile))
+			if ( is_dir( $plugin_root.'/'.$file ) ) {
+				$plugins_subdir = @ dir( $plugin_root.'/'.$file );
+				if ( $plugins_subdir ) {
+					while (($subfile = $plugins_subdir->read() ) !== false ) {
+						if ( substr($subfile, 0, 1) == '.' )
 							continue;
-						if (preg_match('|\.php$|', $subfile))
+						if ( substr($subfile, -4) == '.php' )
 							$plugin_files[] = "$file/$subfile";
 					}
 				}
 			} else {
-				if (preg_match('|\.php$|', $file))
+				if ( substr($file, -4) == '.php' )
 					$plugin_files[] = $file;
 			}
 		}
@@ -1591,77 +1797,78 @@
 		return $wp_plugins;
 
 	foreach ( $plugin_files as $plugin_file ) {
-		if ( !is_readable("$plugin_root/$plugin_file"))
+		if ( !is_readable( "$plugin_root/$plugin_file" ) )
 			continue;
 
-		$plugin_data = get_plugin_data("$plugin_root/$plugin_file");
+		$plugin_data = get_plugin_data( "$plugin_root/$plugin_file" );
 
-		if ( empty ($plugin_data['Name']) )
+		if ( empty ( $plugin_data['Name'] ) )
 			continue;
 
-		$wp_plugins[plugin_basename($plugin_file)] = $plugin_data;
+		$wp_plugins[plugin_basename( $plugin_file )] = $plugin_data;
 	}
 
-	uasort($wp_plugins, create_function('$a, $b', 'return strnatcasecmp($a["Name"], $b["Name"]);'));
+	uasort( $wp_plugins, create_function( '$a, $b', 'return strnatcasecmp( $a["Name"], $b["Name"] );' ));
 
 	return $wp_plugins;
 }
 
-function get_plugin_page_hookname($plugin_page, $parent_page) {
+function get_plugin_page_hookname( $plugin_page, $parent_page ) {
 	global $admin_page_hooks;
 
 	$parent = get_admin_page_parent();
 
-	if (empty ($parent_page) || 'admin.php' == $parent_page) {
-		if (isset ($admin_page_hooks[$plugin_page]))
+	if ( empty ( $parent_page ) || 'admin.php' == $parent_page ) {
+		if ( isset( $admin_page_hooks[$plugin_page] ))
 			$page_type = 'toplevel';
 		else
-			if (isset ($admin_page_hooks[$parent]))
+			if ( isset( $admin_page_hooks[$parent] ))
 				$page_type = $admin_page_hooks[$parent];
 	} else
-		if (isset ($admin_page_hooks[$parent_page])) {
+		if ( isset( $admin_page_hooks[$parent_page] ) ) {
 			$page_type = $admin_page_hooks[$parent_page];
 		} else {
 			$page_type = 'admin';
 		}
 
-	$plugin_name = preg_replace('!\.php!', '', $plugin_page);
+	$plugin_name = preg_replace( '!\.php!', '', $plugin_page );
 
 	return $page_type.'_page_'.$plugin_name;
 }
 
-function get_plugin_page_hook($plugin_page, $parent_page) {
+function get_plugin_page_hook( $plugin_page, $parent_page ) {
 	global $wp_filter;
 
-	$hook = get_plugin_page_hookname($plugin_page, $parent_page);
-	if (isset ($wp_filter[$hook]))
+	$hook = get_plugin_page_hookname( $plugin_page, $parent_page );
+	if ( isset( $wp_filter[$hook] ))
 		return $hook;
 	else
 		return '';
 }
 
 function browse_happy() {
-	$getit = __('WordPress recommends a better browser');
+	$getit = __( 'WordPress recommends a better browser' );
 	echo '
 		<p id="bh" style="text-align: center;"><a href="http://browsehappy.com/" title="'.$getit.'"><img src="images/browse-happy.gif" alt="Browse Happy" /></a></p>
 		';
 }
-if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE'))
-	add_action('admin_footer', 'browse_happy');
 
-function documentation_link($for) {
+if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false)
+	add_action( 'admin_footer', 'browse_happy' );
+
+function documentation_link( $for ) {
 	return;
 }
 
-function register_importer($id, $name, $description, $callback) {
+function register_importer( $id, $name, $description, $callback ) {
 	global $wp_importers;
 
-	$wp_importers[$id] = array ($name, $description, $callback);
+	$wp_importers[$id] = array ( $name, $description, $callback );
 }
 
 function get_importers() {
 	global $wp_importers;
-
+	uasort($wp_importers, create_function('$a, $b', 'return strcmp($a[0], $b[0]);'));
 	return $wp_importers;
 }
 
@@ -1685,14 +1892,14 @@
 
 // array wp_handle_upload ( array &file [, array overrides] )
 // file: reference to a single element of $_FILES. Call the function once for each uploaded file.
-// overrides: an associative array of names=>values to override default variables with extract($overrides, EXTR_OVERWRITE).
+// overrides: an associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ).
 // On success, returns an associative array of file attributes.
-// On failure, returns $overrides['upload_error_handler'](&$file, $message) or array('error'=>$message).
-function wp_handle_upload(&$file, $overrides = false) {
+// On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
+function wp_handle_upload( &$file, $overrides = false ) {
 	// The default error handler.
-	if (! function_exists('wp_handle_upload_error') ) {
-		function wp_handle_upload_error(&$file, $message) {
-			return array('error'=>$message);
+	if (! function_exists( 'wp_handle_upload_error' ) ) {
+		function wp_handle_upload_error( &$file, $message ) {
+			return array( 'error'=>$message );
 		}
 	}
 
@@ -1703,13 +1910,13 @@
 	$action = 'wp_handle_upload';
 
 	// Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
-	$upload_error_strings = array(false,
-		__("The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."),
-		__("The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."),
-		__("The uploaded file was only partially uploaded."),
-		__("No file was uploaded."),
-		__("Missing a temporary folder."),
-		__("Failed to write file to disk."));
+	$upload_error_strings = array( false,
+		__( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
+		__( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
+		__( "The uploaded file was only partially uploaded." ),
+		__( "No file was uploaded." ),
+		__( "Missing a temporary folder." ),
+		__( "Failed to write file to disk." ));
 
 	// All tests are on by default. Most can be turned off by $override[{test_name}] = false;
 	$test_form = true;
@@ -1719,175 +1926,407 @@
 	$test_type = true;
 
 	// Install user overrides. Did we mention that this voids your warranty?
-	if ( is_array($overrides) )
-		extract($overrides, EXTR_OVERWRITE);
+	if ( is_array( $overrides ) )
+		extract( $overrides, EXTR_OVERWRITE );
 
 	// A correct form post will pass this test.
-	if ( $test_form && (!isset($_POST['action']) || ($_POST['action'] != $action)) )
-		return $upload_error_handler($file, __('Invalid form submission.'));
+	if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
+		return $upload_error_handler( $file, __( 'Invalid form submission.' ));
 
 	// A successful upload will pass this test. It makes no sense to override this one.
 	if ( $file['error'] > 0 )
-		return $upload_error_handler($file, $upload_error_strings[$file['error']]);
+		return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
 
 	// A non-empty file will pass this test.
-	if ( $test_size && !($file['size'] > 0) )
-		return $upload_error_handler($file, __('File is empty. Please upload something more substantial.'));
+	if ( $test_size && !($file['size'] > 0 ) )
+		return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial.' ));
 
 	// A properly uploaded file will pass this test. There should be no reason to override this one.
-	if (! @ is_uploaded_file($file['tmp_name']) )
-		return $upload_error_handler($file, __('Specified file failed upload test.'));
+	if (! @ is_uploaded_file( $file['tmp_name'] ) )
+		return $upload_error_handler( $file, __( 'Specified file failed upload test.' ));
 
 	// A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
 	if ( $test_type ) {
-		$wp_filetype = wp_check_filetype($file['name'], $mimes);
+		$wp_filetype = wp_check_filetype( $file['name'], $mimes );
 
-		extract($wp_filetype);
+		extract( $wp_filetype );
 
 		if ( !$type || !$ext )
-			return $upload_error_handler($file, __('File type does not meet security guidelines. Try another.'));
+			return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
 	}
 
 	// A writable uploads dir will pass this test. Again, there's no point overriding this one.
 	if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
-		return $upload_error_handler($file, $uploads['error']);
+		return $upload_error_handler( $file, $uploads['error'] );
 
 	// Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied.
-	if ( isset($unique_filename_callback) && function_exists($unique_filename_callback) ) {
-		$filename = $unique_filename_callback($uploads['path'], $file['name']);
+	if ( isset( $unique_filename_callback ) && function_exists( $unique_filename_callback ) ) {
+		$filename = $unique_filename_callback( $uploads['path'], $file['name'] );
 	} else {
 		$number = '';
-		$filename = str_replace('#', '_', $file['name']);
-		$filename = str_replace(array('\\', "'"), '', $filename);
-		if ( empty($ext) )
+		$filename = str_replace( '#', '_', $file['name'] );
+		$filename = str_replace( array( '\\', "'" ), '', $filename );
+		if ( empty( $ext) )
 			$ext = '';
 		else
 			$ext = ".$ext";
-		while ( file_exists($uploads['path'] . "/$filename") ) {
+		while ( file_exists( $uploads['path'] . "/$filename" ) ) {
 			if ( '' == "$number$ext" )
 				$filename = $filename . ++$number . $ext;
 			else
-				$filename = str_replace("$number$ext", ++$number . $ext, $filename);
+				$filename = str_replace( "$number$ext", ++$number . $ext, $filename );
 		}
-		$filename = str_replace($ext, '', $filename);
-		$filename = sanitize_title_with_dashes($filename) . $ext;
+		$filename = str_replace( $ext, '', $filename );
+		$filename = sanitize_title_with_dashes( $filename ) . $ext;
 	}
 
 	// Move the file to the uploads dir
 	$new_file = $uploads['path'] . "/$filename";
-	if ( false === @ move_uploaded_file($file['tmp_name'], $new_file) )
-		die(printf(__('The uploaded file could not be moved to %s.'), $file['path']));
+	if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) )
+		wp_die( printf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ));
 
 	// Set correct file permissions
-	$stat = stat(dirname($new_file));
+	$stat = stat( dirname( $new_file ));
 	$perms = $stat['mode'] & 0000666;
-	@ chmod($new_file, $perms);
+	@ chmod( $new_file, $perms );
 
 	// Compute the URL
 	$url = $uploads['url'] . "/$filename";
 
-	return array('file' => $new_file, 'url' => $url, 'type' => $type);
+	$return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
+
+	return $return;
 }
 
-function wp_shrink_dimensions($width, $height, $wmax = 128, $hmax = 96) {
+function wp_shrink_dimensions( $width, $height, $wmax = 128, $hmax = 96 ) {
 	if ( $height <= $hmax && $width <= $wmax )
-		return array($width, $height);
+		return array( $width, $height);
 	elseif ( $width / $height > $wmax / $hmax )
-		return array($wmax, (int) ($height / $width * $wmax));
+		return array( $wmax, (int) ($height / $width * $wmax ));
 	else
-		return array((int) ($width / $height * $hmax), $hmax);
+		return array( (int) ($width / $height * $hmax ), $hmax );
 }
 
-function wp_import_cleanup($id) {
-	wp_delete_attachment($id);
+function wp_import_cleanup( $id ) {
+	wp_delete_attachment( $id );
 }
 
-function wp_import_upload_form($action) {
+function wp_import_upload_form( $action ) {
+	$size = strtolower( ini_get( 'upload_max_filesize' ) );
+	$bytes = 0;
+	if (strpos($size, 'k') !== false)
+		$bytes = $size * 1024;
+	if (strpos($size, 'm') !== false)
+		$bytes = $size * 1024 * 1024;
+	if (strpos($size, 'g') !== false)
+		$bytes = $size * 1024 * 1024 * 1024;
 ?>
-<script type="text/javascript">
-function cancelUpload() {
-o = document.getElementById('uploadForm');
-o.method = 'GET';
-o.action.value = 'view';
-o.submit();
-}
-</script>
-<form enctype="multipart/form-data" id="uploadForm" method="post" action="<?php echo $action ?>">
-<label for="upload"><?php _e('File:'); ?></label><input type="file" id="upload" name="import" />
+<form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo attribute_escape($action) ?>">
+<p>
+<?php wp_nonce_field('import-upload'); ?>
+<label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label> (<?php printf( __('Maximum size: %s' ), $size ); ?> )
+<input type="file" id="upload" name="import" size="25" />
 <input type="hidden" name="action" value="save" />
-<div id="buttons">
-<input type="submit" value="<?php _e('Import'); ?>" />
-<input type="button" value="<?php _e('Cancel'); ?>" onclick="cancelUpload()" />
-</div>
+<input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" />
+</p>
+<p class="submit">
+<input type="submit" value="<?php _e( 'Upload file and import' ); ?> &raquo;" />
+</p>
 </form>
-<?php	
+<?php
 }
 
 function wp_import_handle_upload() {
-	$overrides = array('test_form' => false, 'test_type' => false);
-	$file = wp_handle_upload($_FILES['import'], $overrides);
+	$overrides = array( 'test_form' => false, 'test_type' => false );
+	$file = wp_handle_upload( $_FILES['import'], $overrides );
 
-	if ( isset($file['error']) )
+	if ( isset( $file['error'] ) )
 		return $file;
 
 	$url = $file['url'];
-	$file = $file['file'];
-	$filename = basename($file);
+	$type = $file['type'];
+	$file = addslashes( $file['file'] );
+	$filename = basename( $file );
 
 	// Construct the object array
-	$object = array(
-		'post_title' => $filename,
+	$object = array( 'post_title' => $filename,
 		'post_content' => $url,
-		'post_mime_type' => 'import',
+		'post_mime_type' => $type,
 		'guid' => $url
 	);
 
 	// Save the data
-	$id = wp_insert_attachment($object, $file);
+	$id = wp_insert_attachment( $object, $file );
 
-	return array('file' => $file, 'id' => $id);
+	return array( 'file' => $file, 'id' => $id );
 }
 
-function user_can_richedit() {
-	if ( 'true' != get_user_option('rich_editing') )
-		return false;
-
-	if ( preg_match('!opera[ /][2-8]|konqueror|safari!i', $_SERVER['HTTP_USER_AGENT']) )
-		return false;
-
-	return true; // Best guess
-}
-
-function the_attachment_links($id = false) {
+function the_attachment_links( $id = false ) {
 	$id = (int) $id;
-	$post = & get_post($id);
+	$post = & get_post( $id );
 
-	if ( $post->post_status != 'attachment' )
+	if ( $post->post_type != 'attachment' )
 		return false;
 
-	$icon = get_attachment_icon($post->ID);
-
+	$icon = get_attachment_icon( $post->ID );
+	$attachment_data = wp_get_attachment_metadata( $id );
+	$thumb = isset( $attachment_data['thumb'] );
 ?>
-<p><?php _e('Text linked to file') ?><br />
-<textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo $post->guid ?>" class="attachmentlink"><?php echo basename($post->guid) ?></a></textarea></p>
-<p><?php _e('Text linked to subpost') ?><br />
-<textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link($post->ID) ?>" rel="attachment" id="<?php echo $post->ID ?>"><?php echo $post->post_title ?></a></textarea></p>
+<form id="the-attachment-links">
+<table>
+	<col />
+	<col class="widefat" />
+	<tr>
+		<th scope="row"><?php _e( 'URL' ) ?></th>
+		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><?php echo wp_get_attachment_url(); ?></textarea></td>
+	</tr>
 <?php if ( $icon ) : ?>
-<p><?php _e('Thumbnail linked to file') ?><br />
-<textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo $post->guid ?>" class="attachmentlink"><?php echo $icon ?></a></textarea></p>
-<p><?php _e('Thumbnail linked to subpost') ?><br />
-<textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link($post->ID) ?>" rel="attachment" id="<?php echo $post->ID ?>"><?php echo $icon ?></a></textarea></p>
+	<tr>
+		<th scope="row"><?php $thumb ? _e( 'Thumbnail linked to file' ) : _e( 'Image linked to file' ); ?></th>
+		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo wp_get_attachment_url(); ?>"><?php echo $icon ?></a></textarea></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php $thumb ? _e( 'Thumbnail linked to page' ) : _e( 'Image linked to page' ); ?></th>
+		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link( $post->ID ) ?>" rel="attachment wp-att-<?php echo $post->ID; ?>"><?php echo $icon ?></a></textarea></td>
+	</tr>
+<?php else : ?>
+	<tr>
+		<th scope="row"><?php _e( 'Link to file' ) ?></th>
+		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo wp_get_attachment_url(); ?>" class="attachmentlink"><?php echo basename( wp_get_attachment_url() );  ?></a></textarea></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e( 'Link to page' ) ?></th>
+		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php echo get_attachment_link( $post->ID ) ?>" rel="attachment wp-att-<?php echo $post->ID ?>"><?php the_title(); ?></a></textarea></td>
+	</tr>
 <?php endif; ?>
+</table>
+</form>
 <?php
 }
 
-function get_udims($width, $height) {
+function get_udims( $width, $height) {
 	if ( $height <= 96 && $width <= 128 )
-		return array($width, $height);
+		return array( $width, $height);
 	elseif ( $width / $height > 4 / 3 )
-		return array(128, (int) ($height / $width * 128));
+		return array( 128, (int) ($height / $width * 128 ));
 	else
-		return array((int) ($width / $height * 96), 96);
+		return array( (int) ($width / $height * 96 ), 96 );
+}
+
+function wp_reset_vars( $vars ) {
+	for ( $i=0; $i<count( $vars ); $i += 1 ) {
+		$var = $vars[$i];
+		global $$var;
+
+		if (!isset( $$var ) ) {
+			if ( empty( $_POST["$var"] ) ) {
+				if ( empty( $_GET["$var"] ) )
+					$$var = '';
+				else
+					$$var = $_GET["$var"];
+			} else {
+				$$var = $_POST["$var"];
+			}
+		}
+	}
+}
+
+
+function wp_remember_old_slug() {
+	global $post;
+	$name = attribute_escape($post->post_name); // just in case
+	if ( strlen($name) )
+		echo '<input type="hidden" id="wp-old-slug" name="wp-old-slug" value="' . $name . '" />';
+}
+
+
+// If siteurl or home changed, reset cookies and flush rewrite rules.
+function update_home_siteurl( $old_value, $value ) {
+	global $wp_rewrite, $user_login, $user_pass_md5;
+
+	if ( defined( "WP_INSTALLING" ) )
+		return;
+
+	// If home changed, write rewrite rules to new location.
+	$wp_rewrite->flush_rules();
+	// Clear cookies for old paths.
+	wp_clearcookie();
+	// Set cookies for new paths.
+	wp_setcookie( $user_login, $user_pass_md5, true, get_option( 'home' ), get_option( 'siteurl' ));
+}
+
+add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );
+add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 );
+
+function wp_crop_image( $src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) {
+	if ( ctype_digit( $src_file ) ) // Handle int as attachment ID
+		$src_file = get_attached_file( $src_file );
+
+	$src = wp_load_image( $src_file );
+
+	if ( !is_resource( $src ))
+		return $src;
+
+	$dst = imagecreatetruecolor( $dst_w, $dst_h );
+
+	if ( $src_abs ) {
+		$src_w -= $src_x;
+		$src_h -= $src_y;
+	}
+
+	if (function_exists('imageantialias'))
+		imageantialias( $dst, true );
+	
+	imagecopyresampled( $dst, $src, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );
+
+	if ( !$dst_file )
+		$dst_file = str_replace( basename( $src_file ), 'cropped-'.basename( $src_file ), $src_file );
+
+	$dst_file = preg_replace( '/\\.[^\\.]+$/', '.jpg', $dst_file );
+
+	if ( imagejpeg( $dst, $dst_file ) )
+		return $dst_file;
+	else
+		return false;
+}
+
+function wp_load_image( $file ) {
+	if ( ctype_digit( $file ) )
+		$file = get_attached_file( $file );
+
+	if ( !file_exists( $file ) )
+		return sprintf(__("File '%s' doesn't exist?"), $file);
+
+	if ( ! function_exists('imagecreatefromstring') )
+		return __('The GD image library is not installed.');
+
+	$contents = file_get_contents( $file );
+
+	$image = imagecreatefromstring( $contents );
+
+	if ( !is_resource( $image ) )
+		return sprintf(__("File '%s' is not an image."), $file);
+
+	return $image;
+}
+
+function wp_generate_attachment_metadata( $attachment_id, $file ) {
+	$attachment = get_post( $attachment_id );
+
+	$metadata = array();
+	if ( preg_match('!^image/!', get_post_mime_type( $attachment )) ) {
+		$imagesize = getimagesize($file);
+		$metadata['width'] = $imagesize['0'];
+		$metadata['height'] = $imagesize['1'];
+		list($uwidth, $uheight) = get_udims($metadata['width'], $metadata['height']);
+		$metadata['hwstring_small'] = "height='$uheight' width='$uwidth'";
+		$metadata['file'] = $file;
+
+		$max = apply_filters( 'wp_thumbnail_creation_size_limit', 3 * 1024 * 1024, $attachment_id, $file );
+
+		if ( $max < 0 || $metadata['width'] * $metadata['height'] < $max ) {
+			$max_side = apply_filters( 'wp_thumbnail_max_side_length', 128, $attachment_id, $file );
+			$thumb = wp_create_thumbnail( $file, $max_side );
+
+			if ( @file_exists($thumb) )
+				$metadata['thumb'] = basename($thumb);
+		}
+	}
+	return apply_filters( 'wp_generate_attachment_metadata', $metadata );
+}
+
+function wp_create_thumbnail( $file, $max_side, $effect = '' ) {
+
+		// 1 = GIF, 2 = JPEG, 3 = PNG
+
+	if ( file_exists( $file ) ) {
+		$type = getimagesize( $file );
+
+		// if the associated function doesn't exist - then it's not
+		// handle. duh. i hope.
+
+		if (!function_exists( 'imagegif' ) && $type[2] == 1 ) {
+			$error = __( 'Filetype not supported. Thumbnail not created.' );
+		}
+		elseif (!function_exists( 'imagejpeg' ) && $type[2] == 2 ) {
+			$error = __( 'Filetype not supported. Thumbnail not created.' );
+		}
+		elseif (!function_exists( 'imagepng' ) && $type[2] == 3 ) {
+			$error = __( 'Filetype not supported. Thumbnail not created.' );
+		} else {
+
+			// create the initial copy from the original file
+			if ( $type[2] == 1 ) {
+				$image = imagecreatefromgif( $file );
+			}
+			elseif ( $type[2] == 2 ) {
+				$image = imagecreatefromjpeg( $file );
+			}
+			elseif ( $type[2] == 3 ) {
+				$image = imagecreatefrompng( $file );
+			}
+
+			if ( function_exists( 'imageantialias' ))
+				imageantialias( $image, TRUE );
+
+			$image_attr = getimagesize( $file );
+
+			// figure out the longest side
+
+			if ( $image_attr[0] > $image_attr[1] ) {
+				$image_width = $image_attr[0];
+				$image_height = $image_attr[1];
+				$image_new_width = $max_side;
+
+				$image_ratio = $image_width / $image_new_width;
+				$image_new_height = $image_height / $image_ratio;
+				//width is > height
+			} else {
+				$image_width = $image_attr[0];
+				$image_height = $image_attr[1];
+				$image_new_height = $max_side;
+
+				$image_ratio = $image_height / $image_new_height;
+				$image_new_width = $image_width / $image_ratio;
+				//height > width
+			}
+
+			$thumbnail = imagecreatetruecolor( $image_new_width, $image_new_height);
+			@ imagecopyresampled( $thumbnail, $image, 0, 0, 0, 0, $image_new_width, $image_new_height, $image_attr[0], $image_attr[1] );
+
+			// If no filters change the filename, we'll do a default transformation.
+			if ( basename( $file ) == $thumb = apply_filters( 'thumbnail_filename', basename( $file ) ) )
+				$thumb = preg_replace( '!(\.[^.]+)?$!', '.thumbnail' . '$1', basename( $file ), 1 );
+
+			$thumbpath = str_replace( basename( $file ), $thumb, $file );
+
+			// move the thumbnail to its final destination
+			if ( $type[2] == 1 ) {
+				if (!imagegif( $thumbnail, $thumbpath ) ) {
+					$error = __( "Thumbnail path invalid" );
+				}
+			}
+			elseif ( $type[2] == 2 ) {
+				if (!imagejpeg( $thumbnail, $thumbpath ) ) {
+					$error = __( "Thumbnail path invalid" );
+				}
+			}
+			elseif ( $type[2] == 3 ) {
+				if (!imagepng( $thumbnail, $thumbpath ) ) {
+					$error = __( "Thumbnail path invalid" );
+				}
+			}
+
+		}
+	} else {
+		$error = __( 'File not found' );
+	}
+
+	if (!empty ( $error ) ) {
+		return $error;
+	} else {
+		return apply_filters( 'wp_create_thumbnail', $thumbpath );
+	}
 }
 
 ?>
diff -ruN 2.0.5/wp-admin/admin-header.php 2.2.2/wp-admin/admin-header.php
--- 2.0.5/wp-admin/admin-header.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/admin-header.php	2007-04-13 19:16:38.000000000 -0500
@@ -1,67 +1,52 @@
-<?php 
+<?php
 @header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
 if (!isset($_GET["page"])) require_once('admin.php');
 if ( $editing ) {
-	$dbx_js = true;
+	wp_enqueue_script( array('dbx-admin-key?pagenow=' . attribute_escape($pagenow),'admin-custom-fields') );
 	if ( current_user_can('manage_categories') )
-		$cat_js = true;
+		wp_enqueue_script( 'ajaxcat' );
+	if ( user_can_richedit() )
+		wp_enqueue_script( 'wp_tiny_mce' );
 }
-if ( $list_js || $cat_js )
-	$sack_js = true;
+
+get_admin_page_title();
+
 ?>
-<?php get_admin_page_title(); ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php do_action('admin_xml_ns'); ?> <?php language_attributes(); ?>>
 <head>
-<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
-<title><?php bloginfo('name') ?> &rsaquo; <?php echo $title; ?> &#8212; WordPress</title>
-<link rel="stylesheet" href="<?php echo get_settings('siteurl') ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
+<title><?php bloginfo('name') ?> &rsaquo; <?php echo wp_specialchars( strip_tags( $title ) ); ?> &#8212; WordPress</title>
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php endif; ?> 
 <script type="text/javascript">
 //<![CDATA[
 function addLoadEvent(func) {if ( typeof wpOnload!='function'){wpOnload=func;}else{ var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}}
 //]]>
 </script>
-<script type="text/javascript" src="../wp-includes/js/fat.js"></script>
-<?php if ( $xfn_js ) { ?>
-<script type="text/javascript" src="xfn.js"></script>
-<?php } ?>
-<?php if ( $sack_js ) { ?>
-<script type="text/javascript" src="../wp-includes/js/tw-sack.js"></script>
-<?php } ?>
-<?php if ( $list_js ) { ?>
-<script type="text/javascript" src="list-manipulation.js"></script>
-<?php } ?>
-<?php if ( $dbx_js ) { ?>
-<script type="text/javascript" src="../wp-includes/js/dbx.js"></script>
-<script type="text/javascript">
-//<![CDATA[
-addLoadEvent( function() {
-<?php switch ( $pagenow ) : case 'post.php' : ?>
-var manager = new dbxManager('postmeta');
-<?php break; case 'page-new.php' : ?>
-var manager = new dbxManager('pagemeta');
-<?php break; endswitch; ?>
-});
-//]]>
-</script>
-<script type="text/javascript" src="../wp-includes/js/dbx-key.js"></script>
-<?php } ?>
-<?php if ( $editing && user_can_richedit() ) { ?>
-<script type="text/javascript" src="../wp-includes/js/tinymce/tiny_mce_gzip.php?ver=20051211"></script>
-<?php } ?>
-<?php if ( $cat_js ) { ?>
-<script type="text/javascript" src="cat-js.php"></script>
-<?php } ?>
 <?php if ( ($parent_file != 'link-manager.php') && ($parent_file != 'options-general.php') ) : ?>
 <style type="text/css">* html { overflow-x: hidden; }</style>
-<?php endif; ?>
-<?php do_action('admin_head'); ?>
+<?php endif;
+if ( isset($page_hook) )
+	do_action('admin_print_scripts-' . $page_hook);
+else if ( isset($plugin_page) )
+	do_action('admin_print_scripts-' . $plugin_page);
+do_action('admin_print_scripts');
+
+if ( isset($page_hook) )
+	do_action('admin_head-' . $page_hook);
+else if ( isset($plugin_page) )
+	do_action('admin_head-' . $plugin_page);
+do_action('admin_head');
+?>
 </head>
 <body>
 <div id="wphead">
-<h1><?php echo wptexturize(get_settings(('blogname'))); ?> <span>(<a href="<?php echo get_settings('home') . '/'; ?>"><?php _e('View site') ?> &raquo;</a>)</span></h1>
+<h1><?php bloginfo('name'); ?> <span>(<a href="<?php echo get_option('home') . '/'; ?>"><?php _e('View site &raquo;') ?></a>)</span></h1>
 </div>
-<div id="user_info"><p><?php printf(__('Howdy, <strong>%s</strong>.'), $user_identity) ?> [<a href="<?php echo get_settings('siteurl'); ?>/wp-login.php?action=logout" title="<?php _e('Log out of this account') ?>"><?php _e('Sign Out'); ?></a>, <a href="profile.php"><?php _e('My Account'); ?></a>] </p></div>
+<div id="user_info"><p><?php printf(__('Howdy, <strong>%s</strong>.'), $user_identity) ?> [<a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="<?php _e('Log out of this account') ?>"><?php _e('Sign Out'); ?></a>, <a href="profile.php"><?php _e('My Profile'); ?></a>] </p></div>
 
 <?php
 require(ABSPATH . '/wp-admin/menu-header.php');
diff -ruN 2.0.5/wp-admin/admin.php 2.2.2/wp-admin/admin.php
--- 2.0.5/wp-admin/admin.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/admin.php	2007-02-15 02:16:43.000000000 -0600
@@ -4,12 +4,14 @@
 else
     require_once('../wp-config.php');
 
-if ( get_option('db_version') != $wp_db_version )
-	die (sprintf(__("Your database is out-of-date.  Please <a href='%s'>upgrade</a>."), get_option('siteurl') . '/wp-admin/upgrade.php'));
-    
+if ( get_option('db_version') != $wp_db_version ) {
+	wp_redirect(get_option('siteurl') . '/wp-admin/upgrade.php?_wp_http_referer=' . urlencode(stripslashes($_SERVER['REQUEST_URI'])));
+	exit;
+}
+
 require_once(ABSPATH . 'wp-admin/admin-functions.php');
 require_once(ABSPATH . 'wp-admin/admin-db.php');
-require_once(ABSPATH . WPINC . '/registration-functions.php');
+require_once(ABSPATH . WPINC . '/registration.php');
 
 auth_redirect();
 
@@ -19,28 +21,16 @@
 
 wp_get_current_user();
 
-$posts_per_page = get_settings('posts_per_page');
-$what_to_show = get_settings('what_to_show');
-$date_format = get_settings('date_format');
-$time_format = get_settings('time_format');
-
-$wpvarstoreset = array('profile','redirect','redirect_url','a','popuptitle','popupurl','text', 'trackback', 'pingback');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-    $wpvar = $wpvarstoreset[$i];
-    if (!isset($$wpvar)) {
-        if (empty($_POST["$wpvar"])) {
-            if (empty($_GET["$wpvar"])) {
-                $$wpvar = '';
-            } else {
-                $$wpvar = $_GET["$wpvar"];
-            }
-        } else {
-            $$wpvar = $_POST["$wpvar"];
-        }
-    }
-}
+$posts_per_page = get_option('posts_per_page');
+$what_to_show = get_option('what_to_show');
+$date_format = get_option('date_format');
+$time_format = get_option('time_format');
+
+wp_reset_vars(array('profile', 'redirect', 'redirect_url', 'a', 'popuptitle', 'popupurl', 'text', 'trackback', 'pingback'));
 
-$xfn_js = $sack_js = $list_js = $cat_js = $dbx_js = $editing = false;
+wp_enqueue_script( 'fat' );
+
+$editing = false;
 
 if (isset($_GET['page'])) {
 	$plugin_page = stripslashes($_GET['page']);
@@ -54,59 +44,64 @@
 	$page_hook = get_plugin_page_hook($plugin_page, $pagenow);
 
 	if ( $page_hook ) {
+		do_action('load-' . $page_hook);
 		if (! isset($_GET['noheader']))
 			require_once(ABSPATH . '/wp-admin/admin-header.php');
-		
+
 		do_action($page_hook);
 	} else {
 		if ( validate_file($plugin_page) ) {
-			die(__('Invalid plugin page'));
+			wp_die(__('Invalid plugin page'));
 		}
-		
-		if (! file_exists(ABSPATH . "wp-content/plugins/$plugin_page"))
-			die(sprintf(__('Cannot load %s.'), htmlentities($plugin_page)));
+
+		if (! file_exists(ABSPATH . PLUGINDIR . "/$plugin_page"))
+			wp_die(sprintf(__('Cannot load %s.'), htmlentities($plugin_page)));
+
+		do_action('load-' . $plugin_page);
 
 		if (! isset($_GET['noheader']))
 			require_once(ABSPATH . '/wp-admin/admin-header.php');
-		
-		include(ABSPATH . "wp-content/plugins/$plugin_page");
+
+		include(ABSPATH . PLUGINDIR . "/$plugin_page");
 	}
-	
+
 	include(ABSPATH . 'wp-admin/admin-footer.php');
 
 	exit();
 } else if (isset($_GET['import'])) {
-	
+
 	$importer = $_GET['import'];
 
 	if ( ! current_user_can('import') )
 		wp_die(__('You are not allowed to import.'));
 
 	if ( validate_file($importer) ) {
-		die(__('Invalid importer.'));
+		wp_die(__('Invalid importer.'));
 	}
-		
+
 	if (! file_exists(ABSPATH . "wp-admin/import/$importer.php"))
-		die(__('Cannot load importer.'));
-	
+		wp_die(__('Cannot load importer.'));
+
 	include(ABSPATH . "wp-admin/import/$importer.php");
 
-	$parent_file = 'import.php';
+	$parent_file = 'edit.php';
+	$submenu_file = 'import.php';
 	$title = __('Import');
-	
+
 	if (! isset($_GET['noheader']))
 		require_once(ABSPATH . 'wp-admin/admin-header.php');
 
 	require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
 
 	define('WP_IMPORTING', true);
-	kses_init_filters();  // Always filter imported data with kses.
 
 	call_user_func($wp_importers[$importer][2]);
-			
+
 	include(ABSPATH . 'wp-admin/admin-footer.php');
 
 	exit();
+} else {
+	do_action("load-$pagenow");
 }
 
 ?>
diff -ruN 2.0.5/wp-admin/bookmarklet.php 2.2.2/wp-admin/bookmarklet.php
--- 2.0.5/wp-admin/bookmarklet.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/bookmarklet.php	2007-03-17 03:46:59.000000000 -0500
@@ -3,7 +3,7 @@
 require_once('admin.php');
 
 if ( ! current_user_can('edit_posts') )
-	die ("Cheatin' uh?");
+	wp_die(__('Cheatin&#8217; uh?'));
 
 if ('b' == $a):
 ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -25,32 +25,32 @@
 
 $popuptitle = wp_specialchars(stripslashes($popuptitle));
 $text       = wp_specialchars(stripslashes(urldecode($text)));
-	
+
 $popuptitle = funky_javascript_fix($popuptitle);
 $text       = funky_javascript_fix($text);
-	
+
 $post_title = wp_specialchars($_REQUEST['post_title']);
 if (!empty($post_title))
 	$post->post_title =  stripslashes($post_title);
 else
 	$post->post_title = $popuptitle;
-	
-  
+
+
 $content  = wp_specialchars($_REQUEST['content']);
-$popupurl = wp_specialchars($_REQUEST['popupurl']);
-    if ( !empty($content) ) {
-        $post->post_content = wp_specialchars( stripslashes($_REQUEST['content']) );
-    } else {
-        $post->post_content = '<a href="'.$popupurl.'">'.$popuptitle.'</a>'."\n$text";
-    }
+$popupurl = clean_url($_REQUEST['popupurl']);
+if ( !empty($content) ) {
+	$post->post_content = wp_specialchars( stripslashes($_REQUEST['content']) );
+} else {
+	$post->post_content = '<a href="'.$popupurl.'">'.$popuptitle.'</a>'."\n$text";
+}
 
-    /* /big funky fixes */
+/* /big funky fixes */
 
 ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title><?php bloginfo('name') ?> &rsaquo; Bookmarklet &#8212; WordPress</title>
-<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
+<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
 <link rel="stylesheet" href="wp-admin.css" type="text/css" />
 
 <style type="text/css">
@@ -77,15 +77,15 @@
 }
 
 #wpbookmarklet .wrap {
-    border: 0px;
+	border: 0px;
 }
 
 #wpbookmarklet #postdiv {
-    margin-bottom: 0.5em;
+	margin-bottom: 0.5em;
 }
 
 #wpbookmarklet #titlediv {
-    margin-bottom: 1em;
+	margin-bottom: 1em;
 }
 
 -->
diff -ruN 2.0.5/wp-admin/cat-js.php 2.2.2/wp-admin/cat-js.php
--- 2.0.5/wp-admin/cat-js.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/cat-js.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,178 +0,0 @@
-<?php
-require_once('admin.php');
-header('Content-type: text/javascript; charset=' . get_settings('blog_charset'), true);
-?>
-var ajaxCat = new sack();
-var newcat;
- 
-function newCatAddIn() {
-	if ( !document.getElementById('jaxcat') ) return false;
-	var ajaxcat = document.createElement('span');
-	ajaxcat.id = 'ajaxcat';
-
-	newcat = document.createElement('input');
-	newcat.type = 'text';
-	newcat.name = 'newcat';
-	newcat.id = 'newcat';
-	newcat.size = '16';
-	newcat.setAttribute('autocomplete', 'off');
-	newcat.onkeypress = ajaxNewCatKeyPress;
-
-	var newcatSub = document.createElement('input');
-	newcatSub.type = 'button';
-	newcatSub.name = 'Button';
-	newcatSub.id = 'catadd';
-	newcatSub.value = '<?php echo addslashes(__('Add')); ?>';
-	newcatSub.onclick = ajaxNewCat;
-
-	ajaxcat.appendChild(newcat);
-	ajaxcat.appendChild(newcatSub);
-	document.getElementById('jaxcat').appendChild(ajaxcat);
-
-	howto = document.createElement('span');
-	howto.innerHTML = '<?php echo addslashes(__('Separate multiple categories with commas.')); ?>';
-	howto.id = 'howto';
-	ajaxcat.appendChild(howto);
-}
-
-addLoadEvent(newCatAddIn);
-
-function getResponseElement() {
-	var p = document.getElementById('ajaxcatresponse');
-	if (!p) {
-		p = document.createElement('span');
-		document.getElementById('jaxcat').appendChild(p);
-		p.id = 'ajaxcatresponse';
-	}
-	return p;
-}
-
-function newCatLoading() {
-	var p = getResponseElement();
-	p.innerHTML = '<?php echo addslashes(__('Sending Data...')); ?>';
-}
-
-function newCatLoaded() {
-	var p = getResponseElement();
-	p.innerHTML = '<?php echo addslashes(__('Data Sent...')); ?>';
-}
-
-function newCatInteractive() {
-	var p = getResponseElement();
-	p.innerHTML = '<?php echo addslashes(__('Processing Request...')); ?>';
-}
-
-function newCatCompletion() {
-	var p = getResponseElement();
-	var id    = 0;
-	var ids   = new Array();
-	var names = new Array();
-	
-	ids   = myPload( ajaxCat.response );
-	names = myPload( newcat.value );
-	for ( i = 0; i < ids.length; i++ ) {
-		id = ids[i].replace(/[\n\r]+/g, "");
-		if ( id == '-1' ) {
-			p.innerHTML = "<?php echo addslashes(__("You don't have permission to do that.")); ?>";
-			return;
-		}
-		if ( id == '0' ) {
-			p.innerHTML = "<?php echo addslashes(__('That category name is invalid.  Try something else.')); ?>";
-			return;
-		}
-		
-		var exists = document.getElementById('category-' + id);
-		
-		if (exists) {
-			var moveIt = exists.parentNode;
-			var container = moveIt.parentNode;
-			container.removeChild(moveIt);
-			container.insertBefore(moveIt, container.firstChild);
-			moveIt.id = 'new-category-' + id;
-			exists.checked = 'checked';
-			var nowClass = moveIt.className;
-			moveIt.className = nowClass + ' fade';
-			Fat.fade_all();
-			moveIt.className = nowClass;
-		} else {
-			var catDiv = document.getElementById('categorychecklist');
-			var newLabel = document.createElement('label');
-			newLabel.setAttribute('for', 'category-' + id);
-			newLabel.id = 'new-category-' + id;
-			newLabel.className = 'selectit fade';
-	
-			var newCheck = document.createElement('input');
-			newCheck.type = 'checkbox';
-			newCheck.value = id;
-			newCheck.name = 'post_category[]';
-			newCheck.id = 'category-' + id;
-			newLabel.appendChild(newCheck);
-	
-			var newLabelText = document.createTextNode(' ' + names[i]);
-			newLabel.appendChild(newLabelText);
-	
-			catDiv.insertBefore(newLabel, catDiv.firstChild);
-			newCheck.checked = 'checked';
-	
-			Fat.fade_all();
-			newLabel.className = 'selectit';
-		}
-		newcat.value = '';
-	}
-	p.parentNode.removeChild(p);
-//	var id = parseInt(ajaxCat.response, 10);
-}
-
-function ajaxNewCatKeyPress(e) {
-	if (!e) {
-		if (window.event) {
-			e = window.event;
-		} else {
-			return;
-		}
-	}
-	if (e.keyCode == 13) {
-		ajaxNewCat();
-		e.returnValue = false;
-		e.cancelBubble = true;
-		return false;
-	}
-}
-
-function ajaxNewCat() {
-	var newcat = document.getElementById('newcat');
-	var split_cats = new Array(1);
-	var catString = '';
-
-	catString = ajaxCat.encVar('ajaxnewcat', newcat.value) + '&' + ajaxCat.encVar('cookie', document.cookie);
-	ajaxCat.requestFile = 'edit-form-ajax-cat.php';
-	ajaxCat.method = 'POST';
-	ajaxCat.onLoading = newCatLoading;
-	ajaxCat.onLoaded = newCatLoaded;
-	ajaxCat.onInteractive = newCatInteractive;
-	ajaxCat.onCompletion = newCatCompletion;
-	ajaxCat.runAJAX(catString);
-}
-
-function myPload( str ) {
-	var fixedExplode = new Array();
-	var comma = new String(',');
-	var count = 0;
-	var currentElement = '';
-
-	for( x=0; x < str.length; x++) {
-		andy = str.charAt(x);
-		if ( comma.indexOf(andy) != -1 ) {
-			currentElement = currentElement.replace(new RegExp('^\\s*(.*?)\\s*$', ''), '$1'); // trim
-			fixedExplode[count] = currentElement;
-			currentElement = "";
-			count++;
-		} else {
-			currentElement += andy;
-		}
-	}
-
-	if ( currentElement != "" )
-		fixedExplode[count] = currentElement;
-	return fixedExplode;
-}
diff -ruN 2.0.5/wp-admin/cat.js 2.2.2/wp-admin/cat.js
--- 2.0.5/wp-admin/cat.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/cat.js	2007-04-17 15:56:41.000000000 -0500
@@ -0,0 +1,10 @@
+addLoadEvent(function(){catList=new listMan('categorychecklist');catList.ajaxRespEl='jaxcat';catList.topAdder=1;catList.alt=0;catList.showLink=0;});
+addLoadEvent(newCatAddIn);
+function newCatAddIn() {
+	var jaxcat = $('jaxcat');
+	if ( !jaxcat )
+		return false;
+	Element.update(jaxcat,'<span id="ajaxcat"><input type="text" name="newcat" id="newcat" size="16" autocomplete="off"/><input type="button" name="Button" id="catadd" value="' + catL10n.add + '"/><input type="hidden"/><span id="howto">' + catL10n.how + '</span></span>');
+	$('newcat').onkeypress = function(e) { return killSubmit("catList.ajaxAdder('category','jaxcat');", e); };
+	$('catadd').onclick = function() { catList.ajaxAdder('category', 'jaxcat'); };
+}
diff -ruN 2.0.5/wp-admin/categories.js 2.2.2/wp-admin/categories.js
--- 2.0.5/wp-admin/categories.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/categories.js	2007-03-27 18:51:26.000000000 -0500
@@ -0,0 +1,16 @@
+addLoadEvent(function() {
+	if (!theList.theList) return false;
+	document.forms.addcat.submit.onclick = function(e) {return killSubmit('theList.ajaxAdder("cat", "addcat");', e); };
+	theList.addComplete = function(what, where, update, transport) {
+		var name = getNodeValue(transport.responseXML, 'name').unescapeHTML();
+		var id = transport.responseXML.getElementsByTagName(what)[0].getAttribute('id');
+		var options = document.forms['addcat'].category_parent.options;
+		options[options.length] = new Option(name, id);
+	};
+	theList.delComplete = function(what, id) {
+		var options = document.forms['addcat'].category_parent.options;
+		for ( var o = 0; o < options.length; o++ )
+			if ( id == options[o].value )
+				options[o] = null;
+	};
+});
diff -ruN 2.0.5/wp-admin/categories.php 2.2.2/wp-admin/categories.php
--- 2.0.5/wp-admin/categories.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/categories.php	2007-04-19 17:26:52.000000000 -0500
@@ -3,23 +3,8 @@
 
 $title = __('Categories');
 $parent_file = 'edit.php';
-$list_js = true;
 
-$wpvarstoreset = array('action','cat');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-    $wpvar = $wpvarstoreset[$i];
-    if (!isset($$wpvar)) {
-        if (empty($_POST["$wpvar"])) {
-            if (empty($_GET["$wpvar"])) {
-                $$wpvar = '';
-            } else {
-                $$wpvar = $_GET["$wpvar"];
-            }
-        } else {
-            $$wpvar = $_POST["$wpvar"];
-        }
-    }
-}
+wp_reset_vars(array('action', 'cat'));
 
 switch($action) {
 
@@ -28,11 +13,14 @@
 	check_admin_referer('add-category');
 
 	if ( !current_user_can('manage_categories') )
-		die (__('Cheatin&#8217; uh?'));
-	
-	wp_insert_category($_POST);
+		wp_die(__('Cheatin&#8217; uh?'));
 
-	wp_redirect('categories.php?message=1#addcat');
+	if( wp_insert_category($_POST ) ) {
+		wp_redirect('categories.php?message=1#addcat');
+	} else {
+		wp_redirect('categories.php?message=4#addcat');
+	}
+	exit;
 break;
 
 case 'delete':
@@ -40,59 +28,30 @@
 	check_admin_referer('delete-category_' .  $cat_ID);
 
 	if ( !current_user_can('manage_categories') )
-		die (__('Cheatin&#8217; uh?'));
+		wp_die(__('Cheatin&#8217; uh?'));
 
 	$cat_name = get_catname($cat_ID);
 
 	// Don't delete the default cats.
-	if ( $cat_ID == get_option('default_category') )
-		die(sprintf(__("Can't delete the <strong>%s</strong> category: this is the default one"), $cat_name));
+    if ( $cat_ID == get_option('default_category') )
+		wp_die(sprintf(__("Can&#8217;t delete the <strong>%s</strong> category: this is the default one"), $cat_name));
+
+    if ( $cat_ID == get_option('default_link_category') )
+		wp_die(sprintf(__("Can&#8217;t delete the <strong>%s</strong> category: this is the default one for links"), $cat_name));
 
 	wp_delete_category($cat_ID);
 
 	wp_redirect('categories.php?message=2');
+	exit;
 
 break;
 
 case 'edit':
 
-    require_once ('admin-header.php');
-    $cat_ID = (int) $_GET['cat_ID'];
-    $category = get_category_to_edit($cat_ID);
-    ?>
-
-<div class="wrap">
- <h2><?php _e('Edit Category') ?></h2>
- <form name="editcat" action="categories.php" method="post">
-	  <?php wp_nonce_field('update-category_' .  $category->cat_ID); ?>
-	  <table class="editform" width="100%" cellspacing="2" cellpadding="5">
-		<tr>
-		  <th width="33%" scope="row"><?php _e('Category name:') ?></th>
-		  <td width="67%"><input name="cat_name" type="text" value="<?php echo wp_specialchars($category->cat_name); ?>" size="40" /> <input type="hidden" name="action" value="editedcat" />
-<input type="hidden" name="cat_ID" value="<?php echo $category->cat_ID ?>" /></td>
-		</tr>
-		<tr>
-			<th scope="row"><?php _e('Category slug:') ?></th>
-			<td><input name="category_nicename" type="text" value="<?php echo wp_specialchars($category->category_nicename); ?>" size="40" /></td>
-		</tr>
-		<tr>
-			<th scope="row"><?php _e('Category parent:') ?></th>
-			<td>        
-			<select name='category_parent'>
-	  <option value='0' <?php if (!$category->category_parent) echo " selected='selected'"; ?>><?php _e('None') ?></option>
-	  <?php wp_dropdown_cats($category->cat_ID, $category->category_parent); ?>
-	  </select></td>
-		</tr>
-		<tr>
-			<th scope="row"><?php _e('Description:') ?></th>
-			<td><textarea name="category_description" rows="5" cols="50" style="width: 97%;"><?php echo wp_specialchars($category->category_description, 1); ?></textarea></td>
-		</tr>
-		</table>
-	  <p class="submit"><input type="submit" name="submit" value="<?php _e('Edit category') ?> &raquo;" /></p>
- </form>
- <p><a href="categories.php"><?php _e('&laquo; Return to category list'); ?></a></p>
-</div>
-    <?php
+	require_once ('admin-header.php');
+	$cat_ID = (int) $_GET['cat_ID'];
+	$category = get_category_to_edit($cat_ID);
+	include('edit-category-form.php');
 
 break;
 
@@ -101,20 +60,26 @@
 	check_admin_referer('update-category_' . $cat_ID);
 
 	if ( !current_user_can('manage_categories') )
-		die (__('Cheatin&#8217; uh?'));
-	
-	wp_update_category($_POST);
+		wp_die(__('Cheatin&#8217; uh?'));
 
-	wp_redirect('categories.php?message=3');
+	if ( wp_update_category($_POST) )
+		wp_redirect('categories.php?message=3'); 
+	else
+		wp_redirect('categories.php?message=5'); 
+
+	exit;
 break;
 
 default:
 
+wp_enqueue_script( 'admin-categories' );
 require_once ('admin-header.php');
 
 $messages[1] = __('Category added.');
 $messages[2] = __('Category deleted.');
 $messages[3] = __('Category updated.');
+$messages[4] = __('Category not added.');
+$messages[5] = __('Category not updated.');
 ?>
 
 <?php if (isset($_GET['message'])) : ?>
@@ -127,44 +92,32 @@
 <?php else : ?>
 	<h2><?php _e('Categories') ?> </h2>
 <?php endif; ?>
-<table id="the-list-x" width="100%" cellpadding="3" cellspacing="3">
+<table class="widefat">
+	<thead>
 	<tr>
-		<th scope="col"><?php _e('ID') ?></th>
+		<th scope="col" style="text-align: center"><?php _e('ID') ?></th>
         <th scope="col"><?php _e('Name') ?></th>
         <th scope="col"><?php _e('Description') ?></th>
-        <th scope="col"><?php _e('# Posts') ?></th>
-        <th colspan="2"><?php _e('Action') ?></th>
+        <th scope="col" width="90" style="text-align: center"><?php _e('Posts') ?></th>
+        <th scope="col" width="90" style="text-align: center"><?php _e('Links') ?></th>
+        <th colspan="2" style="text-align: center"><?php _e('Action') ?></th>
 	</tr>
+	</thead>
+	<tbody id="the-list">
 <?php
 cat_rows();
 ?>
+	</tbody>
 </table>
 
-<div id="ajax-response"></div>
-
 </div>
 
 <?php if ( current_user_can('manage_categories') ) : ?>
 <div class="wrap">
-<p><?php printf(__('<strong>Note:</strong><br />Deleting a category does not delete posts from that category, it will just set them back to the default category <strong>%s</strong>.'), get_catname(get_option('default_category'))) ?></p>
+<p><?php printf(__('<strong>Note:</strong><br />Deleting a category does not delete the posts and links in that category. Instead, posts that were only assigned to the deleted category are set to the category <strong>%s</strong> and links that were only assigned to the deleted category are set to <strong>%s</strong>.'), apply_filters('the_category', get_catname(get_option('default_category'))), apply_filters('the_category', get_catname(get_option('default_link_category')))) ?></p>
 </div>
 
-<div class="wrap">
-    <h2><?php _e('Add New Category') ?></h2>
-    <form name="addcat" id="addcat" action="categories.php" method="post">
-    <?php wp_nonce_field('add-category'); ?>
-        <p><?php _e('Name:') ?><br />
-        <input type="text" name="cat_name" value="" /></p>
-        <p><?php _e('Category parent:') ?><br />
-        <select name='category_parent' class='postform'>
-        <option value='0'><?php _e('None') ?></option>
-        <?php wp_dropdown_cats(0); ?>
-        </select></p>
-        <p><?php _e('Description: (optional)') ?> <br />
-        <textarea name="category_description" rows="5" cols="50" style="width: 97%;"></textarea></p>
-        <p class="submit"><input type="hidden" name="action" value="addcat" /><input type="submit" name="submit" value="<?php _e('Add Category &raquo;') ?>" /></p>
-    </form>
-</div>
+<?php include('edit-category-form.php'); ?>
 <?php endif; ?>
 
 <?php
@@ -172,4 +125,5 @@
 }
 
 include('admin-footer.php');
+
 ?>
diff -ruN 2.0.5/wp-admin/comment.php 2.2.2/wp-admin/comment.php
--- 2.0.5/wp-admin/comment.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/comment.php	2007-05-28 23:37:35.000000000 -0500
@@ -0,0 +1,213 @@
+<?php
+require_once('admin.php');
+
+$parent_file = 'edit-comments.php';
+$submenu_file = 'edit-comments.php';
+
+wp_reset_vars(array('action'));
+
+if ( isset( $_POST['deletecomment'] ) )
+	$action = 'deletecomment';
+
+switch($action) {
+case 'editcomment':
+	$title = __('Edit Comment');
+
+	require_once ('admin-header.php');
+
+	$comment = (int) $_GET['c'];
+
+	if ( ! $comment = get_comment($comment) )
+		wp_die(__('Oops, no comment with this ID.').sprintf(' <a href="%s">'.__('Go back').'</a>!', 'javascript:history.go(-1)'));
+
+	if ( !current_user_can('edit_post', $comment->comment_post_ID) )
+		wp_die( __('You are not allowed to edit comments on this post.') );
+
+	$comment = get_comment_to_edit($comment);
+
+	include('edit-form-comment.php');
+
+	break;
+
+case 'cdc':
+case 'mac':
+
+	require_once('./admin-header.php');
+
+	$comment = (int) $_GET['c'];
+	$formaction = 'cdc' == $action ? 'deletecomment' : 'approvecomment';
+	$nonce_action = 'cdc' == $action ? 'delete-comment_' : 'approve-comment_';
+	$nonce_action .= $comment;
+
+	if ( ! $comment = get_comment_to_edit($comment) )
+		wp_die(__('Oops, no comment with this ID.').sprintf(' <a href="%s">'.__('Go back').'</a>!', 'edit.php'));
+
+	if ( !current_user_can('edit_post', $comment->comment_post_ID) )
+		wp_die( 'cdc' == $action ? __('You are not allowed to delete comments on this post.') : __('You are not allowed to edit comments on this post, so you cannot approve this comment.') );
+?>
+<div class='wrap'>
+
+<div class="narrow">
+<?php if ( 'spam' == $_GET['dt'] ) { ?>
+<p><?php echo '<strong>'.__('Caution:').'</strong> '.__('You are about to mark the following comment as spam:'); ?></p>
+<?php } elseif ( 'cdc' == $action ) { ?>
+<p><?php echo '<strong>'.__('Caution:').'</strong> '.__('You are about to delete the following comment:'); ?></p>
+<?php } else { ?>
+<p><?php echo '<strong>'.__('Caution:').'</strong> '.__('You are about to approve the following comment:'); ?></p>
+<?php } ?>
+
+<p><?php _e('Are you sure you want to do that?'); ?></p>
+
+<form action='<?php echo get_option('siteurl'); ?>/wp-admin/comment.php' method='get'>
+
+<table width="100%">
+<tr>
+<td><input type='button' value='<?php _e('No'); ?>' onclick="self.location='<?php echo get_option('siteurl'); ?>/wp-admin/edit-comments.php';" /></td>
+<td align="right"><input type='submit' value='<?php _e('Yes'); ?>' /></td>
+</tr>
+</table>
+
+<?php wp_nonce_field($nonce_action); ?>
+<input type='hidden' name='action' value='<?php echo $formaction; ?>' />
+<?php if ( 'spam' == $_GET['dt'] ) { ?>
+<input type='hidden' name='dt' value='spam' />
+<?php } ?>
+<input type='hidden' name='p' value='<?php echo $comment->comment_post_ID; ?>' />
+<input type='hidden' name='c' value='<?php echo $comment->comment_ID; ?>' />
+<input type='hidden' name='noredir' value='1' />
+</form>
+
+<table class="editform" cellpadding="5">
+<tr class="alt">
+<th scope="row"><?php _e('Author:'); ?></th>
+<td><?php echo $comment->comment_author; ?></td>
+</tr>
+<?php if ( $comment->comment_author_email ) { ?>
+<tr>
+<th scope="row"><?php _e('E-mail:'); ?></th>
+<td><?php echo $comment->comment_author_email; ?></td>
+</tr>
+<?php } ?>
+<?php if ( $comment->comment_author_url ) { ?>
+<tr>
+<th scope="row"><?php _e('URL:'); ?></th>
+<td><?php echo $comment->comment_author_url; ?></td>
+</tr>
+<?php } ?>
+<tr>
+<th scope="row" valign="top"><p><?php _e('Comment:'); ?></p></th>
+<td><?php echo $comment->comment_content; ?></td>
+</tr>
+</table>
+
+</div>
+</div>
+<?php
+	break;
+
+case 'deletecomment':
+	$comment = (int) $_REQUEST['c'];
+	check_admin_referer('delete-comment_' . $comment);
+
+	if ( isset($_REQUEST['noredir']) ) {
+		$noredir = true;
+	} else {
+		$noredir = false;
+	}
+
+	if ( ! $comment = get_comment($comment) )
+			 wp_die(__('Oops, no comment with this ID.').sprintf(' <a href="%s">'.__('Go back').'</a>!', 'edit-comments.php'));
+
+	if ( !current_user_can('edit_post', $comment->comment_post_ID) )
+		wp_die( __('You are not allowed to edit comments on this post.') );
+
+	if ( 'spam' == $_REQUEST['dt'] )
+		wp_set_comment_status($comment->comment_ID, 'spam');
+	else
+		wp_delete_comment($comment->comment_ID);
+
+	if ((wp_get_referer() != '') && (false == $noredir)) {
+		wp_redirect(wp_get_referer());
+	} else {
+		wp_redirect(get_option('siteurl') .'/wp-admin/edit-comments.php');
+	}
+	exit();
+	break;
+
+case 'unapprovecomment':
+	$comment = (int) $_GET['c'];
+	check_admin_referer('unapprove-comment_' . $comment);
+
+	if (isset($_GET['noredir'])) {
+		$noredir = true;
+	} else {
+		$noredir = false;
+	}
+
+	if ( ! $comment = get_comment($comment) )
+		wp_die(__('Oops, no comment with this ID.').sprintf(' <a href="%s">'.__('Go back').'</a>!', 'edit.php'));
+
+	if ( !current_user_can('edit_post', $comment->comment_post_ID) )
+		wp_die( __('You are not allowed to edit comments on this post, so you cannot disapprove this comment.') );
+
+	wp_set_comment_status($comment->comment_ID, "hold");
+
+	if ((wp_get_referer() != "") && (false == $noredir)) {
+		wp_redirect(wp_get_referer());
+	} else {
+		wp_redirect(get_option('siteurl') .'/wp-admin/edit.php?p='. (int) $comment->comment_post_ID.'&c=1#comments');
+	}
+	exit();
+	break;
+
+case 'approvecomment':
+	$comment = (int) $_GET['c'];
+	check_admin_referer('approve-comment_' . $comment);
+
+	if (isset($_GET['noredir'])) {
+		$noredir = true;
+	} else {
+		$noredir = false;
+	}
+
+	if ( ! $comment = get_comment($comment) )
+		wp_die(__('Oops, no comment with this ID.').sprintf(' <a href="%s">'.__('Go back').'</a>!', 'edit.php'));
+
+	if ( !current_user_can('edit_post', $comment->comment_post_ID) )
+		wp_die( __('You are not allowed to edit comments on this post, so you cannot approve this comment.') );
+
+	wp_set_comment_status($comment->comment_ID, "approve");
+	if (get_option("comments_notify") == true) {
+		wp_notify_postauthor($comment->comment_ID);
+	}
+
+
+	if ((wp_get_referer() != "") && (false == $noredir)) {
+		wp_redirect(wp_get_referer());
+	} else {
+		wp_redirect(get_option('siteurl') .'/wp-admin/edit.php?p='. (int) $comment->comment_post_ID.'&c=1#comments');
+	}
+	exit();
+	break;
+
+case 'editedcomment':
+
+	$comment_ID = (int) $_POST['comment_ID'];
+	$comment_post_ID = (int) $_POST['comment_post_id'];
+
+	check_admin_referer('update-comment_' . $comment_ID);
+
+	edit_comment();
+
+	$location = ( empty($_POST['referredby']) ? "edit.php?p=$comment_post_ID&c=1" : $_POST['referredby'] ) . '#comment-' . $comment_ID;
+	$location = apply_filters('comment_edit_redirect', $location, $comment_ID);
+	wp_redirect($location);
+	exit();
+	break;
+default:
+	break;
+} // end switch
+
+include('admin-footer.php');
+
+?>
diff -ruN 2.0.5/wp-admin/custom-fields.js 2.2.2/wp-admin/custom-fields.js
--- 2.0.5/wp-admin/custom-fields.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/custom-fields.js	2006-11-19 01:56:05.000000000 -0600
@@ -0,0 +1,26 @@
+function customFieldsOnComplete( what, where, update, transport ) {
+	var pidEl = $('post_ID');
+	pidEl.name = 'post_ID';
+	pidEl.value = getNodeValue(transport.responseXML, 'postid');
+	var aEl = $('hiddenaction')
+	if ( aEl.value == 'post' ) aEl.value = 'postajaxpost';
+}
+addLoadEvent(customFieldsAddIn);
+function customFieldsAddIn() {
+	theList.showLink=0;
+	theList.addComplete = customFieldsOnComplete;
+	if (!theList.theList) return false;
+	inputs = theList.theList.getElementsByTagName('input');
+	for ( var i=0; i < inputs.length; i++ ) {
+		if ('text' == inputs[i].type) {
+			inputs[i].setAttribute('autocomplete', 'off');
+			inputs[i].onkeypress = function(e) {return killSubmit('theList.ajaxUpdater("meta", "meta-' + parseInt(this.name.slice(5),10) + '");', e); };
+		}
+		if ('updatemeta' == inputs[i].className) {
+			inputs[i].onclick = function(e) {return killSubmit('theList.ajaxUpdater("meta", "meta-' + parseInt(this.parentNode.parentNode.id.slice(5),10) + '");', e); };
+		}
+	}
+
+	$('metakeyinput').onkeypress = function(e) {return killSubmit('theList.inputData+="&id="+$("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
+	$('updatemetasub').onclick = function(e) {return killSubmit('theList.inputData+="&id="+$("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
+}
diff -ruN 2.0.5/wp-admin/custom-header.php 2.2.2/wp-admin/custom-header.php
--- 2.0.5/wp-admin/custom-header.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/custom-header.php	2007-05-15 11:47:07.000000000 -0500
@@ -0,0 +1,332 @@
+<?php
+
+class Custom_Image_Header {
+	var $admin_header_callback;
+
+	function Custom_Image_Header($admin_header_callback) {
+		$this->admin_header_callback = $admin_header_callback;
+	}
+
+	function init() {
+		$page = add_theme_page(__('Custom Image Header'), __('Custom Image Header'), 'edit_themes', 'custom-header', array(&$this, 'admin_page'));
+
+		add_action("admin_print_scripts-$page", array(&$this, 'js_includes'));
+		add_action("admin_head-$page", array(&$this, 'js'), 50);
+		add_action("admin_head-$page", $this->admin_header_callback, 51);
+	}
+
+	function js_includes() {
+		wp_enqueue_script('cropper');
+		wp_enqueue_script('colorpicker');
+	}
+
+	function js() {
+
+		if ( isset( $_POST['textcolor'] ) ) {
+			check_admin_referer('custom-header');
+			if ( 'blank' == $_POST['textcolor'] ) {
+				set_theme_mod('header_textcolor', 'blank');
+			} else {
+				$color = preg_replace('/[^0-9a-fA-F]/', '', $_POST['textcolor']);
+				if ( strlen($color) == 6 || strlen($color) == 3 )
+					set_theme_mod('header_textcolor', $color);
+			}
+		}
+		if ( isset($_POST['resetheader']) ) {
+			check_admin_referer('custom-header');
+			remove_theme_mods();
+		}
+	?>
+<script type="text/javascript">
+
+	function onEndCrop( coords, dimensions ) {
+		$( 'x1' ).value = coords.x1;
+		$( 'y1' ).value = coords.y1;
+		$( 'x2' ).value = coords.x2;
+		$( 'y2' ).value = coords.y2;
+		$( 'width' ).value = dimensions.width;
+		$( 'height' ).value = dimensions.height;
+	}
+
+	// with a supplied ratio
+	Event.observe(
+		window,
+		'load',
+		function() {
+			var xinit = <?php echo HEADER_IMAGE_WIDTH; ?>;
+			var yinit = <?php echo HEADER_IMAGE_HEIGHT; ?>;
+			var ratio = xinit / yinit;
+			var ximg = $('upload').width;
+			var yimg = $('upload').height;
+			if ( yimg < yinit || ximg < xinit ) {
+				if ( ximg / yimg > ratio ) {
+					yinit = yimg;
+					xinit = yinit * ratio;
+				} else {
+					xinit = ximg;
+					yinit = xinit / ratio;
+				}
+			}
+			new Cropper.Img(
+				'upload',
+				{
+					ratioDim: { x: xinit, y: yinit },
+					displayOnInit: true,
+					onEndCrop: onEndCrop
+				}
+			)
+		}
+	);
+
+	var cp = new ColorPicker();
+
+	function pickColor(color) {
+		$('name').style.color = color;
+		$('desc').style.color = color;
+		$('textcolor').value = color;
+	}
+	function PopupWindow_hidePopup(magicword) {
+		if ( magicword != 'prettyplease' )
+			return false;
+		if (this.divName != null) {
+			if (this.use_gebi) {
+				document.getElementById(this.divName).style.visibility = "hidden";
+			}
+			else if (this.use_css) {
+				document.all[this.divName].style.visibility = "hidden";
+			}
+			else if (this.use_layers) {
+				document.layers[this.divName].visibility = "hidden";
+			}
+		}
+		else {
+			if (this.popupWindow && !this.popupWindow.closed) {
+				this.popupWindow.close();
+				this.popupWindow = null;
+			}
+		}
+		return false;
+	}
+	function colorSelect(t,p) {
+		if ( cp.p == p && document.getElementById(cp.divName).style.visibility != "hidden" ) {
+			cp.hidePopup('prettyplease');
+		} else {
+			cp.p = p;
+			cp.select(t,p);
+		}
+	}
+	function colorDefault() {
+		pickColor('<?php echo HEADER_TEXTCOLOR; ?>');
+	}
+
+	function hide_text() {
+		$('name').style.display = 'none';
+		$('desc').style.display = 'none';
+		$('pickcolor').style.display = 'none';
+		$('defaultcolor').style.display = 'none';
+		$('textcolor').value = 'blank';
+		$('hidetext').value = '<?php _e('Show Text'); ?>';
+//		$('hidetext').onclick = 'show_text()';
+		Event.observe( $('hidetext'), 'click', show_text );
+	}
+
+	function show_text() {
+		$('name').style.display = 'block';
+		$('desc').style.display = 'block';
+		$('pickcolor').style.display = 'inline';
+		$('defaultcolor').style.display = 'inline';
+		$('textcolor').value = '<?php echo HEADER_TEXTCOLOR; ?>';
+		$('hidetext').value = '<?php _e('Hide Text'); ?>';
+		Event.stopObserving( $('hidetext'), 'click', show_text );
+		Event.observe( $('hidetext'), 'click', hide_text );
+	}
+
+	<?php if ( 'blank' == get_theme_mod('header_textcolor', HEADER_TEXTCOLOR) ) { ?>
+Event.observe( window, 'load', hide_text );
+	<?php } ?>
+
+</script>
+<?php
+	}
+
+	function step_1() {
+		if ( $_GET['updated'] ) { ?>
+<div id="message" class="updated fade">
+<p><?php _e('Header updated.') ?></p>
+</div>
+		<?php } ?>
+
+<div class="wrap">
+<h2><?php _e('Your Header Image'); ?></h2>
+<p><?php _e('This is your header image. You can change the text color or upload and crop a new image.'); ?></p>
+
+<div id="headimg" style="background: url(<?php clean_url(header_image()) ?>) no-repeat;">
+<h1><a onclick="return false;" href="<?php bloginfo('url'); ?>" title="<?php bloginfo('name'); ?>" id="name"><?php bloginfo('name'); ?></a></h1>
+<div id="desc"><?php bloginfo('description');?></div>
+</div>
+<?php if ( !defined( 'NO_HEADER_TEXT' ) ) { ?>
+<form method="post" action="<?php echo get_option('siteurl') ?>/wp-admin/themes.php?page=custom-header&amp;updated=true">
+<input type="button" value="<?php _e('Hide Text'); ?>" onclick="hide_text()" id="hidetext" />
+<input type="button" value="<?php _e('Select a Text Color'); ?>" onclick="colorSelect($('textcolor'), 'pickcolor')" id="pickcolor" /><input type="button" value="<?php _e('Use Original Color'); ?>" onclick="colorDefault()" id="defaultcolor" />
+<?php wp_nonce_field('custom-header') ?>
+<input type="hidden" name="textcolor" id="textcolor" value="#<?php attribute_escape(header_textcolor()) ?>" /><input name="submit" type="submit" value="<?php _e('Save Changes'); ?> &raquo;" /></form>
+<?php } ?>
+
+<div id="colorPickerDiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;visibility:hidden;"> </div>
+</div>
+<div class="wrap">
+<h2><?php _e('Upload New Header Image'); ?></h2><p><?php _e('Here you can upload a custom header image to be shown at the top of your blog instead of the default one. On the next screen you will be able to crop the image.'); ?></p>
+<p><?php printf(__('Images of exactly <strong>%1$d x %2$d pixels</strong> will be used as-is.'), HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT); ?></p>
+
+<form enctype="multipart/form-data" id="uploadForm" method="POST" action="<?php echo attribute_escape(add_query_arg('step', 2)) ?>" style="margin: auto; width: 50%;">
+<label for="upload"><?php _e('Choose an image from your computer:'); ?></label><br /><input type="file" id="upload" name="import" />
+<input type="hidden" name="action" value="save" />
+<?php wp_nonce_field('custom-header') ?>
+<p class="submit">
+<input type="submit" value="<?php _e('Upload'); ?> &raquo;" />
+</p>
+</form>
+
+</div>
+
+		<?php if ( get_theme_mod('header_image') || get_theme_mod('header_textcolor') ) : ?>
+<div class="wrap">
+<h2><?php _e('Reset Header Image and Color'); ?></h2>
+<p><?php _e('This will restore the original header image and color. You will not be able to retrieve any customizations.') ?></p>
+<form method="post" action="<?php echo attribute_escape(add_query_arg('step', 1)) ?>">
+<?php wp_nonce_field('custom-header'); ?>
+<input type="submit" name="resetheader" value="<?php _e('Restore Original Header'); ?>" />
+</form>
+</div>
+		<?php endif;
+
+	}
+
+	function step_2() {
+		check_admin_referer('custom-header');
+		$overrides = array('test_form' => false);
+		$file = wp_handle_upload($_FILES['import'], $overrides);
+
+		if ( isset($file['error']) )
+		die( $file['error'] );
+
+		$url = $file['url'];
+		$file = $file['file'];
+		$filename = basename($file);
+
+		// Construct the object array
+		$object = array(
+		'post_title' => $filename,
+		'post_content' => $url,
+		'post_mime_type' => 'import',
+		'guid' => $url);
+
+		// Save the data
+		$id = wp_insert_attachment($object, $file);
+
+		$upload = array('file' => $file, 'id' => $id);
+
+		list($width, $height, $type, $attr) = getimagesize( $file );
+
+		if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
+			set_theme_mod('header_image', clean_url($url));
+			$header = apply_filters('wp_create_file_in_uploads', $file, $id); // For replication
+			return $this->finished();
+		} elseif ( $width > HEADER_IMAGE_WIDTH ) {
+			$oitar = $width / HEADER_IMAGE_WIDTH;
+			$image = wp_crop_image($file, 0, 0, $width, $height, HEADER_IMAGE_WIDTH, $height / $oitar, false, str_replace(basename($file), 'midsize-'.basename($file), $file));
+			$image = apply_filters('wp_create_file_in_uploads', $image, $id); // For replication
+
+			$url = str_replace(basename($url), basename($image), $url);
+			$width = $width / $oitar;
+			$height = $height / $oitar;
+		} else {
+			$oitar = 1;
+		}
+		?>
+
+<div class="wrap">
+
+<form method="POST" action="<?php echo attribute_escape(add_query_arg('step', 3)) ?>">
+
+<p><?php _e('Choose the part of the image you want to use as your header.'); ?></p>
+<div id="testWrap">
+<img src="<?php echo $url; ?>" id="upload" width="<?php echo $width; ?>" height="<?php echo $height; ?>" />
+</div>
+
+<p class="submit">
+<input type="hidden" name="x1" id="x1" />
+<input type="hidden" name="y1" id="y1" />
+<input type="hidden" name="x2" id="x2" />
+<input type="hidden" name="y2" id="y2" />
+<input type="hidden" name="width" id="width" />
+<input type="hidden" name="height" id="height" />
+<input type="hidden" name="attachment_id" id="attachment_id" value="<?php echo $id; ?>" />
+<input type="hidden" name="oitar" id="oitar" value="<?php echo $oitar; ?>" />
+<?php wp_nonce_field('custom-header') ?>
+<input type="submit" value="<?php _e('Crop Header &raquo;'); ?>" />
+</p>
+
+</form>
+</div>
+		<?php
+	}
+
+	function step_3() {
+		check_admin_referer('custom-header');
+		if ( $_POST['oitar'] > 1 ) {
+			$_POST['x1'] = $_POST['x1'] * $_POST['oitar'];
+			$_POST['y1'] = $_POST['y1'] * $_POST['oitar'];
+			$_POST['width'] = $_POST['width'] * $_POST['oitar'];
+			$_POST['height'] = $_POST['height'] * $_POST['oitar'];
+		}
+
+		$header = wp_crop_image($_POST['attachment_id'], $_POST['x1'], $_POST['y1'], $_POST['width'], $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT);
+		$header = apply_filters('wp_create_file_in_uploads', $header); // For replication
+
+		$parent = get_post($_POST['attachment_id']);
+
+		$parent_url = $parent->guid;
+
+		$url = str_replace(basename($parent_url), basename($header), $parent_url);
+
+		set_theme_mod('header_image', $url);
+
+		// cleanup
+		$file = get_attached_file( $_POST['attachment_id'] );
+		$medium = str_replace(basename($file), 'midsize-'.basename($file), $file);
+		@unlink( apply_filters( 'wp_delete_file', $medium ) );
+		wp_delete_attachment( $_POST['attachment_id'] );
+
+		return $this->finished();
+	}
+
+	function finished() {
+		?>
+<div class="wrap">
+<h2><?php _e('Header complete!'); ?></h2>
+
+<p><?php _e('Visit your site and you should see the new header now.'); ?></p>
+
+</div>
+		<?php
+	}
+
+	function admin_page() {
+		if ( !isset( $_GET['step'] ) )
+			$step = 1;
+		else
+			$step = (int) $_GET['step'];
+
+		if ( 1 == $step ) {
+			$this->step_1();
+		} elseif ( 2 == $step ) {
+			$this->step_2();
+		} elseif ( 3 == $step ) {
+			$this->step_3();
+		}
+
+	}
+
+}
+?>
diff -ruN 2.0.5/wp-admin/dbx-admin-key.js 2.2.2/wp-admin/dbx-admin-key.js
--- 2.0.5/wp-admin/dbx-admin-key.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/dbx-admin-key.js	2007-04-17 15:56:41.000000000 -0500
@@ -0,0 +1,47 @@
+addLoadEvent( function() {var manager = new dbxManager( dbxL10n.manager );} );
+
+addLoadEvent( function()
+{
+	//create new docking boxes group
+	var meta = new dbxGroup(
+		'grabit', 		// container ID [/-_a-zA-Z0-9/]
+		'vertical', 		// orientation ['vertical'|'horizontal']
+		'10', 			// drag threshold ['n' pixels]
+		'no',			// restrict drag movement to container axis ['yes'|'no']
+		'10', 			// animate re-ordering [frames per transition, or '0' for no effect]
+		'yes', 			// include open/close toggle buttons ['yes'|'no']
+		'closed', 		// default state ['open'|'closed']
+		dbxL10n.open, 		// word for "open", as in "open this box"
+		dbxL10n.close, 		// word for "close", as in "close this box"
+		dbxL10n.moveMouse,	// sentence for "move this box" by mouse
+		dbxL10n.toggleMouse,	// pattern-match sentence for "(open|close) this box" by mouse
+		dbxL10n.moveKey,	// sentence for "move this box" by keyboard
+		dbxL10n.toggleKey,	// pattern-match sentence-fragment for "(open|close) this box" by keyboard
+		'%mytitle%  [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts
+		);
+
+	// Boxes are closed by default. Open the Category box if the cookie isn't already set.
+	var catdiv = document.getElementById('categorydiv');
+	if ( catdiv ) {
+		var button = catdiv.getElementsByTagName('A')[0];
+		if ( dbx.cookiestate == null && /dbx\-toggle\-closed/.test(button.className) )
+			meta.toggleBoxState(button, true);
+	}
+
+	var advanced = new dbxGroup(
+		'advancedstuff',
+		'vertical',
+		'10',
+		'yes',			// restrict drag movement to container axis ['yes'|'no']
+		'10',
+		'yes',
+		'closed',
+		dbxL10n.open,
+		dbxL10n.close,
+		dbxL10n.moveMouse,
+		dbxL10n.toggleMouse,
+		dbxL10n.moveKey,
+		dbxL10n.toggleKey,
+		'%mytitle%  [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts
+		);
+});
diff -ruN 2.0.5/wp-admin/edit-category-form.php 2.2.2/wp-admin/edit-category-form.php
--- 2.0.5/wp-admin/edit-category-form.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/edit-category-form.php	2007-02-25 07:41:38.000000000 -0600
@@ -0,0 +1,49 @@
+<?php
+if ( ! empty($cat_ID) ) {
+	$heading = __('Edit Category');
+	$submit_text = __('Edit Category &raquo;');
+	$form = '<form name="editcat" id="editcat" method="post" action="categories.php">';
+	$action = 'editedcat';
+	$nonce_action = 'update-category_' . $cat_ID;
+	do_action('edit_category_form_pre', $category);
+} else {
+	$heading = __('Add Category');
+	$submit_text = __('Add Category &raquo;');
+	$form = '<form name="addcat" id="addcat" method="post" action="categories.php">';
+	$action = 'addcat';
+	$nonce_action = 'add-category';
+	do_action('add_category_form_pre', $category);
+}
+?>
+
+<div class="wrap">
+<h2><?php echo $heading ?></h2>
+<div id="ajax-response"></div>
+<?php echo $form ?>
+<input type="hidden" name="action" value="<?php echo $action ?>" />
+<input type="hidden" name="cat_ID" value="<?php echo $category->cat_ID ?>" />
+<?php wp_nonce_field($nonce_action); ?>
+	<table class="editform" width="100%" cellspacing="2" cellpadding="5">
+		<tr>
+			<th width="33%" scope="row" valign="top"><label for="cat_name"><?php _e('Category name:') ?></label></th>
+			<td width="67%"><input name="cat_name" id="cat_name" type="text" value="<?php echo attribute_escape($category->cat_name); ?>" size="40" /></td>
+		</tr>
+		<tr>
+			<th scope="row" valign="top"><label for="category_nicename"><?php _e('Category slug:') ?></label></th>
+			<td><input name="category_nicename" id="category_nicename" type="text" value="<?php echo attribute_escape($category->category_nicename); ?>" size="40" /></td>
+		</tr>
+		<tr>
+			<th scope="row" valign="top"><label for="category_parent"><?php _e('Category parent:') ?></label></th>
+			<td>        
+	  			<?php wp_dropdown_categories('hide_empty=0&name=category_parent&orderby=name&selected=' . $category->category_parent . '&hierarchical=1&show_option_none=' . __('None')); ?>
+	  		</td>
+		</tr>
+		<tr>
+			<th scope="row" valign="top"><label for="category_description"><?php _e('Description: (optional)') ?></label></th>
+			<td><textarea name="category_description" id="category_description" rows="5" cols="50" style="width: 97%;"><?php echo wp_specialchars($category->category_description); ?></textarea></td>
+		</tr>
+	</table>
+<p class="submit"><input type="submit" name="submit" value="<?php echo $submit_text ?>" /></p>
+<?php do_action('edit_category_form', $category); ?>
+</form>
+</div>
diff -ruN 2.0.5/wp-admin/edit-comments.js 2.2.2/wp-admin/edit-comments.js
--- 2.0.5/wp-admin/edit-comments.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/edit-comments.js	2007-03-27 18:49:15.000000000 -0500
@@ -0,0 +1,59 @@
+addLoadEvent(function() {
+	theCommentList = new listMan('the-comment-list');
+	if ( !theCommentList )
+		return false;
+
+	theExtraCommentList = new listMan('the-extra-comment-list');
+	if ( theExtraCommentList ) {
+		theExtraCommentList.showLink = 0;
+		theExtraCommentList.altOffset = 1;
+		if ( theExtraCommentList.theList && theExtraCommentList.theList.childNodes )
+			var commentNum = $A(theExtraCommentList.theList.childNodes).findAll( function(i) { return Element.visible(i) } ).length;
+		else
+			var commentNum = 0;
+		var urlQ   = document.location.href.split('?');
+		var params = urlQ[1] ? urlQ[1].toQueryParams() : [];
+		var search = params['s'] ? params['s'] : '';
+		var page   = params['apage'] ? params['apage'] : 1;
+	}
+
+	theCommentList.dimComplete = function(what,id,dimClass) {
+		var m = document.getElementById('awaitmod');
+		if ( document.getElementById(what + '-' + id).className.match(dimClass) )
+			m.innerHTML = parseInt(m.innerHTML,10) + 1;
+		else
+			m.innerHTML = parseInt(m.innerHTML,10) - 1;
+	}
+
+	theCommentList.delComplete = function(what,id) {
+		var m = document.getElementById('awaitmod');
+		what = what.split('-')[0];
+		if ( document.getElementById(what + '-' + id).className.match('unapproved') )
+			m.innerHTML = parseInt(m.innerHTML,10) - 1;
+		if ( theExtraCommentList && commentNum ) {
+			var theMover = theExtraCommentList.theList.childNodes[0];
+			Element.removeClassName(theMover,'alternate');
+			theCommentList.theList.appendChild(theMover);
+			theExtraCommentList.inputData += '&page=' + page;
+			if ( search )
+				theExtraCommentList.inputData += '&s=' + search; // trust the URL not the search box
+			theExtraCommentList.addComplete = function() {
+				if ( theExtraCommentList.theList.childNodes )
+					var commentNum = $A(theExtraCommentList.theList.childNodes).findAll( function(i) { return Element.visible(i) } ).length;
+				else
+					var commentNum = 0;
+			}
+			theExtraCommentList.ajaxAdder( 'comment', 'ajax-response' ); // Dummy Request
+		}
+	}
+
+	if ( theList ) // the post list: edit.php
+		theList.delComplete = function() {
+			var comments = document.getElementById('comments');
+			var commdel = encloseFunc(function(a){a.parentNode.removeChild(a);},comments);
+			var listdel = encloseFunc(function(a){a.parentNode.removeChild(a);},theCommentList.theList);
+			setTimeout(commdel,705);
+			setTimeout(listdel,705);
+		}
+});
+
diff -ruN 2.0.5/wp-admin/edit-comments.php 2.2.2/wp-admin/edit-comments.php
--- 2.0.5/wp-admin/edit-comments.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-comments.php	2007-08-02 09:58:15.000000000 -0500
@@ -2,12 +2,12 @@
 require_once('admin.php');
 
 $title = __('Edit Comments');
-$parent_file = 'edit.php';
-$list_js = true;
+$parent_file = 'edit-comments.php';
+wp_enqueue_script( 'admin-comments' );
 
 require_once('admin-header.php');
 if (empty($_GET['mode'])) $mode = 'view';
-else $mode = wp_specialchars($_GET['mode'], 1);
+else $mode = attribute_escape($_GET['mode']);
 ?>
 
 <script type="text/javascript">
@@ -23,17 +23,29 @@
 		}
 	}
 }
+
+function getNumChecked(form)
+{
+	var num = 0;
+	for (i = 0, n = form.elements.length; i < n; i++) {
+		if(form.elements[i].type == "checkbox") {
+			if(form.elements[i].checked == true)
+				num++;
+		}
+	}
+	return num;
+}
 //-->
 </script>
 <div class="wrap">
 <h2><?php _e('Comments'); ?></h2>
-<form name="searchform" action="" method="get"> 
+<form name="searchform" action="" method="get" id="editcomments"> 
   <fieldset> 
   <legend><?php _e('Show Comments That Contain...') ?></legend> 
-  <input type="text" name="s" value="<?php if (isset($_GET['s'])) echo wp_specialchars($_GET['s'], 1); ?>" size="17" /> 
+  <input type="text" name="s" value="<?php if (isset($_GET['s'])) echo attribute_escape($_GET['s']); ?>" size="17" /> 
   <input type="submit" name="submit" value="<?php _e('Search') ?>"  />  
   <input type="hidden" name="mode" value="<?php echo $mode; ?>" />
-  <?php _e('(Searches within comment text, e-mail, URI, and IP address.)') ?>
+  <?php _e('(Searches within comment text, e-mail, URL, and IP address.)') ?>
   </fieldset> 
 </form>
 <p><a href="?mode=view"><?php _e('View Mode') ?></a> | <a href="?mode=edit"><?php _e('Mass Edit Mode') ?></a></p>
@@ -44,83 +56,82 @@
 	$i = 0;
 	foreach ($_POST['delete_comments'] as $comment) : // Check the permissions on each
 		$comment = (int) $comment;
-		$post_id = $wpdb->get_var("SELECT comment_post_ID FROM $wpdb->comments WHERE comment_ID = $comment");
-		$authordata = get_userdata( $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $post_id") );
-		if ( current_user_can('edit_post', $post_id) ) :
-			wp_set_comment_status($comment, "delete");
+		$post_id = (int) $wpdb->get_var("SELECT comment_post_ID FROM $wpdb->comments WHERE comment_ID = $comment");
+		// $authordata = get_userdata( $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $post_id") );
+		if ( current_user_can('edit_post', $post_id) ) {
+			if ( !empty( $_POST['spam_button'] ) )
+				wp_set_comment_status($comment, 'spam');
+			else
+				wp_set_comment_status($comment, 'delete');
 			++$i;
-		endif;
+		}
 	endforeach;
-	echo "<div class='wrap'><p>" . sprintf(__('%s comments deleted.'), $i) . "</p></div>";
+	echo '<div style="background-color: rgb(207, 235, 247);" id="message" class="updated fade"><p>';
+	if ( !empty( $_POST['spam_button'] ) ) {
+		printf(__ngettext('%s comment marked as spam', '%s comments marked as spam.', $i), $i);
+	} else {
+		printf(__ngettext('%s comment deleted.', '%s comments deleted.', $i), $i);
+	}
+	echo '</p></div>';
 endif;
 
-if (isset($_GET['s'])) {
-	$s = $wpdb->escape($_GET['s']);
-	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments  WHERE
-		(comment_author LIKE '%$s%' OR
-		comment_author_email LIKE '%$s%' OR
-		comment_author_url LIKE ('%$s%') OR
-		comment_author_IP LIKE ('%$s%') OR
-		comment_content LIKE ('%$s%') ) AND
-		comment_approved != 'spam'
-		ORDER BY comment_date DESC");
-} else {
-	if ( isset($_GET['offset']) )
-		$offset = (int) $_GET['offset'] * 20;
-	else
-		$offset = 0;
+if ( isset( $_GET['apage'] ) )
+	$page = abs( (int) $_GET['apage'] );
+else
+	$page = 1;
+
+$start = $offset = ( $page - 1 ) * 20;
+
+list($_comments, $total) = _wp_get_comment_list( isset($_GET['s']) ? $_GET['s'] : false, $start, 25 ); // Grab a few extra
+
+$comments = array_slice($_comments, 0, 20);
+$extra_comments = array_slice($_comments, 20);
+
+$page_links = paginate_links( array(
+	'base' => add_query_arg( 'apage', '%#%' ), 
+	'format' => '',
+	'total' => ceil($total / 20),
+	'current' => $page
+));
+
+if ( $page_links )
+	echo "<p class='pagenav'>$page_links</p>";
 
-	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = '0' OR comment_approved = '1' ORDER BY comment_date DESC LIMIT $offset,20");
-}
 if ('view' == $mode) {
 	if ($comments) {
-		if ($offset)
-			$start = " start='$offset'";
-		else
-			$start = '';
+		$offset = $offset + 1;
+		$start = " start='$offset'";
 
-		echo "<ol id='the-list' class='commentlist' $start>";
+		echo "<ol id='the-comment-list' class='commentlist' $start>\n";
 		$i = 0;
-		foreach ($comments as $comment) {
-		++$i; $class = '';
-		$authordata = get_userdata($wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $comment->comment_post_ID"));
-			$comment_status = wp_get_comment_status($comment->comment_ID);
-			if ('unapproved' == $comment_status) 
-				$class .= ' unapproved';
-			if ($i % 2)
-				$class .= ' alternate';
-			echo "<li id='comment-$comment->comment_ID' class='$class'>";
-?>		
-        <p><strong><?php _e('Name:') ?></strong> <?php comment_author() ?> <?php if ($comment->comment_author_email) { ?>| <strong><?php _e('E-mail:') ?></strong> <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url ) { ?> | <strong><?php _e('URI:') ?></strong> <?php comment_author_url_link() ?> <?php } ?>| <strong><?php _e('IP:') ?></strong> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
-		
-		<?php comment_text() ?>
-
-        <p><?php _e('Posted'); echo ' '; comment_date('M j, g:i A');  
-			if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
-				echo " | <a href=\"post.php?action=editcomment&amp;comment=".$comment->comment_ID."\">" . __('Edit Comment') . "</a>";
-				echo ' | <a href="' . wp_nonce_url('post.php?action=deletecomment&amp;p=' . $comment->comment_post_ID . '&amp;comment=' . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . '" onclick="return deleteSomething( \'comment\', ' . $comment->comment_ID . ', \'' . __("You are about to delete this comment.\\n&quot;Cancel&quot; to stop, &quot;OK&quot; to delete.") . "' );\">" . __('Delete Comment') . '</a> ';
-			} // end if any comments to show
-			// Get post title
-			if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
-				$post_title = $wpdb->get_var("SELECT post_title FROM $wpdb->posts WHERE ID = $comment->comment_post_ID");
-				$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
-				?> | <a href="post.php?action=edit&amp;post=<?php echo $comment->comment_post_ID; ?>"><?php printf(__('Edit Post &#8220;%s&#8221;'), stripslashes($post_title)); ?></a>
-				<?php } ?>
-			 | <a href="<?php echo get_permalink($comment->comment_post_ID); ?>"><?php _e('View Post') ?></a></p>
-		</li>
+		foreach ( $comments as $comment ) {
+			get_comment( $comment ); // Cache it
+			_wp_comment_list_item( $comment->comment_ID, ++$i );
+		}
+		echo "</ol>\n\n";
 
-<?php } // end foreach ?>
-</ol>
+if ( $extra_comments ) : ?>
+<div id="extra-comments" style="display:none">
+<ul id="the-extra-comment-list" class="commentlist">
+<?php
+	foreach ( $extra_comments as $comment ) {
+		get_comment( $comment ); // Cache it
+		_wp_comment_list_item( $comment->comment_ID, ++$i );
+	}
+?>
+</ul>
+</div>
+<?php endif; // $extra_comments ?>
 
 <div id="ajax-response"></div>
 
 <?php
-	} else {
+	} else { //no comments to show
 
 		?>
 		<p>
-        <strong><?php _e('No comments found.') ?></strong></p>
-		
+			<strong><?php _e('No comments found.') ?></strong></p>
+
 		<?php
 	} // end if ($comments)
 } elseif ('edit' == $mode) {
@@ -128,37 +139,49 @@
 	if ($comments) {
 		echo '<form name="deletecomments" id="deletecomments" action="" method="post"> ';
 		wp_nonce_field('bulk-comments');
-		echo '<table width="100%" cellpadding="3" cellspacing="3">
+		echo '<table class="widefat">
+<thead>
   <tr>
-    <th scope="col">*</th>
+    <th scope="col" style="text-align: center"><input type="checkbox" onclick="checkAll(document.getElementById(\'deletecomments\'));" /></th>
     <th scope="col">' .  __('Name') . '</th>
     <th scope="col">' .  __('E-mail') . '</th>
     <th scope="col">' . __('IP') . '</th>
     <th scope="col">' . __('Comment Excerpt') . '</th>
-	<th scope="col" colspan="3">' .  __('Actions') . '</th>
-  </tr>';
+	<th scope="col" colspan="3" style="text-align: center">' .  __('Actions') . '</th>
+  </tr>
+</thead>';
 		foreach ($comments as $comment) {
 		$authordata = get_userdata($wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $comment->comment_post_ID"));
+		$comment_status = wp_get_comment_status($comment->comment_ID);
 		$class = ('alternate' == $class) ? '' : 'alternate';
+		$class .= ('unapproved' == $comment_status) ? ' unapproved' : '';
 ?>
-  <tr class='<?php echo $class; ?>'>
+  <tr id="comment-<?php echo $comment->comment_ID; ?>" class='<?php echo $class; ?>'>
     <td><?php if ( current_user_can('edit_post', $comment->comment_post_ID) ) { ?><input type="checkbox" name="delete_comments[]" value="<?php echo $comment->comment_ID; ?>" /><?php } ?></td>
     <td><?php comment_author_link() ?></td>
     <td><?php comment_author_email_link() ?></td>
     <td><a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></td>
     <td><?php comment_excerpt(); ?></td>
-    <td><a href="<?php echo get_permalink($comment->comment_post_ID); ?>#comment-<?php comment_ID() ?>" class="edit"><?php _e('View') ?></a></td>
+    <td>
+    	<?php if ('unapproved' == $comment_status) { ?>
+    		(Unapproved)
+    	<?php } else { ?>
+    		<a href="<?php echo get_permalink($comment->comment_post_ID); ?>#comment-<?php comment_ID() ?>" class="edit"><?php _e('View') ?></a>
+    	<?php } ?>
+    </td>
     <td><?php if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
-	echo "<a href='post.php?action=editcomment&amp;comment=$comment->comment_ID' class='edit'>" .  __('Edit') . "</a>"; } ?></td>
+	echo "<a href='comment.php?action=editcomment&amp;c=$comment->comment_ID' class='edit'>" .  __('Edit') . "</a>"; } ?></td>
     <td><?php if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
-            echo "<a href=\"" . wp_nonce_url("post.php?action=deletecomment&amp;p=".$comment->comment_post_ID."&amp;comment=".$comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . "\" onclick=\"return confirm('" . __("You are about to delete this comment.\\n  \'Cancel\' to stop, \'OK\' to delete.") . "')\"    class='delete'>" . __('Delete') . "</a>"; } ?></td>
+		echo "<a href=\"comment.php?action=deletecomment&amp;p=".$comment->comment_post_ID."&amp;c=".$comment->comment_ID."\" onclick=\"return deleteSomething( 'comment', $comment->comment_ID, '" . js_escape(sprintf(__("You are about to delete this comment by '%s'. \n  'Cancel' to stop, 'OK' to delete."), $comment->comment_author ))  . "', theCommentList );\" class='delete'>" . __('Delete') . "</a> ";
+		} ?></td>
   </tr>
 		<?php 
 		} // end foreach
 	?></table>
-    <p><a href="javascript:;" onclick="checkAll(document.getElementById('deletecomments')); return false; "><?php _e('Invert Checkbox Selection') ?></a></p>
-            <p class="submit"><input type="submit" name="Submit" value="<?php _e('Delete Checked Comments') ?> &raquo;" onclick="return confirm('<?php _e("You are about to delete these comments permanently.\\n  \'Cancel\' to stop, \'OK\' to delete.") ?>')" />	</p>
+<p class="submit"><input type="submit" name="delete_button" class="delete" value="<?php _e('Delete Checked Comments &raquo;') ?>" onclick="var numchecked = getNumChecked(document.getElementById('deletecomments')); if(numchecked < 1) { alert('<?php echo js_escape(__("Please select some comments to delete")); ?>'); return false } return confirm('<?php echo sprintf(js_escape(__("You are about to delete %s comments permanently \n  'Cancel' to stop, 'OK' to delete.")), "' + numchecked + '"); ?>')" />
+			<input type="submit" name="spam_button" value="<?php _e('Mark Checked Comments as Spam &raquo;') ?>" onclick="var numchecked = getNumChecked(document.getElementById('deletecomments')); if(numchecked < 1) { alert('<?php echo js_escape(__("Please select some comments to mark as spam")); ?>'); return false } return confirm('<?php echo sprintf(js_escape(__("You are about to mark %s comments as spam \n  'Cancel' to stop, 'OK' to mark as spam.")), "' + numchecked + '"); ?>')" /></p>
   </form>
+<div id="ajax-response"></div>
 <?php
 	} else {
 ?>
@@ -168,7 +191,11 @@
 <?php
 	} // end if ($comments)
 }
-	?>
+
+if ( $page_links )
+	echo "<p class='pagenav'>$page_links</p>";
+
+?>
 
 </div>
 
diff -ruN 2.0.5/wp-admin/edit-form-advanced.php 2.2.2/wp-admin/edit-form-advanced.php
--- 2.0.5/wp-admin/edit-form-advanced.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-form-advanced.php	2007-05-28 23:37:35.000000000 -0500
@@ -1,39 +1,39 @@
 <?php
+if ( isset($_GET['message']) )
+	  $_GET['message'] = (int) $_GET['message'];
 $messages[1] = __('Post updated');
 $messages[2] = __('Custom field updated');
 $messages[3] = __('Custom field deleted.');
 ?>
 <?php if (isset($_GET['message'])) : ?>
-<div id="message" class="updated fade"><p><?php echo $messages[$_GET['message']]; ?></p></div>
+<div id="message" class="updated fade"><p><?php echo wp_specialchars($messages[$_GET['message']]); ?></p></div>
 <?php endif; ?>
 
 <form name="post" action="post.php" method="post" id="post">
-<?php if ( (isset($mode) && 'bookmarklet' == $mode) || 
-            isset($_GET['popupurl']) ): ?>
+<?php if ( (isset($mode) && 'bookmarklet' == $mode) || isset($_GET['popupurl']) ): ?>
 <input type="hidden" name="mode" value="bookmarklet" />
 <?php endif; ?>
 
 <div class="wrap">
-<h2 id="write-post"><?php _e('Write Post'); ?><?php if ( 0 != $post_ID ) : ?>
- <small class="quickjump"><a href="#preview-post"><?php _e('preview &darr;'); ?></a></small><?php endif; ?></h2>
 <?php
 
 if (0 == $post_ID) {
 	$form_action = 'post';
-	$temp_ID = -1 * time();
-	$form_extra = "<input type='hidden' name='temp_ID' value='$temp_ID' />";
+	$temp_ID = -1 * time(); // don't change this formula without looking at wp_write_post()
+	$form_extra = "<input type='hidden' id='post_ID' name='temp_ID' value='$temp_ID' />";
 	wp_nonce_field('add-post');
 } else {
+	$post_ID = (int) $post_ID;
 	$form_action = 'editpost';
-	$form_extra = "<input type='hidden' name='post_ID' value='$post_ID' />";
+	$form_extra = "<input type='hidden' id='post_ID' name='post_ID' value='$post_ID' />";
 	wp_nonce_field('update-post_' .  $post_ID);
 }
 
-$form_pingback = '<input type="hidden" name="post_pingback" value="' . get_option('default_pingback_flag') . '" id="post_pingback" />';
+$form_pingback = '<input type="hidden" name="post_pingback" value="' . (int) get_option('default_pingback_flag') . '" id="post_pingback" />';
 
-$form_prevstatus = '<input type="hidden" name="prev_status" value="' . $post->post_status . '" />';
+$form_prevstatus = '<input type="hidden" name="prev_status" value="' . attribute_escape( $post->post_status ) . '" />';
 
-$form_trackback = '<input type="text" name="trackback_url" style="width: 415px" id="trackback" tabindex="7" value="'. str_replace("\n", ' ', $post->to_ping) .'" />';
+$form_trackback = '<input type="text" name="trackback_url" style="width: 415px" id="trackback" tabindex="7" value="'. attribute_escape( str_replace("\n", ' ', $post->to_ping) ) .'" />';
 
 if ('' != $post->pinged) {
 	$pings = '<p>'. __('Already pinged:') . '</p><ul>';
@@ -44,15 +44,17 @@
 	$pings .= '</ul>';
 }
 
-$saveasdraft = '<input name="save" type="submit" id="save" tabindex="3" value="' . __('Save and Continue Editing') . '" />';
+$saveasdraft = '<input name="save" type="submit" id="save" tabindex="3" value="' . attribute_escape( __('Save and Continue Editing') ) . '" />';
 
 if (empty($post->post_status)) $post->post_status = 'draft';
 
 ?>
 
-<input type="hidden" name="user_ID" value="<?php echo $user_ID ?>" />
-<input type="hidden" name="action" value="<?php echo $form_action ?>" />
-<input type="hidden" name="post_author" value="<?php echo $post->post_author ?>" />
+<input type="hidden" name="user_ID" value="<?php echo (int) $user_ID ?>" />
+<input type="hidden" id="hiddenaction" name="action" value="<?php echo $form_action ?>" />
+<input type="hidden" id="originalaction" name="originalaction" value="<?php echo $form_action ?>" />
+<input type="hidden" name="post_author" value="<?php echo attribute_escape( $post->post_author ); ?>" />
+<input type="hidden" id="post_type" name="post_type" value="post" />
 
 <?php echo $form_extra ?>
 <?php if (isset($_GET['message']) && 2 > $_GET['message']) : ?>
@@ -69,6 +71,13 @@
 <div id="moremeta">
 <div id="grabit" class="dbx-group">
 
+<fieldset id="categorydiv" class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Categories') ?></h3>
+<div class="dbx-content">
+<p id="jaxcat"></p>
+<ul id="categorychecklist"><?php dropdown_categories(); ?></ul></div>
+</fieldset>
+
 <fieldset id="commentstatusdiv" class="dbx-box">
 <h3 class="dbx-handle"><?php _e('Discussion') ?></h3>
 <div class="dbx-content">
@@ -81,26 +90,19 @@
 </fieldset>
 
 <fieldset id="passworddiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Password-Protect Post') ?></h3> 
-<div class="dbx-content"><input name="post_password" type="text" size="13" id="post_password" value="<?php echo $post->post_password ?>" /></div>
+<h3 class="dbx-handle"><?php _e('Post Password') ?></h3> 
+<div class="dbx-content"><input name="post_password" type="text" size="13" id="post_password" value="<?php echo attribute_escape( $post->post_password ); ?>" /></div>
 </fieldset>
 
 <fieldset id="slugdiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Post slug') ?></h3> 
-<div class="dbx-content"><input name="post_name" type="text" size="13" id="post_name" value="<?php echo $post->post_name ?>" /></div>
-</fieldset>
-
-<fieldset id="categorydiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Categories') ?></h3>
-<div class="dbx-content">
-<p id="jaxcat"></p>
-<div id="categorychecklist"><?php dropdown_categories(get_settings('default_category')); ?></div></div>
+<h3 class="dbx-handle"><?php _e('Post Slug') ?></h3> 
+<div class="dbx-content"><input name="post_name" type="text" size="13" id="post_name" value="<?php echo attribute_escape( $post->post_name ); ?>" /></div>
 </fieldset>
 
 <fieldset id="poststatusdiv" class="dbx-box">
 <h3 class="dbx-handle"><?php _e('Post Status') ?></h3> 
 <div class="dbx-content"><?php if ( current_user_can('publish_posts') ) : ?>
-<label for="post_status_publish" class="selectit"><input id="post_status_publish" name="post_status" type="radio" value="publish" <?php checked($post->post_status, 'publish'); ?> /> <?php _e('Published') ?></label>
+<label for="post_status_publish" class="selectit"><input id="post_status_publish" name="post_status" type="radio" value="publish" <?php checked($post->post_status, 'publish'); checked($post->post_status, 'future'); ?> /> <?php _e('Published') ?></label>
 <?php endif; ?>
 	  <label for="post_status_draft" class="selectit"><input id="post_status_draft" name="post_status" type="radio" value="draft" <?php checked($post->post_status, 'draft'); ?> /> <?php _e('Draft') ?></label>
 	  <label for="post_status_private" class="selectit"><input id="post_status_private" name="post_status" type="radio" value="private" <?php checked($post->post_status, 'private'); ?> /> <?php _e('Private') ?></label></div>
@@ -108,22 +110,25 @@
 
 <?php if ( current_user_can('edit_posts') ) : ?>
 <fieldset id="posttimestampdiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Post Timestamp'); ?>:</h3>
+<h3 class="dbx-handle"><?php _e('Post Timestamp'); ?></h3>
 <div class="dbx-content"><?php touch_time(($action == 'edit')); ?></div>
 </fieldset>
 <?php endif; ?>
 
-<?php if ( $authors = get_editable_authors( $current_user->id ) ) : // TODO: ROLE SYSTEM ?>
+<?php 
+$authors = get_editable_authors( $current_user->id ); // TODO: ROLE SYSTEM
+if ( $authors && count( $authors ) > 1 ) :
+?>
 <fieldset id="authordiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Post author'); ?>:</h3>
+<h3 class="dbx-handle"><?php _e('Post Author'); ?></h3>
 <div class="dbx-content">
 <select name="post_author_override" id="post_author_override">
-<?php 
+<?php
 foreach ($authors as $o) :
 $o = get_userdata( $o->ID );
 if ( $post->post_author == $o->ID || ( empty($post_ID) && $user_ID == $o->ID ) ) $selected = 'selected="selected"';
 else $selected = '';
-echo "<option value='$o->ID' $selected>$o->display_name</option>";
+echo "<option value='" . (int) $o->ID . "' $selected>" . wp_specialchars( $o->display_name ) . "</option>";
 endforeach;
 ?>
 </select>
@@ -137,93 +142,55 @@
 </div>
 
 <fieldset id="titlediv">
-  <legend><?php _e('Title') ?></legend> 
-  <div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo $post->post_title; ?>" id="title" /></div>
+	<legend><?php _e('Title') ?></legend>
+	<div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo attribute_escape($post->post_title); ?>" id="title" /></div>
 </fieldset>
 
 <fieldset id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>">
-<legend><?php _e('Post') ?></legend>
+<legend><?php _e('Post') ?>
 
-<?php
- $rows = get_settings('default_post_edit_rows');
- if (($rows < 3) || ($rows > 100)) {
-     $rows = 12;
- }
-?>
-<?php the_quicktags(); ?>
-</fieldset>
+<?php if ( 'publish' == $post->post_status ) { ?>
+<a href="<?php echo clean_url(get_permalink($post->ID)); ?>" class="view-link" target="_blank"><?php _e('View &raquo;'); ?></a>
+<?php } elseif ( 'edit' == $action ) { ?>
+<a href="<?php echo clean_url(apply_filters('preview_post_link', add_query_arg('preview', 'true', get_permalink($post->ID)))); ?>" class="view-link" target="_blank"><?php _e('Preview &raquo;'); ?></a>
+<?php } ?>
+</legend>
 
-<div><textarea <?php if ( user_can_richedit() ) echo 'title="true" '; ?>rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="2" id="content"><?php echo user_can_richedit() ? wp_richedit_pre($post->post_content) : $post->post_content; ?></textarea></div>
+	<?php the_editor($post->post_content); ?>
 </fieldset>
 
-<script type="text/javascript">
-// <![CDATA[
-edCanvas = document.getElementById('content');
-<?php if ( user_can_richedit() ) : ?>
-// This code is meant to allow tabbing from Title to Post (TinyMCE).
-if ( tinyMCE.isMSIE )
-	document.getElementById('title').onkeydown = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-else
-	document.getElementById('title').onkeypress = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-<?php endif; ?>
-// ]]>
-</script>
-
 <?php echo $form_pingback ?>
 <?php echo $form_prevstatus ?>
 
 
-<p class="submit"><?php echo $saveasdraft; ?> <input type="submit" name="submit" value="<?php _e('Save') ?>" style="font-weight: bold;" tabindex="4" /> 
+<p class="submit">
+<span id="autosave"></span>
+<?php echo $saveasdraft; ?>
+<input type="submit" name="submit" value="<?php _e('Save') ?>" style="font-weight: bold;" tabindex="4" /> 
 <?php 
 if ('publish' != $post->post_status || 0 == $post_ID) {
 ?>
 <?php if ( current_user_can('publish_posts') ) : ?>
-	<input name="publish" type="submit" id="publish" tabindex="5" accesskey="p" value="<?php _e('Publish') ?>" /> 
+	<input name="publish" type="submit" id="publish" tabindex="5" accesskey="p" value="<?php _e('Publish'); ?>" /> 
 <?php endif; ?>
 <?php
 }
 ?>
 <input name="referredby" type="hidden" id="referredby" value="<?php 
 if ( !empty($_REQUEST['popupurl']) )
-	echo wp_specialchars($_REQUEST['popupurl']);
+	echo clean_url(stripslashes($_REQUEST['popupurl']));
 else if ( url_to_postid(wp_get_referer()) == $post_ID )
 	echo 'redo';
 else
-	echo wp_specialchars(wp_get_referer());
+	echo clean_url(stripslashes(wp_get_referer()));
 ?>" /></p>
 
 <?php do_action('edit_form_advanced'); ?>
 
 <?php
 if (current_user_can('upload_files')) {
-	$uploading_iframe_ID = (0 == $post_ID ? $temp_ID : $post_ID);
-	$uploading_iframe_src = wp_nonce_url("inline-uploading.php?action=view&amp;post=$uploading_iframe_ID", 'inlineuploading');
+	$uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
+	$uploading_iframe_src = wp_nonce_url("upload.php?style=inline&amp;tab=upload&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
 	$uploading_iframe_src = apply_filters('uploading_iframe_src', $uploading_iframe_src);
 	if ( false != $uploading_iframe_src )
 		echo '<iframe id="uploading" frameborder="0" src="' . $uploading_iframe_src . '">' . __('This feature requires iframe support.') . '</iframe>';
@@ -232,25 +199,25 @@
 
 <div id="advancedstuff" class="dbx-group" >
 
-<div class="dbx-box-wrapper">
+<div class="dbx-b-ox-wrapper">
 <fieldset id="postexcerpt" class="dbx-box">
-<div class="dbx-handle-wrapper">
+<div class="dbx-h-andle-wrapper">
 <h3 class="dbx-handle"><?php _e('Optional Excerpt') ?></h3>
 </div>
-<div class="dbx-content-wrapper">
+<div class="dbx-c-ontent-wrapper">
 <div class="dbx-content"><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"><?php echo $post->post_excerpt ?></textarea></div>
 </div>
 </fieldset>
 </div>
 
-<div class="dbx-box-wrapper">
+<div class="dbx-b-ox-wrapper">
 <fieldset id="trackbacksdiv" class="dbx-box">
-<div class="dbx-handle-wrapper">
+<div class="dbx-h-andle-wrapper">
 <h3 class="dbx-handle"><?php _e('Trackbacks') ?></h3>
 </div>
-<div class="dbx-content-wrapper">
-<div class="dbx-content"><?php _e('Send trackbacks to'); ?>: <?php echo $form_trackback; ?> (<?php _e('Separate multiple URIs with spaces'); ?>)
-<?php 
+<div class="dbx-c-ontent-wrapper">
+<div class="dbx-content"><?php _e('Send trackbacks to:'); ?> <?php echo $form_trackback; ?> (<?php _e('Separate multiple URLs with spaces'); ?>)
+<?php
 if ( ! empty($pings) )
 	echo $pings;
 ?>
@@ -259,23 +226,24 @@
 </fieldset>
 </div>
 
-<div class="dbx-box-wrapper">
+<div class="dbx-b-ox-wrapper">
 <fieldset id="postcustom" class="dbx-box">
-<div class="dbx-handle-wrapper">
+<div class="dbx-h-andle-wrapper">
 <h3 class="dbx-handle"><?php _e('Custom Fields') ?></h3>
 </div>
-<div class="dbx-content-wrapper">
+<div class="dbx-c-ontent-wrapper">
 <div id="postcustomstuff" class="dbx-content">
-<?php 
-if($metadata = has_meta($post_ID)) {
-?>
+<table cellpadding="3">
 <?php
-	list_meta($metadata); 
+$metadata = has_meta($post_ID);
+list_meta($metadata);
 ?>
+
+</table>
 <?php
-}
 	meta_form();
 ?>
+<div id="ajax-response"></div>
 </div>
 </div>
 </fieldset>
@@ -286,7 +254,7 @@
 </div>
 
 <?php if ('edit' == $action) : $delete_nonce = wp_create_nonce( 'delete-post_' . $post_ID ); ?>
-<input name="deletepost" class="button" type="submit" id="deletepost" tabindex="10" value="<?php _e('Delete this post') ?>" <?php echo "onclick=\"if ( confirm('" . sprintf(__("You are about to delete this post \'%s\'\\n  \'Cancel\' to stop, \'OK\' to delete."), js_escape($post->post_title) ) . "') ) { document.forms.post._wpnonce.value = '$delete_nonce'; return true;}return false;\""; ?> />
+<input name="deletepost" class="button delete" type="submit" id="deletepost" tabindex="10" value="<?php echo ( 'draft' == $post->post_status ) ? __('Delete this draft') : __('Delete this post'); ?>" <?php echo "onclick=\"if ( confirm('" . js_escape(sprintf( ('draft' == $post->post_status) ? __("You are about to delete this draft '%s'\n  'Cancel' to stop, 'OK' to delete.") : __("You are about to delete this post '%s'\n  'Cancel' to stop, 'OK' to delete."), $post->post_title )) . "') ) { document.forms.post._wpnonce.value = '$delete_nonce'; return true;}return false;\""; ?> />
 <?php endif; ?>
 
 </div>
diff -ruN 2.0.5/wp-admin/edit-form-ajax-cat.php 2.2.2/wp-admin/edit-form-ajax-cat.php
--- 2.0.5/wp-admin/edit-form-ajax-cat.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-form-ajax-cat.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,37 +0,0 @@
-<?php
-require_once('../wp-config.php');
-require_once('admin-functions.php');
-require_once('admin-db.php');
-
-if ( !current_user_can('manage_categories') )
-	die('-1');
-if ( !check_ajax_referer() )
-	die('-1');
-
-function get_out_now() { exit; }
-
-add_action('shutdown', 'get_out_now', -1);
-
-$names = explode(',', rawurldecode($_POST['ajaxnewcat']) );
-$ids   = array();
-
-foreach ($names as $cat_name) {
-	$cat_name = trim( $cat_name );
-	
-	if ( !$category_nicename = sanitize_title($cat_name) )
-		continue;
-	if ( $already = category_exists($cat_name) ) {
-		$ids[] = (string) $already;
-		continue;
-	}
-	
-	$new_cat_id = wp_create_category($cat_name);
-	
-	$ids[] = (string) $new_cat_id;
-}
-
-$return = join(',', $ids);
-
-die( (string) $return );
-
-?>
diff -ruN 2.0.5/wp-admin/edit-form-comment.php 2.2.2/wp-admin/edit-form-comment.php
--- 2.0.5/wp-admin/edit-form-comment.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-form-comment.php	2007-05-28 23:37:35.000000000 -0500
@@ -2,13 +2,13 @@
 $submitbutton_text = __('Edit Comment &raquo;');
 $toprow_title = sprintf(__('Editing Comment # %s'), $comment->comment_ID);
 $form_action = 'editedcomment';
-$form_extra = "' />\n<input type='hidden' name='comment_ID' value='" . $comment->comment_ID . "' />\n<input type='hidden' name='comment_post_ID' value='".$comment->comment_post_ID;
+$form_extra = "' />\n<input type='hidden' name='comment_ID' value='" . $comment->comment_ID . "' />\n<input type='hidden' name='comment_post_ID' value='" . $comment->comment_post_ID;
 ?>
 
-<form name="post" action="post.php" method="post" id="post">
+<form name="post" action="comment.php" method="post" id="post">
 <?php wp_nonce_field('update-comment_' . $comment->comment_ID) ?>
 <div class="wrap">
-<input type="hidden" name="user_ID" value="<?php echo $user_ID ?>" />
+<input type="hidden" name="user_ID" value="<?php echo (int) $user_ID ?>" />
 <input type="hidden" name="action" value='<?php echo $form_action . $form_extra ?>' />
 
 <script type="text/javascript">
@@ -18,76 +18,29 @@
 addLoadEvent(focusit);
 </script>
 <fieldset id="namediv">
-    <legend><?php _e('Name:') ?></legend>
+    <legend><label for="name"><?php _e('Name:') ?></label></legend>
 	<div>
-	  <input type="text" name="newcomment_author" size="22" value="<?php echo $comment->comment_author ?>" tabindex="1" id="name" />
+	  <input type="text" name="newcomment_author" size="25" value="<?php echo attribute_escape( $comment->comment_author ); ?>" tabindex="1" id="name" />
     </div>
 </fieldset>
 <fieldset id="emaildiv">
-        <legend><?php _e('E-mail:') ?></legend>
+        <legend><label for="email"><?php _e('E-mail:') ?></label></legend>
 		<div>
-		  <input type="text" name="newcomment_author_email" size="30" value="<?php echo $comment->comment_author_email ?>" tabindex="2" id="email" />
+		  <input type="text" name="newcomment_author_email" size="20" value="<?php echo attribute_escape( $comment->comment_author_email ); ?>" tabindex="2" id="email" />
     </div>
 </fieldset>
 <fieldset id="uridiv">
-        <legend><?php _e('URI:') ?></legend>
+        <legend><label for="newcomment_author_url"><?php _e('URL:') ?></label></legend>
 		<div>
-		  <input type="text" id="newcomment_author_url" name="newcomment_author_url" size="35" value="<?php echo $comment->comment_author_url ?>" tabindex="3" id="URL" />
+		  <input type="text" id="newcomment_author_url" name="newcomment_author_url" size="35" value="<?php echo attribute_escape( $comment->comment_author_url ); ?>" tabindex="3" />
     </div>
 </fieldset>
 
 <fieldset style="clear: both;">
         <legend><?php _e('Comment') ?></legend>
-<?php the_quicktags(); ?>
-
-<?php
- $rows = get_settings('default_post_edit_rows');
- if (($rows < 3) || ($rows > 100)) {
-     $rows = 10;
- }
-?>
-<div><textarea title="true" rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="4" id="content" style="width: 99%"><?php echo user_can_richedit() ? wp_richedit_pre($comment->comment_content) : $comment->comment_content; ?></textarea></div>
+	<?php the_editor($comment->comment_content, 'content', 'newcomment_author_url'); ?>
 </fieldset>
 
-<script type="text/javascript">
-<!--
-edCanvas = document.getElementById('content');
-<?php if ( user_can_richedit() ) : ?>
-// This code is meant to allow tabbing from Author URL to Post (TinyMCE).
-if ( tinyMCE.isMSIE )
-	document.getElementById('newcomment_author_url').onkeydown = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-else
-	document.getElementById('newcomment_author_url').onkeypress = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-<?php endif; ?>
-//-->
-</script>
-
 <p class="submit"><input type="submit" name="editcomment" id="editcomment" value="<?php echo $submitbutton_text ?>" style="font-weight: bold;" tabindex="6" />
   <input name="referredby" type="hidden" id="referredby" value="<?php echo wp_get_referer(); ?>" />
 </p>
@@ -101,20 +54,24 @@
 	<tr>
 		<th scope="row" valign="top"><?php _e('Comment Status') ?>:</th>
 		<td><label for="comment_status_approved" class="selectit"><input id="comment_status_approved" name="comment_status" type="radio" value="1" <?php checked($comment->comment_approved, '1'); ?> /> <?php _e('Approved') ?></label><br />
-	  <label for="comment_status_moderated" class="selectit"><input id="comment_status_moderated" name="comment_status" type="radio" value="0" <?php checked($comment->comment_approved, '0'); ?> /> <?php _e('Moderated') ?></label><br />
-	  <label for="comment_status_spam" class="selectit"><input id="comment_status_spam" name="comment_status" type="radio" value="spam" <?php checked($comment->comment_approved, 'spam'); ?> /> <?php _e('Spam') ?></label></td>
+		<label for="comment_status_moderated" class="selectit"><input id="comment_status_moderated" name="comment_status" type="radio" value="0" <?php checked($comment->comment_approved, '0'); ?> /> <?php _e('Moderated') ?></label><br />
+		<label for="comment_status_spam" class="selectit"><input id="comment_status_spam" name="comment_status" type="radio" value="spam" <?php checked($comment->comment_approved, 'spam'); ?> /> <?php _e('Spam') ?></label></td>
 	</tr>
 
 <?php if ( current_user_can('edit_posts') ) : ?>
 	<tr>
-		<th scope="row"><?php _e('Edit time'); ?>:</th>
-		<td><?php touch_time(('editcomment' == $action), 0); ?></td>
+		<th scope="row" valign="top"><?php _e('Edit time'); ?>:</th>
+		<td><?php touch_time(('editcomment' == $action), 0); ?> </td>
 	</tr>
 <?php endif; ?>
 
 	<tr>
-		<th scope="row"><?php _e('Delete'); ?>:</th>
-		<td><p><a class="delete" href="post.php?action=confirmdeletecomment&amp;noredir=true&amp;comment=<?php echo $comment->comment_ID; ?>&amp;p=<?php echo $comment->comment_post_ID; ?>"><?php _e('Delete comment') ?></a></p></td>
+		<th scope="row" valign="top"><?php _e('Delete'); $delete_nonce = wp_create_nonce( 'delete-comment_' . $comment->comment_ID ); ?>:</th>
+		<td><input name="deletecomment" class="button delete" type="submit" id="deletecomment" tabindex="10" value="<?php _e('Delete this comment') ?>" <?php echo "onclick=\"if ( confirm('" . js_escape(__("You are about to delete this comment. \n  'Cancel' to stop, 'OK' to delete.")) . "') ) { document.forms.post._wpnonce.value = '$delete_nonce'; return true; } return false;\""; ?> /> 
+		<input type="hidden" name="c" value="<?php echo $comment->comment_ID ?>" />
+		<input type="hidden" name="p" value="<?php echo $comment->comment_post_ID ?>" />
+		<input type="hidden" name="noredir" value="1" />
+	</td>
 	</tr>
 </table>
 
diff -ruN 2.0.5/wp-admin/edit-form.php 2.2.2/wp-admin/edit-form.php
--- 2.0.5/wp-admin/edit-form.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-form.php	2007-05-28 23:37:35.000000000 -0500
@@ -6,7 +6,7 @@
 <?php if (isset($mode) && 'bookmarklet' == $mode) : ?>
 <input type="hidden" name="mode" value="bookmarklet" />
 <?php endif; ?>
-<input type="hidden" name="user_ID" value="<?php echo $user_ID ?>" />
+<input type="hidden" name="user_ID" value="<?php echo (int) $user_ID ?>" />
 <input type="hidden" name="action" value='post' />
 
 <script type="text/javascript">
@@ -21,7 +21,7 @@
 <div id="poststuff">
     <fieldset id="titlediv">
       <legend><a href="http://wordpress.org/docs/reference/post/#title" title="<?php _e('Help on titles') ?>"><?php _e('Title') ?></a></legend> 
-	  <div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo $post->post_title; ?>" id="title" /></div>
+	  <div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo attribute_escape( $post->post_title ); ?>" id="title" /></div>
     </fieldset>
 
     <fieldset id="categorydiv">
@@ -34,7 +34,7 @@
     <legend><a href="http://wordpress.org/docs/reference/post/#post" title="<?php _e('Help with post field') ?>"><?php _e('Post') ?></a></legend>
 <?php the_quicktags(); ?>
 <?php
- $rows = get_settings('default_post_edit_rows');
+ $rows = get_option('default_post_edit_rows');
  if (($rows < 3) || ($rows > 100)) {
      $rows = 10;
  }
@@ -49,22 +49,22 @@
 //-->
 </script>
 
-<input type="hidden" name="post_pingback" value="<?php echo get_option('default_pingback_flag') ?>" id="post_pingback" />
+<input type="hidden" name="post_pingback" value="<?php echo (int) get_option('default_pingback_flag') ?>" id="post_pingback" />
 
-<p><label for="trackback"> <?php printf(__('<a href="%s" title="Help on trackbacks"><strong>TrackBack</strong> a <abbr title="Universal Resource Identifier">URI</abbr></a>:</label> (Separate multiple <abbr title="Universal Resource Identifier">URI</abbr>s with spaces.)<br />'), 'http://wordpress.org/docs/reference/post/#trackback') ?>
+<p><label for="trackback"> <?php printf(__('<a href="%s" title="Help on trackbacks"><strong>TrackBack</strong> a <abbr title="Universal Resource Locator">URL</abbr></a>:</label> (Separate multiple <abbr title="Universal Resource Locator">URL</abbr>s with spaces.)'), 'http://wordpress.org/docs/reference/post/#trackback'); echo '<br />'; ?>
 	<input type="text" name="trackback_url" style="width: 360px" id="trackback" tabindex="7" /></p>
 
-<p class="submit"><input name="saveasdraft" type="submit" id="saveasdraft" tabindex="9" value="<?php _e('Save as Draft') ?>" /> 
-  <input name="saveasprivate" type="submit" id="saveasprivate" tabindex="10" value="<?php _e('Save as Private') ?>" />
+<p class="submit"><input name="saveasdraft" type="submit" id="saveasdraft" tabindex="9" value="<?php _e('Save as Draft') ?>" />
+	<input name="saveasprivate" type="submit" id="saveasprivate" tabindex="10" value="<?php _e('Save as Private') ?>" />
 
 	 <?php if ( current_user_can('edit_posts') ) : ?>
-  <input name="publish" type="submit" id="publish" tabindex="6" style="font-weight: bold;" value="<?php _e('Publish') ?>" /> 
+	<input name="publish" type="submit" id="publish" tabindex="6" style="font-weight: bold;" value="<?php _e('Publish') ?>" />
 <?php endif; ?>
 
 <?php if ('bookmarklet' != $mode) {
-      echo '<input name="advanced" type="submit" id="advancededit" tabindex="7" value="' .  __('Advanced Editing &raquo;') . '" />';
-  } ?>
-  <input name="referredby" type="hidden" id="referredby" value="<?php if ( wp_get_referer() ) echo urlencode(wp_get_referer()); ?>" />
+		echo '<input name="advanced" type="submit" id="advancededit" tabindex="7" value="' .  __('Advanced Editing &raquo;') . '" />';
+	} ?>
+	<input name="referredby" type="hidden" id="referredby" value="<?php if ( $refby = wp_get_referer() ) echo urlencode($refby); ?>" />
 </p>
 
 <?php do_action('simple_edit_form', ''); ?>
diff -ruN 2.0.5/wp-admin/edit-link-form.php 2.2.2/wp-admin/edit-link-form.php
--- 2.0.5/wp-admin/edit-link-form.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-link-form.php	2007-03-06 23:29:15.000000000 -0600
@@ -1,15 +1,13 @@
 <?php
 if ( ! empty($link_id) ) {
-	$editing = true;
-	$heading = __('Edit a link:');
+	$heading = __('Edit Link');
 	$submit_text = __('Save Changes &raquo;');
-	$form = '<form action="" method="post" name="editlink" id="editlink">'; 
+	$form = '<form name="editlink" id="editlink" method="post" action="link.php">';
 	$nonce_action = 'update-bookmark_' . $link_id;
 } else {
-	$editing = false;
-	$heading = __('<strong>Add</strong> a link:');
+	$heading = __('Add Link');
 	$submit_text = __('Add Link &raquo;');
-	$form = '<form name="addlink" method="post" action="link-manager.php">';
+	$form = '<form name="addlink" id="addlink" method="post" action="link.php">';
 	$nonce_action = 'add-bookmark';
 }
 
@@ -24,216 +22,236 @@
 	}
 
 	if ('' == $value) {
-		if ('family' == $class && !strstr($link_rel, 'child') && !strstr($link_rel, 'parent') && !strstr($link_rel, 'sibling') && !strstr($link_rel, 'spouse') && !strstr($link_rel, 'kin')) echo ' checked="checked"';
-		if ('friendship' == $class && !strstr($link_rel, 'friend') && !strstr($link_rel, 'acquaintance') && !strstr($link_rel, 'contact') ) echo ' checked="checked"';
-		if ('geographical' == $class && !strstr($link_rel, 'co-resident') && !strstr($link_rel, 'neighbor') ) echo ' checked="checked"';
+		if ('family' == $class && strpos($link_rel, 'child') === false && strpos($link_rel, 'parent') === false && strpos($link_rel, 'sibling') === false && strpos($link_rel, 'spouse') === false && strpos($link_rel, 'kin') === false) echo ' checked="checked"';
+		if ('friendship' == $class && strpos($link_rel, 'friend') === false && strpos($link_rel, 'acquaintance') === false && strpos($link_rel, 'contact') === false) echo ' checked="checked"';
+		if ('geographical' == $class && strpos($link_rel, 'co-resident') === false && strpos($link_rel, 'neighbor') === false) echo ' checked="checked"';
 		if ('identity' == $class && in_array('me', $rels) ) echo ' checked="checked"';
 	}
 }
-
 ?>
 
-<div class="wrap"> 
-  <?php echo $form ?>
-  <?php wp_nonce_field($nonce_action); ?>
-  <h2><?php echo $heading ?></h2>
-<fieldset class="options">
-    <legend><?php _e('Basics') ?></legend>
-        <table class="editform" width="100%" cellspacing="2" cellpadding="5">
-         <tr>
-           <th width="33%" scope="row"><?php _e('URI:') ?></th>
-           <td width="67%"><input type="text" name="link_url" value="<?php echo $link->link_url; ?>" style="width: 95%;" /></td>
-         </tr>
-         <tr>
-           <th scope="row"><?php _e('Link Name:') ?></th>
-           <td><input type="text" name="link_name" value="<?php echo $link->link_name; ?>" style="width: 95%" /></td>
-         </tr>
-         <tr>
-            <th scope="row"><?php _e('Short description:') ?></th>
-         	<td><input type="text" name="link_description" value="<?php echo $link->link_description; ?>" style="width: 95%" /></td>
-         	</tr>
-        <tr>
-           <th scope="row"><?php _e('Category:') ?></th>
-           <td><?php link_category_dropdown('link_category', $link->link_category); ?></td>
-         </tr>
-</table>
+<div class="wrap">
+<h2><?php echo $heading ?></h2>
+<?php echo $form ?>
+<?php wp_nonce_field($nonce_action); ?>
+
+<div id="poststuff">
+<div id="moremeta">
+<div id="grabit" class="dbx-group">
+
+<fieldset id="categorydiv" class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Categories') ?></h3>
+<div class="dbx-content">
+<p id="jaxcat"></p>
+<ul id="categorychecklist"><?php dropdown_link_categories(get_option('default_link_category')); ?></ul>
+</div>
 </fieldset>
-       <p class="submit">
-       <input type="submit" name="submit" value="<?php echo $submit_text ?>" />
-       </p>
-	<fieldset class="options">
-        <legend><?php _e('Link Relationship (XFN)') ?></legend>
-        <table class="editform" width="100%" cellspacing="2" cellpadding="5">
-            <tr>
-                <th width="33%" scope="row"><?php _e('rel:') ?></th>
-            	<td width="67%"><input type="text" name="link_rel" id="link_rel" size="50" value="<?php echo $link->link_rel; ?>" /></td>
-           	</tr>
-            <tr>
-                <th scope="row"><?php _e('<a href="http://gmpg.org/xfn/">XFN</a> Creator:') ?></th>
-            	<td>
-					<table cellpadding="3" cellspacing="5">
-	          <tr>
-              <th scope="row"> <?php _e('identity') ?> </th>
-              <td>
-                <label for="me">
-                <input type="checkbox" name="identity" value="me" id="me" <?php xfn_check('identity', 'me'); ?> />
-          <?php _e('another web address of mine') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('friendship') ?> </th>
-              <td>
-			    <label for="contact">
-                <input class="valinp" type="radio" name="friendship" value="contact" id="contact" <?php xfn_check('friendship', 'contact', 'radio'); ?> /> <?php _e('contact') ?></label>
-                <label for="acquaintance">
-                <input class="valinp" type="radio" name="friendship" value="acquaintance" id="acquaintance" <?php xfn_check('friendship', 'acquaintance', 'radio'); ?> />  <?php _e('acquaintance') ?></label>
-                <label for="friend">
-                <input class="valinp" type="radio" name="friendship" value="friend" id="friend" <?php xfn_check('friendship', 'friend', 'radio'); ?> /> <?php _e('friend') ?></label>
-                <label for="friendship">
-                <input name="friendship" type="radio" class="valinp" value="" id="friendship" <?php xfn_check('friendship', '', 'radio'); ?> /> <?php _e('none') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('physical') ?> </th>
-              <td>
-                <label for="met">
-                <input class="valinp" type="checkbox" name="physical" value="met" id="met" <?php xfn_check('physical', 'met'); ?> />
-          <?php _e('met') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('professional') ?> </th>
-              <td>
-                <label for="co-worker">
-                <input class="valinp" type="checkbox" name="professional" value="co-worker" id="co-worker" <?php xfn_check('professional', 'co-worker'); ?> />
-          <?php _e('co-worker') ?></label>
-                <label for="colleague">
-                <input class="valinp" type="checkbox" name="professional" value="colleague" id="colleague" <?php xfn_check('professional', 'colleague'); ?> />
-          <?php _e('colleague') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('geographical') ?> </th>
-              <td>
-                <label for="co-resident">
-                <input class="valinp" type="radio" name="geographical" value="co-resident" id="co-resident" <?php xfn_check('geographical', 'co-resident', 'radio'); ?> />
-          <?php _e('co-resident') ?></label>
-                <label for="neighbor">
-                <input class="valinp" type="radio" name="geographical" value="neighbor" id="neighbor" <?php xfn_check('geographical', 'neighbor', 'radio'); ?> />
-          <?php _e('neighbor') ?></label>
-                <label for="geographical">
-                <input class="valinp" type="radio" name="geographical" value="" id="geographical" <?php xfn_check('geographical', '', 'radio'); ?> />
-          <?php _e('none') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('family') ?> </th>
-              <td>
-                <label for="child">
-                <input class="valinp" type="radio" name="family" value="child" id="child" <?php xfn_check('family', 'child', 'radio'); ?>  />
-          <?php _e('child') ?></label>
-                <label for="kin">
-                <input class="valinp" type="radio" name="family" value="kin" id="kin" <?php xfn_check('family', 'kin', 'radio'); ?>  />
-          <?php _e('kin') ?></label>
-                <label for="parent">
-                <input class="valinp" type="radio" name="family" value="parent" id="parent" <?php xfn_check('family', 'parent', 'radio'); ?> />
-          <?php _e('parent') ?></label>
-                <label for="sibling">
-                <input class="valinp" type="radio" name="family" value="sibling" id="sibling" <?php xfn_check('family', 'sibling', 'radio'); ?> />
-          <?php _e('sibling') ?></label>
-                <label for="spouse">
-                <input class="valinp" type="radio" name="family" value="spouse" id="spouse" <?php xfn_check('family', 'spouse', 'radio'); ?> />
-          <?php _e('spouse') ?></label>
-                <label for="family">
-                <input class="valinp" type="radio" name="family" value="" id="family" <?php xfn_check('family', '', 'radio'); ?> />
-          <?php _e('none') ?></label>
-              </td>
-            </tr>
-            <tr>
-              <th scope="row"> <?php _e('romantic') ?> </th>
-              <td>
-                <label for="muse">
-                <input class="valinp" type="checkbox" name="romantic" value="muse" id="muse" <?php xfn_check('romantic', 'muse'); ?> />
-         <?php _e('muse') ?></label>
-                <label for="crush">
-                <input class="valinp" type="checkbox" name="romantic" value="crush" id="crush" <?php xfn_check('romantic', 'crush'); ?> />
-         <?php _e('crush') ?></label>
-                <label for="date">
-                <input class="valinp" type="checkbox" name="romantic" value="date" id="date" <?php xfn_check('romantic', 'date'); ?> />
-         <?php _e('date') ?></label>
-                <label for="romantic">
-                <input class="valinp" type="checkbox" name="romantic" value="sweetheart" id="romantic" <?php xfn_check('romantic', 'sweetheart'); ?> />
-         <?php _e('sweetheart') ?></label>
-              </td>
-            </tr>
-        </table>
-		  </td>
-           	</tr>
-</table>
+
+<fieldset class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Target') ?></h3>
+<div class="dbx-content">
+<label for="link_target_blank" class="selectit">
+<input id="link_target_blank" type="radio" name="link_target" value="_blank" <?php echo(($link->link_target == '_blank') ? 'checked="checked"' : ''); ?> />
+<code>_blank</code></label>
+<label for="link_target_top" class="selectit">
+<input id="link_target_top" type="radio" name="link_target" value="_top" <?php echo(($link->link_target == '_top') ? 'checked="checked"' : ''); ?> />
+<code>_top</code></label>
+<label for="link_target_none" class="selectit">
+<input id="link_target_none" type="radio" name="link_target" value="" <?php echo(($link->link_target == '') ? 'checked="checked"' : ''); ?> />
+<?php _e('none') ?></label>
+</div>
 </fieldset>
-       <p class="submit">
-       <input type="submit" name="submit" value="<?php echo $submit_text ?>" />
-       </p>
-<fieldset class="options">
-        <legend><?php _e('Advanced') ?></legend>
-        <table class="editform" width="100%" cellspacing="2" cellpadding="5">
-         <tr>
-           <th width="33%" scope="row"><?php _e('Image URI:') ?></th>
-           <td width="67%"><input type="text" name="link_image" size="50" value="<?php echo $link->link_image; ?>" style="width: 95%" /></td>
-         </tr>
+
+<fieldset class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Visible') ?></h3>
+<div class="dbx-content">
+<label for="link_visible_yes" class="selectit">
+<input id="link_visible_yes" type="radio" name="link_visible" <?php if ($link->link_visible == 'Y') echo "checked='checked'"; ?> value="Y" />
+<?php _e('Yes') ?></label>
+<label for="link_visible_no" class="selectit">
+<input id="link_visible_no" type="radio" name="link_visible" <?php if ($link->link_visible == 'N') echo "checked='checked'"; ?> value="N" />
+<?php _e('No') ?></label>
+</div>
+</fieldset>
+
+</div>
+</div>
+
+<table class="editform" width="100%" cellspacing="2" cellpadding="5">
 <tr>
-           <th scope="row"><?php _e('RSS URI:') ?> </th>
-           <td><input name="link_rss" type="text" id="rss_uri" value="<?php echo $link->link_rss; ?>" size="50" style="width: 95%" /></td>
-         </tr>
-         <tr>
-           <th scope="row"><?php _e('Notes:') ?></th>
-           <td><textarea name="link_notes" cols="50" rows="10" style="width: 95%"><?php echo $link->link_notes; ?></textarea></td>
-         </tr>
-         <tr>
-           <th scope="row"><?php _e('Rating:') ?></th>
-           <td><select name="link_rating" size="1">
-<?php
-    for ($r = 0; $r < 10; $r++) {
-      echo('            <option value="'.$r.'" ');
-      if ($link->link_rating == $r)
-        echo 'selected="selected"';
-      echo('>'.$r.'</option>');
-    }
-?>
-           </select>
-         &nbsp;<?php _e('(Leave at 0 for no rating.)') ?> </td>
-         </tr>
-         <tr>
-           <th scope="row"><?php _e('Target') ?></th>
-           <td><label>
-          <input type="radio" name="link_target" value="_blank"   <?php echo(($link->link_target == '_blank') ? 'checked="checked"' : ''); ?> />
-          <code>_blank</code></label><br />
-<label>
-<input type="radio" name="link_target" value="_top" <?php echo(($link->link_target == '_top') ? 'checked="checked"' : ''); ?> />
-<code>_top</code></label><br />
-<label>
-<input type="radio" name="link_target" value=""     <?php echo(($link->link_target == '') ? 'checked="checked"' : ''); ?> />
-<?php _e('none') ?></label><br />
-<?php _e('(Note that the <code>target</code> attribute is illegal in XHTML 1.1 and 1.0 Strict.)') ?></td>
-         </tr>
-         <tr>
-           <th scope="row"><?php _e('Visible:') ?></th>
-           <td><label>
-             <input type="radio" name="link_visible" <?php if ($link->link_visible == 'Y') echo "checked='checked'"; ?> value="Y" />
-<?php _e('Yes') ?></label><br /><label>
-<input type="radio" name="link_visible" <?php if ($link->link_visible == 'N') echo "checked='checked'"; ?> value="N" />
-<?php _e('No') ?></label></td>
-         </tr>
+<th scope="row" valign="top"><label for="link_name"><?php _e('Name:') ?></label></th>
+<td><input type="text" name="link_name" value="<?php echo $link->link_name; ?>" style="width: 95%" /></td>
+</tr>
+<tr>
+<th width="20%" scope="row" valign="top"><label for="link_url"><?php _e('Address:') ?></label></th>
+<td width="80%"><input type="text" name="link_url" value="<?php echo $link->link_url; if ( empty( $link->link_url ) ) echo 'http://'; ?>" style="width: 95%" /></td>
+</tr>
+<tr>
+<th scope="row" valign="top"><label for="link_description"><?php _e('Description:') ?></label></th>
+<td><input type="text" name="link_description" value="<?php echo $link->link_description; ?>" style="width: 95%" /></td>
+</tr>
 </table>
+
+<p class="submit">
+<input type="submit" name="submit" value="<?php echo $submit_text ?>" />
+</p>
+
+<div id="advancedstuff" class="dbx-group" >
+
+<fieldset id="xfn" class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Link Relationship (XFN)') ?></h3>
+<div class="dbx-content">
+<table class="editform" width="100%" cellspacing="2" cellpadding="5">
+	<tr>
+		<th width="20%" scope="row"><?php _e('rel:') ?></th>
+		<td width="80%"><input type="text" name="link_rel" id="link_rel" size="50" value="<?php echo $link->link_rel; ?>" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('<a href="http://gmpg.org/xfn/">XFN</a> Creator:') ?></th>
+		<td>
+			<table cellpadding="3" cellspacing="5">
+				<tr>
+					<th scope="row"> <?php _e('identity') ?> </th>
+					<td>
+						<label for="me">
+						<input type="checkbox" name="identity" value="me" id="me" <?php xfn_check('identity', 'me'); ?> />
+						<?php _e('another web address of mine') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('friendship') ?> </th>
+					<td>
+						<label for="contact">
+						<input class="valinp" type="radio" name="friendship" value="contact" id="contact" <?php xfn_check('friendship', 'contact', 'radio'); ?> /> <?php _e('contact') ?></label>
+						<label for="acquaintance">
+						<input class="valinp" type="radio" name="friendship" value="acquaintance" id="acquaintance" <?php xfn_check('friendship', 'acquaintance', 'radio'); ?> />  <?php _e('acquaintance') ?></label>
+						<label for="friend">
+						<input class="valinp" type="radio" name="friendship" value="friend" id="friend" <?php xfn_check('friendship', 'friend', 'radio'); ?> /> <?php _e('friend') ?></label>
+						<label for="friendship">
+						<input name="friendship" type="radio" class="valinp" value="" id="friendship" <?php xfn_check('friendship', '', 'radio'); ?> /> <?php _e('none') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('physical') ?> </th>
+					<td>
+						<label for="met">
+						<input class="valinp" type="checkbox" name="physical" value="met" id="met" <?php xfn_check('physical', 'met'); ?> />
+						<?php _e('met') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('professional') ?> </th>
+					<td>
+						<label for="co-worker">
+						<input class="valinp" type="checkbox" name="professional" value="co-worker" id="co-worker" <?php xfn_check('professional', 'co-worker'); ?> />
+						<?php _e('co-worker') ?></label>
+						<label for="colleague">
+						<input class="valinp" type="checkbox" name="professional" value="colleague" id="colleague" <?php xfn_check('professional', 'colleague'); ?> />
+						<?php _e('colleague') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('geographical') ?> </th>
+					<td>
+						<label for="co-resident">
+						<input class="valinp" type="radio" name="geographical" value="co-resident" id="co-resident" <?php xfn_check('geographical', 'co-resident', 'radio'); ?> />
+						<?php _e('co-resident') ?></label>
+						<label for="neighbor">
+						<input class="valinp" type="radio" name="geographical" value="neighbor" id="neighbor" <?php xfn_check('geographical', 'neighbor', 'radio'); ?> />
+						<?php _e('neighbor') ?></label>
+						<label for="geographical">
+						<input class="valinp" type="radio" name="geographical" value="" id="geographical" <?php xfn_check('geographical', '', 'radio'); ?> />
+						<?php _e('none') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('family') ?> </th>
+					<td>
+						<label for="child">
+						<input class="valinp" type="radio" name="family" value="child" id="child" <?php xfn_check('family', 'child', 'radio'); ?>  />
+						<?php _e('child') ?></label>
+						<label for="kin">
+						<input class="valinp" type="radio" name="family" value="kin" id="kin" <?php xfn_check('family', 'kin', 'radio'); ?>  />
+						<?php _e('kin') ?></label>
+						<label for="parent">
+						<input class="valinp" type="radio" name="family" value="parent" id="parent" <?php xfn_check('family', 'parent', 'radio'); ?> />
+						<?php _e('parent') ?></label>
+						<label for="sibling">
+						<input class="valinp" type="radio" name="family" value="sibling" id="sibling" <?php xfn_check('family', 'sibling', 'radio'); ?> />
+						<?php _e('sibling') ?></label>
+						<label for="spouse">
+						<input class="valinp" type="radio" name="family" value="spouse" id="spouse" <?php xfn_check('family', 'spouse', 'radio'); ?> />
+						<?php _e('spouse') ?></label>
+						<label for="family">
+						<input class="valinp" type="radio" name="family" value="" id="family" <?php xfn_check('family', '', 'radio'); ?> />
+						<?php _e('none') ?></label>
+					</td>
+				</tr>
+				<tr>
+					<th scope="row"> <?php _e('romantic') ?> </th>
+					<td>
+						<label for="muse">
+						<input class="valinp" type="checkbox" name="romantic" value="muse" id="muse" <?php xfn_check('romantic', 'muse'); ?> />
+						<?php _e('muse') ?></label>
+						<label for="crush">
+						<input class="valinp" type="checkbox" name="romantic" value="crush" id="crush" <?php xfn_check('romantic', 'crush'); ?> />
+						<?php _e('crush') ?></label>
+						<label for="date">
+						<input class="valinp" type="checkbox" name="romantic" value="date" id="date" <?php xfn_check('romantic', 'date'); ?> />
+						<?php _e('date') ?></label>
+						<label for="romantic">
+						<input class="valinp" type="checkbox" name="romantic" value="sweetheart" id="romantic" <?php xfn_check('romantic', 'sweetheart'); ?> />
+						<?php _e('sweetheart') ?></label>
+					</td>
+				</tr>
+			</table>
+		</td>
+	</tr>
+</table>
+</div>
 </fieldset>
-<p class="submit"><input type="submit" name="submit" value="<?php echo $submit_text ?>" /></p>
-<?php if ( $editing ) : ?>
-          <input type="hidden" name="action" value="editlink" />
-          <input type="hidden" name="link_id" value="<?php echo (int) $link_id; ?>" />
-          <input type="hidden" name="order_by" value="<?php echo wp_specialchars($order_by, 1); ?>" />
-          <input type="hidden" name="cat_id" value="<?php echo (int) $cat_id ?>" />
+
+<fieldset id="advanced" class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Advanced') ?></h3>
+<div class="dbx-content">
+<table class="editform" width="100%" cellspacing="2" cellpadding="5">
+	<tr>
+		<th width="20%" scope="row"><?php _e('Image Address:') ?></th>
+		<td width="80%"><input type="text" name="link_image" size="50" value="<?php echo $link->link_image; ?>" style="width: 95%" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('RSS Address:') ?> </th>
+		<td><input name="link_rss" type="text" id="rss_uri" value="<?php echo $link->link_rss; ?>" size="50" style="width: 95%" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('Notes:') ?></th>
+		<td><textarea name="link_notes" cols="50" rows="10" style="width: 95%"><?php echo $link->link_notes; ?></textarea></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('Rating:') ?></th>
+		<td><select name="link_rating" size="1">
+		<?php
+			for ($r = 0; $r < 10; $r++) {
+				echo('            <option value="'.$r.'" ');
+				if ($link->link_rating == $r)
+					echo 'selected="selected"';
+				echo('>'.$r.'</option>');
+			}
+		?></select>&nbsp;<?php _e('(Leave at 0 for no rating.)') ?>
+		</td>
+	</tr>
+</table>
+</fieldset>
+</div>
+
+<?php if ( $link_id ) : ?>
+<input type="hidden" name="action" value="save" />
+<input type="hidden" name="link_id" value="<?php echo (int) $link_id; ?>" />
+<input type="hidden" name="order_by" value="<?php echo attribute_escape($order_by); ?>" />
+<input type="hidden" name="cat_id" value="<?php echo (int) $cat_id ?>" />
 <?php else: ?>
-       	<input type="hidden" name="action" value="Add" />
+<input type="hidden" name="action" value="add" />
 <?php endif; ?>
-</form> 
-</div>
\ No newline at end of file
+</div>
+</form>
+</div>
diff -ruN 2.0.5/wp-admin/edit-page-form.php 2.2.2/wp-admin/edit-page-form.php
--- 2.0.5/wp-admin/edit-page-form.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-page-form.php	2007-05-28 23:37:35.000000000 -0500
@@ -1,40 +1,43 @@
 
 <div class="wrap">
-<h2 id="write-post"><?php _e('Write Page'); ?><?php if ( 0 != $post_ID ) : ?>
-<small class="quickjump"><a href="#preview-post"><?php _e('preview &darr;'); ?></a></small><?php endif; ?></h2>
+<h2 id="write-post"><?php _e('Write Page'); ?></h2>
 <?php
+
 if (0 == $post_ID) {
 	$form_action = 'post';
-	$nonce_action = 'add-post';
-	$temp_ID = -1 * time();
-	$form_extra = "<input type='hidden' name='temp_ID' value='$temp_ID' />";
+	$nonce_action = 'add-page';
+	$temp_ID = -1 * time(); // don't change this formula without looking at wp_write_post()
+	$form_extra = "<input type='hidden' id='post_ID' name='temp_ID' value='$temp_ID' />";
 } else {
+	$post_ID = (int) $post_ID;
 	$form_action = 'editpost';
-	$nonce_action = 'update-post_' . $post_ID;
+	$nonce_action = 'update-page_' . $post_ID;
 	$form_extra = "<input type='hidden' id='post_ID' name='post_ID' value='$post_ID' />";
 }
 
-$sendto = wp_get_referer();
+$temp_ID = (int) $temp_ID;
+$user_ID = (int) $user_ID;
 
-if ( 0 != $post_ID && $sendto == get_permalink($post_ID) )
- 	$sendto = 'redo';
-$sendto = wp_specialchars( $sendto );
+$sendto = clean_url(stripslashes(wp_get_referer()));
 
+if ( 0 != $post_ID && $sendto == get_permalink($post_ID) )
+	$sendto = 'redo';
 ?>
 
-<form name="post" action="post.php" method="post" id="post">
+<form name="post" action="page.php" method="post" id="post">
 
 <?php
 wp_nonce_field($nonce_action);
 
 if (isset($mode) && 'bookmarklet' == $mode) {
-    echo '<input type="hidden" name="mode" value="bookmarklet" />';
+	echo '<input type="hidden" name="mode" value="bookmarklet" />';
 }
 ?>
 <input type="hidden" name="user_ID" value="<?php echo $user_ID ?>" />
 <input type="hidden" id="hiddenaction" name="action" value='<?php echo $form_action ?>' />
+<input type="hidden" id="originalaction" name="originalaction" value="<?php echo $form_action ?>" />
 <?php echo $form_extra ?>
-<input type="hidden" name="post_status" value="static" />
+<input type="hidden" id="post_type" name="post_type" value="page" />
 
 <script type="text/javascript">
 // <![CDATA[
@@ -54,18 +57,27 @@
 <input name="advanced_view" type="hidden" value="1" />
 <label for="comment_status" class="selectit">
 <input name="comment_status" type="checkbox" id="comment_status" value="open" <?php checked($post->comment_status, 'open'); ?> />
-<?php _e('Allow Comments') ?></label> 
+<?php _e('Allow Comments') ?></label>
 <label for="ping_status" class="selectit"><input name="ping_status" type="checkbox" id="ping_status" value="open" <?php checked($post->ping_status, 'open'); ?> /> <?php _e('Allow Pings') ?></label>
 </div>
 </fieldset>
 
+<fieldset class="dbx-box">
+<h3 class="dbx-handle"><?php _e('Page Status') ?></h3>
+<div class="dbx-content"><?php if ( current_user_can('publish_pages') ) : ?>
+<label for="post_status_publish" class="selectit"><input id="post_status_publish" name="post_status" type="radio" value="publish" <?php checked($post->post_status, 'publish'); checked($post->post_status, 'future'); ?> /> <?php _e('Published') ?></label>
+<?php endif; ?>
+	  <label for="post_status_draft" class="selectit"><input id="post_status_draft" name="post_status" type="radio" value="draft" <?php checked($post->post_status, 'draft'); ?> /> <?php _e('Draft') ?></label>
+	  <label for="post_status_private" class="selectit"><input id="post_status_private" name="post_status" type="radio" value="private" <?php checked($post->post_status, 'private'); ?> /> <?php _e('Private') ?></label></div>
+</fieldset>
+
 <fieldset id="passworddiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Password-Protect Post') ?></h3> 
-<div class="dbx-content"><input name="post_password" type="text" size="13" id="post_password" value="<?php echo $post->post_password ?>" /></div>
+<h3 class="dbx-handle"><?php _e('Page Password') ?></h3>
+<div class="dbx-content"><input name="post_password" type="text" size="13" id="post_password" value="<?php echo attribute_escape( $post->post_password ); ?>" /></div>
 </fieldset>
 
 <fieldset id="pageparent" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Page Parent') ?></h3> 
+<h3 class="dbx-handle"><?php _e('Page Parent') ?></h3>
 <div class="dbx-content"><p><select name="parent_id">
 <option value='0'><?php _e('Main Page (no parent)'); ?></option>
 <?php parent_dropdown($post->post_parent); ?>
@@ -75,7 +87,7 @@
 
 <?php if ( 0 != count( get_page_templates() ) ) { ?>
 <fieldset id="pagetemplate" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Page Template:') ?></h3> 
+<h3 class="dbx-handle"><?php _e('Page Template') ?></h3>
 <div class="dbx-content"><p><select name="page_template">
 		<option value='default'><?php _e('Default Template'); ?></option>
 		<?php page_template_dropdown($post->page_template); ?>
@@ -85,20 +97,22 @@
 <?php } ?>
 
 <fieldset id="slugdiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Post slug') ?></h3> 
-<div class="dbx-content"><input name="post_name" type="text" size="13" id="post_name" value="<?php echo $post->post_name ?>" /></div>
+<h3 class="dbx-handle"><?php _e('Page Slug') ?></h3>
+<div class="dbx-content"><input name="post_name" type="text" size="13" id="post_name" value="<?php echo attribute_escape( $post->post_name ); ?>" /></div>
 </fieldset>
 
 <?php if ( $authors = get_editable_authors( $current_user->id ) ) : // TODO: ROLE SYSTEM ?>
 <fieldset id="authordiv" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Post author'); ?>:</h3>
+<h3 class="dbx-handle"><?php _e('Page Author'); ?></h3>
 <div class="dbx-content">
 <select name="post_author_override" id="post_author_override">
-<?php 
+<?php
 foreach ($authors as $o) :
 $o = get_userdata( $o->ID );
 if ( $post->post_author == $o->ID || ( empty($post_ID) && $user_ID == $o->ID ) ) $selected = 'selected="selected"';
 else $selected = '';
+$o->ID = (int) $o->ID;
+$o->display_name = wp_specialchars( $o->display_name );
 echo "<option value='$o->ID' $selected>$o->display_name</option>";
 endforeach;
 ?>
@@ -108,7 +122,7 @@
 <?php endif; ?>
 
 <fieldset id="pageorder" class="dbx-box">
-<h3 class="dbx-handle"><?php _e('Page Order') ?></h3> 
+<h3 class="dbx-handle"><?php _e('Page Order') ?></h3>
 <div class="dbx-content"><p><input name="menu_order" type="text" size="4" id="menu_order" value="<?php echo $post->menu_order ?>" /></p></div>
 </fieldset>
 
@@ -118,70 +132,33 @@
 </div>
 
 <fieldset id="titlediv">
-  <legend><?php _e('Page Title') ?></legend> 
-  <div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo $post->post_title; ?>" id="title" /></div>
+  <legend><?php _e('Page Title') ?></legend>
+  <div><input type="text" name="post_title" size="30" tabindex="1" value="<?php echo attribute_escape( $post->post_title ); ?>" id="title" /></div>
 </fieldset>
 
 
 <fieldset id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>">
-    <legend><?php _e('Page Content') ?></legend>
-<?php
- $rows = get_settings('default_post_edit_rows');
- if (($rows < 3) || ($rows > 100)) {
-     $rows = 10;
- }
-?>
-<?php the_quicktags(); ?>
+<legend><?php _e('Page Content') ?>
 
-<div><textarea title="true" rows="<?php echo $rows; ?>" cols="40" name="content" tabindex="4" id="content"><?php echo user_can_richedit() ? wp_richedit_pre($post->post_content) : $post->post_content; ?></textarea></div>
+<?php if ( 'publish' == $post->post_status ) { ?>
+<a href="<?php echo clean_url(get_permalink($post->ID)); ?>" style="position: absolute; right: 2em; margin-right: 19em; text-decoration: underline;" target="_blank"><?php _e('View &raquo;'); ?></a>
+<?php } elseif ( 'edit' == $action ) { ?>
+<a href="<?php echo clean_url(apply_filters('preview_post_link', add_query_arg('preview', 'true', get_permalink($post->ID)))); ?>" style="position: absolute; right: 2em; margin-right: 19em; text-decoration: underline;" target="_blank"><?php _e('Preview &raquo;'); ?></a>
+<?php } ?>
+</legend>
+	<?php the_editor($post->post_content); ?>
 </fieldset>
 
-<script type="text/javascript">
-<!--
-edCanvas = document.getElementById('content');
-<?php if ( user_can_richedit() ) : ?>
-// This code is meant to allow tabbing from Title to Post (TinyMCE).
-if ( tinyMCE.isMSIE )
-	document.getElementById('title').onkeydown = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-else
-	document.getElementById('title').onkeypress = function (e)
-		{
-			e = e ? e : window.event;
-			if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
-				var i = tinyMCE.selectedInstance;
-				if(typeof i ==  'undefined')
-					return true;
-                                tinyMCE.execCommand("mceStartTyping");
-				this.blur();
-				i.contentWindow.focus();
-				e.returnValue = false;
-				return false;
-			}
-		}
-<?php endif; ?>
-//-->
-</script>
-
 <p class="submit">
-<?php if ( $post_ID ) : ?>
-<input name="save" type="submit" id="save" tabindex="5" value=" <?php _e('Save and Continue Editing'); ?> "/> 
-<input name="savepage" type="submit" id="savepage" tabindex="6" value="<?php $post_ID ? _e('Save') : _e('Create New Page') ?> &raquo;" /> 
-<?php else : ?>
-<input name="savepage" type="submit" id="savepage" tabindex="6" value="<?php _e('Create New Page') ?> &raquo;" /> 
-<?php endif; ?>
+<span id="autosave"></span>
+<input name="save" type="submit" id="save" tabindex="3" value="<?php _e('Save and Continue Editing'); ?>" />
+<input type="submit" name="submit" value="<?php _e('Save') ?>" style="font-weight: bold;" tabindex="4" />
+<?php
+if ('publish' != $post->post_status || 0 == $post_ID):
+?>
+<?php if ( current_user_can('publish_pages') ) : ?>
+	<input name="publish" type="submit" id="publish" tabindex="5" accesskey="p" value="<?php _e('Publish') ?>" />
+<?php endif; endif;?>
 <input name="referredby" type="hidden" id="referredby" value="<?php echo $sendto; ?>" />
 </p>
 
@@ -190,7 +167,7 @@
 <?php
 if (current_user_can('upload_files')) {
 	$uploading_iframe_ID = (0 == $post_ID ? $temp_ID : $post_ID);
-	$uploading_iframe_src = wp_nonce_url("inline-uploading.php?action=view&amp;post=$uploading_iframe_ID", 'inlineuploading');
+	$uploading_iframe_src = wp_nonce_url("upload.php?style=inline&amp;tab=upload&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
 	$uploading_iframe_src = apply_filters('uploading_iframe_src', $uploading_iframe_src);
 	if ( false != $uploading_iframe_src )
 		echo '<iframe id="uploading" frameborder="0" src="' . $uploading_iframe_src . '">' . __('This feature requires iframe support.') . '</iframe>';
@@ -202,14 +179,14 @@
 <fieldset id="postcustom" class="dbx-box">
 <h3 class="dbx-handle"><?php _e('Custom Fields') ?></h3>
 <div id="postcustomstuff" class="dbx-content">
-<?php 
-if($metadata = has_meta($post_ID)) {
-?>
+<table cellpadding="3">
 <?php
-	list_meta($metadata); 
+$metadata = has_meta($post_ID);
+list_meta($metadata);
 ?>
+
+</table>
 <?php
-}
 	meta_form();
 ?>
 </div>
@@ -221,8 +198,9 @@
 </div>
 
 <?php if ('edit' == $action) :
-	$delete_nonce = wp_create_nonce( 'delete-page_' . $post_ID ); ?>
-	<input name="deletepost" class="button" type="submit" id="deletepost" tabindex="10" value="<?php _e('Delete this page') ?>" <?php echo "onclick=\"if ( confirm('" . sprintf(__("You are about to delete this page \'%s\'\\n  \'Cancel\' to stop, \'OK\' to delete."), js_escape($post->post_title) ) . "') ) { document.forms.post._wpnonce.value = '$delete_nonce'; return true;}return false;\""; ?> />
+	$delete_nonce = wp_create_nonce( 'delete-page_' . $post_ID );
+	if ( current_user_can('delete_page', $post->ID) ) ?>
+		<input name="deletepost" class="button delete" type="submit" id="deletepost" tabindex="10" value="<?php _e('Delete this page') ?>" <?php echo "onclick=\"if ( confirm('" . js_escape(sprintf(__("You are about to delete this page '%s'\n  'Cancel' to stop, 'OK' to delete."), $post->post_title )) . "') ) { document.forms.post._wpnonce.value = '$delete_nonce'; return true;}return false;\""; ?> />
 <?php endif; ?>
 </div>
 
diff -ruN 2.0.5/wp-admin/edit-pages.php 2.2.2/wp-admin/edit-pages.php
--- 2.0.5/wp-admin/edit-pages.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit-pages.php	2007-02-21 19:59:33.000000000 -0600
@@ -2,65 +2,48 @@
 require_once('admin.php');
 $title = __('Pages');
 $parent_file = 'edit.php';
-$list_js = true;
+wp_enqueue_script( 'listman' );
 require_once('admin-header.php');
 ?>
 
 <div class="wrap">
 <h2><?php _e('Page Management'); ?></h2>
-<p><?php _e('Pages are like posts except they live outside of the normal blog chronology and can be hierarchical. You can use pages to organize and manage any amount of content.'); ?> <a href="page-new.php"><?php _e('Create a new page'); ?> &raquo;</a></p>
+<p><?php _e('Pages are like posts except they live outside of the normal blog chronology and can be hierarchical. You can use pages to organize and manage any amount of content.'); ?> <a href="page-new.php"><?php _e('Create a new page &raquo;'); ?></a></p>
 
-<form name="searchform" action="" method="get"> 
-  <fieldset> 
-  <legend><?php _e('Search Pages&hellip;') ?></legend>
-  <input type="text" name="s" value="<?php if (isset($_GET['s'])) echo wp_specialchars($_GET['s'], 1); ?>" size="17" /> 
-  <input type="submit" name="submit" value="<?php _e('Search') ?>"  /> 
-  </fieldset>
+<form name="searchform" action="" method="get">
+	<fieldset>
+	<legend><?php _e('Search Pages&hellip;') ?></legend>
+	<input type="text" name="s" value="<?php if (isset($_GET['s'])) echo attribute_escape($_GET['s']); ?>" size="17" />
+	<input type="submit" name="submit" value="<?php _e('Search') ?>"  />
+	</fieldset>
 </form>
 
 <?php
+wp('post_type=page&orderby=menu_order&what_to_show=posts&posts_per_page=-1&posts_per_archive_page=-1&order=asc');
 
-$show_post_type = 'page';
-
-if ( isset($_GET['s']) )
-	wp();
+if ( $_GET['s'] )
+	$all = false;
 else
-	$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'static'");
+	$all = true;
 
 if ($posts) {
 ?>
-<table id="the-list-x" width="100%" cellpadding="3" cellspacing="3"> 
-  <tr> 
-    <th scope="col"><?php _e('ID') ?></th> 
-    <th scope="col"><?php _e('Title') ?></th> 
+<table class="widefat"> 
+  <thead>
+  <tr>
+    <th scope="col" style="text-align: center"><?php _e('ID') ?></th>
+    <th scope="col"><?php _e('Title') ?></th>
     <th scope="col"><?php _e('Owner') ?></th>
 	<th scope="col"><?php _e('Updated') ?></th>
-	<th scope="col"></th> 
-    <th scope="col"></th> 
-    <th scope="col"></th> 
-  </tr> 
-<?php
-if ( isset($_GET['s']) ) {
-foreach ( $posts as $post ) : 
-	$class = ('alternate' != $class) ? 'alternate' : ''; ?>
-  <tr id='page-<?php echo $post->ID; ?>' class='<?php echo $class; ?>'> 
-    <th scope="row"><?php echo $post->ID; ?></th> 
-    <td>
-      <?php echo $pad; ?><?php the_title() ?> 
-    </td> 
-    <td><?php the_author() ?></td>
-    <td><?php echo mysql2date('Y-m-d g:i a', $post->post_modified); ?></td> 
-	<td><a href="<?php the_permalink(); ?>" rel="permalink" class="edit"><?php _e('View'); ?></a></td>
-    <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='post.php?action=edit&amp;post=$post->ID' class='edit'>" . __('Edit') . "</a>"; } ?></td> 
-    <td><?php if ( current_user_can('edit_pages') ) { echo "<a href='" . wp_nonce_url("post.php?action=delete&amp;post=$post->ID", 'delete-post_' . $post->ID) . "' class='delete' onclick=\"return deleteSomething( 'page', " . $id . ", '" . sprintf(__("You are about to delete the &quot;%s&quot; page.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape(get_the_title('','',0))) . "' );\">" . __('Delete') . "</a>"; } ?></td> 
+	<th scope="col" colspan="3" style="text-align: center"><?php _e('Action'); ?></th>
   </tr>
+  </thead>
+  <tbody id="the-list">
 <?php
-endforeach;
-} else {
-	page_rows();
-}
+page_rows(0, 0, $posts, $all);
 ?>
-</table> 
+  </tbody>
+</table>
 
 <div id="ajax-response"></div>
 
@@ -70,10 +53,10 @@
 <p><?php _e('No pages yet.') ?></p>
 <?php
 } // end if ($posts)
-?> 
+?>
 
-<h3><a href="page-new.php"><?php _e('Create New Page'); ?> &raquo;</a></h3>
+<h3><a href="page-new.php"><?php _e('Create New Page &raquo;'); ?></a></h3>
 
 </div>
 
-<?php include('admin-footer.php'); ?> 
+<?php include('admin-footer.php'); ?>
diff -ruN 2.0.5/wp-admin/edit.php 2.2.2/wp-admin/edit.php
--- 2.0.5/wp-admin/edit.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/edit.php	2007-03-23 18:06:45.000000000 -0500
@@ -3,7 +3,7 @@
 
 $title = __('Posts');
 $parent_file = 'edit.php';
-$list_js = true;
+wp_enqueue_script( 1 == $_GET['c'] ? 'admin-comments' : 'listman' );
 require_once('admin-header.php');
 
 $_GET['m'] = (int) $_GET['m'];
@@ -12,40 +12,40 @@
 $other_drafts = get_others_drafts( $user_ID);
 
 if ($drafts || $other_drafts) {
-?> 
+?>
 <div class="wrap">
 <?php if ($drafts) { ?>
-    <p><strong><?php _e('Your Drafts:') ?></strong> 
-    <?php
+	<p><strong><?php _e('Your Drafts:') ?></strong>
+	<?php
 	$i = 0;
 	foreach ($drafts as $draft) {
 		if (0 != $i)
 			echo ', ';
-		$draft->post_title = stripslashes($draft->post_title);
+		$draft->post_title = apply_filters('the_title', stripslashes($draft->post_title));
 		if ($draft->post_title == '')
 			$draft->post_title = sprintf(__('Post #%s'), $draft->ID);
 		echo "<a href='post.php?action=edit&amp;post=$draft->ID' title='" . __('Edit this draft') . "'>$draft->post_title</a>";
 		++$i;
 		}
-	?> 
-    .</p> 
+	?>
+.</p>
 <?php } ?>
 
-<?php if ($other_drafts) { ?> 
-    <p><strong><?php _e('Other&#8217;s Drafts:') ?></strong> 
-    <?php
+<?php if ($other_drafts) { ?>
+	<p><strong><?php _e('Other&#8217;s Drafts:') ?></strong>
+	<?php
 	$i = 0;
 	foreach ($other_drafts as $draft) {
 		if (0 != $i)
 			echo ', ';
-		$draft->post_title = stripslashes($draft->post_title);
+		$draft->post_title = apply_filters('the_title', stripslashes($draft->post_title));
 		if ($draft->post_title == '')
 			$draft->post_title = sprintf(__('Post #%s'), $draft->ID);
 		echo "<a href='post.php?action=edit&amp;post=$draft->ID' title='" . __('Edit this draft') . "'>$draft->post_title</a>";
 		++$i;
 		}
-	?> 
-    .</p> 
+	?>
+	.</p>
 
 <?php } ?>
 
@@ -55,11 +55,8 @@
 <div class="wrap">
 <h2>
 <?php
-$what_to_show = 'posts';
-$posts_per_page = 15;
-$posts_per_archive_page = -1;
 
-wp();
+wp('what_to_show=posts&posts_per_page=15&posts_per_archive_page=-1');
 
 if ( is_month() ) {
 	single_month_title(' ');
@@ -67,7 +64,7 @@
 	printf(__('Search for &#8220;%s&#8221;'), wp_specialchars($_GET['s']) );
 } else {
 	if ( is_single() )
-		printf(__('Comments on %s'), $post->post_title);
+		printf(__('Comments on %s'), apply_filters( "the_title", $post->post_title));
 	elseif ( ! is_paged() || get_query_var('paged') == 1 )
 		_e('Last 15 Posts');
 	else
@@ -76,56 +73,66 @@
 ?>
 </h2>
 
-<form name="searchform" action="" method="get" style="float: left; width: 16em; margin-right: 3em;"> 
+<form name="searchform" id="searchform" action="" method="get">
   <fieldset> 
   <legend><?php _e('Search Posts&hellip;') ?></legend> 
-  <input type="text" name="s" value="<?php if (isset($s)) echo wp_specialchars($s, 1); ?>" size="17" /> 
-  <input type="submit" name="submit" value="<?php _e('Search') ?>"  /> 
+  <input type="text" name="s" value="<?php if (isset($s)) echo attribute_escape($s); ?>" size="17" /> 
+  <input type="submit" name="submit" value="<?php _e('Search') ?>" class="button" /> 
   </fieldset>
 </form>
 
-<?php $arc_result = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_date != '0000-00-00 00:00:00' ORDER BY post_date DESC");
+<?php $arc_result = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = 'post' ORDER BY post_date DESC");
 
 if ( count($arc_result) ) { ?>
 
-<form name="viewarc" action="" method="get" style="float: left; width: 20em; margin-bottom: 1em;">
+<form name="viewarc" id="viewarc" action="" method="get">
 	<fieldset>
 	<legend><?php _e('Browse Month&hellip;') ?></legend>
-    <select name='m'>
+	<select name='m'>
 	<?php
-		foreach ($arc_result as $arc_row) {			
-			$arc_year  = $arc_row->yyear;
-			$arc_month = $arc_row->mmonth;
-			
-			if( isset($_GET['m']) && $arc_year . zeroise($arc_month, 2) == (int) $_GET['m'] )
+		foreach ($arc_result as $arc_row) {
+			if ( $arc_row->yyear == 0 )
+				continue;
+			$arc_row->mmonth = zeroise($arc_row->mmonth, 2);
+
+			if( isset($_GET['m']) && $arc_row->yyear . $arc_row->mmonth == (int) $_GET['m'] )
 				$default = 'selected="selected"';
 			else
 				$default = null;
-			
-			echo "<option $default value=\"" . $arc_year.zeroise($arc_month, 2) . '">';
-			echo $month[zeroise($arc_month, 2)] . " $arc_year";
+
+			echo "<option $default value='$arc_row->yyear$arc_row->mmonth'>";
+			echo $wp_locale->get_month($arc_row->mmonth) . " $arc_row->yyear";
 			echo "</option>\n";
 		}
 	?>
 	</select>
-		<input type="submit" name="submit" value="<?php _e('Show Month') ?>"  /> 
+		<input type="submit" name="submit" value="<?php _e('Show Month') ?>" class="button" /> 
 	</fieldset>
 </form>
 
 <?php } ?>
 
+<form name="viewcat" id="viewcat" action="" method="get">
+	<fieldset>
+	<legend><?php _e('Browse Category&hellip;') ?></legend>
+	<?php wp_dropdown_categories('show_option_all='.__('All').'&hide_empty=1&hierarchical=1&show_count=1&selected='.$cat);?>
+	<input type="submit" name="submit" value="<?php _e('Show Category') ?>" class="button" /> 
+	</fieldset>
+</form>
+
+<?php do_action('restrict_manage_posts'); ?>
+
 <br style="clear:both;" />
 
 <?php
-
 // define the columns to display, the syntax is 'internal name' => 'display name'
 $posts_columns = array(
-  'id'         => __('ID'),
-  'date'       => __('When'),
-  'title'      => __('Title'),
-  'categories' => __('Categories'),
-  'comments'   => __('Comments'),
-  'author'     => __('Author')
+	'id'         => '<div style="text-align: center">' . __('ID') . '</div>',
+	'date'       => __('When'),
+	'title'      => __('Title'),
+	'categories' => __('Categories'),
+	'comments'   => '<div style="text-align: center">' . __('Comments') . '</div>',
+	'author'     => __('Author')
 );
 $posts_columns = apply_filters('manage_posts_columns', $posts_columns);
 
@@ -136,7 +143,8 @@
 
 ?>
 
-<table id="the-list-x" width="100%" cellpadding="3" cellspacing="3"> 
+<table class="widefat">
+	<thead>
 	<tr>
 
 <?php foreach($posts_columns as $column_display_name) { ?>
@@ -144,12 +152,15 @@
 <?php } ?>
 
 	</tr>
+	</thead>
+	<tbody id="the-list">
 <?php
 if ($posts) {
 $bgcolor = '';
-foreach ($posts as $post) { start_wp();
+while (have_posts()) : the_post();
+add_filter('the_title','wp_specialchars');
 $class = ('alternate' == $class) ? '' : 'alternate';
-?> 
+?>
 	<tr id='post-<?php echo $id; ?>' class='<?php echo $class; ?>'>
 
 <?php
@@ -157,16 +168,16 @@
 foreach($posts_columns as $column_name=>$column_display_name) {
 
 	switch($column_name) {
-	
+
 	case 'id':
 		?>
-		<th scope="row"><?php echo $id ?></th>
+		<th scope="row" style="text-align: center"><?php echo $id ?></th>
 		<?php
 		break;
 
 	case 'date':
 		?>
-		<td><?php the_time('Y-m-d \<\b\r \/\> g:i:s a'); ?></td>
+		<td><?php if ( '0000-00-00 00:00:00' ==$post->post_modified ) _e('Unpublished'); else the_time(__('Y-m-d \<\b\r \/\> g:i:s a')); ?></td>
 		<?php
 		break;
 	case 'title':
@@ -184,9 +195,9 @@
 
 	case 'comments':
 		?>
-		<td><a href="edit.php?p=<?php echo $id ?>&amp;c=1"> 
-      <?php comments_number(__('0'), __('1'), __('%')) ?> 
-      </a></td>
+		<td style="text-align: center">
+			<?php comments_number(__('0'), "<a href='edit.php?p=$id&amp;c=1'>" . __('1') . '</a>', "<a href='edit.php?p=$id&amp;c=1'>" . __('%') . '</a>') ?>
+			</td>
 		<?php
 		break;
 
@@ -210,7 +221,7 @@
 
 	case 'control_delete':
 		?>
-		<td><?php if ( current_user_can('edit_post',$post->ID) ) { echo "<a href='" . wp_nonce_url("post.php?action=delete&amp;post=$id", 'delete-post_' . $post->ID) . "' class='delete' onclick=\"return deleteSomething( 'post', " . $id . ", '" . sprintf(__("You are about to delete this post &quot;%s&quot;.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), js_escape(get_the_title())) . "' );\">" . __('Delete') . "</a>"; } ?></td>
+		<td><?php if ( current_user_can('delete_post',$post->ID) ) { echo "<a href='" . wp_nonce_url("post.php?action=delete&amp;post=$id", 'delete-post_' . $post->ID) . "' class='delete' onclick=\"return deleteSomething( 'post', " . $id . ", '" . js_escape(sprintf(__("You are about to delete this post '%s'.\n'OK' to delete, 'Cancel' to stop."), get_the_title())) . "' );\">" . __('Delete') . "</a>"; } ?></td>
 		<?php
 		break;
 
@@ -224,7 +235,7 @@
 ?>
 	</tr> 
 <?php
-}
+endwhile;
 } else {
 ?>
   <tr style='background-color: <?php echo $bgcolor; ?>'> 
@@ -232,7 +243,8 @@
   </tr> 
 <?php
 } // end if ($posts)
-?> 
+?>
+	</tbody>
 </table>
 
 <div id="ajax-response"></div>
@@ -247,54 +259,48 @@
 
 	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $id AND comment_approved != 'spam' ORDER BY comment_date");
 	if ($comments) {
-	?> 
-<h3><?php _e('Comments') ?></h3> 
-<ol id="comments"> 
+	?>
+<h3 id="comments"><?php _e('Comments') ?></h3>
+<ol id="the-comment-list" class="commentlist">
 <?php
+$i = 0;
 foreach ($comments as $comment) {
-$comment_status = wp_get_comment_status($comment->comment_ID);
-?> 
 
-<li <?php if ("unapproved" == $comment_status) echo "class='unapproved'"; ?> >
-  <?php comment_date('Y-n-j') ?> 
-  @
-  <?php comment_time('g:m:s a') ?> 
-  <?php 
-			if ( current_user_can('edit_post', $post->ID) ) {
-				echo "[ <a href=\"post.php?action=editcomment&amp;comment=".$comment->comment_ID."\">" .  __('Edit') . "</a>";
-				echo ' - <a href="' . wp_nonce_url('post.php?action=deletecomment&amp;p=' . $post->ID . '&amp;comment=' . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . '" onclick="return confirm(\'' . __("You are about to delete this comment.\\n&quot;Cancel&quot; to stop, &quot;OK&quot; to delete.") . "');\">" . __('Delete') . '</a> ';
-
-				if ( ('none' != $comment_status) && ( current_user_can('moderate_comments') ) ) {
-					if ('approved' == wp_get_comment_status($comment->comment_ID)) {
-						echo ' - <a href="' . wp_nonce_url('post.php?action=unapprovecomment&amp;p=' . $post->ID . '&amp;comment=' . $comment->comment_ID, 'unapprove-comment_' . $comment->comment_ID) . '">' . __('Unapprove') . '</a> ';
-					} else {
-						echo ' - <a href="' . wp_nonce_url('post.php?action=approvecomment&amp;p=' . $post->ID . '&amp;comment=' . $comment->comment_ID, 'approve-comment_' . $comment->comment_ID) . '">' . __('Approve') . '</a> ';
-					}
-				}
-				echo "]";
-			} // end if any comments to show
-			?> 
-  <br /> 
-  <strong> 
-  <?php comment_author() ?> 
-  (
-  <?php comment_author_email_link() ?> 
-  /
-  <?php comment_author_url_link() ?> 
-  )</strong> (IP:
-  <?php comment_author_IP() ?> 
-  )
-  <?php comment_text() ?> 
+		++$i; $class = '';
+		$authordata = get_userdata($wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = $comment->comment_post_ID"));
+			$comment_status = wp_get_comment_status($comment->comment_ID);
+			if ('unapproved' == $comment_status)
+				$class .= ' unapproved';
+			if ($i % 2)
+				$class .= ' alternate';
+			echo "<li id='comment-$comment->comment_ID' class='$class'>";
+?>
+<p><strong><?php comment_author() ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
+
+<?php comment_text() ?>
+
+<p><?php comment_date(__('M j, g:i A'));  ?> &#8212; [
+<?php
+if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
+	echo " <a href='comment.php?action=editcomment&amp;c=".$comment->comment_ID."'>" .  __('Edit') . '</a>';
+	echo ' | <a href="' . wp_nonce_url('comment.php?action=deletecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . '" onclick="return deleteSomething( \'comment\', ' . $comment->comment_ID . ', \'' . js_escape(sprintf(__("You are about to delete this comment by '%s'.\n'Cancel' to stop, 'OK' to delete."), $comment->comment_author)) . "', theCommentList );\">" . __('Delete') . '</a> ';
+	if ( ('none' != $comment_status) && ( current_user_can('moderate_comments') ) ) {
+		echo '<span class="unapprove"> | <a href="' . wp_nonce_url('comment.php?action=unapprovecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'unapprove-comment_' . $comment->comment_ID) . '" onclick="return dimSomething( \'comment\', ' . $comment->comment_ID . ', \'unapproved\', theCommentList );">' . __('Unapprove') . '</a> </span>';
+		echo '<span class="approve"> | <a href="' . wp_nonce_url('comment.php?action=approvecomment&amp;p=' . $comment->comment_post_ID . '&amp;c=' . $comment->comment_ID, 'approve-comment_' . $comment->comment_ID) . '" onclick="return dimSomething( \'comment\', ' . $comment->comment_ID . ', \'unapproved\', theCommentList );">' . __('Approve') . '</a> </span>';
+	}
+	echo " | <a href=\"" . wp_nonce_url("comment.php?action=deletecomment&amp;dt=spam&amp;p=" . $comment->comment_post_ID . "&amp;c=" . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . "\" onclick=\"return deleteSomething( 'comment-as-spam', $comment->comment_ID, '" . js_escape(sprintf(__("You are about to mark as spam this comment by '%s'.\n'Cancel' to stop, 'OK' to mark as spam."), $comment->comment_author))  . "', theCommentList );\">" . __('Spam') . "</a> ";
+}
+?>
+</p>
+		</li>
 
-</li> 
-<!-- /comment --> 
 <?php //end of the loop, don't delete
 		} // end foreach
 	echo '</ol>';
 	}//end if comments
 	?>
-<?php } ?> 
-</div> 
-<?php 
+<?php } ?>
+</div>
+<?php
  include('admin-footer.php');
-?> 
+?>
diff -ruN 2.0.5/wp-admin/execute-pings.php 2.2.2/wp-admin/execute-pings.php
--- 2.0.5/wp-admin/execute-pings.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/execute-pings.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,25 +0,0 @@
-<?php
-
-require_once('../wp-config.php');
-
-// Do pingbacks
-while ($ping = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1")) {
-	$wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE post_id = {$ping->ID} AND meta_key = '_pingme';");
-	pingback($ping->post_content, $ping->ID);
-}
-
-// Do Enclosures
-while ($enclosure = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1")) {
-	$wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE post_id = {$enclosure->ID} AND meta_key = '_encloseme';");
-	do_enclose($enclosure->post_content, $enclosure->ID);
-}
-
-// Do Trackbacks
-$trackbacks = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE CHAR_LENGTH(TRIM(to_ping)) > 7 AND post_status != 'draft'");
-if ( is_array($trackbacks) ) {
-	foreach ( $trackbacks as $trackback ) {
-		do_trackbacks($trackback->ID);
-	}
-}
-
-?>
diff -ruN 2.0.5/wp-admin/export.php 2.2.2/wp-admin/export.php
--- 2.0.5/wp-admin/export.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/export.php	2007-08-03 09:51:20.000000000 -0500
@@ -0,0 +1,227 @@
+<?php
+require_once ('admin.php');
+$title = __('Export');
+$parent_file = 'edit.php';
+
+if ( isset( $_GET['download'] ) )
+	export_wp();
+
+require_once ('admin-header.php');
+?>
+
+<div class="wrap">
+<h2><?php _e('Export'); ?></h2>
+<div class="narrow">
+<p><?php _e('When you click the button below WordPress will create an XML file for you to save to your computer.'); ?></p>
+<p><?php _e('This format, which we call WordPress eXtended RSS or WXR, will contain your posts, comments, custom fields, and categories.'); ?></p>
+<p><?php _e('Once you&#8217;ve saved the download file, you can use the Import function on another WordPress blog to import this blog.'); ?></p>
+<form action="" method="get">
+<h3><?php _e('Optional options'); ?></h3>
+
+<table>
+<tr>
+<th><?php _e('Restrict Author:'); ?></th>
+<td>
+<select name="author">
+<option value="all" selected="selected"><?php _e('All'); ?></option>
+<?php
+$authors = $wpdb->get_col( "SELECT post_author FROM $wpdb->posts GROUP BY post_author" );  
+foreach ( $authors as $id ) {
+	$o = get_userdata( $id );
+	echo "<option value='$o->ID'>$o->display_name</option>";
+}
+?>
+</select>
+</td>
+</tr>
+</table>
+<p class="submit"><input type="submit" name="submit" value="<?php _e('Download Export File'); ?> &raquo;" />
+<input type="hidden" name="download" value="true" />
+</p>
+</form>
+</div>
+</div>
+
+<?php
+
+function export_wp() {
+global $wpdb, $posts, $post;
+
+$filename = 'wordpress.' . date('Y-m-d') . '.xml';
+
+header('Content-Description: File Transfer');
+header("Content-Disposition: attachment; filename=$filename");
+header('Content-type: text/xml; charset=' . get_option('blog_charset'), true);
+
+$where = '';
+if ( isset( $_GET['author'] ) && $_GET['author'] != 'all' ) {
+	$author_id = (int) $_GET['author'];
+	$where = " WHERE post_author = '$author_id' ";
+}
+
+$posts = $wpdb->get_results("SELECT * FROM $wpdb->posts $where ORDER BY post_date_gmt ASC");
+
+$categories = (array) $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename, category_description, category_parent, posts_private, links_private FROM $wpdb->categories LEFT JOIN $wpdb->post2cat ON (category_id = cat_id) LEFT JOIN $wpdb->posts ON (post_id <=> id) $where GROUP BY cat_id");
+
+function wxr_missing_parents($categories) {
+	if ( !is_array($categories) || empty($categories) )
+		return array();
+
+	foreach ( $categories as $category )
+		$parents[$category->cat_ID] = $category->category_parent;
+
+	$parents = array_unique(array_diff($parents, array_keys($parents)));
+
+	if ( $zero = array_search('0', $parents) )
+		unset($parents[$zero]);
+
+	return $parents;
+}
+
+while ( $parents = wxr_missing_parents($categories) ) {
+	$found_parents = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename, category_description, category_parent, posts_private, links_private FROM $wpdb->categories WHERE cat_ID IN (" . join(', ', $parents) . ")");
+	if ( is_array($found_parents) && count($found_parents) )
+		$categories = array_merge($categories, $found_parents);
+	else
+		break;
+}
+
+// Put them in order to be inserted with no child going before its parent
+$pass = 0;
+$passes = 1000 + count($categories);
+while ( ( $cat = array_shift($categories) ) && ++$pass < $passes ) {
+	if ( $cat->category_parent == 0 || isset($cats[$cat->category_parent]) ) {
+		$cats[$cat->cat_ID] = $cat;
+	} else {
+		$categories[] = $cat;
+	}
+}
+unset($categories);
+
+function wxr_cdata($str) {
+	if ( seems_utf8($str) == false )
+		$str = utf8_encode($str);
+
+	// $str = ent2ncr(wp_specialchars($str));
+
+	$str = "<![CDATA[$str" . ( ( substr($str, -1) == ']' ) ? ' ' : '') . "]]>";
+
+	return $str;
+}
+
+function wxr_cat_name($c) {
+	if ( empty($c->cat_name) )
+		return;
+
+	echo '<wp:cat_name>' . wxr_cdata($c->cat_name) . '</wp:cat_name>';
+}
+
+function wxr_category_description($c) {
+	if ( empty($c->category_description) )
+		return;
+
+	echo '<wp:category_description>' . wxr_cdata($c->category_description) . '</wp:category_description>';
+}
+
+print '<?xml version="1.0" encoding="' . get_bloginfo('charset') . '"?' . ">\n";
+
+?>
+
+<!--
+	This is a WordPress eXtended RSS file generated by WordPress as an export of 
+	your blog. It contains information about your blog's posts, comments, and 
+	categories. You may use this file to transfer that content from one site to 
+	another. This file is not intended to serve as a complete backup of your 
+	blog.
+	
+	To import this information into a WordPress blog follow these steps:
+	
+	1.	Log into that blog as an administrator.
+	2.	Go to Manage > Import in the blog's admin.
+	3.	Choose "WordPress" from the list of importers.
+	4.	Upload this file using the form provided on that page.
+	5.	You will first be asked to map the authors in this export file to users 
+		on the blog. For each author, you may choose to map an existing user on 
+		the blog or to create a new user.
+	6.	WordPress will then import each of the posts, comments, and categories 
+		contained in this file onto your blog.
+-->
+
+<!-- generator="wordpress/<?php bloginfo_rss('version') ?>" created="<?php echo date('Y-m-d H:i'); ?>"-->
+<rss version="2.0"
+	xmlns:content="http://purl.org/rss/1.0/modules/content/"
+	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+	xmlns:dc="http://purl.org/dc/elements/1.1/"
+	xmlns:wp="http://wordpress.org/export/1.0/"
+>
+
+<channel>
+	<title><?php bloginfo_rss('name'); ?></title>
+	<link><?php bloginfo_rss('url') ?></link>
+	<description><?php bloginfo_rss("description") ?></description>
+	<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></pubDate>
+	<generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator>
+	<language><?php echo get_option('rss_language'); ?></language>
+<?php if ( $cats ) : foreach ( $cats as $c ) : ?>
+	<wp:category><wp:category_nicename><?php echo $c->category_nicename; ?></wp:category_nicename><wp:category_parent><?php echo $c->category_parent ? $cats[$c->category_parent]->cat_name : ''; ?></wp:category_parent><wp:posts_private><?php echo $c->posts_private ? '1' : '0'; ?></wp:posts_private><wp:links_private><?php echo $c->links_private ? '1' : '0'; ?></wp:links_private><?php wxr_cat_name($c); ?><?php wxr_category_description($c); ?></wp:category>
+<?php endforeach; endif; ?>
+	<?php do_action('rss2_head'); ?>
+	<?php if ($posts) { foreach ($posts as $post) { start_wp(); ?>
+<item>
+<title><?php the_title_rss() ?></title>
+<link><?php permalink_single_rss() ?></link>
+<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
+<dc:creator><?php the_author() ?></dc:creator>
+<?php the_category_rss() ?>
+
+<guid isPermaLink="false"><?php the_guid(); ?></guid>
+<description></description>
+<content:encoded><![CDATA[<?php echo $post->post_content ?>]]></content:encoded>
+<wp:post_id><?php echo $post->ID; ?></wp:post_id>
+<wp:post_date><?php echo $post->post_date; ?></wp:post_date>
+<wp:post_date_gmt><?php echo $post->post_date_gmt; ?></wp:post_date_gmt>
+<wp:comment_status><?php echo $post->comment_status; ?></wp:comment_status>
+<wp:ping_status><?php echo $post->ping_status; ?></wp:ping_status>
+<wp:post_name><?php echo $post->post_name; ?></wp:post_name>
+<wp:status><?php echo $post->post_status; ?></wp:status>
+<wp:post_parent><?php echo $post->post_parent; ?></wp:post_parent>
+<wp:menu_order><?php echo $post->menu_order; ?></wp:menu_order>
+<wp:post_type><?php echo $post->post_type; ?></wp:post_type>
+<?php
+$postmeta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = $post->ID");
+if ( $postmeta ) {
+?>
+<?php foreach( $postmeta as $meta ) { ?>
+<wp:postmeta>
+<wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key>
+<wp:meta_value><?Php echo $meta->meta_value; ?></wp:meta_value>
+</wp:postmeta>
+<?php } ?>
+<?php } ?>
+<?php
+$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post->ID");
+if ( $comments ) { foreach ( $comments as $c ) { ?>
+<wp:comment>
+<wp:comment_id><?php echo $c->comment_ID; ?></wp:comment_id>
+<wp:comment_author><?php echo $c->comment_author; ?></wp:comment_author>
+<wp:comment_author_email><?php echo $c->comment_author_email; ?></wp:comment_author_email>
+<wp:comment_author_url><?php echo $c->comment_author_url; ?></wp:comment_author_url>
+<wp:comment_author_IP><?php echo $c->comment_author_IP; ?></wp:comment_author_IP>
+<wp:comment_date><?php echo $c->comment_date; ?></wp:comment_date>
+<wp:comment_date_gmt><?php echo $c->comment_date_gmt; ?></wp:comment_date_gmt>
+<wp:comment_content><?php echo $c->comment_content; ?></wp:comment_content>
+<wp:comment_approved><?php echo $c->comment_approved; ?></wp:comment_approved>
+<wp:comment_type><?php echo $c->comment_type; ?></wp:comment_type>
+<wp:comment_parent><?php echo $c->comment_parent; ?></wp:comment_parent>
+</wp:comment>
+<?php } } ?>
+	</item>
+<?php } } ?>
+</channel>
+</rss>
+<?php
+	die();
+}
+
+include ('admin-footer.php');
+?>
Binary files 2.0.5/wp-admin/images/login-bkg-bottom.gif and 2.2.2/wp-admin/images/login-bkg-bottom.gif differ
Binary files 2.0.5/wp-admin/images/login-bkg-tile.gif and 2.2.2/wp-admin/images/login-bkg-tile.gif differ
diff -ruN 2.0.5/wp-admin/import/blogger.php 2.2.2/wp-admin/import/blogger.php
--- 2.0.5/wp-admin/import/blogger.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/blogger.php	2007-05-07 10:57:15.000000000 -0500
@@ -1,40 +1,720 @@
 <?php
 
-class Blogger_Import {
+define( 'MAX_RESULTS',        50 ); // How many records per GData query
+define( 'MAX_EXECUTION_TIME', 20 ); // How many seconds to let the script run
+define( 'STATUS_INTERVAL',     3 ); // How many seconds between status bar updates
 
-	var $lump_authors = false;
-	var $import = array();
+class Blogger_Import {
 
-	// Shows the welcome screen and the magic iframe.
+	// Shows the welcome screen and the magic auth link.
 	function greet() {
+		$next_url = get_option('siteurl') . '/wp-admin/index.php?import=blogger&noheader=true';
+		$auth_url = "https://www.google.com/accounts/AuthSubRequest";
 		$title = __('Import Blogger');
 		$welcome = __('Howdy! This importer allows you to import posts and comments from your Blogger account into your WordPress blog.');
-		$noiframes = __('This feature requires iframe support.');
-		$warning = __('This will delete everything saved by the Blogger importer except your posts and comments. Are you sure you want to do this?');
-		$reset = __('Reset this importer');
-		$incompat = __('Your web server is not properly configured to use this importer. Please enable the CURL extension for PHP and then reload this page.');
-
-		echo "<div class='wrap'><h2>$title</h2><p>$welcome</p>";
-		if ( function_exists('curl_init') )
-			echo "<iframe src='admin.php?import=blogger&amp;noheader=true' height='350px' width = '99%'>$noiframes</iframe><p><a href='admin.php?import=blogger&amp;restart=true&amp;noheader=true' onclick='return confirm(\"$warning\")'>$reset</a></p>";
+		$prereqs = __('To use this importer, you must have a Google account, an upgraded (New, was Beta) blog, and it must be on blogspot or a custom domain (not FTP).');
+		$stepone = __('The first thing you need to do is tell Blogger to let WordPress access your account. You will be sent back here after providing authorization.');
+		$auth = __('Authorize');
+
+		echo "
+		<div class='wrap'><h2>$title</h2><p>$welcome</p><p>$prereqs</p><p>$stepone</p>
+			<form action='$auth_url' method='get'>
+				<p class='submit' style='text-align:left;'>
+					<input type='submit' value='$auth' />
+					<input type='hidden' name='scope' value='http://www.blogger.com/feeds/' />
+					<input type='hidden' name='session' value='1' />
+					<input type='hidden' name='secure' value='0' />
+					<input type='hidden' name='next' value='$next_url' />
+				</p>
+			</form>
+		</div>\n";
+	}
+
+	function uh_oh($title, $message, $info) {
+		echo "<div class='wrap'><h2>$title</h2><p>$message</p><pre>$info</pre></div>";
+	}
+
+	function auth() {
+		// We have a single-use token that must be upgraded to a session token.
+		$token = preg_replace( '/[^-_0-9a-zA-Z]/', '', $_GET['token'] );
+		$headers = array(
+			"GET /accounts/AuthSubSessionToken HTTP/1.0",
+			"Authorization: AuthSub token=\"$token\""
+		);
+		$request = join( "\r\n", $headers ) . "\r\n\r\n";
+		$sock = $this->_get_auth_sock( );
+		if ( ! $sock ) return false;
+		$response = $this->_txrx( $sock, $request );
+		preg_match( '/token=([-_0-9a-z]+)/i', $response, $matches );
+		if ( empty( $matches[1] ) ) {
+			$this->uh_oh(
+				__( 'Authorization failed' ),
+				__( 'Something went wrong. If the problem persists, send this info to support:' ),
+				htmlspecialchars($response)
+			);
+			return false;
+		}
+		$this->token = $matches[1];
+
+		wp_redirect( remove_query_arg( array( 'token', 'noheader' ) ) );
+	}
+
+	function get_token_info() {
+		$headers = array(
+			"GET /accounts/AuthSubTokenInfo  HTTP/1.0",
+			"Authorization: AuthSub token=\"$this->token\""
+		);
+		$request = join( "\r\n", $headers ) . "\r\n\r\n";
+		$sock = $this->_get_auth_sock( );
+		if ( ! $sock ) return;
+		$response = $this->_txrx( $sock, $request );
+		return $this->parse_response($response);
+	}
+
+	function token_is_valid() {
+		$info = $this->get_token_info();
+
+		if ( $info['code'] == 200 )
+			return true;
+
+		return false;
+	}
+
+	function show_blogs($iter = 0) {
+		if ( empty($this->blogs) ) {
+			$headers = array(
+				"GET /feeds/default/blogs HTTP/1.0",
+				"Host: www2.blogger.com",
+				"Authorization: AuthSub token=\"$this->token\""
+			);
+			$request = join( "\r\n", $headers ) . "\r\n\r\n";
+			$sock = $this->_get_blogger_sock( );
+			if ( ! $sock ) return;
+			$response = $this->_txrx( $sock, $request );
+
+			// Quick and dirty XML mining.
+			list( $headers, $xml ) = explode( "\r\n\r\n", $response );
+			$p = xml_parser_create();
+			xml_parse_into_struct($p, $xml, $vals, $index);
+			xml_parser_free($p);
+
+			$this->title = $vals[$index['TITLE'][0]]['value'];
+
+			// Give it a few retries... this step often flakes out the first time.
+			if ( empty( $index['ENTRY'] ) ) {
+				if ( $iter < 3 ) {
+					return $this->show_blogs($iter + 1);
+				} else {
+					$this->uh_oh(
+						__('Trouble signing in'),
+						__('We were not able to gain access to your account. Try starting over.'),
+						''
+					);
+					return false;
+				}
+			}
+
+			foreach ( $index['ENTRY'] as $i ) {
+				$blog = array();
+				while ( ( $tag = $vals[$i] ) && ! ( $tag['tag'] == 'ENTRY' && $tag['type'] == 'close' ) ) {
+					if ( $tag['tag'] == 'TITLE' ) {
+						$blog['title'] = $tag['value'];
+					} elseif ( $tag['tag'] == 'SUMMARY' ) {
+						$blog['summary'] == $tag['value'];
+					} elseif ( $tag['tag'] == 'LINK' ) {
+						if ( $tag['attributes']['REL'] == 'alternate' && $tag['attributes']['TYPE'] == 'text/html' ) {
+							$parts = parse_url( $tag['attributes']['HREF'] );
+							$blog['host'] = $parts['host'];
+						} elseif ( $tag['attributes']['REL'] == 'edit' )
+							$blog['gateway'] = $tag['attributes']['HREF'];
+					}
+					++$i;
+				}
+				if ( ! empty ( $blog ) ) {
+					$blog['total_posts'] = $this->get_total_results('posts', $blog['host']);
+					$blog['total_comments'] = $this->get_total_results('comments', $blog['host']);
+					$blog['mode'] = 'init';
+					$this->blogs[] = $blog;
+				}
+			}
+
+			if ( empty( $this->blogs ) ) {
+				$this->uh_oh(
+					__('No blogs found'),
+					__('We were able to log in but there were no blogs. Try a different account next time.'),
+					''
+				);
+				return false;
+			}
+		}
+//echo '<pre>'.print_r($this,1).'</pre>';
+		$start    = js_escape( __('Import') );
+		$continue = js_escape( __('Continue') );
+		$stop     = js_escape( __('Importing...') );
+		$authors  = js_escape( __('Set Authors') );
+		$loadauth = js_escape( __('Preparing author mapping form...') );
+		$authhead = js_escape( __('Final Step: Author Mapping') );
+		$nothing  = js_escape( __('Nothing was imported. Had you already imported this blog?') );
+		$title    = __('Blogger Blogs');
+		$name     = __('Blog Name');
+		$url      = __('Blog URL');
+		$action   = __('The Magic Button');
+		$posts    = __('Posts');
+		$comments = __('Comments');
+		$noscript = __('This feature requires Javascript but it seems to be disabled. Please enable Javascript and then reload this page. Don\'t worry, you can turn it back off when you\'re done.');
+
+		$interval = STATUS_INTERVAL * 1000;
+
+		foreach ( $this->blogs as $i => $blog ) {
+			if ( $blog['mode'] == 'init' )
+				$value = $start;
+			elseif ( $blog['mode'] == 'posts' || $blog['mode'] == 'comments' )
+				$value = $continue;
+			else
+				$value = $authors;
+			$blogtitle = js_escape( $blog['title'] );
+			$pdone = isset($blog['posts_done']) ? (int) $blog['posts_done'] : 0;
+			$cdone = isset($blog['comments_done']) ? (int) $blog['comments_done'] : 0;
+			$init .= "blogs[$i]=new blog($i,'$blogtitle','{$blog['mode']}'," . $this->get_js_status($i) . ');';
+			$pstat = "<div class='ind' id='pind$i'>&nbsp;</div><div id='pstat$i' class='stat'>$pdone/{$blog['total_posts']}</div>";
+			$cstat = "<div class='ind' id='cind$i'>&nbsp;</div><div id='cstat$i' class='stat'>$cdone/{$blog['total_comments']}</div>";
+			$rows .= "<tr id='blog$i'><td class='blogtitle'>$blogtitle</td><td class='bloghost'>{$blog['host']}</td><td class='bar'>$pstat</td><td class='bar'>$cstat</td><td class='submit'><input type='submit' id='submit$i' value='$value' /><input type='hidden' name='blog' value='$i' /></td></tr>\n";
+		}
+
+		echo "<div class='wrap'><h2>$title</h2><noscript>$noscript</noscript><table cellpadding='5px'><thead><td>$name</td><td>$url</td><td>$posts</td><td>$comments</td><td>$action</td></thead>\n$rows</table></form></div>";
+		echo "
+		<script type='text/javascript'>
+			var strings = {cont:'$continue',stop:'$stop',stopping:'$stopping',authors:'$authors',nothing:'$nothing'};
+			var blogs = {};
+			function blog(i, title, mode, status){
+				this.blog   = i;
+				this.mode   = mode;
+				this.title  = title;
+				this.status = status;
+				this.button = document.getElementById('submit'+this.blog);
+			};
+			blog.prototype = {
+				start: function() {
+					this.cont = true;
+					this.kick();
+					this.check();
+				},
+				kick: function() {
+					++this.kicks;
+					var i = this.blog;
+					jQuery.post('admin.php?import=blogger&noheader=true',{blog:this.blog},function(text,result){blogs[i].kickd(text,result)});
+				},
+				check: function() {
+					++this.checks;
+					var i = this.blog;
+					jQuery.post('admin.php?import=blogger&noheader=true&status=true',{blog:this.blog},function(text,result){blogs[i].checkd(text,result)});
+				},
+				kickd: function(text, result) {
+					if ( result == 'error' ) {
+						// TODO: exception handling
+						if ( this.cont )
+							setTimeout('blogs['+this.blog+'].kick()', 1000);
+					} else {
+						if ( text == 'done' ) {
+							this.stop();
+							this.done();
+						} else if ( text == 'nothing' ) {
+							this.stop();
+							this.nothing();
+						} else if ( text == 'continue' ) {
+							this.kick();
+						} else if ( this.mode = 'stopped' )
+							jQuery(this.button).attr('value', strings.cont);
+					}
+					--this.kicks;
+				},
+				checkd: function(text, result) {
+					if ( result == 'error' ) {
+						// TODO: exception handling
+					} else {
+						eval('this.status='+text);
+						jQuery('#pstat'+this.blog).empty().append(this.status.p1+'/'+this.status.p2);
+						jQuery('#cstat'+this.blog).empty().append(this.status.c1+'/'+this.status.c2);
+						this.update();
+						if ( this.cont || this.kicks > 0 )
+							setTimeout('blogs['+this.blog+'].check()', $interval);
+					}
+					--this.checks;
+				},
+				update: function() {
+					jQuery('#pind'+this.blog).width(((this.status.p1>0&&this.status.p2>0)?(this.status.p1/this.status.p2*jQuery('#pind'+this.blog).parent().width()):1)+'px');
+					jQuery('#cind'+this.blog).width(((this.status.c1>0&&this.status.c2>0)?(this.status.c1/this.status.c2*jQuery('#cind'+this.blog).parent().width()):1)+'px');
+				},
+				stop: function() {
+					this.cont = false;
+				},
+				done: function() {
+					this.mode = 'authors';
+					jQuery(this.button).attr('value', strings.authors);
+				},
+				nothing: function() {
+					this.mode = 'nothing';
+					jQuery(this.button).remove();
+					alert(strings.nothing);
+				},
+				getauthors: function() {
+					if ( jQuery('div.wrap').length > 1 )
+						jQuery('div.wrap').gt(0).remove();
+					jQuery('div.wrap').empty().append('<h2>$authhead</h2><h3>' + this.title + '</h3>');
+					jQuery('div.wrap').append('<p id=\"auth\">$loadauth</p>');
+					jQuery('p#auth').load('index.php?import=blogger&noheader=true&authors=1',{blog:this.blog});
+				},
+				init: function() {
+					this.update();
+					var i = this.blog;
+					jQuery(this.button).bind('click', function(){return blogs[i].click();});
+					this.kicks = 0;
+					this.checks = 0;
+				},
+				click: function() {
+					if ( this.mode == 'init' || this.mode == 'stopped' || this.mode == 'posts' || this.mode == 'comments' ) {
+						this.mode = 'started';
+						this.start();
+						jQuery(this.button).attr('value', strings.stop);
+					} else if ( this.mode == 'started' ) {
+						return false; // let it run...
+						this.mode = 'stopped';
+						this.stop();
+						if ( this.checks > 0 || this.kicks > 0 ) {
+							this.mode = 'stopping';
+							jQuery(this.button).attr('value', strings.stopping);
+						} else {
+							jQuery(this.button).attr('value', strings.cont);
+						}
+					} else if ( this.mode == 'authors' ) {
+						document.location = 'index.php?import=blogger&authors=1&blog='+this.blog;
+						//this.mode = 'authors2';
+						//this.getauthors();
+					}
+					return false;
+				}
+			};
+			$init
+			jQuery.each(blogs, function(i, me){me.init();});
+		</script>\n";
+	}
+
+	// Handy function for stopping the script after a number of seconds.
+	function have_time() {
+		global $importer_started;
+		if ( time() - $importer_started > MAX_EXECUTION_TIME )
+			die('continue');
+		return true;
+	}
+
+	function get_total_results($type, $host) {
+		$headers = array(
+			"GET /feeds/$type/default?max-results=1&start-index=2 HTTP/1.0",
+			"Host: $host",
+			"Authorization: AuthSub token=\"$this->token\""
+		);
+		$request = join( "\r\n", $headers ) . "\r\n\r\n";
+		$sock = $this->_get_blogger_sock( $host );
+		if ( ! $sock ) return;
+		$response = $this->_txrx( $sock, $request );
+		$response = $this->parse_response( $response );
+		$parser = xml_parser_create();
+		xml_parse_into_struct($parser, $response['body'], $struct, $index);
+		xml_parser_free($parser);
+		$total_results = $struct[$index['OPENSEARCH:TOTALRESULTS'][0]]['value'];
+		return (int) $total_results;
+	}
+
+	function import_blog($blogID) {
+		global $importing_blog;
+		$importing_blog = $blogID;
+
+		if ( isset($_GET['authors']) )
+			return print($this->get_author_form());
+
+		header('Content-Type: text/plain');
+
+		if ( isset($_GET['status']) )
+			die($this->get_js_status());
+
+		if ( isset($_GET['saveauthors']) )
+			die($this->save_authors());
+
+		$blog = $this->blogs[$blogID];
+		$total_results = $this->get_total_results('posts', $blog['host']);
+		$this->blogs[$importing_blog]['total_posts'] = $total_results;
+
+		$start_index = $total_results - MAX_RESULTS + 1;
+
+		if ( isset( $this->blogs[$importing_blog]['posts_start_index'] ) )
+			$start_index = (int) $this->blogs[$importing_blog]['posts_start_index'];
+		elseif ( $total_results > MAX_RESULTS )
+			$start_index = $total_results - MAX_RESULTS + 1;
+		else
+			$start_index = 1;
+
+		// This will be positive until we have finished importing posts
+		if ( $start_index > 0 ) {
+			// Grab all the posts
+			$this->blogs[$importing_blog]['mode'] = 'posts';
+			$query = "start-index=$start_index&max-results=" . MAX_RESULTS;
+			do {
+				$index = $struct = $entries = array();
+				$headers = array(
+					"GET /feeds/posts/default?$query HTTP/1.0",
+					"Host: {$blog['host']}",
+					"Authorization: AuthSub token=\"$this->token\""
+				);
+				$request = join( "\r\n", $headers ) . "\r\n\r\n";
+				$sock = $this->_get_blogger_sock( $blog['host'] );
+				if ( ! $sock ) return; // TODO: Error handling
+				$response = $this->_txrx( $sock, $request );
+
+				$response = $this->parse_response( $response );
+
+				// Extract the entries and send for insertion
+				preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches );
+				if ( count( $matches[0] ) ) {
+					$entries = array_reverse($matches[0]);
+					foreach ( $entries as $entry ) {
+						$entry = "<feed>$entry</feed>";
+						$AtomParser = new AtomParser();
+						$AtomParser->parse( $entry );
+						$this->import_post($AtomParser->entry);
+						unset($AtomParser);
+					}
+				} else break;
+
+				// Get the 'previous' query string which we'll use on the next iteration
+				$query = '';
+				$links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches);
+				if ( count( $matches[1] ) )
+					foreach ( $matches[1] as $match )
+						if ( preg_match('/rel=.previous./', $match) )
+							$query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) );
+
+				if ( $query ) {
+					parse_str($query, $q);
+					$this->blogs[$importing_blog]['posts_start_index'] = (int) $q['start-index'];
+				} else
+					$this->blogs[$importing_blog]['posts_start_index'] = 0;
+				$this->save_vars();
+			} while ( !empty( $query ) && $this->have_time() );
+		}
+
+		$total_results = $this->get_total_results( 'comments', $blog['host'] );
+		$this->blogs[$importing_blog]['total_comments'] = $total_results;
+
+		if ( isset( $this->blogs[$importing_blog]['comments_start_index'] ) )
+			$start_index = (int) $this->blogs[$importing_blog]['comments_start_index'];
+		elseif ( $total_results > MAX_RESULTS )
+			$start_index = $total_results - MAX_RESULTS + 1;
 		else
-			echo "<p>$incompat</p>";
-		echo "</div>\n";
+			$start_index = 1;
+
+		if ( $start_index > 0 ) {
+			// Grab all the comments
+			$this->blogs[$importing_blog]['mode'] = 'comments';
+			$query = "start-index=$start_index&max-results=" . MAX_RESULTS;
+			do {
+				$index = $struct = $entries = array();
+				$headers = array(
+					"GET /feeds/comments/default?$query HTTP/1.0",
+					"Host: {$blog['host']}",
+					"Authorization: AuthSub token=\"$this->token\""
+				);
+				$request = join( "\r\n", $headers ) . "\r\n\r\n";
+				$sock = $this->_get_blogger_sock( $blog['host'] );
+				if ( ! $sock ) return; // TODO: Error handling
+				$response = $this->_txrx( $sock, $request );
+
+				$response = $this->parse_response( $response );
+
+				// Extract the comments and send for insertion
+				preg_match_all( '/<entry[^>]*>.*?<\/entry>/s', $response['body'], $matches );
+				if ( count( $matches[0] ) ) {
+					$entries = array_reverse( $matches[0] );
+					foreach ( $entries as $entry ) {
+						$entry = "<feed>$entry</feed>";
+						$AtomParser = new AtomParser();
+						$AtomParser->parse( $entry );
+						$this->import_comment($AtomParser->entry);
+						unset($AtomParser);
+					}
+				}
+
+				// Get the 'previous' query string which we'll use on the next iteration
+				$query = '';
+				$links = preg_match_all('/<link([^>]*)>/', $response['body'], $matches);
+				if ( count( $matches[1] ) )
+					foreach ( $matches[1] as $match )
+						if ( preg_match('/rel=.previous./', $match) )
+							$query = html_entity_decode( preg_replace('/^.*href=[\'"].*\?(.+)[\'"].*$/', '$1', $match) );
+
+				parse_str($query, $q);
+
+				$this->blogs[$importing_blog]['comments_start_index'] = (int) $q['start-index'];
+				$this->save_vars();
+			} while ( !empty( $query ) && $this->have_time() );
+		}
+		$this->blogs[$importing_blog]['mode'] = 'authors';
+		$this->save_vars();
+		if ( !$this->blogs[$importing_blog]['posts_done'] && !$this->blogs[$importing_blog]['comments_done'] )
+			die('nothing');
+		do_action('import_done', 'blogger');
+		die('done');
 	}
 
-	// Deletes saved data and redirect.
-	function restart() {
-		delete_option('import-blogger');
-		wp_redirect("admin.php?import=blogger");
-		die();
+	function convert_date( $date ) {
+	    preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\.[0-9]+)?(Z|[\+|\-][0-9]{2,4}){0,1}#', $date, $date_bits);
+	    $offset = iso8601_timezone_to_offset( $date_bits[7] );
+		$timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
+		$timestamp -= $offset; // Convert from Blogger local time to GMT
+		$timestamp += get_option('gmt_offset') * 3600; // Convert from GMT to WP local time
+		return gmdate('Y-m-d H:i:s', $timestamp);
+	}
+
+	function no_apos( $string ) {
+		return str_replace( '&apos;', "'", $string);
+	}
+
+	function min_whitespace( $string ) {
+		return preg_replace( '|\s+|', ' ', $string );
+	}
+
+	function import_post( $entry ) {
+		global $wpdb, $importing_blog;
+
+		// The old permalink is all Blogger gives us to link comments to their posts.
+		if ( isset( $entry->draft ) )
+			$rel = 'self';
+		else
+			$rel = 'alternate';
+		foreach ( $entry->links as $link ) {
+			if ( $link['rel'] == $rel ) {
+				$parts = parse_url( $link['href'] );
+				$entry->old_permalink = $parts['path'];
+				break;
+			}
+		}
+
+		$post_date    = $this->convert_date( $entry->published );
+		$post_content = trim( addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) ) );
+		$post_title   = trim( addslashes( $this->no_apos( $this->min_whitespace( $entry->title ) ) ) );
+		$post_status  = isset( $entry->draft ) ? 'draft' : 'publish';
+
+		// Clean up content
+		$post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
+		$post_content = str_replace('<br>', '<br />', $post_content);
+		$post_content = str_replace('<hr>', '<hr />', $post_content);
+
+		// Checks for duplicates
+		if (
+			isset( $this->blogs[$importing_blog]['posts'][$entry->old_permalink] ) ||
+			post_exists( $post_title, $post_content, $post_date )
+		) {
+			++$this->blogs[$importing_blog]['posts_skipped'];
+		} else {
+			$post = compact('post_date', 'post_content', 'post_title', 'post_status');
+
+			$post_id = wp_insert_post($post);
+
+			wp_create_categories( array_map( 'addslashes', $entry->categories ), $post_id );
+
+			$author = $this->no_apos( strip_tags( $entry->author ) );
+
+			add_post_meta( $post_id, 'blogger_blog', $this->blogs[$importing_blog]['host'], true );
+			add_post_meta( $post_id, 'blogger_author', $author, true );
+			add_post_meta( $post_id, 'blogger_permalink', $entry->old_permalink, true );
+
+			$this->blogs[$importing_blog]['posts'][$entry->old_permalink] = $post_id;
+			++$this->blogs[$importing_blog]['posts_done'];
+		}
+		$this->save_vars();
+	}
+
+	function import_comment( $entry ) {
+		global $importing_blog;
+
+		// Drop the #fragment and we have the comment's old post permalink.
+		foreach ( $entry->links as $link ) {
+			if ( $link['rel'] == 'alternate' ) {
+				$parts = parse_url( $link['href'] );
+				$entry->old_permalink = $parts['fragment'];
+				$entry->old_post_permalink = $parts['path'];
+				break;
+			}
+		}
+
+		$comment_post_ID = (int) $this->blogs[$importing_blog]['posts'][$entry->old_post_permalink];
+		preg_match('#<name>(.+?)</name>.*(?:\<uri>(.+?)</uri>)?#', $entry->author, $matches);
+		$comment_author  = addslashes( $this->no_apos( strip_tags( (string) $matches[1] ) ) );
+		$comment_author_url = addslashes( $this->no_apos( strip_tags( (string) $matches[2] ) ) );
+		$comment_date    = $this->convert_date( $entry->updated );
+		$comment_content = addslashes( $this->no_apos( html_entity_decode( $entry->content ) ) );
+
+		// Clean up content
+		$comment_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $comment_content);
+		$comment_content = str_replace('<br>', '<br />', $comment_content);
+		$comment_content = str_replace('<hr>', '<hr />', $comment_content);
+
+		// Checks for duplicates
+		if (
+			isset( $this->blogs[$importing_blog]['comments'][$entry->old_permalink] ) ||
+			comment_exists( $comment_author, $comment_date )
+		) {
+			++$this->blogs[$importing_blog]['comments_skipped'];
+		} else {
+			$comment = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_date', 'comment_content');
+
+			$comment_id = wp_insert_comment($comment);
+
+			$this->blogs[$importing_blog]['comments'][$entry->old_permalink] = $comment_id;
+
+			++$this->blogs[$importing_blog]['comments_done'];
+		}
+		$this->save_vars();
 	}
 
-	// Generates a string that will make the page reload in a specified interval.
-	function refresher($msec) {
-		if ( $msec )
-			return "<html><head><script type='text/javascript'>window.onload=setTimeout('window.location.reload()', $msec);</script>\n</head>\n<body>\n";
+	function get_js_status($blog = false) {
+		global $importing_blog;
+		if ( $blog === false )
+			$blog = $this->blogs[$importing_blog];
 		else
-			return "<html><head><script type='text/javascript'>window.onload=window.location.reload();</script>\n</head>\n<body>\n";
+			$blog = $this->blogs[$blog];
+		$p1 = isset( $blog['posts_done'] ) ? (int) $blog['posts_done'] : 0;
+		$p2 = isset( $blog['total_posts'] ) ? (int) $blog['total_posts'] : 0;
+		$c1 = isset( $blog['comments_done'] ) ? (int) $blog['comments_done'] : 0;
+		$c2 = isset( $blog['total_comments'] ) ? (int) $blog['total_comments'] : 0;
+		return "{p1:$p1,p2:$p2,c1:$c1,c2:$c2}";
+	}
+
+	function get_author_form($blog = false) {
+		global $importing_blog, $wpdb, $current_user;
+		if ( $blog === false )
+			$blog = & $this->blogs[$importing_blog];
+		else
+			$blog = & $this->blogs[$blog];
+
+		if ( !isset( $blog['authors'] ) ) {
+			$post_ids = array_values($blog['posts']);
+			$authors = (array) $wpdb->get_col("SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN (" . join( ',', $post_ids ) . ")");
+			$blog['authors'] = array_map(null, $authors, array_fill(0, count($authors), $current_user->ID));
+			$this->save_vars();
+		}
+
+		$directions = __('All posts were imported with the current user as author. Use this form to move each Blogger user\'s posts to a different WordPress user. You may <a href="users.php">add users</a> and then return to this page and complete the user mapping. This form may be used as many times as you like until you activate the "Restart" function below.');
+		$heading = __('Author mapping');
+		$blogtitle = "{$blog['title']} ({$blog['host']})";
+		$mapthis = __('Blogger username');
+		$tothis = __('WordPress login');
+		$submit = js_escape( __('Save Changes &raquo;') );
+
+		foreach ( $blog['authors'] as $i => $author )
+			$rows .= "<tr><td><label for='authors[$i]'>{$author[0]}</label></td><td><select name='authors[$i]' id='authors[$i]'>" . $this->get_user_options($author[1]) . "</select></td></tr>";
+
+		return "<div class='wrap'><h2>$heading</h2><h3>$blogtitle</h3><p>$directions</p><form action='index.php?import=blogger&noheader=true&saveauthors=1' method='post'><input type='hidden' name='blog' value='$importing_blog' /><table cellpadding='5'><thead><td>$mapthis</td><td>$tothis</td></thead>$rows<tr><td></td><td class='submit'><input type='submit' class='authorsubmit' value='$submit' /></td></tr></table></form></div>";
+	}
+
+	function get_user_options($current) {
+		global $wpdb, $importer_users;
+		if ( ! isset( $importer_users ) )
+			$importer_users = (array) get_users_of_blog();
+
+		foreach ( $importer_users as $user ) {
+			$sel = ( $user->user_id == $current ) ? " selected='selected'" : '';
+			$options .= "<option value='$user->user_id'$sel>$user->display_name</option>";
+		}
+
+		return $options;
+	}
+
+	function save_authors() {
+		global $importing_blog, $wpdb;
+		$authors = (array) $_POST['authors'];
+
+		$host = $this->blogs[$importing_blog]['host'];
+
+		// Get an array of posts => authors
+		$post_ids = (array) $wpdb->get_col("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'blogger_blog' AND meta_value = '$host'");
+		$post_ids = join( ',', $post_ids );
+		$results = (array) $wpdb->get_results("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = 'blogger_author' AND post_id IN ($post_ids)");
+		foreach ( $results as $row )
+			$authors_posts[$row->post_id] = $row->meta_value;
+
+		foreach ( $authors as $author => $user_id ) {
+			$user_id = (int) $user_id;
+
+			// Skip authors that haven't been changed
+			if ( $user_id == $this->blogs[$importing_blog]['authors'][$author][1] )
+				continue;
+
+			// Get a list of the selected author's posts
+			$post_ids = (array) array_keys( $authors_posts, $this->blogs[$importing_blog]['authors'][$author][0] );
+			$post_ids = join( ',', $post_ids);
+
+			$wpdb->query("UPDATE $wpdb->posts SET post_author = $user_id WHERE id IN ($post_ids)");
+			$this->blogs[$importing_blog]['authors'][$author][1] = $user_id;
+		}
+		$this->save_vars();
+
+		wp_redirect('edit.php');
+	}
+
+	function _get_auth_sock() {
+		// Connect to https://www.google.com
+		if ( !$sock = @ fsockopen('ssl://www.google.com', 443, $errno, $errstr) ) {
+			$this->uh_oh(
+				__('Could not connect to https://www.google.com'),
+				__('There was a problem opening a secure connection to Google. This is what went wrong:'),
+				"$errstr ($errno)"
+			);
+			return false;
+		}
+		return $sock;
+	}
+
+	function _get_blogger_sock($host = 'www2.blogger.com') {
+		if ( !$sock = @ fsockopen($host, 80, $errno, $errstr) ) {
+			$this->uh_oh(
+				sprintf( __('Could not connect to %s'), $host ),
+				__('There was a problem opening a connection to Blogger. This is what went wrong:'),
+				"$errstr ($errno)"
+			);
+			return false;
+		}
+		return $sock;
+	}
+
+	function _txrx( $sock, $request ) {
+		fwrite( $sock, $request );
+		while ( ! feof( $sock ) )
+			$response .= @ fread ( $sock, 8192 );
+		fclose( $sock );
+		return $response;
+	}
+
+	function revoke($token) {
+		$headers = array(
+			"GET /accounts/AuthSubRevokeToken HTTP/1.0",
+			"Authorization: AuthSub token=\"$token\""
+		);
+		$request = join( "\r\n", $headers ) . "\r\n\r\n";
+		$sock = $this->_get_auth_sock( );
+		if ( ! $sock ) return false;
+		$this->_txrx( $sock, $request );
+	}
+
+	function restart() {
+		global $wpdb;
+		$options = get_option( 'blogger_importer' );
+
+		if ( isset( $options['token'] ) )
+			$this->revoke( $options['token'] );
+
+		delete_option('blogger_importer');
+		$wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_key = 'blogger_author'");
+		wp_redirect('?import=blogger');
 	}
 
 	// Returns associative array of code, header, cookies, body. Based on code from php.net.
@@ -61,607 +741,273 @@
 		return array("code" => $response_code, "header" => $response_header_array, "cookies" => $cookie_array, "body" => $response_body);
 	}
 
-	// Prints a form for the user to enter Blogger creds.
-	function login_form($text='') {
-		echo '<h1>' . __('Log in to Blogger') . "</h1>\n$text\n";
-		echo '<form method="post" action="admin.php?import=blogger&amp;noheader=true&amp;step=0"><table><tr><td>' . __('Username') . ':</td><td><input type="text" name="user" /></td></tr><tr><td>' . __('Password') . ':</td><td><input type="password" name="pass" /></td><td><input type="submit" value="' . __('Start') . '" /></td></tr></table></form>';
-		die;
-	}
-
-	// Sends creds to Blogger, returns the session cookies an array of headers.
-	function login_blogger($user, $pass) {
-		$_url = 'http://www.blogger.com/login.do';
-		$params = "username=$user&password=$pass";
-		$ch = curl_init();
-		curl_setopt($ch, CURLOPT_POST,1);
-		curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
-		curl_setopt($ch, CURLOPT_URL,$_url);
-		curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
-		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
-		curl_setopt($ch, CURLOPT_HEADER,1);
-		curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
-		$response = curl_exec ($ch);
-
-		$response = $this->parse_response($response);
-
-		sleep(1);
-
-		return $response['cookies'];
-	}
-
-	// Requests page from Blogger, returns the response array.
-	function get_blogger($url, $header = '', $user=false, $pass=false) {
-		$ch = curl_init();
-		if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}");
-		curl_setopt($ch, CURLOPT_URL,$url);
-		curl_setopt($ch, CURLOPT_TIMEOUT, 10);
-		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
-		curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
-		curl_setopt($ch, CURLOPT_HEADER,1);
-		if (is_array($header)) curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
-		$response = curl_exec ($ch);
-
-		$response = $this->parse_response($response);
-		$response['url'] = $url;
+	// Step 9: Congratulate the user
+	function congrats() {
+		$blog = (int) $_GET['blog'];
+		echo '<h1>'.__('Congratulations!').'</h1><p>'.__('Now that you have imported your Blogger blog into WordPress, what are you going to do? Here are some suggestions:').'</p><ul><li>'.__('That was hard work! Take a break.').'</li>';
+		if ( count($this->import['blogs']) > 1 )
+			echo '<li>'.__('In case you haven\'t done it already, you can import the posts from your other blogs:'). $this->show_blogs() . '</li>';
+		if ( $n = count($this->import['blogs'][$blog]['newusers']) )
+			echo '<li>'.sprintf(__('Go to <a href="%s" target="%s">Authors &amp; Users</a>, where you can modify the new user(s) or delete them. If you want to make all of the imported posts yours, you will be given that option when you delete the new authors.'), 'users.php', '_parent').'</li>';
+		echo '<li>'.__('For security, click the link below to reset this importer.').'</li>';
+		echo '</ul>';
+	}
 
-		if (curl_errno($ch)) {
-			print curl_error($ch);
-		} else {
-			curl_close($ch);
-		}
+	// Figures out what to do, then does it.
+	function start() {
+		if ( isset($_POST['restart']) )
+			$this->restart();
 
-		return $response;
-	}
+		$options = get_option('blogger_importer');
 
-	// Posts data to Blogger, returns response array.
-	function post_blogger($url, $header = false, $paramary = false, $parse=true) {
-		$params = '';
-		if ( is_array($paramary) ) {
-			foreach($paramary as $key=>$value)
-				if($key && $value != '')
-					$params.=$key."=".urlencode(stripslashes($value))."&";
-		}
-		if ($user && $pass) $params .= "username=$user&password=$pass";
-		$params = trim($params,'&');
-		$ch = curl_init();
-		curl_setopt($ch, CURLOPT_POST,1);
-		curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
-		if ($user && $pass) curl_setopt($ch, CURLOPT_USERPWD,"{$user}:{$pass}");
-		curl_setopt($ch, CURLOPT_URL,$url);
-		curl_setopt($ch, CURLOPT_USERAGENT, 'Blogger Exporter');
-		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
-		curl_setopt($ch, CURLOPT_HEADER,$parse);
-		curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
-		if ($header) curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
-		$response = curl_exec ($ch);
-
-		if ($parse) {
-			$response = $this->parse_response($response);
-			$response['url'] = $url;
-			return $response;
-		}
+		if ( is_array($options) )
+			foreach ( $options as $key => $value )
+				$this->$key = $value;
+
+		if ( isset( $_REQUEST['blog'] ) ) {
+			$blog = is_array($_REQUEST['blog']) ? array_shift( array_keys( $_REQUEST['blog'] ) ) : $_REQUEST['blog'];
+			$blog = (int) $blog;
+			$this->import_blog( $blog );
+		} elseif ( isset($_GET['token']) )
+			$this->auth();
+		elseif ( $this->token && $this->token_is_valid() )
+			$this->show_blogs();
+		else
+			$this->greet();
 
-		return $response;
-	}
+		$saved = $this->save_vars();
 
-	// Prints the list of blogs for import.
-	function show_blogs() {
-		global $import;
-		echo '<h1>' . __('Selecting a Blog') . "</h1>\n<ul>";
-		foreach ( $this->import['blogs'] as $blog ) {
-			if (9 == $blog['nextstep']) $status = "100%";
-			elseif (8 == $blog['nextstep']) $status = "90%";
-			elseif (7 == $blog['nextstep']) $status = "82.5%";
-			elseif (6 == $blog['nextstep']) $status = "75%";
-			elseif (5 == $blog['nextstep']) $status = "57%";
-			elseif (4 == $blog['nextstep']) $status = "28%";
-			elseif (3 == $blog['nextstep']) $status = "14%";
-			else $status = "0%";
-			echo "\t<li><a href='admin.php?import=blogger&amp;noheader=true&amp;blog={$blog['id']}'>{$blog['title']}</a> $status</li>\n";
-		}
-		die("</ul>\n");
-	}
-
-	// Publishes.
-	function publish_blogger($i, $text) {
-		$head = $this->refresher(2000) . "<h1>$text</h1>\n";
-		if ( ! strstr($this->import['blogs'][$_GET['blog']]['publish'][$i], 'http') ) {
-			// First call. Start the publish process with a fresh set of cookies.
-			$this->import['cookies'] = $this->login_blogger($this->import['user'], $this->import['pass']);
-			update_option('import-blogger', $this->import);
-			$paramary = array('blogID' => $_GET['blog'], 'all' => '1', 'republishAll' => 'Republish Entire Blog', 'publish' => '1', 'redirectUrl' => "/publish.do?blogID={$_GET['blog']}&inprogress=true");
-
-			$response = $this->post_blogger("http://www.blogger.com/publish.do?blogID={$_GET['blog']}", $this->import['cookies'], $paramary);
-			if ( $response['code'] == '302' ) {
-				$url = str_replace('publish.g', 'publish-body.g', $response['header']['Location']);
-				$this->import['blogs'][$_GET['blog']]['publish'][$i] = $url;
-				update_option('import-blogger', $this->import);
-				$response = $this->get_blogger($url, $this->import['cookies']);
-				preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches);
-				$progress = $matches[0];
-				die($head . $progress);
-			} else {
-				$this->import['blogs'][$_GET['blog']]['publish'][$i] = false;
-				update_option('import-blogger', $this->import);
-				die($head);
-			}
-		} else {
-			// Subsequent call. Keep checking status until Blogger reports publish complete.
-			$url = $this->import['blogs'][$_GET['blog']]['publish'][$i];
-			$response = $this->get_blogger($url, $this->import['cookies']);
-			if ( preg_match('#<p class="progressIndicator">.*</p>#U', $response['body'], $matches) ) {
-				$progress = $matches[0];
-				if ( strstr($progress, '100%') ) {
-					$this->set_next_step($i);
-					$progress .= '<p>'.__('Moving on...').'</p>';
-				}
-				die($head . $progress);
-			} else {
-				$this->import['blogs'][$_GET['blog']]['publish'][$i] = false;
-				update_option('import-blogger', $this->import);
-				die("$head<p>" . __('Trying again...') . '</p>');
-			}
+		if ( $saved && !isset($_GET['noheader']) ) {
+			$restart = __('Restart');
+			$message = __('We have saved some information about your Blogger account in your WordPress database. Clearing this information will allow you to start over. Restarting will not affect any posts you have already imported. If you attempt to re-import a blog, duplicate posts and comments will be skipped.');
+			$submit = __('Clear account information');
+			echo "<div class='wrap'><h2>$restart</h2><p>$message</p><form method='post' action='?import=blogger&noheader=true'><p class='submit' style='text-align:left;'><input type='submit' value='$submit' name='restart' /></p></form></div>";
 		}
 	}
 
-	// Sets next step, saves options
-	function set_next_step($step) {
-		$this->import['blogs'][$_GET['blog']]['nextstep'] = $step;
-		update_option('import-blogger', $this->import);
-	}
-
-	// Redirects to next step
-	function do_next_step() {
-		wp_redirect("admin.php?import=blogger&noheader=true&blog={$_GET['blog']}");
-		die();
-	}
-
-	// Step 0: Do Blogger login, get blogid/title pairs.
-	function do_login() {
-		if ( ( ! $this->import['user'] && ! is_array($this->import['cookies']) ) ) {
-			// The user must provide a Blogger username and password.
-			if ( ! ( $_POST['user'] && $_POST['pass'] ) ) {
-				$this->login_form(__('The script will log into your Blogger account, change some settings so it can read your blog, and restore the original settings when it\'s done. Here\'s what you do:').'</p><ol><li>'.__('Back up your Blogger template.').'</li><li>'.__('Back up any other Blogger settings you might need later.').'</li><li>'.__('Log out of Blogger').'</li><li>'.__('Log in <em>here</em> with your Blogger username and password.').'</li><li>'.__('On the next screen, click one of your Blogger blogs.').'</li><li>'.__('Do not close this window or navigate away until the process is complete.').'</li></ol>');
-			}
-
-			// Try logging in. If we get an array of cookies back, we at least connected.
-			$this->import['cookies'] = $this->login_blogger($_POST['user'], $_POST['pass']);
-			if ( !is_array( $this->import['cookies'] ) ) {
-				$this->login_form(__('Login failed. Please enter your credentials again.'));
-			}
-
-			// Save the password so we can log the browser in when it's time to publish.
-			$this->import['pass'] = $_POST['pass'];
-			$this->import['user'] = $_POST['user'];
-
-			// Get the Blogger welcome page and scrape the blog numbers and names from it
-			$response = $this->get_blogger('http://www.blogger.com/home', $this->import['cookies']);
-			if (! stristr($response['body'], 'signed in as') ) $this->login_form(__('Login failed. Please re-enter your username and password.'));
-			$blogsary = array();
-			preg_match_all('#posts\.g\?blogID=(\d+)">([^<]+)</a>#U', $response['body'], $blogsary);
-			if ( ! count( $blogsary[1] < 1 ) )
-				die(__('No blogs found for this user.'));
-			$this->import['blogs'] = array();
-			$template = '<MainPage><br /><br /><br /><p>'.__('Are you looking for %title%? It is temporarily out of service. Please try again in a few minutes. Meanwhile, discover <a href="http://wordpress.org/">a better blogging tool</a>.').'</p><BloggerArchives><a class="archive" href="<$BlogArchiveURL$>"><$BlogArchiveName$></a><br /></BloggerArchives></MainPage><ArchivePage><Blogger><wordpresspost><$BlogItemDateTime$>|W|P|<$BlogItemAuthorNickname$>|W|P|<$BlogItemBody$>|W|P|<$BlogItemNumber$>|W|P|<$BlogItemTitle$>|W|P|<$BlogItemAuthorEmail$><BlogItemCommentsEnabled><BlogItemComments><wordpresscomment><$BlogCommentDateTime$>|W|P|<$BlogCommentAuthor$>|W|P|<$BlogCommentBody$></BlogItemComments></BlogItemCommentsEnabled></Blogger></ArchivePage>';
-			foreach ( $blogsary[1] as $key => $id ) {
-				// Define the required Blogger options.
-				$blog_opts = array(
-					'blog-options-basic' => false,
-					'blog-options-archiving' => array('archiveFrequency' => 'm'),
-					'blog-publishing' => array('publishMode'=>'0', 'blogID' => "$id", 'subdomain' => mt_rand().mt_rand(), 'pingWeblogs' => 'false'),
-					'blog-formatting' => array('timeStampFormat' => '0', 'encoding'=>'UTF-8', 'convertLineBreaks'=>'false', 'floatAlignment'=>'false'),
-					'blog-comments' => array('commentsTimeStampFormat' => '0'),
-					'template-edit' => array( 'templateText' =>  str_replace('%title%', trim($blogsary[2][$key]), $template) )
-				);
+	function save_vars() {
+		$vars = get_object_vars($this);
+		update_option( 'blogger_importer', $vars );
 
-				// Build the blog options array template
-				foreach ($blog_opts as $blog_opt => $modify)
-					$new_opts["$blog_opt"] = array('backup'=>false, 'modify' => $modify, 'error'=>false);
-
-				$this->import['blogs']["$id"] = array(
-					'id' => $id,
-					'title' => trim($blogsary[2][$key]),
-					'options' => $new_opts,
-					'url' => false,
-					'publish_cookies' => false,
-					'published' => false,
-					'archives' => false,
-					'lump_authors' => false,
-					'newusers' => array(),
-					'nextstep' => 2
-				);
-			}
-			update_option('import-blogger', $this->import);
-			wp_redirect("admin.php?import=blogger&noheader=true&step=1");
-		}
-		die();
+		return !empty($vars);
 	}
 
-	// Step 1: Select one of the blogs belonging to the user logged in.
-	function select_blog() {
-		if ( is_array($this->import['blogs']) ) {
-			$this->show_blogs();
-			die();
-		} else {
-			$this->restart();
-		}
+	function admin_head() {
+?>
+<style type="text/css">
+td { text-align: center; line-height: 2em;}
+thead td { font-weight: bold; }
+.bar {
+	width: 200px;
+	text-align: left;
+	line-height: 2em;
+	padding: 0px;
+}
+.ind {
+	position: absolute;
+	background-color: #83B4D8;
+	width: 1px;
+	z-index: 9;
+}
+.stat {
+	z-index: 10;
+	position: relative;
+	text-align: center;
+}
+.submit {
+	text-align: center !important;
+}
+</style>
+<?php
 	}
 
-	// Step 2: Backup the Blogger options pages, updating some of them.
-	function backup_settings() {
-		$output.= '<h1>'.__('Backing up Blogger options')."</h1>\n";
-		$form = false;
-		foreach ($this->import['blogs'][$_GET['blog']]['options'] as $blog_opt => $optary) {
-			if ( $blog_opt == $_GET['form'] ) {
-				// Save the posted form data
-				$this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['backup'] = $_POST;
-				update_option('import-blogger',$this->import);
-
-				// Post the modified form data to Blogger
-				if ( $optary['modify'] ) {
-					$posturl = "http://www.blogger.com/{$blog_opt}.do";
-					$headers = array_merge($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'], $this->import['cookies']);
-					if ( 'blog-publishing' == $blog_opt ) {
-						if ( $_POST['publishMode'] > 0 ) {
-							$response = $this->get_blogger("http://www.blogger.com/blog-publishing.g?blogID={$_GET['blog']}&publishMode=0", $headers);
-							if ( $response['code'] >= 400 )
-								die('<h2>'.__('Failed attempt to change publish mode from FTP to BlogSpot.').'</h2><pre>' . addslashes(print_r($headers, 1)) . addslashes(print_r($response, 1)) . '</pre>');
-							$this->import['blogs'][$_GET['blog']]['url'] = 'http://' . $optary['modify']['subdomain'] . '.blogspot.com/';
-							sleep(2);
-						} else {
-							$this->import['blogs'][$_GET['blog']]['url'] = 'http://' . $_POST['subdomain'] . '.blogspot.com/';
-							update_option('import-blogger', $this->import);
-							$output .= "<del><p>$blog_opt</p></del>\n";
-							continue;
-						}
-						$paramary = $optary['modify'];
-					} else {
-						$paramary = array_merge($_POST, $optary['modify']);
-					}
-					$response = $this->post_blogger($posturl, $headers, $paramary);
-					if ( $response['code'] >= 400 || strstr($response['body'], 'There are errors on this form') )
-						die('<p>'.__('Error on form submission. Retry or reset the importer.').'</p>' . addslashes(print_r($response, 1)));
-				}
-				$output .= "<del><p>$blog_opt</p></del>\n";
-			} elseif ( is_array($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['backup']) ) {
-				// This option set has already been backed up.
-				$output .= "<del><p>$blog_opt</p></del>\n";
-			} elseif ( ! $form ) {
-				// This option page needs to be downloaded and given to the browser for submission back to this script.
-				$response = $this->get_blogger("http://www.blogger.com/{$blog_opt}.g?blogID={$_GET['blog']}", $this->import['cookies']);
-				$this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'] = $response['cookies'];
-				update_option('import-blogger',$this->import);
-				$body = $response['body'];
-				$body = preg_replace("|\<!DOCTYPE.*\<body[^>]*>|ms","",$body);
-				$body = preg_replace("|/?{$blog_opt}.do|","admin.php?import=blogger&amp;noheader=true&amp;step=2&amp;blog={$_GET['blog']}&amp;form={$blog_opt}",$body);
-				$body = str_replace("name='submit'","name='supermit'",$body);
-				$body = str_replace('name="submit"','name="supermit"',$body);
-				$body = str_replace('</body>','',str_replace('</html>','',$body));
-				$form = "<div style='height:0px;width:0px;overflow:hidden;'>";
-				$form.= $body;
-				$form.= "</div><script type='text/javascript'>forms=document.getElementsByTagName('form');for(i=0;i<forms.length;i++){if(forms[i].action.search('{$blog_opt}')){forms[i].submit();break;}}</script>";
-				$output.= '<p>'.sprintf(__('<strong>%s</strong> in progress, please wait...'), $blog_opt)."</p>\n";
-			} else {
-				$output.= "<p>$blog_opt</p>\n";
-			}
+	function Blogger_Import() {
+		global $importer_started;
+		$importer_started = time();
+		if ( isset( $_GET['import'] ) && $_GET['import'] == 'blogger' ) {
+			wp_enqueue_script('jquery');
+			add_action('admin_head', array(&$this, 'admin_head'));
 		}
-		if ( $form )
-			die($output . $form);
-
-		$this->set_next_step(4);
-		$this->do_next_step();
 	}
+}
+
+$blogger_import = new Blogger_Import();
+
+register_importer('blogger', __('Blogger'), __('Import posts, comments, and users from a Blogger blog'), array ($blogger_import, 'start'));
+
+class AtomEntry {
+	var $links = array();
+	var $categories = array();
+}
+
+class AtomParser {
+
+	var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');
+	var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft','author');
+
+	var $depth = 0;
+	var $indent = 2;
+	var $in_content;
+	var $ns_contexts = array();
+	var $ns_decls = array();
+	var $is_xhtml = false;
+	var $skipped_div = false;
 
-	// Step 3: Cancelled :-)
+	var $entry;
 
-	// Step 4: Publish with the new template and settings.
-	function publish_blog() {
-		$this->publish_blogger(5, __('Publishing with new template and options'));
+	function AtomParser() {
+
+		$this->entry = new AtomEntry();
+		$this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";');
+		$this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";');
 	}
 
-	// Step 5: Get the archive URLs from the new blog.
-	function get_archive_urls() {
-		$bloghtml = $this->get_blogger($this->import['blogs'][$_GET['blog']]['url']);
-		if (! strstr($bloghtml['body'], '<a class="archive"') )
-			die(__('Your Blogger blog did not take the new template or did not respond.'));
-		preg_match_all('#<a class="archive" href="([^"]*)"#', $bloghtml['body'], $archives);
-		foreach ($archives[1] as $archive) {
-			$this->import['blogs'][$_GET['blog']]['archives'][$archive] = false;
-		}
-		$this->set_next_step(6);
-		$this->do_next_step();
+	function parse($xml) {
+
+		global $app_logging;
+		array_unshift($this->ns_contexts, array());
+
+		$parser = xml_parser_create_ns();
+		xml_set_object($parser, $this);
+		xml_set_element_handler($parser, "start_element", "end_element");
+		xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
+		xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
+		xml_set_character_data_handler($parser, "cdata");
+		xml_set_default_handler($parser, "_default");
+		xml_set_start_namespace_decl_handler($parser, "start_ns");
+		xml_set_end_namespace_decl_handler($parser, "end_ns");
+
+		$contents = "";
+
+		xml_parse($parser, $xml);
+
+		xml_parser_free($parser);
+
+		return true;
 	}
 
-	// Step 6: Get each monthly archive, import it, mark it done.
-	function get_archive() {
-		global $wpdb;
-		$output = '<h2>'.__('Importing Blogger archives into WordPress').'</h2>';
-		$did_one = false;
-		$post_array = $posts = array();
-		foreach ( $this->import['blogs'][$_GET['blog']]['archives'] as $url => $status ) {
-			$archivename = substr(basename($url),0,7);
-			if ( $status || $did_one ) {
-				$foo = 'bar';
-				// Do nothing.
-			} else {
-				// Import the selected month
-				$postcount = 0;
-				$skippedpostcount = 0;
-				$commentcount = 0;
-				$skippedcommentcount = 0;
-				$status = __('in progress...');
-				$this->import['blogs'][$_GET['blog']]['archives']["$url"] = $status;
-				update_option('import-blogger', $import);
-				$archive = $this->get_blogger($url);
-				if ( $archive['code'] > 200 )
-					continue;
-				$posts = explode('<wordpresspost>', $archive['body']);
-				for ($i = 1; $i < count($posts); $i = $i + 1) {
-					$postparts = explode('<wordpresscomment>', $posts[$i]);
-					$postinfo = explode('|W|P|', $postparts[0]);
-					$post_date = $postinfo[0];
-					$post_content = $postinfo[2];
-					// Don't try to re-use the original numbers
-					// because the new, longer numbers are too
-					// big to handle as ints.
-					//$post_number = $postinfo[3];
-					$post_title = ( $postinfo[4] != '' ) ? $postinfo[4] : $postinfo[3];
-					$post_author_name = $wpdb->escape(trim($postinfo[1]));
-					$post_author_email = $postinfo[5] ? $postinfo[5] : 'user@wordpress.org';
-
-					if ( $this->lump_authors ) {
-						// Ignore Blogger authors. Use the current user_ID for all posts imported.
-						$post_author = $GLOBALS['user_ID'];
-					} else {
-						// Add a user for each new author encountered.
-						if (! username_exists($post_author_name) ) {
-							$user_login = $wpdb->escape($post_author_name);
-							$user_email = $wpdb->escape($post_author_email);
-							$user_password = substr(md5(uniqid(microtime())), 0, 6);
-							$result = wp_create_user( $user_login, $user_password, $user_email );
-							$status.= sprintf(__('Registered user <strong>%s</strong>.'), $user_login);
-							$this->import['blogs'][$_GET['blog']]['newusers'][] = $user_login;
-						}
-						$userdata = get_userdatabylogin( $post_author_name );
-						$post_author = $userdata->ID;
-					}
-					$post_date = explode(' ', $post_date);
-					$post_date_Ymd = explode('/', $post_date[0]);
-					$postyear = $post_date_Ymd[2];
-					$postmonth = zeroise($post_date_Ymd[0], 2);
-					$postday = zeroise($post_date_Ymd[1], 2);
-					$post_date_His = explode(':', $post_date[1]);
-					$posthour = zeroise($post_date_His[0], 2);
-					$postminute = zeroise($post_date_His[1], 2);
-					$postsecond = zeroise($post_date_His[2], 2);
-
-					if (($post_date[2] == 'PM') && ($posthour != '12'))
-						$posthour = $posthour + 12;
-					else if (($post_date[2] == 'AM') && ($posthour == '12'))
-						$posthour = '00';
-
-					$post_date = "$postyear-$postmonth-$postday $posthour:$postminute:$postsecond";
-
-					$post_content = addslashes($post_content);
-					$post_content = str_replace(array('<br>','<BR>','<br/>','<BR/>','<br />','<BR />'), "\n", $post_content); // the XHTML touch... ;)
-
-					$post_title = addslashes($post_title);
-
-					$post_status = 'publish';
-
-					if ( $ID = post_exists($post_title, '', $post_date) ) {
-						$post_array[$i]['ID'] = $ID;
-						$skippedpostcount++;
-					} else {
-						$post_array[$i]['post'] = compact('post_author', 'post_content', 'post_title', 'post_category', 'post_author', 'post_date', 'post_status');
-						$post_array[$i]['comments'] = false;
-					}
+	function start_element($parser, $name, $attrs) {
 
-					// Import any comments attached to this post.
-					if ($postparts[1]) :
-					for ($j = 1; $j < count($postparts); $j = $j + 1) {
-						$commentinfo = explode('|W|P|', $postparts[$j]);
-						$comment_date = explode(' ', $commentinfo[0]);
-						$comment_date_Ymd = explode('/', $comment_date[0]);
-						$commentyear = $comment_date_Ymd[2];
-						$commentmonth = zeroise($comment_date_Ymd[0], 2);
-						$commentday = zeroise($comment_date_Ymd[1], 2);
-						$comment_date_His = explode(':', $comment_date[1]);
-						$commenthour = zeroise($comment_date_His[0], 2);
-						$commentminute = zeroise($comment_date_His[1], 2);
-						$commentsecond = '00';
-						if (($comment_date[2] == 'PM') && ($commenthour != '12'))
-							$commenthour = $commenthour + 12;
-						else if (($comment_date[2] == 'AM') && ($commenthour == '12'))
-							$commenthour = '00';
-						$comment_date = "$commentyear-$commentmonth-$commentday $commenthour:$commentminute:$commentsecond";
-						$comment_author = addslashes(strip_tags($commentinfo[1]));
-						if ( strpos($commentinfo[1], 'a href') ) {
-							$comment_author_parts = explode('&quot;', htmlentities($commentinfo[1]));
-							$comment_author_url = $comment_author_parts[1];
-						} else $comment_author_url = '';
-						$comment_content = $commentinfo[2];
-						$comment_content = str_replace(array('<br>','<BR>','<br/>','<BR/>','<br />','<BR />'), "\n", $comment_content);
-						$comment_approved = 1;
-						if ( comment_exists($comment_author, $comment_date) ) {
-							$skippedcommentcount++;
-						} else {
-							$comment = compact('comment_author', 'comment_author_url', 'comment_date', 'comment_content', 'comment_approved');
-							$post_array[$i]['comments'][$j] = wp_filter_comment($comment);
-						}
-						$commentcount++;
-					}
-					endif;
-					$postcount++;
-				}
-				if ( count($post_array) ) {
-					krsort($post_array);
-					foreach($post_array as $post) {
-						if ( ! $comment_post_ID = $post['ID'] )
-							$comment_post_ID = wp_insert_post($post['post']);
-						if ( $post['comments'] ) {
-							foreach ( $post['comments'] as $comment ) {
-								$comment['comment_post_ID'] = $comment_post_ID;
-								wp_insert_comment($comment);
-							}
-						}
-					}
+		$tag = array_pop(split(":", $name));
+
+		array_unshift($this->ns_contexts, $this->ns_decls);
+
+		$this->depth++;
+
+		if(!empty($this->in_content)) {
+			$attrs_prefix = array();
+
+			// resolve prefixes for attributes
+			foreach($attrs as $key => $value) {
+				$attrs_prefix[$this->ns_to_prefix($key)] = $this->xml_escape($value);
+			}
+			$attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));
+			if(strlen($attrs_str) > 0) {
+				$attrs_str = " " . $attrs_str;
+			}
+
+			$xmlns_str = join(' ', array_map($this->map_xmlns_func, array_keys($this->ns_contexts[0]), array_values($this->ns_contexts[0])));
+			if(strlen($xmlns_str) > 0) {
+				$xmlns_str = " " . $xmlns_str;
+			}
+
+			// handle self-closing tags (case: a new child found right-away, no text node)
+			if(count($this->in_content) == 2) {
+				array_push($this->in_content, ">");
+			}
+		 
+			array_push($this->in_content, "<". $this->ns_to_prefix($name) ."{$xmlns_str}{$attrs_str}");
+		} else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {
+			$this->in_content = array();
+			$this->is_xhtml = $attrs['type'] == 'xhtml'; 
+			array_push($this->in_content, array($tag,$this->depth));
+		} else if($tag == 'link') {
+			array_push($this->entry->links, $attrs);
+		} else if($tag == 'category') {
+			array_push($this->entry->categories, $attrs['term']);
+		}
+
+		$this->ns_decls = array();
+	}
+
+	function end_element($parser, $name) {
+
+		$tag = array_pop(split(":", $name));
+
+		if(!empty($this->in_content)) {
+			if($this->in_content[0][0] == $tag && 
+			$this->in_content[0][1] == $this->depth) {
+				array_shift($this->in_content);
+				if($this->is_xhtml) {
+					$this->in_content = array_slice($this->in_content, 2, count($this->in_content)-3);
 				}
-				$status = sprintf(__('%s post(s) parsed, %s skipped...'), $postcount,  $skippedpostcount).' '.
-					sprintf(__('%s comment(s) parsed, %s skipped...'), $commentcount, $skippedcommentcount).' '.
-					' <strong>'.__('Done').'</strong>';
-				$import = $this->import;
-				$import['blogs'][$_GET['blog']]['archives']["$url"] = $status;
-				update_option('import-blogger', $import);
-				$did_one = true;
-			}
-			$output.= "<p>$archivename $status</p>\n";
- 		}
-		if ( ! $did_one )
-			$this->set_next_step(7);
-		die( $this->refresher(1000) . $output );
-	}
-
-	// Step 7: Restore the backed-up settings to Blogger
-	function restore_settings() {
-		$output = '<h1>'.__('Restoring your Blogger options')."</h1>\n";
-		$did_one = false;
-		// Restore options in reverse order.
-		if ( ! $this->import['reversed'] ) {
-			$this->import['blogs'][$_GET['blog']]['options'] = array_reverse($this->import['blogs'][$_GET['blog']]['options'], true);
-			$this->import['reversed'] = true;
-			update_option('import-blogger', $this->import);
-		}
-		foreach ( $this->import['blogs'][$_GET['blog']]['options'] as $blog_opt => $optary ) {
-			if ( $did_one ) {
-				$output .= "<p>$blog_opt</p>\n";
-			} elseif ( $optary['restored'] || ! $optary['modify'] ) {
-				$output .= "<p><del>$blog_opt</del></p>\n";
+				$this->entry->$tag = join('',$this->in_content);
+				$this->in_content = array();
 			} else {
-				$posturl = "http://www.blogger.com/{$blog_opt}.do";
-				$headers = array_merge($this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['cookies'], $this->import['cookies']);
-				if ( 'blog-publishing' == $blog_opt) {
-					if ( $optary['backup']['publishMode'] > 0 ) {
-						$response = $this->get_blogger("http://www.blogger.com/blog-publishing.g?blogID={$_GET['blog']}&publishMode={$optary['backup']['publishMode']}", $headers);
-						sleep(2);
-						if ( $response['code'] >= 400 )
-							die('<h1>'.__('Error restoring publishMode').'</h1><p>'.__('Please tell the devs.').'</p>' . addslashes(print_r($response, 1)) );
-					}
+				$endtag = $this->ns_to_prefix($name);
+				if (strpos($this->in_content[count($this->in_content)-1], '<' . $endtag) !== false) {
+					array_push($this->in_content, "/>");
+				} else {
+					array_push($this->in_content, "</$endtag>");
 				}
-				if ( $optary['backup'] != $optary['modify'] ) {
-					$response = $this->post_blogger($posturl, $headers, $optary['backup']);
-					if ( $response['code'] >= 400 || strstr($response['body'], 'There are errors on this form') ) {
-						$this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['error'] = true;
-						update_option('import-blogger', $this->import);
-						$output .= sprintf(__('%s failed. Trying again.'), "<p><strong>$blog_opt</strong> ").'</p>';
-					} else {
-						$this->import['blogs'][$_GET['blog']]['options']["$blog_opt"]['restored'] = true;
-						update_option('import-blogger', $this->import);
-						$output .= sprintf(__('%s restored.'), "<p><strong>$blog_opt</strong> ").'</p>';
-					}
-				}
-				$did_one = true;
 			}
 		}
 
-		if ( $did_one ) {
-			die( $this->refresher(1000) . $output );
-		} elseif ( $this->import['blogs'][$_GET['blog']]['options']['blog-publishing']['backup']['publishMode'] > 0 ) {
-			$this->set_next_step(9);
-		} else {
-			$this->set_next_step(8);
-		}
+		array_shift($this->ns_contexts);
+
+		#print str_repeat(" ", $this->depth * $this->indent) . "end_element('$name')" ."\n";
 
-		$this->do_next_step();
+		$this->depth--;
 	}
 
-	// Step 8: Republish, all back to normal
-	function republish_blog() {
-		$this->publish_blogger(9, __('Publishing with original template and options'));
+	function start_ns($parser, $prefix, $uri) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "starting: " . $prefix . ":" . $uri . "\n";
+		array_push($this->ns_decls, array($prefix,$uri));
 	}
 
-	// Step 9: Congratulate the user
-	function congrats() {
-		echo '<h1>'.__('Congratulations!').'</h1><p>'.__('Now that you have imported your Blogger blog into WordPress, what are you going to do? Here are some suggestions:').'</p><ul><li>'.__('That was hard work! Take a break.').'</li>';
-		if ( count($this->import['blogs']) > 1 )
-			echo '<li>'.__('In case you haven\'t done it already, you can import the posts from your other blogs:'). $this->show_blogs() . '</li>';
-		if ( $n = count($this->import['blogs'][$_GET['blog']]['newusers']) )
-			echo '<li>'.sprintf(__('Go to <a href="%s" target="%s">Authors &amp; Users</a>, where you can modify the new user(s) or delete them. If you want to make all of the imported posts yours, you will be given that option when you delete the new authors.'), 'users.php', '_parent').'</li>';
-		echo '<li>'.__('For security, click the link below to reset this importer. That will clear your Blogger credentials and options from the database.').'</li>';
-		echo '</ul>';
+	function end_ns($parser, $prefix) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "ending: #" . $prefix . "#\n";
 	}
 
-	// Figures out what to do, then does it.
-	function start() {
-		if ( $_GET['restart'] == 'true' ) {
-			$this->restart();
+	function cdata($parser, $data) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "data: #" . $data . "#\n";
+		if(!empty($this->in_content)) {
+			// handle self-closing tags (case: text node found, need to close element started)
+			if (strpos($this->in_content[count($this->in_content)-1], '<') !== false) {
+				array_push($this->in_content, ">");
+			}
+			array_push($this->in_content, $this->xml_escape($data));
 		}
+	}
 
-		if ( isset($_GET['noheader']) ) {
-			header('Content-Type: text/html; charset=utf-8');
+	function _default($parser, $data) {
+		# when does this gets called?
+	}
 
-			$this->import = get_option('import-blogger');
 
-			if ( false === $this->import ) {
-				$step = 0;
-			} elseif ( isset($_GET['step']) ) {
-				$step = (int) $_GET['step'];
-			} elseif ( isset($_GET['blog']) && isset($this->import['blogs'][$_GET['blog']]['nextstep']) ) {
-				$step = $this->import['blogs'][$_GET['blog']]['nextstep'];
-			} elseif ( is_array($this->import['blogs']) ) {
-				$step = 1;
-			} else {
-				$step = 0;
-			}
-//echo "Step $step.";
-//die('<pre>'.print_r($this->import,1).'</pre');
-			switch ($step) {
-				case 0 :
-					$this->do_login();
-					break;
-				case 1 :
-					$this->select_blog();
-					break;
-				case 2 :
-					$this->backup_settings();
-					break;
-				case 3 :
-					$this->wait_for_blogger();
-					break;
-				case 4 :
-					$this->publish_blog();
-					break;
-				case 5 :
-					$this->get_archive_urls();
-					break;
-				case 6 :
-					$this->get_archive();
-					break;
-				case 7 :
-					$this->restore_settings();
-					break;
-				case 8 :
-					$this->republish_blog();
-					break;
-				case 9 :
-					$this->congrats();
-					break;
-			}
-			die;
+	function ns_to_prefix($qname) {
+		$components = split(":", $qname);
+		$name = array_pop($components);
 
-		} else {
-			$this->greet();
-		}
+		if(!empty($components)) {
+			$ns = join(":",$components);
+			foreach($this->ns_contexts as $context) {
+				foreach($context as $mapping) {
+					if($mapping[1] == $ns && strlen($mapping[0]) > 0) {
+						return "$mapping[0]:$name";
+					}
+				}
+			}
+		} 
+		return $name;
 	}
 
-	function Blogger_Import() {
-		// This space intentionally left blank.
+	function xml_escape($string)
+	{
+			 return str_replace(array('&','"',"'",'<','>'), 
+				array('&amp;','&quot;','&apos;','&lt;','&gt;'), 
+				$string );
 	}
 }
 
-$blogger_import = new Blogger_Import();
-
-register_importer('blogger', __('Blogger and Blogspot'), __('Import <strong>posts and comments</strong> from your Blogger account'), array ($blogger_import, 'start'));
-
 ?>
diff -ruN 2.0.5/wp-admin/import/blogware.php 2.2.2/wp-admin/import/blogware.php
--- 2.0.5/wp-admin/import/blogware.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/import/blogware.php	2007-03-22 19:59:21.000000000 -0500
@@ -0,0 +1,194 @@
+<?php
+
+/* By Shayne Sweeney - http://www.theshayne.com/ */
+
+class BW_Import {
+
+	var $file;
+
+	function header() {
+		echo '<div class="wrap">';
+		echo '<h2>'.__('Import Blogware').'</h2>';
+	}
+
+	function footer() {
+		echo '</div>';
+	}
+
+	function unhtmlentities($string) { // From php.net for < 4.3 compat
+		$trans_tbl = get_html_translation_table(HTML_ENTITIES);
+		$trans_tbl = array_flip($trans_tbl);
+		return strtr($string, $trans_tbl);
+	}
+
+	function greet() {
+		echo '<div class="narrow">';
+		echo '<p>'.__('Howdy! This importer allows you to extract posts from Blogware XML export file into your blog.  Pick a Blogware file to upload and click Import.').'</p>';
+		wp_import_upload_form("admin.php?import=blogware&amp;step=1");
+		echo '</div>';
+	}
+
+	function import_posts() {
+		global $wpdb, $current_user;
+
+		set_magic_quotes_runtime(0);
+		$importdata = file($this->file); // Read the file into an array
+		$importdata = implode('', $importdata); // squish it
+		$importdata = str_replace(array ("\r\n", "\r"), "\n", $importdata);
+
+		preg_match_all('|(<item[^>]+>(.*?)</item>)|is', $importdata, $posts);
+		$posts = $posts[1];
+		unset($importdata);
+		echo '<ol>';
+		foreach ($posts as $post) {
+			flush();
+			preg_match('|<item type=\"(.*?)\">|is', $post, $post_type);
+			$post_type = $post_type[1];
+			if($post_type == "photo") {
+				preg_match('|<photoFilename>(.*?)</photoFilename>|is', $post, $post_title);
+			} else {
+				preg_match('|<title>(.*?)</title>|is', $post, $post_title);
+			}
+			$post_title = $wpdb->escape(trim($post_title[1]));
+
+			preg_match('|<pubDate>(.*?)</pubDate>|is', $post, $post_date);
+			$post_date = strtotime($post_date[1]);
+			$post_date = gmdate('Y-m-d H:i:s', $post_date);
+
+			preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
+			$categories = $categories[1];
+
+			$cat_index = 0;
+			foreach ($categories as $category) {
+				$categories[$cat_index] = $wpdb->escape($this->unhtmlentities($category));
+				$cat_index++;
+			}
+
+			if(strcasecmp($post_type, "photo") === 0) {
+				preg_match('|<sizedPhotoUrl>(.*?)</sizedPhotoUrl>|is', $post, $post_content);
+				$post_content = '<img src="'.trim($post_content[1]).'" />';
+				$post_content = $this->unhtmlentities($post_content);
+			} else {
+				preg_match('|<body>(.*?)</body>|is', $post, $post_content);
+				$post_content = str_replace(array ('<![CDATA[', ']]>'), '', trim($post_content[1]));
+				$post_content = $this->unhtmlentities($post_content);
+			}
+
+			// Clean up content
+			$post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
+			$post_content = str_replace('<br>', '<br />', $post_content);
+			$post_content = str_replace('<hr>', '<hr />', $post_content);
+			$post_content = $wpdb->escape($post_content);
+
+			$post_author = $current_user->ID;
+			preg_match('|<postStatus>(.*?)</postStatus>|is', $post, $post_status);
+			$post_status = trim($post_status[1]);
+
+			echo '<li>';
+			if ($post_id = post_exists($post_title, $post_content, $post_date)) {
+				printf(__('Post <i>%s</i> already exists.'), stripslashes($post_title));
+			} else {
+				printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
+				$postdata = compact('post_author', 'post_date', 'post_content', 'post_title', 'post_status');
+				$post_id = wp_insert_post($postdata);
+				if (!$post_id) {
+					_e("Couldn't get post ID");
+					echo '</li>';
+					break;
+				}
+				if(0 != count($categories))
+					wp_create_categories($categories, $post_id);
+			}
+
+			preg_match_all('|<comment>(.*?)</comment>|is', $post, $comments);
+			$comments = $comments[1];
+
+			if ( $comments ) {
+				$comment_post_ID = (int) $post_id;
+				$num_comments = 0;
+				foreach ($comments as $comment) {
+					preg_match('|<body>(.*?)</body>|is', $comment, $comment_content);
+					$comment_content = str_replace(array ('<![CDATA[', ']]>'), '', trim($comment_content[1]));
+					$comment_content = $this->unhtmlentities($comment_content);
+
+					// Clean up content
+					$comment_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $comment_content);
+					$comment_content = str_replace('<br>', '<br />', $comment_content);
+					$comment_content = str_replace('<hr>', '<hr />', $comment_content);
+					$comment_content = $wpdb->escape($comment_content);
+
+					preg_match('|<pubDate>(.*?)</pubDate>|is', $comment, $comment_date);
+					$comment_date = trim($comment_date[1]);
+					$comment_date = date('Y-m-d H:i:s', strtotime($comment_date));
+
+					preg_match('|<author>(.*?)</author>|is', $comment, $comment_author);
+					$comment_author = $wpdb->escape(trim($comment_author[1]));
+
+					$comment_author_email = NULL;
+
+					$comment_approved = 1;
+					// Check if it's already there
+					if (!comment_exists($comment_author, $comment_date)) {
+						$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_date', 'comment_content', 'comment_approved');
+						$commentdata = wp_filter_comment($commentdata);
+						wp_insert_comment($commentdata);
+						$num_comments++;
+					}
+				}
+			}
+			if ( $num_comments ) {
+				echo ' ';
+				printf(__('(%s comments)'), $num_comments);
+			}
+			echo '</li>';
+			flush();
+			ob_flush();
+		}
+		echo '</ol>';
+	}
+
+	function import() {
+		$file = wp_import_handle_upload();
+		if ( isset($file['error']) ) {
+			echo $file['error'];
+			return;
+		}
+
+		$this->file = $file['file'];
+		$this->import_posts();
+		wp_import_cleanup($file['id']);
+
+		echo '<h3>';
+		printf(__('All done. <a href="%s">Have fun!</a>'), get_option('home'));
+		echo '</h3>';
+	}
+
+	function dispatch() {
+		if (empty ($_GET['step']))
+			$step = 0;
+		else
+			$step = (int) $_GET['step'];
+
+		$this->header();
+
+		switch ($step) {
+			case 0 :
+				$this->greet();
+				break;
+			case 1 :
+				$this->import();
+				break;
+		}
+
+		$this->footer();
+	}
+
+	function BW_Import() {
+		// Nothing.
+	}
+}
+
+$blogware_import = new BW_Import();
+
+register_importer('blogware', __('Blogware'), __('Import posts from Blogware'), array ($blogware_import, 'dispatch'));
+?>
diff -ruN 2.0.5/wp-admin/import/dotclear.php 2.2.2/wp-admin/import/dotclear.php
--- 2.0.5/wp-admin/import/dotclear.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/dotclear.php	2007-05-07 10:57:15.000000000 -0500
@@ -1,16 +1,21 @@
 <?php
+/*
+ * DotClear import plugin
+ * by Thomas Quinot - http://thomas.quinot.org/
+ */
+
 /**
 	Add These Functions to make our lives easier
 **/
 if(!function_exists('get_catbynicename'))
 {
-	function get_catbynicename($category_nicename) 
+	function get_catbynicename($category_nicename)
 	{
 	global $wpdb;
-	
+
 	$cat_id -= 0; 	// force numeric
 	$name = $wpdb->get_var('SELECT cat_ID FROM '.$wpdb->categories.' WHERE category_nicename="'.$category_nicename.'"');
-	
+
 	return $name;
 	}
 }
@@ -55,57 +60,58 @@
 //
 //    This cries out for a C-implementation to be included in PHP core
 //
-   function valid_1byte($char) {
-       if(!is_int($char)) return false;
-       return ($char & 0x80) == 0x00;
-   }
-  
-   function valid_2byte($char) {
-       if(!is_int($char)) return false;
-       return ($char & 0xE0) == 0xC0;
-   }
-
-   function valid_3byte($char) {
-       if(!is_int($char)) return false;
-       return ($char & 0xF0) == 0xE0;
-   }
-
-   function valid_4byte($char) {
-       if(!is_int($char)) return false;
-       return ($char & 0xF8) == 0xF0;
-   }
-  
-   function valid_nextbyte($char) {
-       if(!is_int($char)) return false;
-       return ($char & 0xC0) == 0x80;
-   }
-  
-   function valid_utf8($string) {
-       $len = strlen($string);
-       $i = 0;   
-       while( $i < $len ) {
-           $char = ord(substr($string, $i++, 1));
-           if(valid_1byte($char)) {    // continue
-               continue;
-           } else if(valid_2byte($char)) { // check 1 byte
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-           } else if(valid_3byte($char)) { // check 2 bytes
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-           } else if(valid_4byte($char)) { // check 3 bytes
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-               if(!valid_nextbyte(ord(substr($string, $i++, 1))))
-                   return false;
-           } // goto next char
-       }
-       return true; // done
-   }
+
+function valid_1byte($char) {
+	if(!is_int($char)) return false;
+		return ($char & 0x80) == 0x00;
+}
+
+function valid_2byte($char) {
+	if(!is_int($char)) return false;
+		return ($char & 0xE0) == 0xC0;
+}
+
+function valid_3byte($char) {
+	if(!is_int($char)) return false;
+		return ($char & 0xF0) == 0xE0;
+}
+
+function valid_4byte($char) {
+	if(!is_int($char)) return false;
+		return ($char & 0xF8) == 0xF0;
+}
+
+function valid_nextbyte($char) {
+	if(!is_int($char)) return false;
+		return ($char & 0xC0) == 0x80;
+}
+
+function valid_utf8($string) {
+	$len = strlen($string);
+	$i = 0;
+	while( $i < $len ) {
+		$char = ord(substr($string, $i++, 1));
+		if(valid_1byte($char)) {    // continue
+			continue;
+		} else if(valid_2byte($char)) { // check 1 byte
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+		} else if(valid_3byte($char)) { // check 2 bytes
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+		} else if(valid_4byte($char)) { // check 3 bytes
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+			if(!valid_nextbyte(ord(substr($string, $i++, 1))))
+				return false;
+		} // goto next char
+	}
+	return true; // done
+}
 
 function csc ($s) {
 	if (valid_utf8 ($s)) {
@@ -127,7 +133,7 @@
 	function header() 
 	{
 		echo '<div class="wrap">';
-		echo '<h2>'.__('Import Dotclear').'</h2>';
+		echo '<h2>'.__('Import DotClear').'</h2>';
 		echo '<p>'.__('Steps may take a few minutes depending on the size of your database. Please be patient.').'</p>';
 	}
 
@@ -135,78 +141,79 @@
 	{
 		echo '</div>';
 	}
-	
+
 	function greet() 
 	{
-		echo '<p>'.__('Howdy! This importer allows you to extract posts from a Dotclear database into your blog.  Mileage may vary.').'</p>';
-		echo '<p>'.__('Your Dotclear Configuration settings are as follows:').'</p>';
+		echo '<div class="narrow"><p>'.__('Howdy! This importer allows you to extract posts from a DotClear database into your blog.  Mileage may vary.').'</p>';
+		echo '<p>'.__('Your DotClear Configuration settings are as follows:').'</p>';
 		echo '<form action="admin.php?import=dotclear&amp;step=1" method="post">';
+		wp_nonce_field('import-dotclear');
 		$this->db_form();
-		echo '<input type="submit" name="submit" value="'.__('Import Categories').'" />';
-		echo '</form>';
+		echo '<p class="submit"><input type="submit" name="submit" value="'.attribute_escape(__('Import Categories &raquo;')).'" /></p>';
+		echo '</form></div>';
 	}
 
-	function get_dc_cats() 
+	function get_dc_cats()
 	{
 		global $wpdb;
 		// General Housekeeping
 		$dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
 		set_magic_quotes_runtime(0);
-		$prefix = get_option('tpre');
-		
+		$dbprefix = get_option('dcdbprefix');
+
 		// Get Categories
-		return $dcdb->get_results('SELECT * FROM dc_categorie', ARRAY_A);
+		return $dcdb->get_results('SELECT * FROM '.$dbprefix.'categorie', ARRAY_A);
 	}
-	
+
 	function get_dc_users()
 	{
 		global $wpdb;
 		// General Housekeeping
 		$dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
 		set_magic_quotes_runtime(0);
-		$prefix = get_option('tpre');
-		
+		$dbprefix = get_option('dcdbprefix');
+
 		// Get Users
-		
-		return $dcdb->get_results('SELECT * FROM dc_user', ARRAY_A);
+
+		return $dcdb->get_results('SELECT * FROM '.$dbprefix.'user', ARRAY_A);
 	}
-	
+
 	function get_dc_posts()
 	{
 		// General Housekeeping
 		$dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
 		set_magic_quotes_runtime(0);
-		$prefix = get_option('tpre');
-		
+		$dbprefix = get_option('dcdbprefix');
+
 		// Get Posts
-		return $dcdb->get_results('SELECT dc_post.*, dc_categorie.cat_libelle_url AS post_cat_name
-						FROM dc_post INNER JOIN dc_categorie
-						  ON dc_post.cat_id = dc_categorie.cat_id', ARRAY_A);
+		return $dcdb->get_results('SELECT '.$dbprefix.'post.*, '.$dbprefix.'categorie.cat_libelle_url AS post_cat_name
+						FROM '.$dbprefix.'post INNER JOIN '.$dbprefix.'categorie
+						ON '.$dbprefix.'post.cat_id = '.$dbprefix.'categorie.cat_id', ARRAY_A);
 	}
-	
+
 	function get_dc_comments()
 	{
 		global $wpdb;
 		// General Housekeeping
 		$dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
 		set_magic_quotes_runtime(0);
-		$prefix = get_option('tpre');
-		
+		$dbprefix = get_option('dcdbprefix');
+
 		// Get Comments
-		return $dcdb->get_results('SELECT * FROM dc_comment', ARRAY_A);
+		return $dcdb->get_results('SELECT * FROM '.$dbprefix.'comment', ARRAY_A);
 	}
-	
+
 	function get_dc_links()
 	{
 		//General Housekeeping
 		$dcdb = new wpdb(get_option('dcuser'), get_option('dcpass'), get_option('dcname'), get_option('dchost'));
 		set_magic_quotes_runtime(0);
-		$prefix = get_option('tpre');
+		$dbprefix = get_option('dcdbprefix');
 
-		return $dcdb->get_results('SELECT * FROM dc_link ORDER BY position', ARRAY_A);
+		return $dcdb->get_results('SELECT * FROM '.$dbprefix.'link ORDER BY position', ARRAY_A);
 	}
-	
-	function cat2wp($categories='') 
+
+	function cat2wp($categories='')
 	{
 		// General Housekeeping
 		global $wpdb;
@@ -216,11 +223,11 @@
 		if(is_array($categories))
 		{
 			echo '<p>'.__('Importing Categories...').'<br /><br /></p>';
-			foreach ($categories as $category) 
+			foreach ($categories as $category)
 			{
 				$count++;
 				extract($category);
-				
+
 				// Make Nice Variables
 				$name = $wpdb->escape($cat_libelle_url);
 				$title = $wpdb->escape(csc ($cat_libelle));
@@ -236,7 +243,7 @@
 				}
 				$dccat2wpcat[$id] = $ret_id;
 			}
-			
+
 			// Store category translation for future use
 			add_option('dccat2wpcat',$dccat2wpcat);
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> categories imported.'), $count).'<br /><br /></p>';
@@ -245,14 +252,14 @@
 		echo __('No Categories to Import!');
 		return false;
 	}
-	
+
 	function users2wp($users='')
 	{
 		// General Housekeeping
 		global $wpdb;
 		$count = 0;
 		$dcid2wpid = array();
-		
+
 		// Midnight Mojo
 		if(is_array($users))
 		{
@@ -261,14 +268,14 @@
 			{
 				$count++;
 				extract($user);
-				
+
 				// Make Nice Variables
 				$name = $wpdb->escape(csc ($name));
 				$RealName = $wpdb->escape(csc ($user_pseudo));
-				
+
 				if($uinfo = get_userdatabylogin($name))
 				{
-					
+
 					$ret_id = wp_insert_user(array(
 								'ID'		=> $uinfo->ID,
 								'user_login'	=> $user_id,
@@ -278,7 +285,7 @@
 								'display_name'	=> $Realname)
 								);
 				}
-				else 
+				else
 				{
 					$ret_id = wp_insert_user(array(
 								'user_login'	=> $user_id,
@@ -289,9 +296,9 @@
 								);
 				}
 				$dcid2wpid[$user_id] = $ret_id;
-				
-				// Set Dotclear-to-WordPress permissions translation
-				
+
+				// Set DotClear-to-WordPress permissions translation
+
 				// Update Usermeta Data
 				$user = new WP_User($ret_id);
 				$wp_perms = $user_level + 1;
@@ -302,26 +309,26 @@
 				else if(3  <= $wp_perms) { $user->set_role('contributor'); }
 				else if(2  <= $wp_perms) { $user->set_role('contributor'); }
 				else                     { $user->set_role('subscriber'); }
-				
+
 				update_usermeta( $ret_id, 'wp_user_level', $wp_perms);
 				update_usermeta( $ret_id, 'rich_editing', 'false');
 				update_usermeta( $ret_id, 'first_name', csc ($user_prenom));
 				update_usermeta( $ret_id, 'last_name', csc ($user_nom));
 			}// End foreach($users as $user)
-			
+
 			// Store id translation array for future use
 			add_option('dcid2wpid',$dcid2wpid);
-			
-			
+
+
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> users imported.'), $count).'<br /><br /></p>';
 			return true;
 		}// End if(is_array($users)
-		
+
 		echo __('No Users to Import!');
 		return false;
-		
+
 	}// End function user2wp()
-	
+
 	function posts2wp($posts='')
 	{
 		// General Housekeeping
@@ -338,17 +345,18 @@
 			{
 				$count++;
 				extract($post);
-				
-				// Set Dotclear-to-WordPress status translation
+
+				// Set DotClear-to-WordPress status translation
 				$stattrans = array(0 => 'draft', 1 => 'publish');
 				$comment_status_map = array (0 => 'closed', 1 => 'open');
-				
+
 				//Can we do this more efficiently?
 				$uinfo = ( get_userdatabylogin( $user_id ) ) ? get_userdatabylogin( $user_id ) : 1;
 				$authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
 
 				$Title = $wpdb->escape(csc ($post_titre));
 				$post_content = textconv ($post_content);
+				$post_excerpt = "";
 				if ($post_chapo != "") {
 					$post_excerpt = textconv ($post_chapo);
 					$post_content = $post_excerpt ."\n<!--more-->\n".$post_content;
@@ -356,9 +364,9 @@
 				$post_excerpt = $wpdb->escape ($post_excerpt);
 				$post_content = $wpdb->escape ($post_content);
 				$post_status = $stattrans[$post_pub];
-				
+
 				// Import Post data into WordPress
-				
+
 				if($pinfo = post_exists($Title,$post_content))
 				{
 					$ret_id = wp_insert_post(array(
@@ -378,7 +386,7 @@
 							'comment_count'		=> $post_nb_comment + $post_nb_trackback)
 							);
 				}
-				else 
+				else
 				{
 					$ret_id = wp_insert_post(array(
 							'post_author'		=> $authorid,
@@ -397,21 +405,21 @@
 							);
 				}
 				$dcposts2wpposts[$post_id] = $ret_id;
-				
+
 				// Make Post-to-Category associations
 				$cats = array();
 				if($cat1 = get_catbynicename($post_cat_name)) { $cats[1] = $cat1; }
 
-				if(!empty($cats)) { wp_set_post_cats('', $ret_id, $cats); }
+				if(!empty($cats)) { wp_set_post_categories($ret_id, $cats); }
 			}
 		}
 		// Store ID translation for later use
 		add_option('dcposts2wpposts',$dcposts2wpposts);
-		
+
 		echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> posts imported.'), $count).'<br /><br /></p>';
-		return true;	
+		return true;
 	}
-	
+
 	function comments2wp($comments='')
 	{
 		// General Housekeeping
@@ -419,7 +427,7 @@
 		$count = 0;
 		$dccm2wpcm = array();
 		$postarr = get_option('dcposts2wpposts');
-		
+
 		// Magic Mojo
 		if(is_array($comments))
 		{
@@ -428,16 +436,16 @@
 			{
 				$count++;
 				extract($comment);
-				
+
 				// WordPressify Data
-				$comment_ID = ltrim($comment_id, '0');
-				$comment_post_ID = $postarr[$post_id];
+				$comment_ID = (int) ltrim($comment_id, '0');
+				$comment_post_ID = (int) $postarr[$post_id];
 				$comment_approved = "$comment_pub";
 				$name = $wpdb->escape(csc ($comment_auteur));
 				$email = $wpdb->escape($comment_email);
 				$web = "http://".$wpdb->escape($comment_site);
 				$message = $wpdb->escape(textconv ($comment_content));
-				
+
 				if($cinfo = comment_exists($name, $comment_dt))
 				{
 					// Update comments
@@ -454,7 +462,7 @@
 							'comment_approved'	=> $comment_approved)
 							);
 				}
-				else 
+				else
 				{
 					// Insert comments
 					$ret_id = wp_insert_comment(array(
@@ -472,25 +480,25 @@
 				$dccm2wpcm[$comment_ID] = $ret_id;
 			}
 			// Store Comment ID translation for future use
-			add_option('dccm2wpcm', $dccm2wpcm);			
-			
+			add_option('dccm2wpcm', $dccm2wpcm);
+
 			// Associate newly formed categories with posts
 			get_comment_count($ret_id);
-			
-			
+
+
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
 			return true;
 		}
 		echo __('No Comments to Import!');
 		return false;
 	}
-	
+
 	function links2wp($links='')
 	{
 		// General Housekeeping
 		global $wpdb;
 		$count = 0;
-		
+
 		// Deal with the links
 		if(is_array($links))
 		{
@@ -499,7 +507,7 @@
 			{
 				$count++;
 				extract($link);
-				
+
 				if ($title != "") {
 					if ($cinfo = link_cat_exists (csc ($title))) {
 						$category = $cinfo;
@@ -511,7 +519,7 @@
 				} else {
 					$linkname = $wpdb->escape(csc ($label));
 					$description = $wpdb->escape(csc ($title));
-				
+
 					if($linfo = link_exists($linkname)) {
 						$ret_id = wp_insert_link(array(
 									'link_id'		=> $linfo,
@@ -540,70 +548,75 @@
 		echo __('No Links to Import!');
 		return false;
 	}
-		
-	function import_categories() 
-	{	
-		// Category Import	
+
+	function import_categories()
+	{
+		// Category Import
 		$cats = $this->get_dc_cats();
 		$this->cat2wp($cats);
 		add_option('dc_cats', $cats);
-		
-		
-			
+
+
+
 		echo '<form action="admin.php?import=dotclear&amp;step=2" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Users'));
+		wp_nonce_field('import-dotclear');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Users')));
 		echo '</form>';
 
 	}
-	
+
 	function import_users()
 	{
 		// User Import
-		$users = $this->get_dc_users(); 
+		$users = $this->get_dc_users();
 		$this->users2wp($users);
-		
+
 		echo '<form action="admin.php?import=dotclear&amp;step=3" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Posts'));
+		wp_nonce_field('import-dotclear');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Posts')));
 		echo '</form>';
 	}
-	
+
 	function import_posts()
 	{
 		// Post Import
 		$posts = $this->get_dc_posts();
 		$this->posts2wp($posts);
-		
+
 		echo '<form action="admin.php?import=dotclear&amp;step=4" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Comments'));
+		wp_nonce_field('import-dotclear');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Comments')));
 		echo '</form>';
 	}
-	
+
 	function import_comments()
 	{
 		// Comment Import
 		$comments = $this->get_dc_comments();
 		$this->comments2wp($comments);
-		
+
 		echo '<form action="admin.php?import=dotclear&amp;step=5" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Links'));
+		wp_nonce_field('import-dotclear');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Links')));
 		echo '</form>';
 	}
-	
+
 	function import_links()
 	{
 		//Link Import
 		$links = $this->get_dc_links();
 		$this->links2wp($links);
 		add_option('dc_links', $links);
-		
+
 		echo '<form action="admin.php?import=dotclear&amp;step=6" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Finish'));
+		wp_nonce_field('import-dotclear');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Finish')));
 		echo '</form>';
 	}
-	
+
 	function cleanup_dcimport()
 	{
-		delete_option('tpre');
+		delete_option('dcdbprefix');
 		delete_option('dc_cats');
 		delete_option('dcid2wpid');
 		delete_option('dccat2wpcat');
@@ -617,16 +630,16 @@
 		delete_option('dccharset');
 		$this->tips();
 	}
-	
+
 	function tips()
 	{
-		echo '<p>'.__('Welcome to WordPress.  We hope (and expect!) that you will find this platform incredibly rewarding!  As a new WordPress user coming from Dotclear, there are some things that we would like to point out.  Hopefully, they will help your transition go as smoothly as possible.').'</p>';
+		echo '<p>'.__('Welcome to WordPress.  We hope (and expect!) that you will find this platform incredibly rewarding!  As a new WordPress user coming from DotClear, there are some things that we would like to point out.  Hopefully, they will help your transition go as smoothly as possible.').'</p>';
 		echo '<h3>'.__('Users').'</h3>';
-		echo '<p>'.sprintf(__('You have already setup WordPress and have been assigned an administrative login and password.  Forget it.  You didn\'t have that login in Dotclear, why should you have it here?  Instead we have taken care to import all of your users into our system.  Unfortunately there is one downside.  Because both WordPress and Dotclear uses a strong encryption hash with passwords, it is impossible to decrypt it and we are forced to assign temporary passwords to all your users.  <strong>Every user has the same username, but their passwords are reset to password123.</strong>  So <a href="%1$s">Login</a> and change it.'), '/wp-login.php').'</p>';
+		echo '<p>'.sprintf(__('You have already setup WordPress and have been assigned an administrative login and password.  Forget it.  You didn\'t have that login in DotClear, why should you have it here?  Instead we have taken care to import all of your users into our system.  Unfortunately there is one downside.  Because both WordPress and DotClear uses a strong encryption hash with passwords, it is impossible to decrypt it and we are forced to assign temporary passwords to all your users.  <strong>Every user has the same username, but their passwords are reset to password123.</strong>  So <a href="%1$s">Login</a> and change it.'), '/wp-login.php').'</p>';
 		echo '<h3>'.__('Preserving Authors').'</h3>';
 		echo '<p>'.__('Secondly, we have attempted to preserve post authors.  If you are the only author or contributor to your blog, then you are safe.  In most cases, we are successful in this preservation endeavor.  However, if we cannot ascertain the name of the writer due to discrepancies between database tables, we assign it to you, the administrative user.').'</p>';
 		echo '<h3>'.__('Textile').'</h3>';
-		echo '<p>'.__('Also, since you\'re coming from Dotclear, you probably have been using Textile to format your comments and posts.  If this is the case, we recommend downloading and installing <a href="http://www.huddledmasses.org/category/development/wordpress/textile/">Textile for WordPress</a>.  Trust me... You\'ll want it.').'</p>';
+		echo '<p>'.__('Also, since you\'re coming from DotClear, you probably have been using Textile to format your comments and posts.  If this is the case, we recommend downloading and installing <a href="http://www.huddledmasses.org/category/development/wordpress/textile/">Textile for WordPress</a>.  Trust me... You\'ll want it.').'</p>';
 		echo '<h3>'.__('WordPress Resources').'</h3>';
 		echo '<p>'.__('Finally, there are numerous WordPress resources around the internet.  Some of them are:').'</p>';
 		echo '<ul>';
@@ -636,20 +649,20 @@
 		echo '</ul>';
 		echo '<p>'.sprintf(__('That\'s it! What are you waiting for? Go <a href="%1$s">login</a>!'), '../wp-login.php').'</p>';
 	}
-	
+
 	function db_form()
 	{
-		echo '<ul>';
-		printf('<li><label for="dbuser">%s</label> <input type="text" name="dbuser" id="dbuser" /></li>', __('Dotclear Database User:'));
-		printf('<li><label for="dbpass">%s</label> <input type="password" name="dbpass" id="dbpass" /></li>', __('Dotclear Database Password:'));
-		printf('<li><label for="dbname">%s</label> <input type="text" name="dbname" id="dbname" /></li>', __('Dotclear Database Name:'));
-		printf('<li><label for="dbhost">%s</label> <input type="text" name="dbhost" id="dbhost" value="localhost" /></li>', __('Dotclear Database Host:'));
-		/* printf('<li><label for="dbprefix">%s</label> <input type="text" name="dbprefix" /></li>', __('Dotclear Table prefix (if any):')); */
-		printf('<li><label for="dccharset">%s</label> <input type="text" id="dccharset" name="dccharset" value="ISO-8859-15"/></li>', __('Originating character set:'));
-		echo '</ul>';
+		echo '<table class="editform">';
+		printf('<tr><th><label for="dbuser">%s</label></th><td><input type="text" name="dbuser" id="dbuser" /></td></tr>', __('DotClear Database User:'));
+		printf('<tr><th><label for="dbpass">%s</label></th><td><input type="password" name="dbpass" id="dbpass" /></td></tr>', __('DotClear Database Password:'));
+		printf('<tr><th><label for="dbname">%s</label></th><td><input type="text" name="dbname" id="dbname" /></td></tr>', __('DotClear Database Name:'));
+		printf('<tr><th><label for="dbhost">%s</label></th><td><input type="text" name="dbhost" nameid="dbhost" value="localhost" /></td></tr>', __('DotClear Database Host:'));
+		printf('<tr><th><label for="dbprefix">%s</label></th><td><input type="text" name="dbprefix" id="dbprefix" value="dc_"/></td></tr>', __('DotClear Table prefix:'));
+		printf('<tr><th><label for="dccharset">%s</label></th><td><input type="text" name="dccharset" id="dccharset" value="ISO-8859-15"/></td></tr>', __('Originating character set:'));
+		echo '</table>';
 	}
-	
-	function dispatch() 
+
+	function dispatch()
 	{
 
 		if (empty ($_GET['step']))
@@ -657,51 +670,53 @@
 		else
 			$step = (int) $_GET['step'];
 		$this->header();
-		
-		if ( $step > 0 ) 
+
+		if ( $step > 0 )
 		{
+			check_admin_referer('import-dotclear');
+
 			if($_POST['dbuser'])
 			{
 				if(get_option('dcuser'))
-					delete_option('dcuser');	
-				add_option('dcuser',$_POST['dbuser']);
+					delete_option('dcuser');
+				add_option('dcuser', sanitize_user($_POST['dbuser'], true));
 			}
 			if($_POST['dbpass'])
 			{
 				if(get_option('dcpass'))
-					delete_option('dcpass');	
-				add_option('dcpass',$_POST['dbpass']);
+					delete_option('dcpass');
+				add_option('dcpass', sanitize_user($_POST['dbpass'], true));
 			}
-			
+
 			if($_POST['dbname'])
 			{
 				if(get_option('dcname'))
-					delete_option('dcname');	
-				add_option('dcname',$_POST['dbname']);
+					delete_option('dcname');
+				add_option('dcname', sanitize_user($_POST['dbname'], true));
 			}
 			if($_POST['dbhost'])
 			{
 				if(get_option('dchost'))
 					delete_option('dchost');
-				add_option('dchost',$_POST['dbhost']); 
+				add_option('dchost', sanitize_user($_POST['dbhost'], true));
 			}
 			if($_POST['dccharset'])
 			{
 				if(get_option('dccharset'))
 					delete_option('dccharset');
-				add_option('dccharset',$_POST['dccharset']); 
-			}			
+				add_option('dccharset', sanitize_user($_POST['dccharset'], true));
+			}
 			if($_POST['dbprefix'])
 			{
-				if(get_option('tpre'))
-					delete_option('tpre');
-				add_option('tpre',$_POST['dbprefix']); 
-			}			
+				if(get_option('dcdbprefix'))
+					delete_option('dcdbprefix');
+				add_option('dcdbprefix', sanitize_user($_POST['dbprefix'], true));
+			}
 
 
 		}
 
-		switch ($step) 
+		switch ($step)
 		{
 			default:
 			case 0 :
@@ -726,16 +741,16 @@
 				$this->cleanup_dcimport();
 				break;
 		}
-		
+
 		$this->footer();
 	}
 
-	function Dotclear_Import() 
+	function Dotclear_Import()
 	{
-		// Nothing.	
+		// Nothing.
 	}
 }
 
 $dc_import = new Dotclear_Import();
-register_importer('dotclear', __('Dotclear'), __('Import posts from a Dotclear Blog'), array ($dc_import, 'dispatch'));
+register_importer('dotclear', __('DotClear'), __('Import categories, users, posts, comments, and links from a DotClear blog'), array ($dc_import, 'dispatch'));
 ?>
diff -ruN 2.0.5/wp-admin/import/greymatter.php 2.2.2/wp-admin/import/greymatter.php
--- 2.0.5/wp-admin/import/greymatter.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/greymatter.php	2007-05-07 10:57:15.000000000 -0500
@@ -6,7 +6,7 @@
 
 	function header() {
 		echo '<div class="wrap">';
-		echo '<h2>'.__('Import Greymatter').'</h2>';
+		echo '<h2>'.__('Import GreyMatter').'</h2>';
 	}
 
 	function footer() {
@@ -34,6 +34,7 @@
 <form name="stepOne" method="get">
 <input type="hidden" name="import" value="greymatter" />
 <input type="hidden" name="step" value="1" />
+<?php wp_nonce_field('import-greymatter'); ?>
 <h3><?php _e('Second step: GreyMatter details:') ?></h3>
 <p><table cellpadding="0">
 <tr>
@@ -66,10 +67,10 @@
 		$string = str_replace("|*|","<br />\n",$string);
 		return($string);
 	}
-	
+
 	function import() {
 		global $wpdb;
-	
+
 		$wpvarstoreset = array('gmpath', 'archivespath', 'lastentry');
 		for ($i=0; $i<count($wpvarstoreset); $i += 1) {
 			$wpvar = $wpvarstoreset[$i];
@@ -87,11 +88,13 @@
 		}
 
 		if (!chdir($archivespath))
-			die(sprintf(__("Wrong path, %s\ndoesn't exist\non the server"), $archivespath));
+			wp_die(__("Wrong path, the path to the GM entries does not exist on the server"));
 
 		if (!chdir($gmpath))
-			die(sprintf(__("Wrong path, %s\ndoesn't exist\non the server"), $gmpath));
-			
+			wp_die(__("Wrong path, the path to the GM files does not exist on the server"));
+
+		$lastentry = (int) $lastentry;
+
 		$this->header();
 ?>
 <p><?php _e('The importer is running...') ?></p>
@@ -128,7 +131,7 @@
 		$user_info = array("user_login"=>"$user_login", "user_pass"=>"$pass1", "user_nickname"=>"$user_nickname", "user_email"=>"$user_email", "user_url"=>"$user_url", "user_ip"=>"$user_ip", "user_domain"=>"$user_domain", "user_browser"=>"$user_browser", "dateYMDhour"=>"$user_joindate", "user_level"=>"1", "user_idmode"=>"nickname");
 		$user_id = wp_insert_user($user_info);
 		$this->gmnames[$userdata[0]] = $user_id;
-		
+
 		printf('<li>'.__('user %s...').' <strong>'.__('Done').'</strong></li>', "<em>$user_login</em>");
 	}
 
@@ -136,11 +139,11 @@
 <li><?php _e('importing posts, comments, and karma...') ?><br /><ul><?php
 
 	chdir($archivespath);
-	
+
 	for($i = 0; $i <= $lastentry; $i = $i + 1) {
-		
+
 		$entryfile = "";
-		
+
 		if ($i<10000000) {
 			$entryfile .= "0";
 			if ($i<1000000) {
@@ -194,7 +197,7 @@
 			$post_status = 'publish'; //in greymatter, there are no drafts
 			$comment_status = 'open';
 			$ping_status = 'closed';
-			
+
 			if ($post_ID = post_exists($post_title, '', $post_date)) {
 				echo ' ';
 				_e('(already exists)');
@@ -213,21 +216,21 @@
 					$user_email=$wpdb->escape("user@deleted.com");
 					$user_url=$wpdb->escape("");
 					$user_joindate=$wpdb->escape($user_joindate);
-					
+
 					$user_info = array("user_login"=>$user_login, "user_pass"=>$pass1, "user_nickname"=>$user_nickname, "user_email"=>$user_email, "user_url"=>$user_url, "user_ip"=>$user_ip, "user_domain"=>$user_domain, "user_browser"=>$user_browser, "dateYMDhour"=>$user_joindate, "user_level"=>0, "user_idmode"=>"nickname");
 					$user_id = wp_insert_user($user_info);
 					$this->gmnames[$postinfo[1]] = $user_id;
-					
+
 					echo ': ';
 					printf(__('registered deleted user %s at level 0 '), "<em>$user_login</em>");
 				}
-			
+
 				if (array_key_exists($postinfo[1], $this->gmnames)) {
 					$post_author = $this->gmnames[$postinfo[1]];
 				} else {
 					$post_author = $user_id;
 				}
-			
+
 				$postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_modified', 'post_modified_gmt');
 				$post_ID = wp_insert_post($postdata);
 			}
@@ -281,7 +284,7 @@
 	?>
 </ul><strong><?php _e('Done') ?></strong></li></ul>
 <p>&nbsp;</p>
-<p><?php _e('Completed Greymatter import!') ?></p>
+<p><?php _e('Completed GreyMatter import!') ?></p>
 <?php
 	$this->footer();
 	}
@@ -297,17 +300,18 @@
 				$this->greet();
 				break;
 			case 1:
+				check_admin_referer('import-greymatter');
 				$this->import();
 				break;
 		}
 	}
 
 	function GM_Import() {
-		// Nothing.	
+		// Nothing.
 	}
 }
 
 $gm_import = new GM_Import();
 
-register_importer('greymatter', __('Greymatter'), __('Import posts and comments from your Greymatter blog'), array ($gm_import, 'dispatch'));
+register_importer('greymatter', __('GreyMatter'), __('Import users, posts, and comments from a Greymatter blog'), array ($gm_import, 'dispatch'));
 ?>
diff -ruN 2.0.5/wp-admin/import/livejournal.php 2.2.2/wp-admin/import/livejournal.php
--- 2.0.5/wp-admin/import/livejournal.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/livejournal.php	2007-05-07 10:57:15.000000000 -0500
@@ -18,15 +18,18 @@
 		$trans_tbl = array_flip($trans_tbl);
 		return strtr($string, $trans_tbl);
 	}
-	
+
 	function greet() {
-		echo '<p>'.__('Howdy! This importer allows you to extract posts from LiveJournal XML export file into your blog.  Pick a LiveJournal file to upload and click Import.').'</p>';
+		echo '<div class="narrow">';
+		echo '<p>'.__('Howdy! Upload your LiveJournal XML export file and we&#8217;ll import the posts into this blog.').'</p>';
+		echo '<p>'.__('Choose a LiveJournal XML file to upload, then click Upload file and import.').'</p>';
 		wp_import_upload_form("admin.php?import=livejournal&amp;step=1");
+		echo '</div>';
 	}
 
 	function import_posts() {
 		global $wpdb, $current_user;
-		
+
 		set_magic_quotes_runtime(0);
 		$importdata = file($this->file); // Read the file into an array
 		$importdata = implode('', $importdata); // squish it
@@ -35,9 +38,8 @@
 		preg_match_all('|<entry>(.*?)</entry>|is', $importdata, $posts);
 		$posts = $posts[1];
 		unset($importdata);
-		echo '<ol>';		
+		echo '<ol>';
 		foreach ($posts as $post) {
-			flush();
 			preg_match('|<subject>(.*?)</subject>|is', $post, $post_title);
 			$post_title = $wpdb->escape(trim($post_title[1]));
 			if ( empty($post_title) ) {
@@ -78,9 +80,9 @@
 
 			preg_match_all('|<comment>(.*?)</comment>|is', $post, $comments);
 			$comments = $comments[1];
-			
+
 			if ( $comments ) {
-				$comment_post_ID = $post_id;
+				$comment_post_ID = (int) $post_id;
 				$num_comments = 0;
 				foreach ($comments as $comment) {
 					preg_match('|<event>(.*?)</event>|is', $comment, $comment_content);
@@ -118,8 +120,6 @@
 				printf(__('(%s comments)'), $num_comments);
 			}
 			echo '</li>';
-			flush();
-			ob_flush();
 		}
 		echo '</ol>';
 	}
@@ -134,7 +134,7 @@
 		$this->file = $file['file'];
 		$this->import_posts();
 		wp_import_cleanup($file['id']);
-		
+
 		echo '<h3>';
 		printf(__('All done. <a href="%s">Have fun!</a>'), get_option('home'));
 		echo '</h3>';
@@ -147,25 +147,26 @@
 			$step = (int) $_GET['step'];
 
 		$this->header();
-		
+
 		switch ($step) {
 			case 0 :
 				$this->greet();
 				break;
 			case 1 :
+				check_admin_referer('import-upload');
 				$this->import();
 				break;
 		}
-		
+
 		$this->footer();
 	}
 
 	function LJ_Import() {
-		// Nothing.	
+		// Nothing.
 	}
 }
 
 $livejournal_import = new LJ_Import();
 
-register_importer('livejournal', __('LiveJournal'), __('Import posts from LiveJournal'), array ($livejournal_import, 'dispatch'));
+register_importer('livejournal', __('LiveJournal'), __('Import posts from a LiveJournal XML export file'), array ($livejournal_import, 'dispatch'));
 ?>
diff -ruN 2.0.5/wp-admin/import/mt.php 2.2.2/wp-admin/import/mt.php
--- 2.0.5/wp-admin/import/mt.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/mt.php	2007-05-07 10:57:15.000000000 -0500
@@ -11,7 +11,7 @@
 
 	function header() {
 		echo '<div class="wrap">';
-		echo '<h2>'.__('Import Movable Type and Typepad').'</h2>';
+		echo '<h2>'.__('Import Movable Type or TypePad').'</h2>';
 	}
 
 	function footer() {
@@ -21,9 +21,11 @@
 	function greet() {
 		$this->header();
 ?>
-<p><?php _e('Howdy! We&#8217;re about to begin the process to import all of your Movable Type entries into WordPress. To begin, select a file to upload and click Import.'); ?></p>
+<div class="narrow">
+<p><?php _e('Howdy! We&#8217;re about to begin importing all of your Movable Type or Typepad entries into WordPress. To begin, choose a file to upload and click Upload file and import.'); ?></p>
 <?php wp_import_upload_form( add_query_arg('step', 1) ); ?>
 	<p><?php _e('The importer is smart enough not to import duplicates, so you can run this multiple times without worry if&#8212;for whatever reason&#8212;it doesn\'t finish. If you get an <strong>out of memory</strong> error try splitting up the import file into pieces.'); ?> </p>
+</div>
 <?php
 		$this->footer();
 	}
@@ -53,9 +55,9 @@
 		$pass = 'changeme';
 		if (!(in_array($author, $this->mtnames))) { //a new mt author name is found
 			++ $this->j;
-			$this->mtnames[$this->j] = $author; //add that new mt author name to an array 
+			$this->mtnames[$this->j] = $author; //add that new mt author name to an array
 			$user_id = username_exists($this->newauthornames[$this->j]); //check if the new author name defined by the user is a pre-existing wp user
-			if (!$user_id) { //banging my head against the desk now. 
+			if (!$user_id) { //banging my head against the desk now.
 				if ($newauthornames[$this->j] == 'left_blank') { //check if the user does not want to change the authorname
 					$user_id = wp_create_user($author, $pass);
 					$this->newauthornames[$this->j] = $author; //now we have a name, in the place of left_blank.
@@ -145,6 +147,7 @@
 		$authors = $this->get_mt_authors();
 		echo '<ol id="authors">';
 		echo '<form action="?import=mt&amp;step=2&amp;id=' . $this->id . '" method="post">';
+		wp_nonce_field('import-mt');
 		$j = -1;
 		foreach ($authors as $author) {
 			++ $j;
@@ -169,7 +172,7 @@
 			return;
 		}
 		$this->file = $file['file'];
-		$this->id = $file['id'];
+		$this->id = (int) $file['id'];
 
 		$this->get_entries();
 		$this->mt_authors_form();
@@ -293,7 +296,7 @@
 					}
 				}
 
-				$comment_post_ID = $post_id;
+				$comment_post_ID = (int) $post_id;
 				$comment_approved = 1;
 
 				// Now for comments
@@ -397,7 +400,7 @@
 
 	function import() {
 		$this->id = (int) $_GET['id'];
-		
+
 		$this->file = get_attached_file($this->id);
 		$this->get_authors_from_post();
 		$this->get_entries();
@@ -415,9 +418,11 @@
 				$this->greet();
 				break;
 			case 1 :
+				check_admin_referer('import-upload');
 				$this->select_authors();
 				break;
 			case 2:
+				check_admin_referer('import-mt');
 				$this->import();
 				break;
 		}
@@ -430,5 +435,5 @@
 
 $mt_import = new MT_Import();
 
-register_importer('mt', __('Movable Type and Typepad'), __('Imports <strong>posts and comments</strong> from your Movable Type or Typepad blog'), array ($mt_import, 'dispatch'));
-?>
+register_importer('mt', __('Movable Type and TypePad'), __('Import posts and comments from a Movable Type or Typepad blog'), array ($mt_import, 'dispatch'));
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/import/rss.php 2.2.2/wp-admin/import/rss.php
--- 2.0.5/wp-admin/import/rss.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/rss.php	2007-05-07 10:57:15.000000000 -0500
@@ -19,15 +19,17 @@
 		$trans_tbl = array_flip($trans_tbl);
 		return strtr($string, $trans_tbl);
 	}
-	
+
 	function greet() {
-		echo '<p>'.__('Howdy! This importer allows you to extract posts from any RSS 2.0 file into your blog. This is useful if you want to import your posts from a system that is not handled by a custom import tool. Pick an RSS file to upload and click Import.').'</p>';
+		echo '<div class="narrow">';
+		echo '<p>'.__('Howdy! This importer allows you to extract posts from an RSS 2.0 file into your blog. This is useful if you want to import your posts from a system that is not handled by a custom import tool. Pick an RSS file to upload and click Import.').'</p>';
 		wp_import_upload_form("admin.php?import=rss&amp;step=1");
+		echo '</div>';
 	}
 
 	function get_posts() {
 		global $wpdb;
-		
+
 		set_magic_quotes_runtime(0);
 		$datalines = file($this->file); // Read the file into an array
 		$importdata = implode('', $datalines); // squish it
@@ -135,7 +137,7 @@
 		$this->get_posts();
 		$this->import_posts();
 		wp_import_cleanup($file['id']);
-		
+
 		echo '<h3>';
 		printf(__('All done. <a href="%s">Have fun!</a>'), get_option('home'));
 		echo '</h3>';
@@ -148,21 +150,22 @@
 			$step = (int) $_GET['step'];
 
 		$this->header();
-		
+
 		switch ($step) {
 			case 0 :
 				$this->greet();
 				break;
 			case 1 :
+				check_admin_referer('import-upload');
 				$this->import();
 				break;
 		}
-		
+
 		$this->footer();
 	}
 
 	function RSS_Import() {
-		// Nothing.	
+		// Nothing.
 	}
 }
 
diff -ruN 2.0.5/wp-admin/import/textpattern.php 2.2.2/wp-admin/import/textpattern.php
--- 2.0.5/wp-admin/import/textpattern.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import/textpattern.php	2007-05-07 10:57:15.000000000 -0500
@@ -4,13 +4,13 @@
 **/
 if(!function_exists('get_catbynicename'))
 {
-	function get_catbynicename($category_nicename) 
+	function get_catbynicename($category_nicename)
 	{
 	global $wpdb;
-	
+
 	$cat_id -= 0; 	// force numeric
 	$name = $wpdb->get_var('SELECT cat_ID FROM '.$wpdb->categories.' WHERE category_nicename="'.$category_nicename.'"');
-	
+
 	return $name;
 	}
 }
@@ -49,15 +49,18 @@
 	{
 		echo '</div>';
 	}
-	
-	function greet() 
-	{
-		echo '<p>'.__('Howdy! This importer allows you to extract posts from any Textpattern 4.0.2+ into your blog. This has not been tested on previous versions of Textpattern.  Mileage may vary.').'</p>';
+
+	function greet() {
+		echo '<div class="narrow">';
+		echo '<p>'.__('Howdy! This imports categories, users, posts, comments, and links from any Textpattern 4.0.2+ into this blog.').'</p>';
+		echo '<p>'.__('This has not been tested on previous versions of Textpattern.  Mileage may vary.').'</p>';
 		echo '<p>'.__('Your Textpattern Configuration settings are as follows:').'</p>';
 		echo '<form action="admin.php?import=textpattern&amp;step=1" method="post">';
+		wp_nonce_field('import-textpattern');
 		$this->db_form();
-		echo '<input type="submit" name="submit" value="'.__('Import Categories').'" />';
+		echo '<p class="submit"><input type="submit" name="submit" value="'.attribute_escape(__('Import Categories &raquo;')).'" /></p>';
 		echo '</form>';
+		echo '</div>';
 	}
 
 	function get_txp_cats()
@@ -67,17 +70,17 @@
 		$txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
 		set_magic_quotes_runtime(0);
 		$prefix = get_option('tpre');
-		
+
 		// Get Categories
-		return $txpdb->get_results('SELECT 
-										id,
-										name,
-										title
-							   		 FROM '.$prefix.'txp_category 
-							   		 WHERE type = "article"', 
-									 ARRAY_A);
+		return $txpdb->get_results('SELECT
+			id,
+			name,
+			title
+			FROM '.$prefix.'txp_category
+			WHERE type = "article"',
+			ARRAY_A);
 	}
-	
+
 	function get_txp_users()
 	{
 		global $wpdb;
@@ -85,44 +88,44 @@
 		$txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
 		set_magic_quotes_runtime(0);
 		$prefix = get_option('tpre');
-		
+
 		// Get Users
-		
+
 		return $txpdb->get_results('SELECT
-										user_id,
-										name,
-										RealName,
-										email,
-										privs
-							   		FROM '.$prefix.'txp_users', ARRAY_A);
+			user_id,
+			name,
+			RealName,
+			email,
+			privs
+			FROM '.$prefix.'txp_users', ARRAY_A);
 	}
-	
+
 	function get_txp_posts()
 	{
 		// General Housekeeping
 		$txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
 		set_magic_quotes_runtime(0);
 		$prefix = get_option('tpre');
-		
+
 		// Get Posts
-		return $txpdb->get_results('SELECT 
-										ID,
-										Posted,
-										AuthorID,
-										LastMod,
-										Title,
-										Body,
-										Excerpt,
-										Category1,
-										Category2,
-										Status,
-										Keywords,
-										url_title,
-										comments_count
-							   		FROM '.$prefix.'textpattern
-							   		', ARRAY_A);
+		return $txpdb->get_results('SELECT
+			ID,
+			Posted,
+			AuthorID,
+			LastMod,
+			Title,
+			Body,
+			Excerpt,
+			Category1,
+			Category2,
+			Status,
+			Keywords,
+			url_title,
+			comments_count
+			FROM '.$prefix.'textpattern
+			', ARRAY_A);
 	}
-	
+
 	function get_txp_comments()
 	{
 		global $wpdb;
@@ -130,30 +133,30 @@
 		$txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
 		set_magic_quotes_runtime(0);
 		$prefix = get_option('tpre');
-		
+
 		// Get Comments
 		return $txpdb->get_results('SELECT * FROM '.$prefix.'txp_discuss', ARRAY_A);
 	}
-	
+
 		function get_txp_links()
 	{
 		//General Housekeeping
 		$txpdb = new wpdb(get_option('txpuser'), get_option('txppass'), get_option('txpname'), get_option('txphost'));
 		set_magic_quotes_runtime(0);
 		$prefix = get_option('tpre');
-		
-		return $txpdb->get_results('SELECT 
-										id,
-										date,
-										category,
-										url,
-										linkname,
-										description
-									  FROM '.$prefix.'txp_link', 
-									  ARRAY_A);						  
+
+		return $txpdb->get_results('SELECT
+			id,
+			date,
+			category,
+			url,
+			linkname,
+			description
+			FROM '.$prefix.'txp_link',
+			ARRAY_A);
 	}
-	
-	function cat2wp($categories='') 
+
+	function cat2wp($categories='')
 	{
 		// General Housekeeping
 		global $wpdb;
@@ -163,16 +166,16 @@
 		if(is_array($categories))
 		{
 			echo '<p>'.__('Importing Categories...').'<br /><br /></p>';
-			foreach ($categories as $category) 
+			foreach ($categories as $category)
 			{
 				$count++;
 				extract($category);
-				
-				
+
+
 				// Make Nice Variables
 				$name = $wpdb->escape($name);
 				$title = $wpdb->escape($title);
-				
+
 				if($cinfo = category_exists($name))
 				{
 					$ret_id = wp_insert_category(array('cat_ID' => $cinfo, 'category_nicename' => $name, 'cat_name' => $title));
@@ -183,7 +186,7 @@
 				}
 				$txpcat2wpcat[$id] = $ret_id;
 			}
-			
+
 			// Store category translation for future use
 			add_option('txpcat2wpcat',$txpcat2wpcat);
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> categories imported.'), $count).'<br /><br /></p>';
@@ -192,14 +195,14 @@
 		echo __('No Categories to Import!');
 		return false;
 	}
-	
+
 	function users2wp($users='')
 	{
 		// General Housekeeping
 		global $wpdb;
 		$count = 0;
 		$txpid2wpid = array();
-		
+
 		// Midnight Mojo
 		if(is_array($users))
 		{
@@ -208,14 +211,14 @@
 			{
 				$count++;
 				extract($user);
-				
+
 				// Make Nice Variables
 				$name = $wpdb->escape($name);
 				$RealName = $wpdb->escape($RealName);
-				
+
 				if($uinfo = get_userdatabylogin($name))
 				{
-					
+
 					$ret_id = wp_insert_user(array(
 								'ID'			=> $uinfo->ID,
 								'user_login'	=> $name,
@@ -225,7 +228,7 @@
 								'display_name'	=> $name)
 								);
 				}
-				else 
+				else
 				{
 					$ret_id = wp_insert_user(array(
 								'user_login'	=> $name,
@@ -236,10 +239,10 @@
 								);
 				}
 				$txpid2wpid[$user_id] = $ret_id;
-				
+
 				// Set Textpattern-to-WordPress permissions translation
 				$transperms = array(1 => '10', 2 => '9', 3 => '5', 4 => '4', 5 => '3', 6 => '2', 7 => '0');
-				
+
 				// Update Usermeta Data
 				$user = new WP_User($ret_id);
 				if('10' == $transperms[$privs]) { $user->set_role('administrator'); }
@@ -249,24 +252,24 @@
 				if('3'  == $transperms[$privs]) { $user->set_role('contributor'); }
 				if('2'  == $transperms[$privs]) { $user->set_role('contributor'); }
 				if('0'  == $transperms[$privs]) { $user->set_role('subscriber'); }
-				
+
 				update_usermeta( $ret_id, 'wp_user_level', $transperms[$privs] );
 				update_usermeta( $ret_id, 'rich_editing', 'false');
 			}// End foreach($users as $user)
-			
+
 			// Store id translation array for future use
 			add_option('txpid2wpid',$txpid2wpid);
-			
-			
+
+
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> users imported.'), $count).'<br /><br /></p>';
 			return true;
 		}// End if(is_array($users)
-		
+
 		echo __('No Users to Import!');
 		return false;
-		
+
 	}// End function user2wp()
-	
+
 	function posts2wp($posts='')
 	{
 		// General Housekeeping
@@ -283,10 +286,10 @@
 			{
 				$count++;
 				extract($post);
-				
+
 				// Set Textpattern-to-WordPress status translation
 				$stattrans = array(1 => 'draft', 2 => 'private', 3 => 'draft', 4 => 'publish', 5 => 'publish');
-				
+
 				//Can we do this more efficiently?
 				$uinfo = ( get_userdatabylogin( $AuthorID ) ) ? get_userdatabylogin( $AuthorID ) : 1;
 				$authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
@@ -295,59 +298,59 @@
 				$Body = $wpdb->escape($Body);
 				$Excerpt = $wpdb->escape($Excerpt);
 				$post_status = $stattrans[$Status];
-				
+
 				// Import Post data into WordPress
-				
+
 				if($pinfo = post_exists($Title,$Body))
 				{
 					$ret_id = wp_insert_post(array(
-							'ID'				=> $pinfo,
-							'post_date'			=> $Posted,
-							'post_date_gmt'		=> $post_date_gmt,
-							'post_author'		=> $authorid,
-							'post_modified'		=> $LastMod,
-							'post_modified_gmt' => $post_modified_gmt,
-							'post_title'		=> $Title,
-							'post_content'		=> $Body,
-							'post_excerpt'		=> $Excerpt,
-							'post_status'		=> $post_status,
-							'post_name'			=> $url_title,
-							'comment_count'		=> $comments_count)
-							);
+						'ID'				=> $pinfo,
+						'post_date'			=> $Posted,
+						'post_date_gmt'		=> $post_date_gmt,
+						'post_author'		=> $authorid,
+						'post_modified'		=> $LastMod,
+						'post_modified_gmt' => $post_modified_gmt,
+						'post_title'		=> $Title,
+						'post_content'		=> $Body,
+						'post_excerpt'		=> $Excerpt,
+						'post_status'		=> $post_status,
+						'post_name'			=> $url_title,
+						'comment_count'		=> $comments_count)
+						);
 				}
-				else 
+				else
 				{
 					$ret_id = wp_insert_post(array(
-							'post_date'			=> $Posted,
-							'post_date_gmt'		=> $post_date_gmt,
-							'post_author'		=> $authorid,
-							'post_modified'		=> $LastMod,
-							'post_modified_gmt' => $post_modified_gmt,
-							'post_title'		=> $Title,
-							'post_content'		=> $Body,
-							'post_excerpt'		=> $Excerpt,
-							'post_status'		=> $post_status,
-							'post_name'			=> $url_title,
-							'comment_count'		=> $comments_count)
-							);
+						'post_date'			=> $Posted,
+						'post_date_gmt'		=> $post_date_gmt,
+						'post_author'		=> $authorid,
+						'post_modified'		=> $LastMod,
+						'post_modified_gmt' => $post_modified_gmt,
+						'post_title'		=> $Title,
+						'post_content'		=> $Body,
+						'post_excerpt'		=> $Excerpt,
+						'post_status'		=> $post_status,
+						'post_name'			=> $url_title,
+						'comment_count'		=> $comments_count)
+						);
 				}
 				$txpposts2wpposts[$ID] = $ret_id;
-				
+
 				// Make Post-to-Category associations
 				$cats = array();
 				if($cat1 = get_catbynicename($Category1)) { $cats[1] = $cat1; }
 				if($cat2 = get_catbynicename($Category2)) { $cats[2] = $cat2; }
 
-				if(!empty($cats)) { wp_set_post_cats('', $ret_id, $cats); }
+				if(!empty($cats)) { wp_set_post_categories($ret_id, $cats); }
 			}
 		}
 		// Store ID translation for later use
 		add_option('txpposts2wpposts',$txpposts2wpposts);
-		
+
 		echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> posts imported.'), $count).'<br /><br /></p>';
-		return true;	
+		return true;
 	}
-	
+
 	function comments2wp($comments='')
 	{
 		// General Housekeeping
@@ -355,7 +358,7 @@
 		$count = 0;
 		$txpcm2wpcm = array();
 		$postarr = get_option('txpposts2wpposts');
-		
+
 		// Magic Mojo
 		if(is_array($comments))
 		{
@@ -364,7 +367,7 @@
 			{
 				$count++;
 				extract($comment);
-				
+
 				// WordPressify Data
 				$comment_ID = ltrim($discussid, '0');
 				$comment_post_ID = $postarr[$parentid];
@@ -373,57 +376,57 @@
 				$email = $wpdb->escape($email);
 				$web = $wpdb->escape($web);
 				$message = $wpdb->escape($message);
-				
+
 				if($cinfo = comment_exists($name, $posted))
 				{
 					// Update comments
 					$ret_id = wp_update_comment(array(
-							'comment_ID'			=> $cinfo,
-							'comment_post_ID'		=> $comment_post_ID,
-							'comment_author'		=> $name,
-							'comment_author_email'	=> $email,
-							'comment_author_url'	=> $web,
-							'comment_date'			=> $posted,
-							'comment_content'		=> $message,
-							'comment_approved'		=> $comment_approved)
-							);
+						'comment_ID'			=> $cinfo,
+						'comment_post_ID'		=> $comment_post_ID,
+						'comment_author'		=> $name,
+						'comment_author_email'	=> $email,
+						'comment_author_url'	=> $web,
+						'comment_date'			=> $posted,
+						'comment_content'		=> $message,
+						'comment_approved'		=> $comment_approved)
+						);
 				}
-				else 
+				else
 				{
 					// Insert comments
 					$ret_id = wp_insert_comment(array(
-							'comment_post_ID'		=> $comment_post_ID,
-							'comment_author'		=> $name,
-							'comment_author_email'	=> $email,
-							'comment_author_url'	=> $web,
-							'comment_author_IP'		=> $ip,
-							'comment_date'			=> $posted,
-							'comment_content'		=> $message,
-							'comment_approved'		=> $comment_approved)
-							);
+						'comment_post_ID'		=> $comment_post_ID,
+						'comment_author'		=> $name,
+						'comment_author_email'	=> $email,
+						'comment_author_url'	=> $web,
+						'comment_author_IP'		=> $ip,
+						'comment_date'			=> $posted,
+						'comment_content'		=> $message,
+						'comment_approved'		=> $comment_approved)
+						);
 				}
 				$txpcm2wpcm[$comment_ID] = $ret_id;
 			}
 			// Store Comment ID translation for future use
-			add_option('txpcm2wpcm', $txpcm2wpcm);			
-			
+			add_option('txpcm2wpcm', $txpcm2wpcm);
+
 			// Associate newly formed categories with posts
 			get_comment_count($ret_id);
-			
-			
+
+
 			echo '<p>'.sprintf(__('Done! <strong>%1$s</strong> comments imported.'), $count).'<br /><br /></p>';
 			return true;
 		}
 		echo __('No Comments to Import!');
 		return false;
 	}
-	
+
 	function links2wp($links='')
 	{
 		// General Housekeeping
 		global $wpdb;
 		$count = 0;
-		
+
 		// Deal with the links
 		if(is_array($links))
 		{
@@ -432,12 +435,12 @@
 			{
 				$count++;
 				extract($link);
-				
+
 				// Make nice vars
 				$category = $wpdb->escape($category);
 				$linkname = $wpdb->escape($linkname);
 				$description = $wpdb->escape($description);
-				
+
 				if($linfo = link_exists($linkname))
 				{
 					$ret_id = wp_insert_link(array(
@@ -449,7 +452,7 @@
 								'link_updated'		=> $date)
 								);
 				}
-				else 
+				else
 				{
 					$ret_id = wp_insert_link(array(
 								'link_url'			=> $url,
@@ -470,67 +473,72 @@
 		echo __('No Links to Import!');
 		return false;
 	}
-		
-	function import_categories() 
-	{	
-		// Category Import	
+
+	function import_categories()
+	{
+		// Category Import
 		$cats = $this->get_txp_cats();
 		$this->cat2wp($cats);
 		add_option('txp_cats', $cats);
-		
-		
-			
+
+
+
 		echo '<form action="admin.php?import=textpattern&amp;step=2" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Users'));
+		wp_nonce_field('import-textpattern');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Users')));
 		echo '</form>';
 
 	}
-	
+
 	function import_users()
 	{
 		// User Import
-		$users = $this->get_txp_users(); 
+		$users = $this->get_txp_users();
 		$this->users2wp($users);
-		
+
 		echo '<form action="admin.php?import=textpattern&amp;step=3" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Posts'));
+		wp_nonce_field('import-textpattern');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Posts')));
 		echo '</form>';
 	}
-	
+
 	function import_posts()
 	{
 		// Post Import
 		$posts = $this->get_txp_posts();
 		$this->posts2wp($posts);
-		
+
 		echo '<form action="admin.php?import=textpattern&amp;step=4" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Comments'));
+		wp_nonce_field('import-textpattern');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Comments')));
 		echo '</form>';
 	}
-	
+
 	function import_comments()
 	{
 		// Comment Import
 		$comments = $this->get_txp_comments();
 		$this->comments2wp($comments);
-		
+
 		echo '<form action="admin.php?import=textpattern&amp;step=5" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Import Links'));
+		wp_nonce_field('import-textpattern');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Import Links')));
 		echo '</form>';
 	}
-	
+
 	function import_links()
 	{
 		//Link Import
 		$links = $this->get_txp_links();
 		$this->links2wp($links);
 		add_option('txp_links', $links);
-		
+
 		echo '<form action="admin.php?import=textpattern&amp;step=6" method="post">';
-		printf('<input type="submit" name="submit" value="%s" />', __('Finish'));
+		wp_nonce_field('import-textpattern');
+		printf('<input type="submit" name="submit" value="%s" />', attribute_escape(__('Finish')));
 		echo '</form>';
 	}
-	
+
 	function cleanup_txpimport()
 	{
 		delete_option('tpre');
@@ -546,7 +554,7 @@
 		delete_option('txphost');
 		$this->tips();
 	}
-	
+
 	function tips()
 	{
 		echo '<p>'.__('Welcome to WordPress.  We hope (and expect!) that you will find this platform incredibly rewarding!  As a new WordPress user coming from Textpattern, there are some things that we would like to point out.  Hopefully, they will help your transition go as smoothly as possible.').'</p>';
@@ -565,19 +573,19 @@
 		echo '</ul>';
 		echo '<p>'.sprintf(__('That\'s it! What are you waiting for? Go <a href="%1$s">login</a>!'), '/wp-login.php').'</p>';
 	}
-	
+
 	function db_form()
 	{
-		echo '<ul>';
-		printf('<li><label for="dbuser">%s</label> <input type="text" name="dbuser" id="dbuser" /></li>', __('Textpattern Database User:'));
-		printf('<li><label for="dbpass">%s</label> <input type="password" name="dbpass" id="dbpass" /></li>', __('Textpattern Database Password:'));
-		printf('<li><label for="dbname">%s</label> <input type="text" id="dbname" name="dbname" /></li>', __('Textpattern Database Name:'));
-		printf('<li><label for="dbhost">%s</label> <input type="text" id="dbhost" name="dbhost" value="localhost" /></li>', __('Textpattern Database Host:'));
-		printf('<li><label for="dbprefix">%s</label> <input type="text" name="dbprefix" id="dbprefix"  /></li>', __('Textpattern Table prefix (if any):'));
-		echo '</ul>';
+		echo '<table class="editform">';
+		printf('<tr><th scope="row"><label for="dbuser">%s</label></th><td><input type="text" name="dbuser" id="dbuser" /></td></tr>', __('Textpattern Database User:'));
+		printf('<tr><th scope="row"><label for="dbpass">%s</label></th><td><input type="password" name="dbpass" id="dbpass" /></td></tr>', __('Textpattern Database Password:'));
+		printf('<tr><th scope="row"><label for="dbname">%s</label></th><td><input type="text" id="dbname" name="dbname" /></td></tr>', __('Textpattern Database Name:'));
+		printf('<tr><th scope="row"><label for="dbhost">%s</label></th><td><input type="text" id="dbhost" name="dbhost" value="localhost" /></td></tr>', __('Textpattern Database Host:'));
+		printf('<tr><th scope="row"><label for="dbprefix">%s</label></th><td><input type="text" name="dbprefix" id="dbprefix"  /></td></tr>', __('Textpattern Table prefix (if any):'));
+		echo '</table>';
 	}
-	
-	function dispatch() 
+
+	function dispatch()
 	{
 
 		if (empty ($_GET['step']))
@@ -585,45 +593,47 @@
 		else
 			$step = (int) $_GET['step'];
 		$this->header();
-		
-		if ( $step > 0 ) 
+
+		if ( $step > 0 )
 		{
+			check_admin_referer('import-textpattern');
+
 			if($_POST['dbuser'])
 			{
 				if(get_option('txpuser'))
-					delete_option('txpuser');	
-				add_option('txpuser',$_POST['dbuser']);
+					delete_option('txpuser');
+				add_option('txpuser', sanitize_user($_POST['dbuser'], true));
 			}
 			if($_POST['dbpass'])
 			{
 				if(get_option('txppass'))
-					delete_option('txppass');	
-				add_option('txppass',$_POST['dbpass']);
+					delete_option('txppass');
+				add_option('txppass',  sanitize_user($_POST['dbpass'], true));
 			}
-			
+
 			if($_POST['dbname'])
 			{
 				if(get_option('txpname'))
-					delete_option('txpname');	
-				add_option('txpname',$_POST['dbname']);
+					delete_option('txpname');
+				add_option('txpname',  sanitize_user($_POST['dbname'], true));
 			}
 			if($_POST['dbhost'])
 			{
 				if(get_option('txphost'))
 					delete_option('txphost');
-				add_option('txphost',$_POST['dbhost']); 
+				add_option('txphost',  sanitize_user($_POST['dbhost'], true));
 			}
 			if($_POST['dbprefix'])
 			{
 				if(get_option('tpre'))
 					delete_option('tpre');
-				add_option('tpre',$_POST['dbprefix']); 
-			}			
+				add_option('tpre',  sanitize_user($_POST['dbprefix']));
+			}
 
 
 		}
 
-		switch ($step) 
+		switch ($step)
 		{
 			default:
 			case 0 :
@@ -648,16 +658,16 @@
 				$this->cleanup_txpimport();
 				break;
 		}
-		
+
 		$this->footer();
 	}
 
-	function Textpattern_Import() 
+	function Textpattern_Import()
 	{
-		// Nothing.	
+		// Nothing.
 	}
 }
 
 $txp_import = new Textpattern_Import();
-register_importer('textpattern', __('Textpattern'), __('Import posts from a Textpattern Blog'), array ($txp_import, 'dispatch'));
+register_importer('textpattern', __('Textpattern'), __('Import categories, users, posts, comments, and links from a Textpattern blog'), array ($txp_import, 'dispatch'));
 ?>
diff -ruN 2.0.5/wp-admin/import/wordpress.php 2.2.2/wp-admin/import/wordpress.php
--- 2.0.5/wp-admin/import/wordpress.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/import/wordpress.php	2007-07-30 11:08:30.000000000 -0500
@@ -0,0 +1,408 @@
+<?php
+
+class WP_Import {
+
+	var $posts = array ();
+	var $posts_processed = array ();
+    // Array of arrays. [[0] => XML fragment, [1] => New post ID]
+	var $file;
+	var $id;
+	var $mtnames = array ();
+	var $newauthornames = array ();
+	var $j = -1;
+
+	function header() {
+		echo '<div class="wrap">';
+		echo '<h2>'.__('Import WordPress').'</h2>';
+	}
+
+	function footer() {
+		echo '</div>';
+	}
+
+	function unhtmlentities($string) { // From php.net for < 4.3 compat
+		$trans_tbl = get_html_translation_table(HTML_ENTITIES);
+		$trans_tbl = array_flip($trans_tbl);
+		return strtr($string, $trans_tbl);
+	}
+
+	function greet() {
+		echo '<div class="narrow">';
+		echo '<p>'.__('Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import the posts, comments, custom fields, and categories into this blog.').'</p>';
+		echo '<p>'.__('Choose a WordPress WXR file to upload, then click Upload file and import.').'</p>';
+		wp_import_upload_form("admin.php?import=wordpress&amp;step=1");
+		echo '</div>';
+	}
+
+	function get_tag( $string, $tag ) {
+		global $wpdb;
+		preg_match("|<$tag.*?>(.*?)</$tag>|is", $string, $return);
+		$return = preg_replace('|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1]);
+		$return = $wpdb->escape( trim( $return ) );
+		return $return;
+	}
+
+	function users_form($n) {
+		global $wpdb, $testing;
+		$users = $wpdb->get_results("SELECT * FROM $wpdb->users ORDER BY ID");
+?><select name="userselect[<?php echo $n; ?>]">
+	<option value="#NONE#">- Select -</option>
+	<?php
+		foreach ($users as $user) {
+			echo '<option value="'.$user->user_login.'">'.$user->user_login.'</option>';
+		}
+?>
+	</select>
+	<?php
+	}
+
+	//function to check the authorname and do the mapping
+	function checkauthor($author) {
+		global $wpdb;
+		//mtnames is an array with the names in the mt import file
+		$pass = 'changeme';
+		if (!(in_array($author, $this->mtnames))) { //a new mt author name is found
+			++ $this->j;
+			$this->mtnames[$this->j] = $author; //add that new mt author name to an array
+			$user_id = username_exists($this->newauthornames[$this->j]); //check if the new author name defined by the user is a pre-existing wp user
+			if (!$user_id) { //banging my head against the desk now.
+				if ($this->newauthornames[$this->j] == 'left_blank') { //check if the user does not want to change the authorname
+					$user_id = wp_create_user($author, $pass);
+					$this->newauthornames[$this->j] = $author; //now we have a name, in the place of left_blank.
+				} else {
+					$user_id = wp_create_user($this->newauthornames[$this->j], $pass);
+				}
+			} else {
+				return $user_id; // return pre-existing wp username if it exists
+			}
+		} else {
+			$key = array_search($author, $this->mtnames); //find the array key for $author in the $mtnames array
+			$user_id = username_exists($this->newauthornames[$key]); //use that key to get the value of the author's name from $newauthornames
+		}
+
+		return $user_id;
+	}
+
+	function get_entries() {
+		set_magic_quotes_runtime(0);
+		$importdata = array_map('rtrim', file($this->file)); // Read the file into an array
+
+		$this->posts = array();
+		$this->categories = array();
+		$num = 0;
+		$doing_entry = false;
+		foreach ($importdata as $importline) {
+			if ( false !== strpos($importline, '<wp:category>') ) {
+				preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
+				$this->categories[] = $category[1];
+				continue;
+			}
+			if ( false !== strpos($importline, '<item>') ) {
+				$this->posts[$num] = '';
+				$doing_entry = true;
+				continue;	
+			}
+			if ( false !== strpos($importline, '</item>') ) {
+				$num++;
+				$doing_entry = false;
+				continue;	
+			}
+			if ( $doing_entry ) {
+				$this->posts[$num] .= $importline . "\n";
+			}
+		}
+
+		foreach ($this->posts as $post) {
+			$post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
+			if ($post_ID) {
+				$this->posts_processed[$post_ID][0] = &$post;
+				$this->posts_processed[$post_ID][1] = 0;
+			}
+		}
+	}
+
+	function get_wp_authors() {
+		$temp = array ();
+		$i = -1;
+		foreach ($this->posts as $post) {
+			if ('' != trim($post)) {
+				++ $i;
+				$author = $this->get_tag( $post, 'dc:creator' );
+				array_push($temp, "$author"); //store the extracted author names in a temporary array
+			}
+		}
+
+		// We need to find unique values of author names, while preserving the order, so this function emulates the unique_value(); php function, without the sorting.
+		$authors[0] = array_shift($temp);
+		$y = count($temp) + 1;
+		for ($x = 1; $x < $y; $x ++) {
+			$next = array_shift($temp);
+			if (!(in_array($next, $authors)))
+				array_push($authors, "$next");
+		}
+
+		return $authors;
+	}
+
+	function get_authors_from_post() {
+		$formnames = array ();
+		$selectnames = array ();
+
+		foreach ($_POST['user'] as $key => $line) {
+			$newname = trim(stripslashes($line));
+			if ($newname == '')
+				$newname = 'left_blank'; //passing author names from step 1 to step 2 is accomplished by using POST. left_blank denotes an empty entry in the form.
+			array_push($formnames, "$newname");
+		} // $formnames is the array with the form entered names
+
+		foreach ($_POST['userselect'] as $user => $key) {
+			$selected = trim(stripslashes($key));
+			array_push($selectnames, "$selected");
+		}
+
+		$count = count($formnames);
+		for ($i = 0; $i < $count; $i ++) {
+			if ($selectnames[$i] != '#NONE#') { //if no name was selected from the select menu, use the name entered in the form
+				array_push($this->newauthornames, "$selectnames[$i]");
+			} else {
+				array_push($this->newauthornames, "$formnames[$i]");
+			}
+		}
+	}
+
+	function wp_authors_form() {
+?>
+<h2><?php _e('Assign Authors'); ?></h2>
+<p><?php _e('To make it easier for you to edit and save the imported posts and drafts, you may want to change the name of the author of the posts. For example, you may want to import all the entries as <code>admin</code>s entries.'); ?></p>
+<p><?php _e('If a new user is created by WordPress, the password will be set, by default, to "changeme". Quite suggestive, eh? ;)'); ?></p>
+	<?php
+
+
+		$authors = $this->get_wp_authors();
+		echo '<ol id="authors">';
+		echo '<form action="?import=wordpress&amp;step=2&amp;id=' . $this->id . '" method="post">';
+		wp_nonce_field('import-wordpress');
+		$j = -1;
+		foreach ($authors as $author) {
+			++ $j;
+			echo '<li>'.__('Current author:').' <strong>'.$author.'</strong><br />'.sprintf(__('Create user %1$s or map to existing'), ' <input type="text" value="'.$author.'" name="'.'user[]'.'" maxlength="30"> <br />');
+			$this->users_form($j);
+			echo '</li>';
+		}
+
+		echo '<input type="submit" value="Submit">'.'<br/>';
+		echo '</form>';
+		echo '</ol>';
+
+	}
+
+	function select_authors() {
+		$file = wp_import_handle_upload();
+		if ( isset($file['error']) ) {
+			echo '<p>'.__('Sorry, there has been an error.').'</p>';
+			echo '<p><strong>' . $file['error'] . '</strong></p>';
+			return;
+		}
+		$this->file = $file['file'];
+		$this->id = (int) $file['id'];
+
+		$this->get_entries();
+		$this->wp_authors_form();
+	}
+
+	function process_categories() {
+		global $wpdb;
+
+		$cat_names = (array) $wpdb->get_col("SELECT cat_name FROM $wpdb->categories");
+
+		while ( $c = array_shift($this->categories) ) {
+			$cat_name = trim($this->get_tag( $c, 'wp:cat_name' ));
+
+			// If the category exists we leave it alone
+			if ( in_array($cat_name, $cat_names) )
+				continue;
+
+			$category_nicename	= $this->get_tag( $c, 'wp:category_nicename' );
+			$posts_private		= (int) $this->get_tag( $c, 'wp:posts_private' );
+			$links_private		= (int) $this->get_tag( $c, 'wp:links_private' );
+
+			$parent = $this->get_tag( $c, 'wp:category_parent' );
+
+			if ( empty($parent) )
+				$category_parent = '0';
+			else
+				$category_parent = category_exists($parent);
+
+			$catarr = compact('category_nicename', 'category_parent', 'posts_private', 'links_private', 'posts_private', 'cat_name');
+
+			$cat_ID = wp_insert_category($catarr);
+		}
+	}
+
+	function process_posts() {
+		$i = -1;
+		echo '<ol>';
+
+		foreach ($this->posts as $post)
+			$this->process_post($post);
+
+		echo '</ol>';
+
+		wp_import_cleanup($this->id);
+
+		echo '<h3>'.sprintf(__('All done.').' <a href="%s">'.__('Have fun!').'</a>', get_option('home')).'</h3>';
+	}
+  
+	function process_post($post) {
+		global $wpdb;
+
+		$post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
+  		if ( $post_ID && !empty($this->posts_processed[$post_ID][1]) ) // Processed already
+			return 0;
+      
+		// There are only ever one of these
+		$post_title     = $this->get_tag( $post, 'title' );
+		$post_date      = $this->get_tag( $post, 'wp:post_date' );
+		$post_date_gmt  = $this->get_tag( $post, 'wp:post_date_gmt' );
+		$comment_status = $this->get_tag( $post, 'wp:comment_status' );
+		$ping_status    = $this->get_tag( $post, 'wp:ping_status' );
+		$post_status    = $this->get_tag( $post, 'wp:status' );
+		$post_name      = $this->get_tag( $post, 'wp:post_name' );
+		$post_parent    = $this->get_tag( $post, 'wp:post_parent' );
+		$menu_order     = $this->get_tag( $post, 'wp:menu_order' );
+		$post_type      = $this->get_tag( $post, 'wp:post_type' );
+		$guid           = $this->get_tag( $post, 'guid' );
+		$post_author    = $this->get_tag( $post, 'dc:creator' );
+
+		$post_content = $this->get_tag( $post, 'content:encoded' );
+		$post_content = preg_replace('|<(/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
+		$post_content = str_replace('<br>', '<br />', $post_content);
+		$post_content = str_replace('<hr>', '<hr />', $post_content);
+
+		preg_match_all('|<category>(.*?)</category>|is', $post, $categories);
+		$categories = $categories[1];
+
+		$cat_index = 0;
+		foreach ($categories as $category) {
+			$categories[$cat_index] = $wpdb->escape($this->unhtmlentities(str_replace(array ('<![CDATA[', ']]>'), '', $category)));
+			$cat_index++;
+		}
+
+		if ($post_id = post_exists($post_title, '', $post_date)) {
+			echo '<li>';
+			printf(__('Post <i>%s</i> already exists.'), stripslashes($post_title));
+		} else {
+
+			// If it has parent, process parent first.
+			$post_parent = (int) $post_parent;
+			if ($parent = $this->posts_processed[$post_parent]) {
+				if (!$parent[1]) $this->process_post($parent[0]); // If not yet, process the parent first.
+				$post_parent = $parent[1]; // New ID of the parent;
+			}
+
+			echo '<li>';
+			printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
+
+			$post_author = $this->checkauthor($post_author); //just so that if a post already exists, new users are not created by checkauthor
+
+			$postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'post_name', 'comment_status', 'ping_status', 'post_modified', 'post_modified_gmt', 'guid', 'post_parent', 'menu_order', 'post_type');
+			$comment_post_ID = $post_id = wp_insert_post($postdata);
+
+			// Memorize old and new ID.
+			if ( $post_id && $post_ID && $this->posts_processed[$post_ID] )
+				$this->posts_processed[$post_ID][1] = $post_id; // New ID.
+			
+			// Add categories.
+			if (count($categories) > 0) {
+				$post_cats = array();
+				foreach ($categories as $category) {
+					$cat_ID = (int) $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE cat_name = '$category'");
+					if ($cat_ID == 0) {
+						$cat_ID = wp_insert_category(array('cat_name' => $category));
+					}
+					$post_cats[] = $cat_ID;
+				}
+				wp_set_post_categories($post_id, $post_cats);
+			}	
+		}
+
+		// Now for comments
+		preg_match_all('|<wp:comment>(.*?)</wp:comment>|is', $post, $comments);
+		$comments = $comments[1];
+		$num_comments = 0;
+		if ( $comments) { foreach ($comments as $comment) {
+			$comment_author       = $this->get_tag( $comment, 'wp:comment_author');
+			$comment_author_email = $this->get_tag( $comment, 'wp:comment_author_email');
+			$comment_author_IP    = $this->get_tag( $comment, 'wp:comment_author_IP');
+			$comment_author_url   = $this->get_tag( $comment, 'wp:comment_author_url');
+			$comment_date         = $this->get_tag( $comment, 'wp:comment_date');
+			$comment_date_gmt     = $this->get_tag( $comment, 'wp:comment_date_gmt');
+			$comment_content      = $this->get_tag( $comment, 'wp:comment_content');
+			$comment_approved     = $this->get_tag( $comment, 'wp:comment_approved');
+			$comment_type         = $this->get_tag( $comment, 'wp:comment_type');
+			$comment_parent       = $this->get_tag( $comment, 'wp:comment_parent');
+
+			if ( !comment_exists($comment_author, $comment_date) ) {
+				$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_author_email', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_approved', 'comment_type', 'comment_parent');
+				wp_insert_comment($commentdata);
+				$num_comments++;
+			}
+		} }
+
+		if ( $num_comments )
+			printf(' '.__('(%s comments)'), $num_comments);
+
+		// Now for post meta
+		preg_match_all('|<wp:postmeta>(.*?)</wp:postmeta>|is', $post, $postmeta);
+		$postmeta = $postmeta[1];
+		if ( $postmeta) { foreach ($postmeta as $p) {
+			$key   = $this->get_tag( $p, 'wp:meta_key' );
+			$value = $this->get_tag( $p, 'wp:meta_value' );
+			$value = stripslashes($value); // add_post_meta() will escape.
+			add_post_meta( $post_id, $key, $value );
+		} }
+	}
+
+	function import() {
+		$this->id = (int) $_GET['id'];
+
+		$this->file = get_attached_file($this->id);
+		$this->get_authors_from_post();
+		$this->get_entries();
+		$this->process_categories();
+		$this->process_posts();
+	}
+
+	function dispatch() {
+		if (empty ($_GET['step']))
+			$step = 0;
+		else
+			$step = (int) $_GET['step'];
+
+		$this->header();
+		switch ($step) {
+			case 0 :
+				$this->greet();
+				break;
+			case 1 :
+				check_admin_referer('import-upload');
+				$this->select_authors();
+				break;
+			case 2:
+				check_admin_referer('import-wordpress');
+				$this->import();
+				break;
+		}
+		$this->footer();
+	}
+
+	function WP_Import() {
+		// Nothing.
+	}
+}
+
+$wp_import = new WP_Import();
+
+register_importer('wordpress', 'WordPress', __('Import <strong>posts, comments, custom fields, pages, and categories</strong> from a WordPress export file'), array ($wp_import, 'dispatch'));
+
+?>
diff -ruN 2.0.5/wp-admin/import.php 2.2.2/wp-admin/import.php
--- 2.0.5/wp-admin/import.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/import.php	2007-04-07 10:46:09.000000000 -0500
@@ -1,13 +1,13 @@
 <?php
 require_once ('admin.php');
 $title = __('Import');
-$parent_file = 'import.php';
+$parent_file = 'edit.php';
 require_once ('admin-header.php');
 ?>
 
 <div class="wrap">
 <h2><?php _e('Import'); ?></h2>
-<p><?php _e('If you have posts or comments in another system WordPress can import them into your current blog. To get started, choose a system to import from below:'); ?></p>
+<p><?php _e('If you have posts or comments in another system, WordPress can import those into this blog. To get started, choose a system to import from below:'); ?></p>
 
 <?php
 
@@ -17,10 +17,11 @@
 $imports_dir = @ dir($import_root);
 if ($imports_dir) {
 	while (($file = $imports_dir->read()) !== false) {
-		if (preg_match('|^\.+$|', $file))
+		if ($file{0} == '.') {
 			continue;
-		if (preg_match('|\.php$|', $file))
-			require_once("$import_root/$file");
+		} elseif (substr($file, -4) == '.php') {
+			require_once($import_root . '/' . $file);
+		}
 	}
 }
 
@@ -30,7 +31,7 @@
 	echo '<p>'.__('No importers are available.').'</p>'; // TODO: make more helpful
 } else {
 ?>
-<table width="100%" cellpadding="3" cellspacing="3">
+<table class="widefat">
 
 <?php
 	$style = '';
@@ -42,8 +43,8 @@
 			$style = 'class="'.$style.'"';
 		echo "
 			<tr $style>
-				<td class=\"togl\">$action</td>
-				<td class=\"desc\">{$data[1]}</td>
+				<td class='import-system'>$action</td>
+				<td class='desc'>{$data[1]}</td>
 			</tr>";
 	}
 ?>
diff -ruN 2.0.5/wp-admin/index-extra.php 2.2.2/wp-admin/index-extra.php
--- 2.0.5/wp-admin/index-extra.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/index-extra.php	2007-02-06 14:12:53.000000000 -0600
@@ -0,0 +1,69 @@
+<?php
+require_once('admin.php');
+require_once (ABSPATH . WPINC . '/rss.php');
+
+@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
+
+switch ( $_GET['jax'] ) {
+
+case 'incominglinks' :
+$rss = @fetch_rss('http://feeds.technorati.com/cosmos/rss/?url='. trailingslashit(get_option('home')) .'&partner=wordpress');
+if ( isset($rss->items) && 1 < count($rss->items) ) { // Technorati returns a 1-item feed when it has no results
+?>
+<h3><?php _e('Incoming Links'); ?> <cite><a href="http://www.technorati.com/search/<?php echo trailingslashit(get_option('home')); ?>?partner=wordpress"><?php _e('More &raquo;'); ?></a></cite></h3>
+<ul>
+<?php
+$rss->items = array_slice($rss->items, 0, 10);
+foreach ($rss->items as $item ) {
+?>
+	<li><a href="<?php echo wp_filter_kses($item['link']); ?>"><?php echo wptexturize(wp_specialchars($item['title'])); ?></a></li>
+<?php } ?>
+</ul>
+<?php
+}
+break;
+
+case 'devnews' :
+$rss = @fetch_rss('http://wordpress.org/development/feed/');
+if ( isset($rss->items) && 0 != count($rss->items) ) {
+?>
+<h3><?php _e('WordPress Development Blog'); ?></h3>
+<?php
+$rss->items = array_slice($rss->items, 0, 3);
+foreach ($rss->items as $item ) {
+?>
+<h4><a href='<?php echo wp_filter_kses($item['link']); ?>'><?php echo wp_specialchars($item['title']); ?></a> &#8212; <?php printf(__('%s ago'), human_time_diff(strtotime($item['pubdate'], time() ) ) ); ?></h4>
+<p><?php echo $item['description']; ?></p>
+<?php
+	}
+}
+?>
+
+<?php
+break;
+
+case 'planetnews' :
+$rss = @fetch_rss('http://planet.wordpress.org/feed/');
+if ( isset($rss->items) && 0 != count($rss->items) ) {
+?>
+<h3><?php _e('Other WordPress News'); ?></h3>
+<ul>
+<?php
+$rss->items = array_slice($rss->items, 0, 20);
+foreach ($rss->items as $item ) {
+$title = wp_specialchars($item['title']);
+$author = preg_replace( '|(.+?):.+|s', '$1', $item['title'] );
+$post = preg_replace( '|.+?:(.+)|s', '$1', $item['title'] );
+?>
+<li><a href='<?php echo wp_filter_kses($item['link']); ?>'><span class="post"><?php echo $post; ?></span><span class="hidden"> - </span><cite><?php echo $author; ?></cite></a></li>
+<?php
+	}
+?>
+</ul>
+<p class="readmore"><a href="http://planet.wordpress.org/"><?php _e('Read more'); ?> &raquo;</a></p>
+<?php
+}
+break;
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/index.php 2.2.2/wp-admin/index.php
--- 2.0.5/wp-admin/index.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/index.php	2007-04-05 22:33:21.000000000 -0500
@@ -1,35 +1,37 @@
 <?php
 require_once('admin.php'); 
+
+function index_js() {
+?>
+<script type="text/javascript">
+Event.observe( window, 'load', dashboard_init, false );
+function dashboard_init() {
+	var update1 = new Ajax.Updater( 'incominglinks', 'index-extra.php?jax=incominglinks' );
+	var update2 = new Ajax.Updater( 'devnews', 'index-extra.php?jax=devnews' );
+	var update3 = new Ajax.Updater( 'planetnews', 'index-extra.php?jax=planetnews'	);
+}
+</script>
+<?php
+}
+add_action( 'admin_head', 'index_js' );
+wp_enqueue_script('prototype');
+wp_enqueue_script('interface');
+
 $title = __('Dashboard'); 
+$parent_file = 'index.php';
 require_once('admin-header.php');
-require_once (ABSPATH . WPINC . '/rss-functions.php');
 
 $today = current_time('mysql', 1);
 ?>
 
 <div class="wrap">
 
-<h2><?php _e('Dashboard'); ?></h2>
+<h2><?php _e('Welcome to WordPress'); ?></h2>
 
 <div id="zeitgeist">
 <h2><?php _e('Latest Activity'); ?></h2>
 
-<?php
-$rss = @fetch_rss('http://feeds.technorati.com/cosmos/rss/?url='. trailingslashit(get_option('home')) .'&partner=wordpress');
-if ( isset($rss->items) && 0 != count($rss->items) ) {
-?>
-<div id="incominglinks">
-<h3><?php _e('Incoming Links'); ?> <cite><a href="http://www.technorati.com/search/<?php echo trailingslashit(get_option('home')); ?>?partner=wordpress"><?php _e('More'); ?> &raquo;</a></cite></h3>
-<ul>
-<?php
-$rss->items = array_slice($rss->items, 0, 10);
-foreach ($rss->items as $item ) {
-?>
-	<li><a href="<?php echo wp_filter_kses($item['link']); ?>"><?php echo wptexturize(wp_specialchars($item['title'])); ?></a></li>
-<?php } ?>
-</ul>
-</div>
-<?php } ?>
+<div id="incominglinks"></div>
 
 <?php
 $comments = $wpdb->get_results("SELECT comment_author, comment_author_url, comment_ID, comment_post_ID FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 5");
@@ -45,11 +47,11 @@
 <?php endif; ?>
 
 <ul>
-<?php 
+<?php
 if ( $comments ) {
 foreach ($comments as $comment) {
-	echo '<li>' . sprintf(__('%1$s on %2$s'), get_comment_author_link(), '<a href="'. get_permalink($comment->comment_post_ID) . '#comment-' . $comment->comment_ID . '">' . get_the_title($comment->comment_post_ID) . '</a>');
-	edit_comment_link(__("Edit"), ' <small>(', ')</small>'); 
+	echo '<li>' . sprintf(__('%1$s on %2$s'), get_comment_author_link(), '<a href="'. get_permalink($comment->comment_post_ID) . '#comment-' . $comment->comment_ID . '">' . apply_filters('the_title', get_the_title($comment->comment_post_ID)) . '</a>');
+	edit_comment_link(__("Edit"), ' <small>(', ')</small>');
 	echo '</li>';
 }
 }
@@ -58,9 +60,8 @@
 </div>
 <?php endif; ?>
 
-
 <?php
-if ( $recentposts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_date_gmt < '$today' ORDER BY post_date DESC LIMIT 5") ) :
+if ( $recentposts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND " . get_private_posts_cap_sql('post') . " AND post_date_gmt < '$today' ORDER BY post_date DESC LIMIT 5") ) :
 ?>
 <div>
 <h3><?php _e('Posts'); ?> <a href="edit.php" title="<?php _e('More posts...'); ?>">&raquo;</a></h3>
@@ -79,8 +80,8 @@
 <?php endif; ?>
 
 <?php
-if ( $scheduled = $wpdb->get_results("SELECT ID, post_title, post_date_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_date_gmt > '$today' ORDER BY post_date ASC") ) :
-?> 
+if ( $scheduled = $wpdb->get_results("SELECT ID, post_title, post_date_gmt FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'future' ORDER BY post_date ASC") ) :
+?>
 <div>
 <h3><?php _e('Scheduled Entries:') ?></h3>
 <ul>
@@ -90,7 +91,7 @@
 		$post->post_title = sprintf(__('Post #%s'), $post->ID);
 	echo "<li>" . sprintf(__('%1$s in %2$s'), "<a href='post.php?action=edit&amp;post=$post->ID' title='" . __('Edit this post') . "'>$post->post_title</a>", human_time_diff( current_time('timestamp', 1), strtotime($post->post_date_gmt. ' GMT') ))  . "</li>";
 }
-?> 
+?>
 </ul>
 </div>
 <?php endif; ?>
@@ -98,70 +99,41 @@
 <div>
 <h3><?php _e('Blog Stats'); ?></h3>
 <?php
-$numposts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish'");
-if (0 < $numposts) $numposts = number_format($numposts); 
-
-$numcomms = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '1'");
-if (0 < $numcomms) $numcomms = number_format($numcomms);
+$numposts = (int) $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'");
+$numcomms = (int) $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '1'");
+$numcats  = (int) $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->categories");
 
-$numcats = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->categories");
-if (0 < $numcats) $numcats = number_format($numcats);
+$post_str = sprintf(__ngettext('%1$s <a href="%2$s" title="Posts">post</a>', '%1$s <a href="%2$s" title="Posts">posts</a>', $numposts), number_format($numposts), 'edit.php');
+$comm_str = sprintf(__ngettext('%1$s <a href="%2$s" title="Comments">comment</a>', '%1$s <a href="%2$s" title="Comments">comments</a>', $numcomms), number_format($numcomms), 'edit-comments.php');
+$cat_str  = sprintf(__ngettext('%1$s <a href="%2$s" title="Categories">category</a>', '%1$s <a href="%2$s" title="Categories">categories</a>', $numcats), number_format($numcats), 'categories.php');
 ?>
-<p><?php printf(__('There are currently %1$s <a href="%2$s" title="Posts">posts</a> and %3$s <a href="%4$s" title="Comments">comments</a>, contained within %5$s <a href="%6$s" title="categories">categories</a>.'), $numposts, 'edit.php',  $numcomms, 'edit-comments.php', $numcats, 'categories.php'); ?></p>
+
+<p><?php printf(__('There are currently %1$s and %2$s, contained within %3$s.'), $post_str, $comm_str, $cat_str); ?></p>
 </div>
 
 <?php do_action('activity_box_end'); ?>
 </div>
 
-<h3><?php _e('Welcome to WordPress'); ?></h3>
-
 <p><?php _e('Use these links to get started:'); ?></p>
 
 <ul>
-<li><a href="post.php"><?php _e('Write a post'); ?></a></li>
-<li><a href="profile.php"><?php _e('Update your profile or change your password'); ?></a></li>
-<li><a href="link-add.php"><?php _e('Add a link to your blogroll'); ?></a></li>
-<li><a href="themes.php"><?php _e('Change your site&#8217;s look or theme'); ?></a></li>
+<?php if ( current_user_can('edit_posts') ) : ?>
+	<li><a href="post-new.php"><?php _e('Write a post'); ?></a></li>
+<?php endif; ?>
+	<li><a href="profile.php"><?php _e('Update your profile or change your password'); ?></a></li>
+<?php if ( current_user_can('manage_links') ) : ?>
+	<li><a href="link-add.php"><?php _e('Add a link to your blogroll'); ?></a></li>
+<?php endif; ?>
+<?php if ( current_user_can('switch_themes') ) : ?>
+	<li><a href="themes.php"><?php _e('Change your site&#8217;s look or theme'); ?></a></li>
+<?php endif; ?>
 </ul>
+<p><?php _e("Need help with WordPress? Please see our <a href='http://codex.wordpress.org/'>documentation</a> or visit the <a href='http://wordpress.org/support/'>support forums</a>."); ?></p>
 
-<p><?php _e("Below is the latest news from the official WordPress development blog, click on a title to read the full entry. If you need help with WordPress please see our <a href='http://codex.wordpress.org/'>great documentation</a> or if that doesn't help visit the <a href='http://wordpress.org/support/'>support forums</a>."); ?></p>
-<?php
-$rss = @fetch_rss('http://wordpress.org/development/feed/');
-if ( isset($rss->items) && 0 != count($rss->items) ) {
-?>
-<h3><?php _e('WordPress Development Blog'); ?></h3>
-<?php
-$rss->items = array_slice($rss->items, 0, 3);
-foreach ($rss->items as $item ) {
-?>
-<h4><a href='<?php echo wp_filter_kses($item['link']); ?>'><?php echo wp_specialchars($item['title']); ?></a> &#8212; <?php printf(__('%s ago'), human_time_diff(strtotime($item['pubdate'], time() ) ) ); ?></h4>
-<p><?php echo $item['description']; ?></p>
-<?php
-	}
-}
-?>
+<div id="devnews"></div>
 
+<div id="planetnews"></div>
 
-<?php
-$rss = @fetch_rss('http://planet.wordpress.org/feed/');
-if ( isset($rss->items) && 0 != count($rss->items) ) {
-?>
-<div id="planetnews">
-<h3><?php _e('Other WordPress News'); ?> <a href="http://planet.wordpress.org/"><?php _e('more'); ?> &raquo;</a></h3>
-<ul>
-<?php
-$rss->items = array_slice($rss->items, 0, 20);
-foreach ($rss->items as $item ) {
-?>
-<li><a href='<?php echo wp_filter_kses($item['link']); ?>'><?php echo wp_specialchars($item['title']); ?></a></li>
-<?php
-	}
-?>
-</ul>
-</div>
-<?php
-}
-?>
 <div style="clear: both">&nbsp;
 <br clear="all" />
 </div>
diff -ruN 2.0.5/wp-admin/inline-uploading.php 2.2.2/wp-admin/inline-uploading.php
--- 2.0.5/wp-admin/inline-uploading.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/inline-uploading.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,724 +0,0 @@
-<?php
-
-require_once('admin.php');
-
-header('Content-Type: text/html; charset=' . get_option('blog_charset'));
-
-if (!current_user_can('upload_files'))
-	die(__('You do not have permission to upload files.'));
-
-$wpvarstoreset = array('action', 'post', 'all', 'last', 'link', 'sort', 'start', 'imgtitle', 'descr', 'attachment');
-
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-			$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
-
-$all = ( 'true' == $all ) ? 'true' : 'false';
-$start = (int) $start;
-$post = (int) $post;
-$images_width = 1;
-
-switch($action) {
-case 'links':
-// Do not pass GO.
-break;
-
-case 'delete':
-
-check_admin_referer('inlineuploading');
-
-if ( !current_user_can('edit_post', (int) $attachment) )
-	die(__('You are not allowed to delete this attachment.').' <a href="'.basename(__FILE__)."?post=$post&amp;all=$all&amp;action=upload\">".__('Go back').'</a>');
-
-wp_delete_attachment($attachment);
-
-wp_redirect(basename(__FILE__) ."?post=$post&all=$all&action=view&start=$start");
-die;
-
-case 'save':
-
-check_admin_referer('inlineuploading');
-
-$overrides = array('action'=>'save');
-
-$file = wp_handle_upload($_FILES['image'], $overrides);
-
-if ( isset($file['error']) )
-	die($file['error'] . '<br /><a href="' . basename(__FILE__) . '?action=upload&post=' . $post . '">'.__('Back to Image Uploading').'</a>');
-
-$url = $file['url'];
-$type = $file['type'];
-$file = $file['file'];
-$filename = basename($file);
-
-// Construct the attachment array
-$attachment = array(
-	'post_title' => $imgtitle ? $imgtitle : $filename,
-	'post_content' => $descr,
-	'post_status' => 'attachment',
-	'post_parent' => $post,
-	'post_mime_type' => $type,
-	'guid' => $url
-	);
-
-// Save the data
-$id = wp_insert_attachment($attachment, $file, $post);
-
-if ( preg_match('!^image/!', $attachment['post_mime_type']) ) {
-	// Generate the attachment's postmeta.
-	$imagesize = getimagesize($file);
-	$imagedata['width'] = $imagesize['0'];
-	$imagedata['height'] = $imagesize['1'];
-	list($uwidth, $uheight) = get_udims($imagedata['width'], $imagedata['height']);
-	$imagedata['hwstring_small'] = "height='$uheight' width='$uwidth'";
-	$imagedata['file'] = $file;
-
-	add_post_meta($id, '_wp_attachment_metadata', $imagedata);
-
-	if ( $imagedata['width'] * $imagedata['height'] < 3 * 1024 * 1024 ) {
-		if ( $imagedata['width'] > 128 && $imagedata['width'] >= $imagedata['height'] * 4 / 3 )
-			$thumb = wp_create_thumbnail($file, 128);
-		elseif ( $imagedata['height'] > 96 )
-			$thumb = wp_create_thumbnail($file, 96);
-
-		if ( @file_exists($thumb) ) {
-			$newdata = $imagedata;
-			$newdata['thumb'] = basename($thumb);
-			update_post_meta($id, '_wp_attachment_metadata', $newdata, $imagedata);
-		} else {
-			$error = $thumb;
-		}
-	}
-} else {
-	add_post_meta($id, '_wp_attachment_metadata', array());
-}
-
-wp_redirect(basename(__FILE__) . "?post=$post&all=$all&action=view&start=0");
-die();
-
-case 'upload':
-
-$current_1 = ' class="current"';
-$back = $next = false;
-break;
-
-case 'view':
-
-// How many images do we show? How many do we query?
-$num = 5;
-$double = $num * 2;
-
-if ( $post && (empty($all) || $all == 'false') ) {
-	$and_post = "AND post_parent = '$post'";
-	$current_2 = ' class="current"';
-} else {
-	$current_3 = ' class="current"';
-}
-
-if (! current_user_can('edit_others_posts') )
-	$and_user = "AND post_author = " . $user_ID;
-
-if ( $last )
-	$start = $wpdb->get_var("SELECT count(ID) FROM $wpdb->posts WHERE post_status = 'attachment' $and_user $and_post") - $num;
-else
-	$start = (int) $start;
-
-if ( $start < 0 )
-	$start = 0;
-
-if ( '' == $sort )
-	$sort = "post_date_gmt DESC";
-
-$attachments = $wpdb->get_results("SELECT ID, post_date, post_title, post_mime_type, guid FROM $wpdb->posts WHERE post_status = 'attachment' $and_type $and_post $and_user ORDER BY $sort LIMIT $start, $double", ARRAY_A);
-
-if ( count($attachments) == 0 ) {
-	wp_redirect( basename(__FILE__) ."?post=$post&action=upload" );
-	die;
-} elseif ( count($attachments) > $num ) {
-	$next = $start + count($attachments) - $num;
-} else {
-	$next = false;
-}
-
-if ( $start > 0 ) {
-	$back = $start - $num;
-	if ( $back < 1 )
-		$back = '0';
-} else {
-	$back = false;
-}
-
-$uwidth_sum = 0;
-$html = '';
-$popups = '';
-$style = '';
-$script = '';
-if ( count($attachments) > 0 ) {
-	$attachments = array_slice( $attachments, 0, $num );
-	$__delete = __('Delete');
-	$__not_linked = __('Not Linked');
-	$__linked_to_page = __('Linked to Page');
-	$__linked_to_image = __('Linked to Image');
-	$__linked_to_file = __('Linked to File');
-	$__using_thumbnail = __('Using Thumbnail');
-	$__using_original = __('Using Original');
-	$__using_title = __('Using Title');
-	$__using_filename = __('Using Filename');
-	$__using_icon = __('Using Icon');
-	$__no_thumbnail = '<del>'.__('No Thumbnail').'</del>';
-	$__send_to_editor = __('Send to editor');
-	$__close = __('Close Options');
-	$__confirmdelete = __('Delete this file from the server?');
-	$__nothumb = __('There is no thumbnail associated with this photo.');
-	$script .= "notlinked = '$__not_linked';
-linkedtoimage = '$__linked_to_image';
-linkedtopage = '$__linked_to_page';
-linkedtofile = '$__linked_to_file';
-usingthumbnail = '$__using_thumbnail';
-usingoriginal = '$__using_original';
-usingtitle = '$__using_title';
-usingfilename = '$__using_filename';
-usingicon = '$__using_icon';
-var aa = new Array();
-var ab = new Array();
-var imga = new Array();
-var imgb = new Array();
-var srca = new Array();
-var srcb = new Array();
-var title = new Array();
-var filename = new Array();
-var icon = new Array();
-";
-	foreach ( $attachments as $key => $attachment ) {
-		$ID = $attachment['ID'];
-		$href = get_attachment_link($ID);
-		$meta = get_post_meta($ID, '_wp_attachment_metadata', true);
-		if (!is_array($meta)) {
-			$meta = get_post_meta($ID, 'imagedata', true); // Try 1.6 Alpha meta key
-			if (!is_array($meta)) {
-				$meta = array();
-			}
-			add_post_meta($ID, '_wp_attachment_metadata', $meta);
-		}
-		$attachment = array_merge($attachment, $meta);
-		$noscript = "<noscript>
-		<div class='caption'><a href=\"".basename(__FILE__)."?action=links&amp;attachment={$ID}&amp;post={$post}&amp;all={$all}&amp;start={$start}\">Choose Links</a></div>
-		</noscript>
-";
-		$send_delete_cancel = "<a onclick=\"sendToEditor({$ID});return false;\" href=\"javascript:void()\">$__send_to_editor</a>
-<a onclick=\"return confirm('$__confirmdelete')\" href=\"" . wp_nonce_url( basename(__FILE__) . "?action=delete&amp;attachment={$ID}&amp;all=$all&amp;start=$start&amp;post=$post", inlineuploading) . "\">$__delete</a>
-		<a onclick=\"popup.style.display='none';return false;\" href=\"javascript:void()\">$__close</a>
-";
-		$uwidth_sum += 128;
-		if ( preg_match('!^image/!', $attachment['post_mime_type'] ) ) {
-			$image = & $attachment;
-			if ( ($image['width'] > 128 || $image['height'] > 96) && !empty($image['thumb']) && file_exists(dirname($image['file']).'/'.$image['thumb']) ) {
-				$src = str_replace(basename($image['guid']), $image['thumb'], $image['guid']);
-				$script .= "srca[{$ID}] = '$src';
-srcb[{$ID}] = '{$image['guid']}';
-";
-				$thumb = 'true';
-				$thumbtext = $__using_thumbnail;
-			} else {
-				$src = $image['guid'];
-				$thumb = 'false';
-				$thumbtext = $__no_thumbnail;
-			}
-			list($image['uwidth'], $image['uheight']) = get_udims($image['width'], $image['height']);
-			$height_width = 'height="'.$image['uheight'].'" width="'.$image['uwidth'].'"';
-			$xpadding = (128 - $image['uwidth']) / 2;
-			$ypadding = (96 - $image['uheight']) / 2;
-			$style .= "#target{$ID} img { padding: {$ypadding}px {$xpadding}px; }\n";
-			$title = wp_specialchars($image['post_title'], ENT_QUOTES);
-			$script .= "aa[{$ID}] = '<a id=\"p{$ID}\" rel=\"attachment\" class=\"imagelink\" href=\"$href\" onclick=\"doPopup({$ID});return false;\" title=\"{$title}\">';
-ab[{$ID}] = '<a class=\"imagelink\" href=\"{$image['guid']}\" onclick=\"doPopup({$ID});return false;\" title=\"{$title}\">';
-imga[{$ID}] = '<img id=\"image{$ID}\" src=\"$src\" alt=\"{$title}\" $height_width />';
-imgb[{$ID}] = '<img id=\"image{$ID}\" src=\"{$image['guid']}\" alt=\"{$title}\" $height_width />';
-";
-			$html .= "<div id='target{$ID}' class='attwrap left'>
-	<div id='div{$ID}' class='imagewrap' onclick=\"doPopup({$ID});\">
-		<img id=\"image{$ID}\" src=\"$src\" alt=\"{$title}\" $height_width />
-	</div>
-	{$noscript}
-</div>
-";
-			$popups .= "<div id='popup{$ID}' class='popup'>
-	<a id=\"I{$ID}\" onclick=\"if($thumb)toggleImage({$ID});else alert('$__nothumb');return false;\" href=\"javascript:void()\">$thumbtext</a>
-	<a id=\"L{$ID}\" onclick=\"toggleLink({$ID});return false;\" href=\"javascript:void()\">$__not_linked</a>
-	{$send_delete_cancel}
-</div>
-";
-		} else {
-			$title = wp_specialchars($attachment['post_title'], ENT_QUOTES);
-			$filename = basename($attachment['guid']);
-			$icon = get_attachment_icon($ID);
-			$toggle_icon = "<a id=\"I{$ID}\" onclick=\"toggleOtherIcon({$ID});return false;\" href=\"javascript:void()\">$__using_title</a>";
-			$script .= "aa[{$ID}] = '<a id=\"p{$ID}\" rel=\"attachment\" href=\"$href\" onclick=\"doPopup({$ID});return false;\" title=\"{$title}\">';
-ab[{$ID}] = '<a id=\"p{$ID}\" href=\"{$filename}\" onclick=\"doPopup({$ID});return false;\" title=\"{$title}\">';
-title[{$ID}] = '{$title}';
-filename[{$ID}] = '{$filename}';
-icon[{$ID}] = '{$icon}';
-";
-			$html .= "<div id='target{$ID}' class='attwrap left'>
-	<div id='div{$ID}' class='otherwrap usingtext' onmousedown=\"selectLink({$ID})\" onclick=\"doPopup({$ID});return false;\">
-		<a id=\"p{$ID}\" href=\"{$attachment['guid']}\" onmousedown=\"selectLink({$ID});\" onclick=\"return false;\">{$title}</a>
-	</div>
-	{$noscript}
-</div>
-";
-			$popups .= "<div id='popup{$ID}' class='popup'>
-	<div class='filetype'>".__('File Type:').' '.str_replace('/',"/\n",$attachment['post_mime_type'])."</div>
-	<a id=\"L{$ID}\" onclick=\"toggleOtherLink({$ID});return false;\" href=\"javascript:void()\">$__linked_to_file</a>
-	{$toggle_icon}
-	{$send_delete_cancel}
-</div>
-";
-		}
-	}
-}
-
-$images_width = $uwidth_sum + ( count($images) * 6 ) + 35;
-
-break;
-
-default:
-die(__('This script was not meant to be called directly.'));
-}
-
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
-<title></title>
-<meta http-equiv="imagetoolbar" content="no" />
-<script type="text/javascript">
-// <![CDATA[
-/* Define any variables we'll need, such as alternate URLs. */
-<?php echo $script; ?>
-function htmldecode(st) {
-	o = document.getElementById('htmldecode');
-	if (! o) {
-		o = document.createElement("A");
-		o.id = "htmldecode"
-	}
-	o.innerHTML = st;
-	r = o.innerHTML;
-	return r;
-}
-function cancelUpload() {
-	o = document.getElementById('uploadForm');
-	o.method = 'GET';
-	o.action.value = 'view';
-	o.submit();
-}
-function doPopup(i) {
-	if ( popup )
-	popup.style.display = 'none';
-	target = document.getElementById('target'+i);
-	popup = document.getElementById('popup'+i);
-	popup.style.left = (target.offsetLeft) + 'px';
-	popup.style.top = (target.offsetTop) + 'px';
-	popup.style.display = 'block';
-}
-popup = false;
-function selectLink(n) {
-	o=document.getElementById('div'+n);
-	if ( typeof document.body.createTextRange == 'undefined' || typeof win.tinyMCE == 'undefined' || win.tinyMCE.configs.length < 1 )
-		return;
-	r = document.body.createTextRange();
-	if ( typeof r != 'undefined' ) {
-		r.moveToElementText(o);
-		r.select();
-	}
-}
-function toggleLink(n) {
-	ol=document.getElementById('L'+n);
-	if ( ol.innerHTML == htmldecode(notlinked) ) {
-		ol.innerHTML = linkedtoimage;
-	} else if ( ol.innerHTML == htmldecode(linkedtoimage) ) {
-		ol.innerHTML = linkedtopage;
-	} else {
-		ol.innerHTML = notlinked;
-	}
-	updateImage(n);
-}
-function toggleOtherLink(n) {
-	ol=document.getElementById('L'+n);
-	if ( ol.innerHTML == htmldecode(linkedtofile) ) {
-		ol.innerHTML = linkedtopage;
-	} else {
-		ol.innerHTML = linkedtofile;
-	}
-	updateOtherIcon(n);
-}
-function toggleImage(n) {
-	oi = document.getElementById('I'+n);
-	if ( oi.innerHTML == htmldecode(usingthumbnail) ) {
-		oi.innerHTML = usingoriginal;
-	} else {
-		oi.innerHTML = usingthumbnail;
-	}
-	updateImage(n);
-}
-function toggleOtherIcon(n) {
-	od = document.getElementById('div'+n);
-	oi = document.getElementById('I'+n);
-	if ( oi.innerHTML == htmldecode(usingtitle) ) {
-		oi.innerHTML = usingfilename;
-		od.className = 'otherwrap usingtext';
-	} else if ( oi.innerHTML == htmldecode(usingfilename) && icon[n] != '' ) {
-		oi.innerHTML = usingicon;
-		od.className = 'otherwrap usingicon';
-	} else {
-		oi.innerHTML = usingtitle;
-		od.className = 'otherwrap usingtext';
-	}
-	updateOtherIcon(n);
-}
-function updateImage(n) {
-	od=document.getElementById('div'+n);
-	ol=document.getElementById('L'+n);
-	oi=document.getElementById('I'+n);
-	if ( oi.innerHTML == htmldecode(usingthumbnail) ) {
-		img = imga[n];
-	} else {
-		img = imgb[n];
-	}
-	if ( ol.innerHTML == htmldecode(linkedtoimage) ) {
-		od.innerHTML = ab[n]+img+'</a>';
-	} else if ( ol.innerHTML == htmldecode(linkedtopage) ) {
-		od.innerHTML = aa[n]+img+'</a>';
-	} else {
-		od.innerHTML = img;
-	}
-}
-function updateOtherIcon(n) {
-	od=document.getElementById('div'+n);
-	ol=document.getElementById('L'+n);
-	oi=document.getElementById('I'+n);
-	if ( oi.innerHTML == htmldecode(usingfilename) ) {
-		txt = filename[n];
-	} else if ( oi.innerHTML == htmldecode(usingicon) ) {
-		txt = icon[n];
-	} else {
-		txt = title[n];
-	}
-	if ( ol.innerHTML == htmldecode(linkedtofile) ) {
-		od.innerHTML = ab[n]+txt+'</a>';
-	} else if ( ol.innerHTML == htmldecode(linkedtopage) ) {
-		od.innerHTML = aa[n]+txt+'</a>';
-	} else {
-		od.innerHTML = txt;
-	}
-}
-
-var win = window.opener ? window.opener : window.dialogArguments;
-if (!win) win = top;
-tinyMCE = win.tinyMCE;
-richedit = ( typeof tinyMCE == 'object' && tinyMCE.configs.length > 0 );
-function sendToEditor(n) {
-	o = document.getElementById('div'+n);
-	h = o.innerHTML.replace(new RegExp('^\\s*(.*?)\\s*$', ''), '$1'); // Trim
-	h = h.replace(new RegExp(' (class|title|width|height|id|onclick|onmousedown)=([^\'"][^ ]*)( |/|>)', 'g'), ' $1="$2"$3'); // Enclose attribs in quotes
-	h = h.replace(new RegExp(' (width|height)=".*?"', 'g'), ''); // Drop size constraints
-	h = h.replace(new RegExp(' on(click|mousedown)="[^"]*"', 'g'), ''); // Drop menu events
-	h = h.replace(new RegExp('<(/?)A', 'g'), '<$1a'); // Lowercase tagnames
-	h = h.replace(new RegExp('<IMG', 'g'), '<img'); // Lowercase again
-	h = h.replace(new RegExp('(<img .+?")>', 'g'), '$1 />'); // XHTML
-	if ( richedit )
-		win.tinyMCE.execCommand('mceInsertContent', false, h);
-	else
-		win.edInsertContent(win.edCanvas, h);
-}
-// ]]>
-</script>
-<style type="text/css">
-<?php if ( $action == 'links' ) : ?>
-* html { overflow-x: hidden; }
-<?php else : ?>
-* html { overflow-y: hidden; }
-<?php endif; ?>
-body {
-	font: 13px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana;
-	border: none;
-	margin: 0px;
-	height: 150px;
-	background: #dfe8f1;
-}
-form {
-	margin: 3px 2px 0px 6px;
-}
-#wrap {
-	clear: both;
-	padding: 0px;
-	width: 100%;
-}
-#images {
-	position: absolute;
-	clear: both;
-	margin: 0px;
-	padding: 15px 15px;
-	width: <?php echo $images_width; ?>px;
-}
-#images img {
-	background-color: rgb(209, 226, 239);
-}
-<?php echo $style; ?>
-.attwrap, .attwrap * {
-	margin: 0px;
-	padding: 0px;
-	border: 0px;
-}
-.imagewrap {
-	margin-right: 5px;
-	overflow: hidden;
-	width: 128px;
-}
-.otherwrap {
-	margin-right: 5px;
-	overflow: hidden;
-	background-color: #f9fcfe;
-}
-.otherwrap a {
-	display: block;
-}
-.otherwrap a, .otherwrap a:hover, .otherwrap a:active, .otherwrap a:visited {
-	color: blue;
-}
-.usingicon {
-	padding: 0px;
-	height: 96px;
-	text-align: center;
-	width: 128px;
-}
-.usingtext {
-	padding: 3px;
-	height: 90px;
-	text-align: left;
-	width: 122px;
-}
-.filetype {
-	font-size: 80%;
-	border-bottom: 3px double #89a
-}
-.imagewrap, .imagewrap img, .imagewrap a, .imagewrap a img, .imagewrap a:hover img, .imagewrap a:visited img, .imagewrap a:active img {
-	text-decoration: none;
-}
-#upload-menu {
-	background: #fff;
-	margin: 0px;
-	padding: 0;
-	list-style: none;
-	height: 2em;
-	border-bottom: 1px solid #448abd;
-	width: 100%;
-}
-#upload-menu li {
-	float: left;
-	margin: 0 0 0 .75em;
-}
-#upload-menu a {
-	display: block;
-	padding: 5px;
-	text-decoration: none;
-	color: #000;
-	border-top: 3px solid #fff;
-}
-#upload-menu .current a {
-	background: #dfe8f1;
-	border-right: 2px solid #448abd;
-}
-#upload-menu a:hover {
-	background: #dfe8f1;
-	color: #000;
-}
-.tip {
-	color: rgb(68, 138, 189);
-	padding: 2px 1em;
-}
-.inactive {
-	color: #fff;
-	padding: 1px 3px;
-}
-.left {
-	float: left;
-}
-.right {
-	float: right;
-}
-.center {
-	text-align: center;
-}
-#upload-menu li.spacer {
-	margin-left: 40px;
-}
-#title, #descr {
-	width: 99%;
-	margin-top: 1px;
-}
-th {
-	width: 4.5em;
-}
-#descr {
-	height: 36px;
-}
-#buttons {
-	margin-top: 2px;
-	text-align: right;
-}
-.popup {
-	margin: 4px 4px;
-	padding: 1px;
-	position: absolute;
-	width: 114px;
-	display: none;
-	background-color: rgb(240, 240, 238);
-	border-top: 2px solid #fff;
-	border-right: 2px solid #ddd;
-	border-bottom: 2px solid #ddd;
-	border-left: 2px solid #fff;
-	text-align: center;
-}
-.imagewrap .popup {
-	opacity: .90;
-	filter:alpha(opacity=90);
-}
-.otherwrap .popup {
-	padding-top: 20px;
-}
-.popup a, .popup a:visited, .popup a:active {
-	background-color: transparent;
-	display: block;
-	width: 100%;
-	text-decoration: none;
-	color: #246;
-}
-.popup a:hover {
-	background-color: #fff;
-	color: #000;
-}
-.caption {
-	text-align: center;
-}
-#submit {
-	margin: 1px;
-	width: 99%;
-}
-#submit input, #submit input:focus {
-	background: url( images/fade-butt.png );
-	border: 3px double #999;
-	border-left-color: #ccc;
-	border-top-color: #ccc;
-	color: #333;
-	padding: 0.25em;
-}
-#submit input:active {
-	background: #f4f4f4;
-	border: 3px double #ccc;
-	border-left-color: #999;
-	border-top-color: #999;
-}
-.zerosize {
-	width: 0px;
-	height: 0px;
-	overflow: hidden;
-	position: absolute;
-}
-#links {
-	margin: 3px 8px;
-	line-height: 2em;
-}
-#links textarea {
-	width: 95%;
-	height: 4.5em;
-}
-</style>
-</head>
-<body>
-<ul id="upload-menu">
-<li<?php echo $current_1; ?>><a href="<?php echo basename(__FILE__) . "?action=upload&amp;post=$post&amp;all=$all&amp;start=$start"; ?>"><?php _e('Upload'); ?></a></li>
-<?php if ( $attachments = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_parent = '$post'") ) { ?>
-<li<?php echo $current_2; ?>><a href="<?php echo basename(__FILE__) . "?action=view&amp;post=$post&amp;all=false"; ?>"><?php _e('Browse'); ?></a></li>
-<?php } ?>
-<?php if ($wpdb->get_var("SELECT count(ID) FROM $wpdb->posts WHERE post_status = 'attachment'")) { ?>
-<li<?php echo $current_3; ?>><a href="<?php echo basename(__FILE__) . "?action=view&amp;post=$post&amp;all=true"; ?>"><?php _e('Browse All'); ?></a></li>
-<?php } ?>
-<li> </li>
-<?php if ( $action == 'view' ) { ?>
-<?php if ( false !== $back ) : ?>
-<li class="spacer"><a href="<?php echo basename(__FILE__) . "?action=$action&amp;post=$post&amp;all=$all&amp;start=0"; ?>" title="<?php _e('First'); ?>">|&laquo;</a></li>
-<li><a href="<?php echo basename(__FILE__) . "?action=$action&amp;post=$post&amp;all=$all&amp;start=$back"; ?>">&laquo; <?php _e('Back'); ?></a></li>
-<?php else : ?>
-<li class="inactive spacer">|&laquo;</li>
-<li class="inactive">&laquo; <?php _e('Back'); ?></li>
-<?php endif; ?>
-<?php if ( false !== $next ) : ?>
-<li><a href="<?php echo basename(__FILE__) . "?action=$action&amp;post=$post&amp;all=$all&amp;start=$next"; ?>"><?php _e('Next &raquo;'); ?></a></li>
-<li><a href="<?php echo basename(__FILE__) . "?action=$action&amp;post=$post&amp;all=$all&amp;last=true"; ?>" title="<?php _e('Last'); ?>">&raquo;|</a></li>
-<?php else : ?>
-<li class="inactive"><?php _e('Next'); ?> &raquo;</li>
-<li class="inactive">&raquo;|</li>
-<?php endif; ?>
-<?php } // endif not upload?>
-</ul>
-<?php if ( $action == 'view' ) : ?>
-<div id="wrap">
-<!--<div class="tip"><?php _e('You can drag and drop these items into your post. Click on one for more options.'); ?></div>-->
-<div id="images">
-<?php echo $html; ?>
-<?php echo $popups; ?>
-</div>
-</div>
-<?php elseif ( $action == 'upload' ) : ?>
-<div class="tip"></div>
-<form enctype="multipart/form-data" id="uploadForm" method="post" action="<?php echo basename(__FILE__); ?>">
-<table style="width:99%;">
-<tr>
-<th scope="row" align="right"><label for="upload"><?php _e('File:'); ?></label></th>
-<td><input type="file" id="upload" name="image" /></td>
-</tr>
-<tr>
-<th scope="row" align="right"><label for="title"><?php _e('Title:'); ?></label></th>
-<td><input type="text" id="title" name="imgtitle" /></td>
-</tr>
-<tr>
-<th scope="row" align="right"><label for="descr"><?php _e('Description:'); ?></label></th>
-<td><input type="textarea" name="descr" id="descr" value="" /></td>
-</tr>
-<tr id="buttons">
-<th></th>
-<td>
-<input type="hidden" name="action" value="save" />
-<input type="hidden" name="post" value="<?php echo $post; ?>" />
-<input type="hidden" name="all" value="<?php echo $all; ?>" />
-<input type="hidden" name="start" value="<?php echo $start; ?>" />
-<?php wp_nonce_field( 'inlineuploading' ); ?>
-<div id="submit">
-<input type="submit" value="<?php _e('Upload'); ?>" />
-<?php if ( !empty($all) ) : ?>
-<input type="button" value="<?php _e('Cancel'); ?>" onclick="cancelUpload()" />
-<?php endif; ?>
-</div>
-</td>
-</tr>
-</table>
-</form>
-<?php elseif ( $action == 'links' ) : ?>
-<div id="links">
-<?php the_attachment_links($attachment); ?>
-</div>
-<?php endif; ?>
-</body>
-</html>
diff -ruN 2.0.5/wp-admin/install-helper.php 2.2.2/wp-admin/install-helper.php
--- 2.0.5/wp-admin/install-helper.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/install-helper.php	2006-11-19 01:56:05.000000000 -0600
@@ -0,0 +1,152 @@
+<?php
+require_once('../wp-config.php');
+$debug = 0;
+
+/**
+ ** maybe_create_table()
+ ** Create db table if it doesn't exist.
+ ** Returns:  true if already exists or on successful completion
+ **           false on error
+ */
+function maybe_create_table($table_name, $create_ddl) {
+	global $wpdb;
+	foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
+		if ($table == $table_name) {
+			return true;
+		}
+	}
+	//didn't find it try to create it.
+	$q = $wpdb->query($create_ddl);
+	// we cannot directly tell that whether this succeeded!
+	foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
+		if ($table == $table_name) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ ** maybe_add_column()
+ ** Add column to db table if it doesn't exist.
+ ** Returns:  true if already exists or on successful completion
+ **           false on error
+ */
+function maybe_add_column($table_name, $column_name, $create_ddl) {
+	global $wpdb, $debug;
+	foreach ($wpdb->get_col("DESC $table_name",0) as $column ) {
+		if ($debug) echo("checking $column == $column_name<br />");
+			if ($column == $column_name) {
+				return true;
+			}
+	}
+	//didn't find it try to create it.
+	$q = $wpdb->query($create_ddl);
+	// we cannot directly tell that whether this succeeded!
+	foreach ($wpdb->get_col("DESC $table_name",0) as $column ) {
+		if ($column == $column_name) {
+			return true;
+		}
+	}
+	return false;
+}
+
+
+/**
+ ** maybe_drop_column()
+ ** Drop column from db table if it exists.
+ ** Returns:  true if it doesn't already exist or on successful drop
+ **           false on error
+ */
+function maybe_drop_column($table_name, $column_name, $drop_ddl) {
+	global $wpdb;
+	foreach ($wpdb->get_col("DESC $table_name",0) as $column ) {
+		if ($column == $column_name) {
+			//found it try to drop it.
+			$q = $wpdb->query($drop_ddl);
+			// we cannot directly tell that whether this succeeded!
+			foreach ($wpdb->get_col("DESC $table_name",0) as $column ) {
+				if ($column == $column_name) {
+					return false;
+				}
+			}
+		}
+	}
+	// else didn't find it
+	return true;
+}
+
+
+/**
+ ** check_column()
+ ** Check column matches passed in criteria.
+ ** Pass in null to skip checking that criteria
+ ** Returns:  true if it matches
+ **           false otherwise
+ ** (case sensitive) Column names returned from DESC table are:
+ **      Field
+ **      Type
+ **      Null
+ **      Key
+ **      Default
+ **      Extra
+ */
+function check_column($table_name, $col_name, $col_type, $is_null = null, $key = null, $default = null, $extra = null) {
+	global $wpdb, $debug;
+	$diffs = 0;
+	$results = $wpdb->get_results("DESC $table_name");
+
+	foreach ($results as $row ) {
+		if ($debug > 1) print_r($row);
+			if ($row->Field == $col_name) {
+				// got our column, check the params
+				if ($debug) echo ("checking $row->Type against $col_type\n");
+				if (($col_type != null) && ($row->Type != $col_type)) {
+					++$diffs;
+				}
+				if (($is_null != null) && ($row->Null != $is_null)) {
+					++$diffs;
+				}
+				if (($key != null) && ($row->Key  != $key)) {
+					++$diffs;
+				}
+				if (($default != null) && ($row->Default != $default)) {
+					++$diffs;
+				}
+				if (($extra != null) && ($row->Extra != $extra)) {
+					++$diffs;
+				}
+				if ($diffs > 0) {
+					if ($debug) echo ("diffs = $diffs returning false\n");
+					return false;
+				}
+				return true;
+			} // end if found our column
+	}
+	return false;
+}
+
+/*
+echo "<p>testing</p>";
+echo "<pre>";
+
+//check_column('wp_links', 'link_description', 'mediumtext');
+//if (check_column($wpdb->comments, 'comment_author', 'tinytext'))
+//    echo "ok\n";
+$error_count = 0;
+$tablename = $wpdb->links;
+// check the column
+if (!check_column($wpdb->links, 'link_description', 'varchar(255)'))
+{
+	$ddl = "ALTER TABLE $wpdb->links MODIFY COLUMN link_description varchar(255) NOT NULL DEFAULT '' ";
+	$q = $wpdb->query($ddl);
+}
+if (check_column($wpdb->links, 'link_description', 'varchar(255)')) {
+	$res .= $tablename . ' - ok <br />';
+} else {
+	$res .= 'There was a problem with ' . $tablename . '<br />';
+	++$error_count;
+}
+echo "</pre>";
+*/
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/install-rtl.css 2.2.2/wp-admin/install-rtl.css
--- 2.0.5/wp-admin/install-rtl.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/install-rtl.css	2006-10-25 16:34:42.000000000 -0500
@@ -0,0 +1,5 @@
+body { font-family: Tahoma, Georgia, "Times New Roman", Times, serif; }
+
+ul, ol { padding: 5px 20px 5px 5px; }
+
+.step, th { text-align: left; }
diff -ruN 2.0.5/wp-admin/install.css 2.2.2/wp-admin/install.css
--- 2.0.5/wp-admin/install.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/install.css	2006-10-25 16:34:42.000000000 -0500
@@ -0,0 +1,40 @@
+html { background: #eee; }
+
+body {
+	background: #fff;
+	color: #000;
+	font-family: Georgia, "Times New Roman", Times, serif;
+	margin-left: 20%;
+	margin-right: 20%;
+	padding: .2em 2em;
+}
+
+h1 {
+	color: #006;
+	font-size: 18px;
+	font-weight: lighter;
+}
+
+h2 { font-size: 16px; }
+
+p, li, dt {
+	line-height: 140%;
+	padding-bottom: 2px;
+}
+
+ul, ol { padding: 5px 5px 5px 20px; }
+
+#logo { margin-bottom: 2em; }
+
+.step a, .step input { font-size: 2em; }
+
+td input { font-size: 1.5em; }
+
+.step, th { text-align: right; }
+
+#footer {
+	text-align: center; 
+	border-top: 1px solid #ccc; 
+	padding-top: 1em; 
+	font-style: italic;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/install.php 2.2.2/wp-admin/install.php
--- 2.0.5/wp-admin/install.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/install.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,110 @@
+<?php
+define('WP_INSTALLING', true);
+if (!file_exists('../wp-config.php')) {
+  require_once('../wp-includes/functions.php');
+  wp_die("There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Editing_wp-config.php'>We got it</a>. You can <a href='setup-config.php'>create a <code>wp-config.php</code> file through a web interface</a>, but this doesn't work for all server setups. The safest way is to manually create the file.", "WordPress &rsaquo; Error");
+}
+
+require_once('../wp-config.php');
+require_once('./upgrade-functions.php');
+
+if (isset($_GET['step']))
+	$step = $_GET['step'];
+else
+	$step = 0;
+header( 'Content-Type: text/html; charset=utf-8' );
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title><?php _e('WordPress &rsaquo; Installation'); ?></title>
+	<link rel="stylesheet" href="install.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+	<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+	<link rel="stylesheet" href="install-rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+	<?php endif; ?>
+</head>
+<body>
+<h1 id="logo"><img alt="WordPress" src="images/wordpress-logo.png" /></h1>
+<?php
+// Let's check to make sure WP isn't already installed.
+if ( is_blog_installed() ) die('<h1>'.__('Already Installed').'</h1><p>'.__('You appear to have already installed WordPress. To reinstall please clear your old database tables first.').'</p></body></html>');
+
+switch($step) {
+	case 0:
+?>
+<p><?php printf(__('Welcome to WordPress installation. We&#8217;re now going to go through a few steps to get you up and running with the latest in personal publishing platforms. You may want to peruse the <a href="%s">ReadMe documentation</a> at your leisure.'), '../readme.html'); ?></p>
+<h2 class="step"><a href="install.php?step=1"><?php _e('First Step &raquo;'); ?></a></h2>
+<?php
+		break;
+	case 1:
+?>
+<h1><?php _e('First Step'); ?></h1>
+<p><?php _e("Before we begin we need a little bit of information. Don't worry, you can always change these later."); ?></p>
+
+<form id="setup" method="post" action="install.php?step=2">
+	<table width="100%">
+		<tr>
+			<th width="33%"><?php _e('Weblog title:'); ?></th>
+			<td><input name="weblog_title" type="text" id="weblog_title" size="25" /></td>
+		</tr>
+		<tr>
+			<th><?php _e('Your e-mail:'); ?></th>
+			<td><input name="admin_email" type="text" id="admin_email" size="25" /></td>
+		</tr>
+		<tr>
+			<th scope="row"  valign="top"> <?php __('Privacy:'); ?></th>
+			<td><label><input type="checkbox" name="blog_public" value="1" checked="checked" /> <?php _e('I would like my blog to appear in search engines like Google and Technorati.'); ?></label></td>
+		</tr>
+	</table>
+	<p><em><?php _e('Double-check that email address before continuing.'); ?></em></p>
+	<h2 class="step"><input type="submit" name="Submit" value="<?php _e('Continue to Second Step &raquo;'); ?>" /></h2>
+</form>
+
+<?php
+		break;
+	case 2:
+		// Fill in the data we gathered
+		$weblog_title = stripslashes($_POST['weblog_title']);
+		$admin_email = stripslashes($_POST['admin_email']);
+		$public = (int) $_POST['blog_public'];
+		// check e-mail address
+		if (empty($admin_email)) {
+			die(__("<strong>ERROR</strong>: please type your e-mail address"));
+		} else if (!is_email($admin_email)) {
+			die(__("<strong>ERROR</strong>: the e-mail address isn't correct"));
+		}
+
+?>
+<h1><?php _e('Second Step'); ?></h1>
+<p><?php _e('Now we&#8217;re going to create the database tables and fill them with some default data.'); ?></p>
+
+
+<?php
+	$result = wp_install($weblog_title, 'admin', $admin_email, $public);
+	extract($result, EXTR_SKIP);
+?>
+
+<p><em><?php _e('Finished!'); ?></em></p>
+
+<p><?php printf(__('Now you can <a href="%1$s">log in</a> with the <strong>username</strong> "<code>admin</code>" and <strong>password</strong> "<code>%2$s</code>".'), '../wp-login.php', $password); ?></p>
+<p><?php _e('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you. If you lose it, you will have to delete the tables from the database yourself, and re-install WordPress. So to review:'); ?></p>
+
+<dl>
+	<dt><?php _e('Username'); ?></dt>
+		<dd><code>admin</code></dd>
+	<dt><?php _e('Password'); ?></dt>
+		<dd><code><?php echo $password; ?></code></dd>
+	<dt><?php _e('Login address'); ?></dt>
+		<dd><a href="../wp-login.php">wp-login.php</a></dd>
+</dl>
+<p><?php _e('Were you expecting more steps? Sorry to disappoint. All done! :)'); ?></p>
+
+<?php
+		break;
+}
+?>
+
+<p id="footer"><?php _e('<a href="http://wordpress.org/">WordPress</a>, personal publishing platform.'); ?></p>
+</body>
+</html>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/link-add.php 2.2.2/wp-admin/link-add.php
--- 2.0.5/wp-admin/link-add.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/link-add.php	2007-03-07 11:07:33.000000000 -0600
@@ -6,30 +6,18 @@
 $parent_file = 'link-manager.php';
 
 
-$wpvarstoreset = array('action', 'cat_id', 'linkurl', 'name', 'image',
-                       'description', 'visible', 'target', 'category', 'link_id',
-                       'submit', 'order_by', 'links_show_cat_id', 'rating', 'rel',
-                       'notes', 'linkcheck[]');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-    $wpvar = $wpvarstoreset[$i];
-    if (!isset($$wpvar)) {
-        if (empty($_POST["$wpvar"])) {
-            if (empty($_GET["$wpvar"])) {
-                $$wpvar = '';
-            } else {
-                $$wpvar = $_GET["$wpvar"];
-            }
-        } else {
-            $$wpvar = $_POST["$wpvar"];
-        }
-    }
-}
-
-$xfn_js = true;
+wp_reset_vars(array('action', 'cat_id', 'linkurl', 'name', 'image',
+	'description', 'visible', 'target', 'category', 'link_id',
+	'submit', 'order_by', 'links_show_cat_id', 'rating', 'rel',
+	'notes', 'linkcheck[]'));
+
+wp_enqueue_script( array('xfn', 'dbx-admin-key?pagenow=link.php') );
+if ( current_user_can( 'manage_categories' ) )
+	wp_enqueue_script( 'ajaxcat' );
 require('admin-header.php');
 ?>
 
-<?php if ($_GET['added']) : ?>
+<?php if ($_GET['added'] && '' != $_POST['link_name']) : ?>
 <div id="message" class="updated fade"><p><?php _e('Link added.'); ?></p></div>
 <?php endif; ?>
 
@@ -38,8 +26,10 @@
 	include('edit-link-form.php');
 ?>
 
-<div class="wrap">
-<?php printf(__('<p>You can drag <a href="%s" title="Link add bookmarklet">Link This</a> to your toolbar and when you click it a window will pop up that will allow you to add whatever site you&#8217;re on to your links! Right now this only works on Mozilla or Netscape, but we&#8217;re working on it.</p>'), "javascript:void(linkmanpopup=window.open('" . get_settings('siteurl') . "/wp-admin/link-add.php?action=popup&amp;linkurl='+escape(location.href)+'&amp;name='+escape(document.title),'LinkManager','scrollbars=yes,width=750,height=550,left=15,top=15,status=yes,resizable=yes'));linkmanpopup.focus();window.focus();linkmanpopup.focus();") ?>
+<div id="wp-link-bookmarklet"  class="wrap">
+<h3><?php _e('Add Link Bookmarklet'); ?></h3>
+<p><?php _e('Right click on the following link and choose &#0147;Bookmark This Link...&#0148; or &#0147;Add to Favorites...&#0148; to create a Link This shortcut.'); ?></p>
+<?php printf('<p><a href="%s" title="'.__('Link add bookmarklet').'">'.__('Link This').'</a></p>', "javascript:void(linkmanpopup=window.open('" . get_option('siteurl') . "/wp-admin/link-add.php?action=popup&amp;linkurl='+escape(location.href)+'&amp;name='+escape(document.title),'LinkManager','scrollbars=yes,width=750,height=550,left=15,top=15,status=yes,resizable=yes'));linkmanpopup.focus();window.focus();linkmanpopup.focus();") ?>
 </div>
 
 <?php
diff -ruN 2.0.5/wp-admin/link-categories.php 2.2.2/wp-admin/link-categories.php
--- 2.0.5/wp-admin/link-categories.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/link-categories.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,467 +0,0 @@
-<?php
-// Links
-// Copyright (C) 2002, 2003 Mike Little -- mike@zed1.com
-require_once('admin.php');
-$title = __('Link Categories');
-$this_file='link-categories.php';
-$parent_file = 'link-manager.php';
-$list_js = true;
-
-$wpvarstoreset = array('action', 'cat', 'auto_toggle');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-    $wpvar = $wpvarstoreset[$i];
-    if (!isset($$wpvar)) {
-        if (empty($_POST["$wpvar"])) {
-            if (empty($_GET["$wpvar"])) {
-                $$wpvar = '';
-            } else {
-                $$wpvar = $_GET["$wpvar"];
-            }
-        } else {
-            $$wpvar = $_POST["$wpvar"];
-        }
-    }
-}
-
-switch ($action) {
-  case 'addcat':
-  {
-      check_admin_referer('add-link-category');
-
-      if ( !current_user_can('manage_links') )
-          die (__("Cheatin' uh ?"));
-
-      $cat_name = wp_specialchars($_POST['cat_name']);
-      $auto_toggle = $_POST['auto_toggle'];
-      if ($auto_toggle != 'Y') {
-          $auto_toggle = 'N';
-      }
-
-      $show_images = $_POST['show_images'];
-      if ($show_images != 'Y') {
-          $show_images = 'N';
-      }
-
-      $show_description = $_POST['show_description'];
-      if ($show_description != 'Y') {
-          $show_description = 'N';
-      }
-
-      $show_rating = $_POST['show_rating'];
-      if ($show_rating != 'Y') {
-          $show_rating = 'N';
-      }
-
-      $show_updated = $_POST['show_updated'];
-      if ($show_updated != 'Y') {
-          $show_updated = 'N';
-      }
-
-      $sort_order = $_POST['sort_order'];
-
-      $sort_desc = $_POST['sort_desc'];
-      if ($sort_desc != 'Y') {
-          $sort_desc = 'N';
-      }
-      $text_before_link = $_POST['text_before_link'];
-      $text_after_link = $_POST['text_after_link'];
-      $text_after_all = $_POST['text_after_all'];
-
-      $list_limit = $_POST['list_limit'];
-      if ($list_limit == '')
-          $list_limit = -1;
-
-      $wpdb->query("INSERT INTO $wpdb->linkcategories (cat_id, cat_name, auto_toggle, show_images, show_description, \n" .
-             " show_rating, show_updated, sort_order, sort_desc, text_before_link, text_after_link, text_after_all, list_limit) \n" .
-             " VALUES ('0', '$cat_name', '$auto_toggle', '$show_images', '$show_description', \n" .
-             " '$show_rating', '$show_updated', '$sort_order', '$sort_desc', '$text_before_link', '$text_after_link', \n" .
-             " '$text_after_all', $list_limit)");
-
-      wp_redirect('link-categories.php');
-    break;
-  } // end addcat
-  case 'Delete':
-  {
-   	$cat_id = (int) $_GET['cat_id'];
-    check_admin_referer('delete-link-category_' . $cat_id);
-
-    $cat_name=get_linkcatname($cat_id);
-
-    if ($cat_id=="1")
-        die(sprintf(__("Can't delete the <strong>%s</strong> link category: this is the default one"), $cat_name));
-
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-    $wpdb->query("DELETE FROM $wpdb->linkcategories WHERE cat_id='$cat_id'");
-    $wpdb->query("UPDATE $wpdb->links SET link_category=1 WHERE link_category='$cat_id'");
-
-    wp_redirect('link-categories.php');
-    break;
-  } // end delete
-  case 'Edit':
-  {
-    include_once ('admin-header.php');
-    $cat_id = (int) $_GET['cat_id'];
-    $row = $wpdb->get_row("SELECT cat_id, cat_name, auto_toggle, show_images, show_description, "
-         . " show_rating, show_updated, sort_order, sort_desc, text_before_link, text_after_link, "
-         . " text_after_all, list_limit FROM $wpdb->linkcategories WHERE cat_id=$cat_id");
-    if ($row) {
-        if ($row->list_limit == -1) {
-            $row->list_limit = '';
-        }
-?>
-
-<div class="wrap">
-  <h2><?php printf(__('Edit &#8220%s&#8221; Category'), wp_specialchars($row->cat_name)); ?></h2>
-
-  <form name="editcat" method="post">
-  <?php wp_nonce_field('update-link-category_' . $row->cat_id) ?>
-      <input type="hidden" name="action" value="editedcat" />
-      <input type="hidden" name="cat_id" value="<?php echo $row->cat_id ?>" />
-<fieldset class="options">
-<legend><?php _e('Category Options') ?></legend>
-<table class="editform" width="100%" cellspacing="2" cellpadding="5">
-<tr>
-	<th width="33%" scope="row"><?php _e('Name:') ?></th>
-	<td width="67%"><input name="cat_name" type="text" value="<?php echo wp_specialchars($row->cat_name)?>" size="30" /></td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Show:') ?></th>
-        <td>
-            <label>
-            <input type="checkbox" name="show_images"  value="Y" <?php checked('Y', $row->show_images); ?> /> 
-            <?php _e('Image') ?></label> <br />
-            <label>
-            <input type="checkbox" name="show_description" value="Y" <?php checked('Y', $row->show_description); ?> /> 
-            <?php _e('Description') ?></label> 
-            <?php _e('(shown in <code>title</code> regardless)') ?><br />
-            <label>
-            <input type="checkbox" name="show_rating"  value="Y" <?php checked('Y', $row->show_rating); ?> /> 
-            <?php _e('Rating') ?></label> <br />
-            <label>
-            <input type="checkbox" name="show_updated" value="Y" <?php checked('Y', $row->show_updated); ?> /> 
-            <?php _e('Updated') ?></label>
-<?php _e('(shown in <code>title</code> regardless)') ?></td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Sort order:') ?></th>
-	<td>
-	<select name="sort_order" size="1">
-            <option value="name" <?php echo ($row->sort_order == 'name') ? 'selected="selected"' : ''?>><?php _e('Name') ?></option>
-            <option value="id"      <?php echo ($row->sort_order == 'id') ? 'selected' : ''?>><?php _e('Id') ?></option>
-            <option value="url"     <?php echo ($row->sort_order == 'url') ? 'selected' : ''?>><?php _e('URL') ?></option>
-            <option value="rating"  <?php echo ($row->sort_order == 'rating') ? 'selected' : ''?>><?php _e('Rating') ?></option>
-            <option value="updated" <?php echo ($row->sort_order == 'updated') ? 'selected' : ''?>><?php _e('Updated') ?></option>
-            <option value="rand"  <?php echo ($row->sort_order == 'rand') ? 'selected' : ''?>><?php _e('Random') ?></option>
-            <option value="length"  <?php echo ($row->sort_order == 'length') ? 'selected' : ''?>><?php _e('Name Length') ?></option>
-	</select>
-	<label>
-	<input type="checkbox" name="sort_desc" value="Y" <?php checked('Y', $row->sort_desc); ?> /> 
-	<?php _e('Descending') ?></label>
-	</td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Limit:') ?></th>
-	<td>
-	<input type="text" name="list_limit" size="5" value="<?php echo $row->list_limit ?>" /> 
-	<?php _e('(Leave empty for no limit to number of links shown)') ?>
-	</td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Toggle:') ?></th>
-	<td><label>
-		<input type="checkbox" name="auto_toggle"  value="Y" <?php checked('Y', $row->auto_toggle); ?> /> 
-		<?php _e('When new link is added toggle all others to be invisible') ?></label></td>
-</tr>
-
-</table>
-</fieldset>
-<fieldset class="options">
-<legend><?php _e('Formatting') ?></legend>
-<table class="editform" width="100%" cellspacing="2" cellpadding="5">
-<tr>
-	<th width="33%" scope="row"><?php _e('Before Link:') ?></th>
-	<td width="67%"><input type="text" name="text_before_link" size="45" value="<?php echo wp_specialchars($row->text_before_link,'double')?>" /></td>
-</tr>
-<tr>
-<th scope="row"><?php _e('Between Link and Description:') ?></th>
-<td><input type="text" name="text_after_link" size="45" value="<?php echo wp_specialchars($row->text_after_link,'double')?>" /></td>
-</tr>
-<tr>
-<th scope="row"><?php _e('After Link:') ?></th>
-<td><input type="text" name="text_after_all" size="45" value="<?php echo wp_specialchars($row->text_after_all,'double')?>"/></td>
-</tr>
-</table>
-</fieldset>
-<p class="submit"><input type="submit" name="submit" value="<?php _e('Save Category Settings &raquo;') ?>" /></p>
-</form>
-
-</div>
-<?php
-    } // end if row
-    break;
-  } // end Edit
-  case "editedcat":
-  {
-    $cat_id = (int)$_POST["cat_id"];
-    check_admin_referer('update-link-category_' . $cat_id);
-
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-    $submit=$_POST["submit"];
-    if (isset($submit)) {
-
-    $cat_name= wp_specialchars($_POST["cat_name"]);
-    $auto_toggle = $_POST["auto_toggle"];
-    if ($auto_toggle != 'Y') {
-        $auto_toggle = 'N';
-    }
-
-    $show_images = $_POST["show_images"];
-    if ($show_images != 'Y') {
-        $show_images = 'N';
-    }
-
-    $show_description = $_POST["show_description"];
-    if ($show_description != 'Y') {
-        $show_description = 'N';
-    }
-
-    $show_rating = $_POST["show_rating"];
-    if ($show_rating != 'Y') {
-        $show_rating = 'N';
-    }
-
-    $show_updated = $_POST["show_updated"];
-    if ($show_updated != 'Y') {
-        $show_updated = 'N';
-    }
-
-    $sort_order = $_POST["sort_order"];
-
-    $sort_desc = $_POST["sort_desc"];
-    if ($sort_desc != 'Y') {
-        $sort_desc = 'N';
-    }
-    $text_before_link = $_POST["text_before_link"];
-    $text_after_link = $_POST["text_after_link"];
-    $text_after_all = $_POST["text_after_all"];
-
-    $list_limit = $_POST["list_limit"];
-    if ($list_limit == '')
-        $list_limit = -1;
-
-    $wpdb->query("UPDATE $wpdb->linkcategories set
-            cat_name='$cat_name',
-            auto_toggle='$auto_toggle',
-            show_images='$show_images',
-            show_description='$show_description',
-            show_rating='$show_rating',
-            show_updated='$show_updated',
-            sort_order='$sort_order',
-            sort_desc='$sort_desc',
-            text_before_link='$text_before_link',
-            text_after_link='$text_after_link',
-            text_after_all='$text_after_all',
-            list_limit=$list_limit
-            WHERE cat_id=$cat_id
-            ");
-    } // end if save
-
-
-    wp_redirect("link-categories.php");
-    break;
-  } // end editcat
-  default:
-  {
-    include_once ("admin-header.php");
-    if ( !current_user_can('manage_links') )
-      die(__("You have do not have sufficient permissions to edit the link categories for this blog. :)"));
-?>
-
-<div class="wrap">
-            <h2><?php _e('Link Categories:') ?></h2>
-            <table id="the-list" width="100%" cellpadding="5" cellspacing="0" border="0">
-              <tr>
- 	        <th rowspan="2" valign="bottom"><?php _e('Name') ?></th>
-                <th rowspan="2" valign="bottom"><?php _e('ID') ?></th>
-                <th rowspan="2" valign="bottom"><?php _e('Toggle?') ?></th>
-                <th colspan="4" valign="bottom" class="alternate"><?php _e('Show') ?></th>
-                <th rowspan="2" valign="bottom"><?php _e('Sort Order') ?></th>
-                <th rowspan="2" valign="bottom"><?php _e('Desc?') ?></th>
-                <th colspan="3" valign="bottom" class="alternate"><?php _e('Formatting') ?></th>
-                <th rowspan="2" valign="bottom"><?php _e('Limit') ?></th>
-                <th rowspan="2" colspan="2">&nbsp;</th>
-              </tr>
-              <tr>
-                <th valign="top"><?php _e('Images') ?></th>
-                <th valign="top"><?php _e('Description') ?></th>
-                <th valign="top"><?php _e('Rating') ?></th>
-                <th valign="top"><?php _e('Updated') ?></th>
-                <th valign="top"><?php _e('Before') ?></th>
-                <th valign="top"><?php _e('Between') ?></th>
-                <th valign="top"><?php _e('After') ?></th>
-              </tr>
-<?php
-$results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle, show_images, show_description, "
-         . " show_rating, show_updated, sort_order, sort_desc, text_before_link, text_after_link, "
-         . " text_after_all, list_limit FROM $wpdb->linkcategories ORDER BY cat_id");
-$i = 1;
-foreach ( (array) $results as $row) {
-    if ($row->list_limit == -1) {
-        $row->list_limit = __('none');
-    }
-    $style = ($i % 2) ? ' class="alternate"' : '';
-    /*
-    	Manually internationalize every sort order option.
-    */
-    switch ($row->sort_order) {
-    	case 'name':
-    		$row->sort_order = __('name');
-    		break;
-    	case 'id':
-    		$row->sort_order = __('id');
-    		break;
-    	case 'url':
-    		$row->sort_order = __('url');
-    		break;
-    	case 'rating':
-    		$row->sort_order = __('rating');
-    		break;
-    	case 'updated':
-    		$row->sort_order = __('updated');
-    		break;
-    	case 'rand':
-    		$row->sort_order = __('rand');
-    		break;
-    	case 'length':
-    		$row->sort_order = __('length');
-    		break;
-    }
-?>
-              <tr id="link-category-<?php echo $row->cat_id; ?>" valign="middle" align="center" <?php echo $style ?> style="border-bottom: 1px dotted #9C9A9C;">
-                <td><?php echo wp_specialchars($row->cat_name)?></td>
-				<td ><?php echo $row->cat_id?></td>
-                <td><?php echo $row->auto_toggle == 'Y' ? __('Yes') : __('No') ?></td>
-                <td><?php echo $row->show_images == 'Y' ? __('Yes') : __('No') ?></td>
-                <td><?php echo $row->show_description == 'Y' ? __('Yes') : __('No') ?></td>
-                <td><?php echo $row->show_rating == 'Y' ? __('Yes') : __('No') ?></td>
-                <td><?php echo $row->show_updated == 'Y' ? __('Yes') : __('No') ?></td>
-                <td><?php echo $row->sort_order ?></td>
-                <td><?php echo $row->sort_desc == 'Y' ? __('Yes') : __('No') ?></td>
-                <td nowrap="nowrap"><?php echo wp_specialchars($row->text_before_link)?>&nbsp;</td>
-                <td nowrap="nowrap"><?php echo wp_specialchars($row->text_after_link)?>&nbsp;</td>
-                <td nowrap="nowrap"><?php echo wp_specialchars($row->text_after_all)?></td>
-                <td><?php echo $row->list_limit ?></td>
-                <td><a href="link-categories.php?cat_id=<?php echo $row->cat_id?>&amp;action=Edit" class="edit"><?php _e('Edit') ?></a></td>
-                <td>
-				<?php if (1 == $row->cat_id ) { 
-					_e('Default');
-				} else { ?>
-					<a href="<?php echo wp_nonce_url("link-categories.php?cat_id=$row->cat_id?>&amp;action=Delete", 'delete-link-category_' . $row->cat_id) ?>" onclick="return deleteSomething( 'link category', <?php echo $row->cat_id . ", '" . sprintf(__("You are about to delete the &quot;%s&quot; link category.\\n&quot;Cancel&quot; to stop, &quot;OK&quot; to delete."), js_escape($row->cat_name)); ?>' );" class="delete"><?php _e('Delete') ?></a></td>
-				<?php } ?>
-              </tr>
-<?php
-        ++$i;
-    }
-?>
-            </table>
-<p><?php _e('These are the defaults for when you call a link category with no additional arguments. All of these settings may be overwritten.') ?></p>
-
-<div id="ajax-response"></div>
-
-</div>
-
-<div class="wrap">
-    <form name="addcat" method="post" action="">
-    <?php wp_nonce_field('add-link-category'); ?>
-      <input type="hidden" name="action" value="addcat" />
-	  <h2><?php _e('Add a Link Category:') ?></h2>
-<fieldset class="options">
-<legend><?php _e('Category Options') ?></legend>
-<table class="editform" width="100%" cellspacing="2" cellpadding="5">
-<tr>
-	<th width="33%" scope="row"><?php _e('Name:') ?></th>
-	<td width="67%"><input type="text" name="cat_name" size="30" /></td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Show:') ?></th>
-        <td>
-            <label>
-            <input type="checkbox" name="show_images"  value="Y" /> 
-            <?php _e('Image') ?></label> <br />
-            <label>
-            <input type="checkbox" name="show_description" value="Y" /> 
-            <?php _e('Description') ?></label> 
-            <?php _e('(shown in <code>title</code> regardless)') ?><br />
-            <label>
-            <input type="checkbox" name="show_rating"  value="Y" /> 
-            <?php _e('Rating') ?></label> <br />
-            <label>
-            <input type="checkbox" name="show_updated" value="Y" /> 
-            <?php _e('Updated') ?></label>
-<?php _e('(shown in <code>title</code> regardless)') ?></td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Sort order:') ?></th>
-	<td>
-	<select name="sort_order" size="1">
-	<option value="name"><?php _e('Name') ?></option>
-	<option value="id"><?php _e('Id') ?></option>
-	<option value="url"><?php _e('URL') ?></option>
-	<option value="rating"><?php _e('Rating') ?></option>
-	<option value="updated"><?php _e('Updated') ?></option>
-	<option value="rand"><?php _e('Random') ?></option>
-	</select>
-	<label>
-	<input type="checkbox" name="sort_desc" value="Y" /> 
-	<?php _e('Descending') ?></label>
-	</td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Limit:') ?></th>
-	<td>
-	<input type="text" name="list_limit" size="5" value="" /> <?php _e('(Leave empty for no limit to number of links shown)') ?>
-	</td>
-</tr>
-<tr>
-	<th scope="row"><?php _e('Toggle:') ?></th>
-	<td><label>
-		<input type="checkbox" name="auto_toggle"  value="Y" /> 
-		<?php _e('When new link is added toggle all others to be invisible') ?></label></td>
-</tr>
-
-</table>
-</fieldset>
-<fieldset class="options">
-<legend><?php _e('Formatting') ?></legend>
-<table class="editform" width="100%" cellspacing="2" cellpadding="5">
-<tr>
-	<th width="33%" scope="row"><?php _e('Before Link:') ?></th>
-	<td width="67%"><input type="text" name="text_before_link" size="45" value="&lt;li&gt;" /></td>
-</tr>
-<tr>
-<th scope="row"><?php _e('Between Link and Description:') ?></th>
-<td><input type="text" name="text_after_link" size="45" value="&lt;br /&gt;" /></td>
-</tr>
-<tr>
-<th scope="row"><?php _e('After Link:') ?></th>
-<td><input type="text" name="text_after_all" size="45" value="&lt;/li&gt;"/></td>
-</tr>
-</table>
-</fieldset>
-<p class="submit"><input type="submit" name="submit" value="<?php _e('Add Category &raquo;') ?>" /></p>
-  </form>
-</div>
-<div class="wrap">
-    <h3><?php _e('Note:') ?></h3>
-	<p><?php printf(__('Deleting a link category does not delete links from that category.<br />It will just set them back to the default category <strong>%s</strong>.'), get_linkcatname(1)) ?></p>
-</div>
-<?php
-    break;
-  } // end default
-} // end case
-?>
-<?php include('admin-footer.php'); ?>
diff -ruN 2.0.5/wp-admin/link-import.php 2.2.2/wp-admin/link-import.php
--- 2.0.5/wp-admin/link-import.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/link-import.php	2007-08-02 10:10:25.000000000 -0500
@@ -12,21 +12,21 @@
 ?>
 <?php
 switch ($step) {
-    case 0:
-    {
-        include_once('admin-header.php');
-        if ( !current_user_can('manage_links') )
-            die (__("Cheatin&#8217; uh?"));
+	case 0: {
+		include_once('admin-header.php');
+		if ( !current_user_can('manage_links') )
+			wp_die(__('Cheatin&#8217; uh?'));
 
-        $opmltype = 'blogrolling'; // default.
+		$opmltype = 'blogrolling'; // default.
 ?>
 
 <div class="wrap">
+
 <h2><?php _e('Import your blogroll from another system') ?> </h2>
 <form enctype="multipart/form-data" action="link-import.php" method="post" name="blogroll">
 <?php wp_nonce_field('import-bookmarks') ?>
 
-<p><?php _e('If a program or website you use allows you to export your links or subscriptions as OPML you may import them here.'); ?>
+<p><?php _e('If a program or website you use allows you to export your links or subscriptions as OPML you may import them here.'); ?></p>
 <div style="width: 70%; margin: auto; height: 8em;">
 <input type="hidden" name="step" value="1" />
 <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
@@ -40,96 +40,98 @@
 <input id="userfile" name="userfile" type="file" size="30" />
 </div>
 
-
 </div>
 
 <p style="clear: both; margin-top: 1em;"><?php _e('Now select a category you want to put these links in.') ?><br />
 <?php _e('Category:') ?> <select name="cat_id">
 <?php
-$categories = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
+$categories = get_categories('hide_empty=0');
 foreach ($categories as $category) {
 ?>
-<option value="<?php echo $category->cat_id; ?>"><?php echo $category->cat_id.': '.$category->cat_name; ?></option>
+<option value="<?php echo $category->cat_ID; ?>"><?php echo wp_specialchars(apply_filters('link_category', $category->cat_name)); ?></option>
 <?php
 } // end foreach
 ?>
 </select></p>
 
-<p class="submit"><input type="submit" name="submit" value="<?php _e('Import OPML File') ?> &raquo;" /></p>
+<p class="submit"><input type="submit" name="submit" value="<?php _e('Import OPML File &raquo;') ?>" /></p>
 </form>
 
 </div>
 <?php
-                break;
-            } // end case 0
+		break;
+	} // end case 0
 
-    case 1: {
+	case 1: {
 		check_admin_referer('import-bookmarks');
 
-                include_once('admin-header.php');
-                if ( !current_user_can('manage_links') )
-                    die (__("Cheatin' uh ?"));
+		include_once('admin-header.php');
+		if ( !current_user_can('manage_links') )
+			wp_die(__('Cheatin&#8217; uh?'));
 ?>
 <div class="wrap">
 
-     <h2><?php _e('Importing...') ?></h2>
+<h2><?php _e('Importing...') ?></h2>
 <?php
-                $cat_id = $_POST['cat_id'];
-                if (($cat_id == '') || ($cat_id == 0)) {
-                    $cat_id  = 1;
-                }
-
-                $opml_url = $_POST['opml_url'];
-                if (isset($opml_url) && $opml_url != '' && $opml_url != 'http://') {
-					$blogrolling = true;
-                }
-                else // try to get the upload file.
-				{
-					$overrides = array('test_form' => false, 'test_type' => false);
-					$file = wp_handle_upload($_FILES['userfile'], $overrides);
-
-					if ( isset($file['error']) )
-						die($file['error']);
-
-					$url = $file['url'];
-					$opml_url = $file['file'];
-					$blogrolling = false;
-				}
-
-                if (isset($opml_url) && $opml_url != '') {
-                    $opml = wp_remote_fopen($opml_url);
-                    include_once('link-parse-opml.php');
-
-                    $link_count = count($names);
-                    for ($i = 0; $i < $link_count; $i++) {
-                        if ('Last' == substr($titles[$i], 0, 4))
-                            $titles[$i] = '';
-                        if ('http' == substr($titles[$i], 0, 4))
-                            $titles[$i] = '';
-                        // FIXME:  Use wp_insert_link().
-                        $query = "INSERT INTO $wpdb->links (link_url, link_name, link_target, link_category, link_description, link_owner, link_rss)
-                                VALUES('{$urls[$i]}', '".$wpdb->escape($names[$i])."', '', $cat_id, '".$wpdb->escape($descriptions[$i])."', $user_ID, '{$feeds[$i]}')\n";
-                        $result = $wpdb->query($query);
-						echo sprintf('<p>'.__('Inserted <strong>%s</strong>').'</p>', $names[$i]);
-                    }
-?>
-     <p><?php printf(__('Inserted %1$d links into category %2$s. All done! Go <a href="%3$s">manage those links</a>.'), $link_count, $cat_id, 'link-manager.php') ?></p>
-<?php
-                } // end if got url
-                else
-                {
-                    echo "<p>" . __("You need to supply your OPML url. Press back on your browser and try again") . "</p>\n";
-                } // end else
-
-				if ( ! $blogrolling )
-					@unlink($opml_url);
+		$cat_id = abs( (int) $_POST['cat_id'] );
+		if ( $cat_id < 1 )
+			$cat_id  = 1;
+
+		$opml_url = $_POST['opml_url'];
+		if ( isset($opml_url) && $opml_url != '' && $opml_url != 'http://' ) {
+			$blogrolling = true;
+		} else { // try to get the upload file.
+			$overrides = array('test_form' => false, 'test_type' => false);
+			$file = wp_handle_upload($_FILES['userfile'], $overrides);
+
+			if ( isset($file['error']) )
+				wp_die($file['error']);
+
+			$url = $file['url'];
+			$opml_url = $file['file'];
+			$blogrolling = false;
+		}
+
+		if ( isset($opml_url) && $opml_url != '' ) {
+			if ( $blogrolling === true ) {
+				$opml = wp_remote_fopen($opml_url);
+			} else {
+				$opml = file_get_contents($opml_url);
+			}
+			
+			include_once('link-parse-opml.php');
+
+			$link_count = count($names);
+			for ( $i = 0; $i < $link_count; $i++ ) {
+				if ('Last' == substr($titles[$i], 0, 4))
+					$titles[$i] = '';
+				if ( 'http' == substr($titles[$i], 0, 4) )
+					$titles[$i] = '';
+				$link = array( 'link_url' => $urls[$i], 'link_name' => $wpdb->escape($names[$i]), 'link_category' => array($cat_id), 'link_description' => $wpdb->escape($descriptions[$i]), 'link_owner' => $user_ID, 'link_rss' => $feeds[$i]);
+				wp_insert_link($link);
+				echo sprintf('<p>'.__('Inserted <strong>%s</strong>').'</p>', $names[$i]);
+			}
+?>
+
+<p><?php printf(__('Inserted %1$d links into category %2$s. All done! Go <a href="%3$s">manage those links</a>.'), $link_count, $cat_id, 'link-manager.php') ?></p>
+
+<?php
+} // end if got url
+else
+{
+	echo "<p>" . __("You need to supply your OPML url. Press back on your browser and try again") . "</p>\n";
+} // end else
+
+if ( ! $blogrolling )
+	apply_filters( 'wp_delete_file', $opml_url); 
+	@unlink($opml_url);
 ?>
 </div>
 <?php
-                break;
-            } // end case 1
+		break;
+	} // end case 1
 } // end switch
 
 include('admin-footer.php');
 
-?>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/link-manager.php 2.2.2/wp-admin/link-manager.php
--- 2.0.5/wp-admin/link-manager.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/link-manager.php	2007-05-10 16:07:51.000000000 -0500
@@ -1,251 +1,49 @@
 <?php
+
+
 // Links
 // Copyright (C) 2002, 2003 Mike Little -- mike@zed1.com
 
-require_once('admin.php');
+require_once ('admin.php');
 
-$title = __('Manage Links');
-$this_file = $parent_file = 'link-manager.php';
-$list_js = true;
+wp_enqueue_script( 'listman' );
 
-$wpvarstoreset = array('action','cat_id', 'linkurl', 'name', 'image',
-                       'description', 'visible', 'target', 'category', 'link_id',
-                       'submit', 'order_by', 'links_show_cat_id', 'rating', 'rel',
-                       'notes', 'linkcheck[]');
-
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-    $wpvar = $wpvarstoreset[$i];
-    if (!isset($$wpvar)) {
-        if (empty($_POST["$wpvar"])) {
-            if (empty($_GET["$wpvar"])) {
-                $$wpvar = '';
-            } else {
-                $$wpvar = $_GET["$wpvar"];
-            }
-        } else {
-            $$wpvar = $_POST["$wpvar"];
-        }
-    }
-}
+wp_reset_vars(array('action', 'cat_id', 'linkurl', 'name', 'image', 'description', 'visible', 'target', 'category', 'link_id', 'submit', 'order_by', 'links_show_cat_id', 'rating', 'rel', 'notes', 'linkcheck[]'));
 
-$links_show_cat_id = $_COOKIE['links_show_cat_id_' . COOKIEHASH];
-$links_show_order = $_COOKIE['links_show_order_' . COOKIEHASH];
+if (empty ($cat_id))
+	$cat_id = 'all';
 
-if ('' != $_POST['assign']) $action = 'assign';
-if ('' != $_POST['visibility']) $action = 'visibility';
-if ('' != $_POST['move']) $action = 'move';
-if ('' != $_POST['linkcheck']) $linkcheck = $_POST[linkcheck];
-
-switch ($action) {
-  case 'assign':
-  {
-	check_admin_referer('bulk-bookmarks');
-
-    // check the current user's level first.
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-    //for each link id (in $linkcheck[]): if the current user level >= the
-    //userlevel of the owner of the link then we can proceed.
-
-    if (count($linkcheck) == 0) {
-        wp_redirect($this_file);
-        exit;
-    }
-    $all_links = join(',', $linkcheck);
-    $results = $wpdb->get_results("SELECT link_id, link_owner FROM $wpdb->links LEFT JOIN $wpdb->users ON link_owner = ID WHERE link_id in ($all_links)");
-    foreach ($results as $row) {
-       $ids_to_change[] = $row->link_id;
-    }
-
-    // should now have an array of links we can change
-    $all_links = join(',', $ids_to_change);
-    $q = $wpdb->query("update $wpdb->links SET link_owner='$newowner' WHERE link_id IN ($all_links)");
-
-    wp_redirect($this_file);
-    break;
-  }
-  case 'visibility':
-  {
-  	check_admin_referer('bulk-bookmarks');
-
-    // check the current user's level first.
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-    //for each link id (in $linkcheck[]): toggle the visibility
-    if (count($linkcheck) == 0) {
-        wp_redirect($this_file);
-        exit;
-    }
-    $all_links = join(',', $linkcheck);
-    $results = $wpdb->get_results("SELECT link_id, link_visible FROM $wpdb->links WHERE link_id in ($all_links)");
-    foreach ($results as $row) {
-        if ($row->link_visible == 'Y') { // ok to proceed
-            $ids_to_turnoff[] = $row->link_id;
-        } else {
-            $ids_to_turnon[] = $row->link_id;
-        }
-    }
-
-    // should now have two arrays of links to change
-    if (count($ids_to_turnoff)) {
-        $all_linksoff = join(',', $ids_to_turnoff);
-        $q = $wpdb->query("update $wpdb->links SET link_visible='N' WHERE link_id IN ($all_linksoff)");
-    }
-
-    if (count($ids_to_turnon)) {
-        $all_linkson = join(',', $ids_to_turnon);
-        $q = $wpdb->query("update $wpdb->links SET link_visible='Y' WHERE link_id IN ($all_linkson)");
-    }
-
-    wp_redirect($this_file);
-    break;
-  }
-  case 'move':
-  {
-	check_admin_referer('bulk-bookmarks');
-
-    // check the current user's level first.
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-    //for each link id (in $linkcheck[]) change category to selected value
-    if (count($linkcheck) == 0) {
-        wp_redirect($this_file);
-        exit;
-    }
-    $all_links = join(',', $linkcheck);
-    // should now have an array of links we can change
-    $q = $wpdb->query("update $wpdb->links SET link_category='$category' WHERE link_id IN ($all_links)");
-
-    wp_redirect($this_file);
-    break;
-  }
-
-  case 'Add':
-  {
-  	check_admin_referer('add-bookmark');
-
-	add_link();
-	
-    wp_redirect(wp_get_referer() . '?added=true');
-    break;
-  } // end Add
-
-  case 'editlink':
-  {
-	$link_id = (int) $_POST['link_id'];
-	check_admin_referer('update-bookmark_' . $link_id);
- 	
-	if (isset($links_show_cat_id) && ($links_show_cat_id != ''))
-		$cat_id = $links_show_cat_id;
-
-	if (!isset($cat_id) || ($cat_id == '')) {
-		if (!isset($links_show_cat_id) || ($links_show_cat_id == ''))
-			$cat_id = 'All';
-	}
-	$links_show_cat_id = $cat_id;
+if (empty ($order_by))
+	$order_by = 'order_name';
+
+$title = __('Manage Blogroll');
+$this_file = $parent_file = 'link-manager.php';
+include_once ("./admin-header.php");
 
-	edit_link($link_id);
-	
-    setcookie('links_show_cat_id_' . COOKIEHASH, $links_show_cat_id, time()+600);
-    wp_redirect($this_file);
-    break;
-  } // end Save
-
-  case 'delete':
-  {
-	$link_id = (int) $_GET['link_id'];
-	check_admin_referer('delete-bookmark_' . $link_id);
-
-    if ( !current_user_can('manage_links') )
-      die (__("Cheatin' uh ?"));
-
-	wp_delete_link($link_id);
-	
-    if (isset($links_show_cat_id) && ($links_show_cat_id != ''))
-        $cat_id = $links_show_cat_id;
-
-    if (!isset($cat_id) || ($cat_id == '')) {
-        if (!isset($links_show_cat_id) || ($links_show_cat_id == ''))
-        $cat_id = 'All';
-    }
-    $links_show_cat_id = $cat_id;
-    setcookie('links_show_cat_id_' . COOKIEHASH, $links_show_cat_id, time()+600);
-    wp_redirect($this_file);
-    break;
-  } // end Delete
-
-  case 'linkedit': {
-	$xfn_js = true;
-	include_once ('admin-header.php');
-	if ( !current_user_can('manage_links') )
-		die(__('You do not have sufficient permissions to edit the links for this blog.'));
-	
-	$link_id = (int) $_GET['link_id'];
-	
-	if ( !$link = get_link_to_edit($link_id) )
-		die( __('Link not found.') );
-	
-	include('edit-link-form.php');
-	break;
-  } // end linkedit
-  case __("Show"):
-  {
-    if (!isset($cat_id) || ($cat_id == '')) {
-        if (!isset($links_show_cat_id) || ($links_show_cat_id == ''))
-        $cat_id = 'All';
-    }
-    $links_show_cat_id = $cat_id;
-    if (!isset($order_by) || ($order_by == '')) {
-        if (!isset($links_show_order) || ($links_show_order == ''))
-        $order_by = 'order_name';
-    }
-    $links_show_order = $order_by;
-    //break; fall through
-  } // end Show
-  case "popup":
-  {
-    $link_url = stripslashes($_GET["linkurl"]);
-    $link_name = stripslashes($_GET["name"]);
-    //break; fall through
-  }
-  default:
-  {
-    if (isset($links_show_cat_id) && ($links_show_cat_id != ''))
-        $cat_id = $links_show_cat_id;
-
-    if (!isset($cat_id) || ($cat_id == '')) {
-        if (!isset($links_show_cat_id) || ($links_show_cat_id == ''))
-        $cat_id = 'All';
-    }
-    $links_show_cat_id = $cat_id;
-    if (isset($links_show_order) && ($links_show_order != ''))
-        $order_by = $links_show_order;
-
-    if (!isset($order_by) || ($order_by == ''))
-        $order_by = 'order_name';
-    $links_show_order = $order_by;
-
-    setcookie('links_show_cat_id_' . COOKIEHASH, $links_show_cat_id, time()+600);
-    setcookie('links_show_order_' . COOKIEHASH, $links_show_order, time()+600);
-    include_once ("./admin-header.php");
-    if ( !current_user_can('manage_links') )
-      die(__("You do not have sufficient permissions to edit the links for this blog."));
-
-    switch ($order_by)
-    {
-        case 'order_id':     $sqlorderby = 'id';          break;
-        case 'order_url':    $sqlorderby = 'url';         break;
-        case 'order_desc':   $sqlorderby = 'description'; break;
-        case 'order_owner':  $sqlorderby = 'owner';       break;
-        case 'order_rating': $sqlorderby = 'rating';      break;
-        case 'order_name':
-        default:             $sqlorderby = 'name';        break;
-    }
+if (!current_user_can('manage_links'))
+	wp_die(__("You do not have sufficient permissions to edit the links for this blog."));
 
-  if ($action != "popup") {
+switch ($order_by) {
+	case 'order_id' :
+		$sqlorderby = 'id';
+		break;
+	case 'order_url' :
+		$sqlorderby = 'url';
+		break;
+	case 'order_desc' :
+		$sqlorderby = 'description';
+		break;
+	case 'order_owner' :
+		$sqlorderby = 'owner';
+		break;
+	case 'order_rating' :
+		$sqlorderby = 'rating';
+		break;
+	case 'order_name' :
+	default :
+		$sqlorderby = 'name';
+		break;
+}
 ?>
 <script type="text/javascript">
 <!--
@@ -263,183 +61,145 @@
 //-->
 </script>
 
-<div class="wrap">
-    <form name="cats" method="post" action="">
-    <table width="75%" cellpadding="3" cellspacing="3">
-      <tr>
-        <td>
-        <?php _e('<strong>Show</strong> links in category:'); ?><br />
-        </td>
-        <td>
-          <?php _e('<strong>Order</strong> by:');?>
-        </td>
-		<td>&nbsp;</td>
-      </tr>
-      <tr>
-        <td>
 <?php
-    $results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
-    echo "        <select name=\"cat_id\">\n";
-    echo "          <option value=\"All\"";
-    if ($cat_id == 'All')
-      echo " selected='selected'";
-    echo "> " . __('All') . "</option>\n";
-    foreach ($results as $row) {
-      echo "          <option value=\"".$row->cat_id."\"";
-      if ($row->cat_id == $cat_id)
-        echo " selected='selected'";
-        echo ">".$row->cat_id.": ".wp_specialchars($row->cat_name);
-        if ($row->auto_toggle == 'Y')
-            echo ' '.__('(auto toggle)');
-        echo "</option>\n";
-    }
-    echo "        </select>\n";
+if ( isset($_GET['deleted']) ) {
+	echo '<div style="background-color: rgb(207, 235, 247);" id="message" class="updated fade"><p>';
+	$deleted = (int) $_GET['deleted'];
+	printf(__ngettext('%s link deleted.', '%s links deleted', $deleted), $deleted);
+	echo '</p></div>';
+}
 ?>
-        </td>
-        <td>
-          <select name="order_by">
-            <option value="order_id"     <?php if ($order_by == 'order_id')     echo " selected='selected'";?>><?php _e('Link ID') ?></option>
-            <option value="order_name"   <?php if ($order_by == 'order_name')   echo " selected='selected'";?>><?php _e('Name') ?></option>
-            <option value="order_url"    <?php if ($order_by == 'order_url')    echo " selected='selected'";?>><?php _e('URI') ?></option>
-            <option value="order_desc"   <?php if ($order_by == 'order_desc')   echo " selected='selected'";?>><?php _e('Description') ?></option>
-            <option value="order_owner"  <?php if ($order_by == 'order_owner')  echo " selected='selected'";?>><?php _e('Owner') ?></option>
-            <option value="order_rating" <?php if ($order_by == 'order_rating') echo " selected='selected'";?>><?php _e('Rating') ?></option>
-          </select>
-        </td>
-        <td>
-          <input type="submit" name="action" value="<?php _e('Show') ?>" />
-        </td>
-      </tr>
-    </table>
-    </form>
-
-</div>
 
-<form name="links" id="links" method="post" action="">
 <div class="wrap">
 
-    <?php wp_nonce_field('bulk-bookmarks') ?>
-    <input type="hidden" name="link_id" value="" />
-    <input type="hidden" name="action" value="" />
-    <input type="hidden" name="order_by" value="<?php echo wp_specialchars($order_by, 1); ?>" />
-    <input type="hidden" name="cat_id" value="<?php echo (int) $cat_id ?>" />
-  <table id="the-list-x" width="100%" cellpadding="3" cellspacing="3">
-    <tr>
-      <th width="15%"><?php _e('Name') ?></th>
-      <th><?php _e('URI') ?></th>
-      <th><?php _e('Category') ?></th>
-      <th><?php _e('rel') ?></th>
-      <th><?php _e('Image') ?></th>
-      <th><?php _e('Visible') ?></th>
-      <th colspan="2"><?php _e('Action') ?></th>
-      <th>&nbsp;</th>
-  </tr>
-<?php
-    $sql = "SELECT link_url, link_name, link_image, link_description, link_visible,
-            link_category AS cat_id, cat_name AS category, $wpdb->users.user_login, link_id,
-            link_rating, link_rel
-            FROM $wpdb->links
-            LEFT JOIN $wpdb->linkcategories ON $wpdb->links.link_category = $wpdb->linkcategories.cat_id
-            LEFT JOIN $wpdb->users ON $wpdb->users.ID = $wpdb->links.link_owner ";
-
-    if (isset($cat_id) && ($cat_id != 'All')) {
-      $sql .= " WHERE link_category = $cat_id ";
-    }
-    $sql .= ' ORDER BY link_' . $sqlorderby;
-
-    // echo "$sql";
-    $links = $wpdb->get_results($sql);
-    if ($links) {
-        foreach ($links as $link) {
-      	    $link->link_name = wp_specialchars($link->link_name);
-      	    $link->link_category = wp_specialchars($link->link_category);
-      	    $link->link_description = wp_specialchars($link->link_description);
-            $link->link_url = wp_specialchars($link->link_url);
-            $short_url = str_replace('http://', '', $link->link_url);
-            $short_url = str_replace('www.', '', $short_url);
-            if ('/' == substr($short_url, -1))
-                $short_url = substr($short_url, 0, -1);
-            if (strlen($short_url) > 35)
-                $short_url =  substr($short_url, 0, 32).'...';
-
-            $image = ($link->link_image != null) ? __('Yes') : __('No');
-            $visible = ($link->link_visible == 'Y') ? __('Yes') : __('No');
-            ++$i;
-            $style = ($i % 2) ? '' : ' class="alternate"';
+<h2><?php _e('Blogroll Management'); ?></h2>
+<p><?php _e('Here you <a href="link-add.php">add links</a> to sites that you visit often and share them on your blog. When you have a list of links in your sidebar to other blogs, it&#8217;s called a &#8220;blogroll.&#8221;'); ?></p>
+<form id="cats" method="get" action="">
+<p><?php
+$categories = get_categories("hide_empty=1&type=link");
+$select_cat = "<select name=\"cat_id\">\n";
+$select_cat .= '<option value="all"'  . (($cat_id == 'all') ? " selected='selected'" : '') . '>' . __('All') . "</option>\n";
+foreach ((array) $categories as $cat)
+	$select_cat .= '<option value="' . $cat->cat_ID . '"' . (($cat->cat_ID == $cat_id) ? " selected='selected'" : '') . '>' . wp_specialchars(apply_filters('link_category', $cat->cat_name)) . "</option>\n";
+$select_cat .= "</select>\n";
+
+$select_order = "<select name=\"order_by\">\n";
+$select_order .= '<option value="order_id"' . (($order_by == 'order_id') ? " selected='selected'" : '') . '>' .  __('Link ID') . "</option>\n";
+$select_order .= '<option value="order_name"' . (($order_by == 'order_name') ? " selected='selected'" : '') . '>' .  __('Name') . "</option>\n";
+$select_order .= '<option value="order_url"' . (($order_by == 'order_url') ? " selected='selected'" : '') . '>' .  __('Address') . "</option>\n";
+$select_order .= '<option value="order_rating"' . (($order_by == 'order_rating') ? " selected='selected'" : '') . '>' .  __('Rating') . "</option>\n";
+$select_order .= "</select>\n";
+
+printf(__('Currently showing %1$s links ordered by %2$s'), $select_cat, $select_order);
 ?>
-    <tr id="link-<?php echo $link->link_id; ?>" valign="middle" <?php echo $style; ?>>
-		<td><strong><?php echo $link->link_name; ?></strong><br />
-<?php			
-        echo sprintf(__('Description: %s'), $link->link_description) . "</td>";
-        echo "<td><a href=\"$link->link_url\" title=\"" . sprintf(__('Visit %s'), $link->link_name) . "\">$short_url</a></td>";
-        echo <<<LINKS
-        <td>$link->category</td>
-        <td>$link->link_rel</td>
-        <td align='center'>$image</td>
-        <td align='center'>$visible</td>
-LINKS;
-            $show_buttons = 1; // default
-
-            if ($show_buttons) {
-        echo '<td><a href="link-manager.php?link_id=' . $link->link_id . '&amp;action=linkedit" class="edit">' . __('Edit') . '</a></td>';
- 		echo '<td><a href="' . wp_nonce_url('link-manager.php?link_id='.$link->link_id.'&amp;action=delete', 'delete-bookmark_' . $link->link_id ) . '"'." class='delete' onclick=\"return deleteSomething( 'link', $link->link_id , '".sprintf(__("You are about to delete the &quot;%s&quot; bookmark to %s.\\n&quot;Cancel&quot; to stop, &quot;OK&quot; to delete."), js_escape($link->link_name), js_escape($link->link_url)).'\' );">'.__('Delete').'</a></td>';
-        echo '<td><input type="checkbox" name="linkcheck[]" value="' . $link->link_id . '" /></td>';
-            } else {
-              echo "<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>\n";
-            }
+<input type="submit" name="action" value="<?php _e('Update &raquo;') ?>" /></p>
+</form>
+<?php
+$link_columns = array(
+	'name'       => '<th width="15%">' . __('Name') . '</th>',
+	'url'       => '<th>' . __('URL') . '</th>',
+	'categories' => '<th>' . __('Categories') . '</th>',
+	'rel'      => '<th style="text-align: center">' . __('rel') . '</th>',
+	'visible'   => '<th style="text-align: center">' . __('Visible') . '</th>',
+	'action'   => '<th colspan="2" style="text-align: center">' . __('Action') . '</th>',
+);
+$link_columns = apply_filters('manage_link_columns', $link_columns);
+?>
+
+<?php
+if ( 'all' == $cat_id )
+	$cat_id = '';
+$links = get_bookmarks( "category=$cat_id&hide_invisible=0&orderby=$sqlorderby&hide_empty=0" );
+if ( $links ) {
+?>
+
+<form id="links" method="post" action="link.php">
+<?php wp_nonce_field('bulk-bookmarks') ?>
+<input type="hidden" name="link_id" value="" />
+<input type="hidden" name="action" value="" />
+<input type="hidden" name="order_by" value="<?php echo attribute_escape($order_by); ?>" />
+<input type="hidden" name="cat_id" value="<?php echo (int) $cat_id ?>" />
+<table class="widefat">
+	<thead>
+	<tr>
+<?php foreach($link_columns as $column_display_name) {
+	echo $column_display_name;
+} ?>
+	<th style="text-align: center"><input type="checkbox" onclick="checkAll(document.getElementById('links'));" /></th>
+	</tr>
+	</thead>
+	<tbody id="the-list">
+<?php
+	foreach ($links as $link) {
+		$link->link_name = attribute_escape(apply_filters('link_title', $link->link_name));
+		$link->link_description = wp_specialchars(apply_filters('link_description', $link->link_description));
+		$link->link_url = clean_url($link->link_url);
+		$link->link_category = wp_get_link_cats($link->link_id);
+		$short_url = str_replace('http://', '', $link->link_url);
+		$short_url = str_replace('www.', '', $short_url);
+		if ('/' == substr($short_url, -1))
+			$short_url = substr($short_url, 0, -1);
+		if (strlen($short_url) > 35)
+			$short_url = substr($short_url, 0, 32).'...';
+
+		$visible = ($link->link_visible == 'Y') ? __('Yes') : __('No');
+		++ $i;
+		$style = ($i % 2) ? '' : ' class="alternate"';
+		?><tr id="link-<?php echo $link->link_id; ?>" valign="middle" <?php echo $style; ?>><?php
+		foreach($link_columns as $column_name=>$column_display_name) {
+			switch($column_name) {
+				case 'name':
+					?><td><strong><?php echo $link->link_name; ?></strong><br /><?php
+					echo $link->link_description . "</td>";
+					break;
+				case 'url':
+					echo "<td><a href='$link->link_url' title='".sprintf(__('Visit %s'), $link->link_name)."'>$short_url</a></td>";
+					break;
+				case 'categories':
+					?><td><?php
+					$cat_names = array();
+					foreach ($link->link_category as $category) {
+						$cat_name = get_the_category_by_ID($category);
+						$cat_name = wp_specialchars(apply_filters('link_category', $cat_name));
+						if ( $cat_id != $category )
+							$cat_name = "<a href='link-manager.php?cat_id=$category'>$cat_name</a>";
+						$cat_names[] = $cat_name;
+					}
+					echo implode(', ', $cat_names);
+					?> </td><?php
+					break;
+				case 'rel':
+					?><td><?php echo $link->link_rel; ?></td><?php
+					break;
+				case 'visible':
+					?><td align='center'><?php echo $visible; ?></td><?php
+					break;
+				case 'action':
+					echo '<td><a href="link.php?link_id='.$link->link_id.'&amp;action=edit" class="edit">'.__('Edit').'</a></td>';
+					echo '<td><a href="' . wp_nonce_url('link.php?link_id='.$link->link_id.'&amp;action=delete', 'delete-bookmark_' . $link->link_id ) . '"'." onclick=\"return deleteSomething( 'link', $link->link_id , '".js_escape(sprintf(__("You are about to delete the '%s' link to %s.\n'Cancel' to stop, 'OK' to delete."), $link->link_name, $link->link_url )).'\' );" class="delete">'.__('Delete').'</a></td>';
+					break;
+				default:
+					?>
+					<td><?php do_action('manage_link_custom_column', $column_name, $link->link_id); ?></td>
+					<?php
+					break;
 
+			}
+		}
+		echo '<td align="center"><input type="checkbox" name="linkcheck[]" value="'.$link->link_id.'" /></td>';
 		echo "\n    </tr>\n";
-        }
-    }
+	}
 ?>
+	</tbody>
 </table>
 
 <div id="ajax-response"></div>
 
-</div>
-
-<div class="wrap">
-  <table width="100%" cellpadding="3" cellspacing="3">
-    <tr><th colspan="4"><?php _e('Manage Multiple Links:') ?></th></tr>
-    <tr><td colspan="4"><?php _e('Use the checkboxes on the right to select multiple links and choose an action below:') ?></td></tr>
-    <tr>
-        <td>
-          <?php _e('Assign ownership to:'); ?>
-<?php
-    $results = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users ORDER BY ID");
-    echo "          <select name=\"newowner\" size=\"1\">\n";
-    foreach ($results as $row) {
-      echo "            <option value=\"".$row->ID."\"";
-      echo ">".$row->user_login;
-      echo "</option>\n";
-    }
-    echo "          </select>\n";
-?>
-        <input name="assign" type="submit" id="assign" value="<?php _e('Go') ?>" />
-        </td>
-        <td>
-          <input name="visibility" type="submit" id="visibility" value="<?php _e('Toggle Visibility') ?>" />
-        </td>
-        <td>
-          <?php _e('Move to category:'); link_category_dropdown('category'); ?> <input name="move" type="submit" id="move" value="<?php _e('Go') ?>" />
-        </td>
-        <td align="right">
-          <a href="#" onclick="checkAll(document.getElementById('links')); return false; "><?php _e('Toggle Checkboxes') ?></a>
-        </td>
-    </tr>
-</table>
-
-<?php
-  } // end if !popup
-?>
-</div>
+<p class="submit"><input type="submit" class="button" name="deletebookmarks" id="deletebookmarks" value="<?php _e('Delete Checked Links') ?> &raquo;" onclick="return confirm('<?php echo js_escape(__("You are about to delete these links permanently.\n'Cancel' to stop, 'OK' to delete.")); ?>')" /></p>
 </form>
 
+<?php } ?>
 
-<?php
-    break;
-  } // end default
-} // end case
-?>
+</div>
 
 <?php include('admin-footer.php'); ?>
diff -ruN 2.0.5/wp-admin/link-parse-opml.php 2.2.2/wp-admin/link-parse-opml.php
--- 2.0.5/wp-admin/link-parse-opml.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/link-parse-opml.php	2006-11-19 01:56:05.000000000 -0600
@@ -4,12 +4,12 @@
 // columns we wish to find are:  link_url, link_name, link_target, link_description
 // we need to map XML attribute names to our columns
 $opml_map = array('URL'         => 'link_url',
-                  'HTMLURL'     => 'link_url',
-                  'TEXT'        => 'link_name',
-                  'TITLE'       => 'link_name',
-                  'TARGET'      => 'link_target',
-                  'DESCRIPTION' => 'link_description',
-                  'XMLURL'      => 'link_rss'
+	'HTMLURL'     => 'link_url',
+	'TEXT'        => 'link_name',
+	'TITLE'       => 'link_name',
+	'TARGET'      => 'link_target',
+	'DESCRIPTION' => 'link_description',
+	'XMLURL'      => 'link_rss'
 );
 
 $map = $opml_map;
@@ -20,24 +20,24 @@
  **/
 function startElement($parser, $tagName, $attrs) {
 	global $updated_timestamp, $all_links, $map;
-    global $names, $urls, $targets, $descriptions, $feeds;
+	global $names, $urls, $targets, $descriptions, $feeds;
 
 	if ($tagName == 'OUTLINE') {
-        foreach (array_keys($map) as $key) {
-            if (isset($attrs[$key])) {
-                $$map[$key] = $attrs[$key];
-            }
-        }
-
-        //echo("got data: link_url = [$link_url], link_name = [$link_name], link_target = [$link_target], link_description = [$link_description]<br />\n");
-
-        // save the data away.
-        $names[] = $link_name;
-        $urls[] = $link_url;
-        $targets[] = $link_target;
+		foreach (array_keys($map) as $key) {
+			if (isset($attrs[$key])) {
+				$$map[$key] = $attrs[$key];
+			}
+		}
+
+		//echo("got data: link_url = [$link_url], link_name = [$link_name], link_target = [$link_target], link_description = [$link_description]<br />\n");
+
+		// save the data away.
+		$names[] = $link_name;
+		$urls[] = $link_url;
+		$targets[] = $link_target;
 		$feeds[] = $link_rss;
-        $descriptions[] = $link_description;
-    } // end if outline
+		$descriptions[] = $link_description;
+	} // end if outline
 }
 
 /**
@@ -55,9 +55,9 @@
 xml_set_element_handler($xml_parser, "startElement", "endElement");
 
 if (!xml_parse($xml_parser, $opml, true)) {
-    echo(sprintf(__('XML error: %1$s at line %2$s'),
-                   xml_error_string(xml_get_error_code($xml_parser)),
-                   xml_get_current_line_number($xml_parser)));
+	echo(sprintf(__('XML error: %1$s at line %2$s'),
+	xml_error_string(xml_get_error_code($xml_parser)),
+	xml_get_current_line_number($xml_parser)));
 }
 
 // Free up memory used by the XML parser
diff -ruN 2.0.5/wp-admin/link.php 2.2.2/wp-admin/link.php
--- 2.0.5/wp-admin/link.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/link.php	2006-11-19 20:17:07.000000000 -0600
@@ -0,0 +1,117 @@
+<?php
+require_once ('admin.php');
+
+wp_reset_vars(array('action', 'cat_id', 'linkurl', 'name', 'image', 'description', 'visible', 'target', 'category', 'link_id', 'submit', 'order_by', 'links_show_cat_id', 'rating', 'rel', 'notes', 'linkcheck[]'));
+
+if ('' != $_POST['deletebookmarks'])
+	$action = 'deletebookmarks';
+if ('' != $_POST['move'])
+	$action = 'move';
+if ('' != $_POST['linkcheck'])
+	$linkcheck = $_POST[linkcheck];
+
+$this_file = 'link-manager.php';
+
+switch ($action) {
+		case 'deletebookmarks' :
+		check_admin_referer('bulk-bookmarks');
+
+		// check the current user's level first.
+		if (!current_user_can('manage_links'))
+			wp_die(__('Cheatin&#8217; uh?'));
+
+		//for each link id (in $linkcheck[]) change category to selected value
+		if (count($linkcheck) == 0) {
+			wp_redirect($this_file);
+			exit;
+		}
+
+		$deleted = 0;
+		foreach ($linkcheck as $link_id) {
+			$link_id = (int) $link_id;
+
+			if ( wp_delete_link($link_id) )
+				$deleted++;
+		}
+
+		wp_redirect("$this_file?deleted=$deleted");
+		exit;
+		break;
+
+	case 'move' :
+		check_admin_referer('bulk-bookmarks');
+
+		// check the current user's level first.
+		if (!current_user_can('manage_links'))
+			wp_die(__('Cheatin&#8217; uh?'));
+
+		//for each link id (in $linkcheck[]) change category to selected value
+		if (count($linkcheck) == 0) {
+			wp_redirect($this_file);
+			exit;
+		}
+		$all_links = join(',', $linkcheck);
+		// should now have an array of links we can change
+		//$q = $wpdb->query("update $wpdb->links SET link_category='$category' WHERE link_id IN ($all_links)");
+
+		wp_redirect($this_file);
+		exit;
+		break;
+
+	case 'add' :
+		check_admin_referer('add-bookmark');
+
+		add_link();
+
+		wp_redirect(wp_get_referer().'?added=true');
+		exit;
+		break;
+
+	case 'save' :
+		$link_id = (int) $_POST['link_id'];
+		check_admin_referer('update-bookmark_' . $link_id);
+
+		edit_link($link_id);
+
+		wp_redirect($this_file);
+		exit;
+		break;
+
+	case 'delete' :
+		$link_id = (int) $_GET['link_id'];
+		check_admin_referer('delete-bookmark_' . $link_id);
+
+		if (!current_user_can('manage_links'))
+			wp_die(__('Cheatin&#8217; uh?'));
+
+		wp_delete_link($link_id);
+
+		wp_redirect($this_file);
+		exit;
+		break;
+
+	case 'edit' :
+		wp_enqueue_script( array('xfn', 'dbx-admin-key?pagenow=link.php') );
+		if ( current_user_can( 'manage_categories' ) )
+			wp_enqueue_script( 'ajaxcat' );
+		$parent_file = 'link-manager.php';
+		$submenu_file = 'link-manager.php';
+		$title = __('Edit Link');
+		include_once ('admin-header.php');
+		if (!current_user_can('manage_links'))
+			wp_die(__('You do not have sufficient permissions to edit the links for this blog.'));
+
+		$link_id = (int) $_GET['link_id'];
+
+		if (!$link = get_link_to_edit($link_id))
+			wp_die(__('Link not found.'));
+
+		include ('edit-link-form.php');
+		break;
+
+	default :
+		break;
+}
+
+include ('admin-footer.php');
+?>
diff -ruN 2.0.5/wp-admin/list-manipulation.js 2.2.2/wp-admin/list-manipulation.js
--- 2.0.5/wp-admin/list-manipulation.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/list-manipulation.js	1969-12-31 18:00:00.000000000 -0600
@@ -1,96 +0,0 @@
-var listItems;
-var reg_color = '#FFFFFF';
-var alt_color = '#F1F1F1';
-
-addLoadEvent(getListItems);
-
-function deleteSomething( what, id, message ) {
-	what.replace('-', ' ');
-	if (!message) message = 'Are you sure you want to delete this ' + what + '?';
-	if ( confirm(message) ) {
-		return ajaxDelete( what.replace(' ', '-'), id );
-	} else {
-		return false;
-	}
-}
-
-function getResponseElement() {
-	var p = document.getElementById('ajax-response-p');
-	if (!p) {
-		p = document.createElement('p');
-		p.id = 'ajax-response-p';
-		document.getElementById('ajax-response').appendChild(p);
-		return p;
-	}
-}
-
-function ajaxDelete(what, id) {
-	ajaxDel = new sack('list-manipulation.php');
-	if ( ajaxDel.failed ) return true;
-	ajaxDel.myResponseElement = getResponseElement();
-	ajaxDel.method = 'POST';
-	ajaxDel.onLoading = function() { ajaxDel.myResponseElement.innerHTML = 'Sending Data...'; };
-	ajaxDel.onLoaded = function() { ajaxDel.myResponseElement.innerHTML = 'Data Sent...'; };
-	ajaxDel.onInteractive = function() { ajaxDel.myResponseElement.innerHTML = 'Processing Data...'; };
-	ajaxDel.onCompletion = function() { removeThisItem( what + '-' + id ); };
-	ajaxDel.runAJAX('action=delete-' + what + '&id=' + id + '&' + ajaxDel.encVar('cookie', document.cookie));
-	return false;
-}
-
-function removeThisItem(id) {
-	var response = ajaxDel.response;
-	if ( isNaN(response) ) { ajaxDel.myResponseElement.innerHTML = response; return false; }
-	response = parseInt(response, 10);
-	if ( -1 == response ) { ajaxDel.myResponseElement.innerHTML = "You don't have permission to do that."; }
-	else if ( 0 == response ) { ajaxDel.myResponseElement.interHTML = "Something odd happened.  Try refreshing the page? Either that or what you tried to delete never existed in the first place."; }
-	else if ( 1 == response ) {
-		theItem = document.getElementById(id);
-		Fat.fade_element(id,null,700,'#FF3333');
-		setTimeout('theItem.parentNode.removeChild(theItem)', 705);
-		var pos = getListPos(id);
-		listItems.splice(pos,1);
-		recolorList(pos);
-		ajaxDel.myResponseElement.parentNode.removeChild(ajaxDel.myResponseElement);
-		
-	}
-}
-
-function getListPos(id) {
-	for (var i = 0; i < listItems.length; i++) {
-		if (id == listItems[i]) {
-			var pos = i;
-			break;
-		}
-	}
-	return pos;
-}	
-
-function getListItems() {
-	if (list) return;
-	listItems = new Array();
-	var extra = false;
-	var list = document.getElementById('the-list');
-	if (!list) { var list = document.getElementById('the-list-x'); extra = true; }
-	if (list) {
-		var items = list.getElementsByTagName('tr');
-		if (!items[0]) { items = list.getElementsByTagName('li'); }
-		for (var i=0; i<items.length; i++) { listItems.push(items[i].id); }
-		if (extra) { listItems.splice(0,1); }
-	}
-}
-
-function recolorList(pos,dur,from) {
-	if (!pos) pos = 0;
-
-	if (!from) {
-		reg_from = alt_color;
-		alt_from = reg_color;
-	} else {
-		reg_from = from;
-		alt_from = from;
-	}
-	for (var i = pos; i < listItems.length; i++) {
-		if (i % 2 == 1) Fat.fade_element(listItems[i],null,dur,reg_from,reg_color);
-		else Fat.fade_element(listItems[i],null,dur,alt_from,alt_color);
-	}
-}
diff -ruN 2.0.5/wp-admin/list-manipulation.php 2.2.2/wp-admin/list-manipulation.php
--- 2.0.5/wp-admin/list-manipulation.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/list-manipulation.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,81 +0,0 @@
-<?php
-require_once('../wp-config.php');
-require_once('admin-functions.php');
-require_once('admin-db.php');
-header("Content-type: text/plain", true);
-
-if ( !is_user_logged_in() )
-	die('-1');
-if ( !check_ajax_referer() )
-	die('-1');
-
-function grab_results() {
-	global $ajax_results;
-	$ajax_results = func_get_arg(0);
-}
-
-function get_out_now() { exit; }
-add_action('shutdown', 'get_out_now', -1);
-
-switch ( $_POST['action'] ) :
-case 'delete-link' :
-	$id = (int) $_POST['id'];
-	if ( !current_user_can('manage_links') )
-		die ('-1');
-
-	if ( wp_delete_link($id) ) 
-		die('1');
-	else	die('0');
-	break;
-case 'delete-post' :
-case 'delete-page' :
-	$id = (int) $_POST['id'];
-	if ( !current_user_can('edit_post', $id) )	{
-		die('-1');
-	}
-
-	if ( wp_delete_post($id) ) {
-		die('1');
-	} else	die('0');
-	break;
-case 'delete-cat' :
-	if ( !current_user_can('manage_categories') )
-		die ('-1');
-
-	$id = (int) $_POST['id'];
-	$cat_name = get_catname($cat_ID);
-
-	if ( wp_delete_category($id) )
-		die('1');
-	else	die('0');
-	break;
-case 'delete-comment' :
-	$id = (int) $_POST['id'];
-
-	if ( !$comment = get_comment($id) )
-		die('0');
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die('-1');
-
-	if ( wp_delete_comment($comment->comment_ID) ) {
-		die('1');
-	} else {
-		die('0');
-	}
-	break;
-case 'delete-link-category' :
-	$id = (int) $_POST['id'];
-	if ( 1 == $id )
-		die('0');
-	if ( !current_user_can('manage_links') )
-		die('-1');
-
-	if ( $wpdb->query("DELETE FROM $wpdb->linkcategories WHERE cat_id='$id'") ) {
-		$wpdb->query("UPDATE $wpdb->links SET link_category=1 WHERE link_category='$id'");
-		die('1');
-	} else {
-		die('0');
-	}
-	break;
-endswitch;		
-?>
diff -ruN 2.0.5/wp-admin/menu-header.php 2.2.2/wp-admin/menu-header.php
--- 2.0.5/wp-admin/menu-header.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/menu-header.php	2006-11-19 01:56:05.000000000 -0600
@@ -10,12 +10,19 @@
 
 	// 0 = name, 1 = capability, 2 = file
 	if (( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file))) $class = ' class="current"';
-    
-	if ( current_user_can($item[1]) ) {
-		if ( file_exists(ABSPATH . "wp-content/plugins/{$item[2]}") )
-			echo "\n\t<li><a href='" . get_settings('siteurl') . "/wp-admin/admin.php?page={$item[2]}'$class>{$item[0]}</a></li>";			
+
+	if ( !empty($submenu[$item[2]]) ) {
+		$submenu[$item[2]] = array_values($submenu[$item[2]]);  // Re-index.
+		$menu_hook = get_plugin_page_hook($submenu[$item[2]][0][2], $item[2]);
+		if ( file_exists(ABSPATH . PLUGINDIR . "/{$submenu[$item[2]][0][2]}") || !empty($menu_hook))
+			echo "\n\t<li><a href='admin.php?page={$submenu[$item[2]][0][2]}'$class>{$item[0]}</a></li>";
+		else
+			echo "\n\t<li><a href='{$submenu[$item[2]][0][2]}'$class>{$item[0]}</a></li>";
+	} else if ( current_user_can($item[1]) ) {
+		if ( file_exists(ABSPATH . PLUGINDIR . "/{$item[2]}") )
+			echo "\n\t<li><a href='admin.php?page={$item[2]}'$class>{$item[0]}</a></li>";
 		else
-			echo "\n\t<li><a href='" . get_settings('siteurl') . "/wp-admin/{$item[2]}'$class>{$item[0]}</a></li>";
+			echo "\n\t<li><a href='{$item[2]}'$class>{$item[0]}</a></li>";
 	}
 }
 
@@ -27,8 +34,8 @@
 if ( isset($submenu["$parent_file"]) ) :
 ?>
 <ul id="submenu">
-<?php 
-foreach ($submenu["$parent_file"] as $item) : 
+<?php
+foreach ($submenu["$parent_file"] as $item) :
 	 if ( !current_user_can($item[1]) )
 		 continue;
 
@@ -40,21 +47,25 @@
 
 $menu_hook = get_plugin_page_hook($item[2], $parent_file);
 
-if (file_exists(ABSPATH . "wp-content/plugins/{$item[2]}") || ! empty($menu_hook)) {
+if (file_exists(ABSPATH . PLUGINDIR . "/{$item[2]}") || ! empty($menu_hook)) {
  	if ( 'admin.php' == $pagenow )
-		echo "\n\t<li><a href='" . get_settings('siteurl') . "/wp-admin/admin.php?page={$item[2]}'$class>{$item[0]}</a></li>";
+		echo "\n\t<li><a href='admin.php?page={$item[2]}'$class>{$item[0]}</a></li>";
 	else
-		echo "\n\t<li><a href='" . get_settings('siteurl') . "/wp-admin/{$parent_file}?page={$item[2]}'$class>{$item[0]}</a></li>";
+		echo "\n\t<li><a href='{$parent_file}?page={$item[2]}'$class>{$item[0]}</a></li>";
  } else {
-	echo "\n\t<li><a href='" . get_settings('siteurl') . "/wp-admin/{$item[2]}'$class>{$item[0]}</a></li>";
+	echo "\n\t<li><a href='{$item[2]}'$class>{$item[0]}</a></li>";
  }
 endforeach;
 ?>
 
 </ul>
 <?php
+else :
+?>
+<div id="minisub"></div>
+<?php
 
-endif; 
+endif;
 
 do_action('admin_notices');
 
diff -ruN 2.0.5/wp-admin/menu.php 2.2.2/wp-admin/menu.php
--- 2.0.5/wp-admin/menu.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/menu.php	2007-05-06 15:35:51.000000000 -0500
@@ -5,43 +5,63 @@
 // The minimum level the user needs to access the item: between 0 and 10
 // The URL of the item's file
 $menu[0] = array(__('Dashboard'), 'read', 'index.php');
-$menu[5] = array(__('Write'), 'edit_posts', 'post.php');
-$menu[10] = array(__('Manage'), 'edit_posts', 'edit.php');
-$menu[20] = array(__('Links'), 'manage_links', 'link-manager.php');
+
+if (strpos($_SERVER['REQUEST_URI'], 'edit-pages.php') !== false)
+	$menu[5] = array(__('Write'), 'edit_pages', 'page-new.php');
+else
+	$menu[5] = array(__('Write'), 'edit_posts', 'post-new.php');
+if (strpos($_SERVER['REQUEST_URI'], 'page-new.php') !== false)
+	$menu[10] = array(__('Manage'), 'edit_pages', 'edit-pages.php');
+else
+	$menu[10] = array(__('Manage'), 'edit_posts', 'edit.php');
+
+$menu[15] = array(__('Comments'), 'edit_posts', 'edit-comments.php');
+$menu[20] = array(__('Blogroll'), 'manage_links', 'link-manager.php');
 $menu[25] = array(__('Presentation'), 'switch_themes', 'themes.php');
 $menu[30] = array(__('Plugins'), 'activate_plugins', 'plugins.php');
 if ( current_user_can('edit_users') )
-	$menu[35] = array(__('Users'), 'read', 'profile.php');
+	$menu[35] = array(__('Users'), 'edit_users', 'users.php');
 else
 	$menu[35] = array(__('Profile'), 'read', 'profile.php');
 $menu[40] = array(__('Options'), 'manage_options', 'options-general.php');
-$menu[45] = array(__('Import'), 'import', 'import.php');
 
-$submenu['post.php'][5] = array(__('Write Post'), 'edit_posts', 'post.php');
-$submenu['post.php'][10] = array(__('Write Page'), 'edit_pages', 'page-new.php');
+
+$_wp_real_parent_file['post.php'] = 'post-new.php'; // Back-compat
+$submenu['post-new.php'][5] = array(__('Write Post'), 'edit_posts', 'post-new.php');
+$submenu['post-new.php'][10] = array(__('Write Page'), 'edit_pages', 'page-new.php');
+
+$submenu['edit-comments.php'][5] = array(__('Comments'), 'edit_posts', 'edit-comments.php');
+$awaiting_mod = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'");
+$submenu['edit-comments.php'][25] = array(sprintf(__("Awaiting Moderation (%s)"), "<span id='awaitmod'>$awaiting_mod</span>"), 'edit_posts', 'moderation.php');
+
 
 $submenu['edit.php'][5] = array(__('Posts'), 'edit_posts', 'edit.php');
 $submenu['edit.php'][10] = array(__('Pages'), 'edit_pages', 'edit-pages.php');
+$submenu['edit.php'][12] = array(__('Uploads'), 'upload_files', 'upload.php');
 $submenu['edit.php'][15] = array(__('Categories'), 'manage_categories', 'categories.php');
-$submenu['edit.php'][20] = array(__('Comments'), 'edit_posts', 'edit-comments.php');
-$awaiting_mod = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'");
-$submenu['edit.php'][25] = array(sprintf(__("Awaiting Moderation (%s)"), $awaiting_mod), 'edit_posts', 'moderation.php');
 $submenu['edit.php'][30] = array(__('Files'), 'edit_files', 'templates.php');
+$submenu['edit.php'][35] = array(__('Import'), 'import', 'import.php');
+$submenu['edit.php'][40] = array(__('Export'), 'import', 'export.php');
 
-$submenu['link-manager.php'][5] = array(__('Manage Links'), 'manage_links', 'link-manager.php');
+$submenu['link-manager.php'][5] = array(__('Manage Blogroll'), 'manage_links', 'link-manager.php');
 $submenu['link-manager.php'][10] = array(__('Add Link'), 'manage_links', 'link-add.php');
-$submenu['link-manager.php'][15] = array(__('Link Categories'), 'manage_links', 'link-categories.php');
 $submenu['link-manager.php'][20] = array(__('Import Links'), 'manage_links', 'link-import.php');
 
-$submenu['profile.php'][5] = array(__('Your Profile'), 'read', 'profile.php');
-$submenu['profile.php'][10] = array(__('Authors &amp; Users'), 'edit_users', 'users.php');
+if ( current_user_can('edit_users') ) {
+	$_wp_real_parent_file['profile.php'] = 'users.php'; // Back-compat for plugins adding submenus to profile.php.
+	$submenu['users.php'][5] = array(__('Authors &amp; Users'), 'edit_users', 'users.php');
+	$submenu['users.php'][10] = array(__('Your Profile'), 'read', 'profile.php');
+} else {
+	$submenu['profile.php'][5] = array(__('Your Profile'), 'read', 'profile.php');
+}
 
 $submenu['options-general.php'][10] = array(__('General'), 'manage_options', 'options-general.php');
 $submenu['options-general.php'][15] = array(__('Writing'), 'manage_options', 'options-writing.php');
 $submenu['options-general.php'][20] = array(__('Reading'), 'manage_options', 'options-reading.php');
 $submenu['options-general.php'][25] = array(__('Discussion'), 'manage_options', 'options-discussion.php');
-$submenu['options-general.php'][30] = array(__('Permalinks'), 'manage_options', 'options-permalink.php');
-$submenu['options-general.php'][35] = array(__('Miscellaneous'), 'manage_options', 'options-misc.php');
+$submenu['options-general.php'][30] = array(__('Privacy'), 'manage_options', 'options-privacy.php');
+$submenu['options-general.php'][35] = array(__('Permalinks'), 'manage_options', 'options-permalink.php');
+$submenu['options-general.php'][40] = array(__('Miscellaneous'), 'manage_options', 'options-misc.php');
 
 $submenu['plugins.php'][5] = array(__('Plugins'), 'activate_plugins', 'plugins.php');
 $submenu['plugins.php'][10] = array(__('Plugin Editor'), 'edit_plugins', 'plugin-editor.php');
@@ -49,16 +69,74 @@
 $submenu['themes.php'][5] = array(__('Themes'), 'switch_themes', 'themes.php');
 $submenu['themes.php'][10] = array(__('Theme Editor'), 'edit_themes', 'theme-editor.php');
 
+do_action('_admin_menu');
+
 // Create list of page plugin hook names.
 foreach ($menu as $menu_page) {
 	$admin_page_hooks[$menu_page[2]] = sanitize_title($menu_page[0]);
 }
 
+$_wp_submenu_nopriv = array();
+$_wp_menu_nopriv = array();
+// Loop over submenus and remove pages for which the user does not have privs.
+foreach ($submenu as $parent => $sub) {
+	foreach ($sub as $index => $data) {
+		if ( ! current_user_can($data[1]) ) {
+			unset($submenu[$parent][$index]);
+			$_wp_submenu_nopriv[$parent][$data[2]] = true;
+		}
+	}
+
+	if ( empty($submenu[$parent]) )
+		unset($submenu[$parent]);
+}
+
+// Loop over the top-level menu.
+// Menus for which the original parent is not acessible due to lack of privs will have the next
+// submenu in line be assigned as the new menu parent.
+foreach ( $menu as $id => $data ) {
+	if ( empty($submenu[$data[2]]) ) 
+		continue;
+	$subs = $submenu[$data[2]];
+	$first_sub = array_shift($subs);
+	$old_parent = $data[2];
+	$new_parent = $first_sub[2];
+	// If the first submenu is not the same as the assigned parent,
+	// make the first submenu the new parent.
+	if ( $new_parent != $old_parent ) {
+		$_wp_real_parent_file[$old_parent] = $new_parent;
+		$menu[$id][2] = $new_parent;
+
+		foreach ($submenu[$old_parent] as $index => $data) {
+			$submenu[$new_parent][$index] = $submenu[$old_parent][$index];
+			unset($submenu[$old_parent][$index]);
+		}
+		unset($submenu[$old_parent]);
+		$_wp_submenu_nopriv[$new_parent] = $_wp_submenu_nopriv[$old_parent];
+	}
+}
+
 do_action('admin_menu', '');
+
+// Remove menus that have no accessible submenus and require privs that the user does not have.
+// Run re-parent loop again.
+foreach ( $menu as $id => $data ) {
+	// If submenu is empty...
+	if ( empty($submenu[$data[2]]) ) {
+		// And user doesn't have privs, remove menu.
+		if ( ! current_user_can($data[1]) ) {
+			$_wp_menu_nopriv[$data[2]] = true;
+			unset($menu[$id]);
+		}
+	}
+}
+
+unset($id);
+
 uksort($menu, "strnatcasecmp"); // make it all pretty
 
 if (! user_can_access_admin_page()) {
-	die( __('You do not have sufficient permissions to access this page.') );
+	wp_die( __('You do not have sufficient permissions to access this page.') );
 }
 
 ?>
diff -ruN 2.0.5/wp-admin/moderation.php 2.2.2/wp-admin/moderation.php
--- 2.0.5/wp-admin/moderation.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/moderation.php	2007-03-06 19:25:17.000000000 -0600
@@ -2,24 +2,10 @@
 require_once('admin.php');
 
 $title = __('Moderate comments');
-$parent_file = 'edit.php';
-$list_js = true;
+$parent_file = 'edit-comments.php';
+wp_enqueue_script( 'admin-comments' );
 
-$wpvarstoreset = array('action', 'item_ignored', 'item_deleted', 'item_approved', 'item_spam', 'feelinglucky');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'item_ignored', 'item_deleted', 'item_approved', 'item_spam', 'feelinglucky'));
 
 $comment = array();
 if (isset($_POST["comment"])) {
@@ -34,8 +20,8 @@
 
 	check_admin_referer('moderate-comments');
 
-	if ( ! current_user_can('moderate_comments') )
-	die('<p>'.__('Your level is not high enough to moderate comments.').'</p>');
+	if ( !current_user_can('moderate_comments') )
+		wp_die(__('Your level is not high enough to moderate comments.'));
 
 	$item_ignored = 0;
 	$item_deleted = 0;
@@ -45,7 +31,7 @@
 	foreach($comment as $key => $value) {
 	if ($feelinglucky && 'later' == $value)
 		$value = 'delete';
-	    switch($value) {
+		switch($value) {
 			case 'later':
 				// do nothing with that comment
 				// wp_set_comment_status($key, "hold");
@@ -55,18 +41,18 @@
 				wp_set_comment_status($key, 'delete');
 				++$item_deleted;
 				break;
- 			case 'spam':
- 				wp_set_comment_status($key, 'spam');
- 				++$item_spam;
- 				break;
+			case 'spam':
+				wp_set_comment_status($key, 'spam');
+				++$item_spam;
+				break;
 			case 'approve':
 				wp_set_comment_status($key, 'approve');
-				if ( get_settings('comments_notify') == true ) {
+				if ( get_option('comments_notify') == true ) {
 					wp_notify_postauthor($key);
 				}
 				++$item_approved;
 				break;
-	    }
+		}
 	}
 
 	$file = basename(__FILE__);
@@ -86,38 +72,26 @@
 	$ignored  = (int) $_GET['ignored'];
 	$spam     = (int) $_GET['spam'];
 	if ($approved) {
-		if ('1' == $approved) {
-			echo __("1 comment approved") . " <br/>\n";
-		} else {
-		 echo sprintf(__("%s comments approved <br />"), $approved) . "\n";
-		}
+		printf(__ngettext('%s comment approved', '%s comments approved', $approved), $approved);
+		echo "<br/>\n";
 	}
 	if ($deleted) {
-		if ('1' == $deleted) {
-			echo __("1 comment deleted") . " <br/>\n";
-		} else {
-			echo sprintf(__("%s comments deleted"), $deleted) . " <br/>\n";
-		}
+		printf(__ngettext('%s comment deleted', '%s comments deleted', $deleted), $deleted);
+		echo "<br/>\n";
+	}
+	if ($spam) {
+		printf(__ngettext('%s comment marked as spam', '%s comments marked as spam', $spam), $spam);
+		echo "<br/>\n";
 	}
- 	if ($spam) {
- 		if ('1' == $spam) {
-			echo __("1 comment marked as spam") . " <br/>\n";
- 		} else {
- 			echo sprintf(__("%s comments marked as spam"), $spam) . " <br/>\n";
- 		}
- 	}
 	if ($ignored) {
-		if ('1' == $ignored) {
-			echo __("1 comment unchanged") . " <br/>\n";
-		} else {
-			echo sprintf(__("%s comments unchanged"), $ignored) . " <br/>\n";
-		}
+		printf(__ngettext('%s comment unchanged', '%s comments unchanged', $ignored), $ignored);
+		echo "<br/>\n";
 	}
 	echo "</p></div>\n";
 }
 
 ?>
-	
+
 <div class="wrap">
 
 <?php
@@ -134,39 +108,44 @@
     <form name="approval" action="moderation.php" method="post">
     <?php wp_nonce_field('moderate-comments') ?>
     <input type="hidden" name="action" value="update" />
-    <ol id="the-list" class="commentlist">
+    <ol id="the-comment-list" class="commentlist">
 <?php
 $i = 0;
     foreach($comments as $comment) {
 	++$i;
-	$comment_date = mysql2date(get_settings("date_format") . " @ " . get_settings("time_format"), $comment->comment_date);
+	$comment_date = mysql2date(get_option("date_format") . " @ " . get_option("time_format"), $comment->comment_date);
 	$post_title = $wpdb->get_var("SELECT post_title FROM $wpdb->posts WHERE ID='$comment->comment_post_ID'");
-	if ($i % 2) $class = 'class="alternate"';
-	else $class = '';
-	echo "\n\t<li id='comment-$comment->comment_ID' $class>"; 
+	if ($i % 2) $class = 'js-unapproved alternate';
+	else $class = 'js-unapproved';
+	echo "\n\t<li id='comment-$comment->comment_ID' class='$class'>"; 
 	?>
-	<p><strong><?php _e('Name:') ?></strong> <?php comment_author_link() ?> <?php if ($comment->comment_author_email) { ?>| <strong><?php _e('E-mail:') ?></strong> <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <strong><?php _e('URI:') ?></strong> <?php comment_author_url_link() ?> <?php } ?>| <strong><?php _e('IP:') ?></strong> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a> | <strong><?php _e('Date:') ?></strong> <?php comment_date(); ?></p>
+	<p><strong><?php comment_author() ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
 <?php comment_text() ?>
-<p><?php
-echo '<a href="post.php?action=editcomment&amp;comment='.$comment->comment_ID.'">' . __('Edit') . '</a> | ';?>
-<a href="<?php echo get_permalink($comment->comment_post_ID); ?>"><?php _e('View Post') ?></a> | 
-<?php 
-echo " <a href=\"" . wp_nonce_url("post.php?action=deletecomment&amp;p=".$comment->comment_post_ID."&amp;comment=".$comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . "\" onclick=\"return deleteSomething( 'comment', $comment->comment_ID, '" . __("You are about to delete this comment.\\n&quot;Cancel&quot; to stop, &quot;OK&quot; to delete.") . "' );\">" . __('Delete just this comment') . "</a> | "; ?>  <?php _e('Bulk action:') ?>
-	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-approve" value="approve" /> <label for="comment[<?php echo $comment->comment_ID; ?>]-approve"><?php _e('Approve') ?></label>
-	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-spam" value="spam" /> <label for="comment[<?php echo $comment->comment_ID; ?>]-spam"><?php _e('Spam') ?></label>
-	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-delete" value="delete" /> <label for="comment[<?php echo $comment->comment_ID; ?>]-delete"><?php _e('Delete') ?></label>
-	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-nothing" value="later" checked="checked" /> <label for="comment[<?php echo $comment->comment_ID; ?>]-nothing"><?php _e('Defer until later') ?></label>
+<p><?php comment_date(__('M j, g:i A')); ?> &#8212; [ <?php
+echo '<a href="comment.php?action=editcomment&amp;c='.$comment->comment_ID.'">' . __('Edit') . '</a> | ';
+echo " <a href=\"post.php?action=deletecomment&amp;p=".$comment->comment_post_ID."&amp;comment=".$comment->comment_ID."\" onclick=\"return deleteSomething( 'comment', $comment->comment_ID, '" . js_escape(sprintf(__("You are about to delete this comment by '%s'.\n'Cancel' to stop, 'OK' to delete."), $comment->comment_author )) . "', theCommentList );\">" . __('Delete') . "</a> | "; ?>
+<?php
+$post = get_post($comment->comment_post_ID);
+$post_title = wp_specialchars( $post->post_title, 'double' );
+$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
+?>
+<a href="<?php echo get_permalink($comment->comment_post_ID); ?>" title="<?php echo $post_title; ?>"><?php _e('View Post') ?></a> ] &#8212;
+ <?php _e('Bulk action:') ?>
+	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-approve" value="approve" /> <label for="comment-<?php echo $comment->comment_ID; ?>-approve"><?php _e('Approve') ?></label> &nbsp;
+	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-spam" value="spam" /> <label for="comment-<?php echo $comment->comment_ID; ?>-spam"><?php _e('Spam') ?></label> &nbsp;
+	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-delete" value="delete" /> <label for="comment-<?php echo $comment->comment_ID; ?>-delete"><?php _e('Delete') ?></label> &nbsp;
+	<input type="radio" name="comment[<?php echo $comment->comment_ID; ?>]" id="comment-<?php echo $comment->comment_ID; ?>-nothing" value="later" checked="checked" /> <label for="comment-<?php echo $comment->comment_ID; ?>-nothing"><?php _e('Defer until later') ?></label>
 	</p>
 
 	</li>
 <?php
-    }
+	}
 ?>
-    </ol>
+	</ol>
 
 <div id="ajax-response"></div>
 
-    <p class="submit"><input type="submit" name="submit" value="<?php _e('Moderate Comments &raquo;') ?>" /></p>
+<p class="submit"><input type="submit" name="submit" value="<?php _e('Bulk Moderate Comments &raquo;') ?>" /></p>
 <script type="text/javascript">
 // <![CDATA[
 function markAllForDelete() {
@@ -206,10 +185,10 @@
 		<input name="feelinglucky" type="checkbox" id="feelinglucky" value="true" /> <label for="feelinglucky"><?php _e('Delete every comment marked "defer." <strong>Warning: This can&#8217;t be undone.</strong>'); ?></label>
 	</p>
 </noscript>
-    </form>
+</form>
 <?php
 } else {
-    // nothing to approve
+	// nothing to approve
 	echo '<p>'.__("Currently there are no comments for you to moderate.") . "</p>\n";
 }
 ?>
@@ -222,4 +201,6 @@
 }
 
 
-include('admin-footer.php') ?>
+include('admin-footer.php');
+
+?>
diff -ruN 2.0.5/wp-admin/options-discussion.php 2.2.2/wp-admin/options-discussion.php
--- 2.0.5/wp-admin/options-discussion.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-discussion.php	2007-01-15 20:27:00.000000000 -0600
@@ -5,39 +5,29 @@
 $parent_file = 'options-general.php';
 
 include('admin-header.php');
-
-if ($action == 'retrospam') {
-	if ( $_GET['move'] == 'true' ) {
-		retrospam_mgr::move_spam( $_GET[ids] );
-	}
-	$retrospaminator = new retrospam_mgr();
-	$result = $retrospaminator->find_spam();
-	echo $retrospaminator->display_edit_form( $result );
-	include('./admin-footer.php');
-	exit;
-}
 ?>
 
 <div class="wrap"> 
 <h2><?php _e('Discussion Options') ?></h2> 
 <form method="post" action="options.php"> 
 <?php wp_nonce_field('update-options') ?>
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /></p>
 <fieldset class="options">
-<legend><?php _e('Usual settings for an article:<br /><small><em>(These settings may be overridden for individual articles.)</em></small>') ?></legend> 
+<legend><?php echo __('Usual settings for an article:').'<br /><small><em>('.__('These settings may be overridden for individual articles.').')</em></small>'; ?></legend> 
 <ul> 
 <li> 
 <label for="default_pingback_flag"> 
-<input name="default_pingback_flag" type="checkbox" id="default_pingback_flag" value="1" <?php checked('1', get_settings('default_pingback_flag')); ?> /> 
+<input name="default_pingback_flag" type="checkbox" id="default_pingback_flag" value="1" <?php checked('1', get_option('default_pingback_flag')); ?> /> 
 <?php _e('Attempt to notify any Weblogs linked to from the article (slows down posting.)') ?></label> 
 </li> 
 <li> 
 <label for="default_ping_status"> 
-<input name="default_ping_status" type="checkbox" id="default_ping_status" value="open" <?php checked('open', get_settings('default_ping_status')); ?> /> 
+<input name="default_ping_status" type="checkbox" id="default_ping_status" value="open" <?php checked('open', get_option('default_ping_status')); ?> /> 
 <?php _e('Allow link notifications from other Weblogs (pingbacks and trackbacks.)') ?></label> 
 </li> 
 <li> 
 <label for="default_comment_status"> 
-<input name="default_comment_status" type="checkbox" id="default_comment_status" value="open" <?php checked('open', get_settings('default_comment_status')); ?> /> 
+<input name="default_comment_status" type="checkbox" id="default_comment_status" value="open" <?php checked('open', get_option('default_comment_status')); ?> /> 
 <?php _e('Allow people to post comments on the article') ?></label> 
 </li> 
 </ul> 
@@ -47,12 +37,12 @@
 <ul> 
 <li> 
 <label for="comments_notify"> 
-<input name="comments_notify" type="checkbox" id="comments_notify" value="1" <?php checked('1', get_settings('comments_notify')); ?> /> 
+<input name="comments_notify" type="checkbox" id="comments_notify" value="1" <?php checked('1', get_option('comments_notify')); ?> /> 
 <?php _e('Anyone posts a comment') ?> </label> 
 </li> 
 <li> 
 <label for="moderation_notify"> 
-<input name="moderation_notify" type="checkbox" id="moderation_notify" value="1" <?php checked('1', get_settings('moderation_notify')); ?> /> 
+<input name="moderation_notify" type="checkbox" id="moderation_notify" value="1" <?php checked('1', get_option('moderation_notify')); ?> /> 
 <?php _e('A comment is held for moderation') ?> </label> 
 </li> 
 </ul> 
@@ -62,40 +52,35 @@
 <ul>
 <li>
 <label for="comment_moderation"> 
-<input name="comment_moderation" type="checkbox" id="comment_moderation" value="1" <?php checked('1', get_settings('comment_moderation')); ?> /> 
-<?php _e('An administrator must approve the comment (regardless of any matches below)') ?> </label> 
+<input name="comment_moderation" type="checkbox" id="comment_moderation" value="1" <?php checked('1', get_option('comment_moderation')); ?> /> 
+<?php _e('An administrator must always approve the comment') ?> </label> 
 </li> 
-<li><label for="require_name_email"><input type="checkbox" name="require_name_email" id="require_name_email" value="1" <?php checked('1', get_settings('require_name_email')); ?> /> <?php _e('Comment author must fill out name and e-mail') ?></label></li> 
-<li><label for="comment_whitelist"><input type="checkbox" name="comment_whitelist" id="comment_whitelist" value="1" <?php checked('1', get_settings('comment_whitelist')); ?> /> <?php _e('Comment author must have a previously approved comment') ?></label></li> 
+<li><label for="require_name_email"><input type="checkbox" name="require_name_email" id="require_name_email" value="1" <?php checked('1', get_option('require_name_email')); ?> /> <?php _e('Comment author must fill out name and e-mail') ?></label></li> 
+<li><label for="comment_whitelist"><input type="checkbox" name="comment_whitelist" id="comment_whitelist" value="1" <?php checked('1', get_option('comment_whitelist')); ?> /> <?php _e('Comment author must have a previously approved comment') ?></label></li> 
 </ul> 
 </fieldset>
 <fieldset class="options">
 <legend><?php _e('Comment Moderation') ?></legend>
-<p><?php printf(__('Hold a comment in the queue if it contains %s or more links. (A common characteristic of comment spam is a large number of hyperlinks.)'), '<input name="comment_max_links" type="text" id="comment_max_links" size="3" value="' . get_settings('comment_max_links'). '" />' ) ?></p>
+<p><?php printf(__('Hold a comment in the queue if it contains %s or more links. (A common characteristic of comment spam is a large number of hyperlinks.)'), '<input name="comment_max_links" type="text" id="comment_max_links" size="3" value="' . get_option('comment_max_links'). '" />' ) ?></p>
 
-<p><?php _e('When a comment contains any of these words in its content, name, URI, e-mail, or IP, hold it in the moderation queue: (Separate multiple words with new lines.) <a href="http://codex.wordpress.org/Spam_Words">Common spam words</a>.') ?></p>
+<p><?php _e('When a comment contains any of these words in its content, name, URL, e-mail, or IP, it will be held in the <a href="moderation.php">moderation queue</a>. One word or IP per line. It will match inside words, so "press" will match "WordPress".') ?></p>
 <p> 
 <textarea name="moderation_keys" cols="60" rows="4" id="moderation_keys" style="width: 98%; font-size: 12px;" class="code"><?php form_option('moderation_keys'); ?></textarea> 
 </p> 
-<p>
-<a id="retrospambutton" href="options-discussion.php?action=retrospam"><?php _e('Check past comments against moderation list'); ?></a>
-</p> 
 </fieldset>
 <fieldset class="options">
 <legend><?php _e('Comment Blacklist') ?></legend>
-<p><?php _e('This is a list of words that you want completely blacklisted from your blog. Be very careful what you add here, because if a comment matches something here it will be completely nuked and there will be no notification. Remember that partial words can match, so if there is any chance something here might match it would be better to put it in the moderation box above.') ?></p>
+<p><?php _e('When a comment contains any of these words in its content, name, URL, e-mail, or IP, it will be marked as spam. One word or IP per line. It will match inside words, so "press" will match "WordPress".') ?></p>
 <p> 
 <textarea name="blacklist_keys" cols="60" rows="4" id="blacklist_keys" style="width: 98%; font-size: 12px;" class="code"><?php form_option('blacklist_keys'); ?></textarea> 
 </p>
-<p><label for="open_proxy_check"> 
-<input name="open_proxy_check" type="checkbox" id="open_proxy_check" value="1" <?php checked('1', get_settings('open_proxy_check')); ?> /> 
-<?php _e('Blacklist comments from open and insecure proxies.') ?></label></p>
 </fieldset>
 <p class="submit">
 <input type="hidden" name="action" value="update" /> 
-<input type="hidden" name="page_options" value="default_pingback_flag,default_ping_status,default_comment_status,comments_notify,moderation_notify,comment_moderation,require_name_email,comment_whitelist,comment_max_links,moderation_keys,blacklist_keys,open_proxy_check" /> 
-<input type="submit" name="Submit" value="<?php _e('Update Options') ?>" /> 
-</p> 
-</form> 
+<input type="hidden" name="page_options" value="default_pingback_flag,default_ping_status,default_comment_status,comments_notify,moderation_notify,comment_moderation,require_name_email,comment_whitelist,comment_max_links,moderation_keys,blacklist_keys" /> 
+<input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /> 
+</p>
+</form>
 </div>
-<?php include('./admin-footer.php'); ?>
+
+<?php include('./admin-footer.php'); ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/options-general.php 2.2.2/wp-admin/options-general.php
--- 2.0.5/wp-admin/options-general.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-general.php	2007-05-04 19:19:25.000000000 -0500
@@ -11,6 +11,7 @@
 <h2><?php _e('General Options') ?></h2>
 <form method="post" action="options.php"> 
 <?php wp_nonce_field('update-options') ?>
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /></p>
 <table class="optiontable"> 
 <tr valign="top"> 
 <th scope="row"><?php _e('Weblog title:') ?></th> 
@@ -23,12 +24,12 @@
 <?php _e('In a few words, explain what this weblog is about.') ?></td> 
 </tr> 
 <tr valign="top"> 
-<th scope="row"><?php _e('WordPress address (URI):') ?></th> 
-<td><input name="siteurl" type="text" id="siteurl" value="<?php form_option('siteurl'); ?>" size="40" class="code" /></td> 
+<th scope="row"><?php _e('WordPress address (URL):') ?></th> 
+<td><input name="siteurl" type="text" id="siteurl" value="<?php form_option('siteurl'); ?>" size="40" class="code<?php if ( defined( 'WP_SITEURL' ) ) : ?> disabled" disabled="disabled"<?php else: ?>"<?php endif; ?> /></td> 
 </tr> 
 <tr valign="top">
-<th scope="row"><?php _e('Blog address (URI):') ?></th>
-<td><input name="home" type="text" id="home" value="<?php form_option('home'); ?>" size="40" class="code" /><br /><?php _e('If you want your blog homepage <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">to be different than the directory</a> you installed WordPress in, enter that address here.'); ?></td>
+<th scope="row"><?php _e('Blog address (URL):') ?></th>
+<td><input name="home" type="text" id="home" value="<?php form_option('home'); ?>" size="40" class="code<?php if ( defined( 'WP_HOME' ) ) : ?> disabled" disabled="disabled"<?php else: ?>"<?php endif; ?> /><br /><?php _e('Enter the address here if you want your blog homepage <a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory">to be different from the directory</a> you installed WordPress.'); ?></td>
 </tr>
 <tr valign="top"> 
 <th scope="row"><?php _e('E-mail address:') ?> </th> 
@@ -39,10 +40,10 @@
 <tr valign="top"> 
 <th scope="row"><?php _e('Membership:') ?></th> 
 <td> <label for="users_can_register"> 
-<input name="users_can_register" type="checkbox" id="users_can_register" value="1" <?php checked('1', get_settings('users_can_register')); ?> /> 
+<input name="users_can_register" type="checkbox" id="users_can_register" value="1" <?php checked('1', get_option('users_can_register')); ?> /> 
 <?php _e('Anyone can register') ?></label><br />
 <label for="comment_registration">
-<input name="comment_registration" type="checkbox" id="comment_registration" value="1" <?php checked('1', get_settings('comment_registration')); ?> /> 
+<input name="comment_registration" type="checkbox" id="comment_registration" value="1" <?php checked('1', get_option('comment_registration')); ?> /> 
 <?php _e('Users must be registered and logged in to comment') ?>
 </label>
 </td> 
@@ -50,12 +51,7 @@
 <tr valign="top"> 
 <th scope="row"><?php _e('New User Default Role:') ?></th> 
 <td><label for="default_role"> 
-<select name="default_role" id="default_role"><?php 
-foreach($wp_roles->role_names as $role => $name) {
-	$selected = (get_settings('default_role') == $role) ? 'selected="selected"' : '';
-	echo "<option {$selected} value=\"{$role}\">{$name}</option>";
-}
-?></select></label>
+<select name="default_role" id="default_role"><?php wp_dropdown_roles( get_option('default_role') ); ?></select></label>
 </td> 
 </tr> 
 </table> 
@@ -64,22 +60,22 @@
 <table class="optiontable"> 
 <tr> 
 <th scope="row"><?php _e('<abbr title="Coordinated Universal Time">UTC</abbr> time is:') ?> </th> 
-<td><code><?php echo gmdate('Y-m-d g:i:s a'); ?></code></td> 
+<td><code><?php echo gmdate(__('Y-m-d g:i:s a')); ?></code></td> 
 </tr>
 <tr>
 <th scope="row"><?php _e('Times in the weblog should differ by:') ?> </th>
 <td><input name="gmt_offset" type="text" id="gmt_offset" size="2" value="<?php form_option('gmt_offset'); ?>" /> 
-<?php _e('hours') ?> </td>
+<?php _e('hours') ?> (<?php _e('Your timezone offset, for example <code>-6</code> for Central Time.'); ?>)</td>
 </tr>
 <tr>
 <th scope="row"><?php _e('Default date format:') ?></th>
 <td><input name="date_format" type="text" id="date_format" size="30" value="<?php form_option('date_format'); ?>" /><br />
-<?php _e('Output:') ?> <strong><?php echo mysql2date(get_settings('date_format'), current_time('mysql')); ?></strong></td>
+<?php _e('Output:') ?> <strong><?php echo mysql2date(get_option('date_format'), current_time('mysql')); ?></strong></td>
 </tr>
 <tr>
 <th scope="row"><?php _e('Default time format:') ?></th>
 <td><input name="time_format" type="text" id="time_format" size="30" value="<?php form_option('time_format'); ?>" /><br />
-<?php _e('Output:') ?> <strong><?php echo gmdate(get_settings('time_format'), current_time('timestamp')); ?></strong></td>
+<?php _e('Output:') ?> <strong><?php echo gmdate(get_option('time_format'), current_time('timestamp')); ?></strong></td>
 </tr> 
 <tr>
 <th scope="row">&nbsp;</th>
@@ -90,9 +86,8 @@
 <td><select name="start_of_week" id="start_of_week">
 <?php
 for ($day_index = 0; $day_index <= 6; $day_index++) :
-if ($day_index == get_settings('start_of_week')) $selected = " selected='selected'";
-else $selected = '';
-echo "\n\t<option value='$day_index' $selected>$weekday[$day_index]</option>";
+	$selected = (get_option('start_of_week') == $day_index) ? 'selected="selected"' : '';
+	echo "\n\t<option value='$day_index' $selected>" . $wp_locale->get_weekday($day_index) . '</option>';
 endfor;
 ?>
 </select></td>
@@ -100,12 +95,12 @@
 </table>
 </fieldset> 
 
-<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options') ?> &raquo;" />
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" />
 <input type="hidden" name="action" value="update" /> 
-<input type="hidden" name="page_options" value="blogname,blogdescription,siteurl,admin_email,users_can_register,gmt_offset,date_format,time_format,home,start_of_week,comment_registration,default_role" /> 
+<input type="hidden" name="page_options" value="<?php if ( ! defined( 'WP_SITEURL' ) ) echo 'siteurl,'; if ( ! defined( 'WP_HOME' ) ) echo 'home,'; ?>blogname,blogdescription,admin_email,users_can_register,gmt_offset,date_format,time_format,start_of_week,comment_registration,default_role" /> 
 </p>
 </form>
 
 </div> 
 
-<?php include('./admin-footer.php') ?>
\ No newline at end of file
+<?php include('./admin-footer.php') ?>
diff -ruN 2.0.5/wp-admin/options-head.php 2.2.2/wp-admin/options-head.php
--- 2.0.5/wp-admin/options-head.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-head.php	2007-03-16 03:10:02.000000000 -0500
@@ -1,23 +1,4 @@
-<?php
-
-$wpvarstoreset = array('action','standalone', 'option_group_id');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
-?>
-
-<br clear="all" />
+<?php wp_reset_vars(array('action', 'standalone', 'option_group_id')); ?>
 
 <?php if (isset($_GET['updated'])) : ?>
 <div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
diff -ruN 2.0.5/wp-admin/options-misc.php 2.2.2/wp-admin/options-misc.php
--- 2.0.5/wp-admin/options-misc.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-misc.php	2007-03-06 19:35:39.000000000 -0600
@@ -7,17 +7,18 @@
 include('admin-header.php');
 
 ?>
- 
-<div class="wrap"> 
-<h2><?php _e('Miscellaneous Options') ?></h2> 
+
+<div class="wrap">
+<h2><?php _e('Miscellaneous Options') ?></h2>
 <form method="post" action="options.php">
 <?php wp_nonce_field('update-options') ?>
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /></p>
 <fieldset class="options">
 <legend><?php _e('Uploading'); ?></legend>
 <table class="editform optiontable">
 <tr valign="top">
 <th scope="row"><?php _e('Store uploads in this folder'); ?>:</th>
-<td><input name="upload_path" type="text" id="upload_path" class="code" value="<?php echo wp_specialchars(str_replace(ABSPATH, '', get_settings('upload_path')), 1); ?>" size="40" />
+<td><input name="upload_path" type="text" id="upload_path" class="code" value="<?php echo attribute_escape(str_replace(ABSPATH, '', get_option('upload_path'))); ?>" size="40" />
 <br />
 <?php _e('Default is <code>wp-content/uploads</code>'); ?>
 </td>
@@ -26,7 +27,7 @@
 <td></td>
 <td>
 <label for="uploads_use_yearmonth_folders">
-<input name="uploads_use_yearmonth_folders" type="checkbox" id="uploads_use_yearmonth_folders" value="1" <?php checked('1', get_settings('uploads_use_yearmonth_folders')); ?> />
+<input name="uploads_use_yearmonth_folders" type="checkbox" id="uploads_use_yearmonth_folders" value="1" <?php checked('1', get_option('uploads_use_yearmonth_folders')); ?> />
 <?php _e('Organize my uploads into month- and year-based folders'); ?>
 </label>
 </td>
@@ -34,18 +35,18 @@
 </table>
 </fieldset>
 
-<p><input name="use_linksupdate" type="checkbox" id="use_linksupdate" value="1" <?php checked('1', get_settings('use_linksupdate')); ?> />
+<p><input name="use_linksupdate" type="checkbox" id="use_linksupdate" value="1" <?php checked('1', get_option('use_linksupdate')); ?> />
 <label for="use_linksupdate"><?php _e('Track Links&#8217; Update Times') ?></label></p>
 <p>
-<label><input type="checkbox" name="hack_file" value="1" <?php checked('1', get_settings('hack_file')); ?> /> <?php _e('Use legacy <code>my-hacks.php</code> file support') ?></label>
+<label><input type="checkbox" name="hack_file" value="1" <?php checked('1', get_option('hack_file')); ?> /> <?php _e('Use legacy <code>my-hacks.php</code> file support') ?></label>
 </p>
 
 <p class="submit">
 <input type="hidden" name="action" value="update" />
-<input type="hidden" name="page_options" value="hack_file,use_linksupdate,uploads_use_yearmonth_folders,upload_path" /> 
-<input type="submit" name="Submit" value="<?php _e('Update Options') ?> &raquo;" />
+<input type="hidden" name="page_options" value="hack_file,use_linksupdate,uploads_use_yearmonth_folders,upload_path" />
+<input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" />
 </p>
-</form> 
+</form>
 </div>
 
 <?php include('./admin-footer.php'); ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/options-permalink.php 2.2.2/wp-admin/options-permalink.php
--- 2.0.5/wp-admin/options-permalink.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-permalink.php	2007-04-19 17:26:52.000000000 -0500
@@ -41,7 +41,7 @@
 
 var aInputs = document.getElementsByTagName('input');
 
-for (var i = 0; i < aInputs.length; i++) {		
+for (var i = 0; i < aInputs.length; i++) {
 aInputs[i].onclick = aInputs[i].onkeyup = upit;
 }
 }
@@ -66,7 +66,7 @@
 			$permalink_structure = preg_replace('#/+#', '/', '/' . $_POST['permalink_structure']);
 		$wp_rewrite->set_permalink_structure($permalink_structure);
 	}
-	
+
 	if ( isset($_POST['category_base']) ) {
 		$category_base = $_POST['category_base'];
 		if (! empty($category_base) )
@@ -74,9 +74,9 @@
 		$wp_rewrite->set_category_base($category_base);
 	}
 }
-	
-$permalink_structure = get_settings('permalink_structure');
-$category_base = get_settings('category_base');
+
+$permalink_structure = get_option('permalink_structure');
+$category_base = get_option('category_base');
 
 if ( (!file_exists($home_path.'.htaccess') && is_writable($home_path)) || is_writable($home_path.'.htaccess') )
 	$writable = true;
@@ -102,7 +102,10 @@
 
 <div class="wrap"> 
   <h2><?php _e('Customize Permalink Structure') ?></h2> 
-  <p><?php _e('By default WordPress uses web URIs which have question marks and lots of numbers in them, however WordPress offers you the ability to create a custom URI structure for your permalinks and archives. This can improve the aesthetics, usability, and forward-compatibility of your links. A <a href="http://codex.wordpress.org/Using_Permalinks">number of tags are available</a>, and here are some examples to get you started.'); ?></p>
+<form name="form" action="options-permalink.php" method="post"> 
+<?php wp_nonce_field('update-permalink') ?>
+<p class="submit"><input type="submit" name="submit" value="<?php _e('Update Permalink Structure &raquo;') ?>" /></p>
+  <p><?php _e('By default WordPress uses web <abbr title="Universal Resource Locator">URL</abbr>s which have question marks and lots of numbers in them, however WordPress offers you the ability to create a custom URL structure for your permalinks and archives. This can improve the aesthetics, usability, and forward-compatibility of your links. A <a href="http://codex.wordpress.org/Using_Permalinks">number of tags are available</a>, and here are some examples to get you started.'); ?></p>
 
 <?php
 $prefix = '';
@@ -116,25 +119,23 @@
 	$prefix . '/archives/%post_id%'
 	);
 ?>
-<form name="form" action="options-permalink.php" method="post"> 
-<?php wp_nonce_field('update-permalink') ?>
 <h3><?php _e('Common options:'); ?></h3>
 <p>
 	<label>
 <input name="selection" type="radio" value="" class="tog" <?php checked('', $permalink_structure); ?> /> 
-<?php _e('Default'); ?><br /> <span> &raquo; <code><?php echo get_settings('home'); ?>/?p=123</code></span>
+<?php _e('Default'); ?><br /> <span> &raquo; <code><?php echo get_option('home'); ?>/?p=123</code></span>
    </label>
 </p>
 <p>
 	<label>
 <input name="selection" type="radio" value="<?php echo $structures[1]; ?>" class="tog" <?php checked($structures[1], $permalink_structure); ?> /> 
-<?php _e('Date and name based'); ?><br /> <span> &raquo; <code><?php echo get_settings('home') . $prefix . '/' . date('Y') . '/' . date('m') . '/' . date('d') . '/sample-post/'; ?></code></span>
+<?php _e('Date and name based'); ?><br /> <span> &raquo; <code><?php echo get_option('home') . $prefix . '/' . date('Y') . '/' . date('m') . '/' . date('d') . '/sample-post/'; ?></code></span>
    </label>
 </p>
 <p>
 	<label>
 <input name="selection" type="radio" value="<?php echo $structures[2]; ?>" class="tog" <?php checked($structures[2], $permalink_structure); ?> /> 
-<?php _e('Numeric'); ?><br /> <span> &raquo; <code><?php echo get_settings('home') . $prefix  ; ?>/archives/123</code></span>
+<?php _e('Numeric'); ?><br /> <span> &raquo; <code><?php echo get_option('home') . $prefix  ; ?>/archives/123</code></span>
    </label>
 </p>
 <p>
@@ -143,21 +144,21 @@
 <?php if ( !in_array($permalink_structure, $structures) ) { ?>
 checked="checked"
 <?php } ?>
- /> 
-<?php _e('Custom, specify below'); ?>	
+ />
+<?php _e('Custom, specify below'); ?>
 </label>
 <br />
 </p>
-<p id="customstructure"><?php _e('Custom structure'); ?>: <input name="permalink_structure" id="permalink_structure" type="text" class="code" style="width: 60%;" value="<?php echo wp_specialchars($permalink_structure, 1); ?>" size="50" /></p>
+<p id="customstructure"><?php _e('Custom structure'); ?>: <input name="permalink_structure" id="permalink_structure" type="text" class="code" style="width: 60%;" value="<?php echo attribute_escape($permalink_structure); ?>" size="50" /></p>
 
 <h3><?php _e('Optional'); ?></h3>
 <?php if ($is_apache) : ?>
-	<p><?php _e('If you like, you may enter a custom prefix for your category URIs here. For example, <code>/taxonomy/tags</code> would make your category links like <code>http://example.org/taxonomy/tags/uncategorized/</code>. If you leave this blank the default will be used.') ?></p>
+	<p><?php _e('If you like, you may enter a custom prefix for your category <abbr title="Universal Resource Locator">URL</abbr>s here. For example, <code>/taxonomy/tags</code> would make your category links like <code>http://example.org/taxonomy/tags/uncategorized/</code>. If you leave this blank the default will be used.') ?></p>
 <?php else : ?>
-	<p><?php _e('If you like, you may enter a custom prefix for your category URIs here. For example, <code>/index.php/taxonomy/tags</code> would make your category links like <code>http://example.org/index.php/taxonomy/tags/uncategorized/</code>. If you leave this blank the default will be used.') ?></p>
+	<p><?php _e('If you like, you may enter a custom prefix for your category <abbr title="Universal Resource Locator">URL</abbr>s here. For example, <code>/index.php/taxonomy/tags</code> would make your category links like <code>http://example.org/index.php/taxonomy/tags/uncategorized/</code>. If you leave this blank the default will be used.') ?></p>
 <?php endif; ?>
 	<p> 
-  <?php _e('Category base'); ?>: <input name="category_base" type="text" class="code"  value="<?php echo wp_specialchars($category_base, 1); ?>" size="30" /> 
+  <?php _e('Category base'); ?>: <input name="category_base" type="text" class="code"  value="<?php echo attribute_escape($category_base); ?>" size="30" /> 
      </p> 
     <p class="submit"> 
       <input type="submit" name="submit" value="<?php _e('Update Permalink Structure &raquo;') ?>" /> 
@@ -168,7 +169,7 @@
 <form action="options-permalink.php" method="post">
 <?php wp_nonce_field('update-permalink') ?>
    <p>
-<textarea rows="5" style="width: 98%;" name="rules"><?php echo $wp_rewrite->mod_rewrite_rules(); ?>
+<textarea rows="5" style="width: 98%;" name="rules"><?php echo wp_specialchars($wp_rewrite->mod_rewrite_rules()); ?>
 </textarea>
     </p>
 </form>
diff -ruN 2.0.5/wp-admin/options-privacy.php 2.2.2/wp-admin/options-privacy.php
--- 2.0.5/wp-admin/options-privacy.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/options-privacy.php	2006-11-19 01:56:05.000000000 -0600
@@ -0,0 +1,35 @@
+<?php
+require_once('./admin.php');
+
+$title = __('Privacy Options');
+$parent_file = 'options-general.php';
+
+include('./admin-header.php');
+?>
+
+<div class="wrap">
+<h2><?php _e('Privacy Options') ?></h2>
+<form method="post" action="options.php">
+<?php wp_nonce_field('update-options') ?>
+<table class="optiontable">
+<tr valign="top">
+<th scope="row"><?php _e('Blog visibility:') ?> </th>
+<td>
+<p><input id="blog-public" type="radio" name="blog_public" value="1" <?php checked('1', get_option('blog_public')); ?> />
+<label for="blog-public"><?php _e('I would like my blog to be visible to everyone, including search engines (like Google, Sphere, Technorati) and archivers');?></label></p>
+<p><input id="blog-norobots" type="radio" name="blog_public" value="0" <?php checked('0', get_option('blog_public')); ?> />
+<label for="blog-norobots"><?php _e('I would like to block search engines, but allow normal visitors'); ?></label></p>
+<?php do_action('blog_privacy_selector'); ?>
+</td>
+</tr>
+</table>
+
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" />
+<input type="hidden" name="action" value="update" />
+<input type="hidden" name="page_options" value="blog_public" />
+</p>
+</form>
+
+</div>
+
+<?php include('./admin-footer.php') ?>
diff -ruN 2.0.5/wp-admin/options-reading.php 2.2.2/wp-admin/options-reading.php
--- 2.0.5/wp-admin/options-reading.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-reading.php	2007-01-29 10:44:36.000000000 -0600
@@ -11,18 +11,48 @@
 <h2><?php _e('Reading Options') ?></h2> 
 <form name="form1" method="post" action="options.php">
 <?php wp_nonce_field('update-options') ?>
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /></p>
+<?php if ( get_pages() ): ?>
+<fieldset class="options"> 
+<legend><?php _e('Front Page') ?></legend> 
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform"> 
+<tr valign="top"> 
+<th width="33%" scope="row"><?php _e('Front page displays:')?></th> 
+<td>
+	<p><label>
+		<input name="show_on_front" type="radio" value="posts" class="tog" <?php checked('posts', get_option('show_on_front')); ?> /> 
+		<?php _e('Your latest posts'); ?>
+	</label>
+	</p>
+	<p><label>
+		<input name="show_on_front" type="radio" value="page" class="tog" <?php checked('page', get_option('show_on_front')); ?> /> 
+		<?php printf(__('A <a href="%s">static page</a> (select below)'), 'edit-pages.php'); ?>
+	</label>
+	</p>
+<ul>
+	<li><?php printf(__('Front page: %s'), wp_dropdown_pages("name=page_on_front&echo=0&show_option_none=".__('- Select -')."&selected=" . get_option('page_on_front'))); ?></li>
+	<li><?php printf(__('Posts page: %s'), wp_dropdown_pages("name=page_for_posts&echo=0&show_option_none=".__('- Select -')."&selected=" . get_option('page_for_posts'))); ?></li>
+</ul>
+<?php if ( 'page' == get_option('show_on_front') && get_option('page_for_posts') == get_option('page_on_front') ) : ?>
+<div id="front-page-warning" class="updated fade-ff0000">
+	<p>
+		<?php _e('<strong>Warning:</strong> these pages should not be the same!'); ?>
+	</p>
+</div>
+<?php endif; ?>
+</td> 
+</tr> 
+</table> 
+</fieldset>
+<?php endif; ?>
 
 <fieldset class="options"> 
 <legend><?php _e('Blog Pages') ?></legend> 
-<table width="100%" cellspacing="2" cellpadding="5" class="editform"> 
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform"> 
 <tr valign="top"> 
 <th width="33%" scope="row"><?php _e('Show at most:') ?></th> 
 <td>
-<input name="posts_per_page" type="text" id="posts_per_page" value="<?php form_option('posts_per_page'); ?>" size="3" /> 
-<select name="what_to_show" id="what_to_show" > 
-<option value="days" <?php selected('days', get_settings('what_to_show')); ?>><?php _e('days') ?></option> 
-<option value="posts" <?php selected('posts', get_settings('what_to_show')); ?>><?php _e('posts') ?></option> 
-</select>
+<input name="posts_per_page" type="text" id="posts_per_page" value="<?php form_option('posts_per_page'); ?>" size="3" /> <?php _e('posts') ?>
 </td> 
 </tr> 
 </table> 
@@ -30,7 +60,7 @@
 
 <fieldset class="options"> 
 <legend><?php _e('Syndication Feeds') ?></legend> 
-<table width="100%" cellspacing="2" cellpadding="5" class="editform"> 
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform"> 
 <tr valign="top"> 
 <th width="33%" scope="row"><?php _e('Show the most recent:') ?></th> 
 <td><input name="posts_per_rss" type="text" id="posts_per_rss" value="<?php form_option('posts_per_rss'); ?>" size="3" /> <?php _e('posts') ?></td> 
@@ -38,13 +68,14 @@
 <tr valign="top">
 <th scope="row"><?php _e('For each article, show:') ?> </th>
 <td>
-<label><input name="rss_use_excerpt"  type="radio" value="0" <?php checked(0, get_settings('rss_use_excerpt')); ?>  /> <?php _e('Full text') ?></label><br />
-<label><input name="rss_use_excerpt" type="radio" value="1" <?php checked(1, get_settings('rss_use_excerpt')); ?> /> <?php _e('Summary') ?></label>
+<p><label><input name="rss_use_excerpt"  type="radio" value="0" <?php checked(0, get_option('rss_use_excerpt')); ?>	/> <?php _e('Full text') ?></label><br />
+<label><input name="rss_use_excerpt" type="radio" value="1" <?php checked(1, get_option('rss_use_excerpt')); ?> /> <?php _e('Summary') ?></label></p>
+<p><?php _e('Note: If you use the <code>&lt;!--more--&gt;</code> feature, it will cut off posts in RSS feeds.'); ?></p>
 </td>
 </tr> 
 </table> 
 </fieldset> 
-<table width="100%" cellspacing="2" cellpadding="5" class="editform"> 
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform"> 
 <tr valign="top"> 
 <th width="33%" scope="row"><?php _e('Encoding for pages and feeds:') ?></th> 
 <td><input name="blog_charset" type="text" id="blog_charset" value="<?php form_option('blog_charset'); ?>" size="20" class="code" /><br />
@@ -52,13 +83,13 @@
 </tr>
 </table> 
 <p>
-<label><input type="checkbox" name="gzipcompression" value="1" <?php checked('1', get_settings('gzipcompression')); ?> /> 
+<label><input type="checkbox" name="gzipcompression" value="1" <?php checked('1', get_option('gzipcompression')); ?> /> 
 <?php _e('WordPress should compress articles (gzip) if browsers ask for them') ?></label>
 </p>
 <p class="submit">
 <input type="hidden" name="action" value="update" /> 
-<input type="hidden" name="page_options" value="posts_per_page,what_to_show,posts_per_rss,rss_use_excerpt,blog_charset,gzipcompression" /> 
-<input type="submit" name="Submit" value="<?php _e('Update Options') ?> &raquo;" /> 
+<input type="hidden" name="page_options" value="posts_per_page,posts_per_rss,rss_use_excerpt,blog_charset,gzipcompression,show_on_front,page_on_front,page_for_posts" /> 
+<input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /> 
 </p> 
 </form> 
 </div> 
diff -ruN 2.0.5/wp-admin/options-writing.php 2.2.2/wp-admin/options-writing.php
--- 2.0.5/wp-admin/options-writing.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options-writing.php	2007-03-06 19:30:53.000000000 -0600
@@ -11,7 +11,8 @@
 <h2><?php _e('Writing Options') ?></h2> 
 <form method="post" action="options.php"> 
 <?php wp_nonce_field('update-options') ?>
-<table width="100%" cellspacing="2" cellpadding="5" class="editform"> 
+<p class="submit"><input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" /></p>
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform"> 
 <tr valign="top"> 
 <th width="33%" scope="row"> <?php _e('Size of the post box:') ?></th> 
 <td><input name="default_post_edit_rows" type="text" id="default_post_edit_rows" value="<?php form_option('default_post_edit_rows'); ?>" size="2" style="width: 1.5em; " /> 
@@ -20,13 +21,10 @@
 <tr valign="top">
 <th scope="row"><?php _e('Formatting:') ?></th>
 <td>
-<label for="rich_editing">
-<input name="rich_editing" type="checkbox" id="rich_editing" value="true" <?php checked('true', get_settings('rich_editing')); ?> />
-<?php _e('Users should use the visual rich editor by default') ?></label><br />
 <label for="use_smilies">
-<input name="use_smilies" type="checkbox" id="use_smilies" value="1" <?php checked('1', get_settings('use_smilies')); ?> />
+<input name="use_smilies" type="checkbox" id="use_smilies" value="1" <?php checked('1', get_option('use_smilies')); ?> />
 <?php _e('Convert emoticons like <code>:-)</code> and <code>:-P</code> to graphics on display') ?></label><br />
-<label for="use_balanceTags"><input name="use_balanceTags" type="checkbox" id="use_balanceTags" value="1" <?php checked('1', get_settings('use_balanceTags')); ?> /> <?php _e('WordPress should correct invalidly nested XHTML automatically') ?></label>
+<label for="use_balanceTags"><input name="use_balanceTags" type="checkbox" id="use_balanceTags" value="1" <?php checked('1', get_option('use_balanceTags')); ?> /> <?php _e('WordPress should correct invalidly nested XHTML automatically') ?></label>
 </td>
 </tr>
 <tr valign="top">
@@ -35,7 +33,19 @@
 <?php
 $categories = $wpdb->get_results("SELECT * FROM $wpdb->categories ORDER BY cat_name");
 foreach ($categories as $category) :
-if ($category->cat_ID == get_settings('default_category')) $selected = " selected='selected'";
+if ($category->cat_ID == get_option('default_category')) $selected = " selected='selected'";
+else $selected = '';
+echo "\n\t<option value='$category->cat_ID' $selected>$category->cat_name</option>";
+endforeach;
+?>
+</select></td>
+</tr>
+<tr valign="top">
+<th scope="row"><?php _e('Default link category:') ?></th>
+<td><select name="default_link_category" id="default_link_category">
+<?php
+foreach ($categories as $category) :
+if ($category->cat_ID == get_option('default_link_category')) $selected = " selected='selected'";
 else $selected = '';
 echo "\n\t<option value='$category->cat_ID' $selected>$category->cat_name</option>";
 endforeach;
@@ -45,14 +55,14 @@
 </table>
 
 <fieldset class="options">
-<legend><?php _e('Writing by e-mail') ?></legend>
+<legend><?php _e('Post via e-mail') ?></legend>
 <p><?php printf(__('To post to WordPress by e-mail you must set up a secret e-mail account with POP3 access. Any mail received at this address will be posted, so it&#8217;s a good idea to keep this address very secret. Here are three random strings you could use: <code>%s</code>, <code>%s</code>, <code>%s</code>.'), substr(md5(uniqid(microtime())),0,5), substr(md5(uniqid(microtime())),0,5), substr(md5(uniqid(microtime())),0,5)) ?></p>
 
-<table width="100%" cellspacing="2" cellpadding="5" class="editform">
+<table width="100%" cellspacing="2" cellpadding="5" class="optiontable editform">
 <tr valign="top">
 <th scope="row"><?php _e('Mail server:') ?></th>
 <td><input name="mailserver_url" type="text" id="mailserver_url" value="<?php form_option('mailserver_url'); ?>" size="40" />
-<label for="mailserver_port"><?php _e('Port:') ?></label> 
+<label for="mailserver_port"><?php _e('Port:') ?></label>
 <input name="mailserver_port" type="text" id="mailserver_port" value="<?php form_option('mailserver_port'); ?>" size="6" />
 </td>
 </tr>
@@ -67,12 +77,12 @@
 </td>
 </tr>
 <tr valign="top">
-<th scope="row"><?php _e('Default post by mail category:') ?></th>
+<th scope="row"><?php _e('Default mail category:') ?></th>
 <td><select name="default_email_category" id="default_email_category">
 <?php
 //Alreay have $categories from default_category
 foreach ($categories as $category) :
-if ($category->cat_ID == get_settings('default_email_category')) $selected = " selected='selected'";
+if ($category->cat_ID == get_option('default_email_category')) $selected = " selected='selected'";
 else $selected = '';
 echo "\n\t<option value='$category->cat_ID' $selected>$category->cat_name</option>";
 endforeach;
@@ -84,17 +94,27 @@
 
 <fieldset class="options">
 <legend><?php _e('Update Services') ?></legend>
-<p><?php _e('When you publish a new post, WordPress automatically notifies the following site update services. For more about this, see <a href="http://codex.wordpress.org/Update_Services">Update Services</a> on the Codex. Separate multiple service URIs with line breaks.') ?></p>
+
+<?php if ( get_option('blog_public') ) : ?>
+
+<p><?php _e('When you publish a new post, WordPress automatically notifies the following site update services. For more about this, see <a href="http://codex.wordpress.org/Update_Services">Update Services</a> on the Codex. Separate multiple service <abbr title="Universal Resource Locator">URL</abbr>s with line breaks.') ?></p>
 
 <textarea name="ping_sites" id="ping_sites" style="width: 98%;" rows="3" cols="50"><?php form_option('ping_sites'); ?></textarea>
+
+<?php else : ?>
+
+	<p><?php printf(__('WordPress is not notifying any <a href="http://codex.wordpress.org/Update_Services">Update Services</a> because of your blog\'s <a href="%s">privacy settings</a>.'), 'options-privacy.php'); ?>
+
+<?php endif; ?>
+
 </fieldset>
 
 <p class="submit">
-<input type="hidden" name="action" value="update" /> 
-<input type="hidden" name="page_options" value="default_post_edit_rows,use_smilies,rich_editing,ping_sites,mailserver_url,mailserver_port,mailserver_login,mailserver_pass,default_category,default_email_category,use_balanceTags" /> 
-<input type="submit" name="Submit" value="<?php _e('Update Options') ?> &raquo;" /> 
+<input type="hidden" name="action" value="update" />
+<input type="hidden" name="page_options" value="default_post_edit_rows,use_smilies,ping_sites,mailserver_url,mailserver_port,mailserver_login,mailserver_pass,default_category,default_email_category,use_balanceTags,default_link_category" />
+<input type="submit" name="Submit" value="<?php _e('Update Options &raquo;') ?>" />
 </p>
-</form> 
-</div> 
+</form>
+</div>
 
 <?php include('./admin-footer.php') ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/options.php 2.2.2/wp-admin/options.php
--- 2.0.5/wp-admin/options.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/options.php	2007-08-01 14:25:15.000000000 -0500
@@ -5,40 +5,29 @@
 $this_file = 'options.php';
 $parent_file = 'options-general.php';
 
-$wpvarstoreset = array('action');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action'));
 
 if ( !current_user_can('manage_options') )
-	die ( __('Cheatin&#8217; uh?') );
+	wp_die(__('Cheatin&#8217; uh?'));
 
-function sanitize_option($option, $value) {
+function sanitize_option($option, $value) { // Remember to call stripslashes!
 
 	switch ($option) {
 		case 'admin_email':
+			$value = stripslashes($value);
 			$value = sanitize_email($value);
 			break;
 
 		case 'default_post_edit_rows':
 		case 'mailserver_port':
 		case 'comment_max_links':
+			$value = stripslashes($value);
 			$value = abs((int) $value);
 			break;
 
 		case 'posts_per_page':
 		case 'posts_per_rss':
+			$value = stripslashes($value);
 			$value = (int) $value;
 			if ( empty($value) ) $value = 1;
 			if ( $value < -1 ) $value = abs($value);
@@ -46,6 +35,7 @@
 
 		case 'default_ping_status':
 		case 'default_comment_status':
+			$value = stripslashes($value);
 			// Options that if not there have 0 value but need to be something like "closed"
 			if ( $value == '0' || $value == '')
 				$value = 'closed';
@@ -54,11 +44,12 @@
 		case 'blogdescription':
 		case 'blogname':
 			if (current_user_can('unfiltered_html') == false)
-				$value = wp_filter_post_kses( $value );
+				$value = wp_filter_post_kses( $value ); // calls stripslashes then addslashes
+			$value = stripslashes($value);
 			break;
 
 		case 'blog_charset':
-			$value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value);
+			$value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes
 			break;
 
 		case 'date_format':
@@ -69,27 +60,32 @@
 		case 'ping_sites':
 		case 'upload_path':
 			$value = strip_tags($value);
-			$value = wp_filter_kses($value);
+			$value = wp_filter_kses($value); // calls stripslashes then addslashes
+			$value = stripslashes($value);
 			break;
 
 		case 'gmt_offset':
-			$value = preg_replace('/[^0-9:.-]/', '', $value);
+			$value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes
 			break;
 
 		case 'siteurl':
 		case 'home':
+			$value = stripslashes($value);
 			$value = clean_url($value);
 			break;
+		default :
+			$value = stripslashes($value);
+			break;
 	}
 
-	return $value;	
+	return $value;
 }
 
 switch($action) {
 
 case 'update':
 	$any_changed = 0;
-	
+
 	check_admin_referer('update-options');
 
 	if ( !$_POST['page_options'] ) {
@@ -101,36 +97,15 @@
 		$options = explode(',', stripslashes($_POST['page_options']));
 	}
 
-	// Save for later.
-	$old_siteurl = get_settings('siteurl');
-	$old_home = get_settings('home');
-
 	if ($options) {
 		foreach ($options as $option) {
 			$option = trim($option);
-			$value = trim(stripslashes($_POST[$option]));
-			$value = sanitize_option($option, $value);
-			
-			if (update_option($option, $value) ) {
-				$any_changed++;
-			}
+			$value = trim($_POST[$option]);
+			$value = sanitize_option($option, $value); // This does stripslashes on those that need it
+			update_option($option, $value);
 		}
 	}
     
-	if ($any_changed) {
-			// If siteurl or home changed, reset cookies.
-			if ( get_settings('siteurl') != $old_siteurl || get_settings('home') != $old_home ) {
-				// If home changed, write rewrite rules to new location.
-				$wp_rewrite->flush_rules();
-				// Clear cookies for old paths.
-				wp_clearcookie();
-				// Set cookies for new paths.
-				wp_setcookie($user_login, $user_pass_md5, true, get_settings('home'), get_settings('siteurl'));
-			}
-
-			//$message = sprintf(__('%d setting(s) saved... '), $any_changed);
-    }
-    
 	$referred = remove_query_arg('updated' , wp_get_referer());
 	$goback = add_query_arg('updated', 'true', wp_get_referer());
 	$goback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $goback);
@@ -145,16 +120,18 @@
   <form name="form" action="options.php" method="post" id="all-options">
   <?php wp_nonce_field('update-options') ?>
   <input type="hidden" name="action" value="update" />
+	<p class="submit"><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
   <table width="98%">
 <?php
 $options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name");
 
 foreach ( (array) $options as $option) :
 	$disabled = '';
+	$option->option_name = attribute_escape($option->option_name);
 	if ( is_serialized($option->option_value) ) {
 		if ( is_serialized_string($option->option_value) ) {
 			// this is a serialized string, so we should display it
-			$value = wp_specialchars(maybe_unserialize($option->option_value), 'single');
+			$value = maybe_unserialize($option->option_value);
 			$options_to_update[] = $option->option_name;
 			$class = 'all-options';
 		} else {
@@ -163,7 +140,7 @@
 			$class = 'all-options disabled';
 		}
 	} else {
-		$value = wp_specialchars($option->option_value, 'single');
+		$value = $option->option_value;
 		$options_to_update[] = $option->option_name;
 		$class = 'all-options';
 	}
@@ -172,9 +149,9 @@
 	<th scope='row'><label for='$option->option_name'>$option->option_name</label></th>
 <td>";
 
-	if (stristr($value, "\n")) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
-	else echo "<input class='$class' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "'$disabled />";
-	
+	if (strpos($value, "\n") !== false) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>" . wp_specialchars($value) . "</textarea>";
+	else echo "<input class='$class' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . attribute_escape($value) . "'$disabled />";
+
 	echo "</td>
 	<td>$option->option_description</td>
 </tr>";
@@ -182,7 +159,7 @@
 ?>
   </table>
 <?php $options_to_update = implode(',', $options_to_update); ?>
-<p class="submit"><input type="hidden" name="page_options" value="<?php echo wp_specialchars($options_to_update, true); ?>" /><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
+<p class="submit"><input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" /><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
   </form>
 </div>
 
diff -ruN 2.0.5/wp-admin/page-new.php 2.2.2/wp-admin/page-new.php
--- 2.0.5/wp-admin/page-new.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/page-new.php	2007-02-22 09:30:47.000000000 -0600
@@ -1,23 +1,26 @@
 <?php
 require_once('admin.php');
 $title = __('New Page');
-$parent_file = 'post.php';
+$parent_file = 'post-new.php';
 $editing = true;
+wp_enqueue_script('prototype');
+wp_enqueue_script('interface');
+wp_enqueue_script('autosave');
 require_once('admin-header.php');
 ?>
 
-<?php if ( isset($_GET['saved']) ) : ?>
-<div id="message" class="updated fade"><p><strong><?php _e('Page saved.') ?></strong> <a href="edit-pages.php"><?php _e('Manage pages'); ?></a> | <a href="<?php echo get_page_link( $_GET['saved'] ); ?>"><?php _e('View page'); ?> &raquo;</a></p></div>
+<?php if ( (isset($_GET['posted']) && $_GET['posted'])  || isset($_GET['saved'])  ) : ?>
+<div id="message" class="updated fade"><p><strong><?php _e('Page saved.') ?></strong> <a href="edit-pages.php"><?php _e('Manage pages'); ?></a> | <a href="<?php echo get_page_link( isset($_GET['posted']) ? $_GET['posted'] : $_GET['saved'] ); ?>"><?php _e('View page') ; ?> &raquo;</a></p></div>
 <?php endif; ?>
 
 <?php
 if ( current_user_can('edit_pages') ) {
 	$action = 'post';
 	$post = get_default_post_to_edit();
-	$post->post_status = 'static';
+	$post->post_type = 'page';
 
 	include('edit-page-form.php');
 }
 ?>
 
-<?php include('admin-footer.php'); ?>
+<?php include('admin-footer.php'); ?> 
diff -ruN 2.0.5/wp-admin/page.php 2.2.2/wp-admin/page.php
--- 2.0.5/wp-admin/page.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/page.php	2007-03-31 17:02:19.000000000 -0500
@@ -0,0 +1,158 @@
+<?php
+require_once('admin.php');
+
+$parent_file = 'edit.php';
+$submenu_file = 'edit-pages.php';
+
+wp_reset_vars(array('action'));
+
+if (isset($_POST['deletepost'])) {
+$action = "delete";
+}
+
+switch($action) {
+case 'post':
+	check_admin_referer('add-page');
+	$page_ID = write_post();
+
+	// Redirect.
+	if (!empty($_POST['mode'])) {
+	switch($_POST['mode']) {
+		case 'bookmarklet':
+			$location = $_POST['referredby'];
+			break;
+		case 'sidebar':
+			$location = 'sidebar.php?a=b';
+			break;
+		default:
+			$location = 'page-new.php';
+			break;
+		}
+	} else {
+		$location = "page-new.php?posted=$page_ID";
+	}
+
+	if ( isset($_POST['save']) )
+		$location = "page.php?action=edit&post=$page_ID";
+
+	wp_redirect($location);
+	exit();
+	break;
+
+case 'edit':
+	$title = __('Edit');
+	$editing = true;
+	$page_ID = $post_ID = $p = (int) $_GET['post'];
+	$post = get_post_to_edit($page_ID);
+
+	if ( 'post' == $post->post_type ) {
+		wp_redirect("post.php?action=edit&post=$post_ID");
+		exit();
+	}
+
+	if($post->post_status == 'draft') {
+		wp_enqueue_script('prototype');
+		wp_enqueue_script('interface');
+		wp_enqueue_script('autosave');
+	}
+	require_once('admin-header.php');
+
+	if ( !current_user_can('edit_page', $page_ID) )
+		die ( __('You are not allowed to edit this page.') );
+
+	include('edit-page-form.php');
+	break;
+
+case 'editattachment':
+	$page_id = $post_ID = (int) $_POST['post_ID'];
+	check_admin_referer('update-attachment_' . $page_id);
+
+	// Don't let these be changed
+	unset($_POST['guid']);
+	$_POST['post_type'] = 'attachment';
+
+	// Update the thumbnail filename
+	$newmeta = wp_get_attachment_metadata( $page_id, true );
+	$newmeta['thumb'] = $_POST['thumb'];
+
+	wp_update_attachment_metadata( $newmeta );
+
+case 'editpost':
+	$page_ID = (int) $_POST['post_ID'];
+	check_admin_referer('update-page_' . $page_ID);
+
+	$page_ID = edit_post();
+
+	if ( 'post' == $_POST['originalaction'] ) {
+		if (!empty($_POST['mode'])) {
+		switch($_POST['mode']) {
+			case 'bookmarklet':
+				$location = $_POST['referredby'];
+				break;
+			case 'sidebar':
+				$location = 'sidebar.php?a=b';
+				break;
+			default:
+				$location = 'page-new.php';
+				break;
+			}
+		} else {
+			$location = "page-new.php?posted=$page_ID";
+		}
+
+		if ( isset($_POST['save']) )
+			$location = "page.php?action=edit&post=$page_ID";
+	} else {
+		if ($_POST['save']) {
+			$location = "page.php?action=edit&post=$page_ID";
+		} elseif ($_POST['updatemeta']) {
+			$location = wp_get_referer() . '&message=2#postcustom';
+		} elseif ($_POST['deletemeta']) {
+			$location = wp_get_referer() . '&message=3#postcustom';
+		} elseif (!empty($_POST['referredby']) && $_POST['referredby'] != wp_get_referer()) {
+			$location = $_POST['referredby'];
+			if ( $_POST['referredby'] == 'redo' )
+				$location = get_permalink( $page_ID );
+		} elseif ($action == 'editattachment') {
+			$location = 'attachments.php';
+		} else {
+			$location = 'page-new.php';
+		}
+	}
+	wp_redirect($location); // Send user on their way while we keep working
+
+	exit();
+	break;
+
+case 'delete':
+	$page_id = (isset($_GET['post']))  ? intval($_GET['post']) : intval($_POST['post_ID']);
+	check_admin_referer('delete-page_' .  $page_id);
+
+	$page = & get_post($page_id);
+
+	if ( !current_user_can('delete_page', $page_id) )
+		wp_die( __('You are not allowed to delete this page.') );
+
+	if ( $page->post_type == 'attachment' ) {
+		if ( ! wp_delete_attachment($page_id) )
+			wp_die( __('Error in deleting...') );
+	} else {
+		if ( !wp_delete_post($page_id) ) 
+			wp_die( __('Error in deleting...') );
+	}
+
+	$sendback = wp_get_referer();
+	if (strpos($sendback, 'page.php') !== false) $sendback = get_option('siteurl') .'/wp-admin/page.php';
+	elseif (strpos($sendback, 'attachments.php') !== false) $sendback = get_option('siteurl') .'/wp-admin/attachments.php';
+	$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
+	wp_redirect($sendback);
+	exit();
+	break;
+
+default:
+	wp_redirect('edit-pages.php');
+	exit();
+	break;
+} // end switch
+include('admin-footer.php');
+?>
diff -ruN 2.0.5/wp-admin/plugin-editor.php 2.2.2/wp-admin/plugin-editor.php
--- 2.0.5/wp-admin/plugin-editor.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/plugin-editor.php	2007-02-14 00:15:05.000000000 -0600
@@ -4,21 +4,7 @@
 $title = __("Edit Plugins");
 $parent_file = 'plugins.php';
 
-$wpvarstoreset = array('action','redirect','profile','error','warning','a','file');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'redirect', 'profile', 'error', 'warning', 'a', 'file'));
 
 $plugins = get_plugins();
 $plugin_files = array_keys($plugins);
@@ -28,7 +14,7 @@
 }
 
 $file = validate_file_to_edit($file, $plugin_files);
-$real_file = get_real_file_to_edit("wp-content/plugins/$file");
+$real_file = get_real_file_to_edit( PLUGINDIR . "/$file");
 
 switch($action) {
 
@@ -37,13 +23,24 @@
 	check_admin_referer('edit-plugin_' . $file);
 
 	if ( !current_user_can('edit_plugins') )
-	die('<p>'.__('You have do not have sufficient permissions to edit templates for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this blog.').'</p>');
 
 	$newcontent = stripslashes($_POST['newcontent']);
 	if (is_writeable($real_file)) {
 		$f = fopen($real_file, 'w+');
 		fwrite($f, $newcontent);
 		fclose($f);
+
+		// Deactivate so we can test it.
+		$current = get_option('active_plugins');
+		if ( in_array($file, $current) || isset($_POST['phperror']) ) {
+			if ( in_array($file, $current) ) {
+				array_splice($current, array_search( $file, $current), 1 ); // Array-fu!
+				update_option('active_plugins', $current);
+			}
+			wp_redirect(add_query_arg('_wpnonce', wp_create_nonce('edit-plugin-test_' . $file), "plugin-editor.php?file=$file&liveupdate=1"));
+			exit();
+		}
 		wp_redirect("plugin-editor.php?file=$file&a=te");
 	} else {
 		wp_redirect("plugin-editor.php?file=$file");
@@ -54,16 +51,35 @@
 break;
 
 default:
-	
-	require_once('admin-header.php');
+
 	if ( !current_user_can('edit_plugins') )
-	die('<p>'.__('You have do not have sufficient permissions to edit plugins for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit plugins for this blog.').'</p>');
+
+	if ( $_GET['liveupdate'] ) {
+		check_admin_referer('edit-plugin-test_' . $file);
+		$current = get_option('active_plugins');
+		$plugin = $file;
+		if ( validate_file($plugin) )
+			wp_die(__('Invalid plugin.'));
+		if ( ! file_exists(ABSPATH . PLUGINDIR . '/' . $plugin) )
+			wp_die(__('Plugin file does not exist.'));
+		if (!in_array($plugin, $current)) {
+			wp_redirect("plugin-editor.php?file=$file&phperror=1"); // we'll override this later if the plugin can be included without fatal error
+			@include(ABSPATH . PLUGINDIR . '/' . $plugin);
+			$current[] = $plugin;
+			sort($current);
+			update_option('active_plugins', $current);
+		}
+		wp_redirect("plugin-editor.php?file=$file&a=te");
+	}
+
+	require_once('admin-header.php');
+
+	update_recently_edited(PLUGINDIR . "/$file");
 
-	update_recently_edited("wp-content/plugins/$file");
-	
 	if (!is_file($real_file))
 		$error = 1;
-	
+
 	if (!$error) {
 		$f = fopen($real_file, 'r');
 		$content = fread($f, filesize($real_file));
@@ -73,13 +89,23 @@
 	?>
 <?php if (isset($_GET['a'])) : ?>
  <div id="message" class="updated fade"><p><?php _e('File edited successfully.') ?></p></div>
+<?php elseif (isset($_GET['phperror'])) : ?>
+ <div id="message" class="updated fade"><p><?php _e('This plugin has been deactivated because your changes resulted in a <strong>fatal error</strong>.') ?></p></div>
 <?php endif; ?>
- <div class="wrap"> 
-  <?php
-	if (is_writeable($real_file)) {
-		echo '<h2>' . sprintf(__('Editing <strong>%s</strong>'), $file) . '</h2>';
+ <div class="wrap">
+	<?php
+	if ( in_array($file, (array) get_option('active_plugins')) ) {
+		if (is_writeable($real_file)) {
+			echo '<h2>' . sprintf(__('Editing <strong>%s</strong> (active)'), $file) . '</h2>';
+		} else {
+		echo '<h2>' . sprintf(__('Browsing <strong>%s</strong> (active)'), $file) . '</h2>';
+		}
 	} else {
-		echo '<h2>' . sprintf(__('Browsing <strong>%s</strong>'), $file) . '</h2>';
+		if (is_writeable($real_file)) {
+			echo '<h2>' . sprintf(__('Editing <strong>%s</strong> (inactive)'), $file) . '</h2>';
+		} else {
+		echo '<h2>' . sprintf(__('Browsing <strong>%s</strong> (inactive)'), $file) . '</h2>';
+		}
 	}
 	?>
 	<div id="templateside">
@@ -88,39 +114,45 @@
 <?php
 if ($plugin_files) :
 ?>
-  <ul>
-<?php foreach($plugin_files as $plugin_file) : ?>
+	<ul>
+	<?php foreach($plugin_files as $plugin_file) : ?>
 		 <li><a href="plugin-editor.php?file=<?php echo "$plugin_file"; ?>"><?php echo $plugins[$plugin_file]['Name']; ?></a></li>
-<?php endforeach; ?>
-  </ul>
+	<?php endforeach; ?>
+	</ul>
 <?php endif; ?>
 </div>
-	<?php	if (!$error) { ?> 
-  <form name="template" id="template" action="plugin-editor.php" method="post">
-  <?php wp_nonce_field('edit-plugin_' . $file) ?>
-		 <div><textarea cols="70" rows="25" name="newcontent" id="newcontent" tabindex="1"><?php echo $content ?></textarea> 
-     <input type="hidden" name="action" value="update" /> 
-     <input type="hidden" name="file" value="<?php echo $file ?>" /> 
+<?php	if (!$error) { ?>
+	<form name="template" id="template" action="plugin-editor.php" method="post">
+	<?php wp_nonce_field('edit-plugin_' . $file) ?>
+		<div><textarea cols="70" rows="25" name="newcontent" id="newcontent" tabindex="1"><?php echo $content ?></textarea>
+		<input type="hidden" name="action" value="update" />
+		<input type="hidden" name="file" value="<?php echo $file ?>" />
 		</div>
 <?php if ( is_writeable($real_file) ) : ?>
-     <p class="submit">
-<?php
-	echo "<input type='submit' name='submit' value='	" . __('Update File') . " &raquo;' tabindex='2' />";
-?>
-</p>
+	<?php if ( in_array($file, (array) get_option('active_plugins')) ) { ?>
+		<p><?php _e('<strong>Warning:</strong> Making changes to active plugins is not recommended.  If your changes cause a fatal error, the plugin will be automatically deactivated.'); ?></p>
+	<?php } ?>
+	<p class="submit">
+	<?php
+		if ( isset($_GET['phperror']) )
+			echo "<input type='hidden' name='phperror' value='1' /><input type='submit' name='submit' value='" . __('Update File and Attempt to Reactivate &raquo;') . "' tabindex='2' />";
+		else
+			echo "<input type='submit' name='submit' value='" . __('Update File &raquo;') . "' tabindex='2' />";
+	?>
+	</p>
 <?php else : ?>
-<p><em><?php _e('If this file were writable you could edit it.'); ?></em></p>
+	<p><em><?php _e('If this file were writable you could edit it.'); ?></em></p>
 <?php endif; ?>
-   </form> 
-  <?php
+ </form>
+<?php
 	} else {
 		echo '<div class="error"><p>' . __('Oops, no such file exists! Double check the name and try again, merci.') . '</p></div>';
 	}
-	?>
+?>
 <div class="clear"> &nbsp; </div>
-</div> 
+</div>
 <?php
 break;
 }
 
-include("admin-footer.php") ?> 
+include("admin-footer.php") ?>
diff -ruN 2.0.5/wp-admin/plugins.php 2.2.2/wp-admin/plugins.php
--- 2.0.5/wp-admin/plugins.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/plugins.php	2007-04-10 22:23:23.000000000 -0500
@@ -4,22 +4,41 @@
 if ( isset($_GET['action']) ) {
 	if ('activate' == $_GET['action']) {
 		check_admin_referer('activate-plugin_' . $_GET['plugin']);
-		$current = get_settings('active_plugins');
-		if (!in_array($_GET['plugin'], $current)) {
-			$current[] = trim( $_GET['plugin'] );
+		$current = get_option('active_plugins');
+		$plugin = trim($_GET['plugin']);
+		if ( validate_file($plugin) )
+			wp_die(__('Invalid plugin.'));
+		if ( ! file_exists(ABSPATH . PLUGINDIR . '/' . $plugin) )
+			wp_die(__('Plugin file does not exist.'));
+		if (!in_array($plugin, $current)) {
+			wp_redirect('plugins.php?error=true'); // we'll override this later if the plugin can be included without fatal error
+			ob_start();
+			@include(ABSPATH . PLUGINDIR . '/' . $plugin);
+			$current[] = $plugin;
 			sort($current);
 			update_option('active_plugins', $current);
-			include(ABSPATH . 'wp-content/plugins/' . trim( $_GET['plugin'] ));
-			do_action('activate_' . trim( $_GET['plugin'] ));
+			do_action('activate_' . $plugin);
+			ob_end_clean();
 		}
-		wp_redirect('plugins.php?activate=true');
+		wp_redirect('plugins.php?activate=true'); // overrides the ?error=true one above
 	} else if ('deactivate' == $_GET['action']) {
 		check_admin_referer('deactivate-plugin_' . $_GET['plugin']);
-		$current = get_settings('active_plugins');
+		$current = get_option('active_plugins');
 		array_splice($current, array_search( $_GET['plugin'], $current), 1 ); // Array-fu!
 		update_option('active_plugins', $current);
 		do_action('deactivate_' . trim( $_GET['plugin'] ));
 		wp_redirect('plugins.php?deactivate=true');
+	} elseif ($_GET['action'] == 'deactivate-all') {
+		check_admin_referer('deactivate-all');
+		$current = get_option('active_plugins');
+		
+		foreach ($current as $plugin) {
+			array_splice($current, array_search($plugin, $current), 1);
+			do_action('deactivate_' . $plugin);
+		}
+		
+		update_option('active_plugins', array());
+		wp_redirect('plugins.php?deactivate-all=true');
 	}
 	exit;
 }
@@ -30,20 +49,20 @@
 // Clean up options
 // If any plugins don't exist, axe 'em
 
-$check_plugins = get_settings('active_plugins');
+$check_plugins = get_option('active_plugins');
 
 // Sanity check.  If the active plugin list is not an array, make it an
 // empty array.
 if ( !is_array($check_plugins) ) {
 	$check_plugins = array();
-	update_option('active_plugins', $check_plugins);	
+	update_option('active_plugins', $check_plugins);
 }
 
 // If a plugin file does not exist, remove it from the list of active
 // plugins.
 foreach ($check_plugins as $check_plugin) {
-	if (!file_exists(ABSPATH . 'wp-content/plugins/' . $check_plugin)) {
-			$current = get_settings('active_plugins');
+	if (!file_exists(ABSPATH . PLUGINDIR . '/' . $check_plugin)) {
+			$current = get_option('active_plugins');
 			$key = array_search($check_plugin, $current);
 			if ( false !== $key && NULL !== $key ) {
 				unset($current[$key]);
@@ -53,13 +72,14 @@
 }
 ?>
 
-<?php if (isset($_GET['activate'])) : ?>
-<div id="message" class="updated fade"><p><?php _e('Plugin <strong>activated</strong>.') ?></p>
-</div>
-<?php endif; ?>
-<?php if (isset($_GET['deactivate'])) : ?>
-<div id="message" class="updated fade"><p><?php _e('Plugin <strong>deactivated</strong>.') ?></p>
-</div>
+<?php if ( isset($_GET['error']) ) : ?>
+	<div id="message" class="updated fade"><p><?php _e('Plugin could not be activated because it triggered a <strong>fatal error</strong>.') ?></p></div>
+<?php elseif ( isset($_GET['activate']) ) : ?>
+	<div id="message" class="updated fade"><p><?php _e('Plugin <strong>activated</strong>.') ?></p></div>
+<?php elseif ( isset($_GET['deactivate']) ) : ?>
+	<div id="message" class="updated fade"><p><?php _e('Plugin <strong>deactivated</strong>.') ?></p></div>
+<?php elseif (isset($_GET['deactivate-all'])) : ?>
+	<div id="message" class="updated fade"><p><?php _e('All plugins <strong>deactivated</strong>.'); ?></p></div>
 <?php endif; ?>
 
 <div class="wrap">
@@ -67,24 +87,26 @@
 <p><?php _e('Plugins extend and expand the functionality of WordPress. Once a plugin is installed, you may activate it or deactivate it here.'); ?></p>
 <?php
 
-if ( get_settings('active_plugins') )
-	$current_plugins = get_settings('active_plugins');
+if ( get_option('active_plugins') )
+	$current_plugins = get_option('active_plugins');
 
 $plugins = get_plugins();
 
 if (empty($plugins)) {
 	echo '<p>';
-	_e("Couldn't open plugins directory or there are no plugins available."); // TODO: make more helpful
+	_e("Couldn&#8217;t open plugins directory or there are no plugins available."); // TODO: make more helpful
 	echo '</p>';
 } else {
 ?>
-<table width="100%" cellpadding="3" cellspacing="3">
+<table class="widefat plugins">
+	<thead>
 	<tr>
 		<th><?php _e('Plugin'); ?></th>
-		<th><?php _e('Version'); ?></th>
+		<th style="text-align: center"><?php _e('Version'); ?></th>
 		<th><?php _e('Description'); ?></th>
-		<th><?php _e('Action'); ?></th>
+		<th style="text-align: center"<?php if ( current_user_can('edit_plugins') ) echo ' colspan="2"'; ?>><?php _e('Action'); ?></th>
 	</tr>
+	</thead>
 <?php
 	$style = '';
 
@@ -92,33 +114,57 @@
 		$style = ('class="alternate"' == $style|| 'class="alternate active"' == $style) ? '' : 'alternate';
 
 		if (!empty($current_plugins) && in_array($plugin_file, $current_plugins)) {
-			$action = "<a href='" . wp_nonce_url("plugins.php?action=deactivate&amp;plugin=$plugin_file", 'deactivate-plugin_' . $plugin_file) . "' title='".__('Deactivate this plugin')."' class='delete'>".__('Deactivate')."</a>";
+			$toggle = "<a href='" . wp_nonce_url("plugins.php?action=deactivate&amp;plugin=$plugin_file", 'deactivate-plugin_' . $plugin_file) . "' title='".__('Deactivate this plugin')."' class='delete'>".__('Deactivate')."</a>";
 			$plugin_data['Title'] = "<strong>{$plugin_data['Title']}</strong>";
 			$style .= $style == 'alternate' ? ' active' : 'active';
 		} else {
-			$action = "<a href='" . wp_nonce_url("plugins.php?action=activate&amp;plugin=$plugin_file", 'activate-plugin_' . $plugin_file) . "' title='".__('Activate this plugin')."' class='edit'>".__('Activate')."</a>";
+			$toggle = "<a href='" . wp_nonce_url("plugins.php?action=activate&amp;plugin=$plugin_file", 'activate-plugin_' . $plugin_file) . "' title='".__('Activate this plugin')."' class='edit'>".__('Activate')."</a>";
 		}
-		$plugin_data['Description'] = wp_kses($plugin_data['Description'], array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array()) ); ;
-		if ($style != '') $style = 'class="' . $style . '"';
+
+		$plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
+
+		// Sanitize all displayed data
+		$plugin_data['Title']       = wp_kses($plugin_data['Title'], $plugins_allowedtags);
+		$plugin_data['Version']     = wp_kses($plugin_data['Version'], $plugins_allowedtags);
+		$plugin_data['Description'] = wp_kses($plugin_data['Description'], $plugins_allowedtags);
+		$plugin_data['Author']      = wp_kses($plugin_data['Author'], $plugins_allowedtags);
+
+		if ( $style != '' )
+			$style = 'class="' . $style . '"';
+		if ( is_writable(ABSPATH . PLUGINDIR . '/' . $plugin_file) )
+			$edit = "<a href='plugin-editor.php?file=$plugin_file' title='".__('Open this file in the Plugin Editor')."' class='edit'>".__('Edit')."</a>";
+		else
+			$edit = '';
+
 		echo "
 	<tr $style>
 		<td class='name'>{$plugin_data['Title']}</td>
 		<td class='vers'>{$plugin_data['Version']}</td>
-		<td class='desc'>{$plugin_data['Description']} <cite>".sprintf(__('By %s'), $plugin_data['Author']).".</cite></td>
-		<td class='togl'>$action</td>
+		<td class='desc'><p>{$plugin_data['Description']} <cite>".sprintf(__('By %s'), $plugin_data['Author']).".</cite></p></td>
+		<td class='togl'>$toggle</td>";
+		if ( current_user_can('edit_plugins') )
+		echo "
+		<td>$edit</td>";
+		echo"
 	</tr>";
 	}
 ?>
 
+<tr>
+	<td colspan="3">&nbsp;</td>
+	<td colspan="2" style="width:12em;"><a href="<?php echo wp_nonce_url('plugins.php?action=deactivate-all', 'deactivate-all'); ?>" class="delete"><?php _e('Deactivate All Plugins'); ?></a></td>
+</tr>
+
 </table>
 <?php
 }
 ?>
 
-<p><?php _e('If something goes wrong with a plugin and you can&#8217;t use WordPress, delete or rename that file in the <code>wp-content/plugins</code> directory and it will be automatically deactivated.'); ?></p>
+<p><?php printf(__('If something goes wrong with a plugin and you can&#8217;t use WordPress, delete or rename that file in the <code>%s</code> directory and it will be automatically deactivated.'), PLUGINDIR); ?></p>
 
 <h2><?php _e('Get More Plugins'); ?></h2>
-<p><?php _e('You can find additional plugins for your site in the <a href="http://wordpress.org/extend/plugins/">WordPress plugin directory</a>. To install a plugin you generally just need to upload the plugin file into your <code>wp-content/plugins</code> directory. Once a plugin is uploaded, you may activate it here.'); ?></p>
+<p><?php _e('You can find additional plugins for your site in the <a href="http://wordpress.org/extend/plugins/">WordPress plugin directory</a>.'); ?></p>
+<p><?php printf(__('To install a plugin you generally just need to upload the plugin file into your <code>%s</code> directory. Once a plugin is uploaded, you may activate it here.'), PLUGINDIR); ?></p>
 
 </div>
 
diff -ruN 2.0.5/wp-admin/post-new.php 2.2.2/wp-admin/post-new.php
--- 2.0.5/wp-admin/post-new.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/post-new.php	2007-02-22 09:30:47.000000000 -0600
@@ -0,0 +1,97 @@
+<?php
+require_once('admin.php');
+$title = __('Create New Post');
+$parent_file = 'post-new.php';
+$editing = true;
+wp_enqueue_script('prototype');
+wp_enqueue_script('interface');
+wp_enqueue_script('autosave');
+require_once ('./admin-header.php');
+
+if ( ! current_user_can('edit_posts') ) { ?>
+<div class="wrap">
+<p><?php printf(__('Since you&#8217;re a newcomer, you&#8217;ll have to wait for an admin to raise your level to 1, in order to be authorized to post.<br />
+You can also <a href="mailto:%s?subject=Promotion?">e-mail the admin</a> to ask for a promotion.<br />
+When you&#8217;re promoted, just reload this page and you&#8217;ll be able to blog. :)'), get_option('admin_email')); ?>
+</p>
+</div>
+<?php
+	include('admin-footer.php');
+	exit();
+}
+
+if ( isset($_GET['posted']) && $_GET['posted'] ) : ?>
+<div id="message" class="updated fade"><p><strong><?php _e('Post saved.'); ?></strong> <a href="<?php echo get_permalink( $_GET['posted'] ); ?>"><?php _e('View post'); ?> &raquo;</a></p></div>
+<?php
+endif;
+
+if ( $drafts = get_users_drafts( $user_ID ) ) { ?>
+<div class="wrap">
+<p><strong><?php _e('Your Drafts:') ?></strong>
+<?php
+// Show drafts.
+	$num_drafts = count($drafts);
+	if ( $num_drafts > 15 ) $num_drafts = 15;
+	for ( $i = 0; $i < $num_drafts; $i++ ) {
+		$draft = $drafts[$i];
+		if ( 0 != $i )
+			echo ', ';
+		if ( empty($draft->post_title) )
+			$draft->post_title = sprintf(__('Post # %s'), $draft->ID);
+		echo "<a href='post.php?action=edit&amp;post=$draft->ID' title='" . __('Edit this draft') . "'>$draft->post_title</a>";
+	}
+
+	if ( 15 < count($drafts) ) { ?>
+		, <a href="edit.php"><?php echo sprintf(__('and %s more'), (count($drafts) - 15) ); ?> &raquo;</a>
+	<?php } ?>
+.</p>
+</div>
+<?php
+}
+
+// Show post form.
+$post = get_default_post_to_edit();
+include('edit-form-advanced.php');
+?>
+
+<?php if ( $is_NS4 || $is_gecko || $is_winIE ) { ?>
+<div id="wp-bookmarklet" class="wrap">
+<h3><?php _e('WordPress Bookmarklet'); ?></h3>
+<p><?php _e('Right click on the following link and choose "Add to favorites" to create a posting shortcut.'); ?></p>
+<p>
+
+<?php
+if ($is_NS4 || $is_gecko) {
+?>
+<a href="javascript:if(navigator.userAgent.indexOf('Safari') >= 0){Q=getSelection();}else{Q=document.selection?document.selection.createRange().text:document.getSelection();}location.href='<?php echo get_option('siteurl') ?>/wp-admin/post-new.php?text='+encodeURIComponent(Q)+'&amp;popupurl='+encodeURIComponent(location.href)+'&amp;popuptitle='+encodeURIComponent(document.title);"><?php printf(__('Press It - %s'), wp_specialchars(get_option('blogname'))); ?></a> 
+<?php
+} else if ($is_winIE) {
+?>
+<a href="javascript:Q='';if(top.frames.length==0)Q=document.selection.createRange().text;location.href='<?php echo get_option('siteurl') ?>/wp-admin/post-new.php?text='+encodeURIComponent(Q)+'&amp;popupurl='+encodeURIComponent(location.href)+'&amp;popuptitle='+encodeURIComponent(document.title);"><?php printf(__('Press it - %s'), get_option('blogname')); ?></a>
+<script type="text/javascript">
+<!--
+function oneclickbookmarklet(blah) {
+window.open ("profile.php?action=IErightclick", "oneclickbookmarklet", "width=500, height=450, location=0, menubar=0, resizable=0, scrollbars=1, status=1, titlebar=0, toolbar=0, screenX=120, left=120, screenY=120, top=120");
+}
+// -->
+</script>
+<br />
+<br />
+<?php _e('One-click bookmarklet:') ?><br />
+<a href="javascript:oneclickbookmarklet(0);"><?php _e('click here') ?></a> 
+<?php
+} else if ($is_opera) {
+?>
+<a href="javascript:location.href='<?php echo get_option('siteurl'); ?>/wp-admin/post-new.php?popupurl='+escape(location.href)+'&popuptitle='+escape(document.title);"><?php printf(__('Press it - %s'), get_option('blogname')); ?></a> 
+<?php
+} else if ($is_macIE) {
+?>
+<a href="javascript:Q='';location.href='<?php echo get_option('siteurl'); ?>/wp-admin/bookmarklet.php?text='+escape(document.getSelection())+'&popupurl='+escape(location.href)+'&popuptitle='+escape(document.title);"><?php printf(__('Press it - %s'), get_option('blogname')); ?></a> 
+<?php
+}
+?>
+</p>
+</div>
+<?php } ?>
+
+<?php include('admin-footer.php'); ?>
diff -ruN 2.0.5/wp-admin/post.php 2.2.2/wp-admin/post.php
--- 2.0.5/wp-admin/post.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/post.php	2007-03-31 17:02:19.000000000 -0500
@@ -1,38 +1,22 @@
 <?php
 require_once('admin.php');
 
-$wpvarstoreset = array('action', 'safe_mode', 'withcomments', 'posts', 'content', 'edited_post_title', 'comment_error', 'profile', 'trackback_url', 'excerpt', 'showcomments', 'commentstart', 'commentend', 'commentorder' );
+$parent_file = 'edit.php';
+$submenu_file = 'edit.php';
 
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-			$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'safe_mode', 'withcomments', 'posts', 'content', 'edited_post_title', 'comment_error', 'profile', 'trackback_url', 'excerpt', 'showcomments', 'commentstart', 'commentend', 'commentorder'));
 
-if (isset($_POST['deletepost'])) {
-$action = "delete";
-}
-
-// Fix submenu highlighting for pages.
-if ( isset($_REQUEST['post']) && 'static' == get_post_status($_REQUEST['post']) )
-	$submenu_file = 'page-new.php';
-
-$editing = true;
+if ( isset( $_POST['deletepost'] ) )
+	$action = 'delete';
 
 switch($action) {
+case 'postajaxpost':
 case 'post':
+	$parent_file = 'post-new.php';
+	$submenu_file = 'post-new.php';
 	check_admin_referer('add-post');
-	
-	$post_ID = write_post();
+
+	$post_ID = 'post' == $action ? write_post() : edit_post();
 
 	// Redirect.
 	if (!empty($_POST['mode'])) {
@@ -44,16 +28,13 @@
 			$location = 'sidebar.php?a=b';
 			break;
 		default:
-			$location = 'post.php';
+			$location = 'post-new.php';
 			break;
 		}
 	} else {
-		$location = "post.php?posted=$post_ID";
+		$location = "post-new.php?posted=$post_ID";
 	}
 
-	if ( 'static' == $_POST['post_status'] )
-		$location = "page-new.php?saved=$post_ID";
-
 	if ( isset($_POST['save']) )
 		$location = "post.php?action=edit&post=$post_ID";
 
@@ -63,27 +44,28 @@
 
 case 'edit':
 	$title = __('Edit');
+	$editing = true;
+	$post_ID = $p = (int) $_GET['post'];
+	$post = get_post($post_ID);
 
-	require_once('admin-header.php');
+	if ( 'page' == $post->post_type ) {
+		wp_redirect("page.php?action=edit&post=$post_ID");
+		exit();
+	}
 
-	$post_ID = $p = (int) $_GET['post'];
+	if($post->post_status == 'draft') {
+		wp_enqueue_script('prototype');
+		wp_enqueue_script('autosave');
+	}
+	require_once('admin-header.php');
 
 	if ( !current_user_can('edit_post', $post_ID) )
 		die ( __('You are not allowed to edit this post.') );
 
 	$post = get_post_to_edit($post_ID);
-	
-	if ($post->post_status == 'static')
-		include('edit-page-form.php');
-	else
-		include('edit-form-advanced.php');
-
-	?>
-	<div id='preview' class='wrap'>
-	<h2 id="preview-post"><?php _e('Post Preview (updated when post is saved)'); ?> <small class="quickjump"><a href="#write-post"><?php _e('edit &uarr;'); ?></a></small></h2>
-		<iframe src="<?php echo wp_specialchars(apply_filters('preview_post_link', add_query_arg('preview', 'true', get_permalink($post->ID)))); ?>" width="100%" height="600" ></iframe>
-	</div>
-	<?php
+
+	include('edit-form-advanced.php');
+
 	break;
 
 case 'editattachment':
@@ -93,42 +75,60 @@
 
 	// Don't let these be changed
 	unset($_POST['guid']);
-	$_POST['post_status'] = 'attachment';
+	$_POST['post_type'] = 'attachment';
 
 	// Update the thumbnail filename
-	$oldmeta = $newmeta = get_post_meta($post_id, '_wp_attachment_metadata', true);
+	$newmeta = wp_get_attachment_metadata( $post_id, true );
 	$newmeta['thumb'] = $_POST['thumb'];
 
-	if ( '' !== $oldmeta )
-		update_post_meta($post_id, '_wp_attachment_metadata', $newmeta, $oldmeta);
-	else
-		add_post_meta($post_id, '_wp_attachment_metadata', $newmeta);
+	wp_update_attachment_metadata( $post_id, $newmeta );
 
 case 'editpost':
 	$post_ID = (int) $_POST['post_ID'];
 	check_admin_referer('update-post_' . $post_ID);
-	
+
 	$post_ID = edit_post();
 
-	$referredby = '';
-	if ( !empty($_POST['referredby']) )
-		$referredby = preg_replace('|https?://[^/]+|i', '', $_POST['referredby']);
-	$referer = preg_replace('|https?://[^/]+|i', '', wp_get_referer());
-	
-	if ($_POST['save']) {
-		$location = wp_get_referer();
-	} elseif ($_POST['updatemeta']) {
-		$location = wp_get_referer() . '&message=2#postcustom';
-	} elseif ($_POST['deletemeta']) {
-		$location = wp_get_referer() . '&message=3#postcustom';
-	} elseif (!empty($referredby) && $referredby != $referer) {
-		$location = $_POST['referredby'];
-		if ( $_POST['referredby'] == 'redo' )
-			$location = get_permalink( $post_ID );
-	} elseif ($action == 'editattachment') {
-		$location = 'attachments.php';
+	if ( 'post' == $_POST['originalaction'] ) {
+		if (!empty($_POST['mode'])) {
+		switch($_POST['mode']) {
+			case 'bookmarklet':
+				$location = $_POST['referredby'];
+				break;
+			case 'sidebar':
+				$location = 'sidebar.php?a=b';
+				break;
+			default:
+				$location = 'post-new.php';
+				break;
+			}
+		} else {
+			$location = "post-new.php?posted=$post_ID";
+		}
+
+		if ( isset($_POST['save']) )
+			$location = "post.php?action=edit&post=$post_ID";
 	} else {
-		$location = 'post.php';
+		$referredby = '';
+		if ( !empty($_POST['referredby']) )
+			$referredby = preg_replace('|https?://[^/]+|i', '', $_POST['referredby']);
+		$referer = preg_replace('|https?://[^/]+|i', '', wp_get_referer());
+
+		if ($_POST['save']) {
+			$location = "post.php?action=edit&post=$post_ID";
+		} elseif ($_POST['updatemeta']) {
+			$location = wp_get_referer() . '&message=2#postcustom';
+		} elseif ($_POST['deletemeta']) {
+			$location = wp_get_referer() . '&message=3#postcustom';
+		} elseif (!empty($referredby) && $referredby != $referer) {
+			$location = $_POST['referredby'];
+			if ( $_POST['referredby'] == 'redo' )
+				$location = get_permalink( $post_ID );
+		} elseif ($action == 'editattachment') {
+			$location = 'attachments.php';
+		} else {
+			$location = 'post-new.php';
+		}
 	}
 
 	wp_redirect($location); // Send user on their way while we keep working
@@ -141,297 +141,30 @@
 	check_admin_referer('delete-post_' . $post_id);
 
 	$post = & get_post($post_id);
-	
-	if ( !current_user_can('edit_post', $post_id) )	
-		die( __('You are not allowed to delete this post.') );
 
-	if ( $post->post_status == 'attachment' ) {
+	if ( !current_user_can('delete_post', $post_id) )
+		wp_die( __('You are not allowed to delete this post.') );
+
+	if ( $post->post_type == 'attachment' ) {
 		if ( ! wp_delete_attachment($post_id) )
-			die( __('Error in deleting...') );
+			wp_die( __('Error in deleting...') );
 	} else {
 		if ( !wp_delete_post($post_id) ) 
-			die( __('Error in deleting...') );
+			wp_die( __('Error in deleting...') );
 	}
 
 	$sendback = wp_get_referer();
-	if (strstr($sendback, 'post.php')) $sendback = get_settings('siteurl') .'/wp-admin/post.php';
-	elseif (strstr($sendback, 'attachments.php')) $sendback = get_settings('siteurl') .'/wp-admin/attachments.php';
+	if (strpos($sendback, 'post.php') !== false) $sendback = get_option('siteurl') .'/wp-admin/post-new.php';
+	elseif (strpos($sendback, 'attachments.php') !== false) $sendback = get_option('siteurl') .'/wp-admin/attachments.php';
 	$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
 	wp_redirect($sendback);
-	break;
-
-case 'editcomment':
-	$title = __('Edit Comment');
-	$parent_file = 'edit.php';
-	require_once ('admin-header.php');
-
-	get_currentuserinfo();
-
-	$comment = (int) $_GET['comment'];
-
-	if ( ! $comment = get_comment($comment) )
-		die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'javascript:history.go(-1)'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to edit comments on this post.') );
-
-	$comment = get_comment_to_edit($comment);
-
-	include('edit-form-comment.php');
-
-	break;
-
-case 'confirmdeletecomment':
-
-	require_once('./admin-header.php');
-
-	$comment = (int) $_GET['comment'];
-	$p = (int) $_GET['p'];
-
-	if ( ! $comment = get_comment($comment) )
-		die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'edit.php'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to delete comments on this post.') );
-
-	echo "<div class='wrap'>\n";
-	echo "<p>" . __('<strong>Caution:</strong> You are about to delete the following comment:') . "</p>\n";
-	echo "<table border='0'>\n";
-	echo "<tr><td>" . __('Author:') . "</td><td>$comment->comment_author</td></tr>\n";
-	echo "<tr><td>" . __('E-mail:') . "</td><td>$comment->comment_author_email</td></tr>\n";
-	echo "<tr><td>". __('URL:') . "</td><td>$comment->comment_author_url</td></tr>\n";
-	echo "<tr><td>". __('Comment:') . "</td><td>$comment->comment_content</td></tr>\n";
-	echo "</table>\n";
-	echo "<p>" . __('Are you sure you want to do that?') . "</p>\n";
-
-	echo "<form action='".get_settings('siteurl')."/wp-admin/post.php' method='get'>\n";
-	echo "<input type='hidden' name='action' value='deletecomment' />\n";
-	echo "<input type='hidden' name='p' value='$p' />\n";
-	echo "<input type='hidden' name='comment' value='{$comment->comment_ID}' />\n";
-	echo "<input type='hidden' name='noredir' value='1' />\n";
-	wp_nonce_field('delete-comment_' .  $comment->comment_ID);
-	echo "<input type='submit' value='" . __('Yes') . "' />";
-	echo "&nbsp;&nbsp;";
-	echo "<input type='button' value='" . __('No') . "' onclick=\"self.location='". get_settings('siteurl') ."/wp-admin/edit.php?p=$p&amp;c=1#comments';\" />\n";
-	echo "</form>\n";
-	echo "</div>\n";
-
-	break;
-
-case 'deletecomment':
-	$comment = (int) $_GET['comment'];
-	check_admin_referer('delete-comment_' . $comment);
-
-	$p = (int) $_GET['p'];
-	if (isset($_GET['noredir'])) {
-		$noredir = true;
-	} else {
-		$noredir = false;
-	}
-
-	$postdata = get_post($p) or die(sprintf(__('Oops, no post with this ID. <a href="%s">Go back</a>!'), 'edit.php'));
-
-	if ( ! $comment = get_comment($comment) )
-			 die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'post.php'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to edit comments on this post.') );
-
-	wp_set_comment_status($comment->comment_ID, "delete");
-	do_action('delete_comment', $comment->comment_ID);
-
-	if ((wp_get_referer() != "") && (false == $noredir)) {
-		wp_redirect(wp_get_referer());
-	} else {
-		wp_redirect(get_settings('siteurl') .'/wp-admin/edit.php?p='.$p.'&c=1#comments');
-	}
-
-	break;
-
-case 'unapprovecomment':
-	$comment = (int) $_GET['comment'];
-	check_admin_referer('unapprove-comment_' . $comment);
-
-	$p = (int) $_GET['p'];
-	if (isset($_GET['noredir'])) {
-		$noredir = true;
-	} else {
-		$noredir = false;
-	}
-
-	if ( ! $comment = get_comment($comment) )
-		die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'edit.php'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to edit comments on this post, so you cannot disapprove this comment.') );
-
-	wp_set_comment_status($comment->comment_ID, "hold");
-
-	if ((wp_get_referer() != "") && (false == $noredir)) {
-		wp_redirect(wp_get_referer());
-	} else {
-		wp_redirect(get_settings('siteurl') .'/wp-admin/edit.php?p='.$p.'&c=1#comments');
-	}
-
-	break;
-
-case 'mailapprovecomment':
-	$comment = (int) $_GET['comment'];
-	check_admin_referer('approve-comment_' . $comment);
-
-	if ( ! $comment = get_comment($comment) )
-			 die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'edit.php'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to edit comments on this post, so you cannot approve this comment.') );
-
-	if ('1' != $comment->comment_approved) {
-		wp_set_comment_status($comment->comment_ID, 'approve');
-		if (true == get_option('comments_notify'))
-			wp_notify_postauthor($comment->comment_ID);
-	}
-
-	wp_redirect(get_option('siteurl') . '/wp-admin/moderation.php?approved=1');
-
-	break;
-
-case 'approvecomment':
-	$comment = (int) $_GET['comment'];
-	check_admin_referer('approve-comment_' . $comment);
-
-	$p = (int) $_GET['p'];
-	if (isset($_GET['noredir'])) {
-		$noredir = true;
-	} else {
-		$noredir = false;
-	}
-
-	if ( ! $comment = get_comment($comment) )
-		die(sprintf(__('Oops, no comment with this ID. <a href="%s">Go back</a>!'), 'edit.php'));
-
-	if ( !current_user_can('edit_post', $comment->comment_post_ID) )	
-		die( __('You are not allowed to edit comments on this post, so you cannot approve this comment.') );
-
-	wp_set_comment_status($comment->comment_ID, "approve");
-	if (get_settings("comments_notify") == true) {
-		wp_notify_postauthor($comment->comment_ID);
-	}
-
-
-	if ((wp_get_referer() != "") && (false == $noredir)) {
-		wp_redirect(wp_get_referer());
-	} else {
-		wp_redirect(get_settings('siteurl') .'/wp-admin/edit.php?p='.$p.'&c=1#comments');
-	}
-
-	break;
-
-case 'editedcomment':
-
-	$comment_ID = (int) $_POST['comment_ID'];
-	$comment_post_ID = (int)  $_POST['comment_post_ID'];
-
-	check_admin_referer('update-comment_' . $comment_ID);
-
-	edit_comment();
-
-	$location = ( empty($_POST['referredby']) ? "edit.php?p=$comment_post_ID&c=1" : $_POST['referredby'] ) . '#comment-' . $comment_ID;
-	$location = apply_filters('comment_edit_redirect', $location, $comment_ID);
-	wp_redirect($location);
-
+	exit();
 	break;
 
 default:
-	$title = __('Create New Post');
-	require_once ('./admin-header.php');
-?>
-<?php if ( isset($_GET['posted']) ) : ?>
-<div id="message" class="updated fade"><p><strong><?php _e('Post saved.'); ?></strong> <a href="<?php echo get_permalink( $_GET['posted'] ); ?>"><?php _e('View post'); ?> &raquo;</a></p></div>
-<?php endif; ?>
-<?php
-	if ( current_user_can('edit_posts') ) {
-		$action = 'post';
-		get_currentuserinfo();
-		if ( $drafts = get_users_drafts( $user_ID ) ) {
-			?>
-			<div class="wrap">
-			<p><strong><?php _e('Your Drafts:') ?></strong>
-			<?php
-			$num_drafts = count($drafts);
-			if ( $num_drafts > 15 ) $num_drafts = 15;
-			for ( $i = 0; $i < $num_drafts; $i++ ) {
-				$draft = $drafts[$i];
-				if ( 0 != $i )
-					echo ', ';
-				$draft->post_title = stripslashes($draft->post_title);
-				if ( empty($draft->post_title) )
-					$draft->post_title = sprintf(__('Post # %s'), $draft->ID);
-				echo "<a href='post.php?action=edit&amp;post=$draft->ID' title='" . __('Edit this draft') . "'>$draft->post_title</a>";
-			}
-			?>
-			<?php if ( 15 < count($drafts) ) { ?>
-			, <a href="edit.php"><?php echo sprintf(__('and %s more'), (count($drafts) - 15) ); ?> &raquo;</a>
-			<?php } ?>
-			.</p>
-			</div>
-			<?php
-		}
-
-		$post = get_default_post_to_edit();
-
-		include('edit-form-advanced.php');
-?>
-<div id="wp-bookmarklet" class="wrap">
-<?php echo '<h3>'.__('WordPress bookmarklet').'</h3>
-<p>'.__('Right click on the following link and choose "Add to favorites" to create a posting shortcut.').'</p>'; ?>
-<p>
-
-<?php
-if ($is_NS4 || $is_gecko) {
-?>
-<a href="javascript:if(navigator.userAgent.indexOf('Safari') >= 0){Q=getSelection();}else{Q=document.selection?document.selection.createRange().text:document.getSelection();}location.href='<?php echo get_settings('siteurl') ?>/wp-admin/post.php?text='+encodeURIComponent(Q)+'&amp;popupurl='+encodeURIComponent(location.href)+'&amp;popuptitle='+encodeURIComponent(document.title);"><?php printf(__('Press It - %s'), wp_specialchars(get_settings('blogname'))); ?></a> 
-<?php
-} else if ($is_winIE) {
-?>
-<a href="javascript:Q='';if(top.frames.length==0)Q=document.selection.createRange().text;location.href='<?php echo get_settings('siteurl') ?>/wp-admin/post.php?text='+encodeURIComponent(Q)+'&amp;popupurl='+encodeURIComponent(location.href)+'&amp;popuptitle='+encodeURIComponent(document.title);"><?php printf(__('Press it - %s'), get_settings('blogname')); ?></a>
-<script type="text/javascript">
-<!--
-function oneclickbookmarklet(blah) {
-window.open ("profile.php?action=IErightclick", "oneclickbookmarklet", "width=500, height=450, location=0, menubar=0, resizable=0, scrollbars=1, status=1, titlebar=0, toolbar=0, screenX=120, left=120, screenY=120, top=120");
-}
-// -->
-</script>
-<br />
-<br />
-<?php _e('One-click bookmarklet:') ?><br />
-<a href="javascript:oneclickbookmarklet(0);"><?php _e('click here') ?></a> 
-<?php
-} else if ($is_opera) {
-?>
-<a href="javascript:location.href='<?php echo get_settings('siteurl'); ?>/wp-admin/post.php?popupurl='+escape(location.href)+'&popuptitle='+escape(document.title);"><?php printf(__('Press it - %s'), get_settings('blogname')); ?></a> 
-<?php
-} else if ($is_macIE) {
-?>
-<a href="javascript:Q='';location.href='<?php echo get_settings('siteurl'); ?>/wp-admin/bookmarklet.php?text='+escape(document.getSelection())+'&popupurl='+escape(location.href)+'&popuptitle='+escape(document.title);"><?php printf(__('Press it - %s'), get_settings('blogname')); ?></a> 
-<?php
-}
-?>
-</p>
-</div>
-<?php
-} else {
-?>
-<div class="wrap">
-<p><?php printf(__('Since you&#8217;re a newcomer, you&#8217;ll have to wait for an admin to raise your level to 1, in order to be authorized to post.<br />
-You can also <a href="mailto:%s?subject=Promotion?">e-mail the admin</a> to ask for a promotion.<br />
-When you&#8217;re promoted, just reload this page and you&#8217;ll be able to blog. :)'), get_settings('admin_email')); ?>
-</p>
-</div>
-<?php
-}
-
+	wp_redirect('edit.php');
+	exit();
 	break;
 } // end switch
-/* </Edit> */
 include('admin-footer.php');
 ?>
diff -ruN 2.0.5/wp-admin/profile-update.php 2.2.2/wp-admin/profile-update.php
--- 2.0.5/wp-admin/profile-update.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/profile-update.php	2006-12-19 17:19:12.000000000 -0600
@@ -1,25 +1,22 @@
 <?php
 
+$parent_file = 'profile.php';
+$submenu_file = 'profile.php';
 require_once('admin.php');
 
 check_admin_referer('update-profile_' . $user_ID);
 
 if ( !$_POST )
-	die( __('No post?') );
+	wp_die( __('No post?') );
 
 $errors = edit_user($user_ID);
 
-if (count($errors) != 0) {
-	foreach ($errors as $id => $error) {
-		echo $error . '<br/>';
-	}
+if ( is_wp_error( $errors ) ) {
+	foreach( $errors->get_error_messages() as $message )
+		echo "$message<br />";
 	exit;
 }
 
-if ( !isset( $_POST['rich_editing'] ) )
-	$_POST['rich_editing'] = 'false';
-update_user_option( $current_user->id, 'rich_editing', $_POST['rich_editing'], true );
-
 do_action('personal_options_update');
 
 if ( 'profile' == $_POST['from'] )
@@ -30,4 +27,4 @@
 wp_redirect( $to );
 exit;
 
-?>
\ No newline at end of file
+?>
diff -ruN 2.0.5/wp-admin/profile.php 2.2.2/wp-admin/profile.php
--- 2.0.5/wp-admin/profile.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/profile.php	2006-11-19 01:56:05.000000000 -0600
@@ -1,9 +1,12 @@
-<?php 
+<?php
 require_once('admin.php');
 
 $title = __('Profile');
 
-$parent_file = 'profile.php';
+if ( current_user_can('edit_users') )
+	$parent_file = 'users.php';
+else
+	$parent_file = 'profile.php';
 include_once('admin-header.php');
 $profileuser = get_user_to_edit($user_ID);
 
@@ -25,6 +28,17 @@
 <input type="hidden" name="checkuser_id" value="<?php echo $user_ID ?>" />
 </p>
 
+<h3><?php _e('Personal Options'); ?></h3>
+
+<?php if ( rich_edit_exists() ) : // don't bother showing the option if the editor has been removed ?>
+<p><label for="rich_editing"><input name="rich_editing" type="checkbox" id="rich_editing" value="true" <?php checked('true', get_user_option('rich_editing')); ?> />
+<?php _e('Use the visual editor when writing') ?></label></p>
+<?php endif; ?>
+
+<?php do_action('profile_personal_options'); ?>
+
+<p class="submit"><input type="submit" value="<?php _e('Update Profile &raquo;') ?>" name="submit" /></p>
+
 <fieldset>
 <legend><?php _e('Name'); ?></legend>
 <p><label><?php _e('Username: (no editing)'); ?><br />
@@ -76,14 +90,14 @@
 <input type="text" name="yim" value="<?php echo $profileuser->yim ?>" />
 </label></p>
 
-<p><label><?php _e('Jabber / Google Talk:') ?>
+<p><label><?php _e('Jabber / Google Talk:') ?><br />
 <input type="text" name="jabber" value="<?php echo $profileuser->jabber ?>" /></label>
 </p>
 </fieldset>
 <br clear="all" />
 <fieldset>
-<legend><?php _e('About yourself'); ?></legend>
-<p class="desc"><?php _e('Share a little biographical information to fill out your profile. This may be shown publicly.'); ?></p>
+<legend><?php _e('About Yourself'); ?></legend>
+<p class="desc"><?php _e('Share a little biographical information. '); ?></p>
 <p><textarea name="description" rows="5" cols="30"><?php echo $profileuser->description ?></textarea></p>
 </fieldset>
 
@@ -107,20 +121,13 @@
 
 <br clear="all" />
 
-<h3><?php _e('Personal Options'); ?></h3>
-
-<p><label for="rich_editing"><input name="rich_editing" type="checkbox" id="rich_editing" value="true" <?php checked('true', get_user_option('rich_editing')); ?> />
-<?php _e('Use the visual rich editor when writing') ?></label></p>
-
-<?php do_action('profile_personal_options'); ?>
-
-  <table width="99%"  border="0" cellspacing="2" cellpadding="3" class="editform">
-    <?php
-    if(count($profileuser->caps) > count($profileuser->roles)):
-    ?>
-    <tr>
-      <th scope="row"><?php _e('Additional Capabilities:') ?></th>
-      <td><?php 
+	<table width="99%"  border="0" cellspacing="2" cellpadding="3" class="editform">
+		<?php
+		if(count($profileuser->caps) > count($profileuser->roles)):
+		?>
+		<tr>
+			<th scope="row"><?php _e('Additional Capabilities:') ?></th>
+			<td><?php
 			$output = '';
 			foreach($profileuser->caps as $cap => $value) {
 				if(!$wp_roles->is_role($cap)) {
@@ -135,9 +142,7 @@
     endif;
     ?>
   </table>
-<p class="submit">
-<input type="submit" value="<?php _e('Update Profile &raquo;') ?>" name="submit" />
-</p>
+<p class="submit"><input type="submit" value="<?php _e('Update Profile &raquo;') ?>" name="submit" /></p>
 </form>
 
 </div>
diff -ruN 2.0.5/wp-admin/rtl.css 2.2.2/wp-admin/rtl.css
--- 2.0.5/wp-admin/rtl.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/rtl.css	2007-04-12 22:29:43.000000000 -0500
@@ -0,0 +1,205 @@
+#viewarc, #viewcat, #namediv, #emaildiv, #uridiv, #planetnews li, #login ul li, #your-profile fieldset, 
+	#footer .logo, .alignleft .available-theme { float: right; }
+
+#templateside, .alignright { float: left; }
+
+#login #send, .readmore, .widefat th { text-align: right; }
+
+#postcustomsubmit, form#upload th, .submit, .editform th { text-align: left; }
+
+#devnews h4, #wphead h1, #your-profile legend, fieldset.options legend, 
+	#planetnews li .post { font-family: Tahoma, Georgia, "Times New Roman", Times, serif; }
+
+#wphead { padding: .8em 2em .8em 19em; }
+
+#wphead h1 { font-size: 2.4em; }
+
+#postdiv, #titlediv, #guiddiv, #tagdiv { margin: 0 0 0 8px; }
+
+#ed_toolbar input { margin: 3px 0 2px 2px; }
+
+#edButtons input, #edButtons input:active { margin: 0px 0 -1px 2px; }
+
+body, td { font: 13px Tahoma, "Lucida Grande", "Lucida Sans Unicode", Verdana; }
+
+h2 { font: normal 32px/5px serif; }
+
+textarea, input, select { font:  13px Tahoma, Verdana, Arial, Helvetica, sans-serif; }
+
+.quicktags, .search { font: 12px Tahoma, Georgia, "Times New Roman", Times, serif; }
+
+.updated, .confirm { padding: 0 3em 0 1em; }
+
+.submit input, .submit input:focus, .button, .button:focus {
+	border-left-color: #999;
+	border-right-color: #ccc;
+}
+
+.submit input:active, .button:active {
+	border-left-color: #ccc;
+	border-right-color: #999;
+}
+
+#adminmenu {
+	padding: .2em 2em .3em .2em;
+	height: 28px;
+}
+
+#adminmenu li { line-height: 160%; }
+
+#adminmenu a {
+	margin: 0 0 0 10px;
+	display: block;
+	float: right;
+}
+
+#adminmenu a.current {
+	border-right: 0;
+	border-left: 2px solid #4f96c8;
+}
+
+#submenu, #minisub { padding: 1px 3em 0 2em; }
+
+#submenu { height: 28px; }
+
+#submenu li { line-height: 160%; }
+
+#submenu a {
+	margin: 0 0 0 10px;
+	display: block;
+	float: right;
+}
+
+#submenu .current {
+	border-right: 0;
+	border-left: 2px solid #045290;
+}
+
+#currenttheme img {
+	float: right;
+	margin-right: auto;
+	margin-left: 1em;
+}
+
+#postdiv #quicktags {
+	padding-right: 0;
+	padding-left: 6px;
+}
+
+.readmore {
+	margin-right: auto;
+	margin-left: 5em;
+}
+
+#postexcerpt div, #attachmentlinks div {
+	margin-right: auto;
+	margin-left: 8px;
+}
+
+* html #postexcerpt .dbx-toggle-open {
+	padding-right: 0;
+	padding-left: 8px;
+}
+
+#searchform {
+	float: right;
+	margin-right: auto;
+	margin-left: 1em;
+}
+
+#poststuff {
+	margin-right: auto;
+	margin-left: 16em;
+}
+
+#template div {
+	margin-right: auto;
+	margin-left: 190px;
+}
+
+* html #template div {
+	margin-right: auto;
+	margin-left: 0px;
+}
+
+#user_info {
+	right: auto;
+	left: 1em;
+}
+
+#zeitgeist {
+	float: left;
+	margin-left: auto;
+	margin-right: 1em;
+}
+
+#zeitgeist ul {
+	margin: 0 .6em .3em 0;
+	padding: 0 .6em 0 0;
+}
+
+#categorydiv ul {
+	margin-left: auto;
+	margin-right: 10px;
+}
+
+#moremeta fieldset div { margin: 2px 0px 0 0; }
+
+#moremeta {
+	margin-right: auto;
+	margin-left: 15px;
+	right: auto;
+	left: 5%;
+}
+
+#moremeta .dbx-content {
+	background: url(images/box-butt.gif) no-repeat bottom left;
+	padding-right: 0;
+	padding-left: 2px;
+}
+
+#moremeta .dbx-handle { background: #2685af url(images/box-head.gif) no-repeat left; }
+
+#moremeta .dbx-box { background: url(images/box-bg.gif) repeat-y left; }
+
+a.dbx-toggle, a.dbx-toggle:visited {
+	right: auto;
+	left: 2px;
+}
+
+#advancedstuff a.dbx-toggle, #advancedstuff a.dbx-toggle-open:visited {
+	right: auto;
+	left: 5px;
+}
+
+#advancedstuff a.dbx-toggle-open, #advancedstuff a.dbx-toggle-open:visited {
+	right: auto;
+	left: 5px;
+}
+
+#categorychecklist {
+	margin-right: auto;
+	margin-left: 6px;
+}
+
+#ajax-response.alignleft {
+	margin-left: auto;
+	margin-right: 2em;
+}
+
+#postdivrich #edButtons {
+	padding-left: 0;
+	padding-right: 3px;
+}
+
+.page-numbers {
+	margin-right: auto;
+	margin-left: 3px;
+}
+
+a.view-link {
+	right:auto;
+	left:5%;
+	margin-right:0;
+	margin-left:220px;
+}
diff -ruN 2.0.5/wp-admin/setup-config.php 2.2.2/wp-admin/setup-config.php
--- 2.0.5/wp-admin/setup-config.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/setup-config.php	2007-03-08 12:31:46.000000000 -0600
@@ -2,7 +2,7 @@
 define('WP_INSTALLING', true);
 
 if (!file_exists('../wp-config-sample.php'))
-    die('Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file from your WordPress installation.');
+	die('Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file from your WordPress installation.');
 
 $configFile = file('../wp-config-sample.php');
 
@@ -82,103 +82,103 @@
 
 switch($step) {
 	case 0:
-?> 
+?>
 
-<p>Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.</p> 
-<ol> 
-  <li>Database name</li> 
-  <li>Database username</li> 
-  <li>Database password</li>
-  <li>Database host</li> 
-  <li>Table prefix (if you want to run more than one WordPress in a single database) </li>
-</ol> 
+<p>Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.</p>
+<ol>
+	<li>Database name</li>
+	<li>Database username</li>
+	<li>Database password</li>
+	<li>Database host</li>
+	<li>Table prefix (if you want to run more than one WordPress in a single database) </li>
+</ol>
 <p><strong>If for any reason this automatic file creation doesn't work, don't worry. All this does is fill in the database information to a configuration file. You may also simply open <code>wp-config-sample.php</code> in a text editor, fill in your information, and save it as <code>wp-config.php</code>. </strong></p>
 <p>In all likelihood, these items were supplied to you by your ISP. If you do not have this information, then you will need to contact them before you can continue. If you&#8217;re all ready, <a href="setup-config.php?step=1">let&#8217;s go</a>! </p>
 <?php
 	break;
 
 	case 1:
-	?> 
-</p> 
+	?>
+</p>
 <form method="post" action="setup-config.php?step=2">
-  <p>Below you should enter your database connection details. If you're not sure about these, contact your host. </p>
-  <table> 
-    <tr> 
-      <th scope="row">Database Name</th> 
-      <td><input name="dbname" type="text" size="25" value="wordpress" /></td>
-      <td>The name of the database you want to run WP in. </td> 
-    </tr> 
-    <tr> 
-      <th scope="row">User Name</th> 
-      <td><input name="uname" type="text" size="25" value="username" /></td>
-      <td>Your MySQL username</td> 
-    </tr> 
-    <tr> 
-      <th scope="row">Password</th> 
-      <td><input name="pwd" type="text" size="25" value="password" /></td>
-      <td>...and MySQL password.</td> 
-    </tr> 
-    <tr> 
-      <th scope="row">Database Host</th> 
-      <td><input name="dbhost" type="text" size="25" value="localhost" /></td>
-      <td>99% chance you won't need to change this value.</td> 
-    </tr>
-    <tr>
-      <th scope="row">Table Prefix</th>
-      <td><input name="prefix" type="text" id="prefix" value="wp_" size="25" /></td>
-      <td>If you want to run multiple WordPress installations in a single database, change this.</td>
-    </tr> 
-  </table>
-  <h2 class="step">
-  <input name="submit" type="submit" value="Submit" />
-  </h2>
-</form> 
+	<p>Below you should enter your database connection details. If you're not sure about these, contact your host. </p>
+	<table>
+		<tr>
+			<th scope="row">Database Name</th>
+			<td><input name="dbname" type="text" size="25" value="wordpress" /></td>
+			<td>The name of the database you want to run WP in. </td>
+		</tr>
+		<tr>
+			<th scope="row">User Name</th>
+			<td><input name="uname" type="text" size="25" value="username" /></td>
+			<td>Your MySQL username</td>
+		</tr>
+		<tr>
+			<th scope="row">Password</th>
+			<td><input name="pwd" type="text" size="25" value="password" /></td>
+			<td>...and MySQL password.</td>
+		</tr>
+		<tr>
+			<th scope="row">Database Host</th>
+			<td><input name="dbhost" type="text" size="25" value="localhost" /></td>
+			<td>99% chance you won't need to change this value.</td>
+		</tr>
+		<tr>
+			<th scope="row">Table Prefix</th>
+			<td><input name="prefix" type="text" id="prefix" value="wp_" size="25" /></td>
+			<td>If you want to run multiple WordPress installations in a single database, change this.</td>
+		</tr>
+	</table>
+	<h2 class="step">
+	<input name="submit" type="submit" value="Submit" />
+	</h2>
+</form>
 <?php
 	break;
 
 	case 2:
 	$dbname  = trim($_POST['dbname']);
-    $uname   = trim($_POST['uname']);
-    $passwrd = trim($_POST['pwd']);
-    $dbhost  = trim($_POST['dbhost']);
+	$uname   = trim($_POST['uname']);
+	$passwrd = trim($_POST['pwd']);
+	$dbhost  = trim($_POST['dbhost']);
 	$prefix  = trim($_POST['prefix']);
 	if (empty($prefix)) $prefix = 'wp_';
 
-    // Test the db connection.
-    define('DB_NAME', $dbname);
-    define('DB_USER', $uname);
-    define('DB_PASSWORD', $passwrd);
-    define('DB_HOST', $dbhost);
+	// Test the db connection.
+	define('DB_NAME', $dbname);
+	define('DB_USER', $uname);
+	define('DB_PASSWORD', $passwrd);
+	define('DB_HOST', $dbhost);
 
-    // We'll fail here if the values are no good.
-    require_once('../wp-includes/wp-db.php');
+	// We'll fail here if the values are no good.
+	require_once('../wp-includes/wp-db.php');
 	$handle = fopen('../wp-config.php', 'w');
 
-    foreach ($configFile as $line_num => $line) {
-        switch (substr($line,0,16)) {
-            case "define('DB_NAME'":
-                fwrite($handle, str_replace("wordpress", $dbname, $line));
-                break;
-            case "define('DB_USER'":
-                fwrite($handle, str_replace("'username'", "'$uname'", $line));
-                break;
-            case "define('DB_PASSW":
-                fwrite($handle, str_replace("'password'", "'$passwrd'", $line));
-                break;
-            case "define('DB_HOST'":
-                fwrite($handle, str_replace("localhost", $dbhost, $line));
-                break;
+	foreach ($configFile as $line_num => $line) {
+		switch (substr($line,0,16)) {
+			case "define('DB_NAME'":
+				fwrite($handle, str_replace("putyourdbnamehere", $dbname, $line));
+				break;
+			case "define('DB_USER'":
+				fwrite($handle, str_replace("'usernamehere'", "'$uname'", $line));
+				break;
+			case "define('DB_PASSW":
+				fwrite($handle, str_replace("'yourpasswordhere'", "'$passwrd'", $line));
+				break;
+			case "define('DB_HOST'":
+				fwrite($handle, str_replace("localhost", $dbhost, $line));
+				break;
 			case '$table_prefix  =':
 				fwrite($handle, str_replace('wp_', $prefix, $line));
 				break;
-            default:
-                fwrite($handle, $line);
-        }
-    }
-    fclose($handle);
+			default:
+				fwrite($handle, $line);
+		}
+	}
+	fclose($handle);
 	chmod('../wp-config.php', 0666);
-?> 
-<p>All right sparky! You've made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to <a href="install.php">run the install!</a></p> 
+?>
+<p>All right sparky! You've made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to <a href="install.php">run the install!</a></p>
 <?php
 	break;
 }
diff -ruN 2.0.5/wp-admin/sidebar.php 2.2.2/wp-admin/sidebar.php
--- 2.0.5/wp-admin/sidebar.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/sidebar.php	2006-11-19 01:56:05.000000000 -0600
@@ -4,7 +4,7 @@
 require_once('admin.php');
 
 if ( ! current_user_can('edit_posts') )
-	die ("Cheatin' uh ?");
+	wp_die(__('Cheatin&#8217; uh?'));
 
 if ('b' == $_GET['a']) {
 
@@ -34,15 +34,15 @@
 	padding: 3px;
 }
 .sidebar-categories {
-    display: block;
-    height: 6.6em;
-    overflow: auto;
-    background-color: #f4f4f4;
+	display: block;
+	height: 6.6em;
+	overflow: auto;
+	background-color: #f4f4f4;
 }
 .sidebar-categories label {
 	font-size: 10px;
-    display: block;
-    width: 90%;
+	display: block;
+	width: 90%;
 }
 </style>
 </head>
@@ -65,9 +65,9 @@
 <textarea rows="8" cols="12" style="width: 100%" name="content" tabindex="2"></textarea>
 </p>
 <p>
-    <input name="saveasdraft" type="submit" id="saveasdraft" tabindex="9" value="Save as Draft" /> 
+	<input name="saveasdraft" type="submit" id="saveasdraft" tabindex="9" value="Save as Draft" />
 <?php if ( current_user_can('publish_posts') ) : ?>
-    <input name="publish" type="submit" id="publish" tabindex="6" style="font-weight: bold;" value="Publish" /> 
+	<input name="publish" type="submit" id="publish" tabindex="6" style="font-weight: bold;" value="Publish" />
 <?php endif; ?>
 </p>
 </div>
diff -ruN 2.0.5/wp-admin/templates.php 2.2.2/wp-admin/templates.php
--- 2.0.5/wp-admin/templates.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/templates.php	2007-03-06 23:29:15.000000000 -0600
@@ -3,21 +3,7 @@
 $title = __('Template &amp; File Editing');
 $parent_file = 	'edit.php';
 
-$wpvarstoreset = array('action','redirect','profile','error','warning','a','file');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'redirect', 'profile', 'error', 'warning', 'a', 'file'));
 
 $recents = get_option('recently_edited');
 
@@ -39,7 +25,7 @@
 	check_admin_referer('edit-file_' . $file);
 
 	if ( ! current_user_can('edit_files') )
-	die('<p>'.__('You have do not have sufficient permissions to edit templates for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this blog.').'</p>');
 
 	$newcontent = stripslashes($_POST['newcontent']);
 	if (is_writeable($real_file)) {
@@ -62,18 +48,19 @@
 default:
 
 	require_once('./admin-header.php');
-	
+
 	if ( ! current_user_can('edit_files') )
-	die('<p>'.__('You have do not have sufficient permissions to edit templates for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this blog.').'</p>');
 
-	if ( strstr( $file, 'wp-config.php' ) )
-	die('<p>'.__('The config file cannot be edited or viewed through the web interface. Sorry!').'</p>');
+	if (strpos($file, 'wp-config.php') !== false)
+	wp_die('<p>'.__('The config file cannot be edited or viewed through the web interface. Sorry!').'</p>');
 
 	update_recently_edited($file);
 
-	if ( !is_file($real_file) ) {
+	if (!is_file($real_file))
 		$error = true;
-	} else {
+
+	if (!$error) {
 		$f = @ fopen($real_file, 'r');
 		if ( $f ) {
 			if ( filesize($real_file ) > 0 ) {
@@ -93,9 +80,9 @@
  <div id="message" class="error"><p><?php _e('Could not save file.') ?></p></div>
 	<?php else: ?>
  <div id="message" class="updated fade"><p><?php _e('File edited successfully.') ?></p></div>
-	<?php endif; ?>	
+	<?php endif; ?>
 <?php endif; ?>
- <div class="wrap"> 
+ <div class="wrap">
 <?php
 if (is_writeable($real_file)) {
 	echo '<h2>' . sprintf(__('Editing <strong>%s</strong>'), wp_specialchars($file) ) . '</h2>';
@@ -104,14 +91,14 @@
 }
 ?>
 <div id="templateside">
-<?php 
-if ( $recents ) : 
+<?php
+if ( $recents ) :
 ?>
 <h3><?php _e('Recent'); ?></h3>
 <?php
 echo '<ol>';
 foreach ($recents as $recent) :
-	echo "<li><a href='templates.php?file=" . wp_specialchars($recent, true) . "'>" . get_file_description(basename($recent)) . "</a></li>";
+	echo "<li><a href='templates.php?file=" . attribute_escape($recent) . "'>" . wp_specialchars(get_file_description(basename($recent))) . "</a></li>";
 endforeach;
 echo '</ol>';
 endif;
@@ -123,30 +110,30 @@
 	 if (file_exists(ABSPATH . $old_file))
 		 $common_files[] = $old_file;
  } ?>
-  <ul>
-	 <?php foreach ($common_files as $common_file) : ?>
-	  <li><a href="templates.php?file=<?php echo $common_file?>"><?php echo get_file_description($common_file); ?></a></li>
-	 <?php endforeach; ?>
-  </ul>
+<ul>
+	<?php foreach ($common_files as $common_file) : ?>
+		<li><a href="templates.php?file=<?php echo $common_file?>"><?php echo get_file_description($common_file); ?></a></li>
+	<?php endforeach; ?>
+</ul>
 </div>
 <?php if (!$error) { ?>
-  <form name="template" id="template" action="templates.php" method="post"> 
-  <?php wp_nonce_field('edit-file_' . $file) ?>
-     <div><textarea cols="70" rows="25" name="newcontent" id='newcontent' tabindex="1"><?php echo $content ?></textarea> 
-     <input type="hidden" name="action" value="update" /> 
-     <input type="hidden" name="file" value="<?php echo $file ?>" /> 
-</div>
+	<form name="template" id="template" action="templates.php" method="post">
+	<?php wp_nonce_field('edit-file_' . $file) ?>
+		<div><textarea cols="70" rows="25" name="newcontent" id='newcontent' tabindex="1"><?php echo $content ?></textarea>
+		<input type="hidden" name="action" value="update" />
+		<input type="hidden" name="file" value="<?php echo $file ?>" />
+		</div>
 <?php if ( is_writeable($real_file) ) : ?>
-     <p class="submit">
+	<p class="submit">
 <?php
-	echo "<input type='submit' name='submit' value='	" . __('Update File') . " &raquo;' tabindex='2' />";
+	echo "<input type='submit' name='submit' value='	" . __('Update File &raquo;') . "' tabindex='2' />";
 ?>
 </p>
 <?php else : ?>
 <p><em><?php _e('If this file were writable you could edit it.'); ?></em></p>
 <?php endif; ?>
-   </form> 
-  <?php
+	</form>
+	<?php
 	} else {
 		echo '<div class="error"><p>' . __('Oops, no such file exists! Double check the name and try again, merci.') . '</p></div>';
 	}
@@ -156,14 +143,14 @@
 <div class="wrap">
 <h2><?php _e('Other Files') ?></h2>
 
-  <p><?php _e('To edit a file, type its name here. You can edit any file <a href="http://codex.wordpress.org/Changing_File_Permissions" title="Read more about making files writable">writable by the server</a>, e.g. CHMOD 666.') ?></p> 
-  <form name="file" action="templates.php" method="get"> 
-    <input type="text" name="file" /> 
-    <input type="submit" name="submit"  value="<?php _e('Edit file &raquo;') ?>" /> 
-  </form> 
+	<p><?php _e('To edit a file, type its name here. You can edit any file <a href="http://codex.wordpress.org/Changing_File_Permissions" title="Read more about making files writable">writable by the server</a>, e.g. CHMOD 666.') ?></p>
+	<form name="file" action="templates.php" method="get">
+		<input type="text" name="file" />
+		<input type="submit" name="submit"  value="<?php _e('Edit file &raquo;') ?>" />
+	</form>
 
-  <p><?php _e('Note: of course, you can also edit the files/templates in your text editor of choice and upload them. This online editor is only meant to be used when you don&#8217;t have access to a text editor or FTP client.') ?></p>
-</div> 
+	<p><?php _e('Note: of course, you can also edit the files/templates in your text editor of choice and upload them. This online editor is only meant to be used when you don&#8217;t have access to a text editor or FTP client.') ?></p>
+</div>
 <?php
 
 break;
diff -ruN 2.0.5/wp-admin/theme-editor.php 2.2.2/wp-admin/theme-editor.php
--- 2.0.5/wp-admin/theme-editor.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/theme-editor.php	2006-12-21 04:10:04.000000000 -0600
@@ -4,21 +4,7 @@
 $title = __("Edit Themes");
 $parent_file = 'themes.php';
 
-$wpvarstoreset = array('action','redirect','profile','error','warning','a','file', 'theme');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'redirect', 'profile', 'error', 'warning', 'a', 'file', 'theme'));
 
 $themes = get_themes();
 
@@ -30,7 +16,7 @@
 
 
 if ( ! isset($themes[$theme]) )
-	die(__('The requested theme does not exist.'));
+	wp_die(__('The requested theme does not exist.'));
 
 $allowed_files = array_merge($themes[$theme]['Stylesheet Files'], $themes[$theme]['Template Files']);
 
@@ -50,7 +36,7 @@
 	check_admin_referer('edit-theme_' . $file . $theme);
 
 	if ( !current_user_can('edit_themes') )
-	die('<p>'.__('You have do not have sufficient permissions to edit templates for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this blog.').'</p>');
 
 	$newcontent = stripslashes($_POST['newcontent']);
 	$theme = urlencode($theme);
@@ -72,16 +58,17 @@
 break;
 
 default:
-	
-	require_once('admin-header.php');
+
 	if ( !current_user_can('edit_themes') )
-	die('<p>'.__('You have do not have sufficient permissions to edit themes for this blog.').'</p>');
+		wp_die('<p>'.__('You do not have sufficient permissions to edit themes for this blog.').'</p>');
+
+	require_once('admin-header.php');
 
 	update_recently_edited($file);
-	
+
 	if (!is_file($real_file))
 		$error = 1;
-	
+
 	if (!$error && filesize($real_file) > 0) {
 		$f = fopen($real_file, 'r');
 		$content = fread($f, filesize($real_file));
@@ -93,7 +80,7 @@
  <div id="message" class="updated fade"><p><?php _e('File edited successfully.') ?></p></div>
 <?php endif; ?>
  <div class="wrap">
-  <form name="theme" action="theme-editor.php" method="post"> 
+	<form name="theme" action="theme-editor.php" method="post">
 		<?php _e('Select theme to edit:') ?>
 		<select name="theme" id="theme">
 	<?php
@@ -101,12 +88,12 @@
 		$theme_name = $a_theme['Name'];
 		if ($theme_name == $theme) $selected = " selected='selected'";
 		else $selected = '';
-		$theme_name = wp_specialchars($theme_name, true);
+		$theme_name = attribute_escape($theme_name);
 		echo "\n\t<option value=\"$theme_name\" $selected>$theme_name</option>";
 	}
 ?>
  </select>
- <input type="submit" name="Submit" value="<?php _e('Select') ?> &raquo;" />
+ <input type="submit" name="Submit" value="<?php _e('Select &raquo;') ?>" class="button" />
  </form>
  </div>
 
@@ -119,47 +106,47 @@
 	}
 	?>
 	<div id="templateside">
-  <h3><?php printf(__("<strong>'%s'</strong> theme files"), $theme) ?></h3>
+	<h3><?php printf(__("<strong>'%s'</strong> theme files"), $theme) ?></h3>
 
 <?php
 if ($allowed_files) :
 ?>
-  <ul>
+	<ul>
 <?php foreach($allowed_files as $allowed_file) : ?>
 		 <li><a href="theme-editor.php?file=<?php echo "$allowed_file"; ?>&amp;theme=<?php echo urlencode($theme) ?>"><?php echo get_file_description($allowed_file); ?></a></li>
 <?php endforeach; ?>
-  </ul>
+	</ul>
 <?php endif; ?>
-</div> 
+</div>
 	<?php
 	if (!$error) {
-	?> 
-  <form name="template" id="template" action="theme-editor.php" method="post">
-  <?php wp_nonce_field('edit-theme_' . $file . $theme) ?>
-		 <div><textarea cols="70" rows="25" name="newcontent" id="newcontent" tabindex="1"><?php echo $content ?></textarea> 
-     <input type="hidden" name="action" value="update" /> 
-     <input type="hidden" name="file" value="<?php echo $file ?>" /> 
-     <input type="hidden" name="theme" value="<?php echo $theme ?>" />
+	?>
+	<form name="template" id="template" action="theme-editor.php" method="post">
+	<?php wp_nonce_field('edit-theme_' . $file . $theme) ?>
+		 <div><textarea cols="70" rows="25" name="newcontent" id="newcontent" tabindex="1"><?php echo $content ?></textarea>
+		 <input type="hidden" name="action" value="update" />
+		 <input type="hidden" name="file" value="<?php echo $file ?>" />
+		 <input type="hidden" name="theme" value="<?php echo $theme ?>" />
 		 </div>
 <?php if ( is_writeable($real_file) ) : ?>
-     <p class="submit">
+	<p class="submit">
 <?php
-	echo "<input type='submit' name='submit' value='	" . __('Update File') . " &raquo;' tabindex='2' />";
+	echo "<input type='submit' name='submit' value='	" . __('Update File &raquo;') . "' tabindex='2' />";
 ?>
 </p>
 <?php else : ?>
 <p><em><?php _e('If this file were writable you could edit it.'); ?></em></p>
 <?php endif; ?>
-   </form> 
-  <?php
+	</form>
+	<?php
 	} else {
 		echo '<div class="error"><p>' . __('Oops, no such file exists! Double check the name and try again, merci.') . '</p></div>';
 	}
 	?>
 <div class="clear"> &nbsp; </div>
-</div> 
+</div>
 <?php
 break;
 }
 
-include("admin-footer.php") ?> 
+include("admin-footer.php") ?>
diff -ruN 2.0.5/wp-admin/themes.php 2.2.2/wp-admin/themes.php
--- 2.0.5/wp-admin/themes.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/themes.php	2007-03-06 21:05:41.000000000 -0600
@@ -3,16 +3,16 @@
 
 if ( isset($_GET['action']) ) {
 	check_admin_referer('switch-theme_' . $_GET['template']);
-	
+
 	if ('activate' == $_GET['action']) {
 		if ( isset($_GET['template']) )
 			update_option('template', $_GET['template']);
-		
+
 		if ( isset($_GET['stylesheet']) )
 			update_option('stylesheet', $_GET['stylesheet']);
-		
+
 		do_action('switch_theme', get_current_theme());
-		
+
 		wp_redirect('themes.php?activated=true');
 		exit;
 	}
@@ -26,7 +26,7 @@
 <?php if ( ! validate_current_theme() ) : ?>
 <div id="message1" class="updated fade"><p><?php _e('The active theme is broken.  Reverting to the default theme.'); ?></p></div>
 <?php elseif ( isset($_GET['activated']) ) : ?>
-<div id="message2" class="updated fade"><p><?php printf(__('New theme activated. <a href="%s">View site &raquo;</a>'), get_bloginfo('home') . '/'); ?></p></div>
+<div id="message2" class="updated fade"><p><?php printf(__('New theme activated. <a href="%s">View site &raquo;</a>'), get_bloginfo('url') . '/'); ?></p></div>
 <?php endif; ?>
 
 <?php
@@ -102,7 +102,7 @@
 	</tr>
 <?php
 	$theme = '';
-	
+
 	$theme_names = array_keys($broken_themes);
 	natcasesort($theme_names);
 
@@ -112,10 +112,10 @@
 
 		$theme = ('class="alternate"' == $theme) ? '' : 'class="alternate"';
 		echo "
-	  <tr $theme>
-	     <td>$title</td>
-	     <td>$description</td>
-	  </tr>";
+		<tr $theme>
+			 <td>$title</td>
+			 <td>$description</td>
+		</tr>";
 	}
 ?>
 </table>
diff -ruN 2.0.5/wp-admin/update-links.php 2.2.2/wp-admin/update-links.php
--- 2.0.5/wp-admin/update-links.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/update-links.php	2006-11-19 01:56:05.000000000 -0600
@@ -3,12 +3,12 @@
 require_once( ABSPATH . 'wp-includes/class-snoopy.php');
 
 if ( !get_option('use_linksupdate') )
-	die(__('Feature disabled.'));
+	wp_die(__('Feature disabled.'));
 
 $link_uris = $wpdb->get_col("SELECT link_url FROM $wpdb->links");
 
 if ( !$link_uris )
-	die('No links');
+	wp_die(__('No links'));
 
 $link_uris = urlencode( join( $link_uris, "\n" ) );
 
@@ -16,7 +16,7 @@
 
 $http_request  = "POST /updated-batch/ HTTP/1.0\r\n";
 $http_request .= "Host: api.pingomatic.com\r\n";
-$http_request .= 'Content-Type: application/x-www-form-urlencoded; charset='.get_settings('blog_charset')."\r\n";
+$http_request .= 'Content-Type: application/x-www-form-urlencoded; charset='.get_option('blog_charset')."\r\n";
 $http_request .= 'Content-Length: ' . strlen($query_string) . "\r\n";
 $http_request .= 'User-Agent: WordPress/' . $wp_version . "\r\n";
 $http_request .= "\r\n";
@@ -28,13 +28,13 @@
 	while ( !feof($fs) )
 		$response .= fgets($fs, 1160); // One TCP-IP packet
 	fclose($fs);
-    
+
 	$response = explode("\r\n\r\n", $response, 2);
 	$body = trim( $response[1] );
 	$body = str_replace(array("\r\n", "\r"), "\n", $body);
-    
+
 	$returns = explode("\n", $body);
-    
+
 	foreach ($returns as $return) :
 		$time = $wpdb->escape( substr($return, 0, 19) );
 		$uri = $wpdb->escape( preg_replace('/(.*?) | (.*?)/', '$2', $return) );
diff -ruN 2.0.5/wp-admin/upgrade-functions.php 2.2.2/wp-admin/upgrade-functions.php
--- 2.0.5/wp-admin/upgrade-functions.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upgrade-functions.php	2007-05-10 11:31:49.000000000 -0500
@@ -0,0 +1,1124 @@
+<?php
+
+if ( file_exists(ABSPATH . 'wp-content/install.php') )
+	require (ABSPATH . 'wp-content/install.php');
+require_once(ABSPATH . '/wp-admin/admin-functions.php');
+require_once(ABSPATH . '/wp-admin/admin-db.php');
+require_once(ABSPATH . '/wp-admin/upgrade-schema.php');
+require_once(ABSPATH . WPINC . '/registration.php');
+
+if ( !function_exists('wp_install') ) :
+function wp_install($blog_title, $user_name, $user_email, $public, $meta='') {
+	global $wp_rewrite;
+
+	wp_check_mysql_version();
+	wp_cache_flush();
+	make_db_current_silent();
+	populate_options();
+	populate_roles();
+
+	update_option('blogname', $blog_title);
+	update_option('admin_email', $user_email);
+	update_option('blog_public', $public);
+	$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
+
+	if ( defined('WP_SITEURL') && '' != WP_SITEURL )
+		$guessurl = WP_SITEURL;
+	else
+		$guessurl = preg_replace('|/wp-admin/.*|i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
+
+	update_option('siteurl', $guessurl);
+
+	// If not a public blog, don't ping.
+	if ( ! $public )
+		update_option('default_pingback_flag', 0);
+
+	// Create default user.  If the user already exists, the user tables are
+	// being shared among blogs.  Just set the role in that case.
+	$user_id = username_exists($user_name);
+	if ( !$user_id ) {
+		$random_password = substr(md5(uniqid(microtime())), 0, 6);
+		$user_id = wp_create_user($user_name, $random_password, $user_email);
+	} else {
+		$random_password = __('User already exists.  Password inherited.');
+	}
+
+	$user = new WP_User($user_id);
+	$user->set_role('administrator');
+
+	wp_install_defaults($user_id);
+
+	$wp_rewrite->flush_rules();
+
+	wp_new_blog_notification($blog_title, $guessurl, $user_id, $random_password);
+
+	wp_cache_flush();
+
+	return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $random_password);
+}
+endif;
+
+if ( !function_exists('wp_install_defaults') ) :
+function wp_install_defaults($user_id) {
+	global $wpdb;
+
+	// Default category
+	$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_count, category_description) VALUES ('0', '".$wpdb->escape(__('Uncategorized'))."', '".sanitize_title(__('Uncategorized'))."', '1', '')");
+
+	// Default link category
+	$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, link_count, category_description) VALUES ('0', '".$wpdb->escape(__('Blogroll'))."', '".sanitize_title(__('Blogroll'))."', '7', '')");
+
+	// Now drop in some default links
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://inphotos.org/', 'Donncha', 0, 'http://inphotos.org/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (1, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://zengun.org/weblog/', 'Michel', 0, 'http://zengun.org/weblog/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (2, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://boren.nu/', 'Ryan', 0, 'http://boren.nu/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (3, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://photomatt.net/', 'Matt', 0, 'http://xml.photomatt.net/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (4, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://zed1.com/journalized/', 'Mike', 0, 'http://zed1.com/journalized/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (5, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://www.alexking.org/', 'Alex', 0, 'http://www.alexking.org/blog/wp-rss2.php', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (6, 2)" );
+
+	$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://dougal.gunters.org/', 'Dougal', 0, 'http://dougal.gunters.org/feed/', '');");
+	$wpdb->query( "INSERT INTO $wpdb->link2cat (`link_id`, `category_id`) VALUES (7, 2)" );
+
+	// First post
+	$now = date('Y-m-d H:i:s');
+	$now_gmt = gmdate('Y-m-d H:i:s');
+	$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, comment_count, to_ping, pinged, post_content_filtered) VALUES ($user_id, '$now', '$now_gmt', '".$wpdb->escape(__('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!'))."', '', '".$wpdb->escape(__('Hello world!'))."', '0', '".$wpdb->escape(__('hello-world'))."', '$now', '$now_gmt', '1', '', '', '')");
+
+	$wpdb->query( "INSERT INTO $wpdb->post2cat (`rel_id`, `post_id`, `category_id`) VALUES (1, 1, 1)" );
+
+	// Default comment
+	$wpdb->query("INSERT INTO $wpdb->comments (comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_date, comment_date_gmt, comment_content) VALUES ('1', '".$wpdb->escape(__('Mr WordPress'))."', '', 'http://wordpress.org/', '$now', '$now_gmt', '".$wpdb->escape(__('Hi, this is a comment.<br />To delete a comment, just log in and view the post&#039;s comments. There you will have the option to edit or delete them.'))."')");
+
+	// First Page
+	$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, post_status, post_type, to_ping, pinged, post_content_filtered) VALUES ($user_id, '$now', '$now_gmt', '".$wpdb->escape(__('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'))."', '', '".$wpdb->escape(__('About'))."', '0', '".$wpdb->escape(__('about'))."', '$now', '$now_gmt', 'publish', 'page', '', '', '')");
+}
+endif;
+
+if ( !function_exists('wp_new_blog_notification') ) :
+function wp_new_blog_notification($blog_title, $blog_url, $user_id, $password) {
+	$user = new WP_User($user_id);
+	$email = $user->user_email;
+	$name = $user->user_login;
+	$message_headers = 'From: "' . $blog_title . '" <wordpress@' . $_SERVER['SERVER_NAME'] . '>';
+	$message = sprintf(__("Your new WordPress blog has been successfully set up at:
+
+%1\$s
+
+You can log in to the administrator account with the following information:
+
+Username: %2\$s
+Password: %3\$s
+
+We hope you enjoy your new weblog. Thanks!
+
+--The WordPress Team
+http://wordpress.org/
+"), $blog_url, $name, $password);
+
+	@wp_mail($email, __('New WordPress Blog'), $message, $message_headers);
+}
+endif;
+
+if ( !function_exists('wp_upgrade') ) :
+function wp_upgrade() {
+	global $wp_current_db_version, $wp_db_version;
+
+	$wp_current_db_version = __get_option('db_version');
+
+	// We are up-to-date.  Nothing to do.
+	if ( $wp_db_version == $wp_current_db_version )
+		return;
+
+	wp_check_mysql_version();
+	wp_cache_flush();
+	make_db_current_silent();
+	upgrade_all();
+	wp_cache_flush();
+}
+endif;
+
+// Functions to be called in install and upgrade scripts
+function upgrade_all() {
+	global $wp_current_db_version, $wp_db_version, $wp_rewrite;
+	$wp_current_db_version = __get_option('db_version');
+
+	// We are up-to-date.  Nothing to do.
+	if ( $wp_db_version == $wp_current_db_version )
+		return;
+
+	// If the version is not set in the DB, try to guess the version.
+	if ( empty($wp_current_db_version) ) {
+		$wp_current_db_version = 0;
+
+		// If the template option exists, we have 1.5.
+		$template = __get_option('template');
+		if ( !empty($template) )
+			$wp_current_db_version = 2541;
+	}
+
+	populate_options();
+
+	if ( $wp_current_db_version < 2541 ) {
+		upgrade_100();
+		upgrade_101();
+		upgrade_110();
+		upgrade_130();
+	}
+	
+	maybe_disable_automattic_widgets();
+
+	if ( $wp_current_db_version < 3308 )
+		upgrade_160();
+
+	if ( $wp_current_db_version < 4772 )
+		upgrade_210();
+
+	if ( $wp_current_db_version < 4351 )
+		upgrade_old_slugs();
+
+	$wp_rewrite->flush_rules();
+
+	update_option('db_version', $wp_db_version);
+}
+
+function upgrade_100() {
+	global $wpdb;
+
+	// Get the title and ID of every post, post_name to check if it already has a value
+	$posts = $wpdb->get_results("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE post_name = ''");
+	if ($posts) {
+		foreach($posts as $post) {
+			if ('' == $post->post_name) {
+				$newtitle = sanitize_title($post->post_title);
+				$wpdb->query("UPDATE $wpdb->posts SET post_name = '$newtitle' WHERE ID = '$post->ID'");
+			}
+		}
+	}
+
+	$categories = $wpdb->get_results("SELECT cat_ID, cat_name, category_nicename FROM $wpdb->categories");
+	foreach ($categories as $category) {
+		if ('' == $category->category_nicename) {
+			$newtitle = sanitize_title($category->cat_name);
+			$wpdb->query("UPDATE $wpdb->categories SET category_nicename = '$newtitle' WHERE cat_ID = '$category->cat_ID'");
+		}
+	}
+
+
+	$wpdb->query("UPDATE $wpdb->options SET option_value = REPLACE(option_value, 'wp-links/links-images/', 'wp-images/links/')
+	WHERE option_name LIKE 'links_rating_image%'
+	AND option_value LIKE 'wp-links/links-images/%'");
+
+	$done_ids = $wpdb->get_results("SELECT DISTINCT post_id FROM $wpdb->post2cat");
+	if ($done_ids) :
+		foreach ($done_ids as $done_id) :
+			$done_posts[] = $done_id->post_id;
+		endforeach;
+		$catwhere = ' AND ID NOT IN (' . implode(',', $done_posts) . ')';
+	else:
+		$catwhere = '';
+	endif;
+
+	$allposts = $wpdb->get_results("SELECT ID, post_category FROM $wpdb->posts WHERE post_category != '0' $catwhere");
+	if ($allposts) :
+		foreach ($allposts as $post) {
+			// Check to see if it's already been imported
+			$cat = $wpdb->get_row("SELECT * FROM $wpdb->post2cat WHERE post_id = $post->ID AND category_id = $post->post_category");
+			if (!$cat && 0 != $post->post_category) { // If there's no result
+				$wpdb->query("
+					INSERT INTO $wpdb->post2cat
+					(post_id, category_id)
+					VALUES
+					('$post->ID', '$post->post_category')
+					");
+			}
+		}
+	endif;
+}
+
+function upgrade_101() {
+	global $wpdb;
+
+	// Clean up indices, add a few
+	add_clean_index($wpdb->posts, 'post_name');
+	add_clean_index($wpdb->posts, 'post_status');
+	add_clean_index($wpdb->categories, 'category_nicename');
+	add_clean_index($wpdb->comments, 'comment_approved');
+	add_clean_index($wpdb->comments, 'comment_post_ID');
+	add_clean_index($wpdb->links , 'link_category');
+	add_clean_index($wpdb->links , 'link_visible');
+}
+
+
+function upgrade_110() {
+	global $wpdb;
+
+	// Set user_nicename.
+	$users = $wpdb->get_results("SELECT ID, user_nickname, user_nicename FROM $wpdb->users");
+	foreach ($users as $user) {
+		if ('' == $user->user_nicename) {
+			$newname = sanitize_title($user->user_nickname);
+			$wpdb->query("UPDATE $wpdb->users SET user_nicename = '$newname' WHERE ID = '$user->ID'");
+		}
+	}
+
+	$users = $wpdb->get_results("SELECT ID, user_pass from $wpdb->users");
+	foreach ($users as $row) {
+		if (!preg_match('/^[A-Fa-f0-9]{32}$/', $row->user_pass)) {
+			$wpdb->query('UPDATE '.$wpdb->users.' SET user_pass = MD5(\''.$row->user_pass.'\') WHERE ID = \''.$row->ID.'\'');
+		}
+	}
+
+
+	// Get the GMT offset, we'll use that later on
+	$all_options = get_alloptions_110();
+
+	$time_difference = $all_options->time_difference;
+
+	$server_time = time()+date('Z');
+	$weblogger_time = $server_time + $time_difference*3600;
+	$gmt_time = time();
+
+	$diff_gmt_server = ($gmt_time - $server_time) / 3600;
+	$diff_weblogger_server = ($weblogger_time - $server_time) / 3600;
+	$diff_gmt_weblogger = $diff_gmt_server - $diff_weblogger_server;
+	$gmt_offset = -$diff_gmt_weblogger;
+
+	// Add a gmt_offset option, with value $gmt_offset
+	add_option('gmt_offset', $gmt_offset);
+
+	// Check if we already set the GMT fields (if we did, then
+	// MAX(post_date_gmt) can't be '0000-00-00 00:00:00'
+	// <michel_v> I just slapped myself silly for not thinking about it earlier
+	$got_gmt_fields = ($wpdb->get_var("SELECT MAX(post_date_gmt) FROM $wpdb->posts") == '0000-00-00 00:00:00') ? false : true;
+
+	if (!$got_gmt_fields) {
+
+		// Add or substract time to all dates, to get GMT dates
+		$add_hours = intval($diff_gmt_weblogger);
+		$add_minutes = intval(60 * ($diff_gmt_weblogger - $add_hours));
+		$wpdb->query("UPDATE $wpdb->posts SET post_date_gmt = DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
+		$wpdb->query("UPDATE $wpdb->posts SET post_modified = post_date");
+		$wpdb->query("UPDATE $wpdb->posts SET post_modified_gmt = DATE_ADD(post_modified, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE) WHERE post_modified != '0000-00-00 00:00:00'");
+		$wpdb->query("UPDATE $wpdb->comments SET comment_date_gmt = DATE_ADD(comment_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
+		$wpdb->query("UPDATE $wpdb->users SET user_registered = DATE_ADD(user_registered, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)");
+	}
+
+}
+
+function upgrade_130() {
+	global $wpdb;
+
+	// Remove extraneous backslashes.
+	$posts = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, guid, post_date, post_name, post_status, post_author FROM $wpdb->posts");
+	if ($posts) {
+		foreach($posts as $post) {
+			$post_content = addslashes(deslash($post->post_content));
+			$post_title = addslashes(deslash($post->post_title));
+			$post_excerpt = addslashes(deslash($post->post_excerpt));
+			if ( empty($post->guid) )
+				$guid = get_permalink($post->ID);
+			else
+				$guid = $post->guid;
+
+			$wpdb->query("UPDATE $wpdb->posts SET post_title = '$post_title', post_content = '$post_content', post_excerpt = '$post_excerpt', guid = '$guid' WHERE ID = '$post->ID'");
+		}
+	}
+
+	// Remove extraneous backslashes.
+	$comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_content FROM $wpdb->comments");
+	if ($comments) {
+		foreach($comments as $comment) {
+			$comment_content = addslashes(deslash($comment->comment_content));
+			$comment_author = addslashes(deslash($comment->comment_author));
+			$wpdb->query("UPDATE $wpdb->comments SET comment_content = '$comment_content', comment_author = '$comment_author' WHERE comment_ID = '$comment->comment_ID'");
+		}
+	}
+
+	// Remove extraneous backslashes.
+	$links = $wpdb->get_results("SELECT link_id, link_name, link_description FROM $wpdb->links");
+	if ($links) {
+		foreach($links as $link) {
+			$link_name = addslashes(deslash($link->link_name));
+			$link_description = addslashes(deslash($link->link_description));
+			$wpdb->query("UPDATE $wpdb->links SET link_name = '$link_name', link_description = '$link_description' WHERE link_id = '$link->link_id'");
+		}
+	}
+
+	// The "paged" option for what_to_show is no more.
+	if ($wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'what_to_show'") == 'paged') {
+		$wpdb->query("UPDATE $wpdb->options SET option_value = 'posts' WHERE option_name = 'what_to_show'");
+	}
+
+	$active_plugins = __get_option('active_plugins');
+
+	// If plugins are not stored in an array, they're stored in the old
+	// newline separated format.  Convert to new format.
+	if ( !is_array( $active_plugins ) ) {
+		$active_plugins = explode("\n", trim($active_plugins));
+		update_option('active_plugins', $active_plugins);
+	}
+
+	// Obsolete tables
+	$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optionvalues');
+	$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiontypes');
+	$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroups');
+	$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'optiongroup_options');
+
+	// Update comments table to use comment_type
+	$wpdb->query("UPDATE $wpdb->comments SET comment_type='trackback', comment_content = REPLACE(comment_content, '<trackback />', '') WHERE comment_content LIKE '<trackback />%'");
+	$wpdb->query("UPDATE $wpdb->comments SET comment_type='pingback', comment_content = REPLACE(comment_content, '<pingback />', '') WHERE comment_content LIKE '<pingback />%'");
+
+	// Some versions have multiple duplicate option_name rows with the same values
+	$options = $wpdb->get_results("SELECT option_name, COUNT(option_name) AS dupes FROM `$wpdb->options` GROUP BY option_name");
+	foreach ( $options as $option ) {
+		if ( 1 != $option->dupes ) { // Could this be done in the query?
+			$limit = $option->dupes - 1;
+			$dupe_ids = $wpdb->get_col("SELECT option_id FROM $wpdb->options WHERE option_name = '$option->option_name' LIMIT $limit");
+			$dupe_ids = join($dupe_ids, ',');
+			$wpdb->query("DELETE FROM $wpdb->options WHERE option_id IN ($dupe_ids)");
+		}
+	}
+
+	make_site_theme();
+}
+
+function upgrade_160() {
+	global $wpdb, $wp_current_db_version;
+
+	populate_roles_160();
+
+	$users = $wpdb->get_results("SELECT * FROM $wpdb->users");
+	foreach ( $users as $user ) :
+		if ( !empty( $user->user_firstname ) )
+			update_usermeta( $user->ID, 'first_name', $wpdb->escape($user->user_firstname) );
+		if ( !empty( $user->user_lastname ) )
+			update_usermeta( $user->ID, 'last_name', $wpdb->escape($user->user_lastname) );
+		if ( !empty( $user->user_nickname ) )
+			update_usermeta( $user->ID, 'nickname', $wpdb->escape($user->user_nickname) );
+		if ( !empty( $user->user_level ) )
+			update_usermeta( $user->ID, $wpdb->prefix . 'user_level', $user->user_level );
+		if ( !empty( $user->user_icq ) )
+			update_usermeta( $user->ID, 'icq', $wpdb->escape($user->user_icq) );
+		if ( !empty( $user->user_aim ) )
+			update_usermeta( $user->ID, 'aim', $wpdb->escape($user->user_aim) );
+		if ( !empty( $user->user_msn ) )
+			update_usermeta( $user->ID, 'msn', $wpdb->escape($user->user_msn) );
+		if ( !empty( $user->user_yim ) )
+			update_usermeta( $user->ID, 'yim', $wpdb->escape($user->user_icq) );
+		if ( !empty( $user->user_description ) )
+			update_usermeta( $user->ID, 'description', $wpdb->escape($user->user_description) );
+
+		if ( isset( $user->user_idmode ) ):
+			$idmode = $user->user_idmode;
+			if ($idmode == 'nickname') $id = $user->user_nickname;
+			if ($idmode == 'login') $id = $user->user_login;
+			if ($idmode == 'firstname') $id = $user->user_firstname;
+			if ($idmode == 'lastname') $id = $user->user_lastname;
+			if ($idmode == 'namefl') $id = $user->user_firstname.' '.$user->user_lastname;
+			if ($idmode == 'namelf') $id = $user->user_lastname.' '.$user->user_firstname;
+			if (!$idmode) $id = $user->user_nickname;
+			$id = $wpdb->escape( $id );
+			$wpdb->query("UPDATE $wpdb->users SET display_name = '$id' WHERE ID = '$user->ID'");
+		endif;
+
+		// FIXME: RESET_CAPS is temporary code to reset roles and caps if flag is set.
+		$caps = get_usermeta( $user->ID, $wpdb->prefix . 'capabilities');
+		if ( empty($caps) || defined('RESET_CAPS') ) {
+			$level = get_usermeta($user->ID, $wpdb->prefix . 'user_level');
+			$role = translate_level_to_role($level);
+			update_usermeta( $user->ID, $wpdb->prefix . 'capabilities', array($role => true) );
+		}
+
+	endforeach;
+	$old_user_fields = array( 'user_firstname', 'user_lastname', 'user_icq', 'user_aim', 'user_msn', 'user_yim', 'user_idmode', 'user_ip', 'user_domain', 'user_browser', 'user_description', 'user_nickname', 'user_level' );
+	$wpdb->hide_errors();
+	foreach ( $old_user_fields as $old )
+		$wpdb->query("ALTER TABLE $wpdb->users DROP $old");
+	$wpdb->show_errors();
+
+	if ( 0 == $wpdb->get_var("SELECT SUM(category_count) FROM $wpdb->categories") ) { // Create counts
+		$categories = $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories");
+		foreach ( $categories as $cat_id ) {
+			$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status='publish' AND category_id = '$cat_id'");
+			$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
+		}
+	}
+
+	// populate comment_count field of posts table
+	$comments = $wpdb->get_results( "SELECT comment_post_ID, COUNT(*) as c FROM $wpdb->comments WHERE comment_approved = '1' GROUP BY comment_post_ID" );
+	if( is_array( $comments ) ) {
+		foreach ($comments as $comment) {
+			$wpdb->query( "UPDATE $wpdb->posts SET comment_count = $comment->c WHERE ID = '$comment->comment_post_ID'" );
+		}
+	}
+
+	// Some alpha versions used a post status of object instead of attachment and put
+	// the mime type in post_type instead of post_mime_type.
+	if ( $wp_current_db_version > 2541 && $wp_current_db_version <= 3091 ) {
+		$objects = $wpdb->get_results("SELECT ID, post_type FROM $wpdb->posts WHERE post_status = 'object'");
+		foreach ($objects as $object) {
+			$wpdb->query("UPDATE $wpdb->posts SET post_status = 'attachment',
+			post_mime_type = '$object->post_type',
+			post_type = ''
+			WHERE ID = $object->ID");
+
+			$meta = get_post_meta($object->ID, 'imagedata', true);
+			if ( ! empty($meta['file']) )
+				update_attached_file( $object->ID, $meta['file'] );
+		}
+	}
+}
+
+function upgrade_210() {
+	global $wpdb, $wp_current_db_version;
+
+	if ( $wp_current_db_version < 3506 ) {
+		// Update status and type.
+		$posts = $wpdb->get_results("SELECT ID, post_status FROM $wpdb->posts");
+
+		if ( ! empty($posts) ) foreach ($posts as $post) {
+			$status = $post->post_status;
+			$type = 'post';
+
+			if ( 'static' == $status ) {
+				$status = 'publish';
+				$type = 'page';
+			} else if ( 'attachment' == $status ) {
+				$status = 'inherit';
+				$type = 'attachment';
+			}
+
+			$wpdb->query("UPDATE $wpdb->posts SET post_status = '$status', post_type = '$type' WHERE ID = '$post->ID'");
+		}
+	}
+
+	if ( $wp_current_db_version < 3845 ) {
+		populate_roles_210();
+	}
+
+	if ( $wp_current_db_version < 3531 ) {
+		// Give future posts a post_status of future.
+		$now = gmdate('Y-m-d H:i:59');
+		$wpdb->query ("UPDATE $wpdb->posts SET post_status = 'future' WHERE post_status = 'publish' AND post_date_gmt > '$now'");
+
+		$posts = $wpdb->get_results("SELECT ID, post_date FROM $wpdb->posts WHERE post_status ='future'");
+		if ( !empty($posts) )
+			foreach ( $posts as $post )
+				wp_schedule_single_event(mysql2date('U', $post->post_date), 'publish_future_post', array($post->ID));
+	}
+
+	if ( $wp_current_db_version < 3570 ) {
+		// Create categories for link categories if a category with the same
+		// name doesn't exist.  Create a map of link cat IDs to cat IDs.
+		$link_cat_id_map = array();
+		$link_cats = $wpdb->get_results("SELECT cat_id, cat_name FROM " . $wpdb->prefix . 'linkcategories');
+		foreach ( $link_cats as $link_cat) {
+			if ( $cat_id = category_exists($link_cat->cat_name) ) {
+				$link_cat_id_map[$link_cat->cat_id] = $cat_id;
+				$default_link_cat = $cat_id;
+			} else {
+				$link_cat_id_map[$link_cat->cat_id] = wp_create_category($link_cat->cat_name);
+				$default_link_cat = $link_cat_id_map[$link_cat->cat_id];
+			}
+		}
+
+		// Associate links to cats.
+		$links = $wpdb->get_results("SELECT link_id, link_category FROM $wpdb->links");
+		if ( !empty($links) ) foreach ( $links as $link ) {
+			if ( 0 == $link->link_category )
+				continue;
+			if ( ! isset($link_cat_id_map[$link->link_category]) )
+				continue;
+			$link_cat = $link_cat_id_map[$link->link_category];
+			$cat = $wpdb->get_row("SELECT * FROM $wpdb->link2cat WHERE link_id = '$link->link_id' AND category_id = '$link_cat'");
+			if ( !$cat ) {
+				$wpdb->query("INSERT INTO $wpdb->link2cat (link_id, category_id)
+					VALUES ('$link->link_id', '$link_cat')");
+			}
+		}
+
+		// Set default to the last category we grabbed during the upgrade loop.
+		update_option('default_link_category', $default_link_cat);
+
+		// Count links per category.
+		if ( 0 == $wpdb->get_var("SELECT SUM(link_count) FROM $wpdb->categories") ) {
+			$categories = $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories");
+			foreach ( $categories as $cat_id ) {
+				$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->link2cat, $wpdb->links WHERE $wpdb->links.link_id = $wpdb->link2cat.link_id AND category_id = '$cat_id'");
+				$wpdb->query("UPDATE $wpdb->categories SET link_count = '$count' WHERE cat_ID = '$cat_id'");
+			}
+		}
+	}
+
+	if ( $wp_current_db_version < 4772 ) {
+		// Obsolete linkcategories table
+		$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'linkcategories');
+	}
+}
+
+function upgrade_old_slugs() {
+	// upgrade people who were using the Redirect Old Slugs plugin
+	global $wpdb;
+	$wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_wp_old_slug' WHERE meta_key = 'old_slug'");
+}
+
+
+// The functions we use to actually do stuff
+
+// General
+function maybe_create_table($table_name, $create_ddl) {
+	global $wpdb;
+	foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
+		if ($table == $table_name) {
+			return true;
+		}
+	}
+	//didn't find it try to create it.
+	$q = $wpdb->query($create_ddl);
+	// we cannot directly tell that whether this succeeded!
+	foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
+		if ($table == $table_name) {
+			return true;
+		}
+	}
+	return false;
+}
+
+function drop_index($table, $index) {
+	global $wpdb;
+	$wpdb->hide_errors();
+	$wpdb->query("ALTER TABLE `$table` DROP INDEX `$index`");
+	// Now we need to take out all the extra ones we may have created
+	for ($i = 0; $i < 25; $i++) {
+		$wpdb->query("ALTER TABLE `$table` DROP INDEX `{$index}_$i`");
+	}
+	$wpdb->show_errors();
+	return true;
+}
+
+function add_clean_index($table, $index) {
+	global $wpdb;
+	drop_index($table, $index);
+	$wpdb->query("ALTER TABLE `$table` ADD INDEX ( `$index` )");
+	return true;
+}
+
+/**
+ ** maybe_add_column()
+ ** Add column to db table if it doesn't exist.
+ ** Returns:  true if already exists or on successful completion
+ **           false on error
+ */
+function maybe_add_column($table_name, $column_name, $create_ddl) {
+	global $wpdb, $debug;
+	foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
+		if ($debug) echo("checking $column == $column_name<br />");
+		if ($column == $column_name) {
+			return true;
+		}
+	}
+	//didn't find it try to create it.
+	$q = $wpdb->query($create_ddl);
+	// we cannot directly tell that whether this succeeded!
+	foreach ($wpdb->get_col("DESC $table_name", 0) as $column ) {
+		if ($column == $column_name) {
+			return true;
+		}
+	}
+	return false;
+}
+
+
+// get_alloptions as it was for 1.2.
+function get_alloptions_110() {
+	global $wpdb;
+	if ($options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options")) {
+		foreach ($options as $option) {
+			// "When trying to design a foolproof system,
+			//  never underestimate the ingenuity of the fools :)" -- Dougal
+			if ('siteurl' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
+			if ('home' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
+			if ('category_base' == $option->option_name) $option->option_value = preg_replace('|/+$|', '', $option->option_value);
+			$all_options->{$option->option_name} = stripslashes($option->option_value);
+		}
+	}
+	return $all_options;
+}
+
+// Version of get_option that is private to install/upgrade.
+function __get_option($setting) {
+	global $wpdb;
+	
+	if ( $setting == 'home' && defined( 'WP_HOME' ) ) {
+		return preg_replace( '|/+$|', '', constant( 'WP_HOME' ) );
+	}
+	
+	if ( $setting == 'siteurl' && defined( 'WP_SITEURL' ) ) {
+		return preg_replace( '|/+$|', '', constant( 'WP_SITEURL' ) );
+	}
+	
+	$option = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting'");
+
+	if ( 'home' == $setting && '' == $option )
+		return __get_option('siteurl');
+
+	if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting )
+		$option = preg_replace('|/+$|', '', $option);
+
+	@ $kellogs = unserialize($option);
+	if ($kellogs !== FALSE)
+		return $kellogs;
+	else
+		return $option;
+}
+
+function deslash($content) {
+	// Note: \\\ inside a regex denotes a single backslash.
+
+	// Replace one or more backslashes followed by a single quote with
+	// a single quote.
+	$content = preg_replace("/\\\+'/", "'", $content);
+
+	// Replace one or more backslashes followed by a double quote with
+	// a double quote.
+	$content = preg_replace('/\\\+"/', '"', $content);
+
+	// Replace one or more backslashes with one backslash.
+	$content = preg_replace("/\\\+/", "\\", $content);
+
+	return $content;
+}
+
+function dbDelta($queries, $execute = true) {
+	global $wpdb;
+
+	// Seperate individual queries into an array
+	if( !is_array($queries) ) {
+		$queries = explode( ';', $queries );
+		if('' == $queries[count($queries) - 1]) array_pop($queries);
+	}
+
+	$cqueries = array(); // Creation Queries
+	$iqueries = array(); // Insertion Queries
+	$for_update = array();
+
+	// Create a tablename index for an array ($cqueries) of queries
+	foreach($queries as $qry) {
+		if(preg_match("|CREATE TABLE ([^ ]*)|", $qry, $matches)) {
+			$cqueries[strtolower($matches[1])] = $qry;
+			$for_update[$matches[1]] = 'Created table '.$matches[1];
+		}
+		else if(preg_match("|CREATE DATABASE ([^ ]*)|", $qry, $matches)) {
+			array_unshift($cqueries, $qry);
+		}
+		else if(preg_match("|INSERT INTO ([^ ]*)|", $qry, $matches)) {
+			$iqueries[] = $qry;
+		}
+		else if(preg_match("|UPDATE ([^ ]*)|", $qry, $matches)) {
+			$iqueries[] = $qry;
+		}
+		else {
+			// Unrecognized query type
+		}
+	}
+
+	// Check to see which tables and fields exist
+	if($tables = $wpdb->get_col('SHOW TABLES;')) {
+		// For every table in the database
+		foreach($tables as $table) {
+			// If a table query exists for the database table...
+			if( array_key_exists(strtolower($table), $cqueries) ) {
+				// Clear the field and index arrays
+				unset($cfields);
+				unset($indices);
+				// Get all of the field names in the query from between the parens
+				preg_match("|\((.*)\)|ms", $cqueries[strtolower($table)], $match2);
+				$qryline = trim($match2[1]);
+
+				// Separate field lines into an array
+				$flds = explode("\n", $qryline);
+
+				//echo "<hr/><pre>\n".print_r(strtolower($table), true).":\n".print_r($cqueries, true)."</pre><hr/>";
+
+				// For every field line specified in the query
+				foreach($flds as $fld) {
+					// Extract the field name
+					preg_match("|^([^ ]*)|", trim($fld), $fvals);
+					$fieldname = $fvals[1];
+
+					// Verify the found field name
+					$validfield = true;
+					switch(strtolower($fieldname))
+					{
+					case '':
+					case 'primary':
+					case 'index':
+					case 'fulltext':
+					case 'unique':
+					case 'key':
+						$validfield = false;
+						$indices[] = trim(trim($fld), ", \n");
+						break;
+					}
+					$fld = trim($fld);
+
+					// If it's a valid field, add it to the field array
+					if($validfield) {
+						$cfields[strtolower($fieldname)] = trim($fld, ", \n");
+					}
+				}
+
+				// Fetch the table column structure from the database
+				$tablefields = $wpdb->get_results("DESCRIBE {$table};");
+
+				// For every field in the table
+				foreach($tablefields as $tablefield) {
+					// If the table field exists in the field array...
+					if(array_key_exists(strtolower($tablefield->Field), $cfields)) {
+						// Get the field type from the query
+						preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
+						$fieldtype = $matches[1];
+
+						// Is actual field type different from the field type in query?
+						if($tablefield->Type != $fieldtype) {
+							// Add a query to change the column type
+							$cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
+							$for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
+						}
+
+						// Get the default value from the array
+							//echo "{$cfields[strtolower($tablefield->Field)]}<br>";
+						if(preg_match("| DEFAULT '(.*)'|i", $cfields[strtolower($tablefield->Field)], $matches)) {
+							$default_value = $matches[1];
+							if($tablefield->Default != $default_value)
+							{
+								// Add a query to change the column's default value
+								$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT '{$default_value}'";
+								$for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
+							}
+						}
+
+						// Remove the field from the array (so it's not added)
+						unset($cfields[strtolower($tablefield->Field)]);
+					}
+					else {
+						// This field exists in the table, but not in the creation queries?
+					}
+				}
+
+				// For every remaining field specified for the table
+				foreach($cfields as $fieldname => $fielddef) {
+					// Push a query line into $cqueries that adds the field to that table
+					$cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
+					$for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
+				}
+
+				// Index stuff goes here
+				// Fetch the table index structure from the database
+				$tableindices = $wpdb->get_results("SHOW INDEX FROM {$table};");
+
+				if($tableindices) {
+					// Clear the index array
+					unset($index_ary);
+
+					// For every index in the table
+					foreach($tableindices as $tableindex) {
+						// Add the index to the index data array
+						$keyname = $tableindex->Key_name;
+						$index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
+						$index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
+					}
+
+					// For each actual index in the index array
+					foreach($index_ary as $index_name => $index_data) {
+						// Build a create string to compare to the query
+						$index_string = '';
+						if($index_name == 'PRIMARY') {
+							$index_string .= 'PRIMARY ';
+						}
+						else if($index_data['unique']) {
+							$index_string .= 'UNIQUE ';
+						}
+						$index_string .= 'KEY ';
+						if($index_name != 'PRIMARY') {
+							$index_string .= $index_name;
+						}
+						$index_columns = '';
+						// For each column in the index
+						foreach($index_data['columns'] as $column_data) {
+							if($index_columns != '') $index_columns .= ',';
+							// Add the field to the column list string
+							$index_columns .= $column_data['fieldname'];
+							if($column_data['subpart'] != '') {
+								$index_columns .= '('.$column_data['subpart'].')';
+							}
+						}
+						// Add the column list to the index create string
+						$index_string .= ' ('.$index_columns.')';
+
+						if(!(($aindex = array_search($index_string, $indices)) === false)) {
+							unset($indices[$aindex]);
+							//echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br/>Found index:".$index_string."</pre>\n";
+						}
+						//else echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">{$table}:<br/><b>Did not find index:</b>".$index_string."<br/>".print_r($indices, true)."</pre>\n";
+					}
+				}
+
+				// For every remaining index specified for the table
+				foreach($indices as $index) {
+					// Push a query line into $cqueries that adds the index to that table
+					$cqueries[] = "ALTER TABLE {$table} ADD $index";
+					$for_update[$table.'.'.$fieldname] = 'Added index '.$table.' '.$index;
+				}
+
+				// Remove the original table creation query from processing
+				unset($cqueries[strtolower($table)]);
+				unset($for_update[strtolower($table)]);
+			} else {
+				// This table exists in the database, but not in the creation queries?
+			}
+		}
+	}
+
+	$allqueries = array_merge($cqueries, $iqueries);
+	if($execute) {
+		foreach($allqueries as $query) {
+			//echo "<pre style=\"border:1px solid #ccc;margin-top:5px;\">".print_r($query, true)."</pre>\n";
+			$wpdb->query($query);
+		}
+	}
+
+	return $for_update;
+}
+
+function make_db_current() {
+	global $wp_queries;
+
+	$alterations = dbDelta($wp_queries);
+	echo "<ol>\n";
+	foreach($alterations as $alteration) echo "<li>$alteration</li>\n";
+	echo "</ol>\n";
+}
+
+function make_db_current_silent() {
+	global $wp_queries;
+
+	$alterations = dbDelta($wp_queries);
+}
+
+function make_site_theme_from_oldschool($theme_name, $template) {
+	$home_path = get_home_path();
+	$site_dir = ABSPATH . "wp-content/themes/$template";
+
+	if (! file_exists("$home_path/index.php"))
+		return false;
+
+	// Copy files from the old locations to the site theme.
+	// TODO: This does not copy arbitarary include dependencies.  Only the
+	// standard WP files are copied.
+	$files = array('index.php' => 'index.php', 'wp-layout.css' => 'style.css', 'wp-comments.php' => 'comments.php', 'wp-comments-popup.php' => 'comments-popup.php');
+
+	foreach ($files as $oldfile => $newfile) {
+		if ($oldfile == 'index.php')
+			$oldpath = $home_path;
+		else
+			$oldpath = ABSPATH;
+
+		if ($oldfile == 'index.php') { // Check to make sure it's not a new index
+			$index = implode('', file("$oldpath/$oldfile"));
+			if (strpos($index, 'WP_USE_THEMES') !== false) {
+				if (! @copy(ABSPATH . 'wp-content/themes/default/index.php', "$site_dir/$newfile"))
+					return false;
+				continue; // Don't copy anything
+				}
+		}
+
+		if (! @copy("$oldpath/$oldfile", "$site_dir/$newfile"))
+			return false;
+
+		chmod("$site_dir/$newfile", 0777);
+
+		// Update the blog header include in each file.
+		$lines = explode("\n", implode('', file("$site_dir/$newfile")));
+		if ($lines) {
+			$f = fopen("$site_dir/$newfile", 'w');
+
+			foreach ($lines as $line) {
+				if (preg_match('/require.*wp-blog-header/', $line))
+					$line = '//' . $line;
+
+				// Update stylesheet references.
+				$line = str_replace("<?php echo __get_option('siteurl'); ?>/wp-layout.css", "<?php bloginfo('stylesheet_url'); ?>", $line);
+
+				// Update comments template inclusion.
+				$line = str_replace("<?php include(ABSPATH . 'wp-comments.php'); ?>", "<?php comments_template(); ?>", $line);
+
+				fwrite($f, "{$line}\n");
+			}
+			fclose($f);
+		}
+	}
+
+	// Add a theme header.
+	$header = "/*\nTheme Name: $theme_name\nTheme URI: " . __get_option('siteurl') . "\nDescription: A theme automatically created by the upgrade.\nVersion: 1.0\nAuthor: Moi\n*/\n";
+
+	$stylelines = file_get_contents("$site_dir/style.css");
+	if ($stylelines) {
+		$f = fopen("$site_dir/style.css", 'w');
+
+		fwrite($f, $header);
+		fwrite($f, $stylelines);
+		fclose($f);
+	}
+
+	return true;
+}
+
+function make_site_theme_from_default($theme_name, $template) {
+	$site_dir = ABSPATH . "wp-content/themes/$template";
+	$default_dir = ABSPATH . 'wp-content/themes/default';
+
+	// Copy files from the default theme to the site theme.
+	//$files = array('index.php', 'comments.php', 'comments-popup.php', 'footer.php', 'header.php', 'sidebar.php', 'style.css');
+
+	$theme_dir = @ dir("$default_dir");
+	if ($theme_dir) {
+		while(($theme_file = $theme_dir->read()) !== false) {
+			if (is_dir("$default_dir/$theme_file"))
+				continue;
+			if (! @copy("$default_dir/$theme_file", "$site_dir/$theme_file"))
+				return;
+			chmod("$site_dir/$theme_file", 0777);
+		}
+	}
+
+	// Rewrite the theme header.
+	$stylelines = explode("\n", implode('', file("$site_dir/style.css")));
+	if ($stylelines) {
+		$f = fopen("$site_dir/style.css", 'w');
+
+		foreach ($stylelines as $line) {
+			if (strpos($line, 'Theme Name:') !== false) $line = 'Theme Name: ' . $theme_name;
+			elseif (strpos($line, 'Theme URI:') !== false) $line = 'Theme URI: ' . __get_option('url');
+			elseif (strpos($line, 'Description:') !== false) $line = 'Description: Your theme.';
+			elseif (strpos($line, 'Version:') !== false) $line = 'Version: 1';
+			elseif (strpos($line, 'Author:') !== false) $line = 'Author: You';
+			fwrite($f, $line . "\n");
+		}
+		fclose($f);
+	}
+
+	// Copy the images.
+	umask(0);
+	if (! mkdir("$site_dir/images", 0777)) {
+		return false;
+	}
+
+	$images_dir = @ dir("$default_dir/images");
+	if ($images_dir) {
+		while(($image = $images_dir->read()) !== false) {
+			if (is_dir("$default_dir/images/$image"))
+				continue;
+			if (! @copy("$default_dir/images/$image", "$site_dir/images/$image"))
+				return;
+			chmod("$site_dir/images/$image", 0777);
+		}
+	}
+}
+
+// Create a site theme from the default theme.
+function make_site_theme() {
+	// Name the theme after the blog.
+	$theme_name = __get_option('blogname');
+	$template = sanitize_title($theme_name);
+	$site_dir = ABSPATH . "wp-content/themes/$template";
+
+	// If the theme already exists, nothing to do.
+	if ( is_dir($site_dir)) {
+		return false;
+	}
+
+	// We must be able to write to the themes dir.
+	if (! is_writable(ABSPATH . "wp-content/themes")) {
+		return false;
+	}
+
+	umask(0);
+	if (! mkdir($site_dir, 0777)) {
+		return false;
+	}
+
+	if (file_exists(ABSPATH . 'wp-layout.css')) {
+		if (! make_site_theme_from_oldschool($theme_name, $template)) {
+			// TODO:  rm -rf the site theme directory.
+			return false;
+		}
+	} else {
+		if (! make_site_theme_from_default($theme_name, $template))
+			// TODO:  rm -rf the site theme directory.
+			return false;
+	}
+
+	// Make the new site theme active.
+	$current_template = __get_option('template');
+	if ($current_template == 'default') {
+		update_option('template', $template);
+		update_option('stylesheet', $template);
+	}
+	return $template;
+}
+
+function translate_level_to_role($level) {
+	switch ($level) {
+	case 10:
+	case 9:
+	case 8:
+		return 'administrator';
+	case 7:
+	case 6:
+	case 5:
+		return 'editor';
+	case 4:
+	case 3:
+	case 2:
+		return 'author';
+	case 1:
+		return 'contributor';
+	case 0:
+		return 'subscriber';
+	}
+}
+
+function wp_check_mysql_version() {
+	global $wp_version;
+
+	// Make sure the server has MySQL 4.0
+	$mysql_version = preg_replace('|[^0-9\.]|', '', @mysql_get_server_info());
+	if ( version_compare($mysql_version, '4.0.0', '<') )
+		die(sprintf(__('<strong>ERROR</strong>: WordPress %s requires MySQL 4.0.0 or higher'), $wp_version));
+}
+
+function maybe_disable_automattic_widgets() {
+	$plugins = __get_option( 'active_plugins' );
+	
+	foreach ( (array) $plugins as $plugin ) {
+		if ( basename( $plugin ) == 'widgets.php' ) {
+			array_splice( $plugins, array_search( $plugin, $plugins ), 1 );
+			update_option( 'active_plugins', $plugins );
+			break;
+		}
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/upgrade-schema.php 2.2.2/wp-admin/upgrade-schema.php
--- 2.0.5/wp-admin/upgrade-schema.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upgrade-schema.php	2007-04-19 17:26:52.000000000 -0500
@@ -0,0 +1,392 @@
+<?php
+// Here we keep the DB structure and option values
+
+$charset_collate = '';
+
+if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') ) {
+	if ( ! empty($wpdb->charset) )
+		$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
+	if ( ! empty($wpdb->collate) )
+		$charset_collate .= " COLLATE $wpdb->collate";
+}
+
+$wp_queries="CREATE TABLE $wpdb->categories (
+  cat_ID bigint(20) NOT NULL auto_increment,
+  cat_name varchar(55) NOT NULL default '',
+  category_nicename varchar(200) NOT NULL default '',
+  category_description longtext NOT NULL,
+  category_parent bigint(20) NOT NULL default '0',
+  category_count bigint(20) NOT NULL default '0',
+  link_count bigint(20) NOT NULL default '0',
+  posts_private tinyint(1) NOT NULL default '0',
+  links_private tinyint(1) NOT NULL default '0',
+  PRIMARY KEY  (cat_ID),
+  KEY category_nicename (category_nicename)
+) $charset_collate;
+CREATE TABLE $wpdb->comments (
+  comment_ID bigint(20) unsigned NOT NULL auto_increment,
+  comment_post_ID int(11) NOT NULL default '0',
+  comment_author tinytext NOT NULL,
+  comment_author_email varchar(100) NOT NULL default '',
+  comment_author_url varchar(200) NOT NULL default '',
+  comment_author_IP varchar(100) NOT NULL default '',
+  comment_date datetime NOT NULL default '0000-00-00 00:00:00',
+  comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
+  comment_content text NOT NULL,
+  comment_karma int(11) NOT NULL default '0',
+  comment_approved enum('0','1','spam') NOT NULL default '1',
+  comment_agent varchar(255) NOT NULL default '',
+  comment_type varchar(20) NOT NULL default '',
+  comment_parent bigint(20) NOT NULL default '0',
+  user_id bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (comment_ID),
+  KEY comment_approved (comment_approved),
+  KEY comment_post_ID (comment_post_ID)
+) $charset_collate;
+CREATE TABLE $wpdb->link2cat (
+  rel_id bigint(20) NOT NULL auto_increment,
+  link_id bigint(20) NOT NULL default '0',
+  category_id bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (rel_id),
+  KEY link_id (link_id,category_id)
+) $charset_collate;
+CREATE TABLE $wpdb->links (
+  link_id bigint(20) NOT NULL auto_increment,
+  link_url varchar(255) NOT NULL default '',
+  link_name varchar(255) NOT NULL default '',
+  link_image varchar(255) NOT NULL default '',
+  link_target varchar(25) NOT NULL default '',
+  link_category bigint(20) NOT NULL default '0',
+  link_description varchar(255) NOT NULL default '',
+  link_visible enum('Y','N') NOT NULL default 'Y',
+  link_owner int(11) NOT NULL default '1',
+  link_rating int(11) NOT NULL default '0',
+  link_updated datetime NOT NULL default '0000-00-00 00:00:00',
+  link_rel varchar(255) NOT NULL default '',
+  link_notes mediumtext NOT NULL,
+  link_rss varchar(255) NOT NULL default '',
+  PRIMARY KEY  (link_id),
+  KEY link_category (link_category),
+  KEY link_visible (link_visible)
+) $charset_collate;
+CREATE TABLE $wpdb->options (
+  option_id bigint(20) NOT NULL auto_increment,
+  blog_id int(11) NOT NULL default '0',
+  option_name varchar(64) NOT NULL default '',
+  option_can_override enum('Y','N') NOT NULL default 'Y',
+  option_type int(11) NOT NULL default '1',
+  option_value longtext NOT NULL,
+  option_width int(11) NOT NULL default '20',
+  option_height int(11) NOT NULL default '8',
+  option_description tinytext NOT NULL,
+  option_admin_level int(11) NOT NULL default '1',
+  autoload enum('yes','no') NOT NULL default 'yes',
+  PRIMARY KEY  (option_id,blog_id,option_name),
+  KEY option_name (option_name)
+) $charset_collate;
+CREATE TABLE $wpdb->post2cat (
+  rel_id bigint(20) NOT NULL auto_increment,
+  post_id bigint(20) NOT NULL default '0',
+  category_id bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (rel_id),
+  KEY post_id (post_id,category_id)
+) $charset_collate;
+CREATE TABLE $wpdb->postmeta (
+  meta_id bigint(20) NOT NULL auto_increment,
+  post_id bigint(20) NOT NULL default '0',
+  meta_key varchar(255) default NULL,
+  meta_value longtext,
+  PRIMARY KEY  (meta_id),
+  KEY post_id (post_id),
+  KEY meta_key (meta_key)
+) $charset_collate;
+CREATE TABLE $wpdb->posts (
+  ID bigint(20) unsigned NOT NULL auto_increment,
+  post_author bigint(20) NOT NULL default '0',
+  post_date datetime NOT NULL default '0000-00-00 00:00:00',
+  post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00',
+  post_content longtext NOT NULL,
+  post_title text NOT NULL,
+  post_category int(4) NOT NULL default '0',
+  post_excerpt text NOT NULL,
+  post_status enum('publish','draft','private','static','object','attachment','inherit','future') NOT NULL default 'publish',
+  comment_status enum('open','closed','registered_only') NOT NULL default 'open',
+  ping_status enum('open','closed') NOT NULL default 'open',
+  post_password varchar(20) NOT NULL default '',
+  post_name varchar(200) NOT NULL default '',
+  to_ping text NOT NULL,
+  pinged text NOT NULL,
+  post_modified datetime NOT NULL default '0000-00-00 00:00:00',
+  post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00',
+  post_content_filtered text NOT NULL,
+  post_parent bigint(20) NOT NULL default '0',
+  guid varchar(255) NOT NULL default '',
+  menu_order int(11) NOT NULL default '0',
+  post_type varchar(20) NOT NULL default 'post',
+  post_mime_type varchar(100) NOT NULL default '',
+  comment_count bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (ID),
+  KEY post_name (post_name),
+  KEY type_status_date (post_type,post_status,post_date,ID)
+) $charset_collate;
+CREATE TABLE $wpdb->users (
+  ID bigint(20) unsigned NOT NULL auto_increment,
+  user_login varchar(60) NOT NULL default '',
+  user_pass varchar(64) NOT NULL default '',
+  user_nicename varchar(50) NOT NULL default '',
+  user_email varchar(100) NOT NULL default '',
+  user_url varchar(100) NOT NULL default '',
+  user_registered datetime NOT NULL default '0000-00-00 00:00:00',
+  user_activation_key varchar(60) NOT NULL default '',
+  user_status int(11) NOT NULL default '0',
+  display_name varchar(250) NOT NULL default '',
+  PRIMARY KEY  (ID),
+  KEY user_login_key (user_login)
+) $charset_collate;
+CREATE TABLE $wpdb->usermeta (
+  umeta_id bigint(20) NOT NULL auto_increment,
+  user_id bigint(20) NOT NULL default '0',
+  meta_key varchar(255) default NULL,
+  meta_value longtext,
+  PRIMARY KEY  (umeta_id),
+  KEY user_id (user_id),
+  KEY meta_key (meta_key)
+) $charset_collate;";
+
+function populate_options() {
+	global $wpdb, $wp_db_version;
+
+	$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
+	$guessurl = preg_replace('|/wp-admin/.*|i', '', $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
+	add_option('siteurl', $guessurl, __('WordPress web address'));
+	add_option('blogname', __('My Weblog'), __('Blog title'));
+	add_option('blogdescription', __('Just another WordPress weblog'), __('Short tagline'));
+	add_option('new_users_can_blog', 0);
+	add_option('users_can_register', 0);
+	add_option('admin_email', 'you@example.com');
+	add_option('start_of_week', 1);
+	add_option('use_balanceTags', 0);
+	add_option('use_smilies', 1);
+	add_option('require_name_email', 1);
+	add_option('comments_notify', 1);
+	add_option('posts_per_rss', 10);
+	add_option('rss_excerpt_length', 50);
+	add_option('rss_use_excerpt', 0);
+	add_option('mailserver_url', 'mail.example.com');
+	add_option('mailserver_login', 'login@example.com');
+	add_option('mailserver_pass', 'password');
+	add_option('mailserver_port', 110);
+	add_option('default_category', 1);
+	add_option('default_comment_status', 'open');
+	add_option('default_ping_status', 'open');
+	add_option('default_pingback_flag', 1);
+	add_option('default_post_edit_rows', 10);
+	add_option('posts_per_page', 10);
+	add_option('what_to_show', 'posts');
+	add_option('date_format', __('F j, Y'));
+	add_option('time_format', __('g:i a'));
+	add_option('links_updated_date_format', __('F j, Y g:i a'));
+	add_option('links_recently_updated_prepend', '<em>');
+	add_option('links_recently_updated_append', '</em>');
+	add_option('links_recently_updated_time', 120);
+	add_option('comment_moderation', 0);
+	add_option('moderation_notify', 1);
+	add_option('permalink_structure');
+	add_option('gzipcompression', 0);
+	add_option('hack_file', 0);
+	add_option('blog_charset', 'UTF-8');
+	add_option('moderation_keys');
+	add_option('active_plugins');
+	add_option('home', $guessurl);
+	// in case it is set, but blank, update "home"
+	if ( !__get_option('home') ) update_option('home', $guessurl);
+	add_option('category_base');
+	add_option('ping_sites', 'http://rpc.pingomatic.com/');
+	add_option('advanced_edit', 0);
+	add_option('comment_max_links', 2);
+	add_option('gmt_offset', date('Z') / 3600);
+	// 1.5
+	add_option('default_email_category', 1, __('Posts by email go to this category'));
+	add_option('recently_edited');
+	add_option('use_linksupdate', 0);
+	add_option('template', 'default');
+	add_option('stylesheet', 'default');
+	add_option('comment_whitelist', 1);
+	add_option('page_uris');
+	add_option('blacklist_keys');
+	add_option('comment_registration', 0);
+	add_option('rss_language', 'en');
+	add_option('html_type', 'text/html');
+	// 1.5.1
+	add_option('use_trackback', 0);
+	// 2.0
+	add_option('default_role', 'subscriber');
+	add_option('db_version', $wp_db_version);
+	// 2.0.1
+	if ( ini_get('safe_mode') ) {
+		// Safe mode screws up mkdir(), so we must use a flat structure.
+		add_option('uploads_use_yearmonth_folders', 0);
+		add_option('upload_path', 'wp-content');
+	} else {
+		add_option('uploads_use_yearmonth_folders', 1);
+		add_option('upload_path', 'wp-content/uploads');
+	}
+
+	// 2.0.3
+	add_option('secret', md5(uniqid(microtime())));
+
+	// 2.1
+	add_option('blog_public', '1');
+	add_option('default_link_category', 2);
+	add_option('show_on_front', 'posts');
+
+	// Delete unused options
+	$unusedoptions = array ('blodotgsping_url', 'bodyterminator', 'emailtestonly', 'phoneemail_separator', 'smilies_directory', 'subjectprefix', 'use_bbcode', 'use_blodotgsping', 'use_phoneemail', 'use_quicktags', 'use_weblogsping', 'weblogs_cache_file', 'use_preview', 'use_htmltrans', 'smilies_directory', 'fileupload_allowedusers', 'use_phoneemail', 'default_post_status', 'default_post_category', 'archive_mode', 'time_difference', 'links_minadminlevel', 'links_use_adminlevels', 'links_rating_type', 'links_rating_char', 'links_rating_ignore_zero', 'links_rating_single_image', 'links_rating_image0', 'links_rating_image1', 'links_rating_image2', 'links_rating_image3', 'links_rating_image4', 'links_rating_image5', 'links_rating_image6', 'links_rating_image7', 'links_rating_image8', 'links_rating_image9', 'weblogs_cacheminutes', 'comment_allowed_tags', 'search_engine_friendly_urls', 'default_geourl_lat', 'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce', '_wp_http_referer', 'Update', 'action', 'rich_editing');
+	foreach ($unusedoptions as $option) :
+		delete_option($option);
+	endforeach;
+
+	// Set up a few options not to load by default
+	$fatoptions = array( 'moderation_keys', 'recently_edited', 'blacklist_keys' );
+	foreach ($fatoptions as $fatoption) :
+		$wpdb->query("UPDATE $wpdb->options SET `autoload` = 'no' WHERE option_name = '$fatoption'");
+	endforeach;
+}
+
+function populate_roles() {
+	populate_roles_160();
+	populate_roles_210();
+}
+
+function populate_roles_160() {
+	global $wp_roles;
+
+	// Add roles
+	add_role('administrator', __('Administrator'));
+	add_role('editor', __('Editor'));
+	add_role('author', __('Author'));
+	add_role('contributor', __('Contributor'));
+	add_role('subscriber', __('Subscriber'));
+
+	// Add caps for Administrator role
+	$role = get_role('administrator');
+	$role->add_cap('switch_themes');
+	$role->add_cap('edit_themes');
+	$role->add_cap('activate_plugins');
+	$role->add_cap('edit_plugins');
+	$role->add_cap('edit_users');
+	$role->add_cap('edit_files');
+	$role->add_cap('manage_options');
+	$role->add_cap('moderate_comments');
+	$role->add_cap('manage_categories');
+	$role->add_cap('manage_links');
+	$role->add_cap('upload_files');
+	$role->add_cap('import');
+	$role->add_cap('unfiltered_html');
+	$role->add_cap('edit_posts');
+	$role->add_cap('edit_others_posts');
+	$role->add_cap('edit_published_posts');
+	$role->add_cap('publish_posts');
+	$role->add_cap('edit_pages');
+	$role->add_cap('read');
+	$role->add_cap('level_10');
+	$role->add_cap('level_9');
+	$role->add_cap('level_8');
+	$role->add_cap('level_7');
+	$role->add_cap('level_6');
+	$role->add_cap('level_5');
+	$role->add_cap('level_4');
+	$role->add_cap('level_3');
+	$role->add_cap('level_2');
+	$role->add_cap('level_1');
+	$role->add_cap('level_0');
+
+	// Add caps for Editor role
+	$role = get_role('editor');
+	$role->add_cap('moderate_comments');
+	$role->add_cap('manage_categories');
+	$role->add_cap('manage_links');
+	$role->add_cap('upload_files');
+	$role->add_cap('unfiltered_html');
+	$role->add_cap('edit_posts');
+	$role->add_cap('edit_others_posts');
+	$role->add_cap('edit_published_posts');
+	$role->add_cap('publish_posts');
+	$role->add_cap('edit_pages');
+	$role->add_cap('read');
+	$role->add_cap('level_7');
+	$role->add_cap('level_6');
+	$role->add_cap('level_5');
+	$role->add_cap('level_4');
+	$role->add_cap('level_3');
+	$role->add_cap('level_2');
+	$role->add_cap('level_1');
+	$role->add_cap('level_0');
+
+	// Add caps for Author role
+	$role = get_role('author');
+	$role->add_cap('upload_files');
+	$role->add_cap('edit_posts');
+	$role->add_cap('edit_published_posts');
+	$role->add_cap('publish_posts');
+	$role->add_cap('read');
+	$role->add_cap('level_2');
+	$role->add_cap('level_1');
+	$role->add_cap('level_0');
+
+	// Add caps for Contributor role
+	$role = get_role('contributor');
+	$role->add_cap('edit_posts');
+	$role->add_cap('read');
+	$role->add_cap('level_1');
+	$role->add_cap('level_0');
+
+	// Add caps for Subscriber role
+	$role = get_role('subscriber');
+	$role->add_cap('read');
+	$role->add_cap('level_0');
+}
+
+function populate_roles_210() {
+	$roles = array('administrator', 'editor');
+	foreach ($roles as $role) {
+		$role = get_role($role);
+		if ( empty($role) )
+			continue;
+
+		$role->add_cap('edit_others_pages');
+		$role->add_cap('edit_published_pages');
+		$role->add_cap('publish_pages');
+		$role->add_cap('delete_pages');
+		$role->add_cap('delete_others_pages');
+		$role->add_cap('delete_published_pages');
+		$role->add_cap('delete_posts');
+		$role->add_cap('delete_others_posts');
+		$role->add_cap('delete_published_posts');
+		$role->add_cap('delete_private_posts');
+		$role->add_cap('edit_private_posts');
+		$role->add_cap('read_private_posts');
+		$role->add_cap('delete_private_pages');
+		$role->add_cap('edit_private_pages');
+		$role->add_cap('read_private_pages');
+	}
+
+	$role = get_role('administrator');
+	if ( ! empty($role) ) {
+		$role->add_cap('delete_users');
+		$role->add_cap('create_users');
+	}
+
+	$role = get_role('author');
+	if ( ! empty($role) ) {
+		$role->add_cap('delete_posts');
+		$role->add_cap('delete_published_posts');
+	}
+
+	$role = get_role('contributor');
+	if ( ! empty($role) ) {
+		$role->add_cap('delete_posts');
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/upgrade.php 2.2.2/wp-admin/upgrade.php
--- 2.0.5/wp-admin/upgrade.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upgrade.php	2007-03-17 03:46:59.000000000 -0500
@@ -0,0 +1,72 @@
+<?php
+define('WP_INSTALLING', true);
+if (!file_exists('../wp-config.php'))
+	die("There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Installing_WordPress#Step_3:_Set_up_wp-config.php'>We got it</a>. You can <a href='setup-config.php'>create a <code>wp-config.php</code> file through a web interface</a>, but this doesn't work for all server setups. The safest way is to manually create the file.");
+
+require('../wp-config.php');
+timer_start();
+require_once(ABSPATH . '/wp-admin/upgrade-functions.php');
+
+if (isset($_GET['step']))
+	$step = (int) $_GET['step'];
+else
+	$step = 0;
+@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
+<head>
+	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
+	<title><?php _e('WordPress &rsaquo; Upgrade'); ?></title>
+	<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/install.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+	<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+	<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/install-rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+	<?php endif; ?>
+</head>
+<body>
+<h1 id="logo"><img alt="WordPress" src="images/wordpress-logo.png" /></h1>
+
+<?php if ( get_option('db_version') == $wp_db_version ) : ?>
+
+<h2><?php _e('No Upgrade Required'); ?></h2>
+<p><?php _e('Your WordPress database is already up-to-date!'); ?></p>
+<h2 class="step"><a href="<?php echo get_option('home'); ?>/"><?php _e('Continue &raquo;'); ?></a></h2>
+
+<?php else :
+switch($step) :
+	case 0:
+		$goback = clean_url(stripslashes(wp_get_referer()));
+?>
+<h2><?php _e('Database Upgrade Required'); ?></h2>
+<p><?php _e('Your WordPress database is out-of-date, and must be upgraded before you can continue.'); ?></p>
+<p><?php _e('The upgrade process may take a while, so please be patient.'); ?></p> 
+<h2 class="step"><a href="upgrade.php?step=1&amp;backto=<?php echo $goback; ?>"><?php _e('Upgrade WordPress &raquo;'); ?></a></h2>
+<?php
+		break;
+	case 1:
+		wp_upgrade();
+
+		if ( empty( $_GET['backto'] ) )
+			$backto = __get_option('home') . '/';
+		else
+			$backto = clean_url(stripslashes($_GET['backto']));
+?> 
+<h2><?php _e('Upgrade Complete'); ?></h2>
+	<p><?php _e('Your WordPress database has been successfully upgraded!'); ?></p>
+	<h2 class="step"><a href="<?php echo $backto; ?>"><?php _e('Continue &raquo;'); ?></a></h2>
+
+<!--
+<pre>
+<?php printf(__('%s queries'), $wpdb->num_queries); ?>
+
+<?php printf(__('%s seconds'), timer_stop(0)); ?>
+</pre>
+-->
+
+<?php
+		break;
+endswitch;
+endif;
+?>
+</body>
+</html>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/upload-functions.php 2.2.2/wp-admin/upload-functions.php
--- 2.0.5/wp-admin/upload-functions.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upload-functions.php	2007-08-01 15:58:38.000000000 -0500
@@ -0,0 +1,360 @@
+<?php
+function wp_upload_display( $dims = false, $href = '' ) {
+	global $post;
+	$id = get_the_ID();
+	$attachment_data = wp_get_attachment_metadata( $id );
+	$is_image = (int) wp_attachment_is_image();
+	if ( !isset($attachment_data['width']) && $is_image ) {
+		if ( $image_data = getimagesize( get_attached_file( $id ) ) ) {
+			$attachment_data['width'] = $image_data[0];
+			$attachment_data['height'] = $image_data[1];
+			wp_update_attachment_metadata( $id, $attachment_data );
+		}
+	}
+	if ( isset($attachment_data['width']) )
+		list($width,$height) = wp_shrink_dimensions($attachment_data['width'], $attachment_data['height'], 171, 128);
+
+	ob_start();
+		the_title();
+		$post_title = attribute_escape(ob_get_contents());
+	ob_end_clean();
+	$post_content = attribute_escape(apply_filters( 'content_edit_pre', $post->post_content ));
+
+	$class = 'text';
+	$innerHTML = get_attachment_innerHTML( $id, false, $dims );
+	if ( $image_src = get_attachment_icon_src() ) {
+		$image_rel = wp_make_link_relative($image_src);
+		$innerHTML = '&nbsp;' . str_replace($image_src, $image_rel, $innerHTML);
+		$class = 'image';
+	}
+
+	$src_base = wp_get_attachment_url();
+	$src = wp_make_link_relative( $src_base );
+	$src_base = str_replace($src, '', $src_base);
+
+	$r = '';
+
+	if ( $href )
+		$r .= "<a id='file-link-$id' href='$href' title='$post_title' class='file-link $class'>\n";
+	if ( $href || $image_src )
+		$r .= "\t\t\t$innerHTML";
+	if ( $href )
+		$r .= "</a>\n";
+	$r .= "\n\t\t<div class='upload-file-data'>\n\t\t\t<p>\n";
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-url-$id' id='attachment-url-$id' value='$src' />\n";
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-url-base-$id' id='attachment-url-base-$id' value='$src_base' />\n";
+
+	if ( !$thumb_base = wp_get_attachment_thumb_url() )
+		$thumb_base = wp_mime_type_icon();
+	if ( $thumb_base ) {
+		$thumb_rel = wp_make_link_relative( $thumb_base );
+		$thumb_base = str_replace( $thumb_rel, '', $thumb_base );
+		$r .= "\t\t\t\t<input type='hidden' name='attachment-thumb-url-$id' id='attachment-thumb-url-$id' value='$thumb_rel' />\n";
+		$r .= "\t\t\t\t<input type='hidden' name='attachment-thumb-url-base-$id' id='attachment-thumb-url-base-$id' value='$thumb_base' />\n";
+	}
+
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-is-image-$id' id='attachment-is-image-$id' value='$is_image' />\n";
+
+	if ( isset($width) ) {
+		$r .= "\t\t\t\t<input type='hidden' name='attachment-width-$id' id='attachment-width-$id' value='$width' />\n";
+		$r .= "\t\t\t\t<input type='hidden' name='attachment-height-$id' id='attachment-height-$id' value='$height' />\n";
+	}
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-page-url-$id' id='attachment-page-url-$id' value='" . get_attachment_link( $id ) . "' />\n";
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-title-$id' id='attachment-title-$id' value='$post_title' />\n";
+	$r .= "\t\t\t\t<input type='hidden' name='attachment-description-$id' id='attachment-description-$id' value='$post_content' />\n";
+	$r .= "\t\t\t</p>\n\t\t</div>\n";
+	return $r;
+}
+
+function wp_upload_view() {
+	global $style, $post_id, $style;
+	$id = get_the_ID();
+	$attachment_data = wp_get_attachment_metadata( $id );
+?>
+	<div id="upload-file">
+		<div id="file-title">
+			<h2><?php if ( !isset($attachment_data['width']) && 'inline' != $style )
+					echo "<a href='" . wp_get_attachment_url() . "' title='" . __('Direct link to file') . "'>";
+				the_title();
+				if ( !isset($attachment_data['width']) && 'inline' != $style )
+					echo '</a>';
+			?></h2>
+			<span><?php
+				echo '[&nbsp;';
+				echo '<a href="' . get_permalink() . '">' . __('view') . '</a>';
+				echo '&nbsp;|&nbsp;';
+					echo '<a href="' . clean_url(add_query_arg('action', 'edit')) . '" title="' . __('Edit this file') . '">' . __('edit') . '</a>';
+				echo '&nbsp;|&nbsp;';
+				echo '<a href="' . clean_url(remove_query_arg(array('action', 'ID'))) . '" title="' . __('Browse your files') . '">' . __('cancel') . '</a>';
+				echo '&nbsp;]'; ?></span>
+		</div>
+
+		<div id="upload-file-view" class="alignleft">
+<?php		if ( isset($attachment_data['width']) && 'inline' != $style )
+			echo "<a href='" . wp_get_attachment_url() . "' title='" . __('Direct link to file') . "'>";
+		echo wp_upload_display( array(171, 128) );
+		if ( isset($attachment_data['width']) && 'inline' != $style )
+			echo '</a>'; ?>
+		</div>
+		<?php the_attachment_links( $id ); ?>
+	</div>
+<?php	echo "<form action='' id='browse-form'><input type='hidden' id='nonce-value' value='" . wp_create_nonce( 'inlineuploading' )  . "' /></form>\n";
+}
+
+function wp_upload_form() {
+	$id = get_the_ID();
+	global $post_id, $tab, $style;
+	$enctype = $id ? '' : ' enctype="multipart/form-data"';
+	$post_id = (int) $post_id;
+?>
+	<form<?php echo $enctype; ?> id="upload-file" method="post" action="<?php echo get_option('siteurl') . '/wp-admin/upload.php?style=' . attribute_escape($style . '&amp;tab=upload&amp;post_id=' . $post_id); ?>">
+<?php
+	if ( $id ) :
+		$attachment = get_post_to_edit( $id );
+		$attachment_data = wp_get_attachment_metadata( $id );
+?>
+		<div id="file-title">
+			<h2><?php if ( !isset($attachment_data['width']) && 'inline' != $style )
+					echo "<a href='" . wp_get_attachment_url() . "' title='" . __('Direct link to file') . "'>";
+				the_title();
+				if ( !isset($attachment_data['width']) && 'inline' != $style )
+					echo '</a>';
+			?></h2>
+			<span><?php
+				echo '[&nbsp;';
+				echo '<a href="' . get_permalink() . '">' . __('view') . '</a>';
+				echo '&nbsp;|&nbsp;';
+					echo '<a href="' . clean_url(add_query_arg('action', 'view')) . '">' . __('links') . '</a>';
+				echo '&nbsp;|&nbsp;';
+				echo '<a href="' . clean_url(remove_query_arg(array('action','ID'))) . '" title="' . __('Browse your files') . '">' . __('cancel') . '</a>';
+				echo '&nbsp;]'; ?></span>
+		</div>
+
+	<div id="upload-file-view" class="alignleft">
+<?php		if ( isset($attachment_data['width']) && 'inline' != $style )
+			echo "<a href='" . wp_get_attachment_url() . "' title='" . __('Direct link to file') . "'>";
+		echo wp_upload_display( array(171, 128) );
+		if ( isset($attachment_data['width']) && 'inline' != $style )
+			echo '</a>'; ?>
+	</div>
+<?php	endif; ?>
+		<table><col /><col class="widefat" />
+<?php	if ( $id ): ?>
+			<tr>
+				<th scope="row"><label for="url"><?php _e('URL'); ?></label></th>
+				<td><input type="text" id="url" class="readonly" value="<?php echo wp_get_attachment_url(); ?>" readonly="readonly" /></td>
+			</tr>
+<?php	else : ?>
+			<tr>
+				<th scope="row"><label for="upload"><?php _e('File'); ?></label></th>
+				<td><input type="file" id="upload" name="image" /></td>
+			</tr>
+<?php	endif; ?>
+			<tr>
+				<th scope="row"><label for="post_title"><?php _e('Title'); ?></label></th>
+				<td><input type="text" id="post_title" name="post_title" value="<?php echo $attachment->post_title; ?>" /></td>
+			</tr>
+			<tr>
+				<th scope="row"><label for="post_content"><?php _e('Description'); ?></label></th>
+				<td><textarea name="post_content" id="post_content"><?php echo $attachment->post_content; ?></textarea></td>
+			</tr>
+			<tr id="buttons" class="submit">
+				<td colspan='2'>
+<?php	if ( $id ) : ?>
+					<input type="submit" name="delete" id="delete" class="delete alignleft" value="<?php _e('Delete File'); ?>" />
+<?php	endif; ?>
+					<input type="hidden" name="from_tab" value="<?php echo $tab; ?>" />
+					<input type="hidden" name="action" value="<?php echo $id ? 'save' : 'upload'; ?>" />
+<?php	if ( $post_id ) : ?>
+					<input type="hidden" name="post_id" value="<?php echo $post_id; ?>" />
+<?php	endif; if ( $id ) : ?>
+					<input type="hidden" name="ID" value="<?php echo $id; ?>" />
+<?php	endif; ?>
+					<?php wp_nonce_field( 'inlineuploading' ); ?>
+					<div class="submit">
+						<input type="submit" value="<?php $id ? _e('Save') : _e('Upload'); ?> &raquo;" />
+					</div>
+				</td>
+			</tr>
+		</table>
+	</form>
+<?php
+}
+
+function wp_upload_tab_upload() {
+	wp_upload_form();
+}
+
+function wp_upload_tab_upload_action() {
+	global $action;
+	if ( isset($_POST['delete']) )
+		$action = 'delete';
+
+	switch ( $action ) :
+	case 'upload' :
+		global $from_tab, $post_id, $style;
+		if ( !$from_tab )
+			$from_tab = 'upload';
+
+		check_admin_referer( 'inlineuploading' );
+
+		global $post_id, $post_title, $post_content;
+
+		if ( !current_user_can( 'upload_files' ) )
+			wp_die( __('You are not allowed to upload files.')
+				. " <a href='" . get_option('siteurl') . "/wp-admin/upload.php?style=" . attribute_escape($style . "&amp;tab=browse-all&amp;post_id=$post_id") . "'>"
+				. __('Browse Files') . '</a>'
+			);
+
+		$overrides = array('action'=>'upload');
+
+		$file = wp_handle_upload($_FILES['image'], $overrides);
+
+		if ( isset($file['error']) )
+			wp_die($file['error'] . "<br /><a href='" . get_option('siteurl')
+			. "/wp-admin/upload.php?style=" . attribute_escape($style . "&amp;tab=$from_tab&amp;post_id=$post_id") . "'>" . __('Back to Image Uploading') . '</a>'
+		);
+
+		$url = $file['url'];
+		$type = $file['type'];
+		$file = $file['file'];
+		$filename = basename($file);
+
+		// Construct the attachment array
+		$attachment = array(
+			'post_title' => $post_title ? $post_title : $filename,
+			'post_content' => $post_content,
+			'post_type' => 'attachment',
+			'post_parent' => $post_id,
+			'post_mime_type' => $type,
+			'guid' => $url
+		);
+
+		// Save the data
+		$id = wp_insert_attachment($attachment, $file, $post_id);
+
+		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
+
+		wp_redirect( get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=browse&action=view&ID=$id&post_id=$post_id");
+		die;
+		break;
+
+	case 'save' :
+		global $from_tab, $post_id, $style;
+		if ( !$from_tab )
+			$from_tab = 'upload';
+		check_admin_referer( 'inlineuploading' );
+
+		wp_update_post($_POST);
+		wp_redirect( get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=$from_tab&post_id=$post_id");
+		die;
+		break;
+
+	case 'delete' :
+		global $ID, $post_id, $from_tab, $style;
+		if ( !$from_tab )
+			$from_tab = 'upload';
+
+		check_admin_referer( 'inlineuploading' );
+
+		if ( !current_user_can('edit_post', (int) $ID) )
+			wp_die( __('You are not allowed to delete this attachment.')
+				. " <a href='" . get_option('siteurl') . "/wp-admin/upload.php?style=" . attribute_escape($style . "&amp;tab=$from_tab&amp;post_id=$post_id") . "'>"
+				. __('Go back') . '</a>'
+			);
+
+		wp_delete_attachment($ID);
+
+		wp_redirect( get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=$from_tab&post_id=$post_id" );
+		die;
+		break;
+
+	endswitch;
+}
+
+add_action( 'upload_files_upload', 'wp_upload_tab_upload_action' );
+
+function wp_upload_grab_attachments( $obj ) {
+	$obj->is_attachment = true;
+}
+
+function wp_upload_posts_where( $where ) {
+	global $post_id;
+	return $where . " AND post_parent = '" . (int) $post_id . "'";
+}
+
+function wp_upload_tab_browse() {
+	global $wpdb, $action, $paged;
+	$old_vars = compact( 'paged' );
+
+	switch ( $action ) :
+	case 'edit' :
+	case 'view' :
+		global $ID;
+		$attachments = query_posts("attachment_id=$ID");
+		if ( have_posts() ) : while ( have_posts() ) : the_post();
+			'edit' == $action ? wp_upload_form() : wp_upload_view();
+		endwhile; endif;
+		break;
+	default :
+		global $tab, $post_id, $style;
+		add_action( 'pre_get_posts', 'wp_upload_grab_attachments' );
+		if ( 'browse' == $tab && $post_id )
+			add_filter( 'posts_where', 'wp_upload_posts_where' );
+		$attachments = query_posts("what_to_show=posts&posts_per_page=10&paged=$paged");
+		$count_query = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'attachment'";
+		if ( $post_id )
+			$count_query .= " AND post_parent = '$post_id'";
+        	$total =  $wpdb->get_var($count_query);
+
+		echo "<ul id='upload-files'>\n";
+		if ( have_posts() ) : while ( have_posts() ) : the_post();
+			$href = wp_specialchars( add_query_arg( array(
+				'action' => 'inline' == $style ? 'view' : 'edit',
+				'ID' => get_the_ID())
+			 ), 1 );
+
+			echo "\t<li id='file-";
+			the_ID();
+			echo "' class='alignleft'>\n";
+			echo wp_upload_display( array(128,128), $href );
+			echo "\t</li>\n";
+		endwhile;
+		else :
+			echo "\t<li>" . __('There are no attachments to show.') . "</li>\n";
+		endif;
+		echo "</ul>\n\n";
+
+		echo "<form action='' id='browse-form'><input type='hidden' id='nonce-value' value='" . wp_create_nonce( 'inlineuploading' )  . "' /></form>\n";
+		break;
+	endswitch;
+
+	extract($old_vars);
+}
+
+
+function wp_upload_tab_browse_action() {
+	global $style;
+	if ( 'inline' == $style )
+		wp_enqueue_script('upload');
+}
+
+add_action( 'upload_files_browse', 'wp_upload_tab_browse_action' );
+add_action( 'upload_files_browse-all', 'wp_upload_tab_browse_action' );
+
+function wp_upload_admin_head() {
+	global $wp_locale;
+	echo "<link rel='stylesheet' href='" . get_option('siteurl') . '/wp-admin/upload.css?version=' . get_bloginfo('version') . "a' type='text/css' />\n";
+	if ( 'rtl' == $wp_locale->text_direction )
+		echo "<link rel='stylesheet' href='" . get_option('siteurl') . '/wp-admin/upload-rtl.css?version=' . get_bloginfo('version') . "a' type='text/css' />\n";
+	if ( 'inline' == @$_GET['style'] ) {
+		echo "<style type='text/css' media='screen'>\n";
+		echo "\t#upload-menu { position: absolute; z-index: 2; }\n";
+		echo "\tbody > #upload-menu { position: fixed; }\n";
+		echo "\t#upload-content { top: 2em; }\n";
+		echo "\t#upload-file { position: absolute; top: 15px; }\n";
+		echo "</style>";
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/upload-rtl.css 2.2.2/wp-admin/upload-rtl.css
--- 2.0.5/wp-admin/upload-rtl.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upload-rtl.css	2006-11-14 17:18:20.000000000 -0600
@@ -0,0 +1,50 @@
+#upload-menu li a.upload-tab-link {
+	float: right;
+	margin: 0 .75em 0 0;
+}
+
+table { float: right; }
+
+#upload-menu li #current-tab-nav {
+	float: right;
+	padding: 5px 0 0 5px;
+	margin-right: -5px;
+}
+
+#upload-file th, #the-attachment-links textarea { text-align: left; }
+
+h2 { margin: 0 0 0 .2em; }
+
+#upload-files li { margin: 0 15px 15px 0; }
+
+#upload-file-view { padding: 0 75px 0 0; }
+
+#upload-menu li {
+	display: block;
+	float: right;
+}
+
+#upload-menu li.current {
+	border-right: 0;
+	border-left: 2px solid #448abd;
+}
+
+#upload-file {
+	left: auto;
+	right: 0;
+}
+
+#file-title {
+	margin: 0 75px .2em 0;
+	font-family: Tahoma, Georgia, "Times New Roman", Times, serif;
+}
+
+.back {
+	left: auto;
+	right: 14px;
+}
+
+#uploadoptions td {
+	padding-left: 0;
+	padding-right: 1em;
+}
diff -ruN 2.0.5/wp-admin/upload.css 2.2.2/wp-admin/upload.css
--- 2.0.5/wp-admin/upload.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upload.css	2007-05-01 18:34:00.000000000 -0500
@@ -0,0 +1,204 @@
+body { background: #f9fcfe; }
+
+.upload-file-data { display: none; }
+
+#upload-menu {
+	border-top: 2em solid #247fab;
+	margin: 0;
+	padding: 0;
+	height: 0;
+	list-style: none;
+	width: 100%;
+}
+
+body > #upload-menu { border-bottom: 7px solid #fff; }
+
+#upload-menu li {
+	margin: 0;
+	position: relative;
+	top: -2em;
+	padding-bottom: 5px;
+	border: none;
+	border-top: 3px solid #247fab;
+}
+
+#upload-menu li a.upload-tab-link {
+	margin-left: 0.75em;
+	padding: 5px 5px 0;
+	display: block;
+	float: left;
+	height: 100%;
+	text-decoration: none;
+	border-bottom: none;
+	color: #fff;
+}
+
+#upload-menu li.current {
+	border-right: 2px solid #448abd;
+	color: #000;
+}
+
+#upload-menu li.current a.upload-tab-link, #upload-menu li a:hover {
+	background: #f9fcfe;
+	color: #000;
+}
+
+#upload-menu li #current-tab-nav {
+	background: #f9fcfe;
+	float: left;
+	padding: 5px 5px 0 0;
+	margin-left: -5px;
+}
+
+#upload-menu li span .page-numbers {
+	padding: 0;
+	border: none;
+}
+
+#upload-menu li span a.page-numbers { color: #00019b; }
+#upload-menu li span a.page-numbers:hover { text-decoration: underline; }
+
+#upload-content {
+	position: relative;
+	clear: both;
+	margin: 0;
+	padding: 0;
+	border: none;
+	width: 100%;
+	height: 100%;
+	background: none;
+}
+
+#upload-file {
+	margin: 0 auto;
+	top: 0;
+	left: 0;
+	width: 95%;
+	height: 100%;
+	background: #f9fcfe;
+}
+
+#upload-file th {
+	width: 8em;
+}
+
+form#upload-file input, form#upload-file textarea, div#upload-content.upload table { width: 100%; }
+
+form#upload-file .submit input { width: auto; }
+
+#upload-file-view { padding: 0 0 0 75px; }
+
+#file-title {
+	margin: 0 0 .2em 75px;
+	padding: 0;
+	display: block;
+	font-family: Georgia, "Times New Roman", Times, serif;
+	font-size: 16px;
+}
+
+h2 {
+	margin: 0 .2em 0 0;
+	padding: 0;
+	display: inline;
+	border: none;
+	color: #000;
+	font-size: 1.4em;
+	line-height: 1.4em;
+}
+
+.wrap h2 {
+	margin: .4em 0 .5em;
+	display: block;
+	border-bottom: .5em solid #e5f3ff;
+	color: #333;
+	font: normal 32px/5px serif;
+	clear: both;
+}
+
+* html .wrap h2 {
+	margin-top: 1em;
+}
+
+.back {
+	display: block;
+	position: absolute;
+	left: 14px;
+	top: 10px;
+}
+
+#upload-files {
+	list-style-type: none;
+	margin: 0;
+	padding: 15px 0 0;
+}
+
+#upload-files li { margin: 0 0 15px 15px; }
+
+#upload-files a, #upload-file-view a, a.file-link {
+	border: none;
+	text-decoration: none;
+}
+
+#upload-file-view a img { padding-bottom: .2em; border-bottom: 1px solid #6699CC; }
+
+#upload-files a.file-link {
+	display: block;
+	width: 130px;
+	height: 128px;
+	background-color: rgb(209, 226, 239);
+	text-align: center;
+	overflow: hidden;
+}
+
+#upload-files a.text {
+	padding-top: 40px;
+	height: 88px;
+	font-size: 16px;
+}
+
+#upload-files a.file-link.image {
+	font-size: 2px;
+	letter-spacing: 0;
+}
+
+#upload-files a.file-link img { vertical-align: middle; }
+
+#the-attachment-links textarea {
+	font-size: 10px;
+	overflow: hidden;
+}
+
+form table { float: none; padding: 0 15px; }
+
+table {
+	float: left;
+	margin: 0;
+	padding: 0;
+}
+
+th { text-align: right; vertical-align: text-top; }
+
+tr, td, th {
+	margin-top: 0;
+	padding-top: 0;
+}
+
+#uploadoptions th {
+	width: 80px;
+}
+
+#uploadoptions p {
+	margin: 0;
+	padding: 0;
+}
+
+#uploadoptions td {
+	padding-left: 1em;
+	line-height: 140%;
+}
+
+#uploadoptions table {
+	width: 300px;
+}
+
+input.readonly { background-color: #ddd; }
diff -ruN 2.0.5/wp-admin/upload.js 2.2.2/wp-admin/upload.js
--- 2.0.5/wp-admin/upload.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upload.js	2007-03-06 11:35:01.000000000 -0600
@@ -0,0 +1,273 @@
+addLoadEvent( function() {
+	theFileList = {
+		currentImage: {ID: 0},
+		nonce: '',
+		tab: '',
+		postID: 0,
+
+		initializeVars: function() {
+			this.urlData  = document.location.href.split('?');
+			this.params = this.urlData[1].toQueryParams();
+			this.postID = this.params['post_id'];
+			this.tab = this.params['tab'];
+			this.style = this.params['style'];
+			this.ID = this.params['ID'];
+			if ( !this.style )
+				this.style = 'default';
+			var nonceEl = $('nonce-value');
+			if ( nonceEl )
+				this.nonce = nonceEl.value;
+			if ( this.ID ) {
+				this.grabImageData( this.ID );
+				this.imageView( this.ID );
+			}
+		},
+
+		initializeLinks: function() {
+			if ( this.ID )
+				return;
+			$$('a.file-link').each( function(i) {
+				var id = i.id.split('-').pop();
+				i.onclick = function(e) { theFileList[ 'inline' == theFileList.style ? 'imageView' : 'editView' ](id, e); }
+			} );
+		},
+
+		grabImageData: function(id) {
+			if ( id == this.currentImage.ID )
+				return;
+			var thumbEl = $('attachment-thumb-url-' + id);
+			if ( thumbEl ) {
+				this.currentImage.thumb = ( 0 == id ? '' : thumbEl.value );
+				this.currentImage.thumbBase = ( 0 == id ? '' : $('attachment-thumb-url-base-' + id).value );
+			} else {
+				this.currentImage.thumb = false;
+			}
+			this.currentImage.src = ( 0 == id ? '' : $('attachment-url-' + id).value );
+			this.currentImage.srcBase = ( 0 == id ? '' : $('attachment-url-base-' + id).value );
+			this.currentImage.page = ( 0 == id ? '' : $('attachment-page-url-' + id).value );
+			this.currentImage.title = ( 0 == id ? '' : $('attachment-title-' + id).value );
+			this.currentImage.description = ( 0 == id ? '' : $('attachment-description-' + id).value );
+			var widthEl = $('attachment-width-' + id);
+			if ( widthEl ) {
+				this.currentImage.width = ( 0 == id ? '' : widthEl.value );
+				this.currentImage.height = ( 0 == id ? '' : $('attachment-height-' + id).value );
+			} else {
+				this.currentImage.width = false;
+				this.currentImage.height = false;
+			}
+			this.currentImage.isImage = ( 0 == id ? 0 : $('attachment-is-image-' + id).value );
+			this.currentImage.ID = id;
+		},
+
+		imageView: function(id, e) {
+			this.prepView(id);
+			var h = '';
+
+			h += "<div id='upload-file'>"
+			if ( this.ID ) {
+				var params = $H(this.params);
+				params.ID = '';
+				params.action = '';
+				h += "<a href='" + this.urlData[0] + '?' + params.toQueryString() + "'";
+			} else {
+				h += "<a href='#' onclick='return theFileList.cancelView();'";
+			}
+			h += " title='" + this.browseTitle + "' class='back'>" + this.back + "</a>";
+			h += "<div id='file-title'>"
+			if ( 0 == this.currentImage.isImage )
+				h += "<h2><a href='" + this.currentImage.srcBase + this.currentImage.src + "' onclick='return false;' title='" + this.directTitle + "'>" + this.currentImage.title + "</a></h2>";
+			else
+				h += "<h2>" + this.currentImage.title + "</h2>";
+			h += " &#8212; <span>";
+			h += "<a href='#' onclick='return theFileList.editView(" + id + ");'>" + this.edit + "</a>"
+			h += "</span>";
+			h += '</div>'
+			h += "<div id='upload-file-view' class='alignleft'>";
+			if ( 1 == this.currentImage.isImage ) {
+				h += "<a href='" + this.currentImage.srcBase + this.currentImage.src + "' onclick='return false;' title='" + this.directTitle + "'>";
+				h += "<img src='" + ( this.currentImage.thumb ? this.currentImage.thumb : this.currentImage.src ) + "' alt='" + this.currentImage.title + "' width='" + this.currentImage.width + "' height='" + this.currentImage.height + "' />";
+				h += "</a>";
+			} else
+				h += '&nbsp;';
+			h += "</div>";
+
+			h += "<form name='uploadoptions' id='uploadoptions' class='alignleft'>";
+			h += "<table>";
+			var display = [];
+			var checked = 'display-title';
+			if ( 1 == this.currentImage.isImage ) {
+				checked = 'display-full';
+				if ( this.currentImage.thumb ) {
+					display.push("<label for='display-thumb'><input type='radio' name='display' id='display-thumb' value='thumb' /> " + this.thumb + "</label><br />");
+					checked = 'display-thumb';
+				}
+				display.push("<label for='display-full'><input type='radio' name='display' id='display-full' value='full' /> " + this.full + "</label>");
+			} else if ( this.currentImage.thumb ) {
+				display.push("<label for='display-thumb'><input type='radio' name='display' id='display-thumb' value='thumb' /> " + this.icon + "</label>");
+			}
+			if ( display.length ) {
+				display.push("<br /><label for='display-title'><input type='radio' name='display' id='display-title' value='title' /> " + this.title + "</label>");
+				h += "<tr><th style='padding-bottom:.5em'>" + this.show + "</th><td style='padding-bottom:.5em'>";
+				$A(display).each( function(i) { h += i; } );
+				h += "</td></tr>";
+			}
+
+			h += "<tr><th>" + this.link + "</th><td>";
+			h += "<label for='link-file'><input type='radio' name='link' id='link-file' value='file' checked='checked'/> " + this.file + "</label><br />";
+			h += "<label for='link-page'><input type='radio' name='link' id='link-page' value='page' /> " + this.page + "</label><br />";
+			h += "<label for='link-none'><input type='radio' name='link' id='link-none' value='none' /> " + this.none + "</label>";
+			h += "</td></tr>";
+
+			h += "<tr><td colspan='2'><p class='submit'>";
+			h += "<input type='button' class='button' name='send' onclick='theFileList.sendToEditor(" + id + ")' value='" + this.editorText + "' />";
+			h += "</p></td></tr></table>";
+			h += "</form>";
+
+			h += "</div>";
+
+			new Insertion.Top('upload-content', h);
+			var displayEl = $(checked);
+			if ( displayEl )
+				displayEl.checked = true;
+
+			if (e) Event.stop(e);
+			return false;
+		},
+
+		editView: function(id, e) {
+			this.prepView(id);
+			var h = '';
+
+			var action = 'upload.php?style=' + this.style + '&amp;tab=upload';
+			if ( this.postID )
+				action += '&amp;post_id=' + this.postID;
+
+			h += "<form id='upload-file' method='post' action='" + action + "'>";
+			if ( this.ID ) {
+				var params = $H(this.params);
+				params.ID = '';
+				params.action = '';
+				h += "<a href='" + this.urlData[0] + '?' + params.toQueryString() + "'";
+			} else {
+				h += "<a href='#' onclick='return theFileList.cancelView();'";
+			}
+			h += " title='" + this.browseTitle + "' class='back'>" + this.back + "</a>";
+			h += "<div id='file-title'>"
+			if ( 0 == this.currentImage.isImage )
+				h += "<h2><a href='" + this.currentImage.srcBase + this.currentImage.src + "' onclick='return false;' title='" + this.directTitle + "'>" + this.currentImage.title + "</a></h2>";
+			else
+				h += "<h2>" + this.currentImage.title + "</h2>";
+			h += " &#8212; <span>";
+			h += "<a href='#' onclick='return theFileList.imageView(" + id + ");'>" + this.insert + "</a>";
+			h += "</span>";
+			h += '</div>'
+			h += "<div id='upload-file-view' class='alignleft'>";
+			if ( 1 == this.currentImage.isImage ) {
+				h += "<a href='" + this.currentImage.srcBase + this.currentImage.src + "' onclick='return false;' title='" + this.directTitle + "'>";
+				h += "<img src='" + ( this.currentImage.thumb ? this.currentImage.thumb : this.currentImage.src ) + "' alt='" + this.currentImage.title + "' width='" + this.currentImage.width + "' height='" + this.currentImage.height + "' />";
+				h += "</a>";
+			} else
+				h += '&nbsp;';
+			h += "</div>";
+
+
+			h += "<table><col /><col class='widefat' /><tr>";
+			h += "<th scope='row'><label for='url'>" + this.urlText + "</label></th>";
+			h += "<td><input type='text' id='url' class='readonly' value='" + this.currentImage.srcBase + this.currentImage.src + "' readonly='readonly' /></td>";
+			h += "</tr><tr>";
+			h += "<th scope='row'><label for='post_title'>" + this.title + "</label></th>";
+			h += "<td><input type='text' id='post_title' name='post_title' value='" + this.currentImage.title + "' /></td>";
+			h += "</tr><tr>";
+			h += "<th scope='row'><label for='post_content'>" + this.desc + "</label></th>";
+			h += "<td><textarea name='post_content' id='post_content'>" + this.currentImage.description + "</textarea></td>";
+			h += "</tr><tr id='buttons' class='submit'><td colspan='2'><input type='button' id='delete' name='delete' class='delete alignleft' value='" + this.deleteText + "' onclick='theFileList.deleteFile(" + id + ");' />";
+			h += "<input type='hidden' name='from_tab' value='" + this.tab + "' />";
+			h += "<input type='hidden' name='action' id='action-value' value='save' />";
+			h += "<input type='hidden' name='ID' value='" + id + "' />";
+			h += "<input type='hidden' name='_wpnonce' value='" + this.nonce + "' />";
+			h += "<div class='submit'><input type='submit' value='" + this.saveText + "' /></div>";
+			h += "</td></tr></table></form>";
+
+			new Insertion.Top('upload-content', h);
+			if (e) Event.stop(e);
+			return false;
+		},
+
+		prepView: function(id) {
+			this.cancelView( true );
+			var filesEl = $('upload-files');
+			if ( filesEl )
+				filesEl.hide();
+			var navEl = $('current-tab-nav');
+			if ( navEl )
+				navEl.hide();
+			this.grabImageData(id);
+		},
+
+		cancelView: function( prep ) {
+			if ( !prep ) {
+				var filesEl = $('upload-files');
+				if ( filesEl )
+					Element.show(filesEl);
+				var navEl = $('current-tab-nav');
+				if ( navEl )
+					Element.show(navEl);
+			}
+			if ( !this.ID )
+				this.grabImageData(0);
+			var div = $('upload-file');
+			if ( div )
+				Element.remove(div);
+			return false;
+		},
+
+		sendToEditor: function(id) {
+			this.grabImageData(id);
+			var link = '';
+			var display = '';
+			var h = '';
+
+			link = $A(document.forms.uploadoptions.elements.link).detect( function(i) { return i.checked; } ).value;
+			displayEl = $A(document.forms.uploadoptions.elements.display).detect( function(i) { return i.checked; } )
+			if ( displayEl )
+				display = displayEl.value;
+			else if ( 1 == this.currentImage.isImage )
+				display = 'full';
+
+			if ( 'none' != link )
+				h += "<a href='" + ( 'file' == link ? ( this.currentImage.srcBase + this.currentImage.src ) : ( this.currentImage.page + "' rel='attachment wp-att-" + this.currentImage.ID ) ) + "' title='" + this.currentImage.title + "'>";
+			if ( display && 'title' != display )
+				h += "<img src='" + ( 'thumb' == display ? ( this.currentImage.thumbBase + this.currentImage.thumb ) : ( this.currentImage.srcBase + this.currentImage.src ) ) + "' alt='" + this.currentImage.title + "' />";
+			else
+				h += this.currentImage.title;
+			if ( 'none' != link )
+				h += "</a>";
+
+			var win = window.opener ? window.opener : window.dialogArguments;
+			if ( !win )
+				win = top;
+			tinyMCE = win.tinyMCE;
+			if ( typeof tinyMCE != 'undefined' && tinyMCE.getInstanceById('content') ) {
+				tinyMCE.selectedInstance.getWin().focus();
+				tinyMCE.execCommand('mceInsertContent', false, h);
+			} else
+				win.edInsertContent(win.edCanvas, h);
+			if ( !this.ID )
+				this.cancelView();
+			return false;
+		},
+
+		deleteFile: function(id) {
+			if ( confirm( this.confirmText.replace(/%title%/g, this.currentImage.title) ) ) {
+				$('action-value').value = 'delete';
+				$('upload-file').submit();
+				return true;
+			}
+			return false;
+		}
+
+	};
+	Object.extend( theFileList, uploadL10n );
+	theFileList.initializeVars();
+	theFileList.initializeLinks();
+} );
diff -ruN 2.0.5/wp-admin/upload.php 2.2.2/wp-admin/upload.php
--- 2.0.5/wp-admin/upload.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/upload.php	2007-05-01 18:34:00.000000000 -0500
@@ -0,0 +1,138 @@
+<?php
+require_once('admin.php');
+
+@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
+
+if (!current_user_can('upload_files'))
+	wp_die(__('You do not have permission to upload files.'));
+
+wp_reset_vars(array('action', 'tab', 'from_tab', 'style', 'post_id', 'ID', 'paged', 'post_title', 'post_content', 'delete'));
+
+// IDs should be integers
+$ID = (int) $ID;
+$post_id = (int) $post_id;
+
+// Require an ID for the edit screen
+if ( $action == 'edit' && !$ID )
+	wp_die(__("You are not allowed to be here"));
+
+require_once('upload-functions.php');
+if ( !$tab )
+	$tab = 'browse-all';
+
+do_action( "upload_files_$tab" );
+
+$pid = 0;
+if ( $post_id < 0 )
+	$pid = $post_id;
+elseif ( get_post( $post_id ) )
+	$pid = $post_id;
+$wp_upload_tabs = array();
+$all_atts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'attachment'");
+$post_atts = 0;
+
+if ( $pid ) {
+	// 0 => tab display name, 1 => required cap, 2 => function that produces tab content, 3 => total number objects OR array(total, objects per page), 4 => add_query_args
+	$wp_upload_tabs['upload'] = array(__('Upload'), 'upload_files', 'wp_upload_tab_upload', 0);
+	if ( $all_atts && $post_atts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = '$post_id'") )
+		$wp_upload_tabs['browse'] = array(__('Browse'), 'upload_files', "wp_upload_tab_browse", $action ? 0 : $post_atts);
+	if ( $post_atts < $all_atts )
+		$wp_upload_tabs['browse-all'] = array(__('Browse All'), 'upload_files', 'wp_upload_tab_browse', $action ? 0 : $all_atts);
+} else
+	$wp_upload_tabs['browse-all'] = array(__('Browse All'), 'upload_files', 'wp_upload_tab_browse', $action ? 0 : $all_atts);
+
+	$wp_upload_tabs = array_merge($wp_upload_tabs, apply_filters( 'wp_upload_tabs', array() ));
+
+if ( !is_callable($wp_upload_tabs[$tab][2]) ) {
+	$to_tab = isset($wp_upload_tabs['upload']) ? 'upload' : 'browse-all';
+	wp_redirect( add_query_arg( 'tab', $to_tab ) );
+	exit;
+}
+
+foreach ( $wp_upload_tabs as $t => $tab_array ) {
+	if ( !current_user_can( $tab_array[1] ) ) {
+		unset($wp_upload_tabs[$t]);
+		if ( $tab == $t )
+			wp_die(__("You are not allowed to be here"));
+	}
+}
+
+if ( 'inline' == $style ) : ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
+<head>
+<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
+<title><?php bloginfo('name') ?> &rsaquo; <?php _e('Uploads'); ?> &#8212; WordPress</title>
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php endif; ?> 
+<script type="text/javascript">
+//<![CDATA[
+function addLoadEvent(func) {if ( typeof wpOnload!='function'){wpOnload=func;}else{ var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}}
+//]]>
+</script>
+<?php do_action('admin_print_scripts'); wp_upload_admin_head(); ?>
+</head>
+<body>
+<?php
+else :
+	add_action( 'admin_head', 'wp_upload_admin_head' );
+	include_once('admin-header.php');
+?>
+	<div class='wrap'>
+	<h2><?php _e('Uploads'); ?></h2>
+<?php
+endif;
+
+echo "<ul id='upload-menu'>\n";
+foreach ( $wp_upload_tabs as $t => $tab_array ) { // We've already done the current_user_can check
+	$href = add_query_arg( array('tab' => $t, 'ID' => '', 'action' => '', 'paged' => '') );
+	if ( isset($tab_array[4]) && is_array($tab_array[4]) )
+		$href = add_query_arg( $tab_array[4], $href );
+	$_href = clean_url( $href);
+	$page_links = '';
+	$class = 'upload-tab alignleft';
+	if ( $tab == $t ) {
+		$class .= ' current';
+		if ( $tab_array[3] ) {
+			if ( is_array($tab_array[3]) ) {
+				$total = $tab_array[3][0];
+				$per = $tab_array[3][1];
+			} else {
+				$total = $tab_array[3];
+				$per = 10;
+			}
+			$page_links = paginate_links( array(
+				'base' => add_query_arg( 'paged', '%#%' ),
+				'format' => '',
+				'total' => ceil($total / $per),
+				'current' => $paged ? $paged : 1,
+				'prev_text' => '&laquo;',
+				'next_text' => '&raquo;'
+			));
+			if ( $page_links )
+				$page_links = "<span id='current-tab-nav'>: $page_links</span>";
+		}
+	}
+
+	echo "\t<li class='$class'><a href='$_href' class='upload-tab-link' title='{$tab_array[0]}'>{$tab_array[0]}</a>$page_links</li>\n";
+}
+unset($t, $tab_array, $href, $_href, $page_links, $total, $per, $class);
+echo "</ul>\n\n";
+
+echo "<div id='upload-content' class='$tab'>\n";
+
+call_user_func( $wp_upload_tabs[$tab][2] );
+
+echo "</div>\n";
+
+if ( 'inline' != $style ) :
+	echo "<div class='clear'></div></div>";
+	include_once('admin-footer.php');
+else : ?>
+<script type="text/javascript">if(typeof wpOnload=='function')wpOnload();</script>
+
+</body>
+</html>
+<?php endif; ?>
diff -ruN 2.0.5/wp-admin/user-edit.php 2.2.2/wp-admin/user-edit.php
--- 2.0.5/wp-admin/user-edit.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/user-edit.php	2007-05-28 23:37:35.000000000 -0500
@@ -2,29 +2,20 @@
 require_once('admin.php');
 
 $title = __('Edit User');
-$parent_file = 'profile.php';	
+if ( current_user_can('edit_users') )
+	$parent_file = 'users.php';
+else
+	$parent_file = 'profile.php';
 $submenu_file = 'users.php';
 
-$wpvarstoreset = array('action', 'redirect', 'profile', 'user_id');
-for ($i=0; $i<count($wpvarstoreset); $i += 1) {
-	$wpvar = $wpvarstoreset[$i];
-	if (!isset($$wpvar)) {
-		if (empty($_POST["$wpvar"])) {
-			if (empty($_GET["$wpvar"])) {
-				$$wpvar = '';
-			} else {
-				$$wpvar = $_GET["$wpvar"];
-			}
-		} else {
-			$$wpvar = $_POST["$wpvar"];
-		}
-	}
-}
+wp_reset_vars(array('action', 'redirect', 'profile', 'user_id', 'wp_http_referer'));
+
+$wp_http_referer = remove_query_arg(array('update', 'delete_count'), stripslashes($wp_http_referer));
 
 $user_id = (int) $user_id;
 
 if ( !$user_id )
-	die(__('Invalid user ID.'));
+	wp_die(__('Invalid user ID.'));
 
 switch ($action) {
 case 'switchposts':
@@ -39,38 +30,41 @@
 
 check_admin_referer('update-user_' . $user_id);
 
-$errors = array();
+if ( !current_user_can('edit_user', $user_id) )
+	wp_die(__('You do not have permission to edit this user.'));
 
-if (!current_user_can('edit_users'))
-	die(__('You do not have permission to edit this user.'));
-else
-	$errors = edit_user($user_id);
+$errors = edit_user($user_id);
 
-if(count($errors) == 0) {
-	wp_redirect("user-edit.php?user_id=$user_id&updated=true");
+if( !is_wp_error( $errors ) ) {
+	$redirect = "user-edit.php?user_id=$user_id&updated=true";
+	$redirect = add_query_arg('wp_http_referer', urlencode($wp_http_referer), $redirect);
+	wp_redirect($redirect);
 	exit;
 }
 
 default:
-include ('admin-header.php');
-
 $profileuser = get_user_to_edit($user_id);
 
-if (!current_user_can('edit_users')) 
-	die__('You do not have permission to edit this user.');
+if ( !current_user_can('edit_user', $user_id) )
+		wp_die(__('You do not have permission to edit this user.'));
 
+include ('admin-header.php');
 ?>
 
 <?php if ( isset($_GET['updated']) ) : ?>
 <div id="message" class="updated fade">
 	<p><strong><?php _e('User updated.') ?></strong></p>
+	<?php if ( $wp_http_referer ) : ?>
+	<p><a href="users.php"><?php _e('&laquo; Back to Authors and Users'); ?></a></p>
+	<?php endif; ?>
 </div>
 <?php endif; ?>
-<?php if ( count($errors) != 0 ) : ?>
+<?php if ( is_wp_error( $errors ) ) : ?>
 <div class="error">
 	<ul>
 	<?php
-	foreach($errors as $error) echo "<li>$error</li>";
+	foreach( $errors->get_error_messages() as $message )
+		echo "<li>$message</li>";
 	?>
 	</ul>
 </div>
@@ -81,11 +75,18 @@
 
 <form name="profile" id="your-profile" action="user-edit.php" method="post">
 <?php wp_nonce_field('update-user_' . $user_id) ?>
+<?php if ( $wp_http_referer ) : ?>
+	<input type="hidden" name="wp_http_referer" value="<?php echo clean_url($wp_http_referer); ?>" />
+<?php endif; ?>
 <p>
 <input type="hidden" name="from" value="profile" />
 <input type="hidden" name="checkuser_id" value="<?php echo $user_ID ?>" />
 </p>
 
+<p><label for="rich_editing"><input name="rich_editing" type="checkbox" id="rich_editing" value="true" <?php checked('true', $profileuser->rich_editing); ?> /> <?php _e('Use the visual editor when writing'); ?></label></p>
+
+<p class="submit"><input type="submit" value="<?php _e('Update User &raquo;'); ?>" name="submit" /></p>
+
 <fieldset>
 <legend><?php _e('Name'); ?></legend>
 <p><label><?php _e('Username: (no editing)'); ?><br />
@@ -96,11 +97,22 @@
 <?php
 // print_r($profileuser);
 echo '<select name="role">';
+$role_list = '';
+$user_has_role = false;
 foreach($wp_roles->role_names as $role => $name) {
-	$selected = ($profileuser->has_cap($role)) ? ' selected="selected"' : '';
-	echo "<option value=\"{$role}\"{$selected}>{$name}</option>";
+	if ( $profileuser->has_cap($role) ) {
+		$selected = ' selected="selected"';
+		$user_has_role = true;
+	} else {
+		$selected = '';
+	}
+	$role_list .= "<option value=\"{$role}\"{$selected}>{$name}</option>";
 }
-echo '</select>';
+if ( $user_has_role )
+	$role_list .= '<option value="">' . __('&mdash; No role for this blog &mdash;') . '</option>';
+else
+	$role_list .= '<option value="" selected="selected">' . __('&mdash; No role for this blog &mdash;') . '</option>';
+echo $role_list . '</select>';
 ?></label></p>
 
 <p><label><?php _e('First name:') ?><br />
@@ -112,7 +124,7 @@
 <p><label><?php _e('Nickname:') ?><br />
 <input type="text" name="nickname" value="<?php echo $profileuser->nickname ?>" /></label></p>
 
-</p><label><?php _e('Display name publicly as:') ?> <br />
+<p><label><?php _e('Display name publicly as:') ?> <br />
 <select name="display_name">
 <option value="<?php echo $profileuser->display_name; ?>"><?php echo $profileuser->display_name; ?></option>
 <option value="<?php echo $profileuser->nickname ?>"><?php echo $profileuser->nickname ?></option>
@@ -148,7 +160,7 @@
 <input type="text" name="yim" value="<?php echo $profileuser->yim ?>" />
 </label></p>
 
-<p><label><?php _e('Jabber / Google Talk:') ?>
+<p><label><?php _e('Jabber / Google Talk:') ?><br />
 <input type="text" name="jabber" value="<?php echo $profileuser->jabber ?>" /></label>
 </p>
 </fieldset>
@@ -178,13 +190,13 @@
 <?php do_action('edit_user_profile'); ?>
 
 <br clear="all" />
-  <table width="99%"  border="0" cellspacing="2" cellpadding="3" class="editform">
-    <?php
-    if(count($profileuser->caps) > count($profileuser->roles)):
-    ?>
-    <tr>
-      <th scope="row"><?php _e('Additional Capabilities:') ?></th>
-      <td><?php 
+	<table width="99%"  border="0" cellspacing="2" cellpadding="3" class="editform">
+		<?php
+		if(count($profileuser->caps) > count($profileuser->roles)):
+		?>
+		<tr>
+			<th scope="row"><?php _e('Additional Capabilities:') ?></th>
+			<td><?php
 			$output = '';
 			foreach($profileuser->caps as $cap => $value) {
 				if(!$wp_roles->is_role($cap)) {
@@ -194,15 +206,15 @@
 			}
 			echo $output;
 			?></td>
-    </tr>
-    <?php
-    endif;
-    ?>
-  </table>
+		</tr>
+		<?php
+		endif;
+		?>
+	</table>
 <p class="submit">
 	<input type="hidden" name="action" value="update" />
 	<input type="hidden" name="user_id" id="user_id" value="<?php echo $user_id; ?>" />
-    <input type="submit" value="<?php _e('Update User &raquo;') ?>" name="submit" />
+	<input type="submit" value="<?php _e('Update User &raquo;') ?>" name="submit" />
  </p>
 </form>
 </div>
diff -ruN 2.0.5/wp-admin/users.js 2.2.2/wp-admin/users.js
--- 2.0.5/wp-admin/users.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/users.js	2006-12-01 17:00:04.000000000 -0600
@@ -0,0 +1,21 @@
+addLoadEvent(function() {
+	theListEls = document.getElementsByTagName('tbody');
+	theUserLists = new Array();
+	for ( var l = 0; l < theListEls.length; l++ ) {
+		if ( theListEls[l].id )
+			theUserLists[theListEls[l].id] = new listMan(theListEls[l].id);
+	}
+	addUserInputs = document.getElementById('adduser').getElementsByTagName('input');
+	for ( var i = 0; i < addUserInputs.length; i++ ) {
+		addUserInputs[i].onkeypress = function(e) { return killSubmit('addUserSubmit();', e); }
+	}
+	document.getElementById('addusersub').onclick = function(e) { return killSubmit('addUserSubmit();', e); }
+}
+);
+
+function addUserSubmit() {
+	var roleEl = document.getElementById('role');
+	var role = roleEl.options[roleEl.selectedIndex].value;
+	if ( !theUserLists['role-' + role] ) return true;
+	return theUserLists['role-' + role].ajaxAdder('user', 'adduser');
+}
diff -ruN 2.0.5/wp-admin/users.php 2.2.2/wp-admin/users.php
--- 2.0.5/wp-admin/users.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/users.php	2007-06-16 12:52:08.000000000 -0500
@@ -1,39 +1,151 @@
 <?php
 require_once('admin.php');
-require_once( ABSPATH . WPINC . '/registration-functions.php');
+require_once( ABSPATH . WPINC . '/registration.php');
+
+if ( !current_user_can('edit_users') )
+	wp_die(__('Cheatin&#8217; uh?'));
 
 $title = __('Users');
-$parent_file = 'profile.php';
-	
+$parent_file = 'users.php';
+
 $action = $_REQUEST['action'];
 $update = '';
 
+if ( empty($_POST) ) {
+	$referer = '<input type="hidden" name="wp_http_referer" value="'. attribute_escape(stripslashes($_SERVER['REQUEST_URI'])) . '" />';
+} elseif ( isset($_POST['wp_http_referer']) ) {
+	$redirect = remove_query_arg(array('wp_http_referer', 'updated', 'delete_count'), stripslashes($_POST['wp_http_referer']));
+	$referer = '<input type="hidden" name="wp_http_referer" value="' . attribute_escape($redirect) . '" />';
+} else {
+	$redirect = 'users.php';
+}
+
+
+// WP_User_Search class
+// by Mark Jaquith
+
+
+class WP_User_Search {
+	var $results;
+	var $search_term;
+	var $page;
+	var $raw_page;
+	var $users_per_page = 50;
+	var $first_user;
+	var $last_user;
+	var $query_limit;
+	var $query_from_where;
+	var $total_users_for_query = 0;
+	var $too_many_total_users = false;
+	var $search_errors;
+
+	function WP_User_Search ($search_term = '', $page = '') { // constructor
+		$this->search_term = $search_term;
+		$this->raw_page = ( '' == $page ) ? false : (int) $page;
+		$this->page = (int) ( '' == $page ) ? 1 : $page;
+
+		$this->prepare_query();
+		$this->query();
+		$this->prepare_vars_for_template_usage();
+		$this->do_paging();
+	}
+
+	function prepare_query() {
+		global $wpdb;
+		$this->first_user = ($this->page - 1) * $this->users_per_page;
+		$this->query_limit = 'LIMIT ' . $this->first_user . ',' . $this->users_per_page;
+		if ( $this->search_term ) {
+			$searches = array();
+			$search_sql = 'AND (';
+			foreach ( array('user_login', 'user_nicename', 'user_email', 'user_url', 'display_name') as $col )
+				$searches[] = $col . " LIKE '%$this->search_term%'";
+			$search_sql .= implode(' OR ', $searches);
+			$search_sql .= ')';
+		}
+		$this->query_from_where = "FROM $wpdb->users WHERE 1=1 $search_sql";
+
+	}
+
+	function query() {
+		global $wpdb;
+		$this->results = $wpdb->get_col('SELECT ID ' . $this->query_from_where . $this->query_limit);
+
+		if ( $this->results )
+			$this->total_users_for_query = $wpdb->get_var('SELECT COUNT(ID) ' . $this->query_from_where); // no limit
+		else
+			$this->search_errors = new WP_Error('no_matching_users_found', __('No matching users were found!'));
+	}
+
+	function prepare_vars_for_template_usage() {
+		$this->search_term = stripslashes($this->search_term); // done with DB, from now on we want slashes gone
+	}
+
+	function do_paging() {
+		if ( $this->total_users_for_query > $this->users_per_page ) { // have to page the results
+			$this->paging_text = paginate_links( array(
+				'total' => ceil($this->total_users_for_query / $this->users_per_page),
+				'current' => $this->page,
+				'prev_text' => __('&laquo; Previous Page'),
+				'next_text' => __('Next Page &raquo;'),
+				'base' => 'users.php?%_%',
+				'format' => 'userspage=%#%',
+				'add_args' => array( 'usersearch' => urlencode($this->search_term) )
+			) );
+		}
+	}
+
+	function get_results() {
+		return (array) $this->results;
+	}
+
+	function page_links() {
+		echo $this->paging_text;
+	}
+
+	function results_are_paged() {
+		if ( $this->paging_text )
+			return true;
+		return false;
+	}
+
+	function is_search() {
+		if ( $this->search_term )
+			return true;
+		return false;
+	}
+}
+
+
 switch ($action) {
 
 case 'promote':
 	check_admin_referer('bulk-users');
 
 	if (empty($_POST['users'])) {
-		wp_redirect('users.php');
+		wp_redirect($redirect);
+		exit();
 	}
 
 	if ( !current_user_can('edit_users') )
-		die(__('You can&#8217;t edit users.'));
+		wp_die(__('You can&#8217;t edit users.'));
 
- 	$userids = $_POST['users'];
+	$userids = $_POST['users'];
 	$update = 'promote';
- 	foreach($userids as $id) {
+	foreach($userids as $id) {
+		if ( ! current_user_can('edit_user', $id) )
+			wp_die(__('You can&#8217;t edit that user.'));
 		// The new role of the current user must also have edit_users caps
-		if($id == $current_user->id && !$wp_roles->role_objects[$_POST['new_role']]->has_cap('edit_users')) {
+		if($id == $current_user->ID && !$wp_roles->role_objects[$_POST['new_role']]->has_cap('edit_users')) {
 			$update = 'err_admin_role';
 			continue;
 		}
 
- 		$user = new WP_User($id);
- 		$user->set_role($_POST['new_role']);
- 	}
-		
-	wp_redirect('users.php?update=' . $update);
+		$user = new WP_User($id);
+		$user->set_role($_POST['new_role']);
+	}
+
+	wp_redirect(add_query_arg('update', $update, $redirect));
+	exit();
 
 break;
 
@@ -42,21 +154,26 @@
 	check_admin_referer('delete-users');
 
 	if ( empty($_POST['users']) ) {
-		wp_redirect('users.php');
+		wp_redirect($redirect);
+		exit();
 	}
 
-	if ( !current_user_can('edit_users') )
-		die(__('You can&#8217;t delete users.'));
+	if ( !current_user_can('delete_users') )
+		wp_die(__('You can&#8217;t delete users.'));
 
 	$userids = $_POST['users'];
-	
 	$update = 'del';
- 	foreach ($userids as $id) {
-		if($id == $current_user->id) {
+	$delete_count = 0;
+
+	foreach ( (array) $userids as $id) {
+		if ( ! current_user_can('delete_user', $id) )
+			wp_die(__('You can&#8217;t delete that user.'));
+
+		if($id == $current_user->ID) {
 			$update = 'err_admin_del';
 			continue;
 		}
- 		switch($_POST['delete_option']) {
+		switch($_POST['delete_option']) {
 		case 'delete':
 			wp_delete_user($id);
 			break;
@@ -64,9 +181,12 @@
 			wp_delete_user($id, $_POST['reassign_user']);
 			break;
 		}
+		++$delete_count;
 	}
 
-	wp_redirect('users.php?update=' . $update);
+	$redirect = add_query_arg( array('delete_count' => $delete_count, 'update' => $update), $redirect);
+	wp_redirect($redirect);
+	exit();
 
 break;
 
@@ -74,11 +194,13 @@
 
 	check_admin_referer('bulk-users');
 
-	if ( empty($_POST['users']) )
-		wp_redirect('users.php');
+	if ( empty($_POST['users']) ) {
+		wp_redirect($redirect);
+		exit();
+	}
 
-	if ( !current_user_can('edit_users') )
-		$error['edit_users'] = __('You can&#8217;t delete users.');
+	if ( !current_user_can('delete_users') )
+		$errors = new WP_Error('edit_users', __('You can&#8217;t delete users.'));
 
 	$userids = $_POST['users'];
 
@@ -86,33 +208,32 @@
 ?>
 <form action="" method="post" name="updateusers" id="updateusers">
 <?php wp_nonce_field('delete-users') ?>
+<?php echo $referer; ?>
 <div class="wrap">
 <h2><?php _e('Delete Users'); ?></h2>
 <p><?php _e('You have specified these users for deletion:'); ?></p>
 <ul>
 <?php
 	$go_delete = false;
- 	foreach ($userids as $id) {
- 		$user = new WP_User($id);
-		if ($id == $current_user->id) {
+	foreach ( (array) $userids as $id ) {
+		$user = new WP_User($id);
+		if ( $id == $current_user->ID ) {
 			echo "<li>" . sprintf(__('ID #%1s: %2s <strong>The current user will not be deleted.</strong>'), $id, $user->user_login) . "</li>\n";
 		} else {
 			echo "<li><input type=\"hidden\" name=\"users[]\" value=\"{$id}\" />" . sprintf(__('ID #%1s: %2s'), $id, $user->user_login) . "</li>\n";
 			$go_delete = true;
 		}
- 	}
- 	$all_logins = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users ORDER BY user_login");
- 	$user_dropdown = '<select name="reassign_user">';
- 	foreach ($all_logins as $login) {
-		if ( $login->ID == $current_user->id || !in_array($login->ID, $userids) ) {
- 			$user_dropdown .= "<option value=\"{$login->ID}\">{$login->user_login}</option>";
- 		}
- 	}
- 	$user_dropdown .= '</select>';
- 	?>
- 	</ul>
-<?php if($go_delete) : ?>
- 	<p><?php _e('What should be done with posts and links owned by this user?'); ?></p>
+	}
+	$all_logins = $wpdb->get_results("SELECT ID, user_login FROM $wpdb->users ORDER BY user_login");
+	$user_dropdown = '<select name="reassign_user">';
+	foreach ( (array) $all_logins as $login )
+		if ( $login->ID == $current_user->ID || !in_array($login->ID, $userids) )
+			$user_dropdown .= "<option value=\"{$login->ID}\">{$login->user_login}</option>";
+	$user_dropdown .= '</select>';
+	?>
+	</ul>
+<?php if ( $go_delete ) : ?>
+	<p><?php _e('What should be done with posts and links owned by this user?'); ?></p>
 	<ul style="list-style:none;">
 		<li><label><input type="radio" id="delete_option0" name="delete_option" value="delete" checked="checked" />
 		<?php _e('Delete all posts and links.'); ?></label></li>
@@ -132,35 +253,44 @@
 
 case 'adduser':
 	check_admin_referer('add-user');
-	
-	$errors = add_user();
-	
-	if(count($errors) == 0) {
-		wp_redirect('users.php?update=add');
+
+	if ( ! current_user_can('create_users') )
+		wp_die(__('You can&#8217;t create users.'));
+
+	$user_id = add_user();
+	$update = 'add';
+	if ( is_wp_error( $user_id ) )
+		$add_user_errors = $user_id;
+	else {
+		$new_user_login = apply_filters('pre_user_login', sanitize_user(stripslashes($_POST['user_login']), true));
+		$redirect = add_query_arg( array('usersearch' => urlencode($new_user_login), 'update' => $update), $redirect );
+		wp_redirect( $redirect . '#user-' . $user_id );
 		die();
 	}
 
 default:
-	
-	include ('admin-header.php');
-	
-	$userids = $wpdb->get_col("SELECT ID FROM $wpdb->users;");
-	
-	foreach($userids as $userid) {
+	wp_enqueue_script('admin-users');
+
+	include('admin-header.php');
+
+	// Query the users
+	$wp_user_search = new WP_User_Search($_GET['usersearch'], $_GET['userspage']);
+
+	// Make the user objects
+	foreach ( $wp_user_search->get_results() as $userid ) {
 		$tmp_user = new WP_User($userid);
 		$roles = $tmp_user->roles;
 		$role = array_shift($roles);
 		$roleclasses[$role][$tmp_user->user_login] = $tmp_user;
-	}	
-	
-	?>
+	}
 
-	<?php 
-	if (isset($_GET['update'])) : 
+	if ( isset($_GET['update']) ) :
 		switch($_GET['update']) {
 		case 'del':
+		case 'del_many':
 		?>
-			<div id="message" class="updated fade"><p><?php _e('User deleted.'); ?></p></div>
+			<?php $delete_count = (int) $_GET['delete_count']; ?>
+			<div id="message" class="updated fade"><p><?php printf(__ngettext('%s user deleted', '%s users deleted', $delete_count), $delete_count); ?></p></div>
 		<?php
 			break;
 		case 'add':
@@ -186,145 +316,204 @@
 		<?php
 			break;
 		}
-	endif; 
-	if ( isset($errors) ) : ?>
+	endif; ?>
+
+<?php if ( is_wp_error( $errors ) ) : ?>
 	<div class="error">
 		<ul>
 		<?php
-		foreach($errors as $error) echo "<li>$error</li>";
+			foreach ( $errors->get_error_messages() as $message )
+				echo "<li>$message</li>";
 		?>
 		</ul>
 	</div>
-	<?php 
-	endif;
-	?>
-	
-<form action="" method="post" name="updateusers" id="updateusers">
-<?php wp_nonce_field('bulk-users') ?>
+<?php endif; ?>
+
 <div class="wrap">
-	<h2><?php _e('User List by Role'); ?></h2>
-  <table cellpadding="3" cellspacing="3" width="100%">
-	<?php
-	foreach($roleclasses as $role => $roleclass) {
-		uksort($roleclass, "strnatcasecmp");
-		?>
 
-	<tr>
-	<th colspan="8" align="left">
-  <h3><?php echo $wp_roles->role_names[$role]; ?></h3>
-  </th></tr>
+	<?php if ( $wp_user_search->is_search() ) : ?>
+		<h2><?php printf(__('Users Matching "%s" by Role'), wp_specialchars($wp_user_search->search_term)); ?></h2>
+	<?php else : ?>
+		<h2><?php _e('User List by Role'); ?></h2>
+	<?php endif; ?>
+
+	<form action="" method="get" name="search" id="search">
+		<p><input type="text" name="usersearch" id="usersearch" value="<?php echo attribute_escape($wp_user_search->search_term); ?>" /> <input type="submit" value="<?php _e('Search Users &raquo;'); ?>" class="button" /></p>
+	</form>
+
+	<?php if ( is_wp_error( $wp_user_search->search_errors ) ) : ?>
+		<div class="error">
+			<ul>
+			<?php
+				foreach ( $wp_user_search->search_errors->get_error_messages() as $message )
+					echo "<li>$message</li>";
+			?>
+			</ul>
+		</div>
+	<?php endif; ?>
+
+
+<?php if ( $wp_user_search->get_results() ) : ?>
+
+	<?php if ( $wp_user_search->is_search() ) : ?>
+		<p><a href="users.php"><?php _e('&laquo; Back to All Users'); ?></a></p>
+	<?php endif; ?>
+
+	<h3><?php 
+	if ( 0 == $wp_user_search->first_user && $wp_user_search->total_users_for_query <= 50 )
+		printf(__('%3$s shown below'), $wp_user_search->first_user + 1, min($wp_user_search->first_user + $wp_user_search->users_per_page, $wp_user_search->total_users_for_query), $wp_user_search->total_users_for_query);
+	else
+		printf(__('%1$s &#8211; %2$s of %3$s shown below'), $wp_user_search->first_user + 1, min($wp_user_search->first_user + $wp_user_search->users_per_page, $wp_user_search->total_users_for_query), $wp_user_search->total_users_for_query); ?></h3>
+
+	<?php if ( $wp_user_search->results_are_paged() ) : ?>
+		<div class="user-paging-text"><p><?php $wp_user_search->page_links(); ?></p></div>
+	<?php endif; ?>
 
-	<tr>
+<form action="" method="post" name="updateusers" id="updateusers">
+<?php wp_nonce_field('bulk-users') ?>
+<table class="widefat">
+<?php
+foreach($roleclasses as $role => $roleclass) {
+	uksort($roleclass, "strnatcasecmp");
+?>
+<tbody>
+<tr>
+<?php if ( !empty($role) ) : ?>
+	<th colspan="7"><h3><?php echo $wp_roles->role_names[$role]; ?></h3></th>
+<?php else : ?>
+	<th colspan="7"><h3><em><?php _e('No role for this blog'); ?></em></h3></th>
+<?php endif; ?>
+</tr>
+<tr class="thead">
 	<th><?php _e('ID') ?></th>
 	<th><?php _e('Username') ?></th>
 	<th><?php _e('Name') ?></th>
 	<th><?php _e('E-mail') ?></th>
 	<th><?php _e('Website') ?></th>
-	<th><?php _e('Posts') ?></th>
-	<th>&nbsp;</th>
-	</tr>
-	<?php
-	$style = '';
-	foreach ($roleclass as $user_object) {
-		$email = $user_object->user_email;
-		$url = $user_object->user_url;
-		$short_url = str_replace('http://', '', $url);
-		$short_url = str_replace('www.', '', $short_url);
-		if ('/' == substr($short_url, -1))
-			$short_url = substr($short_url, 0, -1);
-		if (strlen($short_url) > 35)
-		$short_url =  substr($short_url, 0, 32).'...';
-		$style = ('class="alternate"' == $style) ? '' : 'class="alternate"';
-		$numposts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = '$user_object->ID' and post_status = 'publish'");
-		if (0 < $numposts) $numposts = "<a href='edit.php?author=$user_object->ID' title='" . __('View posts') . "'>$numposts</a>";
-		echo "
-<tr $style>
-	<td><input type='checkbox' name='users[]' id='user_{$user_object->ID}' value='{$user_object->ID}' /> <label for='user_{$user_object->ID}'>{$user_object->ID}</label></td>
-	<td><label for='user_{$user_object->ID}'><strong>$user_object->user_login</strong></label></td>
-	<td><label for='user_{$user_object->ID}'>$user_object->first_name $user_object->last_name</label></td>
-	<td><a href='mailto:$email' title='" . sprintf(__('e-mail: %s'), $email) . "'>$email</a></td>
-	<td><a href='$url' title='website: $url'>$short_url</a></td>";
-	echo "<td align='right'>$numposts</td>";
-	echo '<td>';
-	if (current_user_can('edit_users'))
-		echo "<a href='user-edit.php?user_id=$user_object->ID' class='edit'>".__('Edit')."</a>";
-	echo '</td>';
-	echo '</tr>';
-	}
-	
-	?>
-	
+	<th colspan="2" style="text-align: center"><?php _e('Actions') ?></th>
+</tr>
+</tbody>
+<tbody id="role-<?php echo $role; ?>"><?php
+$style = '';
+foreach ( (array) $roleclass as $user_object ) {
+	$style = ( ' class="alternate"' == $style ) ? '' : ' class="alternate"';
+	echo "\n\t" . user_row($user_object, $style);
+}
+?>
+
+</tbody>
+<?php } ?>
+</table>
+
+<?php if ( $wp_user_search->results_are_paged() ) : ?>
+	<div class="user-paging-text"><p><?php $wp_user_search->page_links(); ?></p></div>
+<?php endif; ?>
+
+	<h3><?php _e('Update Selected'); ?></h3>
+	<ul style="list-style:none;">
+		<li><input type="radio" name="action" id="action0" value="delete" /> <label for="action0"><?php _e('Delete checked users.'); ?></label></li>
+		<li>
+			<input type="radio" name="action" id="action1" value="promote" /> <label for="action1"><?php _e('Set the Role of checked users to:'); ?></label>
+			<select name="new_role" onchange="getElementById('action1').checked = 'true'"><?php wp_dropdown_roles(); ?></select>
+		</li>
+	</ul>
+	<p class="submit" style="width: 420px">
+		<?php echo $referer; ?>
+		<input type="submit" value="<?php _e('Bulk Update &raquo;'); ?>" />
+	</p>
+</form>
+<?php endif; ?>
+</div>
 
 <?php
+	if ( is_wp_error($add_user_errors) ) {
+		foreach ( array('user_login' => 'user_login', 'first_name' => 'user_firstname', 'last_name' => 'user_lastname', 'email' => 'user_email', 'url' => 'user_uri', 'role' => 'user_role') as $formpost => $var ) {
+			$var = 'new_' . $var;
+			$$var = attribute_escape(stripslashes($_POST[$formpost]));
+		}
+		unset($name);
 	}
 ?>
-  </table>
 
+<div class="wrap">
+<h2 id="add-new-user"><?php _e('Add New User') ?></h2>
 
-	<h2><?php _e('Update Users'); ?></h2>
-<?php
-$role_select = '<select name="new_role">';
-foreach($wp_roles->role_names as $role => $name) {
-	$role_select .= "<option value=\"{$role}\">{$name}</option>";
-}
-$role_select .= '</select>';
-?>  
-  <ul style="list-style:none;">
-  	<li><input type="radio" name="action" id="action0" value="delete" /> <label for="action0"><?php _e('Delete checked users.'); ?></label></li>
-  	<li><input type="radio" name="action" id="action1" value="promote" /> <?php echo '<label for="action1">'.__('Set the Role of checked users to:')."</label> $role_select"; ?></li>
-  </ul>
-	<p class="submit"><input type="submit" value="<?php _e('Update &raquo;'); ?>" /></p>
-</div>
-</form>
+<?php if ( is_wp_error( $add_user_errors ) ) : ?>
+	<div class="error">
+		<?php
+			foreach ( $add_user_errors->get_error_messages() as $message )
+				echo "<p>$message</p>";
+		?>
+	</div>
+<?php endif; ?>
+<div id="ajax-response"></div>
 
-<div class="wrap">
-<h2><?php _e('Add New User') ?></h2>
-<?php echo '<p>'.sprintf(__('Users can <a href="%1$s">register themselves</a> or you can manually create users here.'), get_settings('siteurl').'/wp-register.php').'</p>'; ?>
-<form action="" method="post" name="adduser" id="adduser">
-  <?php wp_nonce_field('add-user') ?>
-  <table class="editform" width="100%" cellspacing="2" cellpadding="5">
-    <tr>
-      <th scope="row" width="33%"><?php _e('Nickname') ?>
-      <input name="action" type="hidden" id="action" value="adduser" /></th>
-      <td width="66%"><input name="user_login" type="text" id="user_login" value="<?php echo $new_user_login; ?>" /></td>
-    </tr>
-    <tr>
-      <th scope="row"><?php _e('First Name') ?> </th>
-      <td><input name="first_name" type="text" id="first_name" value="<?php echo $new_user_firstname; ?>" /></td>
-    </tr>
-    <tr>
-      <th scope="row"><?php _e('Last Name') ?> </th>
-      <td><input name="last_name" type="text" id="last_name" value="<?php echo $new_user_lastname; ?>" /></td>
-    </tr>
-    <tr>
-      <th scope="row"><?php _e('E-mail') ?></th>
-      <td><input name="email" type="text" id="email" value="<?php echo $new_user_email; ?>" /></td>
-    </tr>
-    <tr>
-      <th scope="row"><?php _e('Website') ?></th>
-      <td><input name="url" type="text" id="url" value="<?php echo $new_user_uri; ?>" /></td>
-    </tr>
-<?php
-$show_password_fields = apply_filters('show_password_fields', true);
-if ( $show_password_fields ) :
+<div class="narrow">
+
+<?php 
+	if ( get_option('users_can_register') ) 
+		echo '<p>' . sprintf(__('Users can <a href="%1$s">register themselves</a> or you can manually create users here.'), get_option('siteurl').'/wp-register.php') . '</p>'; 
+	else 
+        echo '<p>' . sprintf(__('Users cannot currently <a href="%1$s">register themselves</a>, but you can manually create users here.'), get_option('siteurl').'/wp-admin/options-general.php#users_can_register') . '</p>'; 
 ?>
-    <tr>
-      <th scope="row"><?php _e('Password (twice)') ?> </th>
-      <td><input name="pass1" type="password" id="pass1" />
-      <br />
-      <input name="pass2" type="password" id="pass2" /></td>
-    </tr>
+<form action="#add-new-user" method="post" name="adduser" id="adduser">
+<?php wp_nonce_field('add-user') ?>
+<table class="editform" width="100%" cellspacing="2" cellpadding="5">
+	<tr>
+		<th scope="row" width="33%"><?php _e('Username (required)') ?><input name="action" type="hidden" id="action" value="adduser" /></th>
+		<td width="66%"><input name="user_login" type="text" id="user_login" value="<?php echo $new_user_login; ?>" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('First Name') ?> </th>
+		<td><input name="first_name" type="text" id="first_name" value="<?php echo $new_user_firstname; ?>" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('Last Name') ?> </th>
+		<td><input name="last_name" type="text" id="last_name" value="<?php echo $new_user_lastname; ?>" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('E-mail (required)') ?></th>
+		<td><input name="email" type="text" id="email" value="<?php echo $new_user_email; ?>" /></td>
+	</tr>
+	<tr>
+		<th scope="row"><?php _e('Website') ?></th>
+		<td><input name="url" type="text" id="url" value="<?php echo $new_user_uri; ?>" /></td>
+	</tr>
+
+<?php if ( apply_filters('show_password_fields', true) ) : ?>
+	<tr>
+		<th scope="row"><?php _e('Password (twice)') ?> </th>
+		<td><input name="pass1" type="password" id="pass1" />
+		<br />
+		<input name="pass2" type="password" id="pass2" /></td>
+	</tr>
 <?php endif; ?>
-  </table>
-  <p class="submit">
-    <input name="adduser" type="submit" id="adduser" value="<?php _e('Add User') ?> &raquo;" />
-  </p>
-  </form>
+
+	<tr>
+		<th scope="row"><?php _e('Role'); ?></th>
+		<td><select name="role" id="role">
+			<?php
+			if ( !$new_user_role )
+				$new_user_role = get_option('default_role');
+			wp_dropdown_roles($new_user_role);
+			?>
+			</select>
+		</td>
+	</tr>
+</table>
+<p class="submit">
+	<?php echo $referer; ?>
+	<input name="adduser" type="submit" id="addusersub" value="<?php _e('Add User &raquo;') ?>" />
+</p>
+</form>
+
+</div>
 </div>
-	<?php
 
+<?php
 break;
-}
+
+} // end of the $action switch
 
 include('admin-footer.php');
 ?>
diff -ruN 2.0.5/wp-admin/widgets-rtl.css 2.2.2/wp-admin/widgets-rtl.css
--- 2.0.5/wp-admin/widgets-rtl.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/widgets-rtl.css	2007-04-27 15:49:52.000000000 -0500
@@ -0,0 +1,39 @@
+#sbreset, #lastmodule, #palettediv .module, .dropzone, .dropzone ul { float: right; }
+
+* .module, #lastmodule { text-align: right; }
+
+* html #palettediv ul { padding: 0 10px 0 0; }
+
+#palettediv ul { padding: 0 10px 0 0; }
+
+* .handle, #lastmodule span {
+	border-right: 1px solid #f2f2f2;
+	border-left: 1px solid #e8e8e8;
+}
+
+#sbadmin p.submit {
+	padding-right: 0;
+	padding-left: 10px;
+	clear: right;
+}
+
+#palettediv .module, #lastmodule, .dropzone {
+	margin-right: auto;
+	margin-left: 10px;
+}
+
+* .popper {
+	right: auto;
+	left: 3px;
+	background-position: 5px 0;
+}
+
+.controlcloser {
+	right: auto;
+	left: 8px;
+}
+
+#shadow {
+	left: auto;
+	right: 0px;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/widgets.css 2.2.2/wp-admin/widgets.css
--- 2.0.5/wp-admin/widgets.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/widgets.css	2007-05-19 12:23:50.000000000 -0500
@@ -0,0 +1,214 @@
+body {
+	height: 100%;
+}
+
+#sbadmin #zones {
+	-moz-user-select: none;
+	-khtml-user-select: none;
+	user-select: none;
+}
+
+#sbreset {
+	float: left;
+	margin: 1px 0;
+}
+
+.dropzone {
+	float: left;
+	margin-right: 10px;
+	padding: 5px;
+	border: 1px solid #bbb;
+	background-color: #f0f8ff;
+}
+
+.dropzone h3 {
+	text-align: center;
+	color: #333;
+}
+
+.dropzone ul {
+	list-style-type: none;
+	width: 240px;
+	float: left;
+	margin: 0;
+	padding: 0;
+}
+
+* .module, #lastmodule {
+	width: 238px;
+	padding: 0;
+	margin: 5px 0;
+	cursor: move;
+	display: block;
+	border: 1px solid #ccc;
+	background-color: #fbfbfb;
+	text-align: left;
+	line-height: 25px;
+}
+
+* .handle, #lastmodule span {
+	display: block;
+	width: 216px;
+	padding: 0 10px;
+	border-top: 1px solid #f2f2f2;
+	border-right: 1px solid #e8e8e8;
+	border-bottom: 1px solid #e8e8e8;
+	border-left: 1px solid #f2f2f2;
+}
+
+* .popper {
+	margin: 0;
+	display: inline;
+	position: absolute;
+	top: 3px;
+	right: 3px;
+	overflow: hidden;
+	text-align: center;
+	height: 16px;
+	font-size: 18px;
+	line-height: 14px;
+	cursor: pointer;
+	padding: 0 3px 1px;
+	border-top: 4px solid #6da6d1;
+	background: url( images/fade-butt.png ) -5px 0px;
+}
+
+* html .popper {
+	padding: 1px 6px 0;
+	font-size: 16px;
+}
+
+#sbadmin p.submit {
+	padding-right: 10px;
+	clear: left;
+}
+
+.placematt {
+	cursor: default;
+	margin: 10px 0 0;
+	padding: 0;
+	width: 238px;
+	float:left;
+	background-color: #ffe;
+}
+
+* html .placematt {
+	margin-top: 5px;
+}
+
+.placematt h4 {
+	text-align: center;
+	margin-bottom: 5px;
+}
+
+.placematt span {
+	padding: 0 10px 10px;
+	text-align: justify;
+}
+
+
+#palettediv {
+	border: 1px solid #bbb;
+	background-color: #f0f8ff;
+	height:auto;
+	margin-top: 10px;
+}
+
+#palettediv h3 {
+	text-align: center;
+	color: #333;
+}
+
+#palettediv ul {
+	padding: 0 0 0 10px;
+}
+
+#palettediv .module, #lastmodule {
+	margin-right: 10px;
+	float: left;
+	width: 120px;
+}
+
+#palettediv .handle, #lastmodule span {
+	height: 40px;
+	font-size: 90%;
+	width: 110px;
+	padding: 0 5px;
+}
+
+#palettediv .popper {
+	visibility: hidden;
+}
+
+#lastmodule {
+	visibility: hidden;
+}
+
+* html #palettediv ul {
+	margin: 0;
+	padding: 0 0 0 10px;
+}
+
+* html #palettediv .module {
+	float: none;
+	display: inline;
+}
+
+#controls {
+	height: 0px;
+}
+
+.control {
+	position: absolute;
+	display: block;
+	background: #f9fcfe;
+	padding: 0;
+}
+
+.controlhandle {
+	cursor: move;
+	background-color: #6da6d1;
+	border-bottom: 2px solid #448abd;
+	color: #333;
+	display: block;
+	margin: 0 0 5px;
+	padding: 4px;
+	font-size: 120%;
+}
+
+.controlcloser {
+	cursor: pointer;
+	font-size: 120%;
+	display: block;
+	position: absolute;
+	top: 2px;
+	right: 8px;
+	padding: 0 3px;
+	font-weight: bold;
+}
+
+.controlform {
+	margin: 20px 30px;
+}
+
+.controlform p {
+	text-align: center;
+}
+
+.control .checkbox {
+	border: none;
+	background: transparent;
+}
+
+.hidden {
+	display: none;
+}
+
+#shadow {
+	background: black;
+	display: none;
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	width: 100%;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-admin/widgets.php 2.2.2/wp-admin/widgets.php
--- 2.0.5/wp-admin/widgets.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-admin/widgets.php	2007-05-22 17:52:29.000000000 -0500
@@ -0,0 +1,392 @@
+<?php
+
+require_once 'admin.php';
+
+if ( ! current_user_can('switch_themes') )
+	wp_die( __( 'Cheatin&#8217; uh?' ));
+
+wp_enqueue_script( 'scriptaculous-effects' );
+wp_enqueue_script( 'scriptaculous-dragdrop' );
+
+function wp_widgets_admin_head() {
+	global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls;
+	
+	define( 'WP_WIDGETS_WIDTH', 1 + 262 * ( count( $wp_registered_sidebars ) ) );
+	define( 'WP_WIDGETS_HEIGHT', 35 * ( count( $wp_registered_widgets ) ) );
+?>
+	<link rel="stylesheet" href="widgets.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+	<!--[if IE 7]>
+	<style type="text/css">
+	#palette {float:left;}
+	</style>
+	<![endif]-->
+	<style type="text/css">
+		.dropzone ul { height: <?php echo constant( 'WP_WIDGETS_HEIGHT' ); ?>px; }
+		#sbadmin #zones { width: <?php echo constant( 'WP_WIDGETS_WIDTH' ); ?>px; }
+	</style>
+<?php
+	if ( get_bloginfo( 'text_direction' ) == 'rtl' ) { 
+?>
+	<link rel="stylesheet" href="widgets-rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php
+	}
+	
+	$cols = array();
+	foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+		$cols[] = '\'' . $index . '\'';
+	}
+	$cols = implode( ', ', $cols );
+	
+	$widgets = array();
+	foreach ( $wp_registered_widgets as $name => $widget ) {
+		$widgets[] = '\'' . $widget['id'] . '\'';
+	}
+	$widgets = implode( ', ', $widgets );
+?>
+<script type="text/javascript">
+// <![CDATA[
+	var cols = [<?php echo $cols; ?>];
+	var widgets = [<?php echo $widgets; ?>];
+	var controldims = new Array;
+	<?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?>
+		controldims['<?php echo $widget['id']; ?>control'] = new Array;
+		controldims['<?php echo $widget['id']; ?>control']['width'] = <?php echo (int) $widget['width']; ?>;
+		controldims['<?php echo $widget['id']; ?>control']['height'] = <?php echo (int) $widget['height']; ?>;
+	<?php endforeach; ?>
+	function initWidgets() {
+	<?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?>
+		$('<?php echo $widget['id']; ?>popper').onclick = function() {popControl('<?php echo $widget['id']; ?>control');};
+		$('<?php echo $widget['id']; ?>closer').onclick = function() {unpopControl('<?php echo $widget['id']; ?>control');};
+		new Draggable('<?php echo $widget['id']; ?>control', {revert:false,handle:'controlhandle',starteffect:function(){},endeffect:function(){},change:function(o){dragChange(o);}});
+		if ( true && window.opera )
+			$('<?php echo $widget['id']; ?>control').style.border = '1px solid #bbb';
+	<?php endforeach; ?>
+		if ( true && window.opera )
+			$('shadow').style.background = 'transparent';
+		new Effect.Opacity('shadow', {to:0.0});
+		widgets.map(function(o) {o='widgetprefix-'+o; Position.absolutize(o); Position.relativize(o);} );
+		$A(Draggables.drags).map(function(o) {o.startDrag(null); o.finishDrag(null);});
+		//for ( var n in Draggables.drags ) {
+		for ( n=0; n<=Draggables.drags.length; n++ ) {
+			if ( parseInt( n ) ) {
+				if ( Draggables.drags[n].element.id == 'lastmodule' ) {
+					Draggables.drags[n].destroy();
+					break;
+				}
+			}
+		}
+		resetPaletteHeight();
+	}
+	function resetDroppableHeights() {
+		var max = 6;
+		cols.map(function(o) {var c = $(o).childNodes.length; if ( c > max ) max = c;} );
+		var height = 35 * ( max + 1);
+		cols.map(function(o) {h = (($(o).childNodes.length + 1) * 35); $(o).style.height = (h > 280 ? h : 280) + 'px';} );
+	}
+	function resetPaletteHeight() {
+		var p = $('palette'), pd = $('palettediv'), last = $('lastmodule');
+		p.appendChild(last);
+		if ( Draggables.activeDraggable && last.id == Draggables.activeDraggable.element.id )
+			last = last.previousSibling;
+		var y1 = Position.cumulativeOffset(last)[1] + last.offsetHeight;
+		var y2 = Position.cumulativeOffset(pd)[1] + pd.offsetHeight;
+		var dy = y1 - y2;
+		pd.style.height = (pd.offsetHeight + dy + 9) + "px";
+	}
+	function maxHeight(elm) {
+		htmlheight = document.body.parentNode.clientHeight;
+		bodyheight = document.body.clientHeight;
+		var height = htmlheight > bodyheight ? htmlheight : bodyheight;
+		$(elm).style.height = height + 'px';
+	}
+	function dragChange(o) {
+		el = o.element ? o.element : $(o);
+		var p = Position.page(el);
+		var right = p[0];
+		var top = p[1];
+		var left = $('shadow').offsetWidth - (el.offsetWidth + right);
+		var bottom = $('shadow').offsetHeight - (el.offsetHeight + top);
+		if ( right < 1 ) el.style.left = 0;
+		if ( top < 1 ) el.style.top = 0;
+		if ( left < 1 ) el.style.left = (left + right) + 'px';
+		if ( bottom < 1 ) el.style.top = (top + bottom) + 'px';
+	}
+	function popControl(elm) {
+		el = $(elm);
+		el.style.width = controldims[elm]['width'] + 'px';
+		el.style.height = controldims[elm]['height'] + 'px';
+		var x = ( document.body.clientWidth - controldims[elm]['width'] ) / 2;
+		var y = ( document.body.parentNode.clientHeight - controldims[elm]['height'] ) / 2;
+		el.style.position = 'absolute';
+		el.style.right = '' + x + 'px';
+		el.style.top = '' + y + 'px';
+		el.style.zIndex = 1000;
+		el.className='control';
+		$('shadow').onclick = function() {unpopControl(elm);};
+	    window.onresize = function(){maxHeight('shadow');dragChange(elm);};
+		popShadow();
+	}
+	function popShadow() {
+		maxHeight('shadow');
+		var shadow = $('shadow');
+		shadow.style.zIndex = 999;
+		shadow.style.display = 'block';
+	    new Effect.Opacity('shadow', {duration:0.5, from:0.0, to:0.2});
+	}
+	function unpopShadow() {
+	    new Effect.Opacity('shadow', {to:0.0});
+		$('shadow').style.display = 'none';
+	}
+	function unpopControl(el) {
+		$(el).className='hidden';
+		unpopShadow();
+	}
+	function serializeAll() {
+	<?php foreach ( $wp_registered_sidebars as $index => $sidebar ) : ?>
+		$('<?php echo $index; ?>order').value = Sortable.serialize('<?php echo $index; ?>');
+	<?php endforeach; ?>
+	}
+	function updateAll() {
+		resetDroppableHeights();
+		resetPaletteHeight();
+		cols.map(function(o){
+			var pm = $(o+'placematt');
+			if ( $(o).childNodes.length == 0 ) {
+				pm.style.display = 'block';
+				//Position.absolutize(o+'placematt');
+			} else {
+				pm.style.display = 'none';
+			}
+		});
+	}
+	function noSelection(event) {
+		if ( document.selection ) {
+			var range = document.selection.createRange();
+			range.collapse(false);
+			range.select();
+			return false;
+		}
+	}
+	addLoadEvent(updateAll);
+	addLoadEvent(initWidgets);
+	Event.observe(window, 'resize', resetPaletteHeight);
+// ]]>
+</script>
+<?php
+}
+add_action( 'admin_head', 'wp_widgets_admin_head' );
+do_action( 'sidebar_admin_setup' );
+
+function wp_widget_draggable( $name ) {
+	global $wp_registered_widgets, $wp_registered_widget_controls;
+	
+	if ( !isset( $wp_registered_widgets[$name] ) ) {
+		return;
+	}
+	
+	$sanitized_name = sanitize_title( $wp_registered_widgets[$name]['id'] );
+	$link_title = __( 'Configure' );
+	$popper = ( isset( $wp_registered_widget_controls[$name] ) ) 
+		? ' <div class="popper" id="' . $sanitized_name . 'popper" title="' . $link_title . '">&#8801;</div>'
+		: '';
+	
+	$output = '<li class="module" id="widgetprefix-%1$s"><span class="handle">%2$s</span></li>';
+	
+	printf( $output, $sanitized_name, $wp_registered_widgets[$name]['name'] . $popper );
+}
+
+$title = __( 'Widgets' );
+$parent_file = 'themes.php';
+
+require_once 'admin-header.php';
+
+if ( count( $wp_registered_sidebars ) < 1 ) {
+?>
+	<div class="wrap">
+		<h2><?php _e( 'No Sidebars Defined' ); ?></h2>
+		
+		<p><?php _e( 'You are seeing this message because the theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="http://automattic.com/code/widgets/themes/">follow these instructions</a>.' ); /* TODO: article on codex */; ?></p>
+	</div>
+<?php
+	
+	require_once 'admin-footer.php';
+	exit;
+}
+
+$sidebars_widgets = wp_get_sidebars_widgets();
+
+if ( empty( $sidebars_widgets ) ) {
+	$sidebars_widgets = wp_get_widget_defaults();
+}
+
+if ( isset( $_POST['action'] ) ) {
+	check_admin_referer( 'widgets-save-widget-order' );
+	
+	switch ( $_POST['action'] ) {
+		case 'default' :
+			$sidebars_widgets = wp_get_widget_defaults();
+			wp_set_sidebars_widgets( $sidebars_widgets );
+		break;
+		
+		case 'save_widget_order' :
+			$sidebars_widgets = array();
+			
+			foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+				$postindex = $index . 'order';
+				
+				parse_str( $_POST[$postindex], $order );
+				
+				$new_order = $order[$index];
+				
+				if ( is_array( $new_order ) ) {
+					foreach ( $new_order as $sanitized_name ) {
+						foreach ( $wp_registered_widgets as $name => $widget ) {
+							if ( $sanitized_name == $widget['id'] ) {
+								$sidebars_widgets[$index][] = $name;
+							}
+						}
+					}
+				}
+			}
+			
+			wp_set_sidebars_widgets( $sidebars_widgets );
+		break;
+	}
+}
+
+ksort( $wp_registered_widgets );
+
+$inactive_widgets = array();
+
+foreach ( $wp_registered_widgets as $name => $widget ) {
+	$is_active = false;
+	
+	foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+		if ( is_array( $sidebars_widgets[$index] ) && in_array( $name, $sidebars_widgets[$index] ) ) {
+			$is_active = true;
+			break;
+		}
+	}
+	
+	if ( !$is_active ) {
+		$inactive_widgets[] = $name;
+	}
+}
+
+$containers = array( 'palette' );
+
+foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+	$containers[] = $index;
+}
+
+$c_string = '';
+
+foreach ( $containers as $container ) {
+	$c_string .= '"' . $container . '",';
+}
+
+$c_string = substr( $c_string, 0, -1 );
+
+if ( isset( $_POST['action'] ) ) {
+?>
+	<div class="fade updated" id="message">
+		<p><?php printf( __( 'Sidebar updated. <a href="%s">View site &raquo;</a>' ), get_bloginfo( 'url' ) . '/' ); ?></p>
+	</div>
+<?php
+}
+?>
+	<div class="wrap">
+		<h2><?php _e( 'Sidebar Arrangement' ); ?></h2>
+		
+		<p><?php _e( 'You can drag and drop widgets onto your sidebar below.' ); ?></p>
+		
+		<form id="sbadmin" method="post" onsubmit="serializeAll();">
+			<p class="submit">
+				<input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" />
+			</p>
+			<div id="zones">
+			<?php
+				foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+			?>
+				<input type="hidden" id="<?php echo $index; ?>order" name="<?php echo $index; ?>order" value="" />
+				
+				<div class="dropzone">
+					<h3><?php echo $sidebar['name']; ?></h3>
+					
+					<div id="<?php echo $index; ?>placematt" class="module placemat">
+						<span class="handle">
+							<h4><?php _e( 'Default Sidebar' ); ?></h4>
+							<?php _e( 'Your theme will display its usual sidebar when this box is empty. Dragging widgets into this box will replace the usual sidebar with your customized sidebar.' ); ?>
+						</span>
+					</div>
+					
+					<ul id="<?php echo $index; ?>">
+					<?php
+						if ( is_array( $sidebars_widgets[$index] ) ) {
+							foreach ( $sidebars_widgets[$index] as $name ) {
+								wp_widget_draggable( $name );
+							}
+						}
+					?>
+					</ul>
+				</div>
+			<?php
+				}
+			?>
+			
+			<br class="clear" />
+			
+			</div>
+		
+			<div id="palettediv">
+				<h3><?php _e( 'Available Widgets' ); ?></h3>
+			
+				<ul id="palette">
+				<?php
+					foreach ( $inactive_widgets as $name ) {
+						wp_widget_draggable( $name );
+					}
+				?>
+					<li id="lastmodule"><span></span></li>
+				</ul>
+			</div>
+		
+			<script type="text/javascript">
+			// <![CDATA[
+			<?php foreach ( $containers as $container ) { ?>
+				Sortable.create("<?php echo $container; ?>", {
+					dropOnEmpty: true, containment: [<?php echo $c_string; ?>], 
+					handle: 'handle', constraint: false, onUpdate: updateAll, 
+					format: /^widgetprefix-(.*)$/
+				});
+			<?php } ?>
+			// ]]>
+			</script>
+		
+			<p class="submit">
+			<?php wp_nonce_field( 'widgets-save-widget-order' ); ?>
+				<input type="hidden" name="action" id="action" value="save_widget_order" />
+				<input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" />
+			</p>
+		
+			<div id="controls">
+			<?php foreach ( $wp_registered_widget_controls as $name => $widget ) { ?>
+				<div class="hidden" id="<?php echo $widget['id']; ?>control">
+					<span class="controlhandle"><?php echo $widget['name']; ?></span>
+					<span id="<?php echo $widget['id']; ?>closer" class="controlcloser">&#215;</span>
+					<div class="controlform">
+					<?php call_user_func_array( $widget['callback'], $widget['params'] ); ?>
+					</div>
+				</div>
+			<?php } ?>
+			</div>
+		</form>
+		
+		<br class="clear" />
+	</div>
+	
+	<div id="shadow"> </div>
+	
+	<?php do_action( 'sidebar_admin_page' ); ?>
+
+<?php require_once 'admin-footer.php'; ?>
diff -ruN 2.0.5/wp-admin/wp-admin.css 2.2.2/wp-admin/wp-admin.css
--- 2.0.5/wp-admin/wp-admin.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/wp-admin.css	2007-04-19 17:26:52.000000000 -0500
@@ -20,6 +20,12 @@
 	color: #fff;
 }
 
+#devnews h4 {
+	font-family: Georgia, "Times New Roman", Times, serif;
+	font-size: 18px;
+	font-weight: normal;
+}
+
 #planetnews ul {
 	list-style: none;
 	margin: 0;
@@ -40,6 +46,63 @@
 	overflow: hidden;
 }
 
+#planetnews cite {
+	font-size: 11px;
+}
+
+#planetnews li .post {
+	font-family: Georgia, "Times New Roman", Times, serif;
+	font-size: 18px;
+	display: block;
+	height: 60px;
+	overflow: hidden;
+}
+
+#planetnews .hidden {
+	display: none;
+}
+
+.readmore {
+	clear: both;
+	text-align: right;
+	margin-right: 5em;
+}
+
+.widefat {
+	width: 100%;
+}
+
+.widefat td, .widefat th {
+	padding: 5px 6px;
+}
+
+.widefat th {
+	text-align: left;
+}
+
+.plugins p {
+	margin: 4px;
+	padding: 0;
+}
+
+.plugins .name {
+	font-size: 16px;
+}
+
+.import-system {
+	font-size: 16px;
+}
+
+thead, .thead {
+	background: #dfdfdf
+}
+
+#import-upload-form {
+	margin: auto;
+	background: #eee;
+	padding: 1em;
+}
+
 a.edit, a.delete, a.edit:hover, a.delete:hover {
 	border-bottom: none;
 	display: block;
@@ -91,17 +154,14 @@
 	padding: .1em .3em;
 }
 
-fieldset span.cat-nest {
-	display: block;
-	margin-left: 10px;
-}
-
 fieldset.options {
 	padding: 1em;
 }
 
 fieldset.options legend {
-	font-size: 16px;
+	font-size: 1.5em;
+	font-weight: bold;
+	font-family: Georgia, "Times New Roman", Times, serif;
 }
 
 form, label input {
@@ -110,25 +170,12 @@
 }
 
 h2 {
-	border-bottom: .5em solid #f0f8ff;
+	border-bottom: .5em solid #e5f3ff;
 	color: #333;
-	font: normal 30px/5px serif;
+	font: normal 32px/5px serif;
 	margin: 5px 10px;
 }
 
-h2 small.quickjump {
-	display: block;
-	text-align: right;
-}
-
-h2 small.quickjump a {
-	text-decoration: none;
-	border-bottom: 0;
-	font-size: 15px;
-	background: #f0f8ff;
-	padding: 5px 10px;
-}
-
 img, #footer a {
 	border: 0;
 }
@@ -147,25 +194,24 @@
 }
 
 p, li, dl, dd, dt {
-	line-height: 130%;
+	line-height: 140%;
 }
 
 textarea, input, select {
 	background: #f4f4f4;
 	border: 1px solid #b2b2b2;
 	color: #000;
-	font:  13px Verdana, Arial, Helvetica, sans-serif;
+	font: 13px Verdana, Arial, Helvetica, sans-serif;
 	margin: 1px;
 	padding: 3px;
 }
 
 #uploading {
 	border-style: none;
-	padding: 0px;
+	padding: 0;
 	margin-bottom: 16px;
-	height: 15em;
+	height: 18em;
 	width: 100%;
-/*	overflow-y: hidden;*/
 }
 
 form#upload th {
@@ -241,8 +287,19 @@
 }
 
 .commentlist li {
-	border-bottom: 1px solid #369;
-	padding: .3em 1em;
+	border-bottom: 1px solid #ccc;
+	padding: 1em 1em .2em;
+	margin: 0;
+}
+
+.commentlist li li {
+	border-bottom: 0px;
+	padding: 0;
+}
+
+.commentlist p {
+	padding: 0;
+	margin: 0 0 .8em;
 }
 
 .clear {
@@ -277,7 +334,7 @@
 	font: 12px Georgia, "Times New Roman", Times, serif;
 }
 
-.submit input, .submit input:focus, .button {
+.submit input, .submit input:focus, .button, .button:focus {
 	background: url( images/fade-butt.png );
 	border: 3px double #999;
 	border-left-color: #ccc;
@@ -293,6 +350,14 @@
 	border-top-color: #999;
 }
 
+.button, .button:focus {
+	padding: 0.15em;
+}
+
+* html .button {
+	padding: 0;
+}
+
 .submit, .editform th, #postcustomsubmit {
 	text-align: right;
 }
@@ -308,6 +373,8 @@
 .optiontable th {
 	width: 33%;
 	text-align: right;
+	font-size: 1.3em;
+	font-weight: normal;
 }
 
 .unapproved {
@@ -326,8 +393,20 @@
 	color: #009ef0;
 }
 
-.updated {
-	background: #CFEBF7 url(images/notice.gif) no-repeat 1em ;
+.approve {
+	display: none;
+}
+
+.unapproved .approve {
+	display: inline;
+}
+
+.unapproved .unapprove {
+	display: none;
+}
+
+.updated, .confirm {
+	background: #CFEBF7 url(images/notice.gif) no-repeat 1em;
 	border: 1px solid #2580B2;
 	margin: 1em 5% 10px;
 	padding: 0 1em 0 3em;
@@ -345,15 +424,28 @@
 	border: 1px solid #ccc;
 	clear: both;
 	margin: 15px 5%;
-	padding: .5em 1em;
+	padding: 1em;
+}
+
+.narrow {
+	width: 450px;
+	margin: auto;
+}
+
+.narrow p {
+	line-height: 150%;
 }
 
 .wrap h2 {
-	margin: .8em 0 .5em;
+	margin: .4em 0 .5em;
 	clear: both;
 }
 
-table .vers, table .name {
+* html .wrap h2 {
+	margin-top: 1em;
+}
+
+table .vers {
 	text-align: center;
 }
 
@@ -366,14 +458,15 @@
 }
 
 #adminmenu {
-	background: #6da6d1;
+	background: #83B4D8;
 	border-top: 3px solid #448abd;
 	margin: 0;
-	padding: .2em .2em .2em 2em;
+	padding: .2em .2em .3em 2em;
 }
 
 #adminmenu .current, #submenu .current {
 	font-weight: bold;
+	text-decoration: none;
 }
 
 #adminmenu a {
@@ -382,10 +475,10 @@
 	font-weight: normal;
 	margin: 0;
 	padding: 3px 5px;
-	text-decoration: none;
+	border-bottom: none;
 }
 
-#adminmenu a:hover, .current {
+#adminmenu a:hover, #adminmenu a.current {
 	background: #ddeaf4;
 	color: #333;
 }
@@ -395,15 +488,28 @@
 	line-height: 200%;
 	list-style: none;
 	text-align: center;
+	white-space: nowrap;
 }
 
-#submenu {
+#adminmenu a.current {
+	background: #0d324f;
+	border-right: 2px solid #4f96c8;
+	border-top: 1px solid #96c0de;
+	color: #fff;
+	padding-bottom: 8px;
+}
+
+#submenu, #minisub {
 	background: #0d324f;
 	border-bottom: none;
 	margin: 0;
 	padding: 3px 2em 0 3em;
 }
 
+#minisub {
+	height: 6px;
+}
+
 #submenu .current {
 	background: #f9fcfe;
 	border-top: 1px solid #045290;
@@ -415,7 +521,7 @@
 	border: none;
 	color: #fff;
 	font-size: 12px;
-	padding: .3em .4em .33em;
+	padding: .3em .4em .4em;
 }
 
 #submenu a:hover {
@@ -424,41 +530,37 @@
 }
 
 #submenu li {
-	line-height: 170%;
+	line-height: 180%;
+	height: 25px;
 }
 
-
 #categorydiv input, #poststatusdiv input, #commentstatusdiv input, #pingstatusdiv input {
 	border: none;
 }
 
-#titlediv, #guiddiv {
+#postdiv, #titlediv, #guiddiv {
 	margin: 0 8px 0 0;
-	padding: 0px;
-}
-
-#postdiv {
-	margin: 0 8px 0 0;
-	padding: 0px;
+	padding: 0;
 }
 
 #postdivrich {
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 }
 
 #content {
-	margin: 0 0 0 0;
+	margin: 0;
 	width: 100%;
 }
 
-#titlediv input, #guiddiv input {
-	margin: 0px;
-	width: 100%;
+#postdivrich #content {
+	padding: 5px;
+	line-height: 140%;
 }
 
-#quicktags {
-	margin-left: -1px;
+#titlediv input, #guiddiv input {
+	margin: 0;
+	width: 100%;
 }
 
 #currenttheme img {
@@ -469,11 +571,40 @@
 	width: 300px;
 }
 
-#deletepost:hover {
+input.delete:hover {
+	background: #ce0000;
+	color: #fff;
+}
+
+#deletebookmarks:hover {
 	background: #ce0000;
 	color: #fff;
 }
 
+#postdivrich #quicktags {
+	background: #f0f0ee;
+	padding: 0;
+	border: 1px solid #ccc;
+	border-bottom: none;
+}
+
+#postdiv #quicktags {
+	padding-right: 6px;
+}
+
+#postdivrich #quicktags {
+	display: none;
+}
+
+#quicktags #ed_toolbar {
+	padding: 0 2px;
+}
+
+#ed_toolbar input {
+	background: #fff url( images/fade-butt.png ) repeat-x 0 -2px;
+	margin: 3px 2px 2px;
+}
+
 #quicktags #ed_strong {
 	font-weight: bold;
 }
@@ -493,10 +624,12 @@
 
 #quicktags #ed_code {
 	font-family: "Courier New", Courier, mono;
+	margin-bottom: 3px;
 }
 
 #title {
-	font-size: 1.5em;
+	font-size: 1.7em;
+	padding: 4px 3px;
 }
 
 #postexcerpt div, #attachmentlinks div {
@@ -514,7 +647,7 @@
 }
 
 #excerpt, .attachmentlinks {
-	margin: 0px;
+	margin: 0;
 	height: 4em;
 	width: 100%;
 }
@@ -522,61 +655,158 @@
 #footer {
 	clear: both;
 	text-align: center;
+	width: 500px;
+	margin: auto;
+	height: 100px;
+}
+
+#footer .docs {
+	padding-top: 19px;
+	line-height: 160%;
+}
+
+#footer .docs a {
+	text-decoration: underline;
+}
+#footer .logo {
+	float: left;
+	margin: 0;
+	padding: 0;
 }
 
 #login {
-	background: #fff;
-	border: 1px solid #a2a2a2;
-	margin: 5em auto;
-	padding: 1.5em;
-	width: 25em;
+	position: relative;
+	background: url('images/login-bkg-tile.gif') no-repeat top center;
+	color: #fff;
+	margin: 5em auto 1em;
+	padding: 20px 0 0;
+	width: 425px;
+	_width: 390px;
+}
+
+#login form {
+	background: url('images/login-bkg-bottom.gif') no-repeat bottom center;
+	padding: 0 50px 25px;
+	_width: 325px;
+	_margin: 0 auto;
 }
 
 #login #login_error {
-	background: #c00;
-	border: 1px solid #a40000;
-	color: #fff;
-	font-size: 16px;
+	background: #0e3350;
+	border: 1px solid #2571ab;
+	color: #ebcd4e;
+	font-size: 11px;
 	font-weight: bold;
-	padding: .5em;
+	padding: .6em;
+	width: 310px;
+	margin: 0 50px;
 	text-align: center;
 }
 
-#login h1 {
-	background: url(images/wordpress-logo.png) no-repeat top left;
-	margin-top: 0;
+#login p { 
+	font-size: 12px;
+}
+
+#login p.message { 
+	width: 310px;
+	margin: 0 auto 1em;
+}
+
+#login #login_error a {
+	color: #ebcd4e;
+	border-color: #ebcd4e;
+}
+
+#login #send {
+	color: #fff;
+	text-align: left;
+	font-weight: normal;
+	font-size: 1.1em;
+	_width: 325px;
+	_margin: 0 auto 15px;
 }
 
 #login h1 a {
+	margin: 0 auto;
+	height: 88px;
+	width: 320px;
 	display: block;
-	text-indent: -1000px;
-	height: 66px;
 	border-bottom: none;
+	text-indent: -9999px;
+}
+
+#login .message {
+	font-size: 10pt;
+	text-align: center;
+}
+
+#login .register {
+	font-size: 20px;
 }
 
 #login input {
-	padding: 3px;
+	padding: 4px;
 }
 
-#login ul {
+.login ul, #protected #login .bottom {
 	list-style: none;
-	margin: 0;
+	width: 325px;
+	margin: 0 auto;
 	padding: 0;
+	line-height: 1.2;
 }
 
-#login ul li {
-	display: inline;
-	margin-left: 1.4em;
-	text-align: center;
+.login ul li {
+	font-size: 11px;
 }
 
-#login #log, #pwd {
-	font-size: 1.7em;
-	width: 80%;
+.login ul li a {
+	color: #0d324f;
+	border: none;
+}
+
+#login ul li a:hover {
+	color: #fff;
+}
+
+#login .input {
+	font-size: 1.8em;
+	margin-top: 3px;
+	width: 97%;
+}
+
+#login p label { 
+	font-size: 11px;
 }
 
 #login #submit {
-	font-size: 1.7em;
+	margin: 0;
+	font-size: 15px;
+}
+
+.plugins p {
+}
+
+#login .fullwidth {
+	width: 320px;
+}
+
+#searchform {
+	float: left;
+	margin-right: 1em;
+	width: 18em;
+}
+
+#viewarc {
+	float: left;
+	width: 23em;
+	margin-bottom: 1em;
+}
+
+#viewcat {
+	float: left;
+	width: 30em;
+	margin-bottom: 1em;
 }
 
 #postcustom .updatemeta, #postcustom .deletemeta {
@@ -585,7 +815,7 @@
 
 #postcustom table {
 	border: 1px solid #ccc;
-	margin: 0px;
+	margin: 0;
 	width: 100%;
 }
 
@@ -606,7 +836,7 @@
 }
 
 * html #template div {
-	margin-right: 0px;
+	margin-right: 0;
 }
 
 #template, #template div, #editcat, #addcat {
@@ -621,9 +851,10 @@
 #templateside {
 	float: right;
 	width: 170px;
+	overflow: hidden;
 }
 
-#templateside h3, #postcustom p {
+#templateside h3, #postcustom p.submit {
 	margin: 0;
 }
 
@@ -660,7 +891,7 @@
 	font-weight: normal;
 	letter-spacing: -.05em;
 	margin: 0;
-	font-family: Georgia, "Times New Roman", Times, serif
+	font-family: Georgia, "Times New Roman", Times, serif;
 }
 
 #wphead h1 span {
@@ -670,7 +901,7 @@
 
 #zeitgeist {
 	background: #eee;
-	border: 1px solid #69c;
+	border: 1px solid #c5c5c5;
 	float: right;
 	font-size: 90%;
 	margin-bottom: .5em;
@@ -684,6 +915,10 @@
 	border-bottom: none;
 }
 
+* html #zeitgeist h2 {
+	padding-top: 10px;
+}
+
 #zeitgeist h2 {
 	margin-top: .4em;
 }
@@ -721,36 +956,44 @@
 	background: #8B8;
 }
 
+#namediv, #emaildiv, #uridiv {
+	float: left;
+}
+
+#ajax-response {
+	padding: .5em;
+}
+
 /* A handy div class for hiding controls.
-   Some browsers will disable them when you
-   set display:none; */
+Some browsers will disable them when you
+set display:none; */
 .zerosize {
-	height: 0px;
-	width: 0px;
-	margin: 0px;
-	border: 0px;
-	padding: 0px;
+	height: 0;
+	width: 0;
+	margin: 0;
+	border: 0;
+	padding: 0;
 	overflow: hidden;
 	position: absolute;
 }
 
 /* Box stuff */
 .dbx-clone {
-	position:absolute;
-	visibility:hidden;
+	position: absolute;
+	visibility: hidden;
 }
 .dbx-clone, .dbx-clone .dbx-handle-cursor {
-	cursor:move !important;
+	cursor: move !important;
 }
 .dbx-dummy {
-	display:block;
-	width:0;
-	height:0;
-	overflow:hidden;
+	display: block;
+	width: 0;
+	height: 0;
+	overflow: hidden;
 }
 .dbx-group, .dbx-box, .dbx-handle {
-	position:relative;
-	display:block;
+	position: relative;
+	display: block;
 }
 
 #grabit {
@@ -758,19 +1001,19 @@
 }
 
 * html #themeselect {
-	padding: 0px 3px;
+	padding: 0 3px;
 	height: 22px;
 }
 
 /****************************************************************
-  avoid padding, margins or borders on dbx-box, 
-  to reduce visual discrepancies between it and the clone.  
-  overall, dbx-box is best left as visually unstyled as possible 
+avoid padding, margins or borders on dbx-box,
+to reduce visual discrepancies between it and the clone.
+overall, dbx-box is best left as visually unstyled as possible
 *****************************************************************/
 .dbx-box {
-	margin:0;
-	padding:0;
-	border:none;
+	margin: 0;
+	padding: 0;
+	border: none;
 }
 
 /* Can change this */
@@ -778,7 +1021,7 @@
 	margin-bottom: 1em;
 }
 #moremeta fieldset div {
-	margin: 2px 0 0 0px;
+	margin: 2px 0 0 0;
 	padding: 7px;
 }
 #moremeta {
@@ -807,24 +1050,41 @@
 	margin-top: .5em;
 }
 
-#categorydiv div div {
+#categorydiv ul {
+	list-style: none;
+	padding: 0;
+	margin-left: 10px;
+}
+
+#categorychecklist {
 	height: 12em;
 	overflow: auto;
+	margin-top: 8px;
+}
+
+#categorychecklist li {
+	margin: 0;
+	padding: 0;
 }
 
 #ajaxcat input {
 	border: 1px solid #ccc;
 }
 
+#your-profile #rich_editing {
+	border: none;
+	background: #fff;
+}
+
 #your-profile fieldset {
 	border: 1px solid #ccc;
 	float: left;
 	width: 40%;
-	padding: .5em 2em;
-	margin: 1em; 
+	padding: .5em 2em 1em;
+	margin: 1em 1em 1em 0;
 }
 
-#your-profile fieldset input  {
+#your-profile fieldset input {
 	width: 100%;
 	font-size: 20px;
 	padding: 2px;
@@ -863,7 +1123,7 @@
 
 /* handles */
 
-.dbx-handle  {
+.dbx-handle {
 	background: #2685af;
 	padding: 6px 1em 2px;
 	font-size: 12px;
@@ -885,10 +1145,12 @@
 	margin-left: 7px;
 	margin-bottom: -7px;
 	padding: 6px 1em 0 3px;
+	height: 19px;
+	font-size: 12px;
 	background: #2685af url(images/box-head-right.gif) no-repeat top right;
 }
 
-#advancedstuff div.dbx-handle-wrapper {
+#advancedstuff div.dbx-h-andle-wrapper {
 	margin: 0 0 0 -7px;
 	background: #fff url(images/box-head-left.gif) no-repeat top left;
 }
@@ -896,7 +1158,7 @@
 #advancedstuff div.dbx-content {
 	margin-left: 8px;
 	background: url(images/box-bg-right.gif) repeat-y right;
-	padding: 10px 10px 15px 0px;
+	padding: 10px 10px 15px 0;
 }
 
 #postexcerpt div.dbx-content {
@@ -904,7 +1166,7 @@
 	padding-right: 17px;
 }
 
-#advancedstuff div.dbx-content-wrapper {
+#advancedstuff div.dbx-c-ontent-wrapper {
 	margin-left: -7px;
 	margin-right: 0;
 	background: url(images/box-bg-left.gif) repeat-y left;
@@ -916,11 +1178,11 @@
 	background: url(images/box-butt-right.gif) no-repeat bottom right;
 }
 
-#advancedstuff div.dbx-box-wrapper {
+#advancedstuff div.dbx-b-ox-wrapper {
 	background: url(images/box-butt-left.gif) no-repeat bottom left;
 }
 
-#advancedstuff .dbx-box-closed div.dbx-content-wrapper {
+#advancedstuff .dbx-box-closed div.dbx-c-ontent-wrapper {
 	padding-bottom: 2px;
 	background: url(images/box-butt-left.gif) no-repeat bottom left;
 }
@@ -929,30 +1191,29 @@
 	background: url(images/box-butt-right.gif) no-repeat bottom right;
 }
 
-
 /* handle cursors */
 .dbx-handle-cursor {
 	cursor: move;
 }
-	
+
 /* toggle images */
 a.dbx-toggle, a.dbx-toggle:visited {
-	display:block;
+	display: block;
 	overflow: hidden;
 	background-image: url( images/toggle.gif );
 	position: absolute;
-	top: 0px;
-	right: 0px;
+	top: 0;
+	right: 0;
 	background-repeat: no-repeat;
-	border: 0px;
-	margin: 0px;
-	padding: 0px;
+	border: 0;
+	margin: 0;
+	padding: 0;
 }
 
 #moremeta a.dbx-toggle, #moremeta a.dbx-toggle-open:visited {
 	height: 25px;
 	width: 27px;
-	background-position: 0 0px;
+	background-position: 0 0;
 }
 
 #moremeta a.dbx-toggle-open, #moremeta a.dbx-toggle-open:visited {
@@ -989,8 +1250,13 @@
 	filter: alpha(opacity=80);
 }
 
-#newcat { width: 120px; margin-right: 5px; }
-input#catadd { 	background: #a4a4a4;
+#newcat {
+	width: 120px;
+	margin-right: 5px;
+}
+
+input #catadd {
+	background: #a4a4a4;
 	border-bottom: 1px solid #898989;
 	border-left: 1px solid #bcbcbc;
 	border-right: 1px solid #898989;
@@ -1003,13 +1269,73 @@
 	height: 20px;
 	margin-bottom: 2px;
 	text-align: center;
-	width: 37px; }
+	width: 37px;
+}
+
 #howto {
 	font-size: 11px;
 	margin: 0 5px;
 	display: block;
 }
+
 #jaxcat {
 	margin: 0;
 	padding: 0;
-}
\ No newline at end of file
+}
+
+#ajax-response.alignleft {
+	margin-left: 2em;
+}
+
+#postdivrich #edButtons {
+	padding-left: 3px;
+}
+
+#postdivrich #content, #postdivrich #content:active {
+	border: 1px solid #ccc;
+}
+
+#edButtons input, #edButtons input:active {
+	margin: 0 2px -1px;
+}
+
+#edButtons input.edButtonFore, #edButtons input.edButtonFore:active {
+	background: #f0f0ee;
+	border-bottom: 1px solid #f0f0ee;
+}
+
+#edButtons input.edButtonBack, #edButtons input.edButtonBack:active {
+	background: #fff url( images/fade-butt.png ) repeat-x 0 15px;
+	border-bottom: 1px solid #ccc;
+}
+
+.page-numbers {
+	padding: 4px 7px;
+	border: 1px solid #fff;
+	margin-right: 3px;
+}
+
+a.page-numbers {
+	border: 1px solid #ccc;
+}
+
+a.page-numbers:hover {
+	border: 1px solid #999;
+}
+
+.page-numbers.current {
+	border: 1px solid #999;
+	font-weight: bold;
+}
+
+.pagenav span {
+	font-weight: bold;
+	margin: 0 6px;
+}
+
+a.view-link {
+	position: absolute;
+	right: 5%;
+	margin-right: 220px;
+	text-decoration:underline;
+}
diff -ruN 2.0.5/wp-admin/xfn.js 2.2.2/wp-admin/xfn.js
--- 2.0.5/wp-admin/xfn.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-admin/xfn.js	2006-11-19 01:56:05.000000000 -0600
@@ -10,10 +10,10 @@
 }
 
 function meChecked() {
-  var undefined;
-  var eMe = document.getElementById('me');
-  if (eMe == undefined) return false;
-  else return eMe.checked;
+	var undefined;
+	var eMe = document.getElementById('me');
+	if (eMe == undefined) return false;
+	else return eMe.checked;
 }
 
 function upit() {
@@ -38,7 +38,7 @@
 
 	var aInputs = document.getElementsByTagName('input');
 
-	for (var i = 0; i < aInputs.length; i++) {		
+	for (var i = 0; i < aInputs.length; i++) {
 		 aInputs[i].onclick = aInputs[i].onkeyup = upit;
 	}
 }
diff -ruN 2.0.5/wp-app.php 2.2.2/wp-app.php
--- 2.0.5/wp-app.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-app.php	2007-06-26 15:47:17.000000000 -0500
@@ -0,0 +1,1262 @@
+<?php
+/* 
+ * wp-app.php - Atom Publishing Protocol support for WordPress
+ * Original code by: Elias Torres, http://torrez.us/archives/2006/08/31/491/
+ * Modified by: Dougal Campbell, http://dougal.gunters.org/
+ *
+ * Version: 1.0.5-dc
+ */
+
+define('APP_REQUEST', true);
+
+require_once('wp-config.php');
+require_once('wp-includes/post-template.php');
+
+// Attempt to automatically detect whether to use querystring
+// or PATH_INFO, based on our environment:
+$use_querystring = $wp_version == 'MU' ? 1 : 0;
+
+// If using querystring, we need to put the path together manually:
+if ($use_querystring) {
+	$GLOBALS['use_querystring'] = $use_querystring;
+	$action = $_GET['action'];
+	$eid = (int) $_GET['eid'];
+
+	$_SERVER['PATH_INFO'] = $action;
+
+	if ($eid) {
+		$_SERVER['PATH_INFO'] .= "/$eid";
+	}
+} else {
+	$_SERVER['PATH_INFO'] = str_replace( '/wp-app.php', '', $_SERVER['REQUEST_URI'] );
+}
+
+$app_logging = 0;
+
+function log_app($label,$msg) {
+	global $app_logging;
+	if ($app_logging) {
+		$fp = fopen( 'app.log', 'a+');
+		$date = gmdate( 'Y-m-d H:i:s' );
+		fwrite($fp, "\n\n$date - $label\n$msg\n");
+		fclose($fp);
+	}
+}
+
+if ( !function_exists('wp_set_current_user') ) :
+function wp_set_current_user($id, $name = '') {
+	global $current_user;
+
+	if ( isset($current_user) && ($id == $current_user->ID) )
+		return $current_user;
+
+	$current_user = new WP_User($id, $name);
+
+	return $current_user;
+}
+endif;
+
+function wa_posts_where_include_drafts_filter($where) {
+	$where = ereg_replace("post_author = ([0-9]+) AND post_status != 'draft'","post_author = \\1 AND post_status = 'draft'", $where);
+	return $where;
+}
+add_filter('posts_where', 'wa_posts_where_include_drafts_filter');
+
+class AtomEntry {
+	var $links = array();
+	var $categories = array();
+}
+
+class AtomParser {
+
+	var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');
+	var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft');
+
+	var $depth = 0;
+	var $indent = 2;
+	var $in_content;
+	var $ns_contexts = array();
+	var $ns_decls = array();
+	var $is_xhtml = false;
+	var $skipped_div = false;
+
+	var $entry;
+
+	function AtomParser() {
+
+		$this->entry = new AtomEntry();
+		$this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";');
+		$this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";');
+	}
+
+	function parse() {
+
+		global $app_logging;
+		array_unshift($this->ns_contexts, array());
+
+		$parser = xml_parser_create_ns();
+		xml_set_object($parser, $this);
+		xml_set_element_handler($parser, "start_element", "end_element");
+		xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
+		xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
+		xml_set_character_data_handler($parser, "cdata");
+		xml_set_default_handler($parser, "_default");
+		xml_set_start_namespace_decl_handler($parser, "start_ns");
+		xml_set_end_namespace_decl_handler($parser, "end_ns");
+
+		$contents = "";
+
+		$fp = fopen("php://input", "r");
+		while(!feof($fp)) {
+			$line = fgets($fp, 4096);
+		 
+			if($app_logging) $contents .= $line;
+
+			if(!xml_parse($parser, $line)) {
+				log_app("xml_parse_error", "line: $line");
+				$this->error = sprintf(__('XML error: %s at line %d')."\n",
+					xml_error_string(xml_get_error_code($xml_parser)),
+					xml_get_current_line_number($xml_parser));
+				log_app("xml_parse_error", $this->error);
+				return false;
+			}
+		}
+		fclose($fp);
+
+		xml_parser_free($parser);
+
+		log_app("AtomParser->parse()",trim($contents));
+
+		return true;
+	}
+
+	function start_element($parser, $name, $attrs) {
+
+		$tag = array_pop(split(":", $name));
+
+		array_unshift($this->ns_contexts, $this->ns_decls);
+
+		$this->depth++;
+
+		#print str_repeat(" ", $this->depth * $this->indent) . "start_element('$name')" ."\n";
+		#print str_repeat(" ", $this->depth+1 * $this->indent) . print_r($this->ns_contexts,true) ."\n";
+
+		if(!empty($this->in_content)) {
+			$attrs_prefix = array();
+
+			// resolve prefixes for attributes
+			foreach($attrs as $key => $value) {
+				$attrs_prefix[$this->ns_to_prefix($key)] = $this->xml_escape($value);
+			}
+			$attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));
+			if(strlen($attrs_str) > 0) {
+				$attrs_str = " " . $attrs_str;
+			}
+
+			$xmlns_str = join(' ', array_map($this->map_xmlns_func, array_keys($this->ns_contexts[0]), array_values($this->ns_contexts[0])));
+			if(strlen($xmlns_str) > 0) {
+				$xmlns_str = " " . $xmlns_str;
+			}
+
+			// handle self-closing tags (case: a new child found right-away, no text node)
+			if(count($this->in_content) == 2) {
+				array_push($this->in_content, ">");
+			}
+		 
+			array_push($this->in_content, "<". $this->ns_to_prefix($name) ."{$xmlns_str}{$attrs_str}");
+		} else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {
+			$this->in_content = array();
+			$this->is_xhtml = $attrs['type'] == 'xhtml'; 
+			array_push($this->in_content, array($tag,$this->depth));
+		} else if($tag == 'link') {
+			array_push($this->entry->links, $attrs);
+		} else if($tag == 'category') {
+			array_push($this->entry->categories, $attrs);
+		}
+
+		$this->ns_decls = array();
+	}
+
+	function end_element($parser, $name) {
+
+		$tag = array_pop(split(":", $name));
+
+		if(!empty($this->in_content)) {
+			if($this->in_content[0][0] == $tag && 
+			$this->in_content[0][1] == $this->depth) {
+				array_shift($this->in_content);
+				if($this->is_xhtml) {
+					$this->in_content = array_slice($this->in_content, 2, count($this->in_content)-3);
+				}
+				$this->entry->$tag = join('',$this->in_content);
+				$this->in_content = array();
+			} else {
+				$endtag = $this->ns_to_prefix($name);
+				if (strpos($this->in_content[count($this->in_content)-1], '<' . $endtag) !== false) {
+					array_push($this->in_content, "/>");
+				} else {
+					array_push($this->in_content, "</$endtag>");
+				}
+			}
+		}
+
+		array_shift($this->ns_contexts);
+
+		#print str_repeat(" ", $this->depth * $this->indent) . "end_element('$name')" ."\n";
+
+		$this->depth--;
+	}
+
+	function start_ns($parser, $prefix, $uri) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "starting: " . $prefix . ":" . $uri . "\n";
+		array_push($this->ns_decls, array($prefix,$uri));
+	}
+
+	function end_ns($parser, $prefix) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "ending: #" . $prefix . "#\n";
+	}
+
+	function cdata($parser, $data) {
+		#print str_repeat(" ", $this->depth * $this->indent) . "data: #" . $data . "#\n";
+		if(!empty($this->in_content)) {
+			// handle self-closing tags (case: text node found, need to close element started)
+			if (strpos($this->in_content[count($this->in_content)-1], '<') !== false) {
+				array_push($this->in_content, ">");
+			}
+			array_push($this->in_content, $this->xml_escape($data));
+		}
+	}
+
+	function _default($parser, $data) {
+		# when does this gets called?
+	}
+
+
+	function ns_to_prefix($qname) {
+		$components = split(":", $qname);
+		$name = array_pop($components);
+
+		if(!empty($components)) {
+			$ns = join(":",$components);
+			foreach($this->ns_contexts as $context) {
+				foreach($context as $mapping) {
+					if($mapping[1] == $ns && strlen($mapping[0]) > 0) {
+						return "$mapping[0]:$name";
+					}
+				}
+			}
+		} 
+		return $name;
+	}
+
+	function xml_escape($string)
+	{
+			 return str_replace(array('&','"',"'",'<','>'), 
+				array('&amp;','&quot;','&apos;','&lt;','&gt;'), 
+				$string );
+	}
+}
+
+class AtomServer {
+
+	var $ATOM_CONTENT_TYPE = 'application/atom+xml';
+	var $CATEGORIES_CONTENT_TYPE = 'application/atomcat+xml';
+	var $INTROSPECTION_CONTENT_TYPE = 'application/atomserv+xml';
+
+	var $ENTRIES_PATH = "posts";
+	var $CATEGORIES_PATH = "categories";
+	var $MEDIA_PATH = "attachments";
+	var $ENTRY_PATH = "post";
+	var $MEDIA_SINGLE_PATH = "attachment";
+
+	var $params = array();
+	var $script_name = "wp-app.php";
+	var $media_content_types = array('image/*','audio/*','video/*');
+	var $atom_content_types = array('application/atom+xml');
+
+	var $selectors = array();
+
+	// support for head
+	var $do_output = true;
+
+	function AtomServer() {
+
+		$this->script_name = array_pop(explode('/',$_SERVER['SCRIPT_NAME']));
+
+		$this->selectors = array(
+			'@/service@' => 
+				array('GET' => 'get_service'),
+			'@/categories@' =>
+				array('GET' => 'get_categories_xml'),
+			'@/post/(\d+)@' => 
+				array('GET' => 'get_post', 
+						'PUT' => 'put_post', 
+						'DELETE' => 'delete_post'),
+			'@/posts/?([^/]+)?@' => 
+				array('GET' => 'get_posts', 
+						'POST' => 'create_post'),
+			'@/attachments/?(\d+)?@' => 
+				array('GET' => 'get_attachment', 
+						'POST' => 'create_attachment'),
+			'@/attachment/file/(\d+)@' => 
+				array('GET' => 'get_file', 
+						'PUT' => 'put_file', 
+						'DELETE' => 'delete_file'),
+			'@/attachment/(\d+)@' => 
+				array('GET' => 'get_attachment', 
+						'PUT' => 'put_attachment', 
+						'DELETE' => 'delete_attachment'),
+		);
+	}
+
+	function handle_request() {
+
+		$path = $_SERVER['PATH_INFO'];
+		$method = $_SERVER['REQUEST_METHOD'];
+
+		log_app('REQUEST',"$method $path\n================");
+
+		//$this->process_conditionals();
+
+		// exception case for HEAD (treat exactly as GET, but don't output)
+		if($method == 'HEAD') {
+			$this->do_output = false;
+			$method = 'GET';
+		}
+
+		// lame. 
+		if(strlen($path) == 0 || $path == '/') {
+			$path = '/service';
+		}
+
+		// authenticate regardless of the operation and set the current
+		// user. each handler will decide if auth is required or not.
+		$this->authenticate();
+
+		// dispatch
+		foreach($this->selectors as $regex => $funcs) {
+			if(preg_match($regex, $path, $matches)) {
+				if(isset($funcs[$method])) {
+					array_shift($matches);
+					call_user_func_array(array(&$this,$funcs[$method]), $matches);
+					exit();
+				} else {
+					// only allow what we have handlers for...
+					$this->not_allowed(array_keys($funcs));
+				}
+			}
+		}
+
+		// oops, nothing found
+		$this->not_found();
+	}
+
+	function get_service() {
+		log_app('function','get_service()');
+		$entries_url = $this->get_entries_url();
+		$categories_url = $this->get_categories_url(); 
+		$media_url = $this->get_attachments_url();
+		$accepted_content_types = join(',',$this->media_content_types);
+		$introspection = <<<EOD
+<service xmlns="http://purl.org/atom/app#" xmlns:atom="http://www.w3.org/2005/Atom"> 
+	<workspace title="WordPress Workspace"> 
+	    <collection href="$entries_url" title="Posts"> 
+		<atom:title>WordPress Posts</atom:title> 
+		<accept>entry</accept> 
+		<categories href="$categories_url" /> 
+	    </collection> 
+	    <collection href="$media_url" title="Media"> 
+		<atom:title>WordPress Media</atom:title> 
+		<accept>$accepted_content_types</accept> 
+	    </collection> 
+	</workspace> 
+</service>
+
+EOD;
+
+		$this->output($introspection, $this->INTROSPECTION_CONTENT_TYPE); 
+	}
+
+function get_categories_xml() {
+	log_app('function','get_categories_xml()');
+	$home = get_bloginfo_rss('home');
+
+	$categories = "";
+	$cats = get_categories("hierarchical=0&hide_empty=0");
+	foreach ((array) $cats as $cat) {
+		$categories .= "    <category term=\"" . attribute_escape($cat->cat_name) .  "\" />\n";
+	}
+        $output = <<<EOD
+<app:categories xmlns:app="http://purl.org/atom/app#"
+	xmlns="http://www.w3.org/2005/Atom"
+	fixed="yes" scheme="$home">
+	$categories
+</app:categories>
+EOD;
+	$this->output($output, $this->CATEGORIES_CONTENT_TYPE); 
+}
+
+	/*
+	 * Create Post (No arguments)
+	 */
+	function create_post() {
+		global $blog_id;
+		$this->get_accepted_content_type($this->atom_content_types);
+
+		$parser = new AtomParser();
+		if(!$parser->parse()) {
+			$this->client_error();
+		}
+
+		$entry = $parser->entry;
+
+		$publish = (isset($entry->draft) && trim($entry->draft) == 'yes') ? false : true;
+
+		$cap = ($publish) ? 'publish_posts' : 'edit_posts';
+
+		if(!current_user_can($cap))
+			$this->auth_required('Sorry, you do not have the right to edit/publish new posts.');
+
+		$blog_ID = (int ) $blog_id;
+		$post_status = ($publish) ? 'publish' : 'draft';
+		$post_author = (int) $user->ID;
+		$post_title = $entry->title;
+		$post_content = $entry->content;
+		$post_excerpt = $entry->summary;
+		$post_date = current_time('mysql');
+		$post_date_gmt = current_time('mysql', 1);
+
+		$post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt');
+
+		log_app('Inserting Post. Data:', print_r($post_data,true));
+
+		$postID = wp_insert_post($post_data);
+
+		if (!$postID) {
+			$this->internal_error('Sorry, your entry could not be posted. Something wrong happened.');
+		}
+
+		$output = $this->get_entry($postID);
+
+		log_app('function',"create_post($postID)");
+		$this->created($postID, $output);
+	}
+
+	function get_post($postID) {
+
+		global $entry;
+		$this->set_current_entry($postID);
+		$output = $this->get_entry($postID);
+		log_app('function',"get_post($postID)");
+		$this->output($output);
+
+	}
+
+	function put_post($postID) {
+
+		// checked for valid content-types (atom+xml)
+		// quick check and exit
+		$this->get_accepted_content_type($this->atom_content_types);
+
+		$parser = new AtomParser();
+		if(!$parser->parse()) {
+			$this->bad_request();
+		}
+
+		$parsed = $parser->entry;
+
+		// check for not found
+		global $entry;
+		$entry = $GLOBALS['entry'];
+		$this->set_current_entry($postID);
+		$this->escape($GLOBALS['entry']);
+
+		if(!current_user_can('edit_post', $entry['ID']))
+			$this->auth_required('Sorry, you do not have the right to edit this post.');
+
+		$publish = (isset($parsed->draft) && trim($parsed->draft) == 'yes') ? false : true;
+
+		extract($entry);
+
+		$post_title = $parsed->title;
+		$post_content = $parsed->content;
+		$post_excerpt = $parsed->summary;
+
+		// let's not go backwards and make something draft again.
+		if(!$publish && $post_status == 'draft') {
+			$post_status = ($publish) ? 'publish' : 'draft';
+		}
+
+		$postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt');
+
+		$result = wp_update_post($postdata);
+
+		if (!$result) {
+			$this->internal_error('For some strange yet very annoying reason, this post could not be edited.');
+		}
+
+		log_app('function',"put_post($postID)");
+		$this->ok();
+	}
+
+	function delete_post($postID) {
+
+		// check for not found
+		global $entry;
+		$this->set_current_entry($postID);
+
+		if(!current_user_can('edit_post', $postID)) {
+			$this->auth_required('Sorry, you do not have the right to delete this post.');
+		}
+
+		if ($entry['post_type'] == 'attachment') {
+			$this->delete_attachment($postID);
+		} else {
+			$result = wp_delete_post($postID);
+
+			if (!$result) {
+				$this->internal_error('For some strange yet very annoying reason, this post could not be deleted.');
+			}
+
+			log_app('function',"delete_post($postID)");
+			$this->ok();
+		}
+
+	}
+
+	function get_attachment($postID = NULL) {
+
+		global $entry;
+		if (!isset($postID)) {
+			$this->get_attachments();
+		} else {
+			$this->set_current_entry($postID);
+			$output = $this->get_entry($postID, 'attachment');
+			log_app('function',"get_attachment($postID)");
+			$this->output($output);
+		}
+	}
+
+	function create_attachment() {
+		global $wp, $wpdb, $wp_query, $blog_id;
+
+		$type = $this->get_accepted_content_type();
+
+		if(!current_user_can('upload_files'))
+			$this->auth_required('You do not have permission to upload files.');
+
+		$fp = fopen("php://input", "rb");
+		$bits = NULL;
+		while(!feof($fp)) {
+			$bits .= fread($fp, 4096);
+		}
+		fclose($fp);
+
+		$slug = '';
+		if ( isset( $_SERVER['HTTP_SLUG'] ) )
+			$slug = sanitize_file_name( $_SERVER['HTTP_SLUG'] );
+		elseif ( isset( $_SERVER['HTTP_TITLE'] ) )
+			$slug = sanitize_file_name( $_SERVER['HTTP_TITLE'] );
+		elseif ( empty( $slug ) ) // just make a random name
+			$slug = substr( md5( uniqid( microtime() ) ), 0, 7);
+		$ext = preg_replace( '|.*/([a-z]+)|', '$1', $_SERVER['CONTENT_TYPE'] );
+		$slug = "$slug.$ext";
+		$file = wp_upload_bits( $slug, NULL, $bits);
+
+		log_app('wp_upload_bits returns:',print_r($file,true));
+
+		$url = $file['url'];
+		$file = $file['file'];
+		$filename = basename($file);
+
+		$header = apply_filters('wp_create_file_in_uploads', $file); // replicate
+
+		// Construct the attachment array
+		$attachment = array(
+			'post_title' => $slug,
+			'post_content' => $slug,
+			'post_status' => 'attachment',
+			'post_parent' => 0,
+			'post_mime_type' => $type,
+			'guid' => $url
+			);
+
+		// Save the data
+		$postID = wp_insert_attachment($attachment, $file, $post);
+
+		if (!$postID) {
+			$this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.'));
+		}
+
+		$output = $this->get_entry($postID, 'attachment');
+
+		$this->created($postID, $output, 'attachment');
+		log_app('function',"create_attachment($postID)");
+	}
+
+	function put_attachment($postID) {
+
+		// checked for valid content-types (atom+xml)
+		// quick check and exit
+		$this->get_accepted_content_type($this->atom_content_types);
+
+		$parser = new AtomParser();
+		if(!$parser->parse()) {
+			$this->bad_request();
+		}
+
+		$parsed = $parser->entry;
+
+		// check for not found
+		global $entry;
+		$this->set_current_entry($postID);
+		$this->escape($entry);
+
+		if(!current_user_can('edit_post', $entry['ID']))
+			$this->auth_required(__('Sorry, you do not have the right to edit this post.'));
+
+		$publish = (isset($parsed->draft) && trim($parsed->draft) == 'yes') ? false : true;
+
+		extract($entry);
+
+		$post_title = $parsed->title;
+		$post_content = $parsed->content;
+
+		$postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt');
+
+		$result = wp_update_post($postdata);
+
+		if (!$result) {
+			$this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.'));
+		}
+
+		log_app('function',"put_attachment($postID)");
+		$this->ok();
+	}
+
+	function delete_attachment($postID) {
+		log_app('function',"delete_attachment($postID). File '$location' deleted.");
+
+		// check for not found
+		global $entry;
+		$this->set_current_entry($postID);
+
+		if(!current_user_can('edit_post', $postID)) {
+			$this->auth_required(__('Sorry, you do not have the right to delete this post.'));
+		}
+
+		$location = get_post_meta($entry['ID'], '_wp_attached_file', true);
+
+		// delete file
+		@unlink($location);
+
+		// delete attachment
+		$result = wp_delete_post($postID);
+
+		if (!$result) {
+			$this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.'));
+		}
+
+		log_app('function',"delete_attachment($postID). File '$location' deleted.");
+		$this->ok();
+	}
+
+	function get_file($postID) {
+
+		// check for not found
+		global $entry;
+		$this->set_current_entry($postID);
+
+		// then whether user can edit the specific post
+		if(!current_user_can('edit_post', $postID)) {
+			$this->auth_required(__('Sorry, you do not have the right to edit this post.'));
+		}
+
+		$location = get_post_meta($entry['ID'], '_wp_attached_file', true);
+		$filetype = wp_check_filetype($location);
+
+		if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']))
+			$this->internal_error(__('Error ocurred while accessing post metadata for file location.'));
+
+		header('Content-Type: ' . $entry['post_mime_type']);
+
+		$fp = fopen($location, "rb");
+		while(!feof($fp)) {
+			echo fread($fp, 4096);
+		}
+		fclose($fp);
+
+		log_app('function',"get_file($postID)");
+		$this->ok();
+	}
+
+	function put_file($postID) {
+
+		$type = $this->get_accepted_content_type();
+
+		// first check if user can upload
+		if(!current_user_can('upload_files'))
+			$this->auth_required(__('You do not have permission to upload files.'));
+
+		// check for not found
+		global $entry;
+		$this->set_current_entry($postID);
+
+		// then whether user can edit the specific post
+		if(!current_user_can('edit_post', $postID)) {
+			$this->auth_required(__('Sorry, you do not have the right to edit this post.'));
+		}
+
+		$location = get_post_meta($entry['ID'], '_wp_attached_file', true);
+		$filetype = wp_check_filetype($location);
+
+		if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']))
+			$this->internal_error(__('Error ocurred while accessing post metadata for file location.'));
+
+		$fp = fopen("php://input", "rb");
+		$localfp = fopen($location, "w+");
+		while(!feof($fp)) {
+			fwrite($localfp,fread($fp, 4096));
+		}
+		fclose($fp);
+		fclose($localfp);
+
+		log_app('function',"put_file($postID)");
+		$this->ok();
+	}
+
+	function get_entries_url($page = NULL) {
+		global $use_querystring;
+		$url = get_bloginfo('url') . '/' . $this->script_name;
+		if ($use_querystring) {
+			$url .= '?action=/' . $this->ENTRIES_PATH;
+			if(isset($page) && is_int($page)) {
+				$url .= "&amp;eid=$page";
+			}
+		} else {
+			$url .= '/' . $this->ENTRIES_PATH;
+			if(isset($page) && is_int($page)) {
+				$url .= "/$page";
+			}
+		}
+		return $url;
+	}
+
+	function the_entries_url($page = NULL) {
+		$url = $this->get_entries_url($page);
+		echo $url;
+	}
+
+	function get_categories_url($page = NULL) {
+		global $use_querystring;
+		$url = get_bloginfo('url') . '/' . $this->script_name;
+		if ($use_querystring) {
+			$url .= '?action=/' . $this->CATEGORIES_PATH;
+		} else {
+			$url .= '/' . $this->CATEGORIES_PATH;
+		}
+		return $url;
+	}
+
+	function the_categories_url() {
+		$url = $this->get_categories_url();
+		echo $url;
+    }
+
+	function get_attachments_url($page = NULL) {
+		global $use_querystring;
+		$url = get_bloginfo('url') . '/' . $this->script_name;
+		if ($use_querystring) {
+			$url .= '?action=/' . $this->MEDIA_PATH;
+			if(isset($page) && is_int($page)) {
+				$url .= "&amp;eid=$page";
+			}
+		} else {
+			$url .= '/' . $this->MEDIA_PATH;
+			if(isset($page) && is_int($page)) {
+				$url .= "/$page";
+			}
+		}
+		return $url;
+	}
+
+	function the_attachments_url($page = NULL) {
+		$url = $this->get_attachments_url($page);
+		echo $url;
+	}
+
+
+	function get_entry_url($postID = NULL) {
+		global $use_querystring;
+		if(!isset($postID)) {
+			global $post;
+			$postID = (int) $GLOBALS['post']->ID;
+		}
+
+		if ($use_querystring) {
+			$url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->ENTRY_PATH . "&amp;eid=$postID";
+		} else {
+			$url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->ENTRY_PATH . "/$postID";
+		}
+
+		log_app('function',"get_entry_url() = $url");
+		return $url;
+	}
+
+	function the_entry_url($postID = NULL) {
+		$url = $this->get_entry_url($postID);
+		echo $url;
+	}
+
+	function get_media_url($postID = NULL) {
+		global $use_querystring;
+		if(!isset($postID)) {
+			global $post;
+			$postID = (int) $GLOBALS['post']->ID;
+		}
+
+		if ($use_querystring) {
+			$url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->MEDIA_SINGLE_PATH ."&amp;eid=$postID";
+		} else {
+			$url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_SINGLE_PATH ."/$postID";
+		}
+
+		log_app('function',"get_media_url() = $url");
+		return $url;
+	}
+
+	function the_media_url($postID = NULL) {
+		$url = $this->get_media_url($postID);
+		echo $url;
+	}
+
+	function set_current_entry($postID) {
+		global $entry;
+		log_app('function',"set_current_entry($postID)");
+
+		if(!isset($postID)) {
+			// $this->bad_request();
+			$this->not_found();
+		}
+
+		$entry = wp_get_single_post($postID,ARRAY_A);
+
+		if(!isset($entry) || !isset($entry['ID']))
+			$this->not_found();
+
+		return;
+	}
+
+	function get_posts_count() {
+		global $wpdb;
+		log_app('function',"get_posts_count()");
+		return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_date_gmt < '" . gmdate("Y-m-d H:i:s",time()) . "'");
+	}
+
+
+	function get_posts($page = 1, $post_type = 'post') {
+			log_app('function',"get_posts($page, '$post_type')");
+			$feed = $this->get_feed($page, $post_type);
+			$this->output($feed);
+	}
+
+	function get_attachments($page = 1, $post_type = 'attachment') {
+			log_app('function',"get_attachments($page, '$post_type')");
+			$feed = $this->get_feed($page, $post_type);
+			$this->output($feed);
+	}
+
+	function get_feed($page = 1, $post_type = 'post') {
+		global $post, $wp, $wp_query, $posts, $wpdb, $blog_id, $post_cache;
+		log_app('function',"get_feed($page, '$post_type')");
+		ob_start();
+
+		if(!isset($page)) {
+			$page = 1;
+		}
+		$page = (int) $page;
+
+		$count = get_option('posts_per_rss');
+		$query = "paged=$page&posts_per_page=$count&order=DESC";
+		if($post_type == 'attachment') {
+			$query .= "&post_type=$post_type";
+		}
+		query_posts($query);
+		$post = $GLOBALS['post'];
+		$posts = $GLOBALS['posts'];
+		$wp = $GLOBALS['wp'];
+		$wp_query = $GLOBALS['wp_query'];
+		$wpdb = $GLOBALS['wpdb'];
+		$blog_id = (int) $GLOBALS['blog_id'];
+		$post_cache = $GLOBALS['post_cache'];
+
+
+		$total_count = $this->get_posts_count();
+		$last_page = (int) ceil($total_count / $count);
+		$next_page = (($page + 1) > $last_page) ? NULL : $page + 1;
+		$prev_page = ($page - 1) < 1 ? NULL : $page - 1; 
+		$last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page;
+?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://purl.org/atom/app#" xml:lang="<?php echo get_option('rss_language'); ?>">
+<id><?php $this->the_entries_url() ?></id>
+<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT')); ?></updated>
+<title type="text"><?php bloginfo_rss('name') ?></title>
+<subtitle type="text"><?php bloginfo_rss("description") ?></subtitle>
+<link rel="first" type="application/atom+xml" href="<?php $this->the_entries_url() ?>" />
+<?php if(isset($prev_page)): ?>
+<link rel="previous" type="application/atom+xml" href="<?php $this->the_entries_url($prev_page) ?>" />
+<?php endif; ?>
+<?php if(isset($next_page)): ?>
+<link rel="next" type="application/atom+xml" href="<?php $this->the_entries_url($next_page) ?>" />
+<?php endif; ?>
+<link rel="last" type="application/atom+xml" href="<?php $this->the_entries_url($last_page) ?>" />
+<link rel="self" type="application/atom+xml" href="<?php $this->the_entries_url() ?>" />
+<rights type="text">Copyright <?php echo mysql2date('Y', get_lastpostdate('blog')); ?></rights>
+<generator uri="http://wordpress.com/" version="1.0.5-dc">WordPress.com Atom API</generator>
+<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); 
+$post = $GLOBALS['post'];
+?>
+<entry>
+		<id><?php the_guid($post->ID); ?></id>
+		<title type="html"><![CDATA[<?php the_title() ?>]]></title>
+		<updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated>
+		<published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published>
+		<app:control>
+			<app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft>
+		</app:control>
+		<author>
+			<name><?php the_author()?></name>
+			<email><?php the_author_email()?></email>
+	<?php if (get_the_author_url() && get_the_author_url() != 'http://') { ?>
+		 <uri><?php the_author_url()?></uri>
+	<?php } ?>
+		</author>
+	<?php if($GLOBALS['post']->post_status == 'attachment') { ?>
+		<link rel="edit" href="<?php $this->the_entry_url() ?>" />
+		<link rel="edit-media" href="<?php $this->the_media_url() ?>" />
+	<?php } else { ?>
+		<link href="<?php permalink_single_rss() ?>" />
+		<link rel="edit" href="<?php $this->the_entry_url() ?>" />
+	<?php } ?>
+	<?php foreach(get_the_category() as $category) { ?>
+	 <category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->cat_name?>" />
+	<?php } ?>   <summary type="html"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
+	<?php if ( strlen( $GLOBALS['post']->post_content ) ) : ?>
+	<content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content>
+<?php endif; ?>
+	</entry>
+<?php
+	endwhile; 
+	endif;
+?></feed>
+<?php 
+		$feed = ob_get_contents();
+		ob_end_clean();
+		return $feed;
+	}
+
+	function get_entry($postID, $post_type = 'post') {
+		log_app('function',"get_entry($postID, '$post_type')");
+		ob_start();
+		global $posts, $post, $wp_query, $wp, $wpdb, $blog_id, $post_cache;
+		switch($post_type) {
+			case 'post':
+				$varname = 'p';
+				break;
+			case 'attachment':
+				$varname = 'attachment_id';
+				break;
+		}
+		query_posts($varname . '=' . $postID);
+		if ( have_posts() ) : while ( have_posts() ) : the_post();
+		$post = $GLOBALS['post'];
+		?>
+		<?php log_app('$post',print_r($GLOBALS['post'],true)); ?>
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://purl.org/atom/app#" xml:lang="<?php echo get_option('rss_language'); ?>">
+	<id><?php the_guid($post->ID); ?></id>
+	<title type="html"><![CDATA[<?php the_title_rss() ?>]]></title>
+
+	<updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated>
+	<published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published>
+	<app:control>
+		<app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft>
+	</app:control>
+	<author>
+		<name><?php the_author()?></name>
+		<email><?php the_author_email()?></email>
+		<uri><?php the_author_url()?></uri>
+	</author>
+<?php if($GLOBALS['post']->post_type == 'attachment') { ?>
+	<link rel="edit" href="<?php $this->the_entry_url() ?>" />
+	<link rel="edit-media" href="<?php $this->the_media_url() ?>" />
+	<content type="<?php echo $GLOBALS['post']->post_mime_type ?>" src="<?php the_guid(); ?>"/>
+<?php } else { ?>
+	<link href="<?php permalink_single_rss() ?>" />
+	<link rel="edit" href="<?php $this->the_entry_url() ?>" />
+<?php } ?>
+<?php foreach(get_the_category() as $category) { ?>
+	<category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->cat_name?>" />
+	<summary type="html"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
+<?php }
+	if ( strlen( $GLOBALS['post']->post_content ) ) : ?>
+	<content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content>
+<?php endif; ?>
+</entry>
+<?php
+		$entry = ob_get_contents();
+		break;
+		endwhile;
+		else:
+			$this->auth_required(__("Access Denied."));
+		endif;
+		ob_end_clean();
+
+		log_app('get_entry returning:',$entry);
+		return $entry; 
+	}
+
+	function ok() { 
+		log_app('Status','200: OK');
+		header('Content-Type: text/plain');
+		status_header('200');
+		exit;
+	}
+
+	function no_content() { 
+		log_app('Status','204: No Content');
+		header('Content-Type: text/plain');
+		status_header('204');
+		echo "Deleted.";
+		exit;
+	}
+
+	function internal_error($msg = 'Internal Server Error') {
+		log_app('Status','500: Server Error');
+		header('Content-Type: text/plain');
+		status_header('500');
+		echo $msg;
+		exit;
+	}
+
+	function bad_request() {
+		log_app('Status','400: Bad Request');
+		header('Content-Type: text/plain');
+		status_header('400');
+		exit;
+	}
+
+	function length_required() {
+		log_app('Status','411: Length Required');
+		header("HTTP/1.1 411 Length Required");
+		header('Content-Type: text/plain');
+		status_header('411');
+		exit;
+	}
+
+	function invalid_media() {
+		log_app('Status','415: Unsupported Media Type');
+		header("HTTP/1.1 415 Unsupported Media Type");
+		header('Content-Type: text/plain');
+		exit;
+	}
+
+	function not_found() {
+		log_app('Status','404: Not Found');
+		header('Content-Type: text/plain');
+		status_header('404');
+		exit;
+	}
+
+	function not_allowed($allow) {
+		log_app('Status','405: Not Allowed');
+		header('Allow: ' . join(',', $allow));
+		status_header('405');
+		exit;
+	}
+
+	function client_error($msg = 'Client Error') {
+		log_app('Status','400: Client Errir');
+		header('Content-Type: text/plain');
+		status_header('400');
+		exit;
+	}
+
+	function created($post_ID, $content, $post_type = 'post') {
+		global $use_querystring;
+		log_app('created()::$post_ID',"$post_ID, $post_type");
+		$edit = $this->get_entry_url($post_ID);
+		switch($post_type) {
+			case 'post':
+				$ctloc = $this->get_entry_url($post_ID);
+				break;
+			case 'attachment':
+				if ($use_querystring) {
+					$edit = get_bloginfo('url') . '/' . $this->script_name . "?action=/attachments&amp;eid=$post_ID";
+				} else {
+					$edit = get_bloginfo('url') . '/' . $this->script_name . "/attachments/$post_ID";
+				}
+				break;
+		}
+		header('Content-Type: application/atom+xml');
+		if(isset($ctloc))
+			header('Content-Location: ' . $ctloc);
+		header('Location: ' . $edit);
+		status_header('201');
+		echo $content;
+		exit;
+	}
+
+	function auth_required($msg) {
+		log_app('Status','401: Auth Required');
+		nocache_headers();
+		header('WWW-Authenticate: Basic realm="WordPress Atom Protocol"');
+		header('WWW-Authenticate: Form action="' . get_option('siteurl') . '/wp-login.php"', false); 
+		header("HTTP/1.1 401 $msg");
+		header('Status: ' . $msg);
+		header('Content-Type: plain/text');
+		echo $msg;
+		exit;
+	}
+
+	function output($xml, $ctype = "application/atom+xml") {
+			status_header('200');
+			$xml = '<?xml version="1.0" encoding="' . strtolower(get_option('blog_charset')) . '"?>'."\n".$xml;
+			header('Connection: close');
+			header('Content-Length: '. strlen($xml));
+			header('Content-Type: ' . $ctype);
+			header('Content-Disposition: attachment; filename=atom.xml');
+			header('Date: '. date('r'));
+			if($this->do_output)
+				echo $xml;
+			log_app('function', "output:\n$xml");
+			exit;
+	}
+
+	function escape(&$array) {
+		global $wpdb;
+
+		foreach ($array as $k => $v) {
+				if (is_array($v)) {
+						$this->escape($array[$k]);
+				} else if (is_object($v)) {
+						//skip
+				} else {
+						$array[$k] = $wpdb->escape($v);
+				}
+		}
+	}
+
+
+
+	/*
+	 * Access credential through various methods and perform login
+	 */
+	function authenticate() {
+		$login_data = array();
+		$already_md5 = false;
+
+		log_app("authenticate()",print_r($_ENV, true));
+
+		// if using mod_rewrite/ENV hack
+		// http://www.besthostratings.com/articles/http-auth-php-cgi.html
+		if(isset($_SERVER['HTTP_AUTHORIZATION'])) {
+			list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = 
+				explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
+		}
+
+		// If Basic Auth is working...
+		if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
+			$login_data = array('login' => $_SERVER['PHP_AUTH_USER'],	'password' => $_SERVER['PHP_AUTH_PW']);
+		} else {
+			// else, do cookie-based authentication
+			if (function_exists('wp_get_cookie_login')) {
+				$login_data = wp_get_cookie_login();
+				$already_md5 = true;
+			}
+		}
+
+		// call wp_login and set current user
+		if (!empty($login_data) && wp_login($login_data['login'], $login_data['password'], $already_md5)) {
+			 $current_user = new WP_User(0, $login_data['login']);
+			 wp_set_current_user($current_user->ID);
+			log_app("authenticate()",$login_data['login']);
+		}
+	}
+
+	function get_accepted_content_type($types = NULL) {
+
+		if(!isset($types)) {
+			$types = $this->media_content_types;
+		}
+
+		if(!isset($_SERVER['CONTENT_LENGTH']) || !isset($_SERVER['CONTENT_TYPE'])) {
+			$this->length_required();
+		}
+
+		$type = $_SERVER['CONTENT_TYPE'];
+		list($type,$subtype) = explode('/',$type);
+		list($subtype) = explode(";",$subtype); // strip MIME parameters
+		log_app("get_accepted_content_type", "type=$type, subtype=$subtype");
+
+		foreach($types as $t) {
+			list($acceptedType,$acceptedSubtype) = explode('/',$t); 
+			if($acceptedType == '*' || $acceptedType == $type) {
+				if($acceptedSubtype == '*' || $acceptedSubtype == $subtype)
+					return $type;
+			}
+		}
+
+		$this->invalid_media();
+	}
+
+
+
+	function process_conditionals() {
+
+		if(empty($this->params)) return;
+		if($_SERVER['REQUEST_METHOD'] == 'DELETE') return;
+
+		switch($this->params[0]) {
+			case $this->ENTRY_PATH:
+				global $post;
+				$post = wp_get_single_post($this->params[1]);
+				$wp_last_modified = get_post_modified_time('D, d M Y H:i:s', true);
+				$post = NULL;
+				break;
+			case $this->ENTRIES_PATH:
+				$wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
+				break;
+			default:
+				return;
+		}
+		$wp_etag = md5($wp_last_modified);
+		@header("Last-Modified: $wp_last_modified");
+		@header("ETag: $wp_etag");
+
+		// Support for Conditional GET
+		if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) 
+			$client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
+		else 
+			$client_etag = false;
+
+		$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']);
+		// If string is empty, return 0. If not, attempt to parse into a timestamp
+		$client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
+
+		// Make a timestamp for our most recent modification...
+		$wp_modified_timestamp = strtotime($wp_last_modified);
+
+		if ( ($client_last_modified && $client_etag) ?
+		(($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) :
+		(($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) {
+			status_header( 304 );
+			exit;
+		}
+	}
+
+
+}
+
+$server = new AtomServer();
+$server->handle_request();
+
+?>
diff -ruN 2.0.5/wp-atom.php 2.2.2/wp-atom.php
--- 2.0.5/wp-atom.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-atom.php	2007-02-22 20:50:05.000000000 -0600
@@ -5,41 +5,6 @@
 	wp('feed=atom');
 }
 
-header('Content-type: application/atom+xml; charset=' . get_settings('blog_charset'), true);
-$more = 1;
+require (ABSPATH . WPINC . '/feed-atom.php');
 
-?>
-<?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
-<feed version="0.3"
-  xmlns="http://purl.org/atom/ns#"
-  xmlns:dc="http://purl.org/dc/elements/1.1/"
-  xml:lang="<?php echo get_option('rss_language'); ?>"
-  <?php do_action('atom_ns'); ?>
-  >
-	<title><?php bloginfo_rss('name') ?></title>
-	<link rel="alternate" type="text/html" href="<?php bloginfo_rss('home') ?>" />
-	<tagline><?php bloginfo_rss("description") ?></tagline>
-	<modified><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></modified>
-	<copyright>Copyright <?php echo mysql2date('Y', get_lastpostdate('blog'), 0); ?></copyright>
-	<generator url="http://wordpress.org/" version="<?php bloginfo_rss('version'); ?>">WordPress</generator>
-	<?php do_action('atom_head'); ?>
-	<?php $items_count = 0; if ($posts) { foreach ($posts as $post) { start_wp(); ?>
-	<entry>
-	  	<author>
-			<name><?php the_author() ?></name>
-		</author>
-		<title type="text/html" mode="escaped"><![CDATA[<?php the_title_rss() ?>]]></title>
-		<link rel="alternate" type="text/html" href="<?php permalink_single_rss() ?>" />
-		<id><?php the_guid(); ?></id>
-		<modified><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></modified>
-		<issued><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></issued>
-		<?php the_category_rss('rdf') ?> 
-		<summary type="text/plain" mode="escaped"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
-<?php if ( !get_settings('rss_use_excerpt') ) : ?>
-		<content type="<?php bloginfo('html_type'); ?>" mode="escaped" xml:base="<?php permalink_single_rss() ?>"><![CDATA[<?php the_content('', 0, '') ?>]]></content>
-<?php endif; ?>
-<?php rss_enclosure(); ?>
-<?php do_action('atom_entry'); ?>
-	</entry>
-	<?php $items_count++; if (($items_count == get_settings('posts_per_rss')) && empty($m)) { break; } } } ?>
-</feed>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-blog-header.php 2.2.2/wp-blog-header.php
--- 2.0.5/wp-blog-header.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-blog-header.php	2007-05-09 11:17:41.000000000 -0500
@@ -2,9 +2,13 @@
 
 if (! isset($wp_did_header)):
 if ( !file_exists( dirname(__FILE__) . '/wp-config.php') ) {
-	if ( strstr( $_SERVER['PHP_SELF'], 'wp-admin') ) $path = '';
+	if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false) $path = '';
 	else $path = 'wp-admin/';
-    die("There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://wordpress.org/docs/faq/#wp-config'>We got it</a>. You can <a href='{$path}setup-config.php'>create a <code>wp-config.php</code> file through a web interface</a>, but this doesn't work for all server setups. The safest way is to manually create the file.");
+
+	require_once( dirname(__FILE__) . '/wp-includes/classes.php');
+	require_once( dirname(__FILE__) . '/wp-includes/functions.php');
+	require_once( dirname(__FILE__) . '/wp-includes/plugin.php');
+	wp_die("There doesn't seem to be a <code>wp-config.php</code> file. I need this before we can get started. Need more help? <a href='http://codex.wordpress.org/Editing_wp-config.php'>We got it</a>. You can <a href='{$path}setup-config.php'>create a <code>wp-config.php</code> file through a web interface</a>, but this doesn't work for all server setups. The safest way is to manually create the file.", "WordPress &rsaquo; Error");
 }
 
 $wp_did_header = true;
@@ -18,4 +22,4 @@
 
 endif;
 
-?>
\ No newline at end of file
+?>
diff -ruN 2.0.5/wp-comments-post.php 2.2.2/wp-comments-post.php
--- 2.0.5/wp-comments-post.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-comments-post.php	2007-03-28 12:34:42.000000000 -0500
@@ -1,4 +1,10 @@
 <?php
+if ($_SERVER["REQUEST_METHOD"] != "POST") {
+    header('Allow: POST');
+	header("HTTP/1.1 405 Method Not Allowed");
+	header("Content-type: text/plain");
+    exit;
+}
 require( dirname(__FILE__) . '/wp-config.php' );
 
 nocache_headers();
@@ -12,46 +18,52 @@
 	exit;
 } elseif ( 'closed' ==  $status->comment_status ) {
 	do_action('comment_closed', $comment_post_ID);
-	die( __('Sorry, comments are closed for this item.') );
+	wp_die( __('Sorry, comments are closed for this item.') );
 } elseif ( 'draft' == $status->post_status ) {
 	do_action('comment_on_draft', $comment_post_ID);
 	exit;
 }
 
-$comment_author       = trim($_POST['author']);
+$comment_author       = trim(strip_tags($_POST['author']));
 $comment_author_email = trim($_POST['email']);
 $comment_author_url   = trim($_POST['url']);
 $comment_content      = trim($_POST['comment']);
 
 // If the user is logged in
 $user = wp_get_current_user();
-if ( $user->ID ) :
+if ( $user->ID ) {
 	$comment_author       = $wpdb->escape($user->display_name);
 	$comment_author_email = $wpdb->escape($user->user_email);
 	$comment_author_url   = $wpdb->escape($user->user_url);
-else :
+	if ( current_user_can('unfiltered_html') ) {
+		if ( wp_create_nonce('unfiltered-html-comment_' . $comment_post_ID) != $_POST['_wp_unfiltered_html_comment'] ) {
+			kses_remove_filters(); // start with a clean slate
+			kses_init_filters(); // set up the filters
+		}
+	}
+} else {
 	if ( get_option('comment_registration') )
-		die( __('Sorry, you must be logged in to post a comment.') );
-endif;
+		wp_die( __('Sorry, you must be logged in to post a comment.') );
+}
 
 $comment_type = '';
 
-if ( get_settings('require_name_email') && !$user->ID ) {
+if ( get_option('require_name_email') && !$user->ID ) {
 	if ( 6 > strlen($comment_author_email) || '' == $comment_author )
-		die( __('Error: please fill the required fields (name, email).') );
+		wp_die( __('Error: please fill the required fields (name, email).') );
 	elseif ( !is_email($comment_author_email))
-		die( __('Error: please enter a valid email address.') );
+		wp_die( __('Error: please enter a valid email address.') );
 }
 
 if ( '' == $comment_content )
-	die( __('Error: please type a comment.') );
+	wp_die( __('Error: please type a comment.') );
 
 $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID');
 
 $comment_id = wp_new_comment( $commentdata );
 
+$comment = get_comment($comment_id);
 if ( !$user->ID ) :
-	$comment = get_comment($comment_id);
 	setcookie('comment_author_' . COOKIEHASH, $comment->comment_author, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
 	setcookie('comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
 	setcookie('comment_author_url_' . COOKIEHASH, clean_url($comment->comment_author_url), time() + 30000000, COOKIEPATH, COOKIE_DOMAIN);
diff -ruN 2.0.5/wp-commentsrss2.php 2.2.2/wp-commentsrss2.php
--- 2.0.5/wp-commentsrss2.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-commentsrss2.php	2007-02-22 20:50:05.000000000 -0600
@@ -1,86 +1,10 @@
-<?php 
+<?php
 
 if (empty($wp)) {
 	require_once('wp-config.php');
 	wp('feed=rss2&withcomments=1');
 }
 
-header('Content-type: text/xml;charset=' . get_settings('blog_charset'), true);
-
-echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; 
-?>
-<!-- generator="wordpress/<?php echo $wp_version ?>" -->
-<rss version="2.0" 
-	xmlns:content="http://purl.org/rss/1.0/modules/content/">
-<channel>
-<?php
-$i = 0;
-if (have_posts()) :
-  while (have_posts()) : the_post();
-	if ($i < 1) {
-		$i++;
-?>
-	<title><?php if (is_single() || is_page() ) { printf(__('Comments on: %s'), get_the_title_rss()); } else { printf(__('Comments for %s'), get_bloginfo_rss("name")); } ?></title>
-	<link><?php (is_single()) ? permalink_single_rss() : bloginfo_rss("url") ?></link>
-	<description><?php bloginfo_rss("description") ?></description>
-	<pubDate><?php echo gmdate('r'); ?></pubDate>
-	<generator>http://wordpress.org/?v=<?php echo $wp_version ?></generator>
+require (ABSPATH . WPINC . '/feed-rss2-comments.php');
 
-<?php 
-		if (is_single() || is_page()) {
-			$comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_author_email, 
-			comment_author_url, comment_date, comment_date_gmt, comment_content, comment_post_ID, 
-			$wpdb->posts.ID, $wpdb->posts.post_password FROM $wpdb->comments 
-			LEFT JOIN $wpdb->posts ON comment_post_id = id WHERE comment_post_ID = '$id' 
-			AND $wpdb->comments.comment_approved = '1' AND $wpdb->posts.post_status IN ('publish', 'static', 'object') 
-			AND post_date_gmt < '" . gmdate("Y-m-d H:i:59") . "' 
-			ORDER BY comment_date_gmt DESC LIMIT " . get_settings('posts_per_rss') );
-		} else { // if no post id passed in, we'll just ue the last 10 comments.
-			$comments = $wpdb->get_results("SELECT comment_ID, comment_author, comment_author_email, 
-			comment_author_url, comment_date, comment_date_gmt, comment_content, comment_post_ID, 
-			$wpdb->posts.ID, $wpdb->posts.post_password FROM $wpdb->comments 
-			LEFT JOIN $wpdb->posts ON comment_post_id = id WHERE $wpdb->posts.post_status IN ('publish', 'static', 'object') 
-			AND $wpdb->comments.comment_approved = '1' AND post_date_gmt < '" . gmdate("Y-m-d H:i:s") . "'  
-			ORDER BY comment_date_gmt DESC LIMIT " . get_settings('posts_per_rss') );
-		}
-	// this line is WordPress' motor, do not delete it.
-		if ($comments) {
-			foreach ($comments as $comment) {
-				// Some plugins may need to know the metadata
-				// associated with this comment's post:
-				get_post_custom($comment->comment_post_ID);
-?>
-	<item>
-		<title><?php if ( ! (is_single() || is_page()) ) {
-			$title = get_the_title($comment->comment_post_ID);
-			$title = apply_filters('the_title', $title);
-			$title = apply_filters('the_title_rss', $title);
-			printf(__('Comment on %1$s by %2$s'), $title, get_comment_author_rss());
-		} else {	
-			printf(__('by: %s'), get_comment_author_rss());			
-		} ?></title>
-		<link><?php comment_link() ?></link>
-		<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_comment_time('Y-m-d H:i:s', true), false); ?></pubDate>
-		<guid><?php comment_link() ?></guid>
-			<?php 
-			if (!empty($comment->post_password) && $_COOKIE['wp-postpass'] != $comment->post_password) {
-			?>
-		<description><?php _e('Protected Comments: Please enter your password to view comments.'); ?></description>
-		<content:encoded><![CDATA[<?php echo get_the_password_form() ?>]]></content:encoded>
-			<?php
-			} else {
-			?>
-		<description><?php comment_text_rss() ?></description>
-		<content:encoded><![CDATA[<?php comment_text() ?>]]></content:encoded>
-			<?php 
-			} // close check for password 
-			?>
-	</item>
-<?php 
-			}
-		}
-	}
-endwhile; endif;
-?>
-</channel>
-</rss>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-config.php 2.2.2/wp-config.php
--- 2.0.5/wp-config.php	2006-10-31 09:07:27.000000000 -0600
+++ 2.2.2/wp-config.php	2007-08-13 07:47:42.000000000 -0500
@@ -4,17 +4,19 @@
 define('DB_USER', '[% mysql_user %]');     // Your MySQL username
 define('DB_PASSWORD', '[% mysql_pass %]'); // ...and password
 define('DB_HOST', '[% mysql.wp.sqlhost %]');     // 99% chance you won't need to change this value
+define('DB_CHARSET', 'utf8');
+define('DB_COLLATE', '');
 
-// Change the prefix if you want to have multiple blogs in a single database.
-$table_prefix  = '[% table_prefix %]_';   // example: 'wp_' or 'b2' or 'mylogin_'
+// You can have multiple installations in one database if you give each a unique prefix
+$table_prefix  = '[% table_prefix %]_';   // Only numbers, letters, and underscores please!
 
 // Change this to localize WordPress.  A corresponding MO file for the
-// chosen language must be installed to wp-includes/languages.
-// For example, install de.mo to wp-includes/languages and set WPLANG to 'de'
+// chosen language must be installed to wp-content/languages.
+// For example, install de.mo to wp-content/languages and set WPLANG to 'de'
 // to enable German language support.
 define ('WPLANG', '');
 
-/* Stop editing */
+/* That's all, stop editing! Happy blogging. */
 
 define('ABSPATH', dirname(__FILE__).'/');
 require_once(ABSPATH.'wp-settings.php');
Binary files 2.0.5/wp-content/.DS_Store and 2.2.2/wp-content/.DS_Store differ
diff -ruN 2.0.5/wp-content/index.php 2.2.2/wp-content/index.php
--- 2.0.5/wp-content/index.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/index.php	2007-05-04 16:48:43.000000000 -0500
@@ -1,3 +1,3 @@
-<?php
-// Silence is golden.
+<?php
+// Silence is golden.
 ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-content/plugins/akismet/akismet.php 2.2.2/wp-content/plugins/akismet/akismet.php
--- 2.0.5/wp-content/plugins/akismet/akismet.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/plugins/akismet/akismet.php	2007-06-18 13:27:32.000000000 -0500
@@ -2,76 +2,148 @@
 /*
 Plugin Name: Akismet
 Plugin URI: http://akismet.com/
-Description: Akismet checks your comments against the Akismet web serivce to see if they look like spam or not. You need a <a href="http://wordpress.com/api-keys/">WordPress.com API key</a> to use this service. You can review the spam it catches under "Manage" and it automatically deletes old spam after 15 days. To show off your Akismet stats just put <code>&lt;?php akismet_counter(); ?></code> in your template.
-Version: 1.2.1
+Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need a <a href="http://wordpress.com/api-keys/">WordPress.com API key</a> to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <code>&lt;?php akismet_counter(); ?></code> in your template.
+Version: 2.0.2
+Author: Matt Mullenweg
 Author URI: http://photomatt.net/
 */
 
-add_action('admin_menu', 'ksd_config_page');
+// If you hardcode a WP.com API key here, all key config screens will be hidden
+$wpcom_api_key = '';
 
-if ( ! function_exists('wp_nonce_field') ) {
-	function akismet_nonce_field($action = -1) {
-		return;	
-	}
+function akismet_init() {
+	global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
+
+	if ( $wpcom_api_key )
+		$akismet_api_host = $wpcom_api_key . '.rest.akismet.com';
+	else
+		$akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
+
+	$akismet_api_port = 80;
+	add_action('admin_menu', 'akismet_config_page');
+}
+add_action('init', 'akismet_init');
+
+if ( !function_exists('wp_nonce_field') ) {
+	function akismet_nonce_field($action = -1) { return; }
 	$akismet_nonce = -1;
 } else {
-	function akismet_nonce_field($action = -1) {
-		return wp_nonce_field($action);
-	}
+	function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
 	$akismet_nonce = 'akismet-update-key';
 }
 
-function ksd_config_page() {
-	global $wpdb;
+function akismet_config_page() {
 	if ( function_exists('add_submenu_page') )
 		add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
 }
 
 function akismet_conf() {
-	global $akismet_nonce;
+	global $akismet_nonce, $wpcom_api_key;
+
 	if ( isset($_POST['submit']) ) {
 		if ( function_exists('current_user_can') && !current_user_can('manage_options') )
 			die(__('Cheatin&#8217; uh?'));
 
-		check_admin_referer($akismet_nonce);
-		$key = preg_replace('/[^a-h0-9]/i', '', $_POST['key']);
-		if ( akismet_verify_key( $key ) )
+		check_admin_referer( $akismet_nonce );
+		$key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
+
+		if ( empty($key) ) {
+			$key_status = 'empty';
+			$ms[] = 'new_key_empty';
+			delete_option('wordpress_api_key');
+		} else {
+			$key_status = akismet_verify_key( $key );
+		}
+
+		if ( $key_status == 'valid' ) {
 			update_option('wordpress_api_key', $key);
+			$ms[] = 'new_key_valid';
+		} else if ( $key_status == 'invalid' ) {
+			$ms[] = 'new_key_invalid';
+		} else if ( $key_status == 'failed' ) {
+			$ms[] = 'new_key_failed';
+		}
+
+		if ( isset( $_POST['akismet_discard_month'] ) )
+			update_option( 'akismet_discard_month', 'true' );
 		else
-			$invalid_key = true;
+			update_option( 'akismet_discard_month', 'false' );
+	}
+
+	if ( $key_status != 'valid' ) {
+		$key = get_option('wordpress_api_key');
+		if ( empty( $key ) ) {
+			if ( $key_status != 'failed' ) {
+				if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
+					$ms[] = 'no_connection';
+				else
+					$ms[] = 'key_empty';
+			}
+			$key_status = 'empty';
+		} else {
+			$key_status = akismet_verify_key( $key );
+		}
+		if ( $key_status == 'valid' ) {
+			$ms[] = 'key_valid';
+		} else if ( $key_status == 'invalid' ) {
+			delete_option('wordpress_api_key');
+			$ms[] = 'key_empty';
+		} else if ( !empty($key) && $key_status == 'failed' ) {
+			$ms[] = 'key_failed';
+		}
 	}
-	if ( !akismet_verify_key( get_option('wordpress_api_key') ) )
-		$invalid_key = true;
-?>
 
+	$messages = array(
+		'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
+		'new_key_valid' => array('color' => '2d2', 'text' => __('Your key has been verified. Happy blogging!')),
+		'new_key_invalid' => array('color' => 'd22', 'text' => __('The key you entered is invalid. Please double-check it.')),
+		'new_key_failed' => array('color' => 'd22', 'text' => __('The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration.')),
+		'no_connection' => array('color' => 'd22', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
+		'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (<a href="%s" style="color:#fff">Get your key.</a>)'), 'http://wordpress.com/profile/')),
+		'key_valid' => array('color' => '2d2', 'text' => __('This key is valid.')),
+		'key_failed' => array('color' => 'aa0', 'text' => __('The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration.')));
+?>
+<?php if ( !empty($_POST ) ) : ?>
+<div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
+<?php endif; ?>
 <div class="wrap">
 <h2><?php _e('Akismet Configuration'); ?></h2>
+<div class="narrow">
+<form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
+<?php if ( !$wpcom_api_key ) { ?>
 	<p><?php printf(__('For many people, <a href="%1$s">Akismet</a> will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have a WordPress.com account yet, you can get one at <a href="%2$s">WordPress.com</a>.'), 'http://akismet.com/', 'http://wordpress.com/api-keys/'); ?></p>
 
-<form action="" method="post" id="akismet-conf" style="margin: auto; width: 25em; ">
 <?php akismet_nonce_field($akismet_nonce) ?>
 <h3><label for="key"><?php _e('WordPress.com API Key'); ?></label></h3>
+<?php foreach ( $ms as $m ) : ?>
+	<p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
+<?php endforeach; ?>
+<p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://faq.wordpress.com/2005/10/19/api-key/">What is this?</a>'); ?>)</p>
 <?php if ( $invalid_key ) { ?>
-	<p style="padding: .5em; background-color: #f33; color: #fff; font-weight: bold;"><?php _e('Your key appears invalid. Double-check it.'); ?></p>
+<h3><?php _e('Why might my key be invalid?'); ?></h3>
+<p><?php _e('This can mean one of two things, either you copied the key wrong or that the plugin is unable to reach the Akismet servers, which is most often caused by an issue with your web host around firewalls or similar.'); ?></p>
 <?php } ?>
-<p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://faq.wordpress.com/2005/10/19/api-key/">What is this?</a>'); ?>)</p>
-	<p class="submit"><input type="submit" name="submit" value="<?php _e('Update API Key &raquo;'); ?>" /></p>
+<?php } ?>
+<p><label><input name="akismet_discard_month" id="akismet_discard_month" value="true" type="checkbox" <?php if ( get_option('akismet_discard_month') == 'true' ) echo ' checked="checked" '; ?> /> <?php _e('Automatically discard spam comments on posts older than a month.'); ?></label></p>
+	<p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
 </form>
 </div>
+</div>
 <?php
 }
 
 function akismet_verify_key( $key ) {
-	global $auto_comment_approved, $ksd_api_host, $ksd_api_port;
+	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
 	$blog = urlencode( get_option('home') );
-	$response = ksd_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $ksd_api_port);
-	if ( 'valid' == $response[1] )
-		return true;
-	else
-		return false;
+	if ( $wpcom_api_key )
+		$key = $wpcom_api_key;
+	$response = akismet_http_post("key=$key&blog=$blog", 'rest.akismet.com', '/1.1/verify-key', $akismet_api_port);
+	if ( !is_array($response) || !isset($response[1]) || $response[1] != 'valid' && $response[1] != 'invalid' )
+		return 'failed';
+	return $response[1];
 }
 
-if ( !get_option('wordpress_api_key') && !isset($_POST['submit']) ) {
+if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
 	function akismet_warning() {
 		echo "
 		<div id='akismet-warning' class='updated fade-ff0000'><p><strong>".__('Akismet is not active.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your WordPress.com API key</a> for it to work.'), "plugins.php?page=akismet-key-config")."</p></div>
@@ -85,19 +157,15 @@
 	return;
 }
 
-$ksd_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
-$ksd_api_port = 80;
-$ksd_user_agent = "WordPress/$wp_version | Akismet/1.2.1";
-
-// Returns array with headers in $response[0] and entity in $response[1]
-function ksd_http_post($request, $host, $path, $port = 80) {
-	global $ksd_user_agent;
+// Returns array with headers in $response[0] and body in $response[1]
+function akismet_http_post($request, $host, $path, $port = 80) {
+	global $wp_version;
 
 	$http_request  = "POST $path HTTP/1.0\r\n";
 	$http_request .= "Host: $host\r\n";
 	$http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n";
 	$http_request .= "Content-Length: " . strlen($request) . "\r\n";
-	$http_request .= "User-Agent: $ksd_user_agent\r\n";
+	$http_request .= "User-Agent: WordPress/$wp_version | Akismet/2.0\r\n";
 	$http_request .= "\r\n";
 	$http_request .= $request;
 
@@ -113,8 +181,9 @@
 	return $response;
 }
 
-function ksd_auto_check_comment( $comment ) {
-	global $auto_comment_approved, $ksd_api_host, $ksd_api_port;
+function akismet_auto_check_comment( $comment ) {
+	global $akismet_api_host, $akismet_api_port;
+
 	$comment['user_ip']    = preg_replace( '/[^0-9., ]/', '', $_SERVER['REMOTE_ADDR'] );
 	$comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
 	$comment['referrer']   = $_SERVER['HTTP_REFERER'];
@@ -130,10 +199,18 @@
 	foreach ( $comment as $key => $data )
 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
 
-	$response = ksd_http_post($query_string, $ksd_api_host, '/1.1/comment-check', $ksd_api_port);
+	$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
 	if ( 'true' == $response[1] ) {
-		$auto_comment_approved = 'spam';
+		add_filter('pre_comment_approved', create_function('$a', 'return \'spam\';'));
 		update_option( 'akismet_spam_count', get_option('akismet_spam_count') + 1 );
+
+		$post = get_post( $comment['comment_post_ID'] );
+		$last_updated = strtotime( $post->post_modified_gmt );
+		$diff = time() - $last_updated;
+		$diff = $diff / 86400;
+
+		if ( $post->post_type == 'post' && $diff > 30 && get_option( 'akismet_discard_month' ) == 'true' )
+			die;
 	}
 	akismet_delete_old();
 	return $comment;
@@ -143,20 +220,13 @@
 	global $wpdb;
 	$now_gmt = current_time('mysql', 1);
 	$wpdb->query("DELETE FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
-	$n = mt_rand(1, 5);
-	if ( $n % 5 )
+	$n = mt_rand(1, 5000);
+	if ( $n == 11 ) // lucky number
 		$wpdb->query("OPTIMIZE TABLE $wpdb->comments");
 }
 
-function ksd_auto_approved( $approved ) {
-	global $auto_comment_approved;
-	if ( 'spam' == $auto_comment_approved )
-		$approved = $auto_comment_approved;
-	return $approved;
-}
-
-function ksd_submit_nonspam_comment ( $comment_id ) {
-	global $wpdb, $ksd_api_host, $ksd_api_port;
+function akismet_submit_nonspam_comment ( $comment_id ) {
+	global $wpdb, $akismet_api_host, $akismet_api_port;
 
 	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
 	if ( !$comment ) // it was deleted
@@ -165,11 +235,11 @@
 	$query_string = '';
 	foreach ( $comment as $key => $data )
 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
-	$response = ksd_http_post($query_string, $ksd_api_host, "/1.1/submit-ham", $ksd_api_port);
+	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
 }
 
-function ksd_submit_spam_comment ( $comment_id ) {
-	global $wpdb, $ksd_api_host, $ksd_api_port;
+function akismet_submit_spam_comment ( $comment_id ) {
+	global $wpdb, $akismet_api_host, $akismet_api_port;
 
 	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
 	if ( !$comment ) // it was deleted
@@ -181,32 +251,37 @@
 	foreach ( $comment as $key => $data )
 		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
 
-	$response = ksd_http_post($query_string, $ksd_api_host, "/1.1/submit-spam", $ksd_api_port);
+	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
 }
 
-add_action('wp_set_comment_status', 'ksd_submit_spam_comment');
-add_action('edit_comment', 'ksd_submit_spam_comment');
-add_action('preprocess_comment', 'ksd_auto_check_comment', 1);
-add_filter('pre_comment_approved', 'ksd_auto_approved');
-
+add_action('wp_set_comment_status', 'akismet_submit_spam_comment');
+add_action('edit_comment', 'akismet_submit_spam_comment');
+add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
 
-function ksd_spam_count() {
+function akismet_spam_count() {
 	global $wpdb, $comments;
-	$count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
+	$count = wp_cache_get( 'akismet_spam_count', 'widget' );
+	if ( false === $count ) {
+		$count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
+		wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
+	}
 	return $count;
 }
 
-function ksd_manage_page() {
-	global $wpdb;
-	$count = sprintf(__('Akismet Spam (%s)'), ksd_spam_count());
-	if ( function_exists('add_management_page') )
-		add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'ksd_caught');
+function akismet_manage_page() {
+	global $wpdb, $submenu;
+	$count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count());
+	if ( isset( $submenu['edit-comments.php'] ) )
+		add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' );
+	elseif ( function_exists('add_management_page') )
+		add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught');
 }
 
-function ksd_caught() {
-	global $wpdb, $comment;
-	
+function akismet_caught() {
+	global $wpdb, $comment, $akismet_caught, $akismet_nonce;
+	akismet_recheck_queue();
 	if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) {
+		check_admin_referer( $akismet_nonce );
 		if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
 			die(__('You do not have sufficient permission to moderate comments.'));
 		
@@ -217,25 +292,38 @@
 				wp_set_comment_status($comment, 'approve');
 			else
 				$wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'");
-			ksd_submit_nonspam_comment($comment);
+			akismet_submit_nonspam_comment($comment);
 			++$i;
 		endforeach;
-		echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
+		$to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] );
+		wp_redirect( $to );
+		exit;
 	}
 	if ('delete' == $_POST['action']) {
+		check_admin_referer( $akismet_nonce );
 		if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
 			die(__('You do not have sufficient permission to moderate comments.'));
 
 		$delete_time = addslashes( $_POST['display_time'] );
 		$nuked = $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" );
-		if (isset($nuked)) {
-			echo '<div class="updated"><p>';
-			if ($nuked) {
-				_e('All spam deleted.');
-			}
-			echo "</p></div>";
-		}
+		wp_cache_delete( 'akismet_spam_count', 'widget' );
+		$to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] );
+		wp_redirect( $to );
+		exit;
 	}
+
+if ( isset( $_GET['recovered'] ) ) {
+	$i = (int) $_GET['recovered'];
+	echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
+}
+
+if (isset( $_GET['deleted'] ) )
+	echo '<div class="updated"><p>' . __('All spam deleted.') . '</p></div>';
+
+if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) )
+	$link = 'edit-comments.php';
+else
+	$link = 'edit.php';
 ?>
 <div class="wrap">
 <h2><?php _e('Caught Spam') ?></h2>
@@ -246,31 +334,55 @@
 <p><?php printf(__('Akismet has caught <strong>%1$s spam</strong> for you since you first installed it.'), number_format($count) ); ?></p>
 <?php
 }
-$spam_count = ksd_spam_count();
+$spam_count = akismet_spam_count();
 if (0 == $spam_count) {
 	echo '<p>'.__('You have no spam currently in the queue. Must be your lucky day. :)').'</p>';
 	echo '</div>';
 } else {
 	echo '<p>'.__('You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don&#8217;t sweat it.').'</p>';
 ?>
-<form method="post" action="">
+<?php if ( !isset( $_POST['s'] ) ) { ?>
+<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
+<?php akismet_nonce_field($akismet_nonce) ?>
 <input type="hidden" name="action" value="delete" />
 <?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" value="<?php _e('Delete all'); ?>" />
 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" />
 </form>
+<?php } ?>
 </div>
 <div class="wrap">
+<?php if ( isset( $_POST['s'] ) ) { ?>
+<h2><?php _e('Search'); ?></h2>
+<?php } else { ?>
 <h2><?php _e('Latest Spam'); ?></h2>
 <?php echo '<p>'.__('These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as "not spam" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you.').'</p>'; ?>
+<?php } ?>
 <?php
-if ( isset( $_GET['apage'] ) )
-	$page = (int) $_GET['apage'];
-else
-	$page = 1;
-$start = ( $page - 1 ) * 50;
-$end = $start + 50;
-$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
-$total = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'" );
+if ( isset( $_POST['s'] ) ) {
+	$s = $wpdb->escape($_POST['s']);
+	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments  WHERE
+		(comment_author LIKE '%$s%' OR
+		comment_author_email LIKE '%$s%' OR
+		comment_author_url LIKE ('%$s%') OR
+		comment_author_IP LIKE ('%$s%') OR
+		comment_content LIKE ('%$s%') ) AND
+		comment_approved = 'spam'
+		ORDER BY comment_date DESC");
+} else {
+	if ( isset( $_GET['apage'] ) )
+		$page = (int) $_GET['apage'];
+	else
+		$page = 1;
+
+	if ( $page < 2 )
+		$page = 1;
+
+	$start = ( $page - 1 ) * 50;
+	$end = $start + 50;
+
+	$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
+	$total = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'" );
+}
 
 if ($comments) {
 ?>
@@ -280,17 +392,17 @@
 $r = '';
 if ( 1 < $page ) {
 	$args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
-	$r .=  '<a class="prev" href="' . add_query_arg( $args ) . '">&laquo; '. __('Previous Page') .'</a>' . "\n";
+	$r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">&laquo; '. __('Previous Page') .'</a>' . "\n";
 }
 if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
 	for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
 		if ( $page == $page_num ) :
-			$r .=  "<span>$page_num</span>\n";
+			$r .=  "<strong>$page_num</strong>\n";
 		else :
 			$p = false;
 			if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
 				$args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
-				$r .= '<a class="page-numbers" href="' . add_query_arg($args) . '">' . ( $page_num ) . "</a>\n";
+				$r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
 				$in = true;
 			elseif ( $in == true ) :
 				$r .= "...\n";
@@ -301,14 +413,18 @@
 }
 if ( ( $page ) * 50 < $total || -1 == $total ) {
 	$args['apage'] = $page + 1;
-	$r .=  '<a class="next" href="' . add_query_arg($args) . '">'. __('Next Page') .' &raquo;</a>' . "\n";
+	$r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page') .' &raquo;</a>' . "\n";
 }
 echo "<p>$r</p>";
 ?>
 
 <?php } ?>
-
-<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
+<form method="post" action="<?php echo attribute_escape("$link?page=akismet-admin"); ?>" id="akismetsearch">
+<p>  <input type="text" name="s" value="<?php if (isset($_POST['s'])) echo attribute_escape($_POST['s']); ?>" size="17" /> 
+  <input type="submit" name="submit" value="<?php echo attribute_escape(__('Search')) ?>"  />  </p>
+</form>
+<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
+<?php akismet_nonce_field($akismet_nonce) ?>
 <input type="hidden" name="action" value="recover" />
 <ul id="spam-list" class="commentlist" style="list-style: none; margin: 0; padding: 0;">
 <?php
@@ -340,25 +456,64 @@
 
 <?php
 }
-}
 ?>
 </ul>
+<?php if ( $total > 50 ) {
+$total_pages = ceil( $total / 50 );
+$r = '';
+if ( 1 < $page ) {
+	$args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
+	$r .=  '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">&laquo; '. __('Previous Page') .'</a>' . "\n";
+}
+if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
+	for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
+		if ( $page == $page_num ) :
+			$r .=  "<strong>$page_num</strong>\n";
+		else :
+			$p = false;
+			if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
+				$args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
+				$r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
+				$in = true;
+			elseif ( $in == true ) :
+				$r .= "...\n";
+				$in = false;
+			endif;
+		endif;
+	endfor;
+}
+if ( ( $page ) * 50 < $total || -1 == $total ) {
+	$args['apage'] = $page + 1;
+	$r .=  '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page') .' &raquo;</a>' . "\n";
+}
+echo "<p>$r</p>";
+}
+?>
 <p class="submit"> 
-<input type="submit" name="submit" value="<?php _e('De-spam marked comments &raquo;'); ?>" />
+<input type="submit" name="submit" value="<?php echo attribute_escape(__('De-spam marked comments &raquo;')); ?>" />
 </p>
 <p><?php _e('Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better.'); ?></p>
 </form>
-<form method="post" action="">
+<?php
+} else {
+?>
+<p><?php _e('No results found.'); ?></p>
+<?php } ?>
+
+<?php if ( !isset( $_POST['s'] ) ) { ?>
+<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
+<?php akismet_nonce_field($akismet_nonce) ?>
 <p><input type="hidden" name="action" value="delete" />
-<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" value="<?php _e('Delete all'); ?>" />
+<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" value="<?php echo attribute_escape(__('Delete all')); ?>" />
 <input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" /></p>
 </form>
+<?php } ?>
 </div>
 <?php
 	}
 }
 
-add_action('admin_menu', 'ksd_manage_page');
+add_action('admin_menu', 'akismet_manage_page');
 
 function akismet_stats() {
 	$count = get_option('akismet_spam_count');
@@ -366,11 +521,87 @@
 		return;
 	$path = plugin_basename(__FILE__);
 	echo '<h3>'.__('Spam').'</h3>';
-	echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', "edit.php?page=akismet-admin", number_format($count) ).'</p>';
+	global $submenu;
+	if ( isset( $submenu['edit-comments.php'] ) )
+		$link = 'edit-comments.php';
+	else
+		$link = 'edit.php';
+	echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', clean_url("$link?page=akismet-admin"), number_format($count) ).'</p>';
 }
 
 add_action('activity_box_end', 'akismet_stats');
 
+
+if ( 'moderation.php' == $pagenow ) {
+	function akismet_recheck_button( $page ) {
+		global $submenu;
+		if ( isset( $submenu['edit-comments.php'] ) )
+			$link = 'edit-comments.php';
+		else
+			$link = 'edit.php';
+		$button = "<a href='$link?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true' style='display: block; width: 100px; position: absolute; right: 7%; padding: 5px; font-size: 14px; text-decoration: underline; background: #fff; border: 1px solid #ccc;'>" . __('Recheck Queue for Spam') . "</a>";
+		$page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
+		return $page;
+	}
+
+	if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
+		ob_start( 'akismet_recheck_button' );
+}
+
+function akismet_recheck_queue() {
+	global $wpdb, $akismet_api_host, $akismet_api_port;
+
+	if ( !isset( $_GET['recheckqueue'] ) )
+		return;
+
+	$moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
+	foreach ( $moderation as $c ) {
+		$c['user_ip']    = $c['comment_author_IP'];
+		$c['user_agent'] = $c['comment_agent'];
+		$c['referrer']   = '';
+		$c['blog']       = get_option('home');
+		$id = $c['comment_ID'];
+		
+		$query_string = '';
+		foreach ( $c as $key => $data )
+		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
+		
+		$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
+		if ( 'true' == $response[1] ) {
+			$wpdb->query( "UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id" );
+		}
+	}
+	wp_redirect( $_SERVER['HTTP_REFERER'] );
+	exit;
+}
+
+function akismet_check_db_comment( $id ) {
+	global $wpdb, $akismet_api_host, $akismet_api_port;
+
+	$id = (int) $id;
+	$c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
+	if ( !$c )
+		return;
+
+	$c['user_ip']    = $c['comment_author_IP'];
+	$c['user_agent'] = $c['comment_agent'];
+	$c['referrer']   = '';
+	$c['blog']       = get_option('home');
+	$id = $c['comment_ID'];
+	
+	$query_string = '';
+	foreach ( $c as $key => $data )
+	$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
+	
+	$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
+	return $response[1];
+}
+
+// This option causes tons of FPs, was removed in 2.1
+function akismet_kill_proxy_check( $option ) { return 0; }
+add_filter('option_open_proxy_check', 'akismet_kill_proxy_check');
+
+// Widget stuff
 function widget_akismet_register() {
 	if ( function_exists('register_sidebar_widget') ) :
 	function widget_akismet($args) {
@@ -381,70 +612,23 @@
 		?>
 			<?php echo $before_widget; ?>
 				<?php echo $before_title . $options['title'] . $after_title; ?>
-				<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><div id="akismet1"><span id="akismetcount"><?php echo $count; ?></span> <span id="akismetsc"><?php _e('spam comments') ?></span></div> <div id="akismet2"><span id="akismetbb"><?php _e('blocked by') ?></span><br /><span id="akismeta">Akismet</span></div></a></div></div>
+				<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><?php printf( __( '%1$s %2$sspam comments%3$s %4$sblocked by%5$s<br />%6$sAkismet%7$s' ), '<div id="akismet1"><span id="akismetcount">' . $count . '</span>', '<span id="akismetsc">', '</span></div>', '<div id="akismet2"><span id="akismetbb">', '</span>', '<span id="akismeta">', '</span></div>' ); ?></a></div></div>
 			<?php echo $after_widget; ?>
 	<?php
 	}
 	
 	function widget_akismet_style() {
 		?>
-		<style type="text/css">
-#aka, #aka:link, #aka:hover, #aka:visited, #aka:active {
-	color: #fff;
-	text-decoration: none;
-}
-
-#aka:hover{
-	border: none;
-	text-decoration: none;
-}
-
-#aka:hover #akismet1{
-	display: none;
-}
-
-#aka:hover #akismet2{
-	display: block;
-}
-
-#akismet1{
-	display: block;
-}
-
-#akismet2{
-	display: none;
-	padding-top: 2px;
-}
-
-#akismeta{
-	font-size: 16px;
-	font-weight: bold;
-	line-height: 18px;
-	text-decoration: none;
-}
-
-#akismetcount{
-	display: block;
-	font: 15px Verdana,Arial,Sans-Serif;
-	font-weight: bold;
-	text-decoration: none;
-}
-
-#akismetwrap #akismetstats{
-	background: url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;
-	border: none;
-	color: #fff;
-	font: 11px 'Trebuchet MS','Myriad Pro',sans-serif;
-	height: 40px;
-	line-height: 100%;
-	overflow: hidden;
-	padding: 8px 0 0;
-	text-align: center;
-	width: 120px;
-}
-
-
-		</style>
+<style type="text/css">
+#aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
+#aka:hover{border:none;text-decoration:none}
+#aka:hover #akismet1{display:none}
+#aka:hover #akismet2,#akismet1{display:block}
+#akismet2{display:none;padding-top:2px}
+#akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
+#akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
+#akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
+</style>
 		<?php
 	}
 
@@ -471,6 +655,7 @@
 		add_action('wp_head', 'widget_akismet_style');
 	endif;
 }
+
 add_action('init', 'widget_akismet_register');
 
 // Counter for non-widget users
@@ -493,43 +678,4 @@
 <?php
 }
 
-if ( 'moderation.php' == $pagenow ) {
-	function akismet_recheck_button( $page ) {
-		$button = "<a href='edit.php?page=akismet-admin&amp;recheckqueue=true' style='display: block; width: 100px; position: absolute; right: 7%; padding: 5px; font-size: 14px; text-decoration: underline; background: #fff; border: 1px solid #ccc;'>Recheck Queue for Spam</a>";
-		$page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
-		return $page;
-	}
-
-	if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
-		ob_start( 'akismet_recheck_button' );
-}
-
-function akismet_recheck_queue() {
-	global $wpdb, $ksd_api_host, $ksd_api_port;
-
-	if ( !isset( $_GET['recheckqueue'] ) )
-		return;
-
-	$moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
-	foreach ( $moderation as $c ) {
-		$c['user_ip']    = $c['comment_author_IP'];
-		$c['user_agent'] = $c['comment_agent'];
-		$c['referrer']   = '';
-		$c['blog']       = get_option('home');
-		$id = $c['comment_ID'];
-		
-		$query_string = '';
-		foreach ( $c as $key => $data )
-		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
-		
-		$response = ksd_http_post($query_string, $ksd_api_host, '/1.1/comment-check', $ksd_api_port);
-		if ( 'true' == $response[1] ) {
-			$wpdb->query( "UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id" );
-		}
-	}
-	wp_redirect( $_SERVER['HTTP_REFERER'] );
-	exit;
-}
-add_action( 'load-manage_page_akismet-admin', 'akismet_recheck_queue' );
-
-?>
\ No newline at end of file
+?>
diff -ruN 2.0.5/wp-content/plugins/hello.php 2.2.2/wp-content/plugins/hello.php
--- 2.0.5/wp-content/plugins/hello.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/plugins/hello.php	2006-10-25 16:39:32.000000000 -0500
@@ -41,7 +41,7 @@
 // Here we split it into lines
 $lyrics = explode("\n", $lyrics);
 // And then randomly choose a line
-$chosen = wptexturize( $lyrics[ mt_rand(0, count($lyrics) ) ] );
+$chosen = wptexturize( $lyrics[ mt_rand(0, count($lyrics) - 1) ] );
 
 // This just echoes the chosen line, we'll position it later
 function hello_dolly() {
diff -ruN 2.0.5/wp-content/plugins/wp-db-backup.php 2.2.2/wp-content/plugins/wp-db-backup.php
--- 2.0.5/wp-content/plugins/wp-db-backup.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/plugins/wp-db-backup.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,910 +0,0 @@
-<?php
-/*
-Plugin Name: WordPress Database Backup
-Plugin URI: http://www.skippy.net/blog/plugins/
-Description: On-demand backup of your WordPress database.
-Author: Scott Merrill
-Version: 1.8
-Author URI: http://www.skippy.net/
-
-Much of this was modified from Mark Ghosh's One Click Backup, which
-in turn was derived from phpMyAdmin.
-
-Many thanks to Owen (http://asymptomatic.net/wp/) for his patch
-   http://dev.wp-plugins.org/ticket/219
-*/
-
-// CHANGE THIS IF YOU WANT TO USE A 
-// DIFFERENT BACKUP LOCATION
-
-$rand = substr( md5( md5( DB_PASSWORD ) ), -5 );
-
-define('WP_BACKUP_DIR', 'wp-content/backup-' . $rand);
-
-define('ROWS_PER_SEGMENT', 100);
-
-class wpdbBackup {
-
-	var $backup_complete = false;
-	var $backup_file = '';
-	var $backup_dir = WP_BACKUP_DIR;
-	var $backup_errors = array();
-	var $basename;
-
-	function gzip() {
-		return function_exists('gzopen');
-	}
-
-	function wpdbBackup() {
-		add_action('wp_cron_daily', array(&$this, 'wp_cron_daily'));
-
-		$this->backup_dir = trailingslashit($this->backup_dir);
-		$this->basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__);
-	
-		if (isset($_POST['do_backup'])) {
-			if ( !current_user_can('import') ) die(__('You are not allowed to perform backups.'));
-			switch($_POST['do_backup']) {
-			case 'backup':
-				$this->perform_backup();
-				break;
-			case 'fragments':
-				add_action('admin_menu', array(&$this, 'fragment_menu'));
-				break;				
-			}
-		} elseif (isset($_GET['fragment'] )) {
-			if ( !current_user_can('import') ) die(__('You are not allowed to perform backups.'));
-			add_action('init', array(&$this, 'init'));
-		} elseif (isset($_GET['backup'] )) {
-			if ( !current_user_can('import') ) die(__('You are not allowed to perform backups.'));
-			add_action('init', array(&$this, 'init'));
-		} else {
-			add_action('admin_menu', array(&$this, 'admin_menu'));
-		}
-	}
-	
-	function init() {
-		if ( !current_user_can('import') ) die(__('You are not allowed to perform backups.'));
-
-		if (isset($_GET['backup'])) {
-			$via = isset($_GET['via']) ? $_GET['via'] : 'http';
-			
-			$this->backup_file = $_GET['backup'];
-			$this->validate_file($this->backup_file);
-
-			switch($via) {
-			case 'smtp':
-			case 'email':
-				$this->deliver_backup ($this->backup_file, 'smtp', $_GET['recipient']);
-				echo '
-					<!-- ' . $via . ' -->
-					<script type="text/javascript"><!--\\
-				';
-				if($this->backup_errors) {
-					foreach($this->backup_errors as $error) {
-						echo "window.parent.addError('$error');\n";
-					}
-				}
-				echo '
-					alert("' . __('Backup Complete!') . '");
-					</script>
-				';
-				break;
-			default:
-				$this->deliver_backup ($this->backup_file, $via);
-			}
-			die();
-		}
-		if (isset($_GET['fragment'] )) {
-			list($table, $segment, $filename) = explode(':', $_GET['fragment']);
-			$this->validate_file($filename);
-			$this->backup_fragment($table, $segment, $filename);
-		}
-
-		die();
-	}
-	
-	function build_backup_script() {
-		global $table_prefix, $wpdb;
-	
-		$datum = date("Ymd_B");
-		$backup_filename = DB_NAME . "_$table_prefix$datum.sql";
-		if ($this->gzip()) $backup_filename .= '.gz';
-		
-		echo "<div class='wrap'>";
-		//echo "<pre>" . print_r($_POST, 1) . "</pre>";
-		echo '<h2>' . __('Backup') . '</h2>
-			<fieldset class="options"><legend>' . __('Progress') . '</legend>
-			<p><strong>' .
-				__('DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:').
-			'</strong></p>
-			<ol>
-				<li>'.__('Close this browser').'</li>
-				<li>'.__('Reload this page').'</li>
-				<li>'.__('Click the Stop or Back buttons in your browser').'</li>
-			</ol>
-			<p><strong>' . __('Progress:') . '</strong></p>
-			<div id="meterbox" style="height:11px;width:80%;padding:3px;border:1px solid #659fff;"><div id="meter" style="height:11px;background-color:#659fff;width:0%;text-align:center;font-size:6pt;">&nbsp;</div></div>
-			<div id="progress_message"></div>
-			<div id="errors"></div>
-			</fieldset>
-			<iframe id="backuploader" src="about:blank" style="border:0px solid white;height:1em;width:1em;"></iframe>
-			<script type="text/javascript"><!--//
-			function setMeter(pct) {
-				var meter = document.getElementById("meter");
-				meter.style.width = pct + "%";
-				meter.innerHTML = Math.floor(pct) + "%";
-			}
-			function setProgress(str) {
-				var progress = document.getElementById("progress_message");
-				progress.innerHTML = str;
-			}
-			function addError(str) {
-				var errors = document.getElementById("errors");
-				errors.innerHTML = errors.innerHTML + str + "<br />";
-			}
-
-			function backup(table, segment) {
-				var fram = document.getElementById("backuploader");				
-				fram.src = "' . $_SERVER['REQUEST_URI'] . '&fragment=" + table + ":" + segment + ":' . $backup_filename . '";
-			}
-			
-			var curStep = 0;
-			
-			function nextStep() {
-				backupStep(curStep);
-				curStep++;
-			}
-			
-			function finishBackup() {
-				var fram = document.getElementById("backuploader");				
-				setMeter(100);
-		';
-
-		$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__);
-		$download_uri = get_settings('siteurl') . "/wp-admin/edit.php?page={$this_basename}&backup={$backup_filename}";
-		switch($_POST['deliver']) {
-		case 'http':
-			echo '
-				setProgress("' . sprintf(__("Backup complete, preparing <a href=\\\"%s\\\">backup</a> for download..."), $download_uri) . '");
-				fram.src = "' . $download_uri . '";
-			';
-			break;
-		case 'smtp':
-			echo '
-				setProgress("' . sprintf(__("Backup complete, sending <a href=\\\"%s\\\">backup</a> via email..."), $download_uri) . '");
-				fram.src = "' . $download_uri . '&via=email&recipient=' . $_POST['backup_recipient'] . '";
-			';
-			break;
-		default:
-			echo '
-				setProgress("' . sprintf(__("Backup complete, download <a href=\\\"%s\\\">here</a>."), $download_uri) . '");
-			';
-		}
-		
-		echo '
-			}
-			
-			function backupStep(step) {
-				switch(step) {
-				case 0: backup("", 0); break;
-		';
-		
-		$also_backup = array();
-		if (isset($_POST['other_tables'])) {
-			$also_backup = $_POST['other_tables'];
-		} else {
-			$also_backup = array();
-		}
-		$core_tables = $_POST['core_tables'];
-		$tables = array_merge($core_tables, $also_backup);
-		$step_count = 1;
-		foreach ($tables as $table) {
-			$rec_count = $wpdb->get_var("SELECT count(*) FROM {$table}");
-			$rec_segments = ceil($rec_count / ROWS_PER_SEGMENT);
-			$table_count = 0;
-			do {
-				echo "case {$step_count}: backup(\"{$table}\", {$table_count}); break;\n";
-				$step_count++;
-				$table_count++;
-			} while($table_count < $rec_segments);
-			echo "case {$step_count}: backup(\"{$table}\", -1); break;\n";
-			$step_count++;
-		}
-		echo "case {$step_count}: finishBackup(); break;";
-		
-		echo '
-				}
-				if(step != 0) setMeter(100 * step / ' . $step_count . ');
-			}
-
-			nextStep();
-			//--></script>
-	</div>
-		';
-	}
-
-	function backup_fragment($table, $segment, $filename) {
-		global $table_prefix, $wpdb;
-			
-		echo "$table:$segment:$filename";
-		
-		if($table == '') {
-			$msg = __('Creating backup file...');
-		} else {
-			if($segment == -1) {
-				$msg = sprintf(__('Finished backing up table \\"%s\\".'), $table);
-			} else {
-				$msg = sprintf(__('Backing up table \\"%s\\"...'), $table);
-			}
-		}
-		
-		echo '<script type="text/javascript"><!--//
-		var msg = "' . $msg . '";
-		window.parent.setProgress(msg);
-		';
-			
-		if (is_writable(ABSPATH . $this->backup_dir)) {
-			$this->fp = $this->open(ABSPATH . $this->backup_dir . $filename, 'a');
-			if(!$this->fp) {
-				$this->backup_error(__('Could not open the backup file for writing!'));
-				$this->fatal_error = __('The backup file could not be saved.  Please check the permissions for writing to your backup directory and try again.');
-			}
-			else {
-				if($table == '') {		
-					//Begin new backup of MySql
-					$this->stow("# WordPress MySQL database backup\n");
-					$this->stow("#\n");
-					$this->stow("# Generated: " . date("l j. F Y H:i T") . "\n");
-					$this->stow("# Hostname: " . DB_HOST . "\n");
-					$this->stow("# Database: " . $this->backquote(DB_NAME) . "\n");
-					$this->stow("# --------------------------------------------------------\n");
-				} else {
-					if($segment == 0) {
-						// Increase script execution time-limit to 15 min for every table.
-						if ( !ini_get('safe_mode')) @set_time_limit(15*60);
-						//ini_set('memory_limit', '16M');
-						// Create the SQL statements
-						$this->stow("# --------------------------------------------------------\n");
-						$this->stow("# Table: " . $this->backquote($table) . "\n");
-						$this->stow("# --------------------------------------------------------\n");
-					}			
-					$this->backup_table($table, $segment);
-				}
-			}
-		} else {
-			$this->backup_error(__('The backup directory is not writeable!'));
-			$this->fatal_error = __('The backup directory is not writeable!  Please check the permissions for writing to your backup directory and try again.');
-		}
-
-		if($this->fp) $this->close($this->fp);
-		
-		if($this->backup_errors) {
-			foreach($this->backup_errors as $error) {
-				echo "window.parent.addError('$error');\n";
-			}
-		}
-		if($this->fatal_error) {
-			echo '
-				alert("' . addslashes($this->fatal_error) . '");
-				//--></script>
-			';
-		}
-		else {
-			echo '
-				window.parent.nextStep();
-				//--></script>
-			';
-		}
-		
-		die();
-	}
-
-	function perform_backup() {
-		// are we backing up any other tables?
-		$also_backup = array();
-		if (isset($_POST['other_tables'])) {
-			$also_backup = $_POST['other_tables'];
-		}
-		
-		$core_tables = $_POST['core_tables'];
-		$this->backup_file = $this->db_backup($core_tables, $also_backup);
-		if (FALSE !== $this->backup_file) {
-			if ('smtp' == $_POST['deliver']) {
-				$this->deliver_backup ($this->backup_file, $_POST['deliver'], $_POST['backup_recipient']);
-			} elseif ('http' == $_POST['deliver']) {
-				$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__);
-				header('Refresh: 3; ' . get_settings('siteurl') . "/wp-admin/edit.php?page={$this_basename}&backup={$this->backup_file}");
-			}
-			// we do this to say we're done.
-			$this->backup_complete = true;
-		}
-	}
-	
-	///////////////////////////////
-	function admin_menu() {
-		add_management_page(__('Backup'), __('Backup'), 'import', basename(__FILE__), array(&$this, 'backup_menu'));
-	}
-
-	function fragment_menu() {
-		add_management_page(__('Backup'), __('Backup'), 'import', basename(__FILE__), array(&$this, 'build_backup_script'));
-	}
-
-	/////////////////////////////////////////////////////////
-	function sql_addslashes($a_string = '', $is_like = FALSE)
-	{
-	        /*
-	                Better addslashes for SQL queries.
-	                Taken from phpMyAdmin.
-	        */
-	    if ($is_like) {
-	        $a_string = str_replace('\\', '\\\\\\\\', $a_string);
-	    } else {
-	        $a_string = str_replace('\\', '\\\\', $a_string);
-	    }
-	    $a_string = str_replace('\'', '\\\'', $a_string);
-
-	    return $a_string;
-	} // function sql_addslashes($a_string = '', $is_like = FALSE)
-
-	///////////////////////////////////////////////////////////
-	function backquote($a_name)
-	{
-	        /*
-	                Add backqouotes to tables and db-names in
-	                SQL queries. Taken from phpMyAdmin.
-	        */
-	    if (!empty($a_name) && $a_name != '*') {
-	        if (is_array($a_name)) {
-	             $result = array();
-	             reset($a_name);
-	             while(list($key, $val) = each($a_name)) {
-	                 $result[$key] = '`' . $val . '`';
-	             }
-	             return $result;
-	        } else {
-	            return '`' . $a_name . '`';
-	        }
-	    } else {
-	        return $a_name;
-	    }
-	} // function backquote($a_name, $do_it = TRUE)
-
-	/////////////
-	function open($filename = '', $mode = 'w') {
-		if ('' == $filename) return false;
-		if ($this->gzip()) {
-			$fp = @gzopen($filename, $mode);
-		} else {
-			$fp = @fopen($filename, $mode);
-		}
-		return $fp;
-	}
-
-	//////////////
-	function close($fp) {
-		if ($this->gzip()) {
-			gzclose($fp);
-		} else {
-			fclose($fp);
-		}
-	}
-	
-	//////////////
-	function stow($query_line) {
-		if ($this->gzip()) {
-			if(@gzwrite($this->fp, $query_line) === FALSE) {
-				backup_error(__('There was an error writing a line to the backup script:'));
-				backup_error('&nbsp;&nbsp;' . $query_line);
-			}
-		} else {
-			if(@fwrite($this->fp, $query_line) === FALSE) {
-				backup_error(__('There was an error writing a line to the backup script:'));
-				backup_error('&nbsp;&nbsp;' . $query_line);
-			}
-		}
-	}
-	
-	function backup_error($err) {
-		if(count($this->backup_errors) < 20) {
-			$this->backup_errors[] = $err;
-		} elseif(count($this->backup_errors) == 20) {
-			$this->backup_errors[] = __('Subsequent errors have been omitted from this log.');
-		}
-	}
-	
-	/////////////////////////////
-	function backup_table($table, $segment = 'none') {
-		global $wpdb;
-		
-		/*
-		Taken partially from phpMyAdmin and partially from
-		Alain Wolf, Zurich - Switzerland
-		Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
-		
-		Modified by Scott Merril (http://www.skippy.net/) 
-		to use the WordPress $wpdb object
-		*/
-
-		$table_structure = $wpdb->get_results("DESCRIBE $table");
-		if (! $table_structure) {
-			backup_errors(__('Error getting table details') . ": $table");
-			return FALSE;
-		}
-	
-		if(($segment == 'none') || ($segment == 0)) {
-			//
-			// Add SQL statement to drop existing table
-			$this->stow("\n\n");
-			$this->stow("#\n");
-			$this->stow("# Delete any existing table " . $this->backquote($table) . "\n");
-			$this->stow("#\n");
-			$this->stow("\n");
-			$this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n");
-			
-			// 
-			//Table structure
-			// Comment in SQL-file
-			$this->stow("\n\n");
-			$this->stow("#\n");
-			$this->stow("# Table structure of table " . $this->backquote($table) . "\n");
-			$this->stow("#\n");
-			$this->stow("\n");
-			
-			$create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N);
-			if (FALSE === $create_table) {
-				$this->backup_error(sprintf(__("Error with SHOW CREATE TABLE for %s."), $table));
-				$this->stow("#\n# Error with SHOW CREATE TABLE for $table!\n#\n");
-			}
-			$this->stow($create_table[0][1] . ' ;');
-			
-			if (FALSE === $table_structure) {
-				$this->backup_error(sprintf(__("Error getting table structure of %s"), $table));
-				$this->stow("#\n# Error getting table structure of $table!\n#\n");
-			}
-		
-			//
-			// Comment in SQL-file
-			$this->stow("\n\n");
-			$this->stow("#\n");
-			$this->stow('# Data contents of table ' . $this->backquote($table) . "\n");
-			$this->stow("#\n");
-		}
-		
-		if(($segment == 'none') || ($segment >= 0)) {
-			$ints = array();
-			foreach ($table_structure as $struct) {
-				if ( (0 === strpos($struct->Type, 'tinyint')) ||
-					(0 === strpos(strtolower($struct->Type), 'smallint')) ||
-					(0 === strpos(strtolower($struct->Type), 'mediumint')) ||
-					(0 === strpos(strtolower($struct->Type), 'int')) ||
-					(0 === strpos(strtolower($struct->Type), 'bigint')) ||
-					(0 === strpos(strtolower($struct->Type), 'timestamp')) ) {
-						$ints[strtolower($struct->Field)] = "1";
-				}
-			}
-			
-			
-			// Batch by $row_inc
-			
-			if($segment == 'none') {
-				$row_start = 0;
-				$row_inc = ROWS_PER_SEGMENT;
-			} else {
-				$row_start = $segment * ROWS_PER_SEGMENT;
-				$row_inc = ROWS_PER_SEGMENT;
-			}
-			
-			do {	
-				if ( !ini_get('safe_mode')) @set_time_limit(15*60);
-				$table_data = $wpdb->get_results("SELECT * FROM $table LIMIT {$row_start}, {$row_inc}", ARRAY_A);
-
-				/*
-				if (FALSE === $table_data) {
-					$wp_backup_error .= "Error getting table contents from $table\r\n";
-					fwrite($fp, "#\n# Error getting table contents fom $table!\n#\n");
-				}
-				*/
-					
-				$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';	
-				//    \x08\\x09, not required
-				$search = array("\x00", "\x0a", "\x0d", "\x1a");
-				$replace = array('\0', '\n', '\r', '\Z');
-				if($table_data) {
-					foreach ($table_data as $row) {
-						$values = array();
-						foreach ($row as $key => $value) {
-							if ($ints[strtolower($key)]) {
-								$values[] = $value;
-							} else {
-								$values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'";
-							}
-						}
-						$this->stow(" \n" . $entries . implode(', ', $values) . ') ;');
-					}
-					$row_start += $row_inc;
-				}
-			} while((count($table_data) > 0) and ($segment=='none'));
-		}
-		
-		
-		if(($segment == 'none') || ($segment < 0)) {
-			// Create footer/closing comment in SQL-file
-			$this->stow("\n");
-			$this->stow("#\n");
-			$this->stow("# End of data contents of table " . $this->backquote($table) . "\n");
-			$this->stow("# --------------------------------------------------------\n");
-			$this->stow("\n");
-		}
-		
-	} // end backup_table()
-	
-	function return_bytes($val) {
-	   $val = trim($val);
-	   $last = strtolower($val{strlen($val)-1});
-	   switch($last) {
-	       // The 'G' modifier is available since PHP 5.1.0
-	       case 'g':
-	           $val *= 1024;
-	       case 'm':
-	           $val *= 1024;
-	       case 'k':
-	           $val *= 1024;
-	   }
-	
-	   return $val;
-	}
-	
-	////////////////////////////
-	function db_backup($core_tables, $other_tables) {
-		global $table_prefix, $wpdb;
-		
-		$datum = date("Ymd_B");
-		$wp_backup_filename = DB_NAME . "_$table_prefix$datum.sql";
-			if ($this->gzip()) {
-				$wp_backup_filename .= '.gz';
-			}
-		
-		if (is_writable(ABSPATH . $this->backup_dir)) {
-			$this->fp = $this->open(ABSPATH . $this->backup_dir . $wp_backup_filename);
-			if(!$this->fp) {
-				$this->backup_error(__('Could not open the backup file for writing!'));
-				return false;
-			}
-		} else {
-			$this->backup_error(__('The backup directory is not writeable!'));
-			return false;
-		}
-		
-		//Begin new backup of MySql
-		$this->stow("# WordPress MySQL database backup\n");
-		$this->stow("#\n");
-		$this->stow("# Generated: " . date("l j. F Y H:i T") . "\n");
-		$this->stow("# Hostname: " . DB_HOST . "\n");
-		$this->stow("# Database: " . $this->backquote(DB_NAME) . "\n");
-		$this->stow("# --------------------------------------------------------\n");
-		
-			if ( (is_array($other_tables)) && (count($other_tables) > 0) )
-			$tables = array_merge($core_tables, $other_tables);
-		else
-			$tables = $core_tables;
-		
-		foreach ($tables as $table) {
-			// Increase script execution time-limit to 15 min for every table.
-			if ( !ini_get('safe_mode')) @set_time_limit(15*60);
-			// Create the SQL statements
-			$this->stow("# --------------------------------------------------------\n");
-			$this->stow("# Table: " . $this->backquote($table) . "\n");
-			$this->stow("# --------------------------------------------------------\n");
-			$this->backup_table($table);
-		}
-				
-		$this->close($this->fp);
-		
-		if (count($this->backup_errors)) {
-			return false;
-		} else {
-			return $wp_backup_filename;
-		}
-		
-	} //wp_db_backup
-	
-	///////////////////////////
-	function deliver_backup ($filename = '', $delivery = 'http', $recipient = '') {
-		if ('' == $filename) { return FALSE; }
-		
-		$diskfile = ABSPATH . $this->backup_dir . $filename;
-		if ('http' == $delivery) {
-			if (! file_exists($diskfile)) {
-				$msg = sprintf(__('File not found:%s'), "<br /><strong>$filename</strong><br />");
-				$this_basename = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', __FILE__);
-				$msg .= '<br /><a href="' . get_settings('siteurl') . "/wp-admin/edit.php?page={$this_basename}" . '">' . __('Return to Backup');
-			die($msg);
-			}
-			header('Content-Description: File Transfer');
-			header('Content-Type: application/octet-stream');
-			header('Content-Length: ' . filesize($diskfile));
-			header("Content-Disposition: attachment; filename=$filename");
-			readfile($diskfile);
-			unlink($diskfile);
-		} elseif ('smtp' == $delivery) {
-			if (! file_exists($diskfile)) return false;
-
-			if (! is_email ($recipient)) {
-				$recipient = get_settings('admin_email');
-			}
-			$randomish = md5(time());
-			$boundary = "==WPBACKUP-BY-SKIPPY-$randomish";
-			$fp = fopen($diskfile,"rb");
-			$file = fread($fp,filesize($diskfile)); 
-			$this->close($fp);
-			$data = chunk_split(base64_encode($file));
-			$headers = "MIME-Version: 1.0\n";
-			$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
-			$headers .= 'From: ' . get_settings('admin_email') . "\n";
-		
-			$message = sprintf(__("Attached to this email is\n   %1s\n   Size:%2s kilobytes\n"), $filename, round(filesize($diskfile)/1024));
-			// Add a multipart boundary above the plain message
-			$message = "This is a multi-part message in MIME format.\n\n" .
-		        	"--{$boundary}\n" .
-				"Content-Type: text/plain; charset=\"utf-8\"\n" .
-				"Content-Transfer-Encoding: 7bit\n\n" .
-				$message . "\n\n";
-			
-			// Add file attachment to the message
-			$message .= "--{$boundary}\n" .
-				"Content-Type: application/octet-stream;\n" .
-				" name=\"{$filename}\"\n" .
-				"Content-Disposition: attachment;\n" .
-				" filename=\"{$filename}\"\n" .
-				"Content-Transfer-Encoding: base64\n\n" .
-				$data . "\n\n" .
-				"--{$boundary}--\n";
-			
-			if (function_exists('wp_mail')) {
-				wp_mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup'), $message, $headers);
-			} else {
-				mail ($recipient, get_bloginfo('name') . ' ' . __('Database Backup'), $message, $headers);
-			}
-			
-			unlink($diskfile);
-		}
-		return;
-	}
-	
-	////////////////////////////
-	function backup_menu() {
-		global $table_prefix, $wpdb;
-		$feedback = '';
-		$WHOOPS = FALSE;
-		
-		// did we just do a backup?  If so, let's report the status
-		if ( $this->backup_complete ) {
-			$feedback = '<div class="updated"><p>' . __('Backup Successful') . '!';
-			$file = $this->backup_file;
-			switch($_POST['deliver']) {
-			case 'http':
-				$feedback .= '<br />' . sprintf(__('Your backup file: <a href="%1s">%2s</a> should begin downloading shortly.'), get_settings('siteurl') . "/{$this->backup_dir}{$this->backup_file}", $this->backup_file);
-				break;
-			case 'smtp':
-				if (! is_email($_POST['backup_recipient'])) {
-					$feedback .= get_settings('admin_email');
-				} else {
-					$feedback .= $_POST['backup_recipient'];
-				}
-				$feedback = '<br />' . sprintf(__('Your backup has been emailed to %s'), $feedback);
-				break;
-			case 'none':
-				$feedback .= '<br />' . __('Your backup file has been saved on the server. If you would like to download it now, right click and select "Save As"');
-				$feedback .= ':<br /> <a href="' . get_settings('siteurl') . "/{$this->backup_dir}$file\">$file</a> : " . sprintf(__('%s bytes'), filesize(ABSPATH . $this->backup_dir . $file));
-			}
-			$feedback .= '</p></div>';
-		}
-		
-		if (count($this->backup_errors)) {
-			$feedback .= '<div class="updated error">' . __('The following errors were reported:') . "<pre>";
-			foreach($this->backup_errors as $error) {
-				$feedback .= "{$error}\n";  //Errors are already localized
-			}
-			$feedback .= "</pre></div>";
-		}
-		
-		// did we just save options for wp-cron?
-		if ( (function_exists('wp_cron_init')) && isset($_POST['wp_cron_backup_options']) ) {
-			update_option('wp_cron_backup_schedule', intval($_POST['cron_schedule']), FALSE);
-			update_option('wp_cron_backup_tables', $_POST['wp_cron_backup_tables']);
-			if (is_email($_POST['cron_backup_recipient'])) {
-				update_option('wp_cron_backup_recipient', $_POST['cron_backup_recipient'], FALSE);
-			}
-			$feedback .= '<div class="updated"><p>' . __('Scheduled Backup Options Saved!') . '</p></div>';
-		}
-		
-		// Simple table name storage
-		$wp_table_names = explode(',','categories,comments,linkcategories,links,options,post2cat,postmeta,posts,users,usermeta');
-		// Apply WP DB prefix to table names
-		$wp_table_names = array_map(create_function('$a', 'global $table_prefix;return "{$table_prefix}{$a}";'), $wp_table_names);
-		
-		$other_tables = array();
-		$also_backup = array();
-	
-		// Get complete db table list	
-		$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
-		$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
-		// Get list of WP tables that actually exist in this DB (for 1.6 compat!)
-		$wp_backup_default_tables = array_intersect($all_tables, $wp_table_names);
-		// Get list of non-WP tables
-		$other_tables = array_diff($all_tables, $wp_backup_default_tables);
-		
-		if ('' != $feedback) {
-			echo $feedback;
-		}
-
-		// Give the new dirs the same perms as wp-content.
-		$stat = stat( ABSPATH . 'wp-content' );
-		$dir_perms = $stat['mode'] & 0000777; // Get the permission bits.
-
-		if ( !file_exists( ABSPATH . $this->backup_dir) ) {
-			if ( @ mkdir( ABSPATH . $this->backup_dir) ) {
-				@ chmod( ABSPATH . $this->backup_dir, $dir_perms);
-			} else {
-				echo '<div class="updated error"><p align="center">' . __('WARNING: Your wp-content directory is <strong>NOT</strong> writable! We can not create the backup directory.') . '<br />' . ABSPATH . $this->backup_dir . "</p></div>";
-			$WHOOPS = TRUE;
-			}
-		}
-		
-		if ( !is_writable( ABSPATH . $this->backup_dir) ) {
-			echo '<div class="updated error"><p align="center">' . __('WARNING: Your backup directory is <strong>NOT</strong> writable! We can not create the backup directory.') . '<br />' . ABSPATH . "</p></div>";
-		}
-
-		if ( !file_exists( ABSPATH . $this->backup_dir . 'index.php') ) {
-			@ touch( ABSPATH . $this->backup_dir . "index.php");
-		}
-
-		echo "<div class='wrap'>";
-		echo '<h2>' . __('Backup') . '</h2>';
-		echo '<fieldset class="options"><legend>' . __('Tables') . '</legend>';
-		echo '<form method="post">';
-		echo '<table align="center" cellspacing="5" cellpadding="5"><tr><td width="50%" align="left" class="alternate" valign="top">';
-		echo __('These core WordPress tables will always be backed up:') . '<br /><ul>';
-		foreach ($wp_backup_default_tables as $table) {
-			echo "<li><input type='hidden' name='core_tables[]' value='$table' />$table</li>";
-		}
-		echo '</ul></td><td width="50%" align="left" valign="top">';
-		if (count($other_tables) > 0) {
-			echo __('You may choose to include any of the following tables:') . ' <br />';
-			foreach ($other_tables as $table) {
-				echo "<label style=\"display:block;\"><input type='checkbox' name='other_tables[]' value='{$table}' /> {$table}</label>";
-			}
-		}
-		echo '</tr></table></fieldset>';
-		echo '<fieldset class="options"><legend>' . __('Backup Options') . '</legend>';
-		echo __('What to do with the backup file:') . "<br />";
-		echo '<label style="display:block;"><input type="radio" name="deliver" value="none" /> ' . __('Save to server') . " ({$this->backup_dir})</label>";
-		echo '<label style="display:block;"><input type="radio" checked="checked" name="deliver" value="http" /> ' . __('Download to your computer') . '</label>';
-		echo '<div><input type="radio" name="deliver" id="do_email" value="smtp" /> ';
-		echo '<label for="do_email">'.__('Email backup to:').'</label><input type="text" name="backup_recipient" size="20" value="' . get_settings('admin_email') . '" />';
-		
-		// Check DB dize.
-		$table_status = $wpdb->get_results("SHOW TABLE STATUS FROM " . $this->backquote(DB_NAME));
-		$core_size = $db_size = 0;
-		foreach($table_status as $table) {
-			$table_size = $table->Data_length - $table->Data_free;
-			if(in_array($table->Name, $wp_backup_default_tables)) {
-				$core_size += $table_size;	
-			}
-			$db_size += $table_size;
-		}
-		$mem_limit = ini_get('memory_limit');
-		$mem_limit = $this->return_bytes($mem_limit);
-		$mem_limit = ($mem_limit == 0) ? 8*1024*1024 :  $mem_limit - 2000000;
-		
-		if (! $WHOOPS) {
-			echo '<input type="hidden" name="do_backup" id="do_backup" value="backup" /></div>';
-			echo '<p class="submit"><input type="submit" name="submit" onclick="document.getElementById(\'do_backup\').value=\'fragments\';" value="' . __('Backup') . '!" / ></p>';
-		} else {
-			echo '<p class="alternate">' . __('WARNING: Your backup directory is <strong>NOT</strong> writable!') . '</p>';
-		}
-		echo '</fieldset>';
-		echo '</form>';
-		
-		// this stuff only displays if wp_cron is installed
-		if (function_exists('wp_cron_init')) {
-			echo '<fieldset class="options"><legend>' . __('Scheduled Backup') . '</legend>';
-			$datetime = get_settings('date_format') . ' @ ' . get_settings('time_format');
-			echo '<p>' . __('Last WP-Cron Daily Execution') . ': ' . date($datetime, get_option('wp_cron_daily_lastrun')) . '<br />';
-			echo __('Next WP-Cron Daily Execution') . ': ' . date($datetime, (get_option('wp_cron_daily_lastrun') + 86400)) . '</p>';
-			echo '<form method="post">';
-			echo '<table width="100%" callpadding="5" cellspacing="5">';
-			echo '<tr><td align="center">';
-			echo __('Schedule: ');
-			$wp_cron_backup_schedule = get_option('wp_cron_backup_schedule');
-			$schedule = array(0 => __('None'), 1 => __('Daily'));
-			foreach ($schedule as $value => $name) {
-				echo ' <input type="radio" name="cron_schedule"';
-				if ($wp_cron_backup_schedule == $value) {
-					echo ' checked="checked" ';
-				}
-				echo 'value="' . $value . '" /> ' . __($name);
-			}
-			echo '</td><td align="center">';
-			$cron_recipient = get_option('wp_cron_backup_recipient');
-			if (! is_email($cron_recipient)) {
-				$cron_recipient = get_settings('admin_email');
-			}
-			echo __('Email backup to:') . ' <input type="text" name="cron_backup_recipient" size="20" value="' . $cron_recipient . '" />';
-			echo '</td></tr>';
-			$cron_tables = get_option('wp_cron_backup_tables');
-			if (! is_array($cron_tables)) {
-				$cron_tables = array();
-			}
-			if (count($other_tables) > 0) {
-				echo '<tr><td colspan="2" align="left">' . __('Tables to include:') . '<br />';
-				foreach ($other_tables as $table) {
-					echo '<input type="checkbox" ';
-					if (in_array($table, $cron_tables)) {
-						echo 'checked=checked ';
-					}
-					echo "name='wp_cron_backup_tables[]' value='{$table}' /> {$table}<br />";
-				}
-				echo '</td></tr>';
-			}
-			echo '<tr><td colspan="2" align="center"><input type="hidden" name="wp_cron_backup_options" value="SET" /><input type="submit" name="submit" value="' . __('Submit') . '" /></td></tr></table></form>';
-			echo '</fieldset>';
-		}
-		// end of wp_cron section
-		
-		echo '</div>';
-		
-	}// end wp_backup_menu()
-	
-	/////////////////////////////
-	function wp_cron_daily() {
-		
-		$schedule = intval(get_option('wp_cron_backup_schedule'));
-		if (0 == $schedule) {
-		        // Scheduled backup is disabled
-		        return;
-		}
-		
-		global $table_prefix, $wpdb;
-
-		$wp_table_names = explode(',','categories,comments,linkcategories,links,options,post2cat,postmeta,posts,users,usermeta');
-		$wp_table_names = array_map(create_function('$a', 'global $table_prefix;return "{$table_prefix}{$a}";'), $wp_table_names);
-		$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
-		$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
-		$core_tables = array_intersect($all_tables, $wp_table_names);
-		$other_tables = get_option('wp_cron_backup_tables');
-		
-		$recipient = get_option('wp_cron_backup_recipient');
-		
-		$backup_file = $this->db_backup($core_tables, $other_tables);
-		if (FALSE !== $backup_file) {
-			$this->deliver_backup ($backup_file, 'smtp', $recipient);
-		}
-		
-		return;
-	} // wp_cron_db_backup
-
-	function validate_file($file) {
-		if (false !== strpos($file, '..'))
-			die(__("Cheatin' uh ?"));
-
-		if (false !== strpos($file, './'))
-			die(__("Cheatin' uh ?"));
-
-		if (':' == substr($file, 1, 1))
-			die(__("Cheatin' uh ?"));
-	}
-
-}
-
-function wpdbBackup_init() {
-	global $mywpdbbackup;
-
-	if ( !current_user_can('import') ) return;
-
-	$mywpdbbackup = new wpdbBackup(); 	
-}
-
-add_action('plugins_loaded', 'wpdbBackup_init');
-
-?>
diff -ruN 2.0.5/wp-content/themes/classic/comments-popup.php 2.2.2/wp-content/themes/classic/comments-popup.php
--- 2.0.5/wp-content/themes/classic/comments-popup.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/comments-popup.php	2007-02-23 02:31:07.000000000 -0600
@@ -1,14 +1,14 @@
-<?php 
+<?php
 /* Don't remove these lines. */
 add_filter('comment_text', 'popuplinks');
-foreach ($posts as $post) { start_wp();
+while( have_posts()) : the_post();
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-     <title><?php echo get_settings('blogname'); ?> - <?php echo sprintf(__("Comments on %s"), the_title('','',false)); ?></title>
+     <title><?php echo get_option('blogname'); ?> - <?php echo sprintf(__("Comments on %s"), the_title('','',false)); ?></title>
 
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
+	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
 	<style type="text/css" media="screen">
 		@import url( <?php bloginfo('stylesheet_url'); ?> );
 		body { margin: 3px; }
@@ -17,14 +17,14 @@
 </head>
 <body id="commentspopup">
 
-<h1 id="header"><a href="" title="<?php echo get_settings('blogname'); ?>"><?php echo get_settings('blogname'); ?></a></h1>
+<h1 id="header"><a href="" title="<?php echo get_option('blogname'); ?>"><?php echo get_option('blogname'); ?></a></h1>
 
 <h2 id="comments"><?php _e("Comments"); ?></h2>
 
-<p><a href="<?php echo get_settings('siteurl'); ?>/wp-commentsrss2.php?p=<?php echo $post->ID; ?>"><?php _e("<abbr title=\"Really Simple Syndication\">RSS</abbr> feed for comments on this post."); ?></a></p>
+<p><a href="<?php echo get_post_comments_feed_link($post->ID); ?>"><?php _e("<abbr title=\"Really Simple Syndication\">RSS</abbr> feed for comments on this post."); ?></a></p>
 
 <?php if ('open' == $post->ping_status) { ?>
-<p><?php _e("The <acronym title=\"Uniform Resource Identifier\">URI</acronym> to TrackBack this entry is:"); ?> <em><?php trackback_url() ?></em></p>
+<p><?php _e("The <abbr title=\"Universal Resource Locator\">URL</abbr> to TrackBack this entry is:"); ?> <em><?php trackback_url() ?></em></p>
 <?php } ?>
 
 <?php
@@ -55,12 +55,15 @@
 <h2><?php _e("Leave a comment"); ?></h2>
 <p><?php _e("Line and paragraph breaks automatic, e-mail address never displayed, <acronym title=\"Hypertext Markup Language\">HTML</acronym> allowed:"); ?> <code><?php echo allowed_tags(); ?></code></p>
 
-<form action="<?php echo get_settings('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
+<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
+<?php if ( $user_ID ) : ?> 
+	<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Logout &raquo;</a></p>
+<?php else : ?> 
 	<p>
 	  <input type="text" name="author" id="author" class="textarea" value="<?php echo $comment_author; ?>" size="28" tabindex="1" />
 	   <label for="author"><?php _e("Name"); ?></label>
 	<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
-	<input type="hidden" name="redirect_to" value="<?php echo wp_specialchars($_SERVER["REQUEST_URI"]); ?>" />
+	<input type="hidden" name="redirect_to" value="<?php echo attribute_escape($_SERVER["REQUEST_URI"]); ?>" />
 	</p>
 
 	<p>
@@ -70,8 +73,9 @@
 
 	<p>
 	  <input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="28" tabindex="3" />
-	   <label for="url"><?php _e("<acronym title=\"Uniform Resource Identifier\">URI</acronym>"); ?></label>
+	   <label for="url"><?php _e("<abbr title=\"Universal Resource Locator\">URL</abbr>"); ?></label>
 	</p>
+<?php endif; ?>
 
 	<p>
 	  <label for="comment"><?php _e("Your Comment"); ?></label>
@@ -93,16 +97,16 @@
 <div><strong><a href="javascript:window.close()"><?php _e("Close this window."); ?></a></strong></div>
 
 <?php // if you delete this the sky will fall on your head
-}
+endwhile;
 ?>
 
 <!-- // this is just the end of the motor - don't touch that line either :) -->
-<?php //} ?> 
+<?php //} ?>
 <p class="credit"><?php timer_stop(1); ?> <?php echo sprintf(__("<cite>Powered by <a href=\"http://wordpress.org\" title=\"%s\"><strong>Wordpress</strong></a></cite>"),__("Powered by WordPress, state-of-the-art semantic personal publishing platform.")); ?></p>
 <?php // Seen at http://www.mijnkopthee.nl/log2/archive/2003/05/28/esc(18) ?>
 <script type="text/javascript">
 <!--
-document.onkeypress = function esc(e) {	
+document.onkeypress = function esc(e) {
 	if(typeof(e) == "undefined") { e=event; }
 	if (e.keyCode == 27) { self.close(); }
 }
diff -ruN 2.0.5/wp-content/themes/classic/comments.php 2.2.2/wp-content/themes/classic/comments.php
--- 2.0.5/wp-content/themes/classic/comments.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/comments.php	2006-11-19 01:56:05.000000000 -0600
@@ -2,7 +2,7 @@
 <p><?php _e('Enter your password to view comments.'); ?></p>
 <?php return; endif; ?>
 
-<h2 id="comments"><?php comments_number(__('No Comments'), __('1 Comment'), __('% Comments')); ?> 
+<h2 id="comments"><?php comments_number(__('No Comments'), __('1 Comment'), __('% Comments')); ?>
 <?php if ( comments_open() ) : ?>
 	<a href="#postcomment" title="<?php _e("Leave a comment"); ?>">&raquo;</a>
 <?php endif; ?>
@@ -25,9 +25,9 @@
 	<p><?php _e('No comments yet.'); ?></p>
 <?php endif; ?>
 
-<p><?php comments_rss_link(__('<abbr title="Really Simple Syndication">RSS</abbr> feed for comments on this post.')); ?> 
+<p><?php comments_rss_link(__('<abbr title="Really Simple Syndication">RSS</abbr> feed for comments on this post.')); ?>
 <?php if ( pings_open() ) : ?>
-	<a href="<?php trackback_url() ?>" rel="trackback"><?php _e('TrackBack <abbr title="Uniform Resource Identifier">URI</abbr>'); ?></a>
+	<a href="<?php trackback_url() ?>" rel="trackback"><?php _e('TrackBack <abbr title="Universal Resource Locator">URL</abbr>'); ?></a>
 <?php endif; ?>
 </p>
 
diff -ruN 2.0.5/wp-content/themes/classic/functions.php 2.2.2/wp-content/themes/classic/functions.php
--- 2.0.5/wp-content/themes/classic/functions.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/functions.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,10 @@
+<?php
+if ( function_exists('register_sidebar') )
+	register_sidebar(array(
+        'before_widget' => '<li id="%1$s" class="widget %2$s">',
+        'after_widget' => '</li>',
+        'before_title' => '',
+        'after_title' => '',
+    ));
+
+?>
diff -ruN 2.0.5/wp-content/themes/classic/header.php 2.2.2/wp-content/themes/classic/header.php
--- 2.0.5/wp-content/themes/classic/header.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/header.php	2007-01-16 18:01:21.000000000 -0600
@@ -1,11 +1,11 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
 
 <head profile="http://gmpg.org/xfn/11">
 	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
 
 	<title><?php bloginfo('name'); ?><?php wp_title(); ?></title>
-	
+
 	<meta name="generator" content="WordPress <?php bloginfo('version'); ?>" /> <!-- leave this for stats please -->
 
 	<style type="text/css" media="screen">
@@ -15,9 +15,9 @@
 	<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="<?php bloginfo('rss2_url'); ?>" />
 	<link rel="alternate" type="text/xml" title="RSS .92" href="<?php bloginfo('rss_url'); ?>" />
 	<link rel="alternate" type="application/atom+xml" title="Atom 0.3" href="<?php bloginfo('atom_url'); ?>" />
-	
+
 	<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
-    <?php wp_get_archives('type=monthly&format=link'); ?>
+	<?php wp_get_archives('type=monthly&format=link'); ?>
 	<?php //comments_popup_script(); // off by default ?>
 	<?php wp_head(); ?>
 </head>
diff -ruN 2.0.5/wp-content/themes/classic/index.php 2.2.2/wp-content/themes/classic/index.php
--- 2.0.5/wp-content/themes/classic/index.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/index.php	2007-04-19 17:26:52.000000000 -0500
@@ -1,22 +1,22 @@
-<?php 
+<?php
 get_header();
 ?>
 
 <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 
 <?php the_date('','<h2>','</h2>'); ?>
-	
+
 <div class="post" id="post-<?php the_ID(); ?>">
 	 <h3 class="storytitle"><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h3>
 	<div class="meta"><?php _e("Filed under:"); ?> <?php the_category(',') ?> &#8212; <?php the_author() ?> @ <?php the_time() ?> <?php edit_post_link(__('Edit This')); ?></div>
-	
+
 	<div class="storycontent">
 		<?php the_content(__('(more...)')); ?>
 	</div>
-	
+
 	<div class="feedback">
-            <?php wp_link_pages(); ?>
-            <?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?>
+		<?php wp_link_pages(); ?>
+		<?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?>
 	</div>
 
 </div>
diff -ruN 2.0.5/wp-content/themes/classic/sidebar.php 2.2.2/wp-content/themes/classic/sidebar.php
--- 2.0.5/wp-content/themes/classic/sidebar.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/classic/sidebar.php	2007-03-31 11:57:50.000000000 -0500
@@ -3,15 +3,13 @@
 <div id="menu">
 
 <ul>
-	<?php wp_list_pages(); ?>
-	<?php get_links_list(); ?>
- <li id="categories"><?php _e('Categories:'); ?>
-	<ul>
-	<?php wp_list_cats(); ?>
-	</ul>
- </li>
+<?php 	/* Widgetized sidebar, if you have the plugin installed. */
+		if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : ?>
+	<?php wp_list_pages('title_li=' . __('Pages:')); ?>
+	<?php wp_list_bookmarks('title_after=&title_before='); ?>
+	<?php wp_list_categories('title_li=' . __('Categories:')); ?>
  <li id="search">
-   <label for="s"><?php _e('Search:'); ?></label>	
+   <label for="s"><?php _e('Search:'); ?></label>
    <form id="searchform" method="get" action="<?php bloginfo('home'); ?>">
 	<div>
 		<input type="text" name="s" id="s" size="15" /><br />
@@ -20,22 +18,23 @@
 	</form>
  </li>
  <li id="archives"><?php _e('Archives:'); ?>
- 	<ul>
+	<ul>
 	 <?php wp_get_archives('type=monthly'); ?>
- 	</ul>
+	</ul>
  </li>
  <li id="meta"><?php _e('Meta:'); ?>
- 	<ul>
+	<ul>
 		<?php wp_register(); ?>
 		<li><?php wp_loginout(); ?></li>
-		<li><a href="feed:<?php bloginfo('rss2_url'); ?>" title="<?php _e('Syndicate this site using RSS'); ?>"><?php _e('<abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
-		<li><a href="feed:<?php bloginfo('comments_rss2_url'); ?>" title="<?php _e('The latest comments to all posts in RSS'); ?>"><?php _e('Comments <abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
+		<li><a href="<?php bloginfo('rss2_url'); ?>" title="<?php _e('Syndicate this site using RSS'); ?>"><?php _e('<abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
+		<li><a href="<?php bloginfo('comments_rss2_url'); ?>" title="<?php _e('The latest comments to all posts in RSS'); ?>"><?php _e('Comments <abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
 		<li><a href="http://validator.w3.org/check/referer" title="<?php _e('This page validates as XHTML 1.0 Transitional'); ?>"><?php _e('Valid <abbr title="eXtensible HyperText Markup Language">XHTML</abbr>'); ?></a></li>
 		<li><a href="http://gmpg.org/xfn/"><abbr title="XHTML Friends Network">XFN</abbr></a></li>
 		<li><a href="http://wordpress.org/" title="<?php _e('Powered by WordPress, state-of-the-art semantic personal publishing platform.'); ?>"><abbr title="WordPress">WP</abbr></a></li>
 		<?php wp_meta(); ?>
 	</ul>
  </li>
+<?php endif; ?>
 
 </ul>
 
diff -ruN 2.0.5/wp-content/themes/default/archive.php 2.2.2/wp-content/themes/default/archive.php
--- 2.0.5/wp-content/themes/default/archive.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/archive.php	2007-04-19 17:26:52.000000000 -0500
@@ -6,7 +6,7 @@
 
 		 <?php $post = $posts[0]; // Hack. Set $post so that the_date() works. ?>
 <?php /* If this is a category archive */ if (is_category()) { ?>
-		<h2 class="pagetitle">Archive for the '<?php echo single_cat_title(); ?>' Category</h2>
+		<h2 class="pagetitle">Archive for the &#8216;<?php single_cat_title(); ?>&#8217; Category</h2>
 
  	  <?php /* If this is a daily archive */ } elseif (is_day()) { ?>
 		<h2 class="pagetitle">Archive for <?php the_time('F jS, Y'); ?></h2>
@@ -17,9 +17,6 @@
 		<?php /* If this is a yearly archive */ } elseif (is_year()) { ?>
 		<h2 class="pagetitle">Archive for <?php the_time('Y'); ?></h2>
 
-	  <?php /* If this is a search */ } elseif (is_search()) { ?>
-		<h2 class="pagetitle">Search Results</h2>
-
 	  <?php /* If this is an author archive */ } elseif (is_author()) { ?>
 		<h2 class="pagetitle">Author Archive</h2>
 
@@ -43,7 +40,7 @@
 					<?php the_content() ?>
 				</div>
 
-				<p class="postmetadata">Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p> 
+				<p class="postmetadata">Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
 
 			</div>
 
@@ -65,4 +62,4 @@
 
 <?php get_sidebar(); ?>
 
-<?php get_footer(); ?>
\ No newline at end of file
+<?php get_footer(); ?>
diff -ruN 2.0.5/wp-content/themes/default/archives.php 2.2.2/wp-content/themes/default/archives.php
--- 2.0.5/wp-content/themes/default/archives.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/archives.php	2006-11-19 01:56:05.000000000 -0600
@@ -11,14 +11,14 @@
 <?php include (TEMPLATEPATH . '/searchform.php'); ?>
 
 <h2>Archives by Month:</h2>
-  <ul>
-    <?php wp_get_archives('type=monthly'); ?>
-  </ul>
+	<ul>
+		<?php wp_get_archives('type=monthly'); ?>
+	</ul>
 
 <h2>Archives by Subject:</h2>
-  <ul>
-     <?php wp_list_cats(); ?>
-  </ul>
+	<ul>
+		 <?php wp_list_categories(); ?>
+	</ul>
 
 </div>
 
diff -ruN 2.0.5/wp-content/themes/default/attachment.php 2.2.2/wp-content/themes/default/attachment.php
--- 2.0.5/wp-content/themes/default/attachment.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/attachment.php	2007-05-04 16:27:10.000000000 -0500
@@ -17,7 +17,7 @@
 
 				<?php the_content('<p class="serif">Read the rest of this entry &raquo;</p>'); ?>
 
-				<?php link_pages('<p><strong>Pages:</strong> ', '</p>', 'number'); ?>
+				<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
 
 				<p class="postmetadata alt">
 					<small>
diff -ruN 2.0.5/wp-content/themes/default/comments-popup.php 2.2.2/wp-content/themes/default/comments-popup.php
--- 2.0.5/wp-content/themes/default/comments-popup.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/comments-popup.php	2007-02-23 02:31:07.000000000 -0600
@@ -1,14 +1,14 @@
-<?php 
+<?php
 /* Don't remove these lines. */
 add_filter('comment_text', 'popuplinks');
-foreach ($posts as $post) { start_wp();
+while ( have_posts()) : the_post();
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-     <title><?php echo get_settings('blogname'); ?> - Comments on <?php the_title(); ?></title>
+     <title><?php echo get_option('blogname'); ?> - Comments on <?php the_title(); ?></title>
 
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
+	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
 	<style type="text/css" media="screen">
 		@import url( <?php bloginfo('stylesheet_url'); ?> );
 		body { margin: 3px; }
@@ -17,14 +17,14 @@
 </head>
 <body id="commentspopup">
 
-<h1 id="header"><a href="" title="<?php echo get_settings('blogname'); ?>"><?php echo get_settings('blogname'); ?></a></h1>
+<h1 id="header"><a href="" title="<?php echo get_option('blogname'); ?>"><?php echo get_option('blogname'); ?></a></h1>
 
 <h2 id="comments">Comments</h2>
 
-<p><a href="<?php echo get_settings('siteurl'); ?>/wp-commentsrss2.php?p=<?php echo $post->ID; ?>"><abbr title="Really Simple Syndication">RSS</abbr> feed for comments on this post.</a></p>
+<p><a href="<?php echo get_post_comments_feed_link($post->ID); ?>"><abbr title="Really Simple Syndication">RSS</abbr> feed for comments on this post.</a></p>
 
 <?php if ('open' == $post->ping_status) { ?>
-<p>The <acronym title="Uniform Resource Identifier">URI</acronym> to TrackBack this entry is: <em><?php trackback_url() ?></em></p>
+<p>The <abbr title="Universal Resource Locator">URL</abbr> to TrackBack this entry is: <em><?php trackback_url() ?></em></p>
 <?php } ?>
 
 <?php
@@ -55,12 +55,15 @@
 <h2>Leave a comment</h2>
 <p>Line and paragraph breaks automatic, e-mail address never displayed, <acronym title="Hypertext Markup Language">HTML</acronym> allowed: <code><?php echo allowed_tags(); ?></code></p>
 
-<form action="<?php echo get_settings('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
+<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
+<?php if ( $user_ID ) : ?> 
+	<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Logout &raquo;</a></p>
+<?php else : ?> 
 	<p>
 	  <input type="text" name="author" id="author" class="textarea" value="<?php echo $comment_author; ?>" size="28" tabindex="1" />
 	   <label for="author">Name</label>
 	<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
-	<input type="hidden" name="redirect_to" value="<?php echo wp_specialchars($_SERVER["REQUEST_URI"]); ?>" />
+	<input type="hidden" name="redirect_to" value="<?php echo attribute_escape($_SERVER["REQUEST_URI"]); ?>" />
 	</p>
 
 	<p>
@@ -70,8 +73,9 @@
 
 	<p>
 	  <input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="28" tabindex="3" />
-	   <label for="url"><acronym title="Uniform Resource Identifier">URI</acronym></label>
+	   <label for="url"><abbr title="Universal Resource Locator">URL</abbr></label>
 	</p>
+<?php endif; ?>
 
 	<p>
 	  <label for="comment">Your Comment</label>
@@ -93,11 +97,11 @@
 <div><strong><a href="javascript:window.close()">Close this window.</a></strong></div>
 
 <?php // if you delete this the sky will fall on your head
-}
+endwhile;
 ?>
 
 <!-- // this is just the end of the motor - don't touch that line either :) -->
-<?php //} ?> 
+<?php //} ?>
 <p class="credit"><?php timer_stop(1); ?> <cite>Powered by <a href="http://wordpress.org/" title="Powered by WordPress, state-of-the-art semantic personal publishing platform"><strong>Wordpress</strong></a></cite></p>
 <?php // Seen at http://www.mijnkopthee.nl/log2/archive/2003/05/28/esc(18) ?>
 <script type="text/javascript">
diff -ruN 2.0.5/wp-content/themes/default/comments.php 2.2.2/wp-content/themes/default/comments.php
--- 2.0.5/wp-content/themes/default/comments.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/comments.php	2007-04-19 22:52:41.000000000 -0500
@@ -2,46 +2,46 @@
 	if ('comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
 		die ('Please do not load this page directly. Thanks!');
 
-        if (!empty($post->post_password)) { // if there's a password
-            if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) {  // and it doesn't match the cookie
-				?>
-
-				<p class="nocomments">This post is password protected. Enter the password to view comments.<p>
-
-				<?php
-				return;
-            }
-        }
+	if (!empty($post->post_password)) { // if there's a password
+		if ($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) {  // and it doesn't match the cookie
+			?>
+
+			<p class="nocomments">This post is password protected. Enter the password to view comments.</p>
+
+			<?php
+			return;
+		}
+	}
 
-		/* This variable is for alternating comment background */
-		$oddcomment = 'alt';
+	/* This variable is for alternating comment background */
+	$oddcomment = 'class="alt" ';
 ?>
 
 <!-- You can start editing here. -->
 
 <?php if ($comments) : ?>
-	<h3 id="comments"><?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;<?php the_title(); ?>&#8221;</h3> 
+	<h3 id="comments"><?php comments_number('No Responses', 'One Response', '% Responses' );?> to &#8220;<?php the_title(); ?>&#8221;</h3>
 
 	<ol class="commentlist">
 
 	<?php foreach ($comments as $comment) : ?>
 
-		<li class="<?php echo $oddcomment; ?>" id="comment-<?php comment_ID() ?>">
+		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
 			<cite><?php comment_author_link() ?></cite> Says:
 			<?php if ($comment->comment_approved == '0') : ?>
 			<em>Your comment is awaiting moderation.</em>
 			<?php endif; ?>
 			<br />
 
-			<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('e','',''); ?></small>
+			<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title=""><?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a> <?php edit_comment_link('edit','&nbsp;&nbsp;',''); ?></small>
 
 			<?php comment_text() ?>
 
 		</li>
 
-	<?php /* Changes every other comment to a different class */
-		if ('alt' == $oddcomment) $oddcomment = '';
-		else $oddcomment = 'alt';
+	<?php
+		/* Changes every other comment to a different class */
+		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
 	?>
 
 	<?php endforeach; /* end for each comment */ ?>
@@ -50,7 +50,7 @@
 
  <?php else : // this is displayed if there are no comments so far ?>
 
-  <?php if ('open' == $post->comment_status) : ?> 
+	<?php if ('open' == $post->comment_status) : ?>
 		<!-- If comments are open, but there are no comments. -->
 
 	 <?php else : // comments are closed ?>
@@ -88,7 +88,7 @@
 
 <?php endif; ?>
 
-<!--<p><small><strong>XHTML:</strong> You can use these tags: <?php echo allowed_tags(); ?></small></p>-->
+<!--<p><small><strong>XHTML:</strong> You can use these tags: <code><?php echo allowed_tags(); ?></code></small></p>-->
 
 <p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
 
diff -ruN 2.0.5/wp-content/themes/default/footer.php 2.2.2/wp-content/themes/default/footer.php
--- 2.0.5/wp-content/themes/default/footer.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/footer.php	2007-04-04 18:35:37.000000000 -0500
@@ -1,12 +1,12 @@
 
 <hr />
 <div id="footer">
-<!-- If you'd like to support WordPress, having the "powered by" link someone on your blog is the best way, it's our only promotion or advertising. -->
+<!-- If you'd like to support WordPress, having the "powered by" link somewhere on your blog is the best way, it's our only promotion or advertising. -->
 	<p>
-		<?php bloginfo('name'); ?> is proudly powered by 
+		<?php bloginfo('name'); ?> is proudly powered by
 		<a href="http://wordpress.org/">WordPress</a>
-		<br /><a href="feed:<?php bloginfo('rss2_url'); ?>">Entries (RSS)</a>
-		and <a href="feed:<?php bloginfo('comments_rss2_url'); ?>">Comments (RSS)</a>.
+		<br /><a href="<?php bloginfo('rss2_url'); ?>">Entries (RSS)</a>
+		and <a href="<?php bloginfo('comments_rss2_url'); ?>">Comments (RSS)</a>.
 		<!-- <?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds. -->
 	</p>
 </div>
diff -ruN 2.0.5/wp-content/themes/default/functions.php 2.2.2/wp-content/themes/default/functions.php
--- 2.0.5/wp-content/themes/default/functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/functions.php	2007-06-11 17:40:08.000000000 -0500
@@ -1,397 +1,416 @@
-<?php
-
-function kubrick_head() {
-	$head = "<style type='text/css'>\n<!--";
-	$output = '';
-	if ( kubrick_header_image() ) {
-		$url =  kubrick_header_image_url() ;
-		$output .= "#header { background: url('$url') no-repeat bottom center; }\n";
-	}
-	if ( false !== ( $color = kubrick_header_color() ) ) {
-		$output .= "#headerimg h1 a, #headerimg h1 a:visited, #headerimg .description { color: $color; }\n";
-	}
-	if ( false !== ( $display = kubrick_header_display() ) ) {
-		$output .= "#headerimg { display: $display }\n";
-	}
-	$foot = "--></style>\n";
-	if ( '' != $output )
-		echo $head . $output . $foot;
-}
-
-add_action('wp_head', 'kubrick_head');
-
-function kubrick_header_image() {
-	return apply_filters('kubrick_header_image', get_settings('kubrick_header_image'));
-}
-
-function kubrick_upper_color() {
-	if ( strstr( $url = kubrick_header_image_url(), 'header-img.php?' ) ) {
-		parse_str(substr($url, strpos($url, '?') + 1), $q);
-		return $q['upper'];
-	} else
-		return '69aee7';
-}
-
-function kubrick_lower_color() {
-	if ( strstr( $url = kubrick_header_image_url(), 'header-img.php?' ) ) {
-		parse_str(substr($url, strpos($url, '?') + 1), $q);
-		return $q['lower'];
-	} else
-		return '4180b6';
-}
-
-function kubrick_header_image_url() {
-	if ( $image = kubrick_header_image() )
-		$url = get_template_directory_uri() . '/images/' . $image;
-	else
-		$url = get_template_directory_uri() . '/images/kubrickheader.jpg';
-
-	return $url;
-}
-
-function kubrick_header_color() {
-	return apply_filters('kubrick_header_color', get_settings('kubrick_header_color'));
-}
-
-function kubrick_header_color_string() {
-	$color = kubrick_header_color();
-	if ( false === $color )
-		return 'white';
-
-	return $color;
-}
-
-function kubrick_header_display() {
-	return apply_filters('kubrick_header_display', get_settings('kubrick_header_display'));
-}
-
-function kubrick_header_display_string() {
-	$display = kubrick_header_display();
-	return $display ? $display : 'inline';
-}
-
-add_action('admin_menu', 'kubrick_add_theme_page');
-
-function kubrick_add_theme_page() {
-	if ( $_GET['page'] == basename(__FILE__) ) {
-		if ( 'save' == $_REQUEST['action'] ) {
-			if ( isset($_REQUEST['njform']) ) {
-				if ( isset($_REQUEST['defaults']) ) {
-					delete_option('kubrick_header_image');
-					delete_option('kubrick_header_color');
-					delete_option('kubrick_header_display');
-				} else {
-					if ( '' == $_REQUEST['njfontcolor'] )
-						delete_option('kubrick_header_color');
-					else
-						update_option('kubrick_header_color', $_REQUEST['njfontcolor']);
-
-					if ( preg_match('/[0-9A-F]{6}|[0-9A-F]{3}/i', $_REQUEST['njuppercolor'], $uc) && preg_match('/[0-9A-F]{6}|[0-9A-F]{3}/i', $_REQUEST['njlowercolor'], $lc) ) {
-						$uc = ( strlen($uc[0]) == 3 ) ? $uc[0]{0}.$uc[0]{0}.$uc[0]{1}.$uc[0]{1}.$uc[0]{2}.$uc[0]{2} : $uc[0];
-						$lc = ( strlen($lc[0]) == 3 ) ? $lc[0]{0}.$lc[0]{0}.$lc[0]{1}.$lc[0]{1}.$lc[0]{2}.$lc[0]{2} : $lc[0];
-						update_option('kubrick_header_image', "header-img.php?upper=$uc&amp;lower=$lc");
-					}
-
-					if ( isset($_REQUEST['toggledisplay']) ) {
-						if ( false === get_settings('kubrick_header_display') )
-							update_option('kubrick_header_display', 'none');
-						else
-							delete_option('kubrick_header_display');
-					}
-				}
-			} else {
-
-				if ( isset($_REQUEST['headerimage']) ) {
-					if ( '' == $_REQUEST['headerimage'] )
-						delete_option('kubrick_header_image');
-					else
-						update_option('kubrick_header_image', $_REQUEST['headerimage']);
-				}
-
-				if ( isset($_REQUEST['fontcolor']) ) {
-					if ( '' == $_REQUEST['fontcolor'] )
-						delete_option('kubrick_header_color');
-					else
-						update_option('kubrick_header_color', $_REQUEST['fontcolor']);
-				}
-
-				if ( isset($_REQUEST['fontdisplay']) ) {
-					if ( '' == $_REQUEST['fontdisplay'] || 'inline' == $_REQUEST['fontdisplay'] )
-						delete_option('kubrick_header_display');
-					else
-						update_option('kubrick_header_display', 'none');
-				}
-			}
-			//print_r($_REQUEST);
-			wp_redirect("themes.php?page=functions.php&saved=true");
-			die;
-		}
-		add_action('admin_head', 'kubrick_theme_page_head');
-	}
-	add_theme_page('Customize Header', 'Header Image and Color', 'edit_themes', basename(__FILE__), 'kubrick_theme_page');
-}
-
-function kubrick_theme_page_head() {
-?>
-<script type="text/javascript" src="../wp-includes/js/colorpicker.js"></script>
-<script type='text/javascript'>
-// <![CDATA[
-	function pickColor(color) {
-		ColorPicker_targetInput.value = color;
-		kUpdate(ColorPicker_targetInput.id);
-	}
-	function PopupWindow_populate(contents) {
-		contents += '<br /><p style="text-align:center;margin-top:0px;"><input type="button" value="Close Color Picker" onclick="cp.hidePopup(\'prettyplease\')"></input></p>';
-		this.contents = contents;
-		this.populated = false;
-	}
-	function PopupWindow_hidePopup(magicword) {
-		if ( magicword != 'prettyplease' )
-			return false;
-		if (this.divName != null) {
-			if (this.use_gebi) {
-				document.getElementById(this.divName).style.visibility = "hidden";
-			}
-			else if (this.use_css) {
-				document.all[this.divName].style.visibility = "hidden";
-			}
-			else if (this.use_layers) {
-				document.layers[this.divName].visibility = "hidden";
-			}
-		}
-		else {
-			if (this.popupWindow && !this.popupWindow.closed) {
-				this.popupWindow.close();
-				this.popupWindow = null;
-			}
-		}
-		return false;
-	}
-	function colorSelect(t,p) {
-		if ( cp.p == p && document.getElementById(cp.divName).style.visibility != "hidden" )
-			cp.hidePopup('prettyplease');
-		else {
-			cp.p = p;
-			cp.select(t,p);
-		}
-	}
-	function PopupWindow_setSize(width,height) {
-		this.width = 162;
-		this.height = 210;
-	}
-
-	var cp = new ColorPicker();
-	function advUpdate(val, obj) {
-		document.getElementById(obj).value = val;
-		kUpdate(obj);
-	}
-	function kUpdate(oid) {
-		if ( 'uppercolor' == oid || 'lowercolor' == oid ) {
-			uc = document.getElementById('uppercolor').value.replace('#', '');
-			lc = document.getElementById('lowercolor').value.replace('#', '');
-			hi = document.getElementById('headerimage');
-			hi.value = 'header-img.php?upper='+uc+'&lower='+lc;
-			document.getElementById('header').style.background = 'url("<?php echo get_template_directory_uri(); ?>/images/'+hi.value+'") center no-repeat';
-			document.getElementById('advuppercolor').value = '#'+uc;
-			document.getElementById('advlowercolor').value = '#'+lc;
-		}
-		if ( 'fontcolor' == oid ) {
-			document.getElementById('header').style.color = document.getElementById('fontcolor').value;
-			document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value;
-		}
-		if ( 'fontdisplay' == oid ) {
-			document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
-		}
-	}
-	function toggleDisplay() {
-		td = document.getElementById('fontdisplay');
-		td.value = ( td.value == 'none' ) ? 'inline' : 'none';
-		kUpdate('fontdisplay');
-	}
-	function toggleAdvanced() {
-		a = document.getElementById('jsAdvanced');
-		if ( a.style.display == 'none' )
-			a.style.display = 'block';
-		else
-			a.style.display = 'none';
-	}
-	function kDefaults() {
-		document.getElementById('headerimage').value = '';
-		document.getElementById('advuppercolor').value = document.getElementById('uppercolor').value = '#69aee7';
-		document.getElementById('advlowercolor').value = document.getElementById('lowercolor').value = '#4180b6';
-		document.getElementById('header').style.background = 'url("<?php echo get_template_directory_uri(); ?>/images/kubrickheader.jpg") center no-repeat';
-		document.getElementById('header').style.color = '#FFFFFF';
-		document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value = '';
-		document.getElementById('fontdisplay').value = 'inline';
-		document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
-	}
-	function kRevert() {
-		document.getElementById('headerimage').value = '<?php echo kubrick_header_image(); ?>';
-		document.getElementById('advuppercolor').value = document.getElementById('uppercolor').value = '#<?php echo kubrick_upper_color(); ?>';
-		document.getElementById('advlowercolor').value = document.getElementById('lowercolor').value = '#<?php echo kubrick_lower_color(); ?>';
-		document.getElementById('header').style.background = 'url("<?php echo kubrick_header_image_url(); ?>") center no-repeat';
-		document.getElementById('header').style.color = '';
-		document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value = '<?php echo kubrick_header_color_string(); ?>';
-		document.getElementById('fontdisplay').value = '<?php echo kubrick_header_display_string(); ?>';
-		document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
-	}
-	function kInit() {
-		document.getElementById('jsForm').style.display = 'block';
-		document.getElementById('nonJsForm').style.display = 'none';
-	}
-	addLoadEvent(kInit);
-// ]]>
-</script>
-<style type='text/css'>
-	#headwrap {
-		text-align: center;
-	}
-	#kubrick-header {
-		font-size: 80%;
-	}
-	#kubrick-header .hibrowser {
-		width: 780px;
-		height: 260px;
-		overflow: scroll;
-	}
-	#kubrick-header #hitarget {
-		display: none;
-	}
-	#kubrick-header #header h1 {
-		font-family: 'Trebuchet MS', 'Lucida Grande', Verdana, Arial, Sans-Serif;
-		font-weight: bold;
-		font-size: 4em;
-		text-align: center;
-		padding-top: 70px;
-		margin: 0;
-	}
-
-	#kubrick-header #header .description {
-		font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif;
-		font-size: 1.2em;
-		text-align: center;
-	}
-	#kubrick-header #header {
-		text-decoration: none;
-		color: <?php echo kubrick_header_color_string(); ?>;
-		padding: 0;
-		margin: 0;
-		height: 200px;
-		text-align: center;
-		background: url('<?php echo kubrick_header_image_url(); ?>') center no-repeat;
-	}
-	#kubrick-header #headerimg {
-		margin: 0;
-		height: 200px;
-		width: 100%;
-		display: <?php echo kubrick_header_display_string(); ?>;
-	}
-	#jsForm {
-		display: none;
-		text-align: center;
-	}
-	#jsForm input.submit, #jsForm input.button, #jsAdvanced input.button {
-		padding: 0px;
-		margin: 0px;
-	}
-	#advanced {
-		text-align: center;
-		width: 620px;
-	}
-	html>body #advanced {
-		text-align: center;
-		position: relative;
-		left: 50%;
-		margin-left: -380px;
-	}
-	#jsAdvanced {
-		text-align: right;
-	}
-	#nonJsForm {
-		position: relative;
-		text-align: left;
-		margin-left: -370px;
-		left: 50%;
-	}
-	#nonJsForm label {
-		padding-top: 6px;
-		padding-right: 5px;
-		float: left;
-		width: 100px;
-		text-align: right;
-	}
-	.defbutton {
-		font-weight: bold;
-	}
-	.zerosize {
-		width: 0px;
-		height: 0px;
-		overflow: hidden;
-	}
-	#colorPickerDiv a, #colorPickerDiv a:hover {
-		padding: 1px;
-		text-decoration: none;
-		border-bottom: 0px;
-	}
-</style>
-<?php
-}
-
-function kubrick_theme_page() {
-	if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>Options saved.</strong></p></div>';
-?>
-<div class='wrap'>
-	<div id="kubrick-header">
-		<h2>Header Image and Color</h2>
-		<div id="headwrap">
-			<div id="header">
-				<div id="headerimg">
-					<h1><?php bloginfo('name'); ?></h1>
-					<div class="description"><?php bloginfo('description'); ?></div>
-				</div>
-			</div>
-		</div>
-		<br />
-		<div id="nonJsForm">
-			<form method="post" action="">
-				<div class="zerosize"><input type="submit" name="defaultsubmit" value="Save" /></div>
-				<label for="njfontcolor">Font Color:</label><input type="text" name="njfontcolor" id="njfontcolor" value="<?php echo kubrick_header_color(); ?>" /> Any CSS color (<code>red</code> or <code>#FF0000</code> or <code>rgb(255, 0, 0)</code>)<br />
-				<label for="njuppercolor">Upper Color:</label><input type="text" name="njuppercolor" id="njuppercolor" value="#<?php echo kubrick_upper_color(); ?>" /> HEX only (<code>#FF0000</code> or <code>#F00</code>)<br />
-				<label for="njlowercolor">Lower Color:</label><input type="text" name="njlowercolor" id="njlowercolor" value="#<?php echo kubrick_lower_color(); ?>" /> HEX only (<code>#FF0000</code> or <code>#F00</code>)<br />
-				<input type="hidden" name="hi" id="hi" value="<?php echo kubrick_header_image(); ?>" />
-				<input type="submit" name="toggledisplay" id="toggledisplay" value="Toggle Text" />
-				<input type="submit" name="defaults" value="Use Defaults" />
-				<input type="submit" class="defbutton" name="submitform" value="&nbsp;&nbsp;Save&nbsp;&nbsp;" />
-				<input type="hidden" name="action" value="save" />
-				<input type="hidden" name="njform" value="true" />
-			</form>
-		</div>
-		<div id="jsForm">
-			<form style="display:inline;" method="post" name="hicolor" id="hicolor" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
-				<input type="button" onclick="tgt=document.getElementById('fontcolor');colorSelect(tgt,'pick1');return false;" name="pick1" id="pick1" value="Font Color"></input>
-				<input type="button" onclick="tgt=document.getElementById('uppercolor');colorSelect(tgt,'pick2');return false;" name="pick2" id="pick2" value="Upper Color"></input>
-				<input type="button" onclick="tgt=document.getElementById('lowercolor');colorSelect(tgt,'pick3');return false;" name="pick3" id="pick3" value="Lower Color"></input>
-				<input type="button" name="revert" value="Revert" onclick="kRevert()" />
-				<input type="button" value="Advanced" onclick="toggleAdvanced()" />
-				<input type="submit" name="submitform" class="defbutton" value="Save" onclick="cp.hidePopup('prettyplease')" />
-				<input type="hidden" name="action" value="save" />
-				<input type="hidden" name="fontdisplay" id="fontdisplay" value="<?php echo kubrick_header_display(); ?>" />
-				<input type="hidden" name="fontcolor" id="fontcolor" value="<?php echo kubrick_header_color(); ?>" />
-				<input type="hidden" name="uppercolor" id="uppercolor" value="<?php echo kubrick_upper_color(); ?>" />
-				<input type="hidden" name="lowercolor" id="lowercolor" value="<?php echo kubrick_lower_color(); ?>" />
-				<input type="hidden" name="headerimage" id="headerimage" value="<?php echo kubrick_header_image(); ?>" />
-			</form>
-			<div id="colorPickerDiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;visibility:hidden;"> </div>
-			<div id="advanced">
-				<form id="jsAdvanced" style="display:none;" action="">
-					<label for="advfontcolor">Font Color (CSS): </label><input type="text" id="advfontcolor" onchange="advUpdate(this.value, 'fontcolor')" value="<?php echo kubrick_header_color(); ?>" /><br />
-					<label for="advuppercolor">Upper Color (HEX): </label><input type="text" id="advuppercolor" onchange="advUpdate(this.value, 'uppercolor')" value="#<?php echo kubrick_upper_color(); ?>" /><br />
-					<label for="advlowercolor">Lower Color (HEX): </label><input type="text" id="advlowercolor" onchange="advUpdate(this.value, 'lowercolor')" value="#<?php echo kubrick_lower_color(); ?>" /><br />
-					<input type="button" name="default" value="Select Default Colors" onclick="kDefaults()" /><br />
-					<input type="button" onclick="toggleDisplay();return false;" name="pick" id="pick" value="Toggle Text Display"></input><br />
-				</form>
-			</div>
-		</div>
-	</div>
-</div>
-<?php } ?>
+<?php
+if ( function_exists('register_sidebar') )
+    register_sidebar(array(
+        'before_widget' => '<li id="%1$s" class="widget %2$s">',
+        'after_widget' => '</li>',
+        'before_title' => '<h2 class="widgettitle">',
+        'after_title' => '</h2>',
+    ));
+
+function kubrick_head() {
+	$head = "<style type='text/css'>\n<!--";
+	$output = '';
+	if ( kubrick_header_image() ) {
+		$url =  kubrick_header_image_url() ;
+		$output .= "#header { background: url('$url') no-repeat bottom center; }\n";
+	}
+	if ( false !== ( $color = kubrick_header_color() ) ) {
+		$output .= "#headerimg h1 a, #headerimg h1 a:visited, #headerimg .description { color: $color; }\n";
+	}
+	if ( false !== ( $display = kubrick_header_display() ) ) {
+		$output .= "#headerimg { display: $display }\n";
+	}
+	$foot = "--></style>\n";
+	if ( '' != $output )
+		echo $head . $output . $foot;
+}
+
+add_action('wp_head', 'kubrick_head');
+
+function kubrick_header_image() {
+	return apply_filters('kubrick_header_image', get_option('kubrick_header_image'));
+}
+
+function kubrick_upper_color() {
+	if (strpos($url = kubrick_header_image_url(), 'header-img.php?') !== false) {
+		parse_str(substr($url, strpos($url, '?') + 1), $q);
+		return $q['upper'];
+	} else
+		return '69aee7';
+}
+
+function kubrick_lower_color() {
+	if (strpos($url = kubrick_header_image_url(), 'header-img.php?') !== false) {
+		parse_str(substr($url, strpos($url, '?') + 1), $q);
+		return $q['lower'];
+	} else
+		return '4180b6';
+}
+
+function kubrick_header_image_url() {
+	if ( $image = kubrick_header_image() )
+		$url = get_template_directory_uri() . '/images/' . $image;
+	else
+		$url = get_template_directory_uri() . '/images/kubrickheader.jpg';
+
+	return $url;
+}
+
+function kubrick_header_color() {
+	return apply_filters('kubrick_header_color', get_option('kubrick_header_color'));
+}
+
+function kubrick_header_color_string() {
+	$color = kubrick_header_color();
+	if ( false === $color )
+		return 'white';
+
+	return $color;
+}
+
+function kubrick_header_display() {
+	return apply_filters('kubrick_header_display', get_option('kubrick_header_display'));
+}
+
+function kubrick_header_display_string() {
+	$display = kubrick_header_display();
+	return $display ? $display : 'inline';
+}
+
+add_action('admin_menu', 'kubrick_add_theme_page');
+
+function kubrick_add_theme_page() {
+	if ( $_GET['page'] == basename(__FILE__) ) {
+		if ( 'save' == $_REQUEST['action'] ) {
+			check_admin_referer('kubrick-header');
+			if ( isset($_REQUEST['njform']) ) {
+				if ( isset($_REQUEST['defaults']) ) {
+					delete_option('kubrick_header_image');
+					delete_option('kubrick_header_color');
+					delete_option('kubrick_header_display');
+				} else {
+					if ( '' == $_REQUEST['njfontcolor'] )
+						delete_option('kubrick_header_color');
+					else {
+						$fontcolor = preg_replace('/^.*(#[0-9a-fA-F]{6})?.*$/', '$1', $_REQUEST['njfontcolor']);
+						update_option('kubrick_header_color', $fontcolor);
+					}
+					if ( preg_match('/[0-9A-F]{6}|[0-9A-F]{3}/i', $_REQUEST['njuppercolor'], $uc) && preg_match('/[0-9A-F]{6}|[0-9A-F]{3}/i', $_REQUEST['njlowercolor'], $lc) ) {
+						$uc = ( strlen($uc[0]) == 3 ) ? $uc[0]{0}.$uc[0]{0}.$uc[0]{1}.$uc[0]{1}.$uc[0]{2}.$uc[0]{2} : $uc[0];
+						$lc = ( strlen($lc[0]) == 3 ) ? $lc[0]{0}.$lc[0]{0}.$lc[0]{1}.$lc[0]{1}.$lc[0]{2}.$lc[0]{2} : $lc[0];
+						update_option('kubrick_header_image', "header-img.php?upper=$uc&lower=$lc");
+					}
+
+					if ( isset($_REQUEST['toggledisplay']) ) {
+						if ( false === get_option('kubrick_header_display') )
+							update_option('kubrick_header_display', 'none');
+						else
+							delete_option('kubrick_header_display');
+					}
+				}
+			} else {
+
+				if ( isset($_REQUEST['headerimage']) ) {
+					check_admin_referer('kubrick-header');
+					if ( '' == $_REQUEST['headerimage'] )
+						delete_option('kubrick_header_image');
+					else {
+						$headerimage = preg_replace('/^.*?(header-img.php\?upper=[0-9a-fA-F]{6}&lower=[0-9a-fA-F]{6})?.*$/', '$1', $_REQUEST['headerimage']);
+						update_option('kubrick_header_image', $headerimage);
+					}
+				}
+
+				if ( isset($_REQUEST['fontcolor']) ) {
+					check_admin_referer('kubrick-header');
+					if ( '' == $_REQUEST['fontcolor'] )
+						delete_option('kubrick_header_color');
+					else {
+						$fontcolor = preg_replace('/^.*?(#[0-9a-fA-F]{6})?.*$/', '$1', $_REQUEST['fontcolor']);
+						update_option('kubrick_header_color', $fontcolor);
+					}
+				}
+
+				if ( isset($_REQUEST['fontdisplay']) ) {
+					check_admin_referer('kubrick-header');
+					if ( '' == $_REQUEST['fontdisplay'] || 'inline' == $_REQUEST['fontdisplay'] )
+						delete_option('kubrick_header_display');
+					else
+						update_option('kubrick_header_display', 'none');
+				}
+			}
+			//print_r($_REQUEST);
+			wp_redirect("themes.php?page=functions.php&saved=true");
+			die;
+		}
+		add_action('admin_head', 'kubrick_theme_page_head');
+	}
+	add_theme_page(__('Customize Header'), __('Header Image and Color'), 'edit_themes', basename(__FILE__), 'kubrick_theme_page');
+}
+
+function kubrick_theme_page_head() {
+?>
+<script type="text/javascript" src="../wp-includes/js/colorpicker.js"></script>
+<script type='text/javascript'>
+// <![CDATA[
+	function pickColor(color) {
+		ColorPicker_targetInput.value = color;
+		kUpdate(ColorPicker_targetInput.id);
+	}
+	function PopupWindow_populate(contents) {
+		contents += '<br /><p style="text-align:center;margin-top:0px;"><input type="button" value="<?php echo attribute_escape(__('Close Color Picker')); ?>" onclick="cp.hidePopup(\'prettyplease\')"></input></p>';
+		this.contents = contents;
+		this.populated = false;
+	}
+	function PopupWindow_hidePopup(magicword) {
+		if ( magicword != 'prettyplease' )
+			return false;
+		if (this.divName != null) {
+			if (this.use_gebi) {
+				document.getElementById(this.divName).style.visibility = "hidden";
+			}
+			else if (this.use_css) {
+				document.all[this.divName].style.visibility = "hidden";
+			}
+			else if (this.use_layers) {
+				document.layers[this.divName].visibility = "hidden";
+			}
+		}
+		else {
+			if (this.popupWindow && !this.popupWindow.closed) {
+				this.popupWindow.close();
+				this.popupWindow = null;
+			}
+		}
+		return false;
+	}
+	function colorSelect(t,p) {
+		if ( cp.p == p && document.getElementById(cp.divName).style.visibility != "hidden" )
+			cp.hidePopup('prettyplease');
+		else {
+			cp.p = p;
+			cp.select(t,p);
+		}
+	}
+	function PopupWindow_setSize(width,height) {
+		this.width = 162;
+		this.height = 210;
+	}
+
+	var cp = new ColorPicker();
+	function advUpdate(val, obj) {
+		document.getElementById(obj).value = val;
+		kUpdate(obj);
+	}
+	function kUpdate(oid) {
+		if ( 'uppercolor' == oid || 'lowercolor' == oid ) {
+			uc = document.getElementById('uppercolor').value.replace('#', '');
+			lc = document.getElementById('lowercolor').value.replace('#', '');
+			hi = document.getElementById('headerimage');
+			hi.value = 'header-img.php?upper='+uc+'&lower='+lc;
+			document.getElementById('header').style.background = 'url("<?php echo get_template_directory_uri(); ?>/images/'+hi.value+'") center no-repeat';
+			document.getElementById('advuppercolor').value = '#'+uc;
+			document.getElementById('advlowercolor').value = '#'+lc;
+		}
+		if ( 'fontcolor' == oid ) {
+			document.getElementById('header').style.color = document.getElementById('fontcolor').value;
+			document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value;
+		}
+		if ( 'fontdisplay' == oid ) {
+			document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
+		}
+	}
+	function toggleDisplay() {
+		td = document.getElementById('fontdisplay');
+		td.value = ( td.value == 'none' ) ? 'inline' : 'none';
+		kUpdate('fontdisplay');
+	}
+	function toggleAdvanced() {
+		a = document.getElementById('jsAdvanced');
+		if ( a.style.display == 'none' )
+			a.style.display = 'block';
+		else
+			a.style.display = 'none';
+	}
+	function kDefaults() {
+		document.getElementById('headerimage').value = '';
+		document.getElementById('advuppercolor').value = document.getElementById('uppercolor').value = '#69aee7';
+		document.getElementById('advlowercolor').value = document.getElementById('lowercolor').value = '#4180b6';
+		document.getElementById('header').style.background = 'url("<?php echo get_template_directory_uri(); ?>/images/kubrickheader.jpg") center no-repeat';
+		document.getElementById('header').style.color = '#FFFFFF';
+		document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value = '';
+		document.getElementById('fontdisplay').value = 'inline';
+		document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
+	}
+	function kRevert() {
+		document.getElementById('headerimage').value = '<?php echo js_escape(kubrick_header_image()); ?>';
+		document.getElementById('advuppercolor').value = document.getElementById('uppercolor').value = '#<?php echo js_escape(kubrick_upper_color()); ?>';
+		document.getElementById('advlowercolor').value = document.getElementById('lowercolor').value = '#<?php echo js_escape(kubrick_lower_color()); ?>';
+		document.getElementById('header').style.background = 'url("<?php echo js_escape(kubrick_header_image_url()); ?>") center no-repeat';
+		document.getElementById('header').style.color = '';
+		document.getElementById('advfontcolor').value = document.getElementById('fontcolor').value = '<?php echo js_escape(kubrick_header_color_string()); ?>';
+		document.getElementById('fontdisplay').value = '<?php echo js_escape(kubrick_header_display_string()); ?>';
+		document.getElementById('headerimg').style.display = document.getElementById('fontdisplay').value;
+	}
+	function kInit() {
+		document.getElementById('jsForm').style.display = 'block';
+		document.getElementById('nonJsForm').style.display = 'none';
+	}
+	addLoadEvent(kInit);
+// ]]>
+</script>
+<style type='text/css'>
+	#headwrap {
+		text-align: center;
+	}
+	#kubrick-header {
+		font-size: 80%;
+	}
+	#kubrick-header .hibrowser {
+		width: 780px;
+		height: 260px;
+		overflow: scroll;
+	}
+	#kubrick-header #hitarget {
+		display: none;
+	}
+	#kubrick-header #header h1 {
+		font-family: 'Trebuchet MS', 'Lucida Grande', Verdana, Arial, Sans-Serif;
+		font-weight: bold;
+		font-size: 4em;
+		text-align: center;
+		padding-top: 70px;
+		margin: 0;
+	}
+
+	#kubrick-header #header .description {
+		font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif;
+		font-size: 1.2em;
+		text-align: center;
+	}
+	#kubrick-header #header {
+		text-decoration: none;
+		color: <?php echo kubrick_header_color_string(); ?>;
+		padding: 0;
+		margin: 0;
+		height: 200px;
+		text-align: center;
+		background: url('<?php echo kubrick_header_image_url(); ?>') center no-repeat;
+	}
+	#kubrick-header #headerimg {
+		margin: 0;
+		height: 200px;
+		width: 100%;
+		display: <?php echo kubrick_header_display_string(); ?>;
+	}
+	#jsForm {
+		display: none;
+		text-align: center;
+	}
+	#jsForm input.submit, #jsForm input.button, #jsAdvanced input.button {
+		padding: 0px;
+		margin: 0px;
+	}
+	#advanced {
+		text-align: center;
+		width: 620px;
+	}
+	html>body #advanced {
+		text-align: center;
+		position: relative;
+		left: 50%;
+		margin-left: -380px;
+	}
+	#jsAdvanced {
+		text-align: right;
+	}
+	#nonJsForm {
+		position: relative;
+		text-align: left;
+		margin-left: -370px;
+		left: 50%;
+	}
+	#nonJsForm label {
+		padding-top: 6px;
+		padding-right: 5px;
+		float: left;
+		width: 100px;
+		text-align: right;
+	}
+	.defbutton {
+		font-weight: bold;
+	}
+	.zerosize {
+		width: 0px;
+		height: 0px;
+		overflow: hidden;
+	}
+	#colorPickerDiv a, #colorPickerDiv a:hover {
+		padding: 1px;
+		text-decoration: none;
+		border-bottom: 0px;
+	}
+</style>
+<?php
+}
+
+function kubrick_theme_page() {
+	if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.__('Options saved.').'</strong></p></div>';
+?>
+<div class='wrap'>
+	<div id="kubrick-header">
+	<h2><?php _e('Header Image and Color'); ?></h2>
+		<div id="headwrap">
+			<div id="header">
+				<div id="headerimg">
+					<h1><?php bloginfo('name'); ?></h1>
+					<div class="description"><?php bloginfo('description'); ?></div>
+				</div>
+			</div>
+		</div>
+		<br />
+		<div id="nonJsForm">
+			<form method="post" action="">
+				<?php wp_nonce_field('kubrick-header'); ?>
+				<div class="zerosize"><input type="submit" name="defaultsubmit" value="<?php echo attribute_escape(__('Save')); ?>" /></div>
+					<label for="njfontcolor"><?php _e('Font Color:'); ?></label><input type="text" name="njfontcolor" id="njfontcolor" value="<?php echo attribute_escape(kubrick_header_color()); ?>" /> <?php printf(__('Any CSS color (%s or %s or %s)'), '<code>red</code>', '<code>#FF0000</code>', '<code>rgb(255, 0, 0)</code>'); ?><br />
+					<label for="njuppercolor"><?php _e('Upper Color:'); ?></label><input type="text" name="njuppercolor" id="njuppercolor" value="#<?php echo attribute_escape(kubrick_upper_color()); ?>" /> <?php printf(__('HEX only (%s or %s)'), '<code>#FF0000</code>', '<code>#F00</code>'); ?><br />
+				<label for="njlowercolor"><?php _e('Lower Color:'); ?></label><input type="text" name="njlowercolor" id="njlowercolor" value="#<?php echo attribute_escape(kubrick_lower_color()); ?>" /> <?php printf(__('HEX only (%s or %s)'), '<code>#FF0000</code>', '<code>#F00</code>'); ?><br />
+				<input type="hidden" name="hi" id="hi" value="<?php echo attribute_escape(kubrick_header_image()); ?>" />
+				<input type="submit" name="toggledisplay" id="toggledisplay" value="<?php echo attribute_escape(__('Toggle Text')); ?>" />
+				<input type="submit" name="defaults" value="<?php echo attribute_escape(__('Use Defaults')); ?>" />
+				<input type="submit" class="defbutton" name="submitform" value="&nbsp;&nbsp;<?php _e('Save'); ?>&nbsp;&nbsp;" />
+				<input type="hidden" name="action" value="save" />
+				<input type="hidden" name="njform" value="true" />
+			</form>
+		</div>
+		<div id="jsForm">
+			<form style="display:inline;" method="post" name="hicolor" id="hicolor" action="<?php echo attribute_escape($_SERVER['REQUEST_URI']); ?>">
+				<?php wp_nonce_field('kubrick-header'); ?>
+	<input type="button" onclick="tgt=document.getElementById('fontcolor');colorSelect(tgt,'pick1');return false;" name="pick1" id="pick1" value="<?php echo attribute_escape(__('Font Color')); ?>"></input>
+		<input type="button" onclick="tgt=document.getElementById('uppercolor');colorSelect(tgt,'pick2');return false;" name="pick2" id="pick2" value="<?php echo attribute_escape(__('Upper Color')); ?>"></input>
+		<input type="button" onclick="tgt=document.getElementById('lowercolor');colorSelect(tgt,'pick3');return false;" name="pick3" id="pick3" value="<?php echo attribute_escape(__('Lower Color')); ?>"></input>
+				<input type="button" name="revert" value="<?php echo attribute_escape(__('Revert')); ?>" onclick="kRevert()" />
+				<input type="button" value="<?php echo attribute_escape(__('Advanced')); ?>" onclick="toggleAdvanced()" />
+				<input type="hidden" name="action" value="save" />
+				<input type="hidden" name="fontdisplay" id="fontdisplay" value="<?php echo attribute_escape(kubrick_header_display()); ?>" />
+				<input type="hidden" name="fontcolor" id="fontcolor" value="<?php echo attribute_escape(kubrick_header_color()); ?>" />
+				<input type="hidden" name="uppercolor" id="uppercolor" value="<?php echo attribute_escape(kubrick_upper_color()); ?>" />
+				<input type="hidden" name="lowercolor" id="lowercolor" value="<?php echo attribute_escape(kubrick_lower_color()); ?>" />
+				<input type="hidden" name="headerimage" id="headerimage" value="<?php echo attribute_escape(kubrick_header_image()); ?>" />
+				<p class="submit"><input type="submit" name="submitform" class="defbutton" value="<?php echo attribute_escape(__('Update Header &raquo;')); ?>" onclick="cp.hidePopup('prettyplease')" /></p>
+			</form>
+			<div id="colorPickerDiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;visibility:hidden;"> </div>
+			<div id="advanced">
+				<form id="jsAdvanced" style="display:none;" action="">
+					<?php wp_nonce_field('kubrick-header'); ?>
+					<label for="advfontcolor"><?php _e('Font Color (CSS):'); ?> </label><input type="text" id="advfontcolor" onchange="advUpdate(this.value, 'fontcolor')" value="<?php echo attribute_escape(kubrick_header_color()); ?>" /><br />
+					<label for="advuppercolor"><?php _e('Upper Color (HEX):');?> </label><input type="text" id="advuppercolor" onchange="advUpdate(this.value, 'uppercolor')" value="#<?php echo attribute_escape(kubrick_upper_color()); ?>" /><br />
+					<label for="advlowercolor"><?php _e('Lower Color (HEX):'); ?> </label><input type="text" id="advlowercolor" onchange="advUpdate(this.value, 'lowercolor')" value="#<?php echo attribute_escape(kubrick_lower_color()); ?>" /><br />
+					<input type="button" name="default" value="<?php echo attribute_escape(__('Select Default Colors')); ?>" onclick="kDefaults()" /><br />
+					<input type="button" onclick="toggleDisplay();return false;" name="pick" id="pick" value="<?php echo attribute_escape(__('Toggle Text Display')); ?>"></input><br />
+				</form>
+			</div>
+		</div>
+	</div>
+</div>
+<?php } ?>
diff -ruN 2.0.5/wp-content/themes/default/header.php 2.2.2/wp-content/themes/default/header.php
--- 2.0.5/wp-content/themes/default/header.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/header.php	2007-03-19 14:08:15.000000000 -0500
@@ -1,5 +1,5 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
 
 <head profile="http://gmpg.org/xfn/11">
 <meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
@@ -14,13 +14,13 @@
 
 <style type="text/css" media="screen">
 
-<?php 
+<?php
 // Checks to see whether it needs a sidebar or not
-if ( !$withcomments && !is_single() ) { 
+if ( !$withcomments && !is_single() ) {
 ?>
-	#page { background: url("<?php bloginfo('stylesheet_directory'); ?>/images/kubrickbg.jpg") repeat-y top; border: none; }
+	#page { background: url("<?php bloginfo('stylesheet_directory'); ?>/images/kubrickbg-<?php bloginfo('text_direction'); ?>.jpg") repeat-y top; border: none; }
 <?php } else { // No sidebar ?>
-	#page { background: url("<?php bloginfo('stylesheet_directory'); ?>/images/kubrickbgwide.jpg") repeat-y top; border: none; } 
+	#page { background: url("<?php bloginfo('stylesheet_directory'); ?>/images/kubrickbgwide.jpg") repeat-y top; border: none; }
 <?php } ?>
 
 </style>
@@ -33,7 +33,7 @@
 
 <div id="header">
 	<div id="headerimg">
-		<h1><a href="<?php echo get_settings('home'); ?>/"><?php bloginfo('name'); ?></a></h1>
+		<h1><a href="<?php echo get_option('home'); ?>/"><?php bloginfo('name'); ?></a></h1>
 		<div class="description"><?php bloginfo('description'); ?></div>
 	</div>
 </div>
Binary files 2.0.5/wp-content/themes/default/images/kubrickbg-ltr.jpg and 2.2.2/wp-content/themes/default/images/kubrickbg-ltr.jpg differ
Binary files 2.0.5/wp-content/themes/default/images/kubrickbg-rtl.jpg and 2.2.2/wp-content/themes/default/images/kubrickbg-rtl.jpg differ
Binary files 2.0.5/wp-content/themes/default/images/kubrickbg.jpg and 2.2.2/wp-content/themes/default/images/kubrickbg.jpg differ
diff -ruN 2.0.5/wp-content/themes/default/page.php 2.2.2/wp-content/themes/default/page.php
--- 2.0.5/wp-content/themes/default/page.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/page.php	2006-11-19 01:56:05.000000000 -0600
@@ -2,17 +2,17 @@
 
 	<div id="content" class="narrowcolumn">
 
-    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
+		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 		<div class="post" id="post-<?php the_ID(); ?>">
 		<h2><?php the_title(); ?></h2>
 			<div class="entry">
 				<?php the_content('<p class="serif">Read the rest of this page &raquo;</p>'); ?>
 
-				<?php link_pages('<p><strong>Pages:</strong> ', '</p>', 'number'); ?>
+				<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
 
 			</div>
 		</div>
-	  <?php endwhile; endif; ?>
+		<?php endwhile; endif; ?>
 	<?php edit_post_link('Edit this entry.', '<p>', '</p>'); ?>
 	</div>
 
diff -ruN 2.0.5/wp-content/themes/default/rtl.css 2.2.2/wp-content/themes/default/rtl.css
--- 2.0.5/wp-content/themes/default/rtl.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-content/themes/default/rtl.css	2007-03-19 14:08:15.000000000 -0500
@@ -0,0 +1,63 @@
+/* Based on Arabic (RTL) version of Kubrick theme, converted by Serdal (Serdal.com) */
+
+.narrowcolumn, .alignleft, .widecolumn .smallattachment { float: right; }
+.alignright, #commentform #submit { float: left; }
+
+#page, #wp-calendar #prev a { text-align: right; }
+
+
+body, #commentform p { font-family: Tahoma, 'Lucida Grande', Verdana, Arial, Sans-Serif; }
+
+small { font-family: Tahoma, Arial, Helvetica, Sans-Serif; }
+
+.commentlist li, #commentform input, #commentform textarea { font: 0.9em Tahoma, 'Lucida Grande', Verdana, Arial, Sans-Serif; }
+
+#sidebar { font: 1em Tahoma, 'Lucida Grande', Verdana, Arial, Sans-Serif; }
+
+#wp-calendar caption { font: bold 1.3em Tahoma, 'Lucida Grande', Verdana, Arial, Sans-Serif; }
+
+#header { margin: 0 1px 0 0; }
+
+.narrowcolumn { padding: 0 45px 20px 0; }
+
+.widecolumn { margin: 5px 150px 0 0; }
+
+.widecolumn .smallattachment { margin: 5px 0px 5px 5px; }
+
+.postmetadata { clear: right; }
+
+img.alignright { margin: 0 7px 2px 0; }
+
+img.alignleft { margin: 0 0 2px 7px; }
+
+.entry ol { padding: 0 35px 0 0; }
+
+#sidebar ul ul, #sidebar ul ol { margin: 5px 10px 0 0; }
+
+#sidebar ul ul ul, #sidebar ul ol { margin: 0 10px 0 0; }
+
+#commentform input { margin: 5px 0 1px 5px; }
+
+.commentlist p { margin: 10px 0 10px 5px; }
+
+#sidebar { margin-right: 545px; }
+
+#wp-calendar #prev a, html>body .entry ul { padding-right: 10px; }
+
+html>body .entry li { margin: 7px 10px 8px 0; }
+
+html>body .entry ul {
+	margin-right: 0px;
+	padding: 0 30px 0 0;
+}
+
+blockquote {
+	margin: 15px 10px 0 30px;
+	padding-right: 20px;
+	border-right: 5px solid #ddd;
+}
+
+#wp-calendar #next a {
+	padding-left: 10px;
+	text-align: left;
+}
diff -ruN 2.0.5/wp-content/themes/default/searchform.php 2.2.2/wp-content/themes/default/searchform.php
--- 2.0.5/wp-content/themes/default/searchform.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/searchform.php	2007-03-06 21:05:41.000000000 -0600
@@ -1,5 +1,5 @@
-<form method="get" id="searchform" action="<?php bloginfo('home'); ?>/">
-<div><input type="text" value="<?php echo wp_specialchars($s, 1); ?>" name="s" id="s" />
+<form method="get" id="searchform" action="<?php bloginfo('url'); ?>/">
+<div><input type="text" value="<?php the_search_query(); ?>" name="s" id="s" />
 <input type="submit" id="searchsubmit" value="Search" />
 </div>
 </form>
diff -ruN 2.0.5/wp-content/themes/default/sidebar.php 2.2.2/wp-content/themes/default/sidebar.php
--- 2.0.5/wp-content/themes/default/sidebar.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/sidebar.php	2007-03-31 11:57:50.000000000 -0500
@@ -1,6 +1,7 @@
 	<div id="sidebar">
 		<ul>
-
+			<?php 	/* Widgetized sidebar, if you have the plugin installed. */
+					if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : ?>
 			<li>
 				<?php include (TEMPLATEPATH . '/searchform.php'); ?>
 			</li>
@@ -11,32 +12,36 @@
 			</li>
 			-->
 
-			<li>
+			<?php if ( is_404() || is_category() || is_day() || is_month() ||
+						is_year() || is_search() || is_paged() ) {
+			?> <li>
+
 			<?php /* If this is a 404 page */ if (is_404()) { ?>
 			<?php /* If this is a category archive */ } elseif (is_category()) { ?>
 			<p>You are currently browsing the archives for the <?php single_cat_title(''); ?> category.</p>
 
 			<?php /* If this is a yearly archive */ } elseif (is_day()) { ?>
-			<p>You are currently browsing the <a href="<?php bloginfo('home'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
+			<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
 			for the day <?php the_time('l, F jS, Y'); ?>.</p>
 
 			<?php /* If this is a monthly archive */ } elseif (is_month()) { ?>
-			<p>You are currently browsing the <a href="<?php bloginfo('home'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
+			<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
 			for <?php the_time('F, Y'); ?>.</p>
 
-      <?php /* If this is a yearly archive */ } elseif (is_year()) { ?>
-			<p>You are currently browsing the <a href="<?php bloginfo('home'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
+			<?php /* If this is a yearly archive */ } elseif (is_year()) { ?>
+			<p>You are currently browsing the <a href="<?php bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
 			for the year <?php the_time('Y'); ?>.</p>
 
-		 <?php /* If this is a monthly archive */ } elseif (is_search()) { ?>
-			<p>You have searched the <a href="<?php echo bloginfo('home'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
-			for <strong>'<?php echo wp_specialchars($s); ?>'</strong>. If you are unable to find anything in these search results, you can try one of these links.</p>
+			<?php /* If this is a monthly archive */ } elseif (is_search()) { ?>
+			<p>You have searched the <a href="<?php echo bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives
+			for <strong>'<?php the_search_query(); ?>'</strong>. If you are unable to find anything in these search results, you can try one of these links.</p>
 
 			<?php /* If this is a monthly archive */ } elseif (isset($_GET['paged']) && !empty($_GET['paged'])) { ?>
-			<p>You are currently browsing the <a href="<?php echo bloginfo('home'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives.</p>
+			<p>You are currently browsing the <a href="<?php echo bloginfo('url'); ?>/"><?php echo bloginfo('name'); ?></a> weblog archives.</p>
 
 			<?php } ?>
-			</li>
+				
+			</li> <?php }?>
 
 			<?php wp_list_pages('title_li=<h2>Pages</h2>' ); ?>
 
@@ -46,14 +51,10 @@
 				</ul>
 			</li>
 
-			<li><h2>Categories</h2>
-				<ul>
-				<?php wp_list_cats('sort_column=name&optioncount=1&hierarchical=0'); ?>
-				</ul>
-			</li>
+			<?php wp_list_categories('show_count=1&title_li=<h2>Categories</h2>'); ?>
 
 			<?php /* If this is the frontpage */ if ( is_home() || is_page() ) { ?>
-				<?php get_links_list(); ?>
+				<?php wp_list_bookmarks(); ?>
 
 				<li><h2>Meta</h2>
 				<ul>
@@ -66,7 +67,8 @@
 				</ul>
 				</li>
 			<?php } ?>
-
+			
+			<?php endif; ?>
 		</ul>
 	</div>
 
diff -ruN 2.0.5/wp-content/themes/default/single.php 2.2.2/wp-content/themes/default/single.php
--- 2.0.5/wp-content/themes/default/single.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/single.php	2007-04-19 17:26:52.000000000 -0500
@@ -2,7 +2,7 @@
 
 	<div id="content" class="widecolumn">
 
-  <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
+	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
 
 		<div class="navigation">
 			<div class="alignleft"><?php previous_post_link('&laquo; %link') ?></div>
@@ -15,7 +15,7 @@
 			<div class="entry">
 				<?php the_content('<p class="serif">Read the rest of this entry &raquo;</p>'); ?>
 
-				<?php link_pages('<p><strong>Pages:</strong> ', '</p>', 'number'); ?>
+				<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>
 
 				<p class="postmetadata alt">
 					<small>
@@ -23,10 +23,10 @@
 						<?php /* This is commented, because it requires a little adjusting sometimes.
 							You'll need to download this plugin, and follow the instructions:
 							http://binarybonsai.com/archives/2004/08/17/time-since-plugin/ */
-							/* $entry_datetime = abs(strtotime($post->post_date) - (60*120)); echo time_since($entry_datetime); echo ' ago'; */ ?> 
+							/* $entry_datetime = abs(strtotime($post->post_date) - (60*120)); echo time_since($entry_datetime); echo ' ago'; */ ?>
 						on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?>
 						and is filed under <?php the_category(', ') ?>.
-						You can follow any responses to this entry through the <?php comments_rss_link('RSS 2.0'); ?> feed. 
+						You can follow any responses to this entry through the <?php comments_rss_link('RSS 2.0'); ?> feed.
 
 						<?php if (('open' == $post-> comment_status) && ('open' == $post->ping_status)) {
 							// Both Comments and Pings are open ?>
diff -ruN 2.0.5/wp-content/themes/default/style.css 2.2.2/wp-content/themes/default/style.css
--- 2.0.5/wp-content/themes/default/style.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-content/themes/default/style.css	2006-12-01 06:09:35.000000000 -0600
@@ -186,7 +186,7 @@
 	text-decoration: underline;
 	}
 
-#wp-calendar #prev a {
+#wp-calendar #prev a, #wp-calendar #next a {
 	font-size: 9pt;
 	}
 
@@ -253,6 +253,10 @@
 	text-align: justify;
 	}
 
+.post hr {
+	display: block;
+	}
+
 .widecolumn .post {
 	margin: 0;
 	}
diff -ruN 2.0.5/wp-cron.php 2.2.2/wp-cron.php
--- 2.0.5/wp-cron.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-cron.php	2007-04-16 15:47:23.000000000 -0500
@@ -0,0 +1,35 @@
+<?php
+ignore_user_abort(true);
+define('DOING_CRON', TRUE);
+require_once('wp-config.php');
+
+if ( $_GET['check'] != wp_hash('187425') )
+	exit;
+
+if ( get_option('doing_cron') > time() )
+	exit;
+
+update_option('doing_cron', time() + 30);
+
+$crons = _get_cron_array();
+$keys = array_keys($crons);
+if (!is_array($crons) || $keys[0] > time())
+	return;
+foreach ($crons as $timestamp => $cronhooks) {
+	if ($timestamp > time()) break;
+	foreach ($cronhooks as $hook => $keys) {
+		foreach ($keys as $key => $args) {
+			$schedule = $args['schedule'];
+			if ($schedule != false) {
+				$new_args = array($timestamp, $schedule, $hook, $args['args']);
+				call_user_func_array('wp_reschedule_event', $new_args);
+			}
+			wp_unschedule_event($timestamp, $hook, $args['args']);
+ 			do_action_ref_array($hook, $args['args']);
+		}
+	}
+}
+
+update_option('doing_cron', 0);
+
+?>
diff -ruN 2.0.5/wp-feed.php 2.2.2/wp-feed.php
--- 2.0.5/wp-feed.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-feed.php	2006-11-19 01:56:05.000000000 -0600
@@ -1,37 +1,10 @@
 <?php
 
 if (empty($doing_rss)) {
-    $doing_rss = 1;
-    require(dirname(__FILE__) . '/wp-blog-header.php');
+	$doing_rss = 1;
+	require(dirname(__FILE__) . '/wp-blog-header.php');
 }
 
-// Remove the pad, if present.
-$feed = preg_replace('/^_+/', '', $feed);
-
-if ($feed == '' || $feed == 'feed') {
-    $feed = 'rss2';
-}
-
-if ( is_single() || ($withcomments == 1) ) {
-    require(ABSPATH . 'wp-commentsrss2.php');
-} else {
-    switch ($feed) {
-    case 'atom':
-        require(ABSPATH . 'wp-atom.php');
-        break;
-    case 'rdf':
-        require(ABSPATH . 'wp-rdf.php');
-        break;
-    case 'rss':
-        require(ABSPATH . 'wp-rss.php');
-        break;
-    case 'rss2':
-        require(ABSPATH . 'wp-rss2.php');
-        break;
-    case 'comments-rss2':
-        require(ABSPATH . 'wp-commentsrss2.php');
-        break;
-    }
-}
+do_feed();
 
 ?>
Binary files 2.0.5/wp-includes/.DS_Store and 2.2.2/wp-includes/.DS_Store differ
diff -ruN 2.0.5/wp-includes/author-template.php 2.2.2/wp-includes/author-template.php
--- 2.0.5/wp-includes/author-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/author-template.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,248 @@
+<?php
+
+function get_the_author($deprecated = '') {
+	global $authordata;
+	return apply_filters('the_author', $authordata->display_name);
+}
+
+// Using echo = false is deprecated.  Use get_the_author instead.
+function the_author($deprecated = '', $deprecated_echo = true) {
+	if ( $deprecated_echo )
+		echo get_the_author();
+	return get_the_author();
+}
+
+function get_the_author_description() {
+	global $authordata;
+	return $authordata->description;
+}
+function the_author_description() {
+	echo get_the_author_description();
+}
+
+function get_the_author_login() {
+	global $authordata;
+	return $authordata->user_login;
+}
+
+function the_author_login() {
+	echo get_the_author_login();
+}
+
+function get_the_author_firstname() {
+	global $authordata;
+	return $authordata->first_name;
+}
+function the_author_firstname() {
+	echo get_the_author_firstname();
+}
+
+function get_the_author_lastname() {
+	global $authordata;
+	return $authordata->last_name;
+}
+
+function the_author_lastname() {
+	echo get_the_author_lastname();
+}
+
+function get_the_author_nickname() {
+	global $authordata;
+	return $authordata->nickname;
+}
+
+function the_author_nickname() {
+	echo get_the_author_nickname();
+}
+
+function get_the_author_ID() {
+	global $authordata;
+	return $authordata->ID;
+}
+function the_author_ID() {
+	echo get_the_author_id();
+}
+
+function get_the_author_email() {
+	global $authordata;
+	return $authordata->user_email;
+}
+
+function the_author_email() {
+	echo apply_filters('the_author_email', get_the_author_email() );
+}
+
+function get_the_author_url() {
+	global $authordata;
+	return $authordata->user_url;
+}
+
+function the_author_url() {
+	echo get_the_author_url();
+}
+
+function the_author_link() {
+	if (get_the_author_url()) {
+		echo '<a href="' . get_the_author_url() . '" title="' . sprintf(__("Visit %s's website"), get_the_author()) . '" rel="external">' . get_the_author() . '</a>';
+	} else {
+		the_author();
+	}
+}
+
+function get_the_author_icq() {
+	global $authordata;
+	return $authordata->icq;
+}
+
+function the_author_icq() {
+	echo get_the_author_icq();
+}
+
+function get_the_author_aim() {
+	global $authordata;
+	return str_replace(' ', '+', $authordata->aim);
+}
+
+function the_author_aim() {
+	echo get_the_author_aim();
+}
+
+function get_the_author_yim() {
+	global $authordata;
+	return $authordata->yim;
+}
+
+function the_author_yim() {
+	echo get_the_author_yim();
+}
+
+function get_the_author_msn() {
+	global $authordata;
+	return $authordata->msn;
+}
+
+function the_author_msn() {
+	echo get_the_author_msn();
+}
+
+function get_the_author_posts() {
+	global $post;
+	$posts = get_usernumposts($post->post_author);
+	return $posts;
+}
+
+function the_author_posts() {
+	echo get_the_author_posts();
+}
+
+/* the_author_posts_link() requires no get_, use get_author_posts_url() */
+function the_author_posts_link($deprecated = '') {
+	global $authordata;
+
+	echo '<a href="' . get_author_posts_url($authordata->ID, $authordata->user_nicename) . '" title="' . sprintf(__("Posts by %s"), attribute_escape(get_the_author())) . '">' . get_the_author() . '</a>';
+}
+
+function get_author_posts_url($author_id, $author_nicename = '') {
+	global $wpdb, $wp_rewrite, $post, $cache_userdata;
+	$auth_ID = (int) $author_id;
+	$link = $wp_rewrite->get_author_permastruct();
+
+	if ( empty($link) ) {
+		$file = get_option('home') . '/';
+		$link = $file . '?author=' . $auth_ID;
+	} else {
+		if ( '' == $author_nicename ) {
+			$user = get_userdata($author_id);
+			if ( !empty($user->user_nicename) )
+				$author_nicename = $user->user_nicename;
+		}
+		$link = str_replace('%author%', $author_nicename, $link);
+		$link = get_option('home') . trailingslashit($link);
+	}
+
+	$link = apply_filters('author_link', $link, $author_id, $author_nicename);
+
+	return $link;
+}
+
+// Get author's preferred display name
+function get_author_name( $auth_id ) {
+	$authordata = get_userdata( $auth_id );
+
+	return $authordata->display_name;
+}
+
+function wp_list_authors($args = '') {
+	global $wpdb;
+	
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('optioncount' => false, 'exclude_admin' => true, 'show_fullname' => false, 'hide_empty' => true,
+		'feed' => '', 'feed_image' => '');
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+	
+	// TODO:  Move select to get_authors().
+	$authors = $wpdb->get_results("SELECT ID, user_nicename from $wpdb->users " . ($exclude_admin ? "WHERE user_login <> 'admin' " : '') . "ORDER BY display_name");
+	
+	$author_count = array();
+	foreach ((array) $wpdb->get_results("SELECT DISTINCT post_author, COUNT(ID) AS count FROM $wpdb->posts WHERE post_status = 'publish' GROUP BY post_author") as $row) {
+		$author_count[$row->post_author] = $row->count;
+	}
+
+	foreach ( (array) $authors as $author ) {
+		$author = get_userdata( $author->ID );
+		$posts = (isset($author_count[$author->ID])) ? $author_count[$author->ID] : 0;
+		$name = $author->nickname;
+
+		if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
+			$name = "$author->first_name $author->last_name";
+
+		if ( !($posts == 0 && $hide_empty) )
+			echo "<li>";
+		if ( $posts == 0 ) {
+			if ( !$hide_empty )
+				$link = $name;
+		} else {
+			$link = '<a href="' . get_author_posts_url($author->ID, $author->user_nicename) . '" title="' . sprintf(__("Posts by %s"), attribute_escape($author->display_name)) . '">' . $name . '</a>';
+
+			if ( (! empty($feed_image)) || (! empty($feed)) ) {
+				$link .= ' ';
+				if (empty($feed_image))
+					$link .= '(';
+				$link .= '<a href="' . get_author_rss_link(0, $author->ID, $author->user_nicename) . '"';
+
+				if ( !empty($feed) ) {
+					$title = ' title="' . $feed . '"';
+					$alt = ' alt="' . $feed . '"';
+					$name = $feed;
+					$link .= $title;
+				}
+
+				$link .= '>';
+
+				if ( !empty($feed_image) )
+					$link .= "<img src=\"$feed_image\" border=\"0\"$alt$title" . ' />';
+				else
+					$link .= $name;
+
+				$link .= '</a>';
+
+				if ( empty($feed_image) )
+					$link .= ')';
+			}
+
+			if ( $optioncount )
+				$link .= ' ('. $posts . ')';
+
+		}
+
+		if ( !($posts == 0 && $hide_empty) )
+			echo "$link</li>";
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/bookmark-template.php 2.2.2/wp-includes/bookmark-template.php
--- 2.0.5/wp-includes/bookmark-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/bookmark-template.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,374 @@
+<?php
+
+/** function wp_get_links()
+ ** Gets the links associated with category n.
+ ** Parameters:
+ **   category (no default)  - The category to use.
+ ** or:
+ **   a query string
+ **/
+function wp_get_links($args = '') {
+	global $wpdb;
+
+	if ( empty($args) )
+		return;
+
+	if ( false === strpos($args, '=') ) {
+		$cat_id = $args;
+		$args = add_query_arg('category', $cat_id, $args);
+	}
+
+	parse_str($args);
+
+	if ( !isset($category) )         $category = -1;
+	if ( !isset($before) )           $before = '';
+	if ( !isset($after) )            $after = '<br />';
+	if ( !isset($between) )          $between = ' ';
+	if ( !isset($show_images) )      $show_images = true;
+	if ( !isset($orderby) )          $orderby = 'name';
+	if ( !isset($show_description) ) $show_description = true;
+	if ( !isset($show_rating) )      $show_rating = false;
+	if ( !isset($limit) )            $limit = -1;
+	if ( !isset($show_updated) )     $show_updated = 1;
+	if ( !isset($echo) )             $echo = true;
+
+	return get_links($category, $before, $after, $between, $show_images, $orderby, $show_description, $show_rating, $limit, $show_updated, $echo);
+} // end wp_get_links
+
+/** function get_links()
+ ** Gets the links associated with category n.
+ ** Parameters:
+ **   category (default -1)  - The category to use. If no category supplied
+ **      uses all
+ **   before (default '')  - the html to output before the link
+ **   after (default '<br />')  - the html to output after the link
+ **   between (default ' ')  - the html to output between the link/image
+ **     and its description. Not used if no image or show_images == true
+ **   show_images (default true) - whether to show images (if defined).
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url', 'description', or 'rating'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   show_description (default true) - whether to show the description if
+ **    show_images=false/not defined .
+ **   show_rating (default false) - show rating stars/chars
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **   show_updated (default 0) - whether to show last updated timestamp
+ **   echo (default true) - whether to echo the results, or return them instead
+ */
+function get_links($category = -1,
+			$before = '',
+			$after = '<br />',
+			$between = ' ',
+			$show_images = true,
+			$orderby = 'name',
+			$show_description = true,
+			$show_rating = false,
+			$limit = -1,
+			$show_updated = 1,
+			$echo = true) {
+
+	global $wpdb;
+
+	$order = 'ASC';
+	if ( substr($orderby, 0, 1) == '_' ) {
+		$order = 'DESC';
+		$orderby = substr($orderby, 1);
+	}
+
+	if ( $category == -1 ) //get_bookmarks uses '' to signify all categories
+		$category = '';
+
+	$results = get_bookmarks("category=$category&orderby=$orderby&order=$order&show_updated=$show_updated&limit=$limit");
+
+	if ( !$results )
+		return;
+
+	$output = '';
+
+	foreach ( (array) $results as $row ) {
+		if ( !isset($row->recently_updated) )
+			$row->recently_updated = false;
+		$output .= $before;
+		if ( $show_updated && $row->recently_updated )
+			$output .= get_option('links_recently_updated_prepend');
+		$the_link = '#';
+		if ( !empty($row->link_url) )
+			$the_link = clean_url($row->link_url);
+		$rel = $row->link_rel;
+		if ( '' != $rel )
+			$rel = ' rel="' . $rel . '"';
+
+		$desc = attribute_escape($row->link_description);
+		$name = attribute_escape($row->link_name);
+		$title = $desc;
+
+		if ( $show_updated )
+			if (substr($row->link_updated_f, 0, 2) != '00')
+				$title .= ' ('.__('Last updated') . ' ' . date(get_option('links_updated_date_format'), $row->link_updated_f + (get_option('gmt_offset') * 3600)) . ')';
+
+		if ( '' != $title )
+			$title = ' title="' . $title . '"';
+
+		$alt = ' alt="' . $name . '"';
+
+		$target = $row->link_target;
+		if ( '' != $target )
+			$target = ' target="' . $target . '"';
+
+		$output .= '<a href="' . $the_link . '"' . $rel . $title . $target. '>';
+
+		if ( $row->link_image != null && $show_images ) {
+			if ( strpos($row->link_image, 'http') !== false )
+				$output .= "<img src=\"$row->link_image\" $alt $title />";
+			else // If it's a relative path
+				$output .= "<img src=\"" . get_option('siteurl') . "$row->link_image\" $alt $title />";
+		} else {
+			$output .= $name;
+		}
+
+		$output .= '</a>';
+
+		if ( $show_updated && $row->recently_updated )
+			$output .= get_option('links_recently_updated_append');
+
+		if ( $show_description && '' != $desc )
+			$output .= $between . $desc;
+		
+		if ($show_rating) {
+			$output .= $between . get_linkrating($row);
+		}
+
+		$output .= "$after\n";
+	} // end while
+
+	if ( !$echo )
+		return $output;
+	echo $output;
+}
+
+function get_linkrating($link) {
+	return apply_filters('link_rating', $link->link_rating);
+}
+
+/** function get_linkcatname()
+ ** Gets the name of category n.
+ ** Parameters: id (default 0)  - The category to get. If no category supplied
+ **                uses 0
+ */
+function get_linkcatname($id = 0) {
+	$id = (int) $id;
+
+	if ( empty($id) )
+		return '';
+
+	$cats = wp_get_link_cats($id);
+
+	if ( empty($cats) || ! is_array($cats) )
+		return '';
+
+	$cat_id = (int) $cats[0]; // Take the first cat.
+
+	$cat = get_category($cat_id);
+	return $cat->cat_name;
+}
+
+/** function links_popup_script()
+ ** This function contributed by Fullo -- http://sprite.csr.unibo.it/fullo/
+ ** Show the link to the links popup and the number of links
+ ** Parameters:
+ **   text (default Links)  - the text of the link
+ **   width (default 400)  - the width of the popup window
+ **   height (default 400)  - the height of the popup window
+ **   file (default linkspopup.php) - the page to open in the popup window
+ **   count (default true) - the number of links in the db
+ */
+function links_popup_script($text = 'Links', $width=400, $height=400, $file='links.all.php', $count = true) {
+	if ( $count )
+		$counts = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->links");
+
+	$javascript = "<a href=\"#\" onclick=\"javascript:window.open('$file?popup=1', '_blank', 'width=$width,height=$height,scrollbars=yes,status=no'); return false\">";
+	$javascript .= $text;
+
+	if ( $count )
+		$javascript .= " ($counts)";
+
+	$javascript .= "</a>\n\n";
+		echo $javascript;
+}
+
+
+/*
+ * function get_links_list()
+ *
+ * added by Dougal
+ *
+ * Output a list of all links, listed by category, using the
+ * settings in $wpdb->linkcategories and output it as a nested
+ * HTML unordered list.
+ *
+ * Parameters:
+ *   order (default 'name')  - Sort link categories by 'name' or 'id'
+ *   hide_if_empty (default true)  - Supress listing empty link categories
+ */
+function get_links_list($order = 'name', $hide_if_empty = 'obsolete') {
+	$order = strtolower($order);
+
+	// Handle link category sorting
+	$direction = 'ASC';
+	if ( '_' == substr($order,0,1) ) {
+		$direction = 'DESC';
+		$order = substr($order,1);
+	}
+
+	if ( !isset($direction) )
+		$direction = '';
+
+	$cats = get_categories("type=link&orderby=$order&order=$direction&hierarchical=0");
+
+	// Display each category
+	if ( $cats ) {
+		foreach ( (array) $cats as $cat ) {
+			// Handle each category.
+
+			// Display the category name
+			echo '	<li id="linkcat-' . $cat->cat_ID . '" class="linkcat"><h2>' . $cat->cat_name . "</h2>\n\t<ul>\n";
+			// Call get_links() with all the appropriate params
+			get_links($cat->cat_ID, '<li>', "</li>", "\n", true, 'name', false);
+
+			// Close the last category
+			echo "\n\t</ul>\n</li>\n";
+		}
+	}
+}
+
+function _walk_bookmarks($bookmarks, $args = '' ) {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('show_updated' => 0, 'show_description' => 0, 'show_images' => 1, 'before' => '<li>',
+		'after' => '</li>', 'between' => "\n");
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	foreach ( (array) $bookmarks as $bookmark ) {
+		if ( !isset($bookmark->recently_updated) )
+			$bookmark->recently_updated = false;
+		$output .= $before;
+		if ( $show_updated && $bookmark->recently_updated )
+			$output .= get_option('links_recently_updated_prepend');
+
+		$the_link = '#';
+		if ( !empty($bookmark->link_url) )
+			$the_link = clean_url($bookmark->link_url);
+
+		$rel = $bookmark->link_rel;
+		if ( '' != $rel )
+			$rel = ' rel="' . $rel . '"';
+
+		$desc = attribute_escape(apply_filters('link_description', $bookmark->link_description)); 
+ 		$name = attribute_escape(apply_filters('link_title', $bookmark->link_name)); 
+ 		$title = $desc;
+
+		if ( $show_updated )
+			if ( '00' != substr($bookmark->link_updated_f, 0, 2) ) {
+				$title .= ' ';
+				$title .= sprintf(__('Last updated: %s'), date(get_option('links_updated_date_format'), $bookmark->link_updated_f + (get_option('gmt_offset') * 3600)));
+				$title .= ')';
+			}
+
+		if ( '' != $title )
+			$title = ' title="' . $title . '"';
+
+		$alt = ' alt="' . $name . '"';
+
+		$target = $bookmark->link_target;
+		if ( '' != $target )
+			$target = ' target="' . $target . '"';
+
+		$output .= '<a href="' . $the_link . '"' . $rel . $title . $target. '>';
+
+		if ( $bookmark->link_image != null && $show_images ) {
+			if ( strpos($bookmark->link_image, 'http') !== false )
+				$output .= "<img src=\"$bookmark->link_image\" $alt $title />";
+			else // If it's a relative path
+				$output .= "<img src=\"" . get_option('siteurl') . "$bookmark->link_image\" $alt $title />";
+		} else {
+			$output .= $name;
+		}
+
+		$output .= '</a>';
+
+		if ( $show_updated && $bookmark->recently_updated )
+			$output .= get_option('links_recently_updated_append');
+
+		if ( $show_description && '' != $desc )
+			$output .= $between . $desc;
+		
+		if ($show_rating) {
+			$output .= $between . get_linkrating($bookmark);
+		}
+		
+		$output .= "$after\n";
+	} // end while
+
+	return $output;
+}
+
+function wp_list_bookmarks($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '',
+		'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'echo' => 1,
+		'categorize' => 1, 'title_li' => __('Bookmarks'), 'title_before' => '<h2>', 'title_after' => '</h2>',
+		'category_orderby' => 'name', 'category_order' => 'ASC', 'class' => 'linkcat',
+		'category_before' => '<li id="%id" class="%class">', 'category_after' => '</li>');
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	$output = '';
+
+	if ( $categorize ) {
+		//Split the bookmarks into ul's for each category
+		$cats = get_categories("type=link&category_name=$category_name&include=$category&orderby=$category_orderby&order=$category_order&hierarchical=0");
+
+		foreach ( (array) $cats as $cat ) {
+			$params = array_merge($r, array('category'=>$cat->cat_ID));
+			$bookmarks = get_bookmarks($params);
+			if ( empty($bookmarks) )
+				continue;
+			$output .= str_replace(array('%id', '%class'), array("linkcat-$cat->cat_ID", $class), $category_before);
+			$catname = apply_filters( "link_category", $cat->cat_name );
+			$output .= "$title_before$catname$title_after\n\t<ul>\n";
+			$output .= _walk_bookmarks($bookmarks, $r);
+			$output .= "\n\t</ul>\n$category_after\n";
+		}
+	} else {
+		//output one single list using title_li for the title
+		$bookmarks = get_bookmarks($r);
+
+		if ( !empty($bookmarks) ) {
+			if ( !empty( $title_li ) ){
+				$output .= str_replace(array('%id', '%class'), array("linkcat-$category", $class), $category_before);
+				$output .= "$title_before$title_li$title_after\n\t<ul>\n";
+				$output .= _walk_bookmarks($bookmarks, $r);
+				$output .= "\n\t</ul>\n$category_after\n";
+			} else {
+				$output .= _walk_bookmarks($bookmarks, $r);
+			}
+		}
+	}
+
+	if ( !$echo )
+		return $output;
+	echo $output;
+}
+
+?>
diff -ruN 2.0.5/wp-includes/bookmark.php 2.2.2/wp-includes/bookmark.php
--- 2.0.5/wp-includes/bookmark.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/bookmark.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,151 @@
+<?php
+
+function get_bookmark($bookmark_id, $output = OBJECT) {
+	global $wpdb;
+
+	$bookmark_id = (int) $bookmark_id;
+	$link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = '$bookmark_id'");
+	$link->link_category = wp_get_link_cats($bookmark_id);
+
+	if ( $output == OBJECT ) {
+		return $link;
+	} elseif ( $output == ARRAY_A ) {
+		return get_object_vars($link);
+	} elseif ( $output == ARRAY_N ) {
+		return array_values(get_object_vars($link));
+	} else {
+		return $link;
+	}
+}
+
+// Deprecate
+function get_link($bookmark_id, $output = OBJECT) {
+	return get_bookmark($bookmark_id, $output);
+}
+
+function get_bookmarks($args = '') {
+	global $wpdb;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '',
+		'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'include' => '', 'exclude' => '');
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	$key = md5( serialize( $r ) );
+	if ( $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ) )
+		if ( isset( $cache[ $key ] ) )
+			return apply_filters('get_bookmarks', $cache[ $key ], $r );
+
+	$inclusions = '';
+	if ( !empty($include) ) {
+	$exclude = '';  //ignore exclude, category, and category_name params if using include
+	$category = '';
+	$category_name = '';
+		$inclinks = preg_split('/[\s,]+/',$include);
+		if ( count($inclinks) ) {
+			foreach ( $inclinks as $inclink ) {
+				if (empty($inclusions))
+					$inclusions = ' AND ( link_id = ' . intval($inclink) . ' ';
+				else
+					$inclusions .= ' OR link_id = ' . intval($inclink) . ' ';
+			}
+		}
+	}
+	if (!empty($inclusions))
+		$inclusions .= ')';
+
+	$exclusions = '';
+	if ( !empty($exclude) ) {
+		$exlinks = preg_split('/[\s,]+/',$exclude);
+		if ( count($exlinks) ) {
+			foreach ( $exlinks as $exlink ) {
+				if (empty($exclusions))
+					$exclusions = ' AND ( link_id <> ' . intval($exlink) . ' ';
+				else
+					$exclusions .= ' AND link_id <> ' . intval($exlink) . ' ';
+			}
+		}
+	}
+	if (!empty($exclusions))
+		$exclusions .= ')';
+
+	if ( ! empty($category_name) ) {
+		if ( $cat_id = $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE cat_name='$category_name' LIMIT 1") )
+			$category = $cat_id;
+	}
+
+	$category_query = '';
+	$join = '';
+	if ( !empty($category) ) {
+		$incategories = preg_split('/[\s,]+/',$category);
+		if ( count($incategories) ) {
+			foreach ( $incategories as $incat ) {
+				if (empty($category_query))
+					$category_query = ' AND ( category_id = ' . intval($incat) . ' ';
+				else
+					$category_query .= ' OR category_id = ' . intval($incat) . ' ';
+			}
+		}
+	}
+	if (!empty($category_query)) {
+		$category_query .= ')';
+		$join = " LEFT JOIN $wpdb->link2cat ON ($wpdb->links.link_id = $wpdb->link2cat.link_id) ";
+	}
+
+	if (get_option('links_recently_updated_time')) {
+		$recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL " . get_option('links_recently_updated_time') . " MINUTE) >= NOW(), 1,0) as recently_updated ";
+	} else {
+		$recently_updated_test = '';
+	}
+
+	if ($show_updated) {
+		$get_updated = ", UNIX_TIMESTAMP(link_updated) AS link_updated_f ";
+	}
+
+	$orderby = strtolower($orderby);
+	$length = '';
+	switch ($orderby) {
+		case 'length':
+			$length = ", CHAR_LENGTH(link_name) AS length";
+			break;
+		case 'rand':
+			$orderby = 'rand()';
+			break;
+		default:
+			$orderby = "link_" . $orderby;
+	}
+
+	if ( 'link_id' == $orderby )
+		$orderby = "$wpdb->links.link_id";
+
+	$visible = '';
+	if ( $hide_invisible )
+		$visible = "AND link_visible = 'Y'";
+
+	$query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query";
+	$query .= " $exclusions $inclusions";
+	$query .= " ORDER BY $orderby $order";
+	if ($limit != -1)
+		$query .= " LIMIT $limit";
+
+	$results = $wpdb->get_results($query);
+
+	$cache[ $key ] = $results;
+	wp_cache_add( 'get_bookmarks', $cache, 'bookmark' );
+
+	return apply_filters('get_bookmarks', $results, $r);
+}
+
+function delete_get_bookmark_cache() {
+	wp_cache_delete( 'get_bookmarks', 'bookmark' );
+}
+add_action( 'add_link', 'delete_get_bookmark_cache' );
+add_action( 'edit_link', 'delete_get_bookmark_cache' );
+add_action( 'delete_link', 'delete_get_bookmark_cache' );
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/cache.php 2.2.2/wp-includes/cache.php
--- 2.0.5/wp-includes/cache.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/cache.php	2007-04-12 11:31:47.000000000 -0500
@@ -1,6 +1,7 @@
 <?php
 function wp_cache_add($key, $data, $flag = '', $expire = 0) {
 	global $wp_object_cache;
+	$data = unserialize(serialize($data));
 
 	return $wp_object_cache->add($key, $data, $flag, $expire);
 }
@@ -8,6 +9,8 @@
 function wp_cache_close() {
 	global $wp_object_cache;
 
+	if ( ! isset($wp_object_cache) )
+		return;
 	return $wp_object_cache->save();
 }
 
@@ -30,19 +33,19 @@
 }
 
 function wp_cache_init() {
-	global $wp_object_cache;
-
-	$wp_object_cache = new WP_Object_Cache();
+	$GLOBALS['wp_object_cache'] =& new WP_Object_Cache();
 }
 
 function wp_cache_replace($key, $data, $flag = '', $expire = 0) {
 	global $wp_object_cache;
+	$data = unserialize(serialize($data));
 
 	return $wp_object_cache->replace($key, $data, $flag, $expire);
 }
 
 function wp_cache_set($key, $data, $flag = '', $expire = 0) {
 	global $wp_object_cache;
+	$data = unserialize(serialize($data));
 
 	return $wp_object_cache->set($key, $data, $flag, $expire);
 }
@@ -67,7 +70,7 @@
 	var $secret = '';
 
 	function acquire_lock() {
-		// Acquire a write lock. 
+		// Acquire a write lock.
 		$this->mutex = @fopen($this->cache_dir.$this->flock_filename, 'w');
 		if ( false == $this->mutex)
 			return false;
@@ -109,7 +112,7 @@
 		$this->cache = array ();
 		$this->dirty_objects = array ();
 		$this->non_existant_objects = array ();
-		
+
 		$this->release_lock();
 
 		return true;
@@ -190,32 +193,9 @@
 			if ($dogs = $wpdb->get_results("SELECT * FROM $wpdb->categories")) {
 				foreach ($dogs as $catt)
 					$this->cache['category'][$catt->cat_ID] = $catt;
-
-				foreach ($this->cache['category'] as $catt) {
-					$curcat = $catt->cat_ID;
-					$fullpath = '/'.$this->cache['category'][$catt->cat_ID]->category_nicename;
-					while ($this->cache['category'][$curcat]->category_parent != 0) {
-						$curcat = $this->cache['category'][$curcat]->category_parent;
-						$fullpath = '/'.$this->cache['category'][$curcat]->category_nicename.$fullpath;
-					}
-					$this->cache['category'][$catt->cat_ID]->fullpath = $fullpath;
-				}
 			}
-		} else
-			if ('options' == $group) {
-				$wpdb->hide_errors();
-				if (!$options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'")) {
-					$options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options");
-				}
-				$wpdb->show_errors();
-
-				if ( ! $options )
-					return;
+		}
 
-				foreach ($options as $option) {
-					$this->cache['options'][$option->option_name] = $option->option_value;
-				}
-			}
 	}
 
 	function make_group_dir($group, $perms) {
@@ -249,15 +229,15 @@
 		while ($index < count($stack)) {
 			# Get indexed directory from stack
 			$dir = $stack[$index];
-      
+
 			$dh = @ opendir($dir);
 			if (!$dh)
 				return false;
-      
+
 			while (($file = @ readdir($dh)) !== false) {
 				if ($file == '.' or $file == '..')
 					continue;
-					
+
 				if (@ is_dir($dir . DIRECTORY_SEPARATOR . $file))
 					$stack[] = $dir . DIRECTORY_SEPARATOR . $file;
 				else if (@ is_file($dir . DIRECTORY_SEPARATOR . $file))
@@ -360,10 +340,9 @@
 				fputs($fd, $serial);
 				fclose($fd);
 				if (!@ rename($temp_file, $cache_file)) {
-					if (@ copy($temp_file, $cache_file))
-						@ unlink($temp_file);
-					else
-						$errors++;	
+					if (!@ copy($temp_file, $cache_file))
+						$errors++;
+					@ unlink($temp_file);
 				}
 				@ chmod($cache_file, $file_perms);
 			}
@@ -372,7 +351,7 @@
 		$this->dirty_objects = array();
 
 		$this->release_lock();
-		
+
 		if ( $errors )
 			return false;
 
@@ -404,8 +383,14 @@
 	}
 
 	function WP_Object_Cache() {
+		return $this->__construct();
+	}
+
+	function __construct() {
 		global $blog_id;
 
+		register_shutdown_function(array(&$this, "__destruct"));
+
 		if (defined('DISABLE_CACHE'))
 			return;
 
@@ -440,5 +425,10 @@
 
 		$this->blog_id = $this->hash($blog_id);
 	}
+
+	function __destruct() {
+		$this->save();
+		return true;
+	}
 }
 ?>
diff -ruN 2.0.5/wp-includes/capabilities.php 2.2.2/wp-includes/capabilities.php
--- 2.0.5/wp-includes/capabilities.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/capabilities.php	2007-01-28 15:58:01.000000000 -0600
@@ -6,16 +6,28 @@
 	var $role_objects = array();
 	var $role_names = array();
 	var $role_key;
+	var $use_db = true;
 
 	function WP_Roles() {
-		global $table_prefix;
-		$this->role_key = $table_prefix . 'user_roles';
+		$this->_init();
+	}
 
-		$this->roles = get_option($this->role_key);
+	function _init () {
+		global $wpdb;
+		global $wp_user_roles;
+		$this->role_key = $wpdb->prefix . 'user_roles';
+		if ( ! empty($wp_user_roles) ) {
+			$this->roles = $wp_user_roles;
+			$this->use_db = false;
+		} else {
+			$this->roles = get_option($this->role_key);
+		}
 
 		if ( empty($this->roles) )
 			return;
 
+		$this->role_objects = array();
+		$this->role_names =  array();
 		foreach ($this->roles as $role => $data) {
 			$this->role_objects[$role] = new WP_Role($role, $this->roles[$role]['capabilities']);
 			$this->role_names[$role] = $this->roles[$role]['name'];
@@ -29,31 +41,35 @@
 		$this->roles[$role] = array(
 			'name' => $display_name,
 			'capabilities' => $capabilities);
-		update_option($this->role_key, $this->roles);
+		if ( $this->use_db )
+			update_option($this->role_key, $this->roles);
 		$this->role_objects[$role] = new WP_Role($role, $capabilities);
 		$this->role_names[$role] = $display_name;
 		return $this->role_objects[$role];
 	}
-	
+
 	function remove_role($role) {
 		if ( ! isset($this->role_objects[$role]) )
 			return;
-		
+
 		unset($this->role_objects[$role]);
 		unset($this->role_names[$role]);
 		unset($this->roles[$role]);
-		
-		update_option($this->role_key, $this->roles);
+
+		if ( $this->use_db )
+			update_option($this->role_key, $this->roles);
 	}
 
 	function add_cap($role, $cap, $grant = true) {
 		$this->roles[$role]['capabilities'][$cap] = $grant;
-		update_option($this->role_key, $this->roles);
+		if ( $this->use_db )
+			update_option($this->role_key, $this->roles);
 	}
 
 	function remove_cap($role, $cap) {
 		unset($this->roles[$role]['capabilities'][$cap]);
-		update_option($this->role_key, $this->roles);
+		if ( $this->use_db )
+			update_option($this->role_key, $this->roles);
 	}
 
 	function &get_role($role) {
@@ -70,7 +86,7 @@
 	function is_role($role)
 	{
 		return isset($this->role_names[$role]);
-	}	
+	}
 }
 
 class WP_Role {
@@ -114,14 +130,15 @@
 
 class WP_User {
 	var $data;
-	var $id = 0;
+	var $ID = 0;
+	var $id = 0; // Deprecated, use $ID instead.
 	var $caps = array();
 	var $cap_key;
 	var $roles = array();
 	var $allcaps = array();
 
 	function WP_User($id, $name = '') {
-		global $table_prefix;
+		global $wpdb;
 
 		if ( empty($id) && empty($name) )
 			return;
@@ -144,16 +161,21 @@
 		}
 
 		$this->id = $this->ID;
-		$this->cap_key = $table_prefix . 'capabilities';
+		$this->_init_caps();
+	}
+
+	function _init_caps() {
+		global $wpdb;
+		$this->cap_key = $wpdb->prefix . 'capabilities';
 		$this->caps = &$this->{$this->cap_key};
 		if ( ! is_array($this->caps) )
 			$this->caps = array();
 		$this->get_role_caps();
 	}
-	
+
 	function get_role_caps() {
 		global $wp_roles;
-		
+
 		if ( ! isset($wp_roles) )
 			$wp_roles = new WP_Roles();
 
@@ -163,72 +185,84 @@
 
 		//Build $allcaps from role caps, overlay user's $caps
 		$this->allcaps = array();
-		foreach($this->roles as $role) {
+		foreach( (array) $this->roles as $role) {
 			$role = $wp_roles->get_role($role);
 			$this->allcaps = array_merge($this->allcaps, $role->capabilities);
 		}
 		$this->allcaps = array_merge($this->allcaps, $this->caps);
 	}
-	
+
 	function add_role($role) {
 		$this->caps[$role] = true;
-		update_usermeta($this->id, $this->cap_key, $this->caps);
+		update_usermeta($this->ID, $this->cap_key, $this->caps);
 		$this->get_role_caps();
 		$this->update_user_level_from_caps();
 	}
-	
+
 	function remove_role($role) {
 		if ( empty($this->roles[$role]) || (count($this->roles) <= 1) )
 			return;
 		unset($this->caps[$role]);
-		update_usermeta($this->id, $this->cap_key, $this->caps);
+		update_usermeta($this->ID, $this->cap_key, $this->caps);
 		$this->get_role_caps();
 	}
-	
+
 	function set_role($role) {
-		foreach($this->roles as $oldrole) 
+		foreach($this->roles as $oldrole)
 			unset($this->caps[$oldrole]);
-		$this->caps[$role] = true;
-		$this->roles = array($role => true);
-		update_usermeta($this->id, $this->cap_key, $this->caps);
+		if ( !empty($role) ) {
+			$this->caps[$role] = true;
+			$this->roles = array($role => true);
+		} else {
+			$this->roles = false;
+		}
+		update_usermeta($this->ID, $this->cap_key, $this->caps);
 		$this->get_role_caps();
 		$this->update_user_level_from_caps();
 	}
 
 	function level_reduction($max, $item) {
-	    if(preg_match('/^level_(10|[0-9])$/i', $item, $matches)) {
-	        $level = intval($matches[1]);
-	        return max($max, $level);
-	    } else {
-	        return $max;
-	    }
+		if(preg_match('/^level_(10|[0-9])$/i', $item, $matches)) {
+			$level = intval($matches[1]);
+			return max($max, $level);
+		} else {
+			return $max;
+		}
 	}
-	
+
 	function update_user_level_from_caps() {
-	    global $table_prefix;
-	    $this->user_level = array_reduce(array_keys($this->allcaps), 	array(&$this, 'level_reduction'), 0);
-	    update_usermeta($this->id, $table_prefix.'user_level', $this->user_level);
+		global $wpdb;
+		$this->user_level = array_reduce(array_keys($this->allcaps), 	array(&$this, 'level_reduction'), 0);
+		update_usermeta($this->ID, $wpdb->prefix.'user_level', $this->user_level);
 	}
-	
+
 	function add_cap($cap, $grant = true) {
 		$this->caps[$cap] = $grant;
-		update_usermeta($this->id, $this->cap_key, $this->caps);
+		update_usermeta($this->ID, $this->cap_key, $this->caps);
 	}
 
 	function remove_cap($cap) {
 		if ( empty($this->caps[$cap]) ) return;
 		unset($this->caps[$cap]);
-		update_usermeta($this->id, $this->cap_key, $this->caps);
+		update_usermeta($this->ID, $this->cap_key, $this->caps);
+	}
+
+	function remove_all_caps() {
+		global $wpdb;
+		$this->caps = array();
+		update_usermeta($this->ID, $this->cap_key, '');
+		update_usermeta($this->ID, $wpdb->prefix.'user_level', '');
+		$this->get_role_caps();
 	}
-	
+
 	//has_cap(capability_or_role_name) or
 	//has_cap('edit_post', post_id)
 	function has_cap($cap) {
 		if ( is_numeric($cap) )
 			$cap = $this->translate_level_to_cap($cap);
-		
+
 		$args = array_slice(func_get_args(), 1);
-		$args = array_merge(array($cap, $this->id), $args);
+		$args = array_merge(array($cap, $this->ID), $args);
 		$caps = call_user_func_array('map_meta_cap', $args);
 		// Must have ALL requested caps
 		$capabilities = apply_filters('user_has_cap', $this->allcaps, $caps, $args);
@@ -253,12 +287,74 @@
 	$caps = array();
 
 	switch ($cap) {
+	case 'delete_user':
+		$caps[] = 'delete_users';
+		break;
+	case 'edit_user':
+		$caps[] = 'edit_users';
+		break;
+	case 'delete_post':
+		$author_data = get_userdata($user_id);
+		//echo "post ID: {$args[0]}<br/>";
+		$post = get_post($args[0]);
+		if ( 'page' == $post->post_type ) {
+			$args = array_merge(array('delete_page', $user_id), $args);
+			return call_user_func_array('map_meta_cap', $args);
+		}
+		$post_author_data = get_userdata($post->post_author);
+		//echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br/>";
+		// If the user is the author...
+		if ($user_id == $post_author_data->ID) {
+			// If the post is published...
+			if ($post->post_status == 'publish')
+				$caps[] = 'delete_published_posts';
+			else
+				// If the post is draft...
+				$caps[] = 'delete_posts';
+		} else {
+			// The user is trying to edit someone else's post.
+			$caps[] = 'delete_others_posts';
+			// The post is published, extra cap required.
+			if ($post->post_status == 'publish')
+				$caps[] = 'delete_published_posts';
+			else if ($post->post_status == 'private')
+				$caps[] = 'delete_private_posts';
+		}
+		break;
+	case 'delete_page':
+		$author_data = get_userdata($user_id);
+		//echo "post ID: {$args[0]}<br/>";
+		$page = get_page($args[0]);
+		$page_author_data = get_userdata($page->post_author);
+		//echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br/>";
+		// If the user is the author...
+		if ($user_id == $page_author_data->ID) {
+			// If the page is published...
+			if ($page->post_status == 'publish')
+				$caps[] = 'delete_published_pages';
+			else
+				// If the page is draft...
+				$caps[] = 'delete_pages';
+		} else {
+			// The user is trying to edit someone else's page.
+			$caps[] = 'delete_others_pages';
+			// The page is published, extra cap required.
+			if ($page->post_status == 'publish')
+				$caps[] = 'delete_published_pages';
+			else if ($page->post_status == 'private')
+				$caps[] = 'delete_private_pages';
+		}
+		break;
 		// edit_post breaks down to edit_posts, edit_published_posts, or
 		// edit_others_posts
 	case 'edit_post':
 		$author_data = get_userdata($user_id);
 		//echo "post ID: {$args[0]}<br/>";
 		$post = get_post($args[0]);
+		if ( 'page' == $post->post_type ) {
+			$args = array_merge(array('edit_page', $user_id), $args);
+			return call_user_func_array('map_meta_cap', $args);
+		}
 		$post_author_data = get_userdata($post->post_author);
 		//echo "current user id : $user_id, post author id: " . $post_author_data->ID . "<br/>";
 		// If the user is the author...
@@ -266,32 +362,55 @@
 			// If the post is published...
 			if ($post->post_status == 'publish')
 				$caps[] = 'edit_published_posts';
-			else if ($post->post_status == 'static')
-				$caps[] = 'edit_pages';
 			else
 				// If the post is draft...
 				$caps[] = 'edit_posts';
 		} else {
-			if ($post->post_status == 'static') {
-				$caps[] = 'edit_pages';
-				break;
-			}
-
 			// The user is trying to edit someone else's post.
 			$caps[] = 'edit_others_posts';
 			// The post is published, extra cap required.
 			if ($post->post_status == 'publish')
 				$caps[] = 'edit_published_posts';
+			else if ($post->post_status == 'private')
+				$caps[] = 'edit_private_posts';
+		}
+		break;
+	case 'edit_page':
+		$author_data = get_userdata($user_id);
+		//echo "post ID: {$args[0]}<br/>";
+		$page = get_page($args[0]);
+		$page_author_data = get_userdata($page->post_author);
+		//echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br/>";
+		// If the user is the author...
+		if ($user_id == $page_author_data->ID) {
+			// If the page is published...
+			if ($page->post_status == 'publish')
+				$caps[] = 'edit_published_pages';
+			else
+				// If the page is draft...
+				$caps[] = 'edit_pages';
+		} else {
+			// The user is trying to edit someone else's page.
+			$caps[] = 'edit_others_pages';
+			// The page is published, extra cap required.
+			if ($page->post_status == 'publish')
+				$caps[] = 'edit_published_pages';
+			else if ($page->post_status == 'private')
+				$caps[] = 'edit_private_pages';
 		}
 		break;
 	case 'read_post':
 		$post = get_post($args[0]);
-		
+		if ( 'page' == $post->post_type ) {
+			$args = array_merge(array('read_page', $user_id), $args);
+			return call_user_func_array('map_meta_cap', $args);
+		}
+
 		if ( 'private' != $post->post_status ) {
 			$caps[] = 'read';
-			break;	
+			break;
 		}
-			
+
 		$author_data = get_userdata($user_id);
 		$post_author_data = get_userdata($post->post_author);
 		if ($user_id == $post_author_data->ID)
@@ -299,6 +418,21 @@
 		else
 			$caps[] = 'read_private_posts';
 		break;
+	case 'read_page':
+		$page = get_page($args[0]);
+
+		if ( 'private' != $page->post_status ) {
+			$caps[] = 'read';
+			break;
+		}
+
+		$author_data = get_userdata($user_id);
+		$page_author_data = get_userdata($page->post_author);
+		if ($user_id == $page_author_data->ID)
+			$caps[] = 'read';
+		else
+			$caps[] = 'read_private_pages';
+		break;
 	default:
 		// If no meta caps match, return the original cap.
 		$caps[] = $cap;
@@ -348,74 +482,4 @@
 	return $wp_roles->remove_role($role);
 }
 
-//
-// These are deprecated.  Use current_user_can().
-//
-
-/* returns true if $user_id can create a new post */
-function user_can_create_post($user_id, $blog_id = 1, $category_id = 'None') {
-	$author_data = get_userdata($user_id);
-	return ($author_data->user_level > 1);
-}
-
-/* returns true if $user_id can create a new post */
-function user_can_create_draft($user_id, $blog_id = 1, $category_id = 'None') {
-	$author_data = get_userdata($user_id);
-	return ($author_data->user_level >= 1);
-}
-
-/* returns true if $user_id can edit $post_id */
-function user_can_edit_post($user_id, $post_id, $blog_id = 1) {
-	$author_data = get_userdata($user_id);
-	$post = get_post($post_id);
-	$post_author_data = get_userdata($post->post_author);
-
-	if ( (($user_id == $post_author_data->ID) && !($post->post_status == 'publish' &&  $author_data->user_level < 2))
-	     || ($author_data->user_level > $post_author_data->user_level)
-	     || ($author_data->user_level >= 10) ) {
-		return true;
-	} else {
-		return false;
-	}
-}
-
-/* returns true if $user_id can delete $post_id */
-function user_can_delete_post($user_id, $post_id, $blog_id = 1) {
-	// right now if one can edit, one can delete
-	return user_can_edit_post($user_id, $post_id, $blog_id);
-}
-
-/* returns true if $user_id can set new posts' dates on $blog_id */
-function user_can_set_post_date($user_id, $blog_id = 1, $category_id = 'None') {
-	$author_data = get_userdata($user_id);
-	return (($author_data->user_level > 4) && user_can_create_post($user_id, $blog_id, $category_id));
-}
-
-/* returns true if $user_id can edit $post_id's date */
-function user_can_edit_post_date($user_id, $post_id, $blog_id = 1) {
-	$author_data = get_userdata($user_id);
-	return (($author_data->user_level > 4) && user_can_edit_post($user_id, $post_id, $blog_id));
-}
-
-/* returns true if $user_id can edit $post_id's comments */
-function user_can_edit_post_comments($user_id, $post_id, $blog_id = 1) {
-	// right now if one can edit a post, one can edit comments made on it
-	return user_can_edit_post($user_id, $post_id, $blog_id);
-}
-
-/* returns true if $user_id can delete $post_id's comments */
-function user_can_delete_post_comments($user_id, $post_id, $blog_id = 1) {
-	// right now if one can edit comments, one can delete comments
-	return user_can_edit_post_comments($user_id, $post_id, $blog_id);
-}
-
-function user_can_edit_user($user_id, $other_user) {
-	$user  = get_userdata($user_id);
-	$other = get_userdata($other_user);
-	if ( $user->user_level > $other->user_level || $user->user_level > 8 || $user->ID == $other->ID )
-		return true;
-	else
-		return false;
-}
-
 ?>
diff -ruN 2.0.5/wp-includes/category-template.php 2.2.2/wp-includes/category-template.php
--- 2.0.5/wp-includes/category-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/category-template.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,300 @@
+<?php
+
+function get_category_children($id, $before = '/', $after = '') {
+	if ( 0 == $id )
+		return '';
+
+	$chain = '';
+
+	$cat_ids = get_all_category_ids();
+	foreach ( $cat_ids as $cat_id ) {
+		if ( $cat_id == $id)
+			continue;
+
+		$category = get_category($cat_id);
+		if ( $category->category_parent == $id ) {
+			$chain .= $before.$category->cat_ID.$after;
+			$chain .= get_category_children($category->cat_ID, $before, $after);
+		}
+	}
+	return $chain;
+}
+
+function get_category_link($category_id) {
+	global $wp_rewrite;
+	$catlink = $wp_rewrite->get_category_permastruct();
+
+	if ( empty($catlink) ) {
+		$file = get_option('home') . '/';
+		$catlink = $file . '?cat=' . $category_id;
+	} else {
+		$category = &get_category($category_id);
+		$category_nicename = $category->category_nicename;
+
+		if ( $parent = $category->category_parent )
+			$category_nicename = get_category_parents($parent, false, '/', true) . $category_nicename;
+
+		$catlink = str_replace('%category%', $category_nicename, $catlink);
+		$catlink = get_option('home') . user_trailingslashit($catlink, 'category');
+	}
+	return apply_filters('category_link', $catlink, $category_id);
+}
+
+function get_category_parents($id, $link = FALSE, $separator = '/', $nicename = FALSE){
+	$chain = '';
+	$parent = &get_category($id);
+
+	if ( $nicename )
+		$name = $parent->category_nicename;
+	else
+		$name = $parent->cat_name;
+
+	if ( $parent->category_parent && ($parent->category_parent != $parent->cat_ID) )
+		$chain .= get_category_parents($parent->category_parent, $link, $separator, $nicename);
+
+	if ( $link )
+		$chain .= '<a href="' . get_category_link($parent->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $parent->cat_name) . '">'.$name.'</a>' . $separator;
+	else
+		$chain .= $name.$separator;
+	return $chain;
+}
+
+function get_the_category($id = false) {
+global $post, $category_cache, $blog_id;
+
+	$id = (int) $id;
+	if ( !$id )
+		$id = (int) $post->ID;
+
+	if ( !isset($category_cache[$blog_id][$id]) )
+		update_post_category_cache($id);
+
+	$categories = $category_cache[$blog_id][$id];
+
+	if ( !empty($categories) )
+		usort($categories, '_get_the_category_usort');
+	else
+		$categories = array();
+
+	return $categories;
+}
+
+function _get_the_category_usort($a, $b) {
+	return strcmp($a->category_name, $b->category_name);
+}
+
+function _get_the_category_usort_by_ID($a, $b) {
+	if ( $a->cat_ID > $b->cat_ID )
+		return 1;
+	elseif ( $a->cat_ID < $b->cat_ID )
+		return -1;
+	else
+		return 0;
+}
+
+function get_the_category_by_ID($cat_ID) {
+	$cat_ID = (int) $cat_ID;
+	$category = &get_category($cat_ID);
+	return $category->cat_name;
+}
+
+function get_the_category_list($separator = '', $parents='') {
+	global $wp_rewrite;
+	$categories = get_the_category();
+	if (empty($categories))
+		return apply_filters('the_category', __('Uncategorized'), $separator, $parents);
+
+	$rel = ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
+
+	$thelist = '';
+	if ( '' == $separator ) {
+		$thelist .= '<ul class="post-categories">';
+		foreach ( $categories as $category ) {
+			$thelist .= "\n\t<li>";
+			switch ( strtolower($parents) ) {
+				case 'multiple':
+					if ($category->category_parent)
+						$thelist .= get_category_parents($category->category_parent, TRUE);
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>' . $category->cat_name.'</a></li>';
+					break;
+				case 'single':
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>';
+					if ($category->category_parent)
+						$thelist .= get_category_parents($category->category_parent, FALSE);
+					$thelist .= $category->cat_name.'</a></li>';
+					break;
+				case '':
+				default:
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>' . $category->cat_name.'</a></li>';
+			}
+		}
+		$thelist .= '</ul>';
+	} else {
+		$i = 0;
+		foreach ( $categories as $category ) {
+			if ( 0 < $i )
+				$thelist .= $separator . ' ';
+			switch ( strtolower($parents) ) {
+				case 'multiple':
+					if ( $category->category_parent )
+						$thelist .= get_category_parents($category->category_parent, TRUE);
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>' . $category->cat_name.'</a>';
+					break;
+				case 'single':
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>';
+					if ( $category->category_parent )
+						$thelist .= get_category_parents($category->category_parent, FALSE);
+					$thelist .= "$category->cat_name</a>";
+					break;
+				case '':
+				default:
+					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" ' . $rel . '>' . $category->cat_name.'</a>';
+			}
+			++$i;
+		}
+	}
+	return apply_filters('the_category', $thelist, $separator, $parents);
+}
+
+function in_category($category) { // Check if the current post is in the given category
+	global $category_cache, $post, $blog_id;
+
+	if ( isset( $category_cache[$blog_id][$post->ID][$category] ) )
+		return true;
+	else
+		return false;
+}
+
+function the_category($separator = '', $parents='') {
+	echo get_the_category_list($separator, $parents);
+}
+
+function category_description($category = 0) {
+	global $cat;
+	if ( !$category )
+		$category = $cat;
+	$category = & get_category($category);
+	return apply_filters('category_description', $category->category_description, $category->cat_ID);
+}
+
+function wp_dropdown_categories($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('show_option_all' => '', 'show_option_none' => '', 'orderby' => 'ID',
+		'order' => 'ASC', 'show_last_update' => 0, 'show_count' => 0,
+		'hide_empty' => 1, 'child_of' => 0, 'exclude' => '', 'echo' => 1,
+		'selected' => 0, 'hierarchical' => 0, 'name' => 'cat',
+		'class' => 'postform');
+	$defaults['selected'] = ( is_category() ) ? get_query_var('cat') : 0;
+	$r = array_merge($defaults, $r);
+	$r['include_last_update_time'] = $r['show_last_update'];
+	extract($r, EXTR_SKIP);
+
+	$categories = get_categories($r);
+
+	$output = '';
+	if ( ! empty($categories) ) {
+		$output = "<select name='$name' id='$name' class='$class'>\n";
+
+		if ( $show_option_all ) {
+			$show_option_all = apply_filters('list_cats', $show_option_all);
+			$output .= "\t<option value='0'>$show_option_all</option>\n";
+		}
+
+		if ( $show_option_none) {
+			$show_option_none = apply_filters('list_cats', $show_option_none);
+			$output .= "\t<option value='-1'>$show_option_none</option>\n";
+		}
+
+		if ( $hierarchical )
+			$depth = 0;  // Walk the full depth.
+		else
+			$depth = -1; // Flat.
+
+		$output .= walk_category_dropdown_tree($categories, $depth, $r);
+		$output .= "</select>\n";
+	}
+
+	$output = apply_filters('wp_dropdown_cats', $output);
+
+	if ( $echo )
+		echo $output;
+
+	return $output;
+}
+
+function wp_list_categories($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('show_option_all' => '', 'orderby' => 'name',
+		'order' => 'ASC', 'show_last_update' => 0, 'style' => 'list',
+		'show_count' => 0, 'hide_empty' => 1, 'use_desc_for_title' => 1,
+		'child_of' => 0, 'feed' => '', 'feed_image' => '', 'exclude' => '',
+		'hierarchical' => true, 'title_li' => __('Categories'));
+	$r = array_merge($defaults, $r);
+	if ( !isset($r['pad_counts']) && $r['show_count'] && $r['hierarchical'] )
+		$r['pad_counts'] = true;
+	if ( isset($r['show_date']) )
+		$r['include_last_update_time'] = $r['show_date'];
+	extract($r, EXTR_SKIP);
+
+	$categories = get_categories($r);
+
+	$output = '';
+	if ( $title_li && 'list' == $style )
+			$output = '<li class="categories">' . $r['title_li'] . '<ul>';
+
+	if ( empty($categories) ) {
+		if ( 'list' == $style )
+			$output .= '<li>' . __("No categories") . '</li>';
+		else
+			$output .= __("No categories");
+	} else {
+		global $wp_query;
+		
+		if( !empty($show_option_all) )
+			if ('list' == $style )  
+				$output .= '<li><a href="' .  get_bloginfo('url')  . '">' . $show_option_all . '</a></li>';
+			else
+				$output .= '<a href="' .  get_bloginfo('url')  . '">' . $show_option_all . '</a>';
+		
+		if ( is_category() )
+			$r['current_category'] = $wp_query->get_queried_object_id();
+
+		if ( $hierarchical )
+			$depth = 0;  // Walk the full depth.
+		else
+			$depth = -1; // Flat.
+
+		$output .= walk_category_tree($categories, $depth, $r);
+	}
+
+	if ( $title_li && 'list' == $style )
+		$output .= '</ul></li>';
+
+	echo apply_filters('wp_list_categories', $output);
+}
+
+//
+// Helper functions
+//
+
+function walk_category_tree() {
+	$walker = new Walker_Category;
+	$args = func_get_args();
+	return call_user_func_array(array(&$walker, 'walk'), $args);
+}
+
+function walk_category_dropdown_tree() {
+	$walker = new Walker_CategoryDropdown;
+	$args = func_get_args();
+	return call_user_func_array(array(&$walker, 'walk'), $args);
+}
+
+?>
diff -ruN 2.0.5/wp-includes/category.php 2.2.2/wp-includes/category.php
--- 2.0.5/wp-includes/category.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/category.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,331 @@
+<?php
+
+function get_all_category_ids() {
+	global $wpdb;
+
+	if ( ! $cat_ids = wp_cache_get('all_category_ids', 'category') ) {
+		$cat_ids = $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories");
+		wp_cache_add('all_category_ids', $cat_ids, 'category');
+	}
+
+	return $cat_ids;
+}
+
+function &get_categories($args = '') {
+	global $wpdb, $category_links;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('type' => 'post', 'child_of' => 0, 'orderby' => 'name', 'order' => 'ASC',
+		'hide_empty' => true, 'include_last_update_time' => false, 'hierarchical' => 1, 'exclude' => '', 'include' => '',
+		'number' => '', 'pad_counts' => false);
+	$r = array_merge($defaults, $r);
+	if ( 'count' == $r['orderby'] )
+		$r['orderby'] = 'category_count';
+	else
+		$r['orderby'] = "cat_" . $r['orderby'];  // restricts order by to cat_ID and cat_name fields
+	$r['number'] = (int) $r['number'];
+	extract($r, EXTR_SKIP);
+
+	$key = md5( serialize( $r ) );
+	if ( $cache = wp_cache_get( 'get_categories', 'category' ) )
+		if ( isset( $cache[ $key ] ) )
+			return apply_filters('get_categories', $cache[$key], $r);
+
+	$where = 'cat_ID > 0';
+	$inclusions = '';
+	if ( !empty($include) ) {
+		$child_of = 0; //ignore child_of and exclude params if using include
+		$exclude = '';
+		$incategories = preg_split('/[\s,]+/',$include);
+		if ( count($incategories) ) {
+			foreach ( $incategories as $incat ) {
+				if (empty($inclusions))
+					$inclusions = ' AND ( cat_ID = ' . intval($incat) . ' ';
+				else
+					$inclusions .= ' OR cat_ID = ' . intval($incat) . ' ';
+			}
+		}
+	}
+	if (!empty($inclusions))
+		$inclusions .= ')';
+	$where .= $inclusions;
+
+	$exclusions = '';
+	if ( !empty($exclude) ) {
+		$excategories = preg_split('/[\s,]+/',$exclude);
+		if ( count($excategories) ) {
+			foreach ( $excategories as $excat ) {
+				if (empty($exclusions))
+					$exclusions = ' AND ( cat_ID <> ' . intval($excat) . ' ';
+				else
+					$exclusions .= ' AND cat_ID <> ' . intval($excat) . ' ';
+				// TODO: Exclude children of excluded cats?   Note: children are getting excluded
+			}
+		}
+	}
+	if (!empty($exclusions))
+		$exclusions .= ')';
+	$exclusions = apply_filters('list_cats_exclusions', $exclusions, $r );
+	$where .= $exclusions;
+
+	if ( $hide_empty && !$hierarchical ) {
+		if ( 'link' == $type )
+			$where .= ' AND link_count > 0';
+		else
+			$where .= ' AND category_count > 0';
+	}
+
+	if ( !empty($number) )
+		$number = 'LIMIT ' . $number;
+	else
+		$number = '';
+
+	$categories = $wpdb->get_results("SELECT * FROM $wpdb->categories WHERE $where ORDER BY $orderby $order $number");
+
+	if ( empty($categories) )
+		return array();
+
+	// TODO: Integrate this into the main query.
+	if ( $include_last_update_time ) {
+		$stamps = $wpdb->get_results("SELECT category_id, UNIX_TIMESTAMP( MAX(post_date) ) AS ts FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories
+							WHERE post_status = 'publish' AND post_id = ID AND $where GROUP BY category_id");
+		global $cat_stamps;
+		foreach ($stamps as $stamp)
+			$cat_stamps[$stamp->category_id] = $stamp->ts;
+		function stamp_cat($cat) {
+			global $cat_stamps;
+			$cat->last_update_timestamp = $cat_stamps[$cat->cat_ID];
+			return $cat;
+		}
+		$categories = array_map('stamp_cat', $categories);
+		unset($cat_stamps);
+	}
+
+	if ( $child_of || $hierarchical ) {
+		$children = _get_category_hierarchy();
+		if ( ! empty($children) )
+			$categories = & _get_cat_children($child_of, $categories);
+	}
+
+	// Update category counts to include children.
+	if ( $pad_counts )
+		_pad_category_counts($type, $categories);
+
+	// Make sure we show empty categories that have children.
+	if ( $hierarchical && $hide_empty ) {
+		foreach ( $categories as $k => $category ) {
+			if ( ! $category->{'link' == $type ? 'link_count' : 'category_count'} ) {
+				$children = _get_cat_children($category->cat_ID, $categories);
+				foreach ( $children as $child )
+					if ( $child->{'link' == $type ? 'link_count' : 'category_count'} )
+						continue 2;
+
+				// It really is empty
+				unset($categories[$k]);
+			}
+		}
+	}
+	reset ( $categories );
+
+	$cache[ $key ] = $categories;
+	wp_cache_add( 'get_categories', $cache, 'category' );
+
+	$categories = apply_filters('get_categories', $categories, $r);
+	return $categories;
+}
+
+// Retrieves category data given a category ID or category object.
+// Handles category caching.
+function &get_category(&$category, $output = OBJECT) {
+	global $wpdb;
+
+	if ( empty($category) )
+		return null;
+
+	if ( is_object($category) ) {
+		wp_cache_add($category->cat_ID, $category, 'category');
+		$_category = $category;
+	} else {
+		$category = (int) $category;
+		if ( ! $_category = wp_cache_get($category, 'category') ) {
+			$_category = $wpdb->get_row("SELECT * FROM $wpdb->categories WHERE cat_ID = '$category' LIMIT 1");
+			wp_cache_add($category, $_category, 'category');
+		}
+	}
+
+	$_category = apply_filters('get_category', $_category);
+
+	if ( $output == OBJECT ) {
+		return $_category;
+	} elseif ( $output == ARRAY_A ) {
+		return get_object_vars($_category);
+	} elseif ( $output == ARRAY_N ) {
+		return array_values(get_object_vars($_category));
+	} else {
+		return $_category;
+	}
+}
+
+function get_category_by_path($category_path, $full_match = true, $output = OBJECT) {
+	global $wpdb;
+	$category_path = rawurlencode(urldecode($category_path));
+	$category_path = str_replace('%2F', '/', $category_path);
+	$category_path = str_replace('%20', ' ', $category_path);
+	$category_paths = '/' . trim($category_path, '/');
+	$leaf_path  = sanitize_title(basename($category_paths));
+	$category_paths = explode('/', $category_paths);
+	$full_path = '';
+	foreach ( (array) $category_paths as $pathdir )
+		$full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir);
+
+	$categories = $wpdb->get_results("SELECT cat_ID, category_nicename, category_parent FROM $wpdb->categories WHERE category_nicename = '$leaf_path'");
+
+	if ( empty($categories) )
+		return NULL;
+
+	foreach ($categories as $category) {
+		$path = '/' . $leaf_path;
+		$curcategory = $category;
+		while ( ($curcategory->category_parent != 0) && ($curcategory->category_parent != $curcategory->cat_ID) ) {
+			$curcategory = $wpdb->get_row("SELECT cat_ID, category_nicename, category_parent FROM $wpdb->categories WHERE cat_ID = '$curcategory->category_parent'");
+			$path = '/' . $curcategory->category_nicename . $path;
+		}
+
+		if ( $path == $full_path )
+			return get_category($category->cat_ID, $output);
+	}
+
+	// If full matching is not required, return the first cat that matches the leaf.
+	if ( ! $full_match )
+		return get_category($categories[0]->cat_ID, $output);
+
+	return NULL;
+}
+
+// Get the ID of a category from its name
+function get_cat_ID($cat_name='General') {
+	global $wpdb;
+
+	$cid = $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE cat_name='$cat_name'");
+
+	return $cid?$cid:1;	// default to cat 1
+}
+
+// Deprecate
+function get_catname($cat_ID) {
+	return get_cat_name($cat_ID);
+}
+
+// Get the name of a category from its ID
+function get_cat_name($cat_id) {
+	$cat_id = (int) $cat_id;
+	$category = &get_category($cat_id);
+	return $category->cat_name;
+}
+
+function cat_is_ancestor_of($cat1, $cat2) { 
+	if ( is_int($cat1) ) 
+		$cat1 = & get_category($cat1); 
+	if ( is_int($cat2) ) 
+		$cat2 = & get_category($cat2); 
+
+	if ( !$cat1->cat_ID || !$cat2->category_parent ) 
+		return false; 
+
+	if ( $cat2->category_parent == $cat1->cat_ID ) 
+		return true; 
+
+	return cat_is_ancestor_of($cat1, get_category($cat2->parent_category)); 
+} 
+
+//
+// Private
+//
+
+function &_get_cat_children($category_id, $categories) {
+	if ( empty($categories) )
+		return array();
+
+	$category_list = array();
+	$has_children = _get_category_hierarchy();
+
+	if  ( ( 0 != $category_id ) && ! isset($has_children[$category_id]) )
+		return array();
+
+	foreach ( $categories as $category ) {
+		if ( $category->cat_ID == $category_id )
+			continue;
+
+		if ( $category->category_parent == $category_id ) {
+			$category_list[] = $category;
+
+			if ( !isset($has_children[$category->cat_ID]) )
+				continue;
+
+			if ( $children = _get_cat_children($category->cat_ID, $categories) )
+				$category_list = array_merge($category_list, $children);
+		}
+	}
+
+	return $category_list;
+}
+
+// Recalculates link or post counts by including items from child categories
+// Assumes all relevant children are already in the $categories argument
+function _pad_category_counts($type, &$categories) {
+	global $wpdb;
+
+	// Set up some useful arrays
+	foreach ( $categories as $key => $cat ) {
+		$cats[$cat->cat_ID] = & $categories[$key];
+		$cat_IDs[] = $cat->cat_ID;
+	}
+
+	// Get the relevant post2cat or link2cat records and stick them in a lookup table
+	if ( $type == 'post' ) {
+		$results = $wpdb->get_results("SELECT post_id, category_id FROM $wpdb->post2cat LEFT JOIN $wpdb->posts ON post_id = ID WHERE category_id IN (".join(',', $cat_IDs).") AND post_type = 'post' AND post_status = 'publish'");
+		foreach ( $results as $row )
+			++$cat_items[$row->category_id][$row->post_id];
+	} else {
+		$results = $wpdb->get_results("SELECT $wpdb->link2cat.link_id, category_id FROM $wpdb->link2cat LEFT JOIN $wpdb->links USING (link_id) WHERE category_id IN (".join(',', $cat_IDs).") AND link_visible = 'Y'");
+		foreach ( $results as $row )
+			++$cat_items[$row->category_id][$row->link_id];
+	}
+
+	// Touch every ancestor's lookup row for each post in each category
+	foreach ( $cat_IDs as $cat_ID ) {
+		$child = $cat_ID;
+		while ( $parent = $cats[$child]->category_parent ) {
+			if ( !empty($cat_items[$cat_ID]) )
+				foreach ( $cat_items[$cat_ID] as $item_id => $touches )
+					++$cat_items[$parent][$item_id];
+			$child = $parent;
+		}
+	}
+
+	// Transfer the touched cells 
+	foreach ( (array) $cat_items as $id => $items )
+		if ( isset($cats[$id]) )
+			$cats[$id]->{'link' == $type ? 'link_count' : 'category_count'} = count($items);
+}
+
+function _get_category_hierarchy() {
+	$children = get_option('category_children');
+	if ( is_array($children) )
+		return $children;
+
+	$children = array();
+	$categories = get_categories('hide_empty=0&hierarchical=0');
+	foreach ( $categories as $cat ) {
+		if ( $cat->category_parent > 0 )
+			$children[$cat->category_parent][] = $cat->cat_ID;
+	}
+	update_option('category_children', $children);
+
+	return $children;
+}
+?>
diff -ruN 2.0.5/wp-includes/class-phpmailer.php 2.2.2/wp-includes/class-phpmailer.php
--- 2.0.5/wp-includes/class-phpmailer.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/class-phpmailer.php	2007-06-11 18:18:24.000000000 -0500
@@ -0,0 +1,1498 @@
+<?php
+////////////////////////////////////////////////////
+// PHPMailer - PHP email class
+//
+// Class for sending email using either
+// sendmail, PHP mail(), or SMTP.  Methods are
+// based upon the standard AspEmail(tm) classes.
+//
+// Copyright (C) 2001 - 2003  Brent R. Matzelle
+//
+// License: LGPL, see LICENSE
+////////////////////////////////////////////////////
+
+/**
+ * PHPMailer - PHP email transport class
+ * @package PHPMailer
+ * @author Brent R. Matzelle
+ * @copyright 2001 - 2003 Brent R. Matzelle
+ */
+class PHPMailer
+{
+    /////////////////////////////////////////////////
+    // PUBLIC VARIABLES
+    /////////////////////////////////////////////////
+
+    /**
+     * Email priority (1 = High, 3 = Normal, 5 = low).
+     * @var int
+     */
+    var $Priority          = 3;
+
+    /**
+     * Sets the CharSet of the message.
+     * @var string
+     */
+    var $CharSet           = "UTF-8";
+
+    /**
+     * Sets the Content-type of the message.
+     * @var string
+     */
+    var $ContentType        = "text/plain";
+
+    /**
+     * Sets the Encoding of the message. Options for this are "8bit",
+     * "7bit", "binary", "base64", and "quoted-printable".
+     * @var string
+     */
+    var $Encoding          = "8bit";
+
+    /**
+     * Holds the most recent mailer error message.
+     * @var string
+     */
+    var $ErrorInfo         = "";
+
+    /**
+     * Sets the From email address for the message.
+     * @var string
+     */
+    var $From               = "support@wordpress.com";
+
+    /**
+     * Sets the From name of the message.
+     * @var string
+     */
+    var $FromName           = "Support";
+
+    /**
+     * Sets the Sender email (Return-Path) of the message.  If not empty,
+     * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
+     * @var string
+     */
+    var $Sender            = "";
+
+    /**
+     * Sets the Subject of the message.
+     * @var string
+     */
+    var $Subject           = "";
+
+    /**
+     * Sets the Body of the message.  This can be either an HTML or text body.
+     * If HTML then run IsHTML(true).
+     * @var string
+     */
+    var $Body               = "";
+
+    /**
+     * Sets the text-only body of the message.  This automatically sets the
+     * email to multipart/alternative.  This body can be read by mail
+     * clients that do not have HTML email capability such as mutt. Clients
+     * that can read HTML will view the normal Body.
+     * @var string
+     */
+    var $AltBody           = "";
+
+    /**
+     * Sets word wrapping on the body of the message to a given number of 
+     * characters.
+     * @var int
+     */
+    var $WordWrap          = 0;
+
+    /**
+     * Method to send mail: ("mail", "sendmail", or "smtp").
+     * @var string
+     */
+    var $Mailer            = "mail";
+
+    /**
+     * Sets the path of the sendmail program.
+     * @var string
+     */
+    var $Sendmail          = "/usr/sbin/sendmail";
+    
+    /**
+     * Path to PHPMailer plugins.  This is now only useful if the SMTP class 
+     * is in a different directory than the PHP include path.  
+     * @var string
+     */
+    var $PluginDir         = "";
+
+    /**
+     *  Holds PHPMailer version.
+     *  @var string
+     */
+    var $Version           = "1.73";
+
+    /**
+     * Sets the email address that a reading confirmation will be sent.
+     * @var string
+     */
+    var $ConfirmReadingTo  = "";
+
+    /**
+     *  Sets the hostname to use in Message-Id and Received headers
+     *  and as default HELO string. If empty, the value returned
+     *  by SERVER_NAME is used or 'localhost.localdomain'.
+     *  @var string
+     */
+    var $Hostname          = "";
+
+    /////////////////////////////////////////////////
+    // SMTP VARIABLES
+    /////////////////////////////////////////////////
+
+    /**
+     *  Sets the SMTP hosts.  All hosts must be separated by a
+     *  semicolon.  You can also specify a different port
+     *  for each host by using this format: [hostname:port]
+     *  (e.g. "smtp1.example.com:25;smtp2.example.com").
+     *  Hosts will be tried in order.
+     *  @var string
+     */
+    var $Host        = "localhost";
+
+    /**
+     *  Sets the default SMTP server port.
+     *  @var int
+     */
+    var $Port        = 25;
+
+    /**
+     *  Sets the SMTP HELO of the message (Default is $Hostname).
+     *  @var string
+     */
+    var $Helo        = "";
+
+    /**
+     *  Sets SMTP authentication. Utilizes the Username and Password variables.
+     *  @var bool
+     */
+    var $SMTPAuth     = false;
+
+    /**
+     *  Sets SMTP username.
+     *  @var string
+     */
+    var $Username     = "";
+
+    /**
+     *  Sets SMTP password.
+     *  @var string
+     */
+    var $Password     = "";
+
+    /**
+     *  Sets the SMTP server timeout in seconds. This function will not 
+     *  work with the win32 version.
+     *  @var int
+     */
+    var $Timeout      = 10;
+
+    /**
+     *  Sets SMTP class debugging on or off.
+     *  @var bool
+     */
+    var $SMTPDebug    = false;
+
+    /**
+     * Prevents the SMTP connection from being closed after each mail 
+     * sending.  If this is set to true then to close the connection 
+     * requires an explicit call to SmtpClose(). 
+     * @var bool
+     */
+    var $SMTPKeepAlive = false;
+
+    /**#@+
+     * @access private
+     */
+    var $smtp            = NULL;
+    var $to              = array();
+    var $cc              = array();
+    var $bcc             = array();
+    var $ReplyTo         = array();
+    var $attachment      = array();
+    var $CustomHeader    = array();
+    var $message_type    = "";
+    var $boundary        = array();
+    var $language        = array();
+    var $error_count     = 0;
+    var $LE              = "\n";
+    /**#@-*/
+    
+    /////////////////////////////////////////////////
+    // VARIABLE METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Sets message type to HTML.  
+     * @param bool $bool
+     * @return void
+     */
+    function IsHTML($bool) {
+        if($bool == true)
+            $this->ContentType = "text/html";
+        else
+            $this->ContentType = "text/plain";
+    }
+
+    /**
+     * Sets Mailer to send message using SMTP.
+     * @return void
+     */
+    function IsSMTP() {
+        $this->Mailer = "smtp";
+    }
+
+    /**
+     * Sets Mailer to send message using PHP mail() function.
+     * @return void
+     */
+    function IsMail() {
+        $this->Mailer = "mail";
+    }
+
+    /**
+     * Sets Mailer to send message using the $Sendmail program.
+     * @return void
+     */
+    function IsSendmail() {
+        $this->Mailer = "sendmail";
+    }
+
+    /**
+     * Sets Mailer to send message using the qmail MTA. 
+     * @return void
+     */
+    function IsQmail() {
+        $this->Sendmail = "/var/qmail/bin/sendmail";
+        $this->Mailer = "sendmail";
+    }
+
+
+    /////////////////////////////////////////////////
+    // RECIPIENT METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Adds a "To" address.  
+     * @param string $address
+     * @param string $name
+     * @return void
+     */
+    function AddAddress($address, $name = "") {
+        $cur = count($this->to);
+        $this->to[$cur][0] = trim($address);
+        $this->to[$cur][1] = $name;
+    }
+
+    /**
+     * Adds a "Cc" address. Note: this function works
+     * with the SMTP mailer on win32, not with the "mail"
+     * mailer.  
+     * @param string $address
+     * @param string $name
+     * @return void
+    */
+    function AddCC($address, $name = "") {
+        $cur = count($this->cc);
+        $this->cc[$cur][0] = trim($address);
+        $this->cc[$cur][1] = $name;
+    }
+
+    /**
+     * Adds a "Bcc" address. Note: this function works
+     * with the SMTP mailer on win32, not with the "mail"
+     * mailer.  
+     * @param string $address
+     * @param string $name
+     * @return void
+     */
+    function AddBCC($address, $name = "") {
+        $cur = count($this->bcc);
+        $this->bcc[$cur][0] = trim($address);
+        $this->bcc[$cur][1] = $name;
+    }
+
+    /**
+     * Adds a "Reply-to" address.  
+     * @param string $address
+     * @param string $name
+     * @return void
+     */
+    function AddReplyTo($address, $name = "") {
+        $cur = count($this->ReplyTo);
+        $this->ReplyTo[$cur][0] = trim($address);
+        $this->ReplyTo[$cur][1] = $name;
+    }
+
+
+    /////////////////////////////////////////////////
+    // MAIL SENDING METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Creates message and assigns Mailer. If the message is
+     * not sent successfully then it returns false.  Use the ErrorInfo
+     * variable to view description of the error.  
+     * @return bool
+     */
+    function Send() {
+        $header = "";
+        $body = "";
+        $result = true;
+
+        if((count($this->to) + count($this->cc) + count($this->bcc)) < 1)
+        {
+            $this->SetError($this->Lang("provide_address"));
+            return false;
+        }
+
+        // Set whether the message is multipart/alternative
+        if(!empty($this->AltBody))
+            $this->ContentType = "multipart/alternative";
+
+        $this->error_count = 0; // reset errors
+        $this->SetMessageType();
+        $header .= $this->CreateHeader();
+        $body = $this->CreateBody();
+
+        if($body == "") { return false; }
+
+        // Choose the mailer
+        switch($this->Mailer)
+        {
+            case "sendmail":
+                $result = $this->SendmailSend($header, $body);
+                break;
+            case "mail":
+                $result = $this->MailSend($header, $body);
+                break;
+            case "smtp":
+                $result = $this->SmtpSend($header, $body);
+                break;
+            default:
+            $this->SetError($this->Mailer . $this->Lang("mailer_not_supported"));
+                $result = false;
+                break;
+        }
+
+        return $result;
+    }
+    
+    /**
+     * Sends mail using the $Sendmail program.  
+     * @access private
+     * @return bool
+     */
+    function SendmailSend($header, $body) {
+        if ($this->Sender != "")
+            $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, escapeshellarg($this->Sender));
+        else
+            $sendmail = sprintf("%s -oi -t", $this->Sendmail);
+
+        if(!@$mail = popen($sendmail, "w"))
+        {
+            $this->SetError($this->Lang("execute") . $this->Sendmail);
+            return false;
+        }
+
+        fputs($mail, $header);
+        fputs($mail, $body);
+        
+        $result = pclose($mail) >> 8 & 0xFF;
+        if($result != 0)
+        {
+            $this->SetError($this->Lang("execute") . $this->Sendmail);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sends mail using the PHP mail() function.  
+     * @access private
+     * @return bool
+     */
+    function MailSend($header, $body) {
+        $to = "";
+        for($i = 0; $i < count($this->to); $i++)
+        {
+            if($i != 0) { $to .= ", "; }
+            $to .= $this->to[$i][0];
+        }
+
+        if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1)
+        {
+            $old_from = ini_get("sendmail_from");
+            ini_set("sendmail_from", $this->Sender);
+            $params = sprintf("-oi -f %s", $this->Sender);
+            $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, 
+                        $header, $params);
+        }
+        else
+            $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);
+
+        if (isset($old_from))
+            ini_set("sendmail_from", $old_from);
+
+        if(!$rt)
+        {
+            $this->SetError($this->Lang("instantiate"));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sends mail via SMTP using PhpSMTP (Author:
+     * Chris Ryan).  Returns bool.  Returns false if there is a
+     * bad MAIL FROM, RCPT, or DATA input.
+     * @access private
+     * @return bool
+     */
+    function SmtpSend($header, $body) {
+        include_once($this->PluginDir . "class.smtp.php");
+        $error = "";
+        $bad_rcpt = array();
+
+        if(!$this->SmtpConnect())
+            return false;
+
+        $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender;
+        if(!$this->smtp->Mail($smtp_from))
+        {
+            $error = $this->Lang("from_failed") . $smtp_from;
+            $this->SetError($error);
+            $this->smtp->Reset();
+            return false;
+        }
+
+        // Attempt to send attach all recipients
+        for($i = 0; $i < count($this->to); $i++)
+        {
+            if(!$this->smtp->Recipient($this->to[$i][0]))
+                $bad_rcpt[] = $this->to[$i][0];
+        }
+        for($i = 0; $i < count($this->cc); $i++)
+        {
+            if(!$this->smtp->Recipient($this->cc[$i][0]))
+                $bad_rcpt[] = $this->cc[$i][0];
+        }
+        for($i = 0; $i < count($this->bcc); $i++)
+        {
+            if(!$this->smtp->Recipient($this->bcc[$i][0]))
+                $bad_rcpt[] = $this->bcc[$i][0];
+        }
+
+        if(count($bad_rcpt) > 0) // Create error message
+        {
+            for($i = 0; $i < count($bad_rcpt); $i++)
+            {
+                if($i != 0) { $error .= ", "; }
+                $error .= $bad_rcpt[$i];
+            }
+            $error = $this->Lang("recipients_failed") . $error;
+            $this->SetError($error);
+            $this->smtp->Reset();
+            return false;
+        }
+
+        if(!$this->smtp->Data($header . $body))
+        {
+            $this->SetError($this->Lang("data_not_accepted"));
+            $this->smtp->Reset();
+            return false;
+        }
+        if($this->SMTPKeepAlive == true)
+            $this->smtp->Reset();
+        else
+            $this->SmtpClose();
+
+        return true;
+    }
+
+    /**
+     * Initiates a connection to an SMTP server.  Returns false if the 
+     * operation failed.
+     * @access private
+     * @return bool
+     */
+    function SmtpConnect() {
+        if($this->smtp == NULL) { $this->smtp = new SMTP(); }
+
+        $this->smtp->do_debug = $this->SMTPDebug;
+        $hosts = explode(";", $this->Host);
+        $index = 0;
+        $connection = ($this->smtp->Connected()); 
+
+        // Retry while there is no connection
+        while($index < count($hosts) && $connection == false)
+        {
+            if(strstr($hosts[$index], ":"))
+                list($host, $port) = explode(":", $hosts[$index]);
+            else
+            {
+                $host = $hosts[$index];
+                $port = $this->Port;
+            }
+
+            if($this->smtp->Connect($host, $port, $this->Timeout))
+            {
+                if ($this->Helo != '')
+                    $this->smtp->Hello($this->Helo);
+                else
+                    $this->smtp->Hello($this->ServerHostname());
+        
+                if($this->SMTPAuth)
+                {
+                    if(!$this->smtp->Authenticate($this->Username, 
+                                                  $this->Password))
+                    {
+                        $this->SetError($this->Lang("authenticate"));
+                        $this->smtp->Reset();
+                        $connection = false;
+                    }
+                }
+                $connection = true;
+            }
+            $index++;
+        }
+        if(!$connection)
+            $this->SetError($this->Lang("connect_host"));
+
+        return $connection;
+    }
+
+    /**
+     * Closes the active SMTP session if one exists.
+     * @return void
+     */
+    function SmtpClose() {
+        if($this->smtp != NULL)
+        {
+            if($this->smtp->Connected())
+            {
+                $this->smtp->Quit();
+                $this->smtp->Close();
+            }
+        }
+    }
+
+    /**
+     * Sets the language for all class error messages.  Returns false 
+     * if it cannot load the language file.  The default language type
+     * is English.
+     * @param string $lang_type Type of language (e.g. Portuguese: "br")
+     * @param string $lang_path Path to the language file directory
+     * @access public
+     * @return bool
+     */
+    function SetLanguage($lang_type, $lang_path = "language/") {
+        if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php'))
+            include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
+        else if(file_exists($lang_path.'phpmailer.lang-en.php'))
+            include($lang_path.'phpmailer.lang-en.php');
+        else
+        {
+            $this->SetError("Could not load language file");
+            return false;
+        }
+        $this->language = $PHPMAILER_LANG;
+    
+        return true;
+    }
+
+    /////////////////////////////////////////////////
+    // MESSAGE CREATION METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Creates recipient headers.  
+     * @access private
+     * @return string
+     */
+    function AddrAppend($type, $addr) {
+        $addr_str = $type . ": ";
+        $addr_str .= $this->AddrFormat($addr[0]);
+        if(count($addr) > 1)
+        {
+            for($i = 1; $i < count($addr); $i++)
+                $addr_str .= ", " . $this->AddrFormat($addr[$i]);
+        }
+        $addr_str .= $this->LE;
+
+        return $addr_str;
+    }
+    
+    /**
+     * Formats an address correctly. 
+     * @access private
+     * @return string
+     */
+    function AddrFormat($addr) {
+        if(empty($addr[1]))
+            $formatted = $addr[0];
+        else
+        {
+            $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . 
+                         $addr[0] . ">";
+        }
+
+        return $formatted;
+    }
+
+    /**
+     * Wraps message for use with mailers that do not
+     * automatically perform wrapping and for quoted-printable.
+     * Original written by philippe.  
+     * @access private
+     * @return string
+     */
+    function WrapText($message, $length, $qp_mode = false) {
+        $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
+
+        $message = $this->FixEOL($message);
+        if (substr($message, -1) == $this->LE)
+            $message = substr($message, 0, -1);
+
+        $line = explode($this->LE, $message);
+        $message = "";
+        for ($i=0 ;$i < count($line); $i++)
+        {
+          $line_part = explode(" ", $line[$i]);
+          $buf = "";
+          for ($e = 0; $e<count($line_part); $e++)
+          {
+              $word = $line_part[$e];
+              if ($qp_mode and (strlen($word) > $length))
+              {
+                $space_left = $length - strlen($buf) - 1;
+                if ($e != 0)
+                {
+                    if ($space_left > 20)
+                    {
+                        $len = $space_left;
+                        if (substr($word, $len - 1, 1) == "=")
+                          $len--;
+                        elseif (substr($word, $len - 2, 1) == "=")
+                          $len -= 2;
+                        $part = substr($word, 0, $len);
+                        $word = substr($word, $len);
+                        $buf .= " " . $part;
+                        $message .= $buf . sprintf("=%s", $this->LE);
+                    }
+                    else
+                    {
+                        $message .= $buf . $soft_break;
+                    }
+                    $buf = "";
+                }
+                while (strlen($word) > 0)
+                {
+                    $len = $length;
+                    if (substr($word, $len - 1, 1) == "=")
+                        $len--;
+                    elseif (substr($word, $len - 2, 1) == "=")
+                        $len -= 2;
+                    $part = substr($word, 0, $len);
+                    $word = substr($word, $len);
+
+                    if (strlen($word) > 0)
+                        $message .= $part . sprintf("=%s", $this->LE);
+                    else
+                        $buf = $part;
+                }
+              }
+              else
+              {
+                $buf_o = $buf;
+                $buf .= ($e == 0) ? $word : (" " . $word); 
+
+                if (strlen($buf) > $length and $buf_o != "")
+                {
+                    $message .= $buf_o . $soft_break;
+                    $buf = $word;
+                }
+              }
+          }
+          $message .= $buf . $this->LE;
+        }
+
+        return $message;
+    }
+    
+    /**
+     * Set the body wrapping.
+     * @access private
+     * @return void
+     */
+    function SetWordWrap() {
+        if($this->WordWrap < 1)
+            return;
+            
+        switch($this->message_type)
+        {
+           case "alt":
+              // fall through
+           case "alt_attachments":
+              $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
+              break;
+           default:
+              $this->Body = $this->WrapText($this->Body, $this->WordWrap);
+              break;
+        }
+    }
+
+    /**
+     * Assembles message header.  
+     * @access private
+     * @return string
+     */
+    function CreateHeader() {
+        $result = "";
+        
+        // Set the boundaries
+        $uniq_id = md5(uniqid(time()));
+        $this->boundary[1] = "b1_" . $uniq_id;
+        $this->boundary[2] = "b2_" . $uniq_id;
+
+        $result .= $this->HeaderLine("Date", $this->RFCDate());
+        if($this->Sender == "")
+            $result .= $this->HeaderLine("Return-Path", trim($this->From));
+        else
+            $result .= $this->HeaderLine("Return-Path", trim($this->Sender));
+        
+        // To be created automatically by mail()
+        if($this->Mailer != "mail")
+        {
+            if(count($this->to) > 0)
+                $result .= $this->AddrAppend("To", $this->to);
+            else if (count($this->cc) == 0)
+                $result .= $this->HeaderLine("To", "undisclosed-recipients:;");
+            if(count($this->cc) > 0)
+                $result .= $this->AddrAppend("Cc", $this->cc);
+        }
+
+        $from = array();
+        $from[0][0] = trim($this->From);
+        $from[0][1] = $this->FromName;
+        $result .= $this->AddrAppend("From", $from); 
+
+        // sendmail and mail() extract Bcc from the header before sending
+        if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0))
+            $result .= $this->AddrAppend("Bcc", $this->bcc);
+
+        if(count($this->ReplyTo) > 0)
+            $result .= $this->AddrAppend("Reply-to", $this->ReplyTo);
+
+        // mail() sets the subject itself
+        if($this->Mailer != "mail")
+            $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject)));
+
+        $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
+        $result .= $this->HeaderLine("X-Priority", $this->Priority);
+        
+        if($this->ConfirmReadingTo != "")
+        {
+            $result .= $this->HeaderLine("Disposition-Notification-To", 
+                       "<" . trim($this->ConfirmReadingTo) . ">");
+        }
+
+        // Add custom headers
+        for($index = 0; $index < count($this->CustomHeader); $index++)
+        {
+            $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), 
+                       $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
+        }
+        $result .= $this->HeaderLine("MIME-Version", "1.0");
+
+        switch($this->message_type)
+        {
+            case "plain":
+                $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);
+                $result .= sprintf("Content-Type: %s; charset=\"%s\"",
+                                    $this->ContentType, $this->CharSet);
+                break;
+            case "attachments":
+                // fall through
+            case "alt_attachments":
+                if($this->InlineImageExists())
+                {
+                    $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 
+                                    "multipart/related", $this->LE, $this->LE, 
+                                    $this->boundary[1], $this->LE);
+                }
+                else
+                {
+                    $result .= $this->HeaderLine("Content-Type", "multipart/mixed;");
+                    $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
+                }
+                break;
+            case "alt":
+                $result .= $this->HeaderLine("Content-Type", "multipart/alternative;");
+                $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
+                break;
+        }
+
+        if($this->Mailer != "mail")
+            $result .= $this->LE.$this->LE;
+
+        return $result;
+    }
+
+    /**
+     * Assembles the message body.  Returns an empty string on failure.
+     * @access private
+     * @return string
+     */
+    function CreateBody() {
+        $result = "";
+
+        $this->SetWordWrap();
+
+        switch($this->message_type)
+        {
+            case "alt":
+                $result .= $this->GetBoundary($this->boundary[1], "", 
+                                              "text/plain", "");
+                $result .= $this->EncodeString($this->AltBody, $this->Encoding);
+                $result .= $this->LE.$this->LE;
+                $result .= $this->GetBoundary($this->boundary[1], "", 
+                                              "text/html", "");
+                
+                $result .= $this->EncodeString($this->Body, $this->Encoding);
+                $result .= $this->LE.$this->LE;
+    
+                $result .= $this->EndBoundary($this->boundary[1]);
+                break;
+            case "plain":
+                $result .= $this->EncodeString($this->Body, $this->Encoding);
+                break;
+            case "attachments":
+                $result .= $this->GetBoundary($this->boundary[1], "", "", "");
+                $result .= $this->EncodeString($this->Body, $this->Encoding);
+                $result .= $this->LE;
+     
+                $result .= $this->AttachAll();
+                break;
+            case "alt_attachments":
+                $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
+                $result .= sprintf("Content-Type: %s;%s" .
+                                   "\tboundary=\"%s\"%s",
+                                   "multipart/alternative", $this->LE, 
+                                   $this->boundary[2], $this->LE.$this->LE);
+    
+                // Create text body
+                $result .= $this->GetBoundary($this->boundary[2], "", 
+                                              "text/plain", "") . $this->LE;
+
+                $result .= $this->EncodeString($this->AltBody, $this->Encoding);
+                $result .= $this->LE.$this->LE;
+    
+                // Create the HTML body
+                $result .= $this->GetBoundary($this->boundary[2], "", 
+                                              "text/html", "") . $this->LE;
+    
+                $result .= $this->EncodeString($this->Body, $this->Encoding);
+                $result .= $this->LE.$this->LE;
+
+                $result .= $this->EndBoundary($this->boundary[2]);
+                
+                $result .= $this->AttachAll();
+                break;
+        }
+        if($this->IsError())
+            $result = "";
+
+        return $result;
+    }
+
+    /**
+     * Returns the start of a message boundary.
+     * @access private
+     */
+    function GetBoundary($boundary, $charSet, $contentType, $encoding) {
+        $result = "";
+        if($charSet == "") { $charSet = $this->CharSet; }
+        if($contentType == "") { $contentType = $this->ContentType; }
+        if($encoding == "") { $encoding = $this->Encoding; }
+
+        $result .= $this->TextLine("--" . $boundary);
+        $result .= sprintf("Content-Type: %s; charset = \"%s\"", 
+                            $contentType, $charSet);
+        $result .= $this->LE;
+        $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);
+        $result .= $this->LE;
+       
+        return $result;
+    }
+    
+    /**
+     * Returns the end of a message boundary.
+     * @access private
+     */
+    function EndBoundary($boundary) {
+        return $this->LE . "--" . $boundary . "--" . $this->LE; 
+    }
+    
+    /**
+     * Sets the message type.
+     * @access private
+     * @return void
+     */
+    function SetMessageType() {
+        if(count($this->attachment) < 1 && strlen($this->AltBody) < 1)
+            $this->message_type = "plain";
+        else
+        {
+            if(count($this->attachment) > 0)
+                $this->message_type = "attachments";
+            if(strlen($this->AltBody) > 0 && count($this->attachment) < 1)
+                $this->message_type = "alt";
+            if(strlen($this->AltBody) > 0 && count($this->attachment) > 0)
+                $this->message_type = "alt_attachments";
+        }
+    }
+
+    /**
+     * Returns a formatted header line.
+     * @access private
+     * @return string
+     */
+    function HeaderLine($name, $value) {
+        return $name . ": " . $value . $this->LE;
+    }
+
+    /**
+     * Returns a formatted mail line.
+     * @access private
+     * @return string
+     */
+    function TextLine($value) {
+        return $value . $this->LE;
+    }
+
+    /////////////////////////////////////////////////
+    // ATTACHMENT METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Adds an attachment from a path on the filesystem.
+     * Returns false if the file could not be found
+     * or accessed.
+     * @param string $path Path to the attachment.
+     * @param string $name Overrides the attachment name.
+     * @param string $encoding File encoding (see $Encoding).
+     * @param string $type File extension (MIME) type.
+     * @return bool
+     */
+    function AddAttachment($path, $name = "", $encoding = "base64", 
+                           $type = "application/octet-stream") {
+        if(!@is_file($path))
+        {
+            $this->SetError($this->Lang("file_access") . $path);
+            return false;
+        }
+
+        $filename = basename($path);
+        if($name == "")
+            $name = $filename;
+
+        $cur = count($this->attachment);
+        $this->attachment[$cur][0] = $path;
+        $this->attachment[$cur][1] = $filename;
+        $this->attachment[$cur][2] = $name;
+        $this->attachment[$cur][3] = $encoding;
+        $this->attachment[$cur][4] = $type;
+        $this->attachment[$cur][5] = false; // isStringAttachment
+        $this->attachment[$cur][6] = "attachment";
+        $this->attachment[$cur][7] = 0;
+
+        return true;
+    }
+
+    /**
+     * Attaches all fs, string, and binary attachments to the message.
+     * Returns an empty string on failure.
+     * @access private
+     * @return string
+     */
+    function AttachAll() {
+        // Return text of body
+        $mime = array();
+
+        // Add all attachments
+        for($i = 0; $i < count($this->attachment); $i++)
+        {
+            // Check for string attachment
+            $bString = $this->attachment[$i][5];
+            if ($bString)
+                $string = $this->attachment[$i][0];
+            else
+                $path = $this->attachment[$i][0];
+
+            $filename    = $this->attachment[$i][1];
+            $name        = $this->attachment[$i][2];
+            $encoding    = $this->attachment[$i][3];
+            $type        = $this->attachment[$i][4];
+            $disposition = $this->attachment[$i][6];
+            $cid         = $this->attachment[$i][7];
+            
+            $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
+            $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
+            $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
+
+            if($disposition == "inline")
+                $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
+
+            $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", 
+                              $disposition, $name, $this->LE.$this->LE);
+
+            // Encode as string attachment
+            if($bString)
+            {
+                $mime[] = $this->EncodeString($string, $encoding);
+                if($this->IsError()) { return ""; }
+                $mime[] = $this->LE.$this->LE;
+            }
+            else
+            {
+                $mime[] = $this->EncodeFile($path, $encoding);                
+                if($this->IsError()) { return ""; }
+                $mime[] = $this->LE.$this->LE;
+            }
+        }
+
+        $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
+
+        return join("", $mime);
+    }
+    
+    /**
+     * Encodes attachment in requested format.  Returns an
+     * empty string on failure.
+     * @access private
+     * @return string
+     */
+    function EncodeFile ($path, $encoding = "base64") {
+        if(!@$fd = fopen($path, "rb"))
+        {
+            $this->SetError($this->Lang("file_open") . $path);
+            return "";
+        }
+        $magic_quotes = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        $file_buffer = fread($fd, filesize($path));
+        $file_buffer = $this->EncodeString($file_buffer, $encoding);
+        fclose($fd);
+        set_magic_quotes_runtime($magic_quotes);
+
+        return $file_buffer;
+    }
+
+    /**
+     * Encodes string to requested format. Returns an
+     * empty string on failure.
+     * @access private
+     * @return string
+     */
+    function EncodeString ($str, $encoding = "base64") {
+        $encoded = "";
+        switch(strtolower($encoding)) {
+          case "base64":
+              // chunk_split is found in PHP >= 3.0.6
+              $encoded = chunk_split(base64_encode($str), 76, $this->LE);
+              break;
+          case "7bit":
+          case "8bit":
+              $encoded = $this->FixEOL($str);
+              if (substr($encoded, -(strlen($this->LE))) != $this->LE)
+                $encoded .= $this->LE;
+              break;
+          case "binary":
+              $encoded = $str;
+              break;
+          case "quoted-printable":
+              $encoded = $this->EncodeQP($str);
+              break;
+          default:
+              $this->SetError($this->Lang("encoding") . $encoding);
+              break;
+        }
+        return $encoded;
+    }
+
+    /**
+     * Encode a header string to best of Q, B, quoted or none.  
+     * @access private
+     * @return string
+     */
+    function EncodeHeader ($str, $position = 'text') {
+      $x = 0;
+      
+      switch (strtolower($position)) {
+        case 'phrase':
+          if (!preg_match('/[\200-\377]/', $str)) {
+            // Can't use addslashes as we don't know what value has magic_quotes_sybase.
+            $encoded = addcslashes($str, "\0..\37\177\\\"");
+
+            if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str))
+              return ($encoded);
+            else
+              return ("\"$encoded\"");
+          }
+          $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
+          break;
+        case 'comment':
+          $x = preg_match_all('/[()"]/', $str, $matches);
+          // Fall-through
+        case 'text':
+        default:
+          $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
+          break;
+      }
+
+      if ($x == 0)
+        return ($str);
+
+      $maxlen = 75 - 7 - strlen($this->CharSet);
+      // Try to select the encoding which should produce the shortest output
+      if (strlen($str)/3 < $x) {
+        $encoding = 'B';
+        $encoded = base64_encode($str);
+        $maxlen -= $maxlen % 4;
+        $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
+      } else {
+        $encoding = 'Q';
+        $encoded = $this->EncodeQ($str, $position);
+        $encoded = $this->WrapText($encoded, $maxlen, true);
+        $encoded = str_replace("=".$this->LE, "\n", trim($encoded));
+      }
+
+      $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
+      $encoded = trim(str_replace("\n", $this->LE, $encoded));
+      
+      return $encoded;
+    }
+    
+    /**
+     * Encode string to quoted-printable.  
+     * @access private
+     * @return string
+     */
+    function EncodeQP ($str) {
+        $encoded = $this->FixEOL($str);
+        if (substr($encoded, -(strlen($this->LE))) != $this->LE)
+            $encoded .= $this->LE;
+
+        // Replace every high ascii, control and = characters
+        $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e',
+                  "'='.sprintf('%02X', ord('\\1'))", $encoded);
+        // Replace every spaces and tabs when it's the last character on a line
+        $encoded = preg_replace("/([\011\040])".$this->LE."/e",
+                  "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded);
+
+        // Maximum line length of 76 characters before CRLF (74 + space + '=')
+        $encoded = $this->WrapText($encoded, 74, true);
+
+        return $encoded;
+    }
+
+    /**
+     * Encode string to q encoding.  
+     * @access private
+     * @return string
+     */
+    function EncodeQ ($str, $position = "text") {
+        // There should not be any EOL in the string
+        $encoded = preg_replace("[\r\n]", "", $str);
+
+        switch (strtolower($position)) {
+          case "phrase":
+            $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
+            break;
+          case "comment":
+            $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
+          case "text":
+          default:
+            // Replace every high ascii, control =, ? and _ characters
+            $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
+                  "'='.sprintf('%02X', ord('\\1'))", $encoded);
+            break;
+        }
+        
+        // Replace every spaces to _ (more readable than =20)
+        $encoded = str_replace(" ", "_", $encoded);
+
+        return $encoded;
+    }
+
+    /**
+     * Adds a string or binary attachment (non-filesystem) to the list.
+     * This method can be used to attach ascii or binary data,
+     * such as a BLOB record from a database.
+     * @param string $string String attachment data.
+     * @param string $filename Name of the attachment.
+     * @param string $encoding File encoding (see $Encoding).
+     * @param string $type File extension (MIME) type.
+     * @return void
+     */
+    function AddStringAttachment($string, $filename, $encoding = "base64", 
+                                 $type = "application/octet-stream") {
+        // Append to $attachment array
+        $cur = count($this->attachment);
+        $this->attachment[$cur][0] = $string;
+        $this->attachment[$cur][1] = $filename;
+        $this->attachment[$cur][2] = $filename;
+        $this->attachment[$cur][3] = $encoding;
+        $this->attachment[$cur][4] = $type;
+        $this->attachment[$cur][5] = true; // isString
+        $this->attachment[$cur][6] = "attachment";
+        $this->attachment[$cur][7] = 0;
+    }
+    
+    /**
+     * Adds an embedded attachment.  This can include images, sounds, and 
+     * just about any other document.  Make sure to set the $type to an 
+     * image type.  For JPEG images use "image/jpeg" and for GIF images 
+     * use "image/gif".
+     * @param string $path Path to the attachment.
+     * @param string $cid Content ID of the attachment.  Use this to identify 
+     *        the Id for accessing the image in an HTML form.
+     * @param string $name Overrides the attachment name.
+     * @param string $encoding File encoding (see $Encoding).
+     * @param string $type File extension (MIME) type.  
+     * @return bool
+     */
+    function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", 
+                              $type = "application/octet-stream") {
+    
+        if(!@is_file($path))
+        {
+            $this->SetError($this->Lang("file_access") . $path);
+            return false;
+        }
+
+        $filename = basename($path);
+        if($name == "")
+            $name = $filename;
+
+        // Append to $attachment array
+        $cur = count($this->attachment);
+        $this->attachment[$cur][0] = $path;
+        $this->attachment[$cur][1] = $filename;
+        $this->attachment[$cur][2] = $name;
+        $this->attachment[$cur][3] = $encoding;
+        $this->attachment[$cur][4] = $type;
+        $this->attachment[$cur][5] = false; // isStringAttachment
+        $this->attachment[$cur][6] = "inline";
+        $this->attachment[$cur][7] = $cid;
+    
+        return true;
+    }
+    
+    /**
+     * Returns true if an inline attachment is present.
+     * @access private
+     * @return bool
+     */
+    function InlineImageExists() {
+        $result = false;
+        for($i = 0; $i < count($this->attachment); $i++)
+        {
+            if($this->attachment[$i][6] == "inline")
+            {
+                $result = true;
+                break;
+            }
+        }
+        
+        return $result;
+    }
+
+    /////////////////////////////////////////////////
+    // MESSAGE RESET METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Clears all recipients assigned in the TO array.  Returns void.
+     * @return void
+     */
+    function ClearAddresses() {
+        $this->to = array();
+    }
+
+    /**
+     * Clears all recipients assigned in the CC array.  Returns void.
+     * @return void
+     */
+    function ClearCCs() {
+        $this->cc = array();
+    }
+
+    /**
+     * Clears all recipients assigned in the BCC array.  Returns void.
+     * @return void
+     */
+    function ClearBCCs() {
+        $this->bcc = array();
+    }
+
+    /**
+     * Clears all recipients assigned in the ReplyTo array.  Returns void.
+     * @return void
+     */
+    function ClearReplyTos() {
+        $this->ReplyTo = array();
+    }
+
+    /**
+     * Clears all recipients assigned in the TO, CC and BCC
+     * array.  Returns void.
+     * @return void
+     */
+    function ClearAllRecipients() {
+        $this->to = array();
+        $this->cc = array();
+        $this->bcc = array();
+    }
+
+    /**
+     * Clears all previously set filesystem, string, and binary
+     * attachments.  Returns void.
+     * @return void
+     */
+    function ClearAttachments() {
+        $this->attachment = array();
+    }
+
+    /**
+     * Clears all custom headers.  Returns void.
+     * @return void
+     */
+    function ClearCustomHeaders() {
+        $this->CustomHeader = array();
+    }
+
+
+    /////////////////////////////////////////////////
+    // MISCELLANEOUS METHODS
+    /////////////////////////////////////////////////
+
+    /**
+     * Adds the error message to the error container.
+     * Returns void.
+     * @access private
+     * @return void
+     */
+    function SetError($msg) {
+        $this->error_count++;
+        $this->ErrorInfo = $msg;
+    }
+
+    /**
+     * Returns the proper RFC 822 formatted date. 
+     * @access private
+     * @return string
+     */
+    function RFCDate() {
+        $tz = date("Z");
+        $tzs = ($tz < 0) ? "-" : "+";
+        $tz = abs($tz);
+        $tz = ($tz/3600)*100 + ($tz%3600)/60;
+        $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);
+
+        return $result;
+    }
+    
+    /**
+     * Returns the appropriate server variable.  Should work with both 
+     * PHP 4.1.0+ as well as older versions.  Returns an empty string 
+     * if nothing is found.
+     * @access private
+     * @return mixed
+     */
+    function ServerVar($varName) {
+        global $HTTP_SERVER_VARS;
+        global $HTTP_ENV_VARS;
+
+        if(!isset($_SERVER))
+        {
+            $_SERVER = $HTTP_SERVER_VARS;
+            if(!isset($_SERVER["REMOTE_ADDR"]))
+                $_SERVER = $HTTP_ENV_VARS; // must be Apache
+        }
+        
+        if(isset($_SERVER[$varName]))
+            return $_SERVER[$varName];
+        else
+            return "";
+    }
+
+    /**
+     * Returns the server hostname or 'localhost.localdomain' if unknown.
+     * @access private
+     * @return string
+     */
+    function ServerHostname() {
+        if ($this->Hostname != "")
+            $result = $this->Hostname;
+        elseif ($this->ServerVar('SERVER_NAME') != "")
+            $result = $this->ServerVar('SERVER_NAME');
+        else
+            $result = "localhost.localdomain";
+
+        return $result;
+    }
+
+    /**
+     * Returns a message in the appropriate language.
+     * @access private
+     * @return string
+     */
+    function Lang($key) {
+        if(count($this->language) < 1)
+            $this->SetLanguage("en"); // set the default language
+    
+        if(isset($this->language[$key]))
+            return $this->language[$key];
+        else
+            return "Language string failed to load: " . $key;
+    }
+    
+    /**
+     * Returns true if an error occurred.
+     * @return bool
+     */
+    function IsError() {
+        return ($this->error_count > 0);
+    }
+
+    /**
+     * Changes every end of line from CR or LF to CRLF.  
+     * @access private
+     * @return string
+     */
+    function FixEOL($str) {
+        $str = str_replace("\r\n", "\n", $str);
+        $str = str_replace("\r", "\n", $str);
+        $str = str_replace("\n", $this->LE, $str);
+        return $str;
+    }
+
+    /**
+     * Adds a custom header. 
+     * @return void
+     */
+    function AddCustomHeader($custom_header) {
+        $this->CustomHeader[] = explode(":", $custom_header, 2);
+    }
+}
+
+?>
diff -ruN 2.0.5/wp-includes/class-pop3.php 2.2.2/wp-includes/class-pop3.php
--- 2.0.5/wp-includes/class-pop3.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/class-pop3.php	2007-02-25 12:19:21.000000000 -0600
@@ -3,7 +3,7 @@
    /**
     * mail_fetch/setup.php
     *
-    * Copyright (c) 1999-2002 The SquirrelMail Project Team
+    * Copyright (c) 1999-2006 The SquirrelMail Project Team
     *
     * Copyright (c) 1999 CDI (cdi@thewebmasters.net) All Rights Reserved
     * Modified by Philippe Mingo 2001 mingo@rotedic.com
@@ -13,7 +13,7 @@
     *
     * pop3 class
     *
-    * $Id: class-pop3.php 2066 2005-01-07 01:29:49Z saxmatt $
+    * $Id: class-pop3.php 4945 2007-02-25 18:19:21Z ryan $
     */
 
 class POP3 {
@@ -40,9 +40,6 @@
     var $BANNER     = '';       //  Holds the banner returned by the
                                 //  pop server - used for apop()
 
-    var $RFC1939    = TRUE;     //  Set by noop(). See rfc1939.txt
-                                //
-
     var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop()
                                 //  This must be set to true
                                 //  manually
@@ -59,12 +56,14 @@
         if(!empty($timeout)) {
             settype($timeout,"integer");
             $this->TIMEOUT = $timeout;
+            if (!ini_get('safe_mode'))
             set_time_limit($timeout);
         }
         return true;
     }
 
     function update_timer () {
+        if (!ini_get('safe_mode'))
         set_time_limit($this->TIMEOUT);
         return true;
     }
@@ -75,6 +74,7 @@
 
         // If MAILSERVER is set, override $server with it's value
 
+        if (!isset($port) || !$port) {$port = 110;}
         if(!empty($this->MAILSERVER))
             $server = $this->MAILSERVER;
 
@@ -84,7 +84,7 @@
             return false;
         }
 
-        $fp = fsockopen("$server", $port, $errno, $errstr);
+        $fp = @fsockopen("$server", $port, $errno, $errstr);
 
         if(!$fp) {
             $this->ERROR = _("POP3 connect:") . ' ' . _("Error ") . "[$errno] [$errstr]";
@@ -105,25 +105,7 @@
         }
         $this->FP = $fp;
         $this->BANNER = $this->parse_banner($reply);
-        $this->RFC1939 = $this->noop();
-        if($this->RFC1939) {
-            $this->ERROR = _("POP3: premature NOOP OK, NOT an RFC 1939 Compliant server");
-            $this->quit();
-            return false;
-        } else
-            return true;
-    }
-
-    function noop () {
-    
-        if(!isset($this->FP)) {
-            $this->ERROR = _("POP3 noop:") . ' ' . _("No connection to server");
-            return false;
-        } else {
-            $cmd = "NOOP";
-            $reply = $this->send_cmd( $cmd );
-            return( $this->is_ok( $reply ) );
-        }
+        return true;
     }
 
     function user ($user = "") {
@@ -158,20 +140,14 @@
         } else {
             $reply = $this->send_cmd("PASS $pass");
             if(!$this->is_ok($reply)) {
-                $this->ERROR = _("POP3 pass:") . ' ' . _("authentication failed ") . "[$reply]";
+                $this->ERROR = _("POP3 pass:") . ' ' . _("Authentication failed ") . "[$reply]";
                 $this->quit();
                 return false;
             } else {
                 //  Auth successful.
                 $count = $this->last("count");
                 $this->COUNT = $count;
-                $this->RFC1939 = $this->noop();
-                if(!$this->RFC1939) {
-                    $this->ERROR = _("POP3 pass:") . ' ' . _("NOOP failed. Server not RFC 1939 compliant");
-                    $this->quit();
-                    return false;
-                } else
-                    return $count;
+                return $count;
             }
         }
     }
@@ -214,13 +190,7 @@
                     //  Auth successful.
                     $count = $this->last("count");
                     $this->COUNT = $count;
-                    $this->RFC1939 = $this->noop();
-                    if(!$this->RFC1939) {
-                        $this->ERROR = _("POP3 apop:") . ' ' . _("NOOP failed. Server not RFC 1939 compliant");
-                        $this->quit();
-                        return false;
-                    } else
-                        return $count;
+                    return $count;
                 }
             }
         }
@@ -330,7 +300,7 @@
                 $this->ERROR = _("POP3 pop_list:") . ' ' . _("Error ") . "[$reply]";
                 return false;
             }
-            list($junk,$num,$size) = explode(" ",$reply);
+            list($junk,$num,$size) = preg_split('/\s+/',$reply);
             return $size;
         }
         $cmd = "LIST";
@@ -353,7 +323,7 @@
                 $this->ERROR = _("POP3 pop_list:") . ' ' . _("Premature end of list");
                 return false;
             }
-            list($thisMsg,$msgSize) = explode(" ",$line);
+            list($thisMsg,$msgSize) = preg_split('/\s+/',$line);
             settype($thisMsg,"integer");
             if($thisMsg != $msgC)
             {
@@ -393,13 +363,18 @@
         $count = 0;
         $MsgArray = array();
 
-        $line = fgets($fp,$buffer);
+        $line = "";
         while ( !ereg("^\.\r\n",$line))
         {
-            $MsgArray[$count] = $line;
-            $count++;
             $line = fgets($fp,$buffer);
+            if (preg_match("/^\s+/", $line) && $count > 0) {
+                $MsgArray[$count-1] .= $line;
+                continue;
+            }
             if(empty($line))    { break; }
+
+            $MsgArray[$count] = $line;
+            $count++;
         }
         return $MsgArray;
     }
@@ -423,7 +398,7 @@
             return $last;
         }
 
-        $Vars = explode(" ",$reply);
+        $Vars = preg_split('/\s+/',$reply);
         $count = $Vars[1];
         $size = $Vars[2];
         settype($count,"integer");
@@ -554,7 +529,7 @@
                 $this->ERROR = _("POP3 uidl:") . ' ' . _("Error ") . "[$reply]";
                 return false;
             }
-            list ($ok,$num,$myUidl) = explode(" ",$reply);
+            list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);
             return $myUidl;
         } else {
             $this->update_timer();
@@ -585,7 +560,7 @@
                 if(ereg("^\.\r\n",$line)) {
                     break;
                 }
-                list ($msg,$msgUidl) = explode(" ",$line);
+                list ($msg,$msgUidl) = preg_split('/\s+/',$line);
                 $msgUidl = $this->strip_clf($msgUidl);
                 if($count == $msg) {
                     $UIDLArray[$msg] = $msgUidl;
@@ -656,7 +631,7 @@
         for($count =0; $count < $length; $count++)
         {
             $digit = substr($server_text, $count, 1);
-            if ( false !== $digit ) {
+            if (!empty($digit)) {
                 if( (!$outside) && ($digit != '<') && ($digit != '>') )
                 {
                     $banner .= $digit;
diff -ruN 2.0.5/wp-includes/class-smtp.php 2.2.2/wp-includes/class-smtp.php
--- 2.0.5/wp-includes/class-smtp.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/class-smtp.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,1045 @@
+<?php
+////////////////////////////////////////////////////
+// SMTP - PHP SMTP class
+//
+// Version 1.02
+//
+// Define an SMTP class that can be used to connect
+// and communicate with any SMTP server. It implements
+// all the SMTP functions defined in RFC821 except TURN.
+//
+// Author: Chris Ryan
+//
+// License: LGPL, see LICENSE
+////////////////////////////////////////////////////
+
+/**
+ * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
+ * commands except TURN which will always return a not implemented
+ * error. SMTP also provides some utility methods for sending mail
+ * to an SMTP server.
+ * @package PHPMailer
+ * @author Chris Ryan
+ */
+class SMTP
+{
+    /**
+     *  SMTP server port
+     *  @var int
+     */
+    var $SMTP_PORT = 25;
+    
+    /**
+     *  SMTP reply line ending
+     *  @var string
+     */
+    var $CRLF = "\r\n";
+    
+    /**
+     *  Sets whether debugging is turned on
+     *  @var bool
+     */
+    var $do_debug;       # the level of debug to perform
+
+    /**#@+
+     * @access private
+     */
+    var $smtp_conn;      # the socket to the server
+    var $error;          # error if any on the last call
+    var $helo_rply;      # the reply the server sent to us for HELO
+    /**#@-*/
+
+    /**
+     * Initialize the class so that the data is in a known state.
+     * @access public
+     * @return void
+     */
+    function SMTP() {
+        $this->smtp_conn = 0;
+        $this->error = null;
+        $this->helo_rply = null;
+
+        $this->do_debug = 0;
+    }
+
+    /*************************************************************
+     *                    CONNECTION FUNCTIONS                  *
+     ***********************************************************/
+
+    /**
+     * Connect to the server specified on the port specified.
+     * If the port is not specified use the default SMTP_PORT.
+     * If tval is specified then a connection will try and be
+     * established with the server for that number of seconds.
+     * If tval is not specified the default is 30 seconds to
+     * try on the connection.
+     *
+     * SMTP CODE SUCCESS: 220
+     * SMTP CODE FAILURE: 421
+     * @access public
+     * @return bool
+     */
+    function Connect($host,$port=0,$tval=30) {
+        # set the error val to null so there is no confusion
+        $this->error = null;
+
+        # make sure we are __not__ connected
+        if($this->connected()) {
+            # ok we are connected! what should we do?
+            # for now we will just give an error saying we
+            # are already connected
+            $this->error =
+                array("error" => "Already connected to a server");
+            return false;
+        }
+
+        if(empty($port)) {
+            $port = $this->SMTP_PORT;
+        }
+
+        #connect to the smtp server
+        $this->smtp_conn = fsockopen($host,    # the host of the server
+                                     $port,    # the port to use
+                                     $errno,   # error number if any
+                                     $errstr,  # error message if any
+                                     $tval);   # give up after ? secs
+        # verify we connected properly
+        if(empty($this->smtp_conn)) {
+            $this->error = array("error" => "Failed to connect to server",
+                                 "errno" => $errno,
+                                 "errstr" => $errstr);
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": $errstr ($errno)" . $this->CRLF;
+            }
+            return false;
+        }
+
+        # sometimes the SMTP server takes a little longer to respond
+        # so we will give it a longer timeout for the first read
+        // Windows still does not have support for this timeout function
+        if(substr(PHP_OS, 0, 3) != "WIN")
+           socket_set_timeout($this->smtp_conn, $tval, 0);
+
+        # get any announcement stuff
+        $announce = $this->get_lines();
+
+        # set the timeout  of any socket functions at 1/10 of a second
+        //if(function_exists("socket_set_timeout"))
+        //   socket_set_timeout($this->smtp_conn, 0, 100000);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
+        }
+
+        return true;
+    }
+
+    /**
+     * Performs SMTP authentication.  Must be run after running the
+     * Hello() method.  Returns true if successfully authenticated.
+     * @access public
+     * @return bool
+     */
+    function Authenticate($username, $password) {
+        // Start authentication
+        fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($code != 334) {
+            $this->error =
+                array("error" => "AUTH not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        // Send encoded username
+        fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($code != 334) {
+            $this->error =
+                array("error" => "Username not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        // Send encoded password
+        fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($code != 235) {
+            $this->error =
+                array("error" => "Password not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if connected to a server otherwise false
+     * @access private
+     * @return bool
+     */
+    function Connected() {
+        if(!empty($this->smtp_conn)) {
+            $sock_status = socket_get_status($this->smtp_conn);
+            if($sock_status["eof"]) {
+                # hmm this is an odd situation... the socket is
+                # valid but we aren't connected anymore
+                if($this->do_debug >= 1) {
+                    echo "SMTP -> NOTICE:" . $this->CRLF .
+                         "EOF caught while checking if connected";
+                }
+                $this->Close();
+                return false;
+            }
+            return true; # everything looks good
+        }
+        return false;
+    }
+
+    /**
+     * Closes the socket and cleans up the state of the class.
+     * It is not considered good to use this function without
+     * first trying to use QUIT.
+     * @access public
+     * @return void
+     */
+    function Close() {
+        $this->error = null; # so there is no confusion
+        $this->helo_rply = null;
+        if(!empty($this->smtp_conn)) {
+            # close the connection and cleanup
+            fclose($this->smtp_conn);
+            $this->smtp_conn = 0;
+        }
+    }
+
+
+    /***************************************************************
+     *                        SMTP COMMANDS                       *
+     *************************************************************/
+
+    /**
+     * Issues a data command and sends the msg_data to the server
+     * finializing the mail transaction. $msg_data is the message
+     * that is to be send with the headers. Each header needs to be
+     * on a single line followed by a <CRLF> with the message headers
+     * and the message body being seperated by and additional <CRLF>.
+     *
+     * Implements rfc 821: DATA <CRLF>
+     *
+     * SMTP CODE INTERMEDIATE: 354
+     *     [data]
+     *     <CRLF>.<CRLF>
+     *     SMTP CODE SUCCESS: 250
+     *     SMTP CODE FAILURE: 552,554,451,452
+     * SMTP CODE FAILURE: 451,554
+     * SMTP CODE ERROR  : 500,501,503,421
+     * @access public
+     * @return bool
+     */
+    function Data($msg_data) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Data() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"DATA" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 354) {
+            $this->error =
+                array("error" => "DATA command not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        # the server is ready to accept data!
+        # according to rfc 821 we should not send more than 1000
+        # including the CRLF
+        # characters on a single line so we will break the data up
+        # into lines by \r and/or \n then if needed we will break
+        # each of those into smaller lines to fit within the limit.
+        # in addition we will be looking for lines that start with
+        # a period '.' and append and additional period '.' to that
+        # line. NOTE: this does not count towards are limit.
+
+        # normalize the line breaks so we know the explode works
+        $msg_data = str_replace("\r\n","\n",$msg_data);
+        $msg_data = str_replace("\r","\n",$msg_data);
+        $lines = explode("\n",$msg_data);
+
+        # we need to find a good way to determine is headers are
+        # in the msg_data or if it is a straight msg body
+        # currently I'm assuming rfc 822 definitions of msg headers
+        # and if the first field of the first line (':' sperated)
+        # does not contain a space then it _should_ be a header
+        # and we can process all lines before a blank "" line as
+        # headers.
+        $field = substr($lines[0],0,strpos($lines[0],":"));
+        $in_headers = false;
+        if(!empty($field) && !strstr($field," ")) {
+            $in_headers = true;
+        }
+
+        $max_line_length = 998; # used below; set here for ease in change
+
+        while(list(,$line) = @each($lines)) {
+            $lines_out = null;
+            if($line == "" && $in_headers) {
+                $in_headers = false;
+            }
+            # ok we need to break this line up into several
+            # smaller lines
+            while(strlen($line) > $max_line_length) {
+                $pos = strrpos(substr($line,0,$max_line_length)," ");
+
+                # Patch to fix DOS attack
+                if(!$pos) {
+                    $pos = $max_line_length - 1;
+                }
+
+                $lines_out[] = substr($line,0,$pos);
+                $line = substr($line,$pos + 1);
+                # if we are processing headers we need to
+                # add a LWSP-char to the front of the new line
+                # rfc 822 on long msg headers
+                if($in_headers) {
+                    $line = "\t" . $line;
+                }
+            }
+            $lines_out[] = $line;
+
+            # now send the lines to the server
+            while(list(,$line_out) = @each($lines_out)) {
+                if(strlen($line_out) > 0)
+                {
+                    if(substr($line_out, 0, 1) == ".") {
+                        $line_out = "." . $line_out;
+                    }
+                }
+                fputs($this->smtp_conn,$line_out . $this->CRLF);
+            }
+        }
+
+        # ok all the message data has been sent so lets get this
+        # over with aleady
+        fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "DATA not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Expand takes the name and asks the server to list all the
+     * people who are members of the _list_. Expand will return
+     * back and array of the result or false if an error occurs.
+     * Each value in the array returned has the format of:
+     *     [ <full-name> <sp> ] <path>
+     * The definition of <path> is defined in rfc 821
+     *
+     * Implements rfc 821: EXPN <SP> <string> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE FAILURE: 550
+     * SMTP CODE ERROR  : 500,501,502,504,421
+     * @access public
+     * @return string array
+     */
+    function Expand($name) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Expand() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "EXPN not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        # parse the reply and place in our array to return to user
+        $entries = explode($this->CRLF,$rply);
+        while(list(,$l) = @each($entries)) {
+            $list[] = substr($l,4);
+        }
+
+        return $list;
+    }
+
+    /**
+     * Sends the HELO command to the smtp server.
+     * This makes sure that we and the server are in
+     * the same known state.
+     *
+     * Implements from rfc 821: HELO <SP> <domain> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE ERROR  : 500, 501, 504, 421
+     * @access public
+     * @return bool
+     */
+    function Hello($host="") {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Hello() without being connected");
+            return false;
+        }
+
+        # if a hostname for the HELO wasn't specified determine
+        # a suitable one to send
+        if(empty($host)) {
+            # we need to determine some sort of appopiate default
+            # to send to the server
+            $host = "localhost";
+        }
+
+        // Send extended hello first (RFC 2821)
+        if(!$this->SendHello("EHLO", $host))
+        {
+            if(!$this->SendHello("HELO", $host))
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sends a HELO/EHLO command.
+     * @access private
+     * @return bool
+     */
+    function SendHello($hello, $host) {
+        fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => $hello . " not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        $this->helo_rply = $rply;
+        
+        return true;
+    }
+
+    /**
+     * Gets help information on the keyword specified. If the keyword
+     * is not specified then returns generic help, ussually contianing
+     * A list of keywords that help is available on. This function
+     * returns the results back to the user. It is up to the user to
+     * handle the returned data. If an error occurs then false is
+     * returned with $this->error set appropiately.
+     *
+     * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
+     *
+     * SMTP CODE SUCCESS: 211,214
+     * SMTP CODE ERROR  : 500,501,502,504,421
+     * @access public
+     * @return string
+     */
+    function Help($keyword="") {
+        $this->error = null; # to avoid confusion
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Help() without being connected");
+            return false;
+        }
+
+        $extra = "";
+        if(!empty($keyword)) {
+            $extra = " " . $keyword;
+        }
+
+        fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 211 && $code != 214) {
+            $this->error =
+                array("error" => "HELP not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        return $rply;
+    }
+
+    /**
+     * Starts a mail transaction from the email address specified in
+     * $from. Returns true if successful or false otherwise. If True
+     * the mail transaction is started and then one or more Recipient
+     * commands may be called followed by a Data command.
+     *
+     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE SUCCESS: 552,451,452
+     * SMTP CODE SUCCESS: 500,501,421
+     * @access public
+     * @return bool
+     */
+    function Mail($from) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Mail() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "MAIL not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Sends the command NOOP to the SMTP server.
+     *
+     * Implements from rfc 821: NOOP <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE ERROR  : 500, 421
+     * @access public
+     * @return bool
+     */
+    function Noop() {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Noop() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"NOOP" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "NOOP not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Sends the quit command to the server and then closes the socket
+     * if there is no error or the $close_on_error argument is true.
+     *
+     * Implements from rfc 821: QUIT <CRLF>
+     *
+     * SMTP CODE SUCCESS: 221
+     * SMTP CODE ERROR  : 500
+     * @access public
+     * @return bool
+     */
+    function Quit($close_on_error=true) {
+        $this->error = null; # so there is no confusion
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Quit() without being connected");
+            return false;
+        }
+
+        # send the quit command to the server
+        fputs($this->smtp_conn,"quit" . $this->CRLF);
+
+        # get any good-bye messages
+        $byemsg = $this->get_lines();
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
+        }
+
+        $rval = true;
+        $e = null;
+
+        $code = substr($byemsg,0,3);
+        if($code != 221) {
+            # use e as a tmp var cause Close will overwrite $this->error
+            $e = array("error" => "SMTP server rejected quit command",
+                       "smtp_code" => $code,
+                       "smtp_rply" => substr($byemsg,4));
+            $rval = false;
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $e["error"] . ": " .
+                         $byemsg . $this->CRLF;
+            }
+        }
+
+        if(empty($e) || $close_on_error) {
+            $this->Close();
+        }
+
+        return $rval;
+    }
+
+    /**
+     * Sends the command RCPT to the SMTP server with the TO: argument of $to.
+     * Returns true if the recipient was accepted false if it was rejected.
+     *
+     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250,251
+     * SMTP CODE FAILURE: 550,551,552,553,450,451,452
+     * SMTP CODE ERROR  : 500,501,503,421
+     * @access public
+     * @return bool
+     */
+    function Recipient($to) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Recipient() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250 && $code != 251) {
+            $this->error =
+                array("error" => "RCPT not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Sends the RSET command to abort and transaction that is
+     * currently in progress. Returns true if successful false
+     * otherwise.
+     *
+     * Implements rfc 821: RSET <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE ERROR  : 500,501,504,421
+     * @access public
+     * @return bool
+     */
+    function Reset() {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Reset() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"RSET" . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "RSET failed",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Starts a mail transaction from the email address specified in
+     * $from. Returns true if successful or false otherwise. If True
+     * the mail transaction is started and then one or more Recipient
+     * commands may be called followed by a Data command. This command
+     * will send the message to the users terminal if they are logged
+     * in.
+     *
+     * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE SUCCESS: 552,451,452
+     * SMTP CODE SUCCESS: 500,501,502,421
+     * @access public
+     * @return bool
+     */
+    function Send($from) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Send() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "SEND not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Starts a mail transaction from the email address specified in
+     * $from. Returns true if successful or false otherwise. If True
+     * the mail transaction is started and then one or more Recipient
+     * commands may be called followed by a Data command. This command
+     * will send the message to the users terminal if they are logged
+     * in and send them an email.
+     *
+     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE SUCCESS: 552,451,452
+     * SMTP CODE SUCCESS: 500,501,502,421
+     * @access public
+     * @return bool
+     */
+    function SendAndMail($from) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                "error" => "Called SendAndMail() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "SAML not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Starts a mail transaction from the email address specified in
+     * $from. Returns true if successful or false otherwise. If True
+     * the mail transaction is started and then one or more Recipient
+     * commands may be called followed by a Data command. This command
+     * will send the message to the users terminal if they are logged
+     * in or mail it to them if they are not.
+     *
+     * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE SUCCESS: 552,451,452
+     * SMTP CODE SUCCESS: 500,501,502,421
+     * @access public
+     * @return bool
+     */
+    function SendOrMail($from) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                "error" => "Called SendOrMail() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250) {
+            $this->error =
+                array("error" => "SOML not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This is an optional command for SMTP that this class does not
+     * support. This method is here to make the RFC821 Definition
+     * complete for this class and __may__ be implimented in the future
+     *
+     * Implements from rfc 821: TURN <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250
+     * SMTP CODE FAILURE: 502
+     * SMTP CODE ERROR  : 500, 503
+     * @access public
+     * @return bool
+     */
+    function Turn() {
+        $this->error = array("error" => "This method, TURN, of the SMTP ".
+                                        "is not implemented");
+        if($this->do_debug >= 1) {
+            echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
+        }
+        return false;
+    }
+
+    /**
+     * Verifies that the name is recognized by the server.
+     * Returns false if the name could not be verified otherwise
+     * the response from the server is returned.
+     *
+     * Implements rfc 821: VRFY <SP> <string> <CRLF>
+     *
+     * SMTP CODE SUCCESS: 250,251
+     * SMTP CODE FAILURE: 550,551,553
+     * SMTP CODE ERROR  : 500,501,502,421
+     * @access public
+     * @return int
+     */
+    function Verify($name) {
+        $this->error = null; # so no confusion is caused
+
+        if(!$this->connected()) {
+            $this->error = array(
+                    "error" => "Called Verify() without being connected");
+            return false;
+        }
+
+        fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($this->do_debug >= 2) {
+            echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+        }
+
+        if($code != 250 && $code != 251) {
+            $this->error =
+                array("error" => "VRFY failed on name '$name'",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                echo "SMTP -> ERROR: " . $this->error["error"] .
+                         ": " . $rply . $this->CRLF;
+            }
+            return false;
+        }
+        return $rply;
+    }
+
+    /*******************************************************************
+     *                       INTERNAL FUNCTIONS                       *
+     ******************************************************************/
+
+    /**
+     * Read in as many lines as possible
+     * either before eof or socket timeout occurs on the operation.
+     * With SMTP we can tell if we have more lines to read if the
+     * 4th character is '-' symbol. If it is a space then we don't
+     * need to read anything else.
+     * @access private
+     * @return string
+     */
+    function get_lines() {
+        $data = "";
+        while($str = fgets($this->smtp_conn,515)) {
+            if($this->do_debug >= 4) {
+                echo "SMTP -> get_lines(): \$data was \"$data\"" .
+                         $this->CRLF;
+                echo "SMTP -> get_lines(): \$str is \"$str\"" .
+                         $this->CRLF;
+            }
+            $data .= $str;
+            if($this->do_debug >= 4) {
+                echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
+            }
+            # if the 4th character is a space then we are done reading
+            # so just break the loop
+            if(substr($str,3,1) == " ") { break; }
+        }
+        return $data;
+    }
+
+}
+
+
+ ?>
diff -ruN 2.0.5/wp-includes/class-snoopy.php 2.2.2/wp-includes/class-snoopy.php
--- 2.0.5/wp-includes/class-snoopy.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/class-snoopy.php	2006-08-04 23:18:09.000000000 -0500
@@ -39,7 +39,7 @@
 class Snoopy
 {
 	/**** Public variables ****/
-	
+
 	/* user definable vars */
 
 	var $host			=	"www.php.net";		// host name we are connecting to
@@ -48,7 +48,7 @@
 	var $proxy_port		=	"";					// proxy port to use
 	var $proxy_user		=	"";					// proxy user to use
 	var $proxy_pass		=	"";					// proxy password to use
-	
+
 	var $agent			=	"Snoopy v1.2.3";	// agent we masquerade as
 	var	$referer		=	"";					// referer info to pass
 	var $cookies		=	array();			// array of cookies to pass
@@ -66,15 +66,15 @@
 	var $passcookies	=	true;				// pass set cookies back through redirects
 												// NOTE: this currently does not respect
 												// dates, domains or paths.
-	
+
 	var	$user			=	"";					// user for http authentication
 	var	$pass			=	"";					// password for http authentication
-	
+
 	// http accept types
 	var $accept			=	"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
-	
+
 	var $results		=	"";					// where the content is put
-		
+
 	var $error			=	"";					// error messages sent here
 	var	$response_code	=	"";					// response code returned from server
 	var	$headers		=	array();			// headers returned from server sent here
@@ -100,11 +100,11 @@
 												// library functions built into php,
 												// as these functions are not stable
 												// as of this Snoopy release.
-	
-	/**** Private variables ****/	
-	
+
+	/**** Private variables ****/
+
 	var	$_maxlinelen	=	4096;				// max line length (headers)
-	
+
 	var $_httpmethod	=	"GET";				// default http request method
 	var $_httpversion	=	"HTTP/1.0";			// default http request version
 	var $_submit_method	=	"POST";				// default submit method
@@ -114,7 +114,7 @@
 	var $_redirectdepth	=	0;					// increments on an http redirect
 	var $_frameurls		= 	array();			// frame src urls
 	var $_framedepth	=	0;					// increments on frame depth
-	
+
 	var $_isproxy		=	false;				// set if using a proxy server
 	var $_fp_timeout	=	30;					// timeout for socket connection
 
@@ -129,7 +129,7 @@
 
 	function fetch($URI)
 	{
-	
+
 		//preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
 		$URI_PARTS = parse_url($URI);
 		if (!empty($URI_PARTS["user"]))
@@ -140,7 +140,7 @@
 			$URI_PARTS["query"] = '';
 		if (empty($URI_PARTS["path"]))
 			$URI_PARTS["path"] = '';
-				
+
 		switch(strtolower($URI_PARTS["scheme"]))
 		{
 			case "http":
@@ -160,7 +160,7 @@
 						// no proxy, send only the path
 						$this->_httprequest($path, $fp, $URI, $this->_httpmethod);
 					}
-					
+
 					$this->_disconnect($fp);
 
 					if($this->_redirectaddr)
@@ -183,7 +183,7 @@
 					{
 						$frameurls = $this->_frameurls;
 						$this->_frameurls = array();
-						
+
 						while(list(,$frameurl) = each($frameurls))
 						{
 							if($this->_framedepth < $this->maxframes)
@@ -194,13 +194,13 @@
 							else
 								break;
 						}
-					}					
+					}
 				}
 				else
 				{
 					return false;
 				}
-				return true;					
+				return true;
 				break;
 			case "https":
 				if(!$this->curl_path)
@@ -254,15 +254,15 @@
 						else
 							break;
 					}
-				}					
-				return true;					
+				}
+				return true;
 				break;
 			default:
 				// not a valid protocol
 				$this->error	=	'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
 				return false;
 				break;
-		}		
+		}
 		return true;
 	}
 
@@ -280,9 +280,9 @@
 	function submit($URI, $formvars="", $formfiles="")
 	{
 		unset($postdata);
-		
+
 		$postdata = $this->_prepare_post_body($formvars, $formfiles);
-			
+
 		$URI_PARTS = parse_url($URI);
 		if (!empty($URI_PARTS["user"]))
 			$this->user = $URI_PARTS["user"];
@@ -312,17 +312,17 @@
 						// no proxy, send only the path
 						$this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
 					}
-					
+
 					$this->_disconnect($fp);
 
 					if($this->_redirectaddr)
 					{
 						/* url was redirected, check if we've hit the max depth */
 						if($this->maxredirs > $this->_redirectdepth)
-						{						
+						{
 							if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
-								$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);						
-							
+								$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);
+
 							// only follow redirect if it's on this site, or offsiteok is true
 							if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
 							{
@@ -341,9 +341,9 @@
 					{
 						$frameurls = $this->_frameurls;
 						$this->_frameurls = array();
-						
+
 						while(list(,$frameurl) = each($frameurls))
-						{														
+						{
 							if($this->_framedepth < $this->maxframes)
 							{
 								$this->fetch($frameurl);
@@ -352,14 +352,14 @@
 							else
 								break;
 						}
-					}					
-					
+					}
+
 				}
 				else
 				{
 					return false;
 				}
-				return true;					
+				return true;
 				break;
 			case "https":
 				if(!$this->curl_path)
@@ -386,9 +386,9 @@
 				{
 					/* url was redirected, check if we've hit the max depth */
 					if($this->maxredirs > $this->_redirectdepth)
-					{						
+					{
 						if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
-							$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);						
+							$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);
 
 						// only follow redirect if it's on this site, or offsiteok is true
 						if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
@@ -410,7 +410,7 @@
 					$this->_frameurls = array();
 
 					while(list(,$frameurl) = each($frameurls))
-					{														
+					{
 						if($this->_framedepth < $this->maxframes)
 						{
 							$this->fetch($frameurl);
@@ -419,16 +419,16 @@
 						else
 							break;
 					}
-				}					
-				return true;					
+				}
+				return true;
 				break;
-				
+
 			default:
 				// not a valid protocol
 				$this->error	=	'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
 				return false;
 				break;
-		}		
+		}
 		return true;
 	}
 
@@ -442,7 +442,7 @@
 	function fetchlinks($URI)
 	{
 		if ($this->fetch($URI))
-		{			
+		{
 			if($this->lastredirectaddr)
 				$URI = $this->lastredirectaddr;
 			if(is_array($this->results))
@@ -470,9 +470,9 @@
 
 	function fetchform($URI)
 	{
-		
+
 		if ($this->fetch($URI))
-		{			
+		{
 
 			if(is_array($this->results))
 			{
@@ -481,14 +481,14 @@
 			}
 			else
 				$this->results = $this->_stripform($this->results);
-			
+
 			return true;
 		}
 		else
 			return false;
 	}
-	
-	
+
+
 /*======================================================================*\
 	Function:	fetchtext
 	Purpose:	fetch the text from a web page, stripping the links
@@ -499,7 +499,7 @@
 	function fetchtext($URI)
 	{
 		if($this->fetch($URI))
-		{			
+		{
 			if(is_array($this->results))
 			{
 				for($x=0;$x<count($this->results);$x++)
@@ -523,7 +523,7 @@
 	function submitlinks($URI, $formvars="", $formfiles="")
 	{
 		if($this->submit($URI,$formvars, $formfiles))
-		{			
+		{
 			if($this->lastredirectaddr)
 				$URI = $this->lastredirectaddr;
 			if(is_array($this->results))
@@ -557,7 +557,7 @@
 	function submittext($URI, $formvars = "", $formfiles = "")
 	{
 		if($this->submit($URI,$formvars, $formfiles))
-		{			
+		{
 			if($this->lastredirectaddr)
 				$URI = $this->lastredirectaddr;
 			if(is_array($this->results))
@@ -581,7 +581,7 @@
 			return false;
 	}
 
-	
+
 
 /*======================================================================*\
 	Function:	set_submit_multipart
@@ -593,7 +593,7 @@
 		$this->_submit_type = "multipart/form-data";
 	}
 
-	
+
 /*======================================================================*\
 	Function:	set_submit_normal
 	Purpose:	Set the form submission content type to
@@ -604,14 +604,14 @@
 		$this->_submit_type = "application/x-www-form-urlencoded";
 	}
 
-	
-	
+
+
 
 /*======================================================================*\
 	Private functions
 \*======================================================================*/
-	
-	
+
+
 /*======================================================================*\
 	Function:	_striplinks
 	Purpose:	strip the hyperlinks from an html document
@@ -620,13 +620,13 @@
 \*======================================================================*/
 
 	function _striplinks($document)
-	{	
+	{
 		preg_match_all("'<\s*a\s.*?href\s*=\s*			# find <a href=
 						([\"\'])?					# find single or double quote
 						(?(1) (.*?)\\1 | ([^\s\>]+))		# if quote found, match up to next matching
 													# quote, otherwise match up to next space
 						'isx",$document,$links);
-						
+
 
 		// catenate the non-empty matches from the conditional subpattern
 
@@ -634,14 +634,14 @@
 		{
 			if(!empty($val))
 				$match[] = $val;
-		}				
-		
+		}
+
 		while(list($key,$val) = each($links[3]))
 		{
 			if(!empty($val))
 				$match[] = $val;
-		}		
-		
+		}
+
 		// return the links
 		return $match;
 	}
@@ -654,18 +654,18 @@
 \*======================================================================*/
 
 	function _stripform($document)
-	{	
+	{
 		preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
-		
+
 		// catenate the matches
 		$match = implode("\r\n",$elements[0]);
-				
+
 		// return the links
 		return $match;
 	}
 
-	
-	
+
+
 /*======================================================================*\
 	Function:	_striptext
 	Purpose:	strip the text from an html document
@@ -675,11 +675,11 @@
 
 	function _striptext($document)
 	{
-		
+
 		// I didn't use preg eval (//e) since that is only available in PHP 4.0.
 		// so, list your entities one by one here. I included some of the
 		// more common ones.
-								
+
 		$search = array("'<script[^>]*?>.*?</script>'si",	// strip out javascript
 						"'<[\/\!]*?[^<>]*?>'si",			// strip out html tags
 						"'([\r\n])[\s]+'",					// strip out white space
@@ -728,9 +728,9 @@
 							"Ü",
 							"ß",
 						);
-					
+
 		$text = preg_replace($search,$replace,$document);
-								
+
 		return $text;
 	}
 
@@ -744,7 +744,7 @@
 
 	function _expandlinks($links,$URI)
 	{
-		
+
 		preg_match("/^[^\?]+/",$URI,$match);
 
 		$match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]);
@@ -752,21 +752,21 @@
 		$match_part = parse_url($match);
 		$match_root =
 		$match_part["scheme"]."://".$match_part["host"];
-				
+
 		$search = array( 	"|^http://".preg_quote($this->host)."|i",
 							"|^(\/)|i",
 							"|^(?!http://)(?!mailto:)|i",
 							"|/\./|",
 							"|/[^\/]+/\.\./|"
 						);
-						
+
 		$replace = array(	"",
 							$match_root."/",
 							$match."/",
 							"/",
 							"/"
-						);			
-				
+						);
+
 		$expandedLinks = preg_replace($search,$replace,$links);
 
 		return $expandedLinks;
@@ -779,19 +779,19 @@
 				$fp			the current open file pointer
 				$URI		the full URI
 				$body		body contents to send if any (POST)
-	Output:		
+	Output:
 \*======================================================================*/
-	
+
 	function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
 	{
 		$cookie_headers = '';
 		if($this->passcookies && $this->_redirectaddr)
 			$this->setcookies();
-			
+
 		$URI_PARTS = parse_url($URI);
 		if(empty($url))
 			$url = "/";
-		$headers = $http_method." ".$url." ".$this->_httpversion."\r\n";		
+		$headers = $http_method." ".$url." ".$this->_httpversion."\r\n";
 		if(!empty($this->agent))
 			$headers .= "User-Agent: ".$this->agent."\r\n";
 		if(!empty($this->host) && !isset($this->rawheaders['Host'])) {
@@ -805,10 +805,10 @@
 		if(!empty($this->referer))
 			$headers .= "Referer: ".$this->referer."\r\n";
 		if(!empty($this->cookies))
-		{			
+		{
 			if(!is_array($this->cookies))
 				$this->cookies = (array)$this->cookies;
-	
+
 			reset($this->cookies);
 			if ( count($this->cookies) > 0 ) {
 				$cookie_headers .= 'Cookie: ';
@@ -831,28 +831,28 @@
 				$headers .= "; boundary=".$this->_mime_boundary;
 			$headers .= "\r\n";
 		}
-		if(!empty($body))	
+		if(!empty($body))
 			$headers .= "Content-length: ".strlen($body)."\r\n";
-		if(!empty($this->user) || !empty($this->pass))	
+		if(!empty($this->user) || !empty($this->pass))
 			$headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n";
-		
+
 		//add proxy auth headers
-		if(!empty($this->proxy_user))	
+		if(!empty($this->proxy_user))
 			$headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n";
 
 
 		$headers .= "\r\n";
-		
+
 		// set the read timeout if needed
 		if ($this->read_timeout > 0)
 			socket_set_timeout($fp, $this->read_timeout);
 		$this->timed_out = false;
-		
+
 		fwrite($fp,$headers.$body,strlen($headers.$body));
-		
+
 		$this->_redirectaddr = false;
 		unset($this->headers);
-						
+
 		while($currentHeader = fgets($fp,$this->_maxlinelen))
 		{
 			if ($this->read_timeout > 0 && $this->_check_timeout($fp))
@@ -860,10 +860,10 @@
 				$this->status=-100;
 				return false;
 			}
-				
+
 			if($currentHeader == "\r\n")
 				break;
-						
+
 			// if a header begins with Location: or URI:, set the redirect
 			if(preg_match("/^(Location:|URI:)/i",$currentHeader))
 			{
@@ -883,16 +883,16 @@
 				else
 					$this->_redirectaddr = $matches[2];
 			}
-		
+
 			if(preg_match("|^HTTP/|",$currentHeader))
 			{
                 if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
 				{
 					$this->status= $status[1];
-                }				
+                }
 				$this->response_code = $currentHeader;
 			}
-				
+
 			$this->headers[] = $currentHeader;
 		}
 
@@ -910,13 +910,13 @@
 			$this->status=-100;
 			return false;
 		}
-		
+
 		// check if there is a a redirect meta tag
-		
+
 		if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
 
 		{
-			$this->_redirectaddr = $this->_expandlinks($match[1],$URI);	
+			$this->_redirectaddr = $this->_expandlinks($match[1],$URI);
 		}
 
 		// have we hit our frame depth and is there frame src to fetch?
@@ -932,7 +932,7 @@
 		// no framed content
 		else
 			$this->results = $results;
-		
+
 		return true;
 	}
 
@@ -942,21 +942,21 @@
 	Input:		$url		the url to fetch
 				$URI		the full URI
 				$body		body contents to send if any (POST)
-	Output:		
+	Output:
 \*======================================================================*/
-	
+
 	function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
 	{
 		if($this->passcookies && $this->_redirectaddr)
 			$this->setcookies();
 
-		$headers = array();		
-					
+		$headers = array();
+
 		$URI_PARTS = parse_url($URI);
 		if(empty($url))
 			$url = "/";
 		// GET ... header not needed for curl
-		//$headers[] = $http_method." ".$url." ".$this->_httpversion;		
+		//$headers[] = $http_method." ".$url." ".$this->_httpversion;
 		if(!empty($this->agent))
 			$headers[] = "User-Agent: ".$this->agent;
 		if(!empty($this->host))
@@ -969,10 +969,10 @@
 		if(!empty($this->referer))
 			$headers[] = "Referer: ".$this->referer;
 		if(!empty($this->cookies))
-		{			
+		{
 			if(!is_array($this->cookies))
 				$this->cookies = (array)$this->cookies;
-	
+
 			reset($this->cookies);
 			if ( count($this->cookies) > 0 ) {
 				$cookie_str = 'Cookie: ';
@@ -995,44 +995,44 @@
 			else
 				$headers[] = "Content-type: $content_type";
 		}
-		if(!empty($body))	
+		if(!empty($body))
 			$headers[] = "Content-length: ".strlen($body);
-		if(!empty($this->user) || !empty($this->pass))	
+		if(!empty($this->user) || !empty($this->pass))
 			$headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
-			
+
 		for($curr_header = 0; $curr_header < count($headers); $curr_header++) {
 			$safer_header = strtr( $headers[$curr_header], "\"", " " );
 			$cmdline_params .= " -H \"".$safer_header."\"";
 		}
-		
+
 		if(!empty($body))
 			$cmdline_params .= " -d \"$body\"";
-		
+
 		if($this->read_timeout > 0)
 			$cmdline_params .= " -m ".$this->read_timeout;
-		
+
 		$headerfile = tempnam($temp_dir, "sno");
 
 		$safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access
 		exec(escapeshellcmd($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\""),$results,$return);
-		
+
 		if($return)
 		{
 			$this->error = "Error: cURL could not retrieve the document, error $return.";
 			return false;
 		}
-			
-			
+
+
 		$results = implode("\r\n",$results);
-		
+
 		$result_headers = file("$headerfile");
-						
+
 		$this->_redirectaddr = false;
 		unset($this->headers);
-						
+
 		for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)
 		{
-			
+
 			// if a header begins with Location: or URI:, set the redirect
 			if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
 			{
@@ -1052,7 +1052,7 @@
 				else
 					$this->_redirectaddr = $matches[2];
 			}
-		
+
 			if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
 				$this->response_code = $result_headers[$currentHeader];
 
@@ -1060,10 +1060,10 @@
 		}
 
 		// check if there is a a redirect meta tag
-		
+
 		if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
 		{
-			$this->_redirectaddr = $this->_expandlinks($match[1],$URI);	
+			$this->_redirectaddr = $this->_expandlinks($match[1],$URI);
 		}
 
 		// have we hit our frame depth and is there frame src to fetch?
@@ -1081,7 +1081,7 @@
 			$this->results = $results;
 
 		unlink("$headerfile");
-		
+
 		return true;
 	}
 
@@ -1089,7 +1089,7 @@
 	Function:	setcookies()
 	Purpose:	set cookies for a redirection
 \*======================================================================*/
-	
+
 	function setcookies()
 	{
 		for($x=0; $x<count($this->headers); $x++)
@@ -1099,7 +1099,7 @@
 		}
 	}
 
-	
+
 /*======================================================================*\
 	Function:	_check_timeout
 	Purpose:	checks whether timeout has occurred
@@ -1123,13 +1123,13 @@
 	Purpose:	make a socket connection
 	Input:		$fp	file pointer
 \*======================================================================*/
-	
+
 	function _connect(&$fp)
 	{
 		if(!empty($this->proxy_host) && !empty($this->proxy_port))
 			{
 				$this->_isproxy = true;
-				
+
 				$host = $this->proxy_host;
 				$port = $this->proxy_port;
 			}
@@ -1138,9 +1138,9 @@
 			$host = $this->host;
 			$port = $this->port;
 		}
-	
+
 		$this->status = 0;
-		
+
 		if($fp = fsockopen(
 					$host,
 					$port,
@@ -1176,13 +1176,13 @@
 	Purpose:	disconnect a socket connection
 	Input:		$fp	file pointer
 \*======================================================================*/
-	
+
 	function _disconnect($fp)
 	{
 		return(fclose($fp));
 	}
 
-	
+
 /*======================================================================*\
 	Function:	_prepare_post_body
 	Purpose:	Prepare post body according to encoding type
@@ -1190,7 +1190,7 @@
 				$formfiles - form upload files
 	Output:		post body
 \*======================================================================*/
-	
+
 	function _prepare_post_body($formvars, $formfiles)
 	{
 		settype($formvars, "array");
@@ -1199,7 +1199,7 @@
 
 		if (count($formvars) == 0 && count($formfiles) == 0)
 			return;
-		
+
 		switch ($this->_submit_type) {
 			case "application/x-www-form-urlencoded":
 				reset($formvars);
@@ -1215,7 +1215,7 @@
 
 			case "multipart/form-data":
 				$this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));
-				
+
 				reset($formvars);
 				while(list($key,$val) = each($formvars)) {
 					if (is_array($val) || is_object($val)) {
@@ -1230,7 +1230,7 @@
 						$postdata .= "$val\r\n";
 					}
 				}
-				
+
 				reset($formfiles);
 				while (list($field_name, $file_names) = each($formfiles)) {
 					settype($file_names, "array");
diff -ruN 2.0.5/wp-includes/classes.php 2.2.2/wp-includes/classes.php
--- 2.0.5/wp-includes/classes.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/classes.php	2007-06-15 12:45:21.000000000 -0500
@@ -1,1479 +1,10 @@
 <?php
 
-class WP_Query {
-	var $query;
-	var $query_vars;
-	var $queried_object;
-	var $queried_object_id;
-	var $request;
-
-	var $posts;
-	var $post_count = 0;
-	var $current_post = -1;
-	var $in_the_loop = false;
-	var $post;
-
-	var $is_single = false;
-	var $is_preview = false;
-	var $is_page = false;
-	var $is_archive = false;
-	var $is_date = false;
-	var $is_year = false;
-	var $is_month = false;
-	var $is_day = false;
-	var $is_time = false;
-	var $is_author = false;
-	var $is_category = false;
-	var $is_search = false;
-	var $is_feed = false;
-	var $is_trackback = false;
-	var $is_home = false;
-	var $is_404 = false;
-	var $is_comments_popup = false;
-	var $is_admin = false;
-	var $is_attachment = false;
-
-	function init_query_flags() {
-		$this->is_single = false;
-		$this->is_page = false;
-		$this->is_archive = false;
-		$this->is_date = false;
-		$this->is_year = false;
-		$this->is_month = false;
-		$this->is_day = false;
-		$this->is_time = false;
-		$this->is_author = false;
-		$this->is_category = false;
-		$this->is_search = false;
-		$this->is_feed = false;
-		$this->is_trackback = false;
-		$this->is_home = false;
-		$this->is_404 = false;
-		$this->is_paged = false;
-		$this->is_admin = false;
-		$this->is_attachment = false;
-	}
-	
-	function init () {
-		unset($this->posts);
-		unset($this->query);
-		unset($this->query_vars);
-		unset($this->queried_object);
-		unset($this->queried_object_id);
-		$this->post_count = 0;
-		$this->current_post = -1;
-		$this->in_the_loop = false;
-		
-		$this->init_query_flags();
-	}
-
-	// Reparse the query vars.
-	function parse_query_vars() {
-		$this->parse_query('');
-	}
-
-	// Parse a query string and set query type booleans.
-	function parse_query ($query) {
-		if ( !empty($query) || !isset($this->query) ) {
-			$this->init();
-			parse_str($query, $qv);
-			$this->query = $query;
-			$this->query_vars = $qv;
-		}
-
-		if ('404' == $qv['error']) {
-			$this->is_404 = true;
-			if ( !empty($query) ) {
-				do_action('parse_query', array(&$this));
-			}
-			return;
-		}
-
-		$qv['m'] =  (int) $qv['m'];
-		$qv['p'] =  (int) $qv['p'];
-
-		// Compat.  Map subpost to attachment.
-		if ( '' != $qv['subpost'] )
-			$qv['attachment'] = $qv['subpost'];
-		if ( '' != $qv['subpost_id'] )
-			$qv['attachment_id'] = $qv['subpost_id'];
-			
-		if ( ('' != $qv['attachment']) || (int) $qv['attachment_id'] ) {
-			$this->is_single = true;
-			$this->is_attachment = true;
-		} elseif ('' != $qv['name']) {
-			$this->is_single = true;
-		} elseif ( $qv['p'] ) {
-			$this->is_single = true;
-		} elseif (('' != $qv['hour']) && ('' != $qv['minute']) &&('' != $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day'])) {
-			// If year, month, day, hour, minute, and second are set, a single 
-			// post is being queried.        
-			$this->is_single = true;
-		} elseif ('' != $qv['static'] || '' != $qv['pagename'] || (int) $qv['page_id']) {
-			$this->is_page = true;
-			$this->is_single = false;
-		} elseif (!empty($qv['s'])) {
-			$this->is_search = true;
-			switch ($qv['show_post_type']) {
-			case 'page' :
-				$this->is_page = true;
-				break;
-			case 'attachment' :
-				$this->is_attachment = true;
-				break;
-			}
-		} else {
-		// Look for archive queries.  Dates, categories, authors.
-
-			if ( (int) $qv['second']) {
-				$this->is_time = true;
-				$this->is_date = true;
-			}
-
-			if ( (int) $qv['minute']) {
-				$this->is_time = true;
-				$this->is_date = true;
-			}
-
-			if ( (int) $qv['hour']) {
-				$this->is_time = true;
-				$this->is_date = true;
-			}
-
-			if ( (int) $qv['day']) {
-				if (! $this->is_date) {
-					$this->is_day = true;
-					$this->is_date = true;
-				}
-			}
-
-			if ( (int)  $qv['monthnum']) {
-				if (! $this->is_date) {
-					$this->is_month = true;
-					$this->is_date = true;
-				}
-			}
-
-			if ( (int)  $qv['year']) {
-				if (! $this->is_date) {
-					$this->is_year = true;
-					$this->is_date = true;
-				}
-			}
-
-			if ( (int)  $qv['m']) {
-				$this->is_date = true;
-				if (strlen($qv['m']) > 9) {
-					$this->is_time = true;
-				} else if (strlen($qv['m']) > 7) {
-					$this->is_day = true;
-				} else if (strlen($qv['m']) > 5) {
-					$this->is_month = true;
-				} else {
-					$this->is_year = true;
-				}
-			}
-
-			if ('' != $qv['w']) {
-				$this->is_date = true;
-			}
-
-			if (empty($qv['cat']) || ($qv['cat'] == '0')) {
-				$this->is_category = false;
-			} else {
-				if (stristr($qv['cat'],'-')) {
-					$this->is_category = false;
-				} else {
-					$this->is_category = true;
-				}
-			}
-
-			if ('' != $qv['category_name']) {
-				$this->is_category = true;
-			}
-            
-			if ((empty($qv['author'])) || ($qv['author'] == '0')) {
-				$this->is_author = false;
-			} else {
-				$this->is_author = true;
-			}
-
-			if ('' != $qv['author_name']) {
-				$this->is_author = true;
-			}
-
-			if ( ($this->is_date || $this->is_author || $this->is_category)) {
-				$this->is_archive = true;
-			}
-
-			if ( 'attachment' == $qv['show_post_type'] ) {
-				$this->is_attachment = true;
-			}
-		}
-
-		if ('' != $qv['feed']) {
-			$this->is_feed = true;
-		}
-
-		if ('' != $qv['tb']) {
-			$this->is_trackback = true;
-		}
-
-		if ('' != $qv['paged']) {
-			$this->is_paged = true;
-		}
-
-		if ('' != $qv['comments_popup']) {
-			$this->is_comments_popup = true;
-		}
-		
-		//if we're previewing inside the write screen
-		if ('' != $qv['preview']) {
-			$this->is_preview = true;
-		}
-
-		if (strstr($_SERVER['PHP_SELF'], 'wp-admin/')) {
-			$this->is_admin = true;
-		}
-
-		if ( ! ($this->is_attachment || $this->is_archive || $this->is_single || $this->is_page || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup)) {
-			$this->is_home = true;
-		}
-
-		if ( !empty($query) ) {
-			do_action('parse_query', array(&$this));
-		}
-	}
-
-	function set_404() {
-		$is_feed = $this->is_feed;
-
-		$this->init_query_flags();
-		$this->is_404 = true;
-
-		$this->is_feed = $is_feed;
-	}
-	
-	function get($query_var) {
-		if (isset($this->query_vars[$query_var])) {
-			return $this->query_vars[$query_var];
-		}
-
-		return '';
-	}
-
-	function set($query_var, $value) {
-		$this->query_vars[$query_var] = $value;
-	}
-
-	function &get_posts() {
-		global $wpdb, $pagenow, $user_ID;
-
-		do_action('pre_get_posts', array(&$this));
-
-		// Shorthand.
-		$q = $this->query_vars;	
-
-		// First let's clear some variables
-		$whichcat = '';
-		$whichauthor = '';
-		$whichpage = '';
-		$result = '';
-		$where = '';
-		$limits = '';
-		$distinct = '';
-		$join = '';
-
-		if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
-			$q['posts_per_page'] = get_settings('posts_per_page');
-		if ( !isset($q['what_to_show']) )
-			$q['what_to_show'] = get_settings('what_to_show');
-		if ( isset($q['showposts']) && $q['showposts'] ) {
-			$q['showposts'] = (int) $q['showposts'];
-			$q['posts_per_page'] = $q['showposts'];
-		}
-		if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
-			$q['posts_per_page'] = $q['posts_per_archive_page'];
-		if ( !isset($q['nopaging']) ) {
-			if ($q['posts_per_page'] == -1) {
-				$q['nopaging'] = true;
-			} else {
-				$q['nopaging'] = false;
-			}
-		}
-		if ( $this->is_feed ) {
-			$q['posts_per_page'] = get_settings('posts_per_rss');
-			$q['what_to_show'] = 'posts';
-		}
-
-		if (isset($q['page'])) {
-			$q['page'] = trim($q['page'], '/');
-			$q['page'] = (int) $q['page'];
-			$q['page'] = abs($q['page']);
-		}
-	
-		$add_hours = intval(get_settings('gmt_offset'));
-		$add_minutes = intval(60 * (get_settings('gmt_offset') - $add_hours));
-		$wp_posts_post_date_field = "post_date"; // "DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)";
-
-		// If a month is specified in the querystring, load that month
-		if ( (int) $q['m'] ) {
-			$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
-			$where .= ' AND YEAR(post_date)=' . substr($q['m'], 0, 4);
-			if (strlen($q['m'])>5)
-				$where .= ' AND MONTH(post_date)=' . substr($q['m'], 4, 2);
-			if (strlen($q['m'])>7)
-				$where .= ' AND DAYOFMONTH(post_date)=' . substr($q['m'], 6, 2);
-			if (strlen($q['m'])>9)
-				$where .= ' AND HOUR(post_date)=' . substr($q['m'], 8, 2);
-			if (strlen($q['m'])>11)
-				$where .= ' AND MINUTE(post_date)=' . substr($q['m'], 10, 2);
-			if (strlen($q['m'])>13)
-				$where .= ' AND SECOND(post_date)=' . substr($q['m'], 12, 2);
-		}
-
-		if ( (int) $q['hour'] ) {
-			$q['hour'] = '' . intval($q['hour']);
-			$where .= " AND HOUR(post_date)='" . $q['hour'] . "'";
-		}
-
-		if ( (int) $q['minute'] ) {
-			$q['minute'] = '' . intval($q['minute']);
-			$where .= " AND MINUTE(post_date)='" . $q['minute'] . "'";
-		}
-
-		if ( (int) $q['second'] ) {
-			$q['second'] = '' . intval($q['second']);
-			$where .= " AND SECOND(post_date)='" . $q['second'] . "'";
-		}
-
-		if ( (int) $q['year'] ) {
-			$q['year'] = '' . intval($q['year']);
-			$where .= " AND YEAR(post_date)='" . $q['year'] . "'";
-		}
-
-		if ( (int) $q['monthnum'] ) {
-			$q['monthnum'] = '' . intval($q['monthnum']);
-			$where .= " AND MONTH(post_date)='" . $q['monthnum'] . "'";
-		}
-
-		if ( (int) $q['day'] ) {
-			$q['day'] = '' . intval($q['day']);
-			$where .= " AND DAYOFMONTH(post_date)='" . $q['day'] . "'";
-		}
-
-		// Compat.  Map subpost to attachment.
-		if ( '' != $q['subpost'] )
-			$q['attachment'] = $q['subpost'];
-		if ( '' != $q['subpost_id'] )
-			$q['attachment_id'] = $q['subpost_id'];
-
-		if ('' != $q['name']) {
-			$q['name'] = sanitize_title($q['name']);
-			$where .= " AND post_name = '" . $q['name'] . "'";
-		} else if ('' != $q['pagename']) {
-			$q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename'])));
-			$page_paths = '/' . trim($q['pagename'], '/');
-			$q['pagename'] = sanitize_title(basename($page_paths));
-			$q['name'] = $q['pagename'];
-			$page_paths = explode('/', $page_paths);
-			foreach($page_paths as $pathdir)
-				$page_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
-				
-			$all_page_ids = get_all_page_ids();
-			$reqpage = 0;
-			if (is_array($all_page_ids)) { foreach ( $all_page_ids as $page_id ) {
-				$page = get_page($page_id);
-				if ( $page->fullpath == $page_path ) {
-					$reqpage = $page_id;
-					break;
-				}
-			} }
-			
-			$where .= " AND (ID = '$reqpage')";
-		} elseif ('' != $q['attachment']) {
-			$q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment'])));
-			$attach_paths = '/' . trim($q['attachment'], '/');
-			$q['attachment'] = sanitize_title(basename($attach_paths));
-			$q['name'] = $q['attachment'];
-			$where .= " AND post_name = '" . $q['attachment'] . "'";
-		}
-
-		if ( (int) $q['w'] ) {
-			$q['w'] = ''.intval($q['w']);
-			$where .= " AND WEEK(post_date, 1)='" . $q['w'] . "'";
-		}
-
-		if ( intval($q['comments_popup']) )
-			$q['p'] = intval($q['comments_popup']);
-
-		// If a attachment is requested by number, let it supercede any post number.
-		if ( ($q['attachment_id'] != '') && (intval($q['attachment_id']) != 0) )
-			$q['p'] = (int) $q['attachment_id'];
-
-		// If a post number is specified, load that post
-		if (($q['p'] != '') && intval($q['p']) != 0) {
-			$q['p'] =  (int) $q['p'];
-			$where = ' AND ID = ' . $q['p'];
-		}
-
-		if (($q['page_id'] != '') && (intval($q['page_id']) != 0)) {
-			$q['page_id'] = intval($q['page_id']);
-			$q['p'] = $q['page_id'];
-			$where = ' AND ID = '.$q['page_id'];
-		}
-
-		// If a search pattern is specified, load the posts that match
-		if (!empty($q['s'])) {
-			$q['s'] = addslashes_gpc($q['s']);
-			$search = ' AND (';
-			$q['s'] = preg_replace('/, +/', ' ', $q['s']);
-			$q['s'] = str_replace(',', ' ', $q['s']);
-			$q['s'] = str_replace('"', ' ', $q['s']);
-			$q['s'] = trim($q['s']);
-			if ($q['exact']) {
-				$n = '';
-			} else {
-				$n = '%';
-			}
-			if (!$q['sentence']) {
-				$s_array = explode(' ',$q['s']);
-				$q['search_terms'] = $s_array;
-				$search .= '((post_title LIKE \''.$n.$s_array[0].$n.'\') OR (post_content LIKE \''.$n.$s_array[0].$n.'\'))';
-				for ( $i = 1; $i < count($s_array); $i = $i + 1) {
-					$search .= ' AND ((post_title LIKE \''.$n.$s_array[$i].$n.'\') OR (post_content LIKE \''.$n.$s_array[$i].$n.'\'))';
-				}
-				$search .= ' OR (post_title LIKE \''.$n.$q['s'].$n.'\') OR (post_content LIKE \''.$n.$q['s'].$n.'\')';
-				$search .= ')';
-			} else {
-				$search = ' AND ((post_title LIKE \''.$n.$q['s'].$n.'\') OR (post_content LIKE \''.$n.$q['s'].$n.'\'))';
-			}
-		}
-
-		// Category stuff
-
-		if ((empty($q['cat'])) || ($q['cat'] == '0') || 
-				// Bypass cat checks if fetching specific posts
-				( $this->is_single || $this->is_page )) {
-			$whichcat='';
-		} else {
-			$q['cat'] = ''.urldecode($q['cat']).'';
-			$q['cat'] = addslashes_gpc($q['cat']);
-			if (stristr($q['cat'],'-')) {
-				// Note: if we have a negative, we ignore all the positives. It must
-				// always mean 'everything /except/ this one'. We should be able to do
-				// multiple negatives but we don't :-(
-				$eq = '!=';
-				$andor = 'AND';
-				$q['cat'] = explode('-',$q['cat']);
-				$q['cat'] = intval($q['cat'][1]);
-			} else {
-				$eq = '=';
-				$andor = 'OR';
-			}
-			$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) ";
-			$cat_array = preg_split('/[,\s]+/', $q['cat']);
-			$whichcat .= ' AND (category_id '.$eq.' '.intval($cat_array[0]);
-			$whichcat .= get_category_children($cat_array[0], ' '.$andor.' category_id '.$eq.' ');
-			for ($i = 1; $i < (count($cat_array)); $i = $i + 1) {
-				$whichcat .= ' '.$andor.' category_id '.$eq.' '.intval($cat_array[$i]);
-				$whichcat .= get_category_children($cat_array[$i], ' '.$andor.' category_id '.$eq.' ');
-			}
-			$whichcat .= ')';
-			if ($eq == '!=') {
-				$q['cat'] = '-'.$q['cat']; // Put back the knowledge that we are excluding a category.
-			}
-		}
-
-		// Category stuff for nice URIs
-
-		global $cache_categories;
-		if ('' != $q['category_name']) {
-			$cat_paths = '/' . trim(urldecode($q['category_name']), '/');
-			$q['category_name'] = sanitize_title(basename($cat_paths));
-			$cat_paths = explode('/', $cat_paths);
-			foreach($cat_paths as $pathdir)
-				$cat_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
-
-			$all_cat_ids = get_all_category_ids();
-			$q['cat'] = 0; $partial_match = 0;
-			foreach ( $all_cat_ids as $cat_id ) {
-				$cat = get_category($cat_id);
-				if ( $cat->fullpath == $cat_path ) {
-					$q['cat'] = $cat_id;
-					break;
-				} elseif ( $cat->category_nicename == $q['category_name'] ) {
-					$partial_match = $cat_id;
-				}
-			}
-			
-			//if we don't match the entire hierarchy fallback on just matching the nicename
-			if (!$q['cat'] && $partial_match) {
-				$q['cat'] = $partial_match;
-			}			
-
-			$tables = ", $wpdb->post2cat, $wpdb->categories";
-			$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) LEFT JOIN $wpdb->categories ON ($wpdb->post2cat.category_id = $wpdb->categories.cat_ID) ";
-			$whichcat = " AND (category_id = '" . $q['cat'] . "'";
-			$whichcat .= get_category_children($q['cat'], " OR category_id = ");
-			$whichcat .= ")";
-		}
-
-		// Author/user stuff
-
-		if ((empty($q['author'])) || ($q['author'] == '0')) {
-			$whichauthor='';
-		} else {
-			$q['author'] = ''.urldecode($q['author']).'';
-			$q['author'] = addslashes_gpc($q['author']);
-			if (stristr($q['author'], '-')) {
-				$eq = '!=';
-				$andor = 'AND';
-				$q['author'] = explode('-', $q['author']);
-				$q['author'] = ''.intval($q['author'][1]);
-			} else {
-				$eq = '=';
-				$andor = 'OR';
-			}
-			$author_array = preg_split('/[,\s]+/', $q['author']);
-			$whichauthor .= ' AND (post_author '.$eq.' '.intval($author_array[0]);
-			for ($i = 1; $i < (count($author_array)); $i = $i + 1) {
-				$whichauthor .= ' '.$andor.' post_author '.$eq.' '.intval($author_array[$i]);
-			}
-			$whichauthor .= ')';
-		}
-
-		// Author stuff for nice URIs
-
-		if ('' != $q['author_name']) {
-			if (stristr($q['author_name'],'/')) {
-				$q['author_name'] = explode('/',$q['author_name']);
-				if ($q['author_name'][count($q['author_name'])-1]) {
-					$q['author_name'] = $q['author_name'][count($q['author_name'])-1];#no trailing slash
-				} else {
-					$q['author_name'] = $q['author_name'][count($q['author_name'])-2];#there was a trailling slash
-				}
-			}
-			$q['author_name'] = sanitize_title($q['author_name']);
-			$q['author'] = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_nicename='".$q['author_name']."'");
-			$whichauthor .= ' AND (post_author = '.intval($q['author']).')';
-		}
-		
-		$where .= $search.$whichcat.$whichauthor;
-
-		if ((empty($q['order'])) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC'))) {
-			$q['order']='DESC';
-		}
-
-		// Order by
-		if (empty($q['orderby'])) {
-			$q['orderby']='date '.$q['order'];
-		} else {
-			// Used to filter values
-			$allowed_keys = array('author', 'date', 'category', 'title', 'modified');
-			$q['orderby'] = urldecode($q['orderby']);
-			$q['orderby'] = addslashes_gpc($q['orderby']);
-			$orderby_array = explode(' ',$q['orderby']);
-			if (!in_array($orderby_array[0],$allowed_keys)) {
-				$orderby_array[0] = 'date';
-			}
-			$q['orderby'] = $orderby_array[0].' '.$q['order'];
-			if (count($orderby_array)>1) {
-				for ($i = 1; $i < (count($orderby_array)); $i = $i + 1) {
-					// Only allow certain values for safety
-					if (in_array($orderby_array[$i],$allowed_keys)) {
-						$q['orderby'] .= ',post_'.$orderby_array[$i].' '.$q['order'];
-					}
-				}
-			}
-		}
-
-		$now = gmdate('Y-m-d H:i:59');
-		
-		//only select past-dated posts, except if a logged in user is viewing a single: then, if they
-		//can edit the post, we let them through
-		if ($pagenow != 'post.php' && $pagenow != 'edit.php' && !($this->is_single && $user_ID)) {
-			$where .= " AND post_date_gmt <= '$now'";
-			$distinct = 'DISTINCT';
-		}
-
-		if ( $this->is_attachment ) {
-			$where .= ' AND (post_status = "attachment")';
-		} elseif ($this->is_page) {
-			$where .= ' AND (post_status = "static")';
-		} elseif ($this->is_single) {
-			$where .= ' AND (post_status != "static")';
-		} else {
-			$where .= ' AND (post_status = "publish"';
-
-			if (isset($user_ID) && ('' != intval($user_ID)))
-				$where .= " OR post_author = $user_ID AND post_status != 'draft' AND post_status != 'static')";
-			else
-				$where .= ')';				
-		}
-
-		if (! $this->is_attachment )
-			$where .= ' AND post_status != "attachment"';
-
-		// Apply filters on where and join prior to paging so that any
-		// manipulations to them are reflected in the paging by day queries.
-		$where = apply_filters('posts_where', $where);
-		$join = apply_filters('posts_join', $join);
-
-		// Paging
-		if (empty($q['nopaging']) && ! $this->is_single && ! $this->is_page) {
-			$page = abs(intval($q['paged']));
-			if (empty($page)) {
-				$page = 1;
-			}
-
-			if (($q['what_to_show'] == 'posts')) {
-				$q['offset'] = abs(intval($q['offset']));
-				if ( empty($q['offset']) ) {
-					$pgstrt = '';
-					$pgstrt = (intval($page) -1) * $q['posts_per_page'] . ', ';
-					$limits = 'LIMIT '.$pgstrt.$q['posts_per_page'];
-				} else { // we're ignoring $page and using 'offset'
-					$pgstrt = $q['offset'] . ', ';
-					$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
-				}
-			} elseif ($q['what_to_show'] == 'days') {
-				$startrow = $q['posts_per_page'] * (intval($page)-1);
-				$start_date = $wpdb->get_var("SELECT max(post_date) FROM $wpdb->posts $join WHERE (1=1) $where GROUP BY year(post_date), month(post_date), dayofmonth(post_date) ORDER BY post_date DESC LIMIT $startrow,1");
-				$endrow = $startrow + $q['posts_per_page'] - 1;
-				$end_date = $wpdb->get_var("SELECT min(post_date) FROM $wpdb->posts $join WHERE (1=1) $where GROUP BY year(post_date), month(post_date), dayofmonth(post_date) ORDER BY post_date DESC LIMIT $endrow,1");
-
-				if ($page > 1) {
-					$where .= " AND post_date >= '$end_date' AND post_date <= '$start_date'";
-				} else {
-					$where .= " AND post_date >= '$end_date'";
-				}
-			}
-		}
-
-		// Apply post-paging filters on where and join.  Only plugins that
-		// manipulate paging queries should use these hooks.
-		$where = apply_filters('posts_where_paged', $where);
-		$groupby = " $wpdb->posts.ID ";
-		$groupby = apply_filters('posts_groupby', $groupby);
-		$join = apply_filters('posts_join_paged', $join);
-		$orderby = "post_" . $q['orderby'];
-		$orderby = apply_filters('posts_orderby', $orderby); 
-		$request = " SELECT $distinct * FROM $wpdb->posts $join WHERE 1=1" . $where . " GROUP BY " . $groupby . " ORDER BY " . $orderby . " $limits";
-		$this->request = apply_filters('posts_request', $request);
-
-		$this->posts = $wpdb->get_results($this->request);
-
-		// Check post status to determine if post should be displayed.
-		if ( !empty($this->posts) && $this->is_single ) {
-			$status = get_post_status($this->posts[0]);
-			if ( ('publish' != $status) && ('static' != $status) ) {
-				if ( ! (isset($user_ID) && ('' != intval($user_ID))) ) {
-					// User must be logged in to view unpublished posts.
-					$this->posts = array();
-				} else {
-					if ('draft' == $status) {
-						// User must have edit permissions on the draft to preview.
-						if (! current_user_can('edit_post', $this->posts[0]->ID)) {
-							$this->posts = array();
-						} else {
-							$this->is_preview = true;
-							$this->posts[0]->post_date = current_time('mysql');
-						}
-					} else {
-						if (! current_user_can('read_post', $this->posts[0]->ID))
-							$this->posts = array();
-					}
-				}
-			} else {
-				if (mysql2date('U', $this->posts[0]->post_date_gmt) > mysql2date('U', $now)) { //it's future dated
-					$this->is_preview = true;
-					if (!current_user_can('edit_post', $this->posts[0]->ID)) {
-						$this->posts = array ( );
-					}
-				}
-			}
-		}
-
-		update_post_caches($this->posts);
-
-		$this->posts = apply_filters('the_posts', $this->posts);
-		$this->post_count = count($this->posts);
-		if ($this->post_count > 0) {
-			$this->post = $this->posts[0];
-		}
-		
-		// Save any changes made to the query vars.
-		$this->query_vars = $q;
-		return $this->posts;
-	}
-
-	function next_post() {
-        
-		$this->current_post++;
-
-		$this->post = $this->posts[$this->current_post];
-		return $this->post;
-	}
-
-	function the_post() {
-		global $post;
-		$this->in_the_loop = true;
-		$post = $this->next_post();
-		setup_postdata($post);
-
-		if ( $this->current_post == 0 ) // loop has just started
-			do_action('loop_start');
-	}
-
-	function have_posts() {
-		if ($this->current_post + 1 < $this->post_count) {
-			return true;
-		} elseif ($this->current_post + 1 == $this->post_count) {
-			do_action('loop_end');
-			// Do some cleaning up after the loop
-			$this->rewind_posts();
-		}
-
-		$this->in_the_loop = false;
-		return false;
-	}
-
-	function rewind_posts() {
-		$this->current_post = -1;
-		if ($this->post_count > 0) {
-			$this->post = $this->posts[0];
-		}
-	}
-    
-	function &query($query) {
-		$this->parse_query($query);
-		return $this->get_posts();
-	}
-
-	function get_queried_object() {
-		if (isset($this->queried_object)) {
-			return $this->queried_object;
-		}
-
-		$this->queried_object = NULL;
-		$this->queried_object_id = 0;
-
-		if ($this->is_category) {
-			$cat = $this->get('cat');
-			$category = &get_category($cat);
-			$this->queried_object = &$category;
-			$this->queried_object_id = $cat;
-		} else if ($this->is_single) {
-			$this->queried_object = $this->post;
-			$this->queried_object_id = $this->post->ID;
-		} else if ($this->is_page) {
-			$this->queried_object = $this->post;
-			$this->queried_object_id = $this->post->ID;
-		} else if ($this->is_author) {
-			$author_id = $this->get('author');
-			$author = get_userdata($author_id);
-			$this->queried_object = $author;
-			$this->queried_object_id = $author_id;
-		}
-
-		return $this->queried_object;
-	}
-
-	function get_queried_object_id() {
-		$this->get_queried_object();
-
-		if (isset($this->queried_object_id)) {
-			return $this->queried_object_id;
-		}
-
-		return 0;
-	}
-
-	function WP_Query ($query = '') {
-		if (! empty($query)) {
-			$this->query($query);
-		}
-	}
-}
-
-class retrospam_mgr {
-	var $spam_words;
-	var $comments_list;
-	var $found_comments;
-
-	function retrospam_mgr() {
-		global $wpdb;
-
-		$list = explode("\n", get_settings('moderation_keys') );
-		$list = array_unique( $list );
-		$this->spam_words = $list;
-
-		$this->comment_list = (array) $wpdb->get_results("SELECT comment_ID AS ID, comment_content AS text, comment_approved AS approved, comment_author_url AS url, comment_author_ip AS ip, comment_author_email AS email FROM $wpdb->comments ORDER BY comment_ID ASC");
-	}	// End of class constructor
-
-	function move_spam( $id_list ) {
-		global $wpdb;
-		$cnt = 0;
-		$id_list = explode( ',', $id_list );
-
-		foreach ( $id_list as $comment ) {
-			if ( $wpdb->query("update $wpdb->comments set comment_approved = '0' where comment_ID = '$comment'") ) {
-				$cnt++;
-			}
-		}
-		echo "<div class='updated'><p> ";
-		printf(__('%d comment(s) moved to the moderation queue.'), $cnt);
-		echo "</p></div>\n";
-	}	// End function move_spam
-
-	function find_spam() {
-		$in_queue = 0;
-
-		foreach( $this->comment_list as $comment ) {
-			if( $comment->approved == 1 ) {
-				foreach( $this->spam_words as $word ) {
-					$word = trim($word);
-					if ( empty( $word ) )
-						continue;
-					$fulltext = strtolower($comment->email.' '.$comment->url.' '.$comment->ip.' '.$comment->text);
-					if( false !== strpos( $fulltext, strtolower($word) ) ) {
-						$this->found_comments[] = $comment->ID;
-						break;
-					}
-				}
-			} else {
-				$in_queue++;
-			}
-		}
-		return array( 'found' => $this->found_comments, 'in_queue' => $in_queue );
-	}	// End function find_spam
-
-	function display_edit_form( $counters ) {
-		$numfound = count($counters[found]);
-		$numqueue = $counters[in_queue];
-
-		$body = '<p>' . sprintf(__('Suspected spam comments: %s'), "<strong>$numfound</strong>") . '</p>';
-
-		if ( count($counters[found]) > 0 ) {
-			$id_list = implode( ',', $counters[found] );
-			$body .= '<p><a href="options-discussion.php?action=retrospam&amp;move=true&amp;ids='.$id_list.'">'. __('Move suspect comments to moderation queue &raquo;') . '</a></p>';
-
-		}
-		$head = '<div class="wrap"><h2>' . __('Check Comments Results:') . '</h2>';
-
-		$foot .= '<p><a href="options-discussion.php">' . __('&laquo; Return to Discussion Options page.') . '</a></p></div>';
-		
-		return $head . $body . $foot;
-	} 	// End function display_edit_form
-
-}
-
-class WP_Rewrite {
-	var $permalink_structure;
-	var $category_base;
-	var $category_structure;
-	var $author_base = 'author';
-	var $author_structure;
-	var $date_structure;
-	var $page_structure;
-	var $search_base = 'search';
-	var $search_structure;
-	var $comments_base = 'comments';
-	var $feed_base = 'feed';
-	var $comments_feed_structure;
-	var $feed_structure;
-	var $front;
-	var $root = '';
-	var $index = 'index.php';
-	var $matches = '';
-	var $rules;
-	var $use_verbose_rules = false;
-	var $rewritecode = 
-		array(
-					'%year%',
-					'%monthnum%',
-					'%day%',
-					'%hour%',
-					'%minute%',
-					'%second%',
-					'%postname%',
-					'%post_id%',
-					'%category%',
-					'%author%',
-					'%pagename%',
-					'%search%'
-					);
-
-	var $rewritereplace = 
-		array(
-					'([0-9]{4})',
-					'([0-9]{1,2})',
-					'([0-9]{1,2})',
-					'([0-9]{1,2})',
-					'([0-9]{1,2})',
-					'([0-9]{1,2})',
-					'([^/]+)',
-					'([0-9]+)',
-					'(.+?)',
-					'([^/]+)',
-					'([^/]+)',
-					'(.+)'
-					);
-
-	var $queryreplace = 
-		array (
-					'year=',
-					'monthnum=',
-					'day=',
-					'hour=',
-					'minute=',
-					'second=',
-					'name=',
-					'p=',
-					'category_name=',
-					'author_name=',
-					'pagename=',
-					's='
-					);
-
-	var $feeds = array ('feed', 'rdf', 'rss', 'rss2', 'atom');
-
-	function using_permalinks() {
-		if (empty($this->permalink_structure))
-			return false;
-		else
-			return true;
-	}					
-
-	function using_index_permalinks() {
-		if (empty($this->permalink_structure)) {
-			return false;
-		}
-
-		// If the index is not in the permalink, we're using mod_rewrite.
-		if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
-			return true;
-		}
-    
-		return false;
-	}
-
-	function using_mod_rewrite_permalinks() {
-		if ( $this->using_permalinks() && ! $this->using_index_permalinks())
-			return true;
-		else
-			return false;
-	}					
-
-	function preg_index($number) {
-		$match_prefix = '$';
-		$match_suffix = '';
-
-		if (! empty($this->matches)) {
-			$match_prefix = '$' . $this->matches . '['; 
-			$match_suffix = ']';
-		}        
-
-		return "$match_prefix$number$match_suffix";        
-	}
-
-	function page_rewrite_rules() {
-		$uris = get_settings('page_uris');
-		$attachment_uris = get_settings('page_attachment_uris');
-
-		$rewrite_rules = array();
-		$page_structure = $this->get_page_permastruct();
-		if( is_array( $attachment_uris ) ) {
-			foreach ($attachment_uris as $uri => $pagename) {
-				$this->add_rewrite_tag('%pagename%', "($uri)", 'attachment=');
-				$rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure));
-			}
-		}
-		if( is_array( $uris ) ) {
-			foreach ($uris as $uri => $pagename) {
-				$this->add_rewrite_tag('%pagename%', "($uri)", 'pagename=');
-				$rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure));
-			}
-		}
-
-		return $rewrite_rules;
-	}
-
-	function get_date_permastruct() {
-		if (isset($this->date_structure)) {
-			return $this->date_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->date_structure = '';
-			return false;
-		}
-		
-		// The date permalink must have year, month, and day separated by slashes.
-		$endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%');
-
-		$this->date_structure = '';
-		$date_endian = '';
-
-		foreach ($endians as $endian) {
-			if (false !== strpos($this->permalink_structure, $endian)) {
-				$date_endian= $endian;
-				break;
-			}
-		} 
-
-		if ( empty($date_endian) )
-			$date_endian = '%year%/%monthnum%/%day%';
-
-		// Do not allow the date tags and %post_id% to overlap in the permalink
-		// structure. If they do, move the date tags to $front/date/.  
-		$front = $this->front;
-		preg_match_all('/%.+?%/', $this->permalink_structure, $tokens);
-		$tok_index = 1;
-		foreach ($tokens[0] as $token) {
-			if ( ($token == '%post_id%') && ($tok_index <= 3) ) {
-				$front = $front . 'date/';
-				break;
-			}
-			$tok_index++;
-		}
-
-		$this->date_structure = $front . $date_endian;
-
-		return $this->date_structure;
-	}
-
-	function get_year_permastruct() {
-		$structure = $this->get_date_permastruct($this->permalink_structure);
-
-		if (empty($structure)) {
-			return false;
-		}
-
-		$structure = str_replace('%monthnum%', '', $structure);
-		$structure = str_replace('%day%', '', $structure);
-
-		$structure = preg_replace('#/+#', '/', $structure);
-
-		return $structure;
-	}
-
-	function get_month_permastruct() {
-		$structure = $this->get_date_permastruct($this->permalink_structure);
-
-		if (empty($structure)) {
-			return false;
-		}
-
-		$structure = str_replace('%day%', '', $structure);
-
-		$structure = preg_replace('#/+#', '/', $structure);
-
-		return $structure;
-	}
-
-	function get_day_permastruct() {
-		return $this->get_date_permastruct($this->permalink_structure);
-	}
-
-	function get_category_permastruct() {
-		if (isset($this->category_structure)) {
-			return $this->category_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->category_structure = '';
-			return false;
-		}
-
-		if (empty($this->category_base))
-			$this->category_structure = $this->front . 'category/';
-		else
-			$this->category_structure = $this->category_base . '/';
-
-		$this->category_structure .= '%category%';
-		
-		return $this->category_structure;
-	}
-
-	function get_author_permastruct() {
-		if (isset($this->author_structure)) {
-			return $this->author_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->author_structure = '';
-			return false;
-		}
-
-		$this->author_structure = $this->front . $this->author_base . '/%author%';
-
-		return $this->author_structure;
-	}
-
-	function get_search_permastruct() {
-		if (isset($this->search_structure)) {
-			return $this->search_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->search_structure = '';
-			return false;
-		}
-
-		$this->search_structure = $this->root . $this->search_base . '/%search%';
-
-		return $this->search_structure;
-	}
-
-	function get_page_permastruct() {
-		if (isset($this->page_structure)) {
-			return $this->page_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->page_structure = '';
-			return false;
-		}
-
-		$this->page_structure = $this->root . '%pagename%';
-
-		return $this->page_structure;
-	}
-
-	function get_feed_permastruct() {
-		if (isset($this->feed_structure)) {
-			return $this->feed_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->feed_structure = '';
-			return false;
-		}
-
-		$this->feed_structure = $this->root . $this->feed_base . '/%feed%';
-
-		return $this->feed_structure;
-	}
-
-	function get_comment_feed_permastruct() {
-		if (isset($this->comment_feed_structure)) {
-			return $this->comment_feed_structure;
-		}
-
-		if (empty($this->permalink_structure)) {
-			$this->comment_feed_structure = '';
-			return false;
-		}
-
-		$this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%';
-
-		return $this->comment_feed_structure;
-	}
-
-	function add_rewrite_tag($tag, $pattern, $query) {
-		// If the tag already exists, replace the existing pattern and query for
-		// that tag, otherwise add the new tag, pattern, and query to the end of
-		// the arrays.
-		$position = array_search($tag, $this->rewritecode);		
-		if (FALSE !== $position && NULL !== $position) {
-			$this->rewritereplace[$position] = $pattern;
-			$this->queryreplace[$position] = $query;			
-		} else {
-			$this->rewritecode[] = $tag;
-			$this->rewritereplace[] = $pattern;
-			$this->queryreplace[] = $query;
-		}
-	}
-
-	function generate_rewrite_rules($permalink_structure, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true) {
-		$feedregex2 = '';
-		foreach ($this->feeds as $feed_name) {
-			$feedregex2 .= $feed_name . '|';
-		}
-		$feedregex2 = '(' . trim($feedregex2, '|') .  ')/?$';
-		$feedregex = $this->feed_base  . '/' . $feedregex2;
-
-		$trackbackregex = 'trackback/?$';
-		$pageregex = 'page/?([0-9]{1,})/?$';
-		
-		$front = substr($permalink_structure, 0, strpos($permalink_structure, '%'));
-		preg_match_all('/%.+?%/', $permalink_structure, $tokens);
-
-		$num_tokens = count($tokens[0]);
-
-		$index = $this->index;
-		$feedindex = $index;
-		$trackbackindex = $index;
-		for ($i = 0; $i < $num_tokens; ++$i) {
-			if (0 < $i) {
-				$queries[$i] = $queries[$i - 1] . '&';
-			}
-             
-			$query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1);
-			$queries[$i] .= $query_token;
-		}
-
-		$structure = $permalink_structure;
-		if ($front != '/') {
-			$structure = str_replace($front, '', $structure);
-		}
-		$structure = trim($structure, '/');
-		if ($walk_dirs) {
-			$dirs = explode('/', $structure);
-		} else {
-			$dirs[] = $structure;
-		}
-		$num_dirs = count($dirs);
-
-		$front = preg_replace('|^/+|', '', $front);
-
-		$post_rewrite = array();
-		$struct = $front;
-		for ($j = 0; $j < $num_dirs; ++$j) {
-			$struct .= $dirs[$j] . '/';
-			$struct = ltrim($struct, '/');
-			$match = str_replace($this->rewritecode, $this->rewritereplace, $struct);
-			$num_toks = preg_match_all('/%.+?%/', $struct, $toks);
-			$query = $queries[$num_toks - 1];
-
-			$pagematch = $match . $pageregex;
-			$pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1);
-
-			$feedmatch = $match . $feedregex;
-			$feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
-
-			$feedmatch2 = $match . $feedregex2;
-			$feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
-
-			if ($forcomments) {
-				$feedquery .= '&withcomments=1';
-				$feedquery2 .= '&withcomments=1';
-			}
-
-			$rewrite = array();
-			if ($feed) 
-				$rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2);
-			if ($paged)
-				$rewrite = array_merge($rewrite, array($pagematch => $pagequery));
-
-			if ($num_toks) {
-				$post = false;
-				$page = false;
-				if (strstr($struct, '%postname%') || strstr($struct, '%post_id%')
-						|| strstr($struct, '%pagename%')
-						|| (strstr($struct, '%year%') &&  strstr($struct, '%monthnum%') && strstr($struct, '%day%') && strstr($struct, '%hour%') && strstr($struct, '%minute') && strstr($struct, '%second%'))) {
-					$post = true;
-					if  ( strstr($struct, '%pagename%') )
-						$page = true;
-					$trackbackmatch = $match . $trackbackregex;
-					$trackbackquery = $trackbackindex . '?' . $query . '&tb=1';
-					$match = rtrim($match, '/');
-					$submatchbase = str_replace(array('(',')'),'',$match);
-					$sub1 = $submatchbase . '/([^/]+)/';
-					$sub1tb = $sub1 . $trackbackregex;
-					$sub1feed = $sub1 . $feedregex;
-					$sub1feed2 = $sub1 . $feedregex2;
-					$sub1 .= '?$';
-					$sub2 = $submatchbase . '/attachment/([^/]+)/';
-					$sub2tb = $sub2 . $trackbackregex;
-					$sub2feed = $sub2 . $feedregex;
-					$sub2feed2 = $sub2 . $feedregex2;
-					$sub2 .= '?$';
-					$subquery = $index . '?attachment=' . $this->preg_index(1);
-					$subtbquery = $subquery . '&tb=1';
-					$subfeedquery = $subquery . '&feed=' . $this->preg_index(2);
-					$match = $match . '(/[0-9]+)?/?$';
-					$query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1);
-				} else {
-					$match .= '?$';
-					$query = $index . '?' . $query;
-				}
-				        
-				$rewrite = array_merge($rewrite, array($match => $query));
-
-				if ($post) {
-					$rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite);
-					if ( ! $page )
-						$rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery));
-					$rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery));
-				}
-			}
-			$post_rewrite = array_merge($rewrite, $post_rewrite);
-		}
-		return $post_rewrite;
-	}
-
-	function generate_rewrite_rule($permalink_structure, $walk_dirs = false) {
-		return $this->generate_rewrite_rules($permalink_structure, false, false, false, $walk_dirs);
-	}
-
-	/* rewrite_rules
-	 * Construct rewrite matches and queries from permalink structure.
-	 * Returns an associate array of matches and queries.
-	 */
-	function rewrite_rules() {
-		$rewrite = array();
-
-		if (empty($this->permalink_structure)) {
-			return $rewrite;
-		}
-
-		// Post
-		$post_rewrite = $this->generate_rewrite_rules($this->permalink_structure);
-		$post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite);
-
-		// Date
-		$date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct());
-		$date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite);
-		
-		// Root
-		$root_rewrite = $this->generate_rewrite_rules($this->root . '/');
-		$root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite);
-
-		// Comments
-		$comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, true, true, true, false);
-		$comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite);
-
-		// Search
-		$search_structure = $this->get_search_permastruct();
-		$search_rewrite = $this->generate_rewrite_rules($search_structure);
-		$search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite);
-
-		// Categories
-		$category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct());
-		$category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite);
-
-		// Authors
-		$author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct());
-		$author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite);
-
-		// Pages
-		$page_rewrite = $this->page_rewrite_rules();
-		$page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite);
-
-		// Put them together.
-		$this->rules = array_merge($page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite);
-
-		do_action('generate_rewrite_rules', array(&$this));
-		$this->rules = apply_filters('rewrite_rules_array', $this->rules);
-
-		return $this->rules;
-	}
-
-	function wp_rewrite_rules() {
-		$this->rules = get_option('rewrite_rules');
-		if ( empty($this->rules) ) {
-			$this->matches = 'matches';
-			$this->rewrite_rules();
-			update_option('rewrite_rules', $this->rules);
-		}
-
-		return $this->rules;
-	}
-
-	function mod_rewrite_rules() {
-		if ( ! $this->using_permalinks()) {
-			return '';
-		}
-
-		$site_root = parse_url(get_settings('siteurl'));
-		$site_root = trailingslashit($site_root['path']);
-
-		$home_root = parse_url(get_settings('home'));
-		$home_root = trailingslashit($home_root['path']);
-    
-		$rules = "<IfModule mod_rewrite.c>\n";
-		$rules .= "RewriteEngine On\n";
-		$rules .= "RewriteBase $home_root\n";
-
-		if ($this->use_verbose_rules) {
-			$this->matches = '';
-			$rewrite = $this->rewrite_rules();
-			$num_rules = count($rewrite);
-			$rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" .
-				"RewriteCond %{REQUEST_FILENAME} -d\n" .
-				"RewriteRule ^.*$ - [S=$num_rules]\n";
-		
-			foreach ($rewrite as $match => $query) {
-				// Apache 1.3 does not support the reluctant (non-greedy) modifier.
-				$match = str_replace('.+?', '.+', $match);
-
-				// If the match is unanchored and greedy, prepend rewrite conditions
-				// to avoid infinite redirects and eclipsing of real files.
-				if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
-					//nada.
-				}
-			
-				if (strstr($query, $this->index)) {
-					$rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
-				} else {
-					$rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n";
-				}
-			}
-		} else {
-			$rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" .
-				"RewriteCond %{REQUEST_FILENAME} !-d\n" .
-				"RewriteRule . {$home_root}{$this->index} [L]\n";
-		}
-
-		$rules .= "</IfModule>\n";
-
-		$rules = apply_filters('mod_rewrite_rules', $rules);
-		$rules = apply_filters('rewrite_rules', $rules);  // Deprecated
-
-		return $rules;
-	}
-
-	function flush_rules() {
-		generate_page_rewrite_rules();
-		delete_option('rewrite_rules');
-		$this->wp_rewrite_rules();
-		if ( function_exists('save_mod_rewrite_rules') )
-			save_mod_rewrite_rules();
-	}
-
-	function init() {
-		$this->permalink_structure = get_settings('permalink_structure');
-		$this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%'));		
-		$this->root = '';
-		if ($this->using_index_permalinks()) {
-			$this->root = $this->index . '/';
-		}
-		$this->category_base = get_settings('category_base');
-		unset($this->category_structure);
-		unset($this->author_structure);
-		unset($this->date_structure);
-		unset($this->page_structure);
-		unset($this->search_structure);
-		unset($this->feed_structure);
-		unset($this->comment_feed_structure);
-	}
-
-	function set_permalink_structure($permalink_structure) {
-		if ($permalink_structure != $this->permalink_structure) {
-			update_option('permalink_structure', $permalink_structure);
-			$this->init();
-		}
-	}
-
-	function set_category_base($category_base) {
-		if ($category_base != $this->category_base) {
-			update_option('category_base', $category_base);
-			$this->init();
-		}
-	}
-
-	function WP_Rewrite() {
-		$this->init();
-	}
-}
-
 class WP {
-	var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview');
+	var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots');
 
-	var $private_query_vars = array('posts_per_page', 'posts_per_archive_page', 'what_to_show', 'showposts', 'nopaging', 'show_post_type');
+	var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'what_to_show', 'showposts', 'nopaging', 'post_type');
+	var $extra_query_vars = array();
 
 	var $query_vars;
 	var $query_string;
@@ -1482,15 +13,19 @@
 	var $matched_query;
 	var $did_permalink = false;
 
+	function add_query_var($qv) {
+		$this->public_query_vars[] = $qv;
+	}
+
 	function parse_request($extra_query_vars = '') {
 		global $wp_rewrite;
 
 		$this->query_vars = array();
 
-		if (! empty($extra_query_vars))
-			parse_str($extra_query_vars, $extra_query_vars);
-		else
-			$extra_query_vars = array();
+		if ( is_array($extra_query_vars) )
+			$this->extra_query_vars = & $extra_query_vars;
+		else if (! empty($extra_query_vars))
+			parse_str($extra_query_vars, $this->extra_query_vars);
 
 		// Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
 
@@ -1502,22 +37,28 @@
 			$error = '404';
 			$this->did_permalink = true;
 
-			$pathinfo = $_SERVER['PATH_INFO'];
+			if ( isset($_SERVER['PATH_INFO']) )
+				$pathinfo = $_SERVER['PATH_INFO'];
+			else
+				$pathinfo = '';
 			$pathinfo_array = explode('?', $pathinfo);
 			$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
 			$req_uri = $_SERVER['REQUEST_URI'];
 			$req_uri_array = explode('?', $req_uri);
 			$req_uri = $req_uri_array[0];
 			$self = $_SERVER['PHP_SELF'];
-			$home_path = parse_url(get_settings('home'));
-			$home_path = $home_path['path'];
+			$home_path = parse_url(get_option('home'));
+			if ( isset($home_path['path']) )
+				$home_path = $home_path['path'];
+			else
+				$home_path = '';
 			$home_path = trim($home_path, '/');
 
 			// Trim path info from the end and the leading home path from the
 			// front.  For path info requests, this leaves us with the requesting
 			// filename, if any.  For 404 requests, this leaves us with the
-			// requested permalink.	
-			$req_uri = str_replace($pathinfo, '', $req_uri);
+			// requested permalink.
+			$req_uri = str_replace($pathinfo, '', rawurldecode($req_uri));
 			$req_uri = trim($req_uri, '/');
 			$req_uri = preg_replace("|^$home_path|", '', $req_uri);
 			$req_uri = trim($req_uri, '/');
@@ -1564,7 +105,7 @@
 					$this->matched_query = $query;
 
 					// Parse the query.
-					parse_str($query, $query_vars);
+					parse_str($query, $perma_query_vars);
 
 					// If we're processing a 404 request, clear the error var
 					// since we found something.
@@ -1579,16 +120,16 @@
 			}
 
 			// If req_uri is empty or if it is a request for ourself, unset error.
-			if ( empty($request) || $req_uri == $self || strstr($_SERVER['PHP_SELF'], 'wp-admin/') ) {
+			if (empty($request) || $req_uri == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false) {
 				if (isset($_GET['error']))
 					unset($_GET['error']);
 
 				if (isset($error))
 					unset($error);
-					
-				if ( isset($query_vars) && strstr($_SERVER['PHP_SELF'], 'wp-admin/') )
-					unset($query_vars);
-					
+
+				if (isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false)
+					unset($perma_query_vars);
+
 				$this->did_permalink = false;
 			}
 		}
@@ -1597,22 +138,34 @@
 
 		for ($i=0; $i<count($this->public_query_vars); $i += 1) {
 			$wpvar = $this->public_query_vars[$i];
-			if (isset($extra_query_vars[$wpvar]))
-				$this->query_vars[$wpvar] = $extra_query_vars[$wpvar];
+			if (isset($this->extra_query_vars[$wpvar]))
+				$this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
 			elseif (isset($GLOBALS[$wpvar]))
 				$this->query_vars[$wpvar] = $GLOBALS[$wpvar];
 			elseif (!empty($_POST[$wpvar]))
 				$this->query_vars[$wpvar] = $_POST[$wpvar];
 			elseif (!empty($_GET[$wpvar]))
 				$this->query_vars[$wpvar] = $_GET[$wpvar];
-			elseif (!empty($query_vars[$wpvar]))
-				$this->query_vars[$wpvar] = $query_vars[$wpvar];
-			else
-				$this->query_vars[$wpvar] = '';
+			elseif (!empty($perma_query_vars[$wpvar]))
+				$this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
+
+			if ( !empty( $this->query_vars[$wpvar] ) )
+				$this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
+		}
+
+		foreach ($this->private_query_vars as $var) {
+			if (isset($this->extra_query_vars[$var]))
+				$this->query_vars[$var] = $this->extra_query_vars[$var];
+			elseif (isset($GLOBALS[$var]) && '' != $GLOBALS[$var])
+				$this->query_vars[$var] = $GLOBALS[$var];
 		}
 
 		if ( isset($error) )
 			$this->query_vars['error'] = $error;
+
+		$this->query_vars = apply_filters('request', $this->query_vars);
+
+		do_action_ref_array('parse_request', array(&$this));
 	}
 
 	function send_headers() {
@@ -1628,23 +181,34 @@
 			@header('Content-type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));
 		} else {
 			// We're showing a feed, so WP is indeed the only thing that last changed
-			if ( $this->query_vars['withcomments'] )
+			if ( $this->query_vars['withcomments']
+				|| ( !$this->query_vars['withoutcomments']
+					&& ( $this->query_vars['p']
+						|| $this->query_vars['name']
+						|| $this->query_vars['page_id']
+						|| $this->query_vars['pagename']
+						|| $this->query_vars['attachment']
+						|| $this->query_vars['attachment_id']
+					)
+				)
+			)
 				$wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastcommentmodified('GMT'), 0).' GMT';
-			else 
+			else
 				$wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
 			$wp_etag = '"' . md5($wp_last_modified) . '"';
 			@header("Last-Modified: $wp_last_modified");
 			@header("ETag: $wp_etag");
 
 			// Support for Conditional GET
-			if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) $client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
+			if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
+				$client_etag = stripslashes(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
 			else $client_etag = false;
 
 			$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']);
 			// If string is empty, return 0. If not, attempt to parse into a timestamp
 			$client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
 
-			// Make a timestamp for our most recent modification...	
+			// Make a timestamp for our most recent modification...
 			$wp_modified_timestamp = strtotime($wp_last_modified);
 
 			if ( ($client_last_modified && $client_etag) ?
@@ -1654,26 +218,27 @@
 				exit;
 			}
 		}
+
+		do_action_ref_array('send_headers', array(&$this));
 	}
 
 	function build_query_string() {
 		$this->query_string = '';
-
-		foreach ($this->public_query_vars as $wpvar) {
-			if (isset($this->query_vars[$wpvar]) && '' != $this->query_vars[$wpvar]) {
+		foreach (array_keys($this->query_vars) as $wpvar) {
+			if ( '' != $this->query_vars[$wpvar] ) {
 				$this->query_string .= (strlen($this->query_string) < 1) ? '' : '&';
+				if ( !is_scalar($this->query_vars[$wpvar]) ) // Discard non-scalars.
+					continue;
 				$this->query_string .= $wpvar . '=' . rawurlencode($this->query_vars[$wpvar]);
 			}
 		}
 
-		foreach ($this->private_query_vars as $wpvar) {
-			if (isset($GLOBALS[$wpvar]) && '' != $GLOBALS[$wpvar]) {
-				$this->query_string .= (strlen($this->query_string) < 1) ? '' : '&';
-				$this->query_string .= $wpvar . '=' . rawurlencode($GLOBALS[$wpvar]);
-			}
+		// query_string filter deprecated.  Use request filter instead.
+		global $wp_filter;
+		if ( isset($wp_filter['query_string']) ) {  // Don't bother filtering and parsing if no plugins are hooked in.
+			$this->query_string = apply_filters('query_string', $this->query_string);
+			parse_str($this->query_string, $this->query_vars);
 		}
-
-		$this->query_string = apply_filters('query_string', $this->query_string);
 	}
 
 	function register_globals() {
@@ -1699,8 +264,9 @@
 	}
 
 	function query_posts() {
+		global $wp_the_query;
 		$this->build_query_string();
-		query_posts($this->query_string);
+		$wp_the_query->query($this->query_vars);
  	}
 
 	function handle_404() {
@@ -1725,6 +291,7 @@
 		$this->query_posts();
 		$this->handle_404();
 		$this->register_globals();
+		do_action_ref_array('wp', array(&$this));
 	}
 
 	function WP() {
@@ -1732,4 +299,445 @@
 	}
 }
 
+class WP_Error {
+	var $errors = array();
+	var $error_data = array();
+
+	function WP_Error($code = '', $message = '', $data = '') {
+		if ( empty($code) )
+			return;
+
+		$this->errors[$code][] = $message;
+
+		if ( ! empty($data) )
+			$this->error_data[$code] = $data;
+	}
+
+	function get_error_codes() {
+		if ( empty($this->errors) )
+			return array();
+
+		return array_keys($this->errors);
+	}
+
+	function get_error_code() {
+		$codes = $this->get_error_codes();
+
+		if ( empty($codes) )
+			return '';
+
+		return $codes[0];
+	}
+
+	function get_error_messages($code = '') {
+		// Return all messages if no code specified.
+		if ( empty($code) ) {
+			$all_messages = array();
+			foreach ( $this->errors as $code => $messages )
+				$all_messages = array_merge($all_messages, $messages);
+
+			return $all_messages;
+		}
+
+		if ( isset($this->errors[$code]) )
+			return $this->errors[$code];
+		else
+			return array();
+	}
+
+	function get_error_message($code = '') {
+		if ( empty($code) )
+			$code = $this->get_error_code();
+		$messages = $this->get_error_messages($code);
+		if ( empty($messages) )
+			return '';
+		return $messages[0];
+	}
+
+	function get_error_data($code = '') {
+		if ( empty($code) )
+			$code = $this->get_error_code();
+
+		if ( isset($this->error_data[$code]) )
+			return $this->error_data[$code];
+		return null;
+	}
+
+	function add($code, $message, $data = '') {
+		$this->errors[$code][] = $message;
+		if ( ! empty($data) )
+			$this->error_data[$code] = $data;
+	}
+
+	function add_data($data, $code = '') {
+		if ( empty($code) )
+			$code = $this->get_error_code();
+
+		$this->error_data[$code] = $data;
+	}
+}
+
+function is_wp_error($thing) {
+	if ( is_object($thing) && is_a($thing, 'WP_Error') )
+		return true;
+	return false;
+}
+
+
+// A class for displaying various tree-like structures. Extend the Walker class to use it, see examples at the bottom
+
+class Walker {
+	var $tree_type;
+	var $db_fields;
+
+	//abstract callbacks
+	function start_lvl($output) { return $output; }
+	function end_lvl($output)   { return $output; }
+	function start_el($output)  { return $output; }
+	function end_el($output)    { return $output; }
+
+	function walk($elements, $to_depth) {
+		$args = array_slice(func_get_args(), 2); $parents = array(); $depth = 1; $previous_element = ''; $output = '';
+
+		//padding at the end
+		$last_element->post_parent = 0;
+		$last_element->post_id = 0;
+		$elements[] = $last_element;
+
+		$id_field = $this->db_fields['id'];
+		$parent_field = $this->db_fields['parent'];
+
+		$flat = ($to_depth == -1) ? true : false;
+
+		foreach ( $elements as $element ) {
+			// If flat, start and end the element and skip the level checks.
+			if ( $flat) {
+				// Start the element.
+				if ( isset($element->$id_field) && $element->$id_field != 0 ) {
+					$cb_args = array_merge( array($output, $element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'start_el'), $cb_args);
+				}
+
+				// End the element.
+				if ( isset($element->$id_field) && $element->$id_field != 0 ) {
+					$cb_args = array_merge( array($output, $element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+				}
+
+				continue;
+			}
+
+			// Walk the tree.
+			if ( !empty($previous_element) && ($element->$parent_field == $previous_element->$id_field) ) {
+				// Previous element is my parent. Descend a level.
+				array_unshift($parents, $previous_element);
+				if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth
+					$cb_args = array_merge( array($output, $depth), $args);
+					$output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
+				} else if ( $to_depth && $depth == $to_depth  ) {  // If we've reached depth, end the previous element.
+					$cb_args = array_merge( array($output, $previous_element, $depth), $args);
+					$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+				}
+				$depth++; //always do this so when we start the element further down, we know where we are
+			} else if ( $element->$parent_field == $previous_element->$parent_field) {
+				// On the same level as previous element.
+				if ( !$to_depth || ($depth <= $to_depth) ) {
+					$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+				}
+			} else if ( $depth > 1 ) {
+				// Ascend one or more levels.
+				if ( !$to_depth || ($depth <= $to_depth) ) {
+					$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+				}
+
+				while ( $parent = array_shift($parents) ) {
+					$depth--;
+					if ( !$to_depth || ($depth < $to_depth) ) {
+						$cb_args = array_merge( array($output, $depth), $args);
+						$output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
+						$cb_args = array_merge( array($output, $parent, $depth - 1), $args);
+						$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+					}
+					if ( $element->$parent_field == $parents[0]->$id_field ) {
+						break;
+					}
+				}
+			} else if ( !empty($previous_element) ) {
+				// Close off previous element.
+				if ( !$to_depth || ($depth <= $to_depth) ) {
+					$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'end_el'), $cb_args);
+				}
+			}
+
+			// Start the element.
+			if ( !$to_depth || ($depth <= $to_depth) ) {
+				if ( $element->$id_field != 0 ) {
+					$cb_args = array_merge( array($output, $element, $depth - 1), $args);
+					$output = call_user_func_array(array(&$this, 'start_el'), $cb_args);
+				}
+			}
+
+			$previous_element = $element;
+		}
+
+		return $output;
+	}
+}
+
+class Walker_Page extends Walker {
+	var $tree_type = 'page';
+	var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
+
+	function start_lvl($output, $depth) {
+		$indent = str_repeat("\t", $depth);
+		$output .= "\n$indent<ul>\n";
+		return $output;
+	}
+
+	function end_lvl($output, $depth) {
+		$indent = str_repeat("\t", $depth);
+		$output .= "$indent</ul>\n";
+		return $output;
+	}
+
+	function start_el($output, $page, $depth, $current_page, $args) {
+		if ( $depth )
+			$indent = str_repeat("\t", $depth);
+		extract($args, EXTR_SKIP);
+		$css_class = 'page_item';
+		$_current_page = get_page( $current_page );
+		if ( $page->ID == $current_page )
+			$css_class .= ' current_page_item';
+		elseif ( $_current_page && $page->ID == $_current_page->post_parent )
+			$css_class .= ' current_page_parent';
+
+		$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . apply_filters('the_title', $page->post_title) . '</a>';
+
+		if ( !empty($show_date) ) {
+			if ( 'modified' == $show_date )
+				$time = $page->post_modified;
+			else
+				$time = $page->post_date;
+
+			$output .= " " . mysql2date($date_format, $time);
+		}
+
+		return $output;
+	}
+
+	function end_el($output, $page, $depth) {
+		$output .= "</li>\n";
+
+		return $output;
+	}
+
+}
+
+class Walker_PageDropdown extends Walker {
+	var $tree_type = 'page';
+	var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
+
+	function start_el($output, $page, $depth, $args) {
+				$pad = str_repeat('&nbsp;', $depth * 3);
+
+				$output .= "\t<option value=\"$page->ID\"";
+				if ( $page->ID == $args['selected'] )
+								$output .= ' selected="selected"';
+				$output .= '>';
+				$title = wp_specialchars($page->post_title);
+				$output .= "$pad$title";
+				$output .= "</option>\n";
+
+				return $output;
+	}
+}
+
+class Walker_Category extends Walker {
+	var $tree_type = 'category';
+	var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this
+
+	function start_lvl($output, $depth, $args) {
+		if ( 'list' != $args['style'] )
+			return $output;
+
+		$indent = str_repeat("\t", $depth);
+		$output .= "$indent<ul class='children'>\n";
+		return $output;
+	}
+
+	function end_lvl($output, $depth, $args) {
+		if ( 'list' != $args['style'] )
+			return $output;
+
+		$indent = str_repeat("\t", $depth);
+		$output .= "$indent</ul>\n";
+		return $output;
+	}
+
+	function start_el($output, $category, $depth, $args) {
+		extract($args);
+
+		$cat_name = attribute_escape( $category->cat_name);
+		$cat_name = apply_filters( 'list_cats', $cat_name, $category );
+		$link = '<a href="' . get_category_link( $category->cat_ID ) . '" ';
+		if ( $use_desc_for_title == 0 || empty($category->category_description) )
+			$link .= 'title="' . sprintf(__( 'View all posts filed under %s' ), $cat_name) . '"';
+		else
+			$link .= 'title="' . attribute_escape( apply_filters( 'category_description', $category->category_description, $category )) . '"';
+		$link .= '>';
+		$link .= $cat_name . '</a>';
+
+		if ( (! empty($feed_image)) || (! empty($feed)) ) {
+			$link .= ' ';
+
+			if ( empty($feed_image) )
+				$link .= '(';
+
+			$link .= '<a href="' . get_category_rss_link( 0, $category->cat_ID, $category->category_nicename ) . '"';
+
+			if ( empty($feed) )
+				$alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
+			else {
+				$title = ' title="' . $feed . '"';
+				$alt = ' alt="' . $feed . '"';
+				$name = $feed;
+				$link .= $title;
+			}
+
+			$link .= '>';
+
+			if ( empty($feed_image) )
+				$link .= $name;
+			else
+				$link .= "<img src='$feed_image'$alt$title" . ' />';
+			$link .= '</a>';
+			if ( empty($feed_image) )
+				$link .= ')';
+		}
+
+		if ( isset($show_count) && $show_count )
+			$link .= ' (' . intval($category->category_count) . ')';
+
+		if ( isset($show_date) && $show_date ) {
+			$link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp);
+		}
+
+		if ( $current_category )
+			$_current_category = get_category( $current_category );
+
+		if ( 'list' == $args['style'] ) {
+			$output .= "\t<li";
+			if ( $current_category && ($category->cat_ID == $current_category) )
+				$output .=  ' class="current-cat"';
+			elseif ( $_current_category && ($category->cat_ID == $_current_category->category_parent) )
+				$output .=  ' class="current-cat-parent"';
+			$output .= ">$link\n";
+		} else {
+			$output .= "\t$link<br />\n";
+		}
+
+		return $output;
+	}
+
+	function end_el($output, $page, $depth, $args) {
+		if ( 'list' != $args['style'] )
+			return $output;
+
+		$output .= "</li>\n";
+		return $output;
+	}
+
+}
+
+class Walker_CategoryDropdown extends Walker {
+	var $tree_type = 'category';
+	var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this
+
+	function start_el($output, $category, $depth, $args) {
+		$pad = str_repeat('&nbsp;', $depth * 3);
+
+		$cat_name = apply_filters('list_cats', $category->cat_name, $category);
+		$output .= "\t<option value=\"".$category->cat_ID."\"";
+		if ( $category->cat_ID == $args['selected'] )
+			$output .= ' selected="selected"';
+		$output .= '>';
+		$output .= $pad.$cat_name;
+		if ( $args['show_count'] )
+			$output .= '&nbsp;&nbsp;('. $category->category_count .')';
+		if ( $args['show_last_update'] ) {
+			$format = 'Y-m-d';
+			$output .= '&nbsp;&nbsp;' . gmdate($format, $category->last_update_timestamp);
+		}
+		$output .= "</option>\n";
+
+		return $output;
+	}
+}
+
+class WP_Ajax_Response {
+	var $responses = array();
+
+	function WP_Ajax_Response( $args = '' ) {
+		if ( !empty($args) )
+			$this->add($args);
+	}
+
+	// a WP_Error object can be passed in 'id' or 'data'
+	function add( $args = '' ) {
+		if ( is_array($args) )
+			$r = &$args;
+		else
+			parse_str($args, $r);
+
+		$defaults = array('what' => 'object', 'action' => false, 'id' => '0', 'old_id' => false,
+				'data' => '', 'supplemental' => array());
+
+		$r = array_merge($defaults, $r);
+		extract($r, EXTR_SKIP);
+
+		if ( is_wp_error($id) ) {
+			$data = $id;
+			$id = 0;
+		}
+
+		$response = '';
+		if ( is_wp_error($data) )
+			foreach ( $data->get_error_codes() as $code )
+				$response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>";
+		else
+			$response = "<response_data><![CDATA[$data]]></response_data>";
+
+		$s = '';
+		if ( (array) $supplemental )
+			foreach ( $supplemental as $k => $v )
+				$s .= "<$k><![CDATA[$v]]></$k>";
+
+		if ( false === $action )
+			$action = $_POST['action'];
+
+		$x = '';
+		$x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action
+		$x .=	"<$what id='$id'" . ( false !== $old_id ? "old_id='$old_id'>" : '>' );
+		$x .=		$response;
+		$x .=		$s;
+		$x .=	"</$what>";
+		$x .= "</response>";
+
+		$this->responses[] = $x;
+		return $x;
+	}
+
+	function send() {
+		header('Content-type: text/xml');
+		echo "<?xml version='1.0' standalone='yes'?><wp_ajax>";
+		foreach ( $this->responses as $response )
+			echo $response;
+		echo '</wp_ajax>';
+		die();
+	}
+}
+
 ?>
diff -ruN 2.0.5/wp-includes/comment-functions.php 2.2.2/wp-includes/comment-functions.php
--- 2.0.5/wp-includes/comment-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/comment-functions.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,937 +0,0 @@
-<?php
-
-// Template functions
-
-function comments_template( $file = '/comments.php' ) {
-	global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity;
-
-	if ( ! (is_single() || is_page() || $withcomments) )
-		return;
-
-	$req = get_settings('require_name_email');
-	$commenter = wp_get_current_commenter();
-	extract($commenter);
-
-	// TODO: Use API instead of SELECTs.
-	if ( empty($comment_author) ) {
-		$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND comment_approved = '1' ORDER BY comment_date");
-	} else {
-		$author_db = $wpdb->escape($comment_author);
-		$email_db  = $wpdb->escape($comment_author_email);
-		$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND ( comment_approved = '1' OR ( comment_author = '$author_db' AND comment_author_email = '$email_db' AND comment_approved = '0' ) ) ORDER BY comment_date");
-	}
-
-	define('COMMENTS_TEMPLATE', true);
-	$include = apply_filters('comments_template', TEMPLATEPATH . $file );
-	if ( file_exists( $include ) )
-		require( $include );
-	else
-		require( ABSPATH . 'wp-content/themes/default/comments.php');
-}
-
-function wp_new_comment( $commentdata ) {
-	$commentdata = apply_filters('preprocess_comment', $commentdata);
-
-	$commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
-	$commentdata['user_ID']         = (int) $commentdata['user_ID'];
-
-	$commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR'];
-	$commentdata['comment_agent']     = $_SERVER['HTTP_USER_AGENT'];
-
-	$commentdata['comment_date']     = current_time('mysql');
-	$commentdata['comment_date_gmt'] = current_time('mysql', 1);
-	
-
-	$commentdata = wp_filter_comment($commentdata);
-
-	$commentdata['comment_approved'] = wp_allow_comment($commentdata);
-
-	$comment_ID = wp_insert_comment($commentdata);
-
-	do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
-
-	if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
-		if ( '0' == $commentdata['comment_approved'] )
-			wp_notify_moderator($comment_ID);
-
-		$post = &get_post($commentdata['comment_post_ID']); // Don't notify if it's your own comment
-
-		if ( get_settings('comments_notify') && $commentdata['comment_approved'] && $post->post_author != $commentdata['user_ID'] )
-			wp_notify_postauthor($comment_ID, $commentdata['comment_type']);
-	}
-
-	return $comment_ID;
-}
-
-function wp_insert_comment($commentdata) {
-	global $wpdb;
-	extract($commentdata);
-
-	if ( ! isset($comment_author_IP) )
-		$comment_author_IP = $_SERVER['REMOTE_ADDR'];
-	if ( ! isset($comment_date) )
-		$comment_date = current_time('mysql');
-	if ( ! isset($comment_date_gmt) )
-		$comment_date_gmt = gmdate('Y-m-d H:i:s', strtotime($comment_date) );
-	if ( ! isset($comment_parent) )
-		$comment_parent = 0;
-	if ( ! isset($comment_approved) )
-		$comment_approved = 1;
-
-	$result = $wpdb->query("INSERT INTO $wpdb->comments 
-	(comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_approved, comment_agent, comment_type, comment_parent, user_id)
-	VALUES 
-	('$comment_post_ID', '$comment_author', '$comment_author_email', '$comment_author_url', '$comment_author_IP', '$comment_date', '$comment_date_gmt', '$comment_content', '$comment_approved', '$comment_agent', '$comment_type', '$comment_parent', '$user_id')
-	");
-
-	$id = $wpdb->insert_id;
-
-	if ( $comment_approved == 1) {
-		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'");
-		$wpdb->query( "UPDATE $wpdb->posts SET comment_count = $count WHERE ID = '$comment_post_ID'" );
-	}
-	return $id;
-}
-
-function wp_filter_comment($commentdata) {
-	$commentdata['user_id']              = apply_filters('pre_user_id', $commentdata['user_ID']);
-	$commentdata['comment_agent']        = apply_filters('pre_comment_user_agent', $commentdata['comment_agent']);
-	$commentdata['comment_author']       = apply_filters('pre_comment_author_name', $commentdata['comment_author']);
-	$commentdata['comment_content']      = apply_filters('pre_comment_content', $commentdata['comment_content']);
-	$commentdata['comment_author_IP']    = apply_filters('pre_comment_user_ip', $commentdata['comment_author_IP']);
-	$commentdata['comment_author_url']   = apply_filters('pre_comment_author_url', $commentdata['comment_author_url']);
-	$commentdata['comment_author_email'] = apply_filters('pre_comment_author_email', $commentdata['comment_author_email']);
-	$commentdata['filtered'] = true;
-	return $commentdata;
-}
-
-function wp_allow_comment($commentdata) {
-	global $wpdb;
-	extract($commentdata);
-
-	// Simple duplicate check
-	$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
-	if ( $comment_author_email )
-		$dupe .= "OR comment_author_email = '$comment_author_email' ";
-	$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
-	if ( $wpdb->get_var($dupe) )
-		die( __('Duplicate comment detected; it looks as though you\'ve already said that!') );
-
-	// Simple flood-protection
-	if ( $lasttime = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_author_IP = '$comment_author_IP' OR comment_author_email = '$comment_author_email' ORDER BY comment_date DESC LIMIT 1") ) {
-		$time_lastcomment = mysql2date('U', $lasttime);
-		$time_newcomment  = mysql2date('U', $comment_date_gmt);
-		if ( ($time_newcomment - $time_lastcomment) < 15 ) {
-			do_action('comment_flood_trigger', $time_lastcomment, $time_newcomment);
-			die( __('Sorry, you can only post a new comment once every 15 seconds. Slow down cowboy.') );
-		}
-	}
-
-	if ( $user_id ) {
-		$userdata = get_userdata($user_id);
-		$user = new WP_User($user_id);
-		$post_author = $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = '$comment_post_ID' LIMIT 1");
-	}
-
-	// The author and the admins get respect.
-	if ( $userdata && ( $user_id == $post_author || $user->has_cap('level_9') ) ) {
-		$approved = 1;
-	}
-
-	// Everyone else's comments will be checked.
-	else {
-		if ( check_comment($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent, $comment_type) )
-			$approved = 1;
-		else
-			$approved = 0;
-		if ( wp_blacklist_check($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent) )
-			$approved = 'spam';
-	}
-
-	$approved = apply_filters('pre_comment_approved', $approved);
-	return $approved;
-}
-
-
-function wp_update_comment($commentarr) {
-	global $wpdb;
-
-	// First, get all of the original fields
-	$comment = get_comment($commentarr['comment_ID'], ARRAY_A);
-
-	// Escape data pulled from DB.
-	foreach ($comment as $key => $value)
-		$comment[$key] = $wpdb->escape($value);
-
-	// Merge old and new fields with new fields overwriting old ones.
-	$commentarr = array_merge($comment, $commentarr);
-
-	$commentarr = wp_filter_comment( $commentarr );
-
-	// Now extract the merged array.
-	extract($commentarr);
-
-	$comment_content = apply_filters('comment_save_pre', $comment_content);
-
-	$result = $wpdb->query(
-		"UPDATE $wpdb->comments SET
-			comment_content = '$comment_content',
-			comment_author = '$comment_author',
-			comment_author_email = '$comment_author_email',
-			comment_approved = '$comment_approved',
-			comment_author_url = '$comment_author_url',
-			comment_date = '$comment_date'
-		WHERE comment_ID = $comment_ID" );
-
-	$rval = $wpdb->rows_affected;
-
-	$c = $wpdb->get_row( "SELECT count(*) as c FROM {$wpdb->comments} WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'" );
-	if( is_object( $c ) )
-		$wpdb->query( "UPDATE $wpdb->posts SET comment_count = '$c->c' WHERE ID = '$comment_post_ID'" );
-
-	do_action('edit_comment', $comment_ID);
-
-	return $rval;
-}
-
-function wp_delete_comment($comment_id) {
-	global $wpdb;
-	do_action('delete_comment', $comment_id);
-
-	$comment = get_comment($comment_id);
-
-	if ( ! $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1") )
-		return false;
-
-	$post_id = $comment->comment_post_ID;
-	if ( $post_id && $comment->comment_approved == 1 ) {
-		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = '$post_id' AND comment_approved = '1'");
-		$wpdb->query( "UPDATE $wpdb->posts SET comment_count = $count WHERE ID = '$post_id'" );
-	}
-
-	do_action('wp_set_comment_status', $comment_id, 'delete');
-	return true;
-}
-
-function clean_url( $url ) {
-	if ('' == $url) return $url;
-	$url = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%]|i', '', $url);
-	$strip = array('%0d', '%0a');
-	$url = str_replace($strip, '', $url);
-	$url = str_replace(';//', '://', $url);
-	$url = (!strstr($url, '://')) ? 'http://'.$url : $url;
-	$url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
-	return $url;
-}
-
-function get_comments_number( $post_id = 0 ) {
-	global $wpdb, $comment_count_cache, $id;
-	$post_id = (int) $post_id;
-
-	if ( !$post_id )
-		$post_id = $id;
-
-	if ( !isset($comment_count_cache[$post_id]) )
-		$comment_count_cache[$id] = $wpdb->get_var("SELECT comment_count FROM $wpdb->posts WHERE ID = '$post_id'");
-	
-	return apply_filters('get_comments_number', $comment_count_cache[$post_id]);
-}
-
-function comments_number( $zero = 'No Comments', $one = '1 Comment', $more = '% Comments', $number = '' ) {
-	global $id, $comment;
-	$number = get_comments_number( $id );
-	if ($number == 0) {
-		$blah = $zero;
-	} elseif ($number == 1) {
-		$blah = $one;
-	} elseif ($number  > 1) {
-		$blah = str_replace('%', $number, $more);
-	}
-	echo apply_filters('comments_number', $blah);
-}
-
-function get_comments_link() {
-	return get_permalink() . '#comments';
-}
-
-function get_comment_link() {
-	global $comment;
-	return get_permalink( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID;
-}
-
-function comments_link( $file = '', $echo = true ) {
-    echo get_comments_link();
-}
-
-function comments_popup_script($width=400, $height=400, $file='') {
-    global $wpcommentspopupfile, $wptrackbackpopupfile, $wppingbackpopupfile, $wpcommentsjavascript;
-
-		if (empty ($file)) {
-			$wpcommentspopupfile = '';  // Use the index.
-		} else {
-			$wpcommentspopupfile = $file;
-		}
-
-    $wpcommentsjavascript = 1;
-    $javascript = "<script type='text/javascript'>\nfunction wpopen (macagna) {\n    window.open(macagna, '_blank', 'width=$width,height=$height,scrollbars=yes,status=yes');\n}\n</script>\n";
-    echo $javascript;
-}
-
-function comments_popup_link($zero='No Comments', $one='1 Comment', $more='% Comments', $CSSclass='', $none='Comments Off') {
-	global $id, $wpcommentspopupfile, $wpcommentsjavascript, $post, $wpdb;
-	global $comment_count_cache;
-	
-	if (! is_single() && ! is_page()) {
-	if ( !isset($comment_count_cache[$id]) )
-		$comment_count_cache[$id] = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_post_ID = $id AND comment_approved = '1';");
-	
-	$number = $comment_count_cache[$id];
-	
-	if (0 == $number && 'closed' == $post->comment_status && 'closed' == $post->ping_status) {
-		echo $none;
-		return;
-	} else {
-		if (!empty($post->post_password)) { // if there's a password
-			if ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) {  // and it doesn't match the cookie
-				echo(__('Enter your password to view comments'));
-				return;
-			}
-		}
-		echo '<a href="';
-		if ($wpcommentsjavascript) {
-			if ( empty($wpcommentspopupfile) )
-				$home = get_settings('home');
-			else
-				$home = get_settings('siteurl');
-			echo $home . '/' . $wpcommentspopupfile.'?comments_popup='.$id;
-			echo '" onclick="wpopen(this.href); return false"';
-		} else { // if comments_popup_script() is not in the template, display simple comment link
-			if ( 0 == $number )
-				echo get_permalink() . '#respond';
-			else
-				comments_link();
-			echo '"';
-		}
-		if (!empty($CSSclass)) {
-			echo ' class="'.$CSSclass.'"';
-		}
-		$title = wp_specialchars(apply_filters('the_title', get_the_title()), true);
-		echo ' title="' . sprintf( __('Comment on %s'), $title ) .'">';
-		comments_number($zero, $one, $more, $number);
-		echo '</a>';
-	}
-	}
-}
-
-function get_comment_ID() {
-	global $comment;
-	return apply_filters('get_comment_ID', $comment->comment_ID);
-}
-
-function comment_ID() {
-	echo get_comment_ID();
-}
-
-function get_comment_author() {
-	global $comment;
-	if ( empty($comment->comment_author) )
-		$author = __('Anonymous');
-	else
-		$author = $comment->comment_author;
-	return apply_filters('get_comment_author', $author);
-}
-
-function comment_author() {
-	$author = apply_filters('comment_author', get_comment_author() );
-	echo $author;
-}
-
-function get_comment_author_email() {
-	global $comment;
-	return apply_filters('get_comment_author_email', $comment->comment_author_email);	
-}
-
-function comment_author_email() {
-	echo apply_filters('author_email', get_comment_author_email() );
-}
-
-function get_comment_author_link() {
-	global $comment;
-	$url    = get_comment_author_url();
-	$author = get_comment_author();
-
-	if ( empty( $url ) || 'http://' == $url )
-		$return = $author;
-	else
-		$return = "<a href='$url' rel='external nofollow'>$author</a>";
-	return apply_filters('get_comment_author_link', $return);
-}
-
-function comment_author_link() {
-	echo get_comment_author_link();
-}
-
-function get_comment_type() {
-	global $comment;
-
-	if ( '' == $comment->comment_type )
-		$comment->comment_type = 'comment';
-
-	return apply_filters('get_comment_type', $comment->comment_type);
-}
-
-function comment_type($commenttxt = 'Comment', $trackbacktxt = 'Trackback', $pingbacktxt = 'Pingback') {
-	$type = get_comment_type();
-	switch( $type ) {
-		case 'trackback' :
-			echo $trackbacktxt;
-			break;
-		case 'pingback' :
-			echo $pingbacktxt;
-			break;
-		default :
-			echo $commenttxt;
-	}
-}
-
-function get_comment_author_url() {
-	global $comment;
-	return apply_filters('get_comment_author_url', $comment->comment_author_url);
-}
-
-function comment_author_url() {
-	echo apply_filters('comment_url', get_comment_author_url());
-}
-
-function comment_author_email_link($linktext='', $before='', $after='') {
-	global $comment;
-	$email = apply_filters('comment_email', $comment->comment_author_email);
-	if ((!empty($email)) && ($email != '@')) {
-	$display = ($linktext != '') ? $linktext : $email;
-		echo $before;
-		echo "<a href='mailto:$email'>$display</a>";
-		echo $after;
-	}
-}
-
-function get_comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
-	global $comment;
-	$url = get_comment_author_url();
-	$display = ($linktext != '') ? $linktext : $url;
-	$return = "$before<a href='$url' rel='external'>$display</a>$after";
-	return apply_filters('get_comment_author_url_link', $return);
-}
-
-function comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
-	echo get_comment_author_url_link( $linktext, $before, $after );
-}
-
-function get_comment_author_IP() {
-	global $comment;
-	return apply_filters('get_comment_author_IP', $comment->comment_author_IP);
-}
-
-function comment_author_IP() {
-	echo get_comment_author_IP();
-}
-
-function get_comment_text() {
-	global $comment;
-	return apply_filters('get_comment_text', $comment->comment_content);
-}
-
-function comment_text() {
-	echo apply_filters('comment_text', get_comment_text() );
-}
-
-function get_comment_excerpt() {
-	global $comment;
-	$comment_text = strip_tags($comment->comment_content);
-	$blah = explode(' ', $comment_text);
-	if (count($blah) > 20) {
-		$k = 20;
-		$use_dotdotdot = 1;
-	} else {
-		$k = count($blah);
-		$use_dotdotdot = 0;
-	}
-	$excerpt = '';
-	for ($i=0; $i<$k; $i++) {
-		$excerpt .= $blah[$i] . ' ';
-	}
-	$excerpt .= ($use_dotdotdot) ? '...' : '';
-	return apply_filters('get_comment_excerpt', $excerpt);
-}
-
-function comment_excerpt() {
-	echo apply_filters('comment_excerpt', get_comment_excerpt() );
-}
-
-function get_comment_date( $d = '' ) {
-	global $comment;
-	if ( '' == $d )
-		$date = mysql2date( get_settings('date_format'), $comment->comment_date);
-	else
-		$date = mysql2date($d, $comment->comment_date);
-	return apply_filters('get_comment_date', $date);
-}
-
-function comment_date( $d = '' ) {
-	echo get_comment_date( $d );
-}
-
-function get_comment_time( $d = '', $gmt = false ) {
-	global $comment;
-	$comment_date = $gmt? $comment->comment_date_gmt : $comment->comment_date;
-	if ( '' == $d )
-		$date = mysql2date(get_settings('time_format'), $comment_date);
-	else
-		$date = mysql2date($d, $comment_date);
-	return apply_filters('get_comment_time', $date);
-}
-
-function comment_time( $d = '' ) {
-	echo get_comment_time($d);
-}
-
-function get_trackback_url() {
-	global $id;
-	$tb_url = get_settings('siteurl') . '/wp-trackback.php?p=' . $id;
-
-	if ( '' != get_settings('permalink_structure') )
-		$tb_url = trailingslashit(get_permalink()) . 'trackback/';
-
-	return $tb_url;
-}
-function trackback_url( $display = true ) {
-	if ( $display)
-		echo get_trackback_url();
-	else
-		return get_trackback_url();
-}
-
-function trackback_rdf($timezone = 0) {
-	global $id;
-	if (!stristr($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator')) {
-	echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
-	    xmlns:dc="http://purl.org/dc/elements/1.1/"
-	    xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
-		<rdf:Description rdf:about="';
-	the_permalink();
-	echo '"'."\n";
-	echo '    dc:identifier="';
-	the_permalink();
-	echo '"'."\n";
-	echo '    dc:title="'.str_replace('--', '&#x2d;&#x2d;', wptexturize(strip_tags(get_the_title()))).'"'."\n";
-	echo '    trackback:ping="'.trackback_url(0).'"'." />\n";
-	echo '</rdf:RDF>';
-	}
-}
-
-function comments_open() {
-	global $post;
-	if ( 'open' == $post->comment_status )
-		return true;
-	else
-		return false;
-}
-
-function pings_open() {
-	global $post;
-	if ( 'open' == $post->ping_status ) 
-		return true;
-	else
-		return false;
-}
-
-// Non-template functions
-
-function get_lastcommentmodified($timezone = 'server') {
-	global $cache_lastcommentmodified, $pagenow, $wpdb;
-	$add_seconds_blog = get_settings('gmt_offset') * 3600;
-	$add_seconds_server = date('Z');
-	$now = current_time('mysql', 1);
-	if ( !isset($cache_lastcommentmodified[$timezone]) ) {
-		switch(strtolower($timezone)) {
-			case 'gmt':
-				$lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
-				break;
-			case 'blog':
-				$lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
-				break;
-			case 'server':
-				$lastcommentmodified = $wpdb->get_var("SELECT DATE_ADD(comment_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
-				break;
-		}
-		$cache_lastcommentmodified[$timezone] = $lastcommentmodified;
-	} else {
-		$lastcommentmodified = $cache_lastcommentmodified[$timezone];
-	}
-	return $lastcommentmodified;
-}
-
-function get_commentdata( $comment_ID, $no_cache = 0, $include_unapproved = false ) { // less flexible, but saves DB queries
-	global $postc, $id, $commentdata, $wpdb;
-	if ($no_cache) {
-		$query = "SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_ID'";
-		if (false == $include_unapproved) {
-		    $query .= " AND comment_approved = '1'";
-		}
-    		$myrow = $wpdb->get_row($query, ARRAY_A);
-	} else {
-		$myrow['comment_ID'] = $postc->comment_ID;
-		$myrow['comment_post_ID'] = $postc->comment_post_ID;
-		$myrow['comment_author'] = $postc->comment_author;
-		$myrow['comment_author_email'] = $postc->comment_author_email;
-		$myrow['comment_author_url'] = $postc->comment_author_url;
-		$myrow['comment_author_IP'] = $postc->comment_author_IP;
-		$myrow['comment_date'] = $postc->comment_date;
-		$myrow['comment_content'] = $postc->comment_content;
-		$myrow['comment_karma'] = $postc->comment_karma;
-		$myrow['comment_approved'] = $postc->comment_approved;
-		$myrow['comment_type'] = $postc->comment_type;
-	}
-	return $myrow;
-}
-
-function pingback($content, $post_ID) {
-	global $wp_version, $wpdb;
-	include_once (ABSPATH . WPINC . '/class-IXR.php');
-
-	// original code by Mort (http://mort.mine.nu:8080)
-	$log = debug_fopen(ABSPATH . '/pingback.log', 'a');
-	$post_links = array();
-	debug_fwrite($log, 'BEGIN '.date('YmdHis', time())."\n");
-
-	$pung = get_pung($post_ID);
-
-	// Variables
-	$ltrs = '\w';
-	$gunk = '/#~:.?+=&%@!\-';
-	$punc = '.:?\-';
-	$any = $ltrs . $gunk . $punc;
-
-	// Step 1
-	// Parsing the post, external links (if any) are stored in the $post_links array
-	// This regexp comes straight from phpfreaks.com
-	// http://www.phpfreaks.com/quickcode/Extract_All_URLs_on_a_Page/15.php
-	preg_match_all("{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp);
-
-	// Debug
-	debug_fwrite($log, 'Post contents:');
-	debug_fwrite($log, $content."\n");
-	
-	// Step 2.
-	// Walking thru the links array
-	// first we get rid of links pointing to sites, not to specific files
-	// Example:
-	// http://dummy-weblog.org
-	// http://dummy-weblog.org/
-	// http://dummy-weblog.org/post.php
-	// We don't wanna ping first and second types, even if they have a valid <link/>
-
-	foreach($post_links_temp[0] as $link_test) :
-		if ( !in_array($link_test, $pung) && (url_to_postid($link_test) != $post_ID) // If we haven't pung it already and it isn't a link to itself
-				&& !is_local_attachment($link_test) ) : // Also, let's never ping local attachments.
-			$test = parse_url($link_test);
-			if (isset($test['query']))
-				$post_links[] = $link_test;
-			elseif(($test['path'] != '/') && ($test['path'] != ''))
-				$post_links[] = $link_test;
-		endif;
-	endforeach;
-
-	do_action('pre_ping',  array(&$post_links, &$pung));
-
-	foreach ($post_links as $pagelinkedto){
-		debug_fwrite($log, "Processing -- $pagelinkedto\n");
-		$pingback_server_url = discover_pingback_server_uri($pagelinkedto, 2048);
-
-		if ($pingback_server_url) {
-			@ set_time_limit( 60 ); 
-			 // Now, the RPC call
-			debug_fwrite($log, "Page Linked To: $pagelinkedto \n");
-			debug_fwrite($log, 'Page Linked From: ');
-			$pagelinkedfrom = get_permalink($post_ID);
-			debug_fwrite($log, $pagelinkedfrom."\n");
-
-			// using a timeout of 3 seconds should be enough to cover slow servers
-			$client = new IXR_Client($pingback_server_url);
-			$client->timeout = 3;
-			$client->useragent .= ' -- WordPress/' . $wp_version;
-
-			// when set to true, this outputs debug messages by itself
-			$client->debug = false;
-			
-			if ( $client->query('pingback.ping', $pagelinkedfrom, $pagelinkedto ) )
-				add_ping( $post_ID, $pagelinkedto );
-			else
-				debug_fwrite($log, "Error.\n Fault code: ".$client->getErrorCode()." : ".$client->getErrorMessage()."\n");
-		}
-	}
-
-	debug_fwrite($log, "\nEND: ".time()."\n****************************\n");
-	debug_fclose($log);
-}
-
-function discover_pingback_server_uri($url, $timeout_bytes = 2048) {
-	global $wp_version;
-
-	$byte_count = 0;
-	$contents = '';
-	$headers = '';
-	$pingback_str_dquote = 'rel="pingback"';
-	$pingback_str_squote = 'rel=\'pingback\'';
-	$x_pingback_str = 'x-pingback: ';
-	$pingback_href_original_pos = 27;
-
-	extract(parse_url($url));
-
-	if (!isset($host)) {
-		// Not an URL. This should never happen.
-		return false;
-	}
-
-	$path  = (!isset($path)) ? '/'        : $path;
-	$path .= (isset($query)) ? '?'.$query : '';
-	$port  = (isset($port))  ? $port      : 80;
-
-	// Try to connect to the server at $host
-	$fp = @fsockopen($host, $port, $errno, $errstr, 2);
-	if (!$fp) {
-		// Couldn't open a connection to $host;
-		return false;
-	}
-
-	// Send the GET request
-	$request = "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: WordPress/$wp_version \r\n\r\n";
-//	ob_end_flush();
-	fputs($fp, $request);
-
-	// Let's check for an X-Pingback header first
-	while (!feof($fp)) {
-		$line = fgets($fp, 512);
-		if (trim($line) == '') {
-			break;
-		}
-		$headers .= trim($line)."\n";
-		$x_pingback_header_offset = strpos(strtolower($headers), $x_pingback_str);
-		if ($x_pingback_header_offset) {
-			// We got it!
-			preg_match('#x-pingback: (.+)#is', $headers, $matches);
-			$pingback_server_url = trim($matches[1]);
-			return $pingback_server_url;
-		}
-		if(strpos(strtolower($headers), 'content-type: ')) {
-			preg_match('#content-type: (.+)#is', $headers, $matches);
-			$content_type = trim($matches[1]);
-		}
-	}
-
-	if (preg_match('#(image|audio|video|model)/#is', $content_type)) {
-		// Not an (x)html, sgml, or xml page, no use going further
-		return false;
-	}
-
-	while (!feof($fp)) {
-		$line = fgets($fp, 1024);
-		$contents .= trim($line);
-		$pingback_link_offset_dquote = strpos($contents, $pingback_str_dquote);
-		$pingback_link_offset_squote = strpos($contents, $pingback_str_squote);
-		if ($pingback_link_offset_dquote || $pingback_link_offset_squote) {
-			$quote = ($pingback_link_offset_dquote) ? '"' : '\'';
-			$pingback_link_offset = ($quote=='"') ? $pingback_link_offset_dquote : $pingback_link_offset_squote;
-			$pingback_href_pos = @strpos($contents, 'href=', $pingback_link_offset);
-			$pingback_href_start = $pingback_href_pos+6;
-			$pingback_href_end = @strpos($contents, $quote, $pingback_href_start);
-			$pingback_server_url_len = $pingback_href_end - $pingback_href_start;
-			$pingback_server_url = substr($contents, $pingback_href_start, $pingback_server_url_len);
-			// We may find rel="pingback" but an incomplete pingback URI
-			if ($pingback_server_url_len > 0) {
-				// We got it!
-				return $pingback_server_url;
-			}
-		}
-		$byte_count += strlen($line);
-		if ($byte_count > $timeout_bytes) {
-			// It's no use going further, there probably isn't any pingback
-			// server to find in this file. (Prevents loading large files.)
-			return false;
-		}
-	}
-
-	// We didn't find anything.
-	return false;
-}
-
-function is_local_attachment($url) {
-	if ( !strstr($url, get_bloginfo('home') ) )
-		return false;
-	if ( strstr($url, get_bloginfo('home') . '/?attachment_id=') )
-		return true;
-	if ( $id = url_to_postid($url) ) {
-		$post = & get_post($id);
-		if ( 'attachment' == $post->post_status )
-			return true;
-	}		
-	return false;
-}
-
-function wp_set_comment_status($comment_id, $comment_status) {
-    global $wpdb;
-
-    switch($comment_status) {
-		case 'hold':
-			$query = "UPDATE $wpdb->comments SET comment_approved='0' WHERE comment_ID='$comment_id' LIMIT 1";
-		break;
-		case 'approve':
-			$query = "UPDATE $wpdb->comments SET comment_approved='1' WHERE comment_ID='$comment_id' LIMIT 1";
-		break;
- 		case 'spam':
- 			$query = "UPDATE $wpdb->comments SET comment_approved='spam' WHERE comment_ID='$comment_id' LIMIT 1";
- 		break;
-		case 'delete':
-			return wp_delete_comment($comment_id);
-		break;
-		default:
-			return false;
-    }
-    
-    if ($wpdb->query($query)) {
-		do_action('wp_set_comment_status', $comment_id, $comment_status);
-		
-		$comment = get_comment($comment_id);
-		$comment_post_ID = $comment->comment_post_ID;
-		$c = $wpdb->get_row( "SELECT count(*) as c FROM {$wpdb->comments} WHERE comment_post_ID = '$comment_post_ID' AND comment_approved = '1'" );
-		if( is_object( $c ) )
-			$wpdb->query( "UPDATE $wpdb->posts SET comment_count = '$c->c' WHERE ID = '$comment_post_ID'" );
-		return true;
-    } else {
-		return false;
-    }
-}
-
-function wp_get_comment_status($comment_id) {
-	global $wpdb;
-	
-	$result = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1");
-	if ($result == NULL) {
-		return 'deleted';
-	} else if ($result == '1') {
-		return 'approved';
-	} else if ($result == '0') {
-		return 'unapproved';
-	} else if ($result == 'spam') {
-		return 'spam';
-	} else {
-		return false;
-	}
-}
-
-function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
-	global $wpdb;
-
-	if (1 == get_settings('comment_moderation')) return false; // If moderation is set to manual
-
-	if ( preg_match_all("|(href\t*?=\t*?['\"]?)?(https?:)?//|i", $comment, $out) >= get_option('comment_max_links') )
-		return false; // Check # of external links
-
-	$mod_keys = trim( get_settings('moderation_keys') );
-	if ( !empty($mod_keys) ) {
-		$words = explode("\n", $mod_keys );
-
-		foreach ($words as $word) {
-			$word = trim($word);
-
-			// Skip empty lines
-			if (empty($word)) { continue; }
-
-			// Do some escaping magic so that '#' chars in the 
-			// spam words don't break things:
-			$word = preg_quote($word, '#');
-		
-			$pattern = "#$word#i"; 
-			if ( preg_match($pattern, $author) ) return false;
-			if ( preg_match($pattern, $email) ) return false;
-			if ( preg_match($pattern, $url) ) return false;
-			if ( preg_match($pattern, $comment) ) return false;
-			if ( preg_match($pattern, $user_ip) ) return false;
-			if ( preg_match($pattern, $user_agent) ) return false;
-		}
-	}
-
-	// Comment whitelisting:
-	if ( 1 == get_settings('comment_whitelist')) {
-		if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll
-			$uri = parse_url($url);
-			$domain = $uri['host'];
-			$uri = parse_url( get_option('home') );
-			$home_domain = $uri['host'];
-			if ( $wpdb->get_var("SELECT link_id FROM $wpdb->links WHERE link_url LIKE ('%$domain%') LIMIT 1") || $domain == $home_domain )
-				return true;
-			else
-				return false;
-		} elseif( $author != '' && $email != '' ) {
-			$ok_to_comment = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_author = '$author' AND comment_author_email = '$email' and comment_approved = '1' LIMIT 1");
-			if ( ( 1 == $ok_to_comment ) &&
-				( empty($mod_keys) || false === strpos( $email, $mod_keys) ) )
-					return true;
-			else
-				return false;
-		} else {
-			return false;
-		}
-	}
-
-	return true;
-}
-
-function get_approved_comments($post_id) {
-	global $wpdb;
-
-	$post_id = (int) $post_id;
-	return $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post_id AND comment_approved = '1' ORDER BY comment_date");
-}
-
-function sanitize_comment_cookies() {
-	if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) ) {
-		$comment_author = apply_filters('pre_comment_author_name', $_COOKIE['comment_author_'.COOKIEHASH]);
-		$comment_author = stripslashes($comment_author);
-		$comment_author = wp_specialchars($comment_author, true);
-		$_COOKIE['comment_author_'.COOKIEHASH] = $comment_author;
-	}
-
-	if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) ) {
-		$comment_author_email = apply_filters('pre_comment_author_email', $_COOKIE['comment_author_email_'.COOKIEHASH]);
-		$comment_author_email = stripslashes($comment_author_email);
-		$comment_author_email = wp_specialchars($comment_author_email, true);	
-		$_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email;
-	}
-
-	if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) {
-		$comment_author_url = apply_filters('pre_comment_author_url', $_COOKIE['comment_author_url_'.COOKIEHASH]);
-		$comment_author_url = stripslashes($comment_author_url);
-		$comment_author_url = wp_specialchars($comment_author_url, true);
-		$_COOKIE['comment_author_url_'.COOKIEHASH] = $comment_author_url;
-	}
-}
-
-function wp_get_current_commenter() {
-	// Cookies should already be sanitized.
-
-	$comment_author = '';
-	if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) )
-		$comment_author = $_COOKIE['comment_author_'.COOKIEHASH];
-
-	$comment_author_email = '';
-	if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) )
-		$comment_author_email = $_COOKIE['comment_author_email_'.COOKIEHASH];
-
-	$comment_author_url = '';
-	if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) )
-		$comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH];
-
-	return compact('comment_author', 'comment_author_email', 'comment_author_url');
-}
-
-?>
diff -ruN 2.0.5/wp-includes/comment-template.php 2.2.2/wp-includes/comment-template.php
--- 2.0.5/wp-includes/comment-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/comment-template.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,372 @@
+<?php
+/*
+ * Comment template functions.
+ */
+
+function get_comment_author() {
+	global $comment;
+	if ( empty($comment->comment_author) )
+		$author = __('Anonymous');
+	else
+		$author = $comment->comment_author;
+	return apply_filters('get_comment_author', $author);
+}
+
+function comment_author() {
+	$author = apply_filters('comment_author', get_comment_author() );
+	echo $author;
+}
+
+function get_comment_author_email() {
+	global $comment;
+	return apply_filters('get_comment_author_email', $comment->comment_author_email);
+}
+
+function comment_author_email() {
+	echo apply_filters('author_email', get_comment_author_email() );
+}
+
+function comment_author_email_link($linktext='', $before='', $after='') {
+	global $comment;
+	$email = apply_filters('comment_email', $comment->comment_author_email);
+	if ((!empty($email)) && ($email != '@')) {
+	$display = ($linktext != '') ? $linktext : $email;
+		echo $before;
+		echo "<a href='mailto:$email'>$display</a>";
+		echo $after;
+	}
+}
+
+function get_comment_author_link() {
+	global $comment;
+	$url    = get_comment_author_url();
+	$author = get_comment_author();
+
+	if ( empty( $url ) || 'http://' == $url )
+		$return = $author;
+	else
+		$return = "<a href='$url' rel='external nofollow'>$author</a>";
+	return apply_filters('get_comment_author_link', $return);
+}
+
+function comment_author_link() {
+	echo get_comment_author_link();
+}
+
+function get_comment_author_IP() {
+	global $comment;
+	return apply_filters('get_comment_author_IP', $comment->comment_author_IP);
+}
+
+function comment_author_IP() {
+	echo get_comment_author_IP();
+}
+
+function get_comment_author_url() {
+	global $comment;
+	return apply_filters('get_comment_author_url', $comment->comment_author_url);
+}
+
+function comment_author_url() {
+	echo apply_filters('comment_url', get_comment_author_url());
+}
+
+function get_comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
+	global $comment;
+	$url = get_comment_author_url();
+	$display = ($linktext != '') ? $linktext : $url;
+	$display = str_replace( 'http://www.', '', $display );
+	$display = str_replace( 'http://', '', $display );
+	if ( '/' == substr($display, -1) )
+		$display = substr($display, 0, -1);
+	$return = "$before<a href='$url' rel='external'>$display</a>$after";
+	return apply_filters('get_comment_author_url_link', $return);
+}
+
+function comment_author_url_link( $linktext = '', $before = '', $after = '' ) {
+	echo get_comment_author_url_link( $linktext, $before, $after );
+}
+
+function get_comment_date( $d = '' ) {
+	global $comment;
+	if ( '' == $d )
+		$date = mysql2date( get_option('date_format'), $comment->comment_date);
+	else
+		$date = mysql2date($d, $comment->comment_date);
+	return apply_filters('get_comment_date', $date, $d);
+}
+
+function comment_date( $d = '' ) {
+	echo get_comment_date( $d );
+}
+
+function get_comment_excerpt() {
+	global $comment;
+	$comment_text = strip_tags($comment->comment_content);
+	$blah = explode(' ', $comment_text);
+	if (count($blah) > 20) {
+		$k = 20;
+		$use_dotdotdot = 1;
+	} else {
+		$k = count($blah);
+		$use_dotdotdot = 0;
+	}
+	$excerpt = '';
+	for ($i=0; $i<$k; $i++) {
+		$excerpt .= $blah[$i] . ' ';
+	}
+	$excerpt .= ($use_dotdotdot) ? '...' : '';
+	return apply_filters('get_comment_excerpt', $excerpt);
+}
+
+function comment_excerpt() {
+	echo apply_filters('comment_excerpt', get_comment_excerpt() );
+}
+
+function get_comment_ID() {
+	global $comment;
+	return apply_filters('get_comment_ID', $comment->comment_ID);
+}
+
+function comment_ID() {
+	echo get_comment_ID();
+}
+
+function get_comment_link() {
+	global $comment;
+	return get_permalink( $comment->comment_post_ID ) . '#comment-' . $comment->comment_ID;
+}
+
+function get_comments_link() {
+	return get_permalink() . '#comments';
+}
+
+function comments_link( $file = '', $echo = true ) {
+		echo get_comments_link();
+}
+
+function get_comments_number( $post_id = 0 ) {
+	global $wpdb, $id;
+	$post_id = (int) $post_id;
+
+	if ( !$post_id )
+		$post_id = (int) $id;
+
+	$post = get_post($post_id);
+	if ( ! isset($post->comment_count) )
+		$count = 0;
+	else
+		$count = $post->comment_count;
+
+	return apply_filters('get_comments_number', $count);
+}
+
+function comments_number( $zero = false, $one = false, $more = false, $deprecated = '' ) {
+	global $id;
+	$number = get_comments_number($id);
+
+	if ( $number > 1 )
+		$output = str_replace('%', $number, ( false === $more ) ? __('% Comments') : $more);
+	elseif ( $number == 0 )
+		$output = ( false === $zero ) ? __('No Comments') : $zero;
+	else // must be one
+		$output = ( false === $one ) ? __('1 Comment') : $one;
+
+	echo apply_filters('comments_number', $output, $number);
+}
+
+function get_comment_text() {
+	global $comment;
+	return apply_filters('get_comment_text', $comment->comment_content);
+}
+
+function comment_text() {
+	echo apply_filters('comment_text', get_comment_text() );
+}
+
+function get_comment_time( $d = '', $gmt = false ) {
+	global $comment;
+	$comment_date = $gmt? $comment->comment_date_gmt : $comment->comment_date;
+	if ( '' == $d )
+		$date = mysql2date(get_option('time_format'), $comment_date);
+	else
+		$date = mysql2date($d, $comment_date);
+	return apply_filters('get_comment_time', $date, $d, $gmt);
+}
+
+function comment_time( $d = '' ) {
+	echo get_comment_time($d);
+}
+
+function get_comment_type() {
+	global $comment;
+
+	if ( '' == $comment->comment_type )
+		$comment->comment_type = 'comment';
+
+	return apply_filters('get_comment_type', $comment->comment_type);
+}
+
+function comment_type($commenttxt = 'Comment', $trackbacktxt = 'Trackback', $pingbacktxt = 'Pingback') {
+	$type = get_comment_type();
+	switch( $type ) {
+		case 'trackback' :
+			echo $trackbacktxt;
+			break;
+		case 'pingback' :
+			echo $pingbacktxt;
+			break;
+		default :
+			echo $commenttxt;
+	}
+}
+
+function get_trackback_url() {
+	global $id;
+	$tb_url = get_option('siteurl') . '/wp-trackback.php?p=' . $id;
+
+	if ( '' != get_option('permalink_structure') )
+		$tb_url = trailingslashit(get_permalink()) . user_trailingslashit('trackback', 'single_trackback');
+
+	return apply_filters('trackback_url', $tb_url);
+}
+function trackback_url( $display = true ) {
+	if ( $display)
+		echo get_trackback_url();
+	else
+		return get_trackback_url();
+}
+
+function trackback_rdf($timezone = 0) {
+	global $id;
+	if (stripos($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator') === false) {
+		echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+				xmlns:dc="http://purl.org/dc/elements/1.1/"
+				xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
+			<rdf:Description rdf:about="';
+		the_permalink();
+		echo '"'."\n";
+		echo '    dc:identifier="';
+		the_permalink();
+		echo '"'."\n";
+		echo '    dc:title="'.str_replace('--', '&#x2d;&#x2d;', wptexturize(strip_tags(get_the_title()))).'"'."\n";
+		echo '    trackback:ping="'.trackback_url(0).'"'." />\n";
+		echo '</rdf:RDF>';
+	}
+}
+
+function comments_open() {
+	global $post;
+	if ( 'open' == $post->comment_status )
+		return true;
+	else
+		return false;
+}
+
+function pings_open() {
+	global $post;
+	if ( 'open' == $post->ping_status )
+		return true;
+	else
+		return false;
+}
+
+function wp_comment_form_unfiltered_html_nonce() {
+	global $post;
+	if ( current_user_can('unfiltered_html') )
+		wp_nonce_field('unfiltered-html-comment_' . $post->ID, '_wp_unfiltered_html_comment', false);
+}
+
+function comments_template( $file = '/comments.php' ) {
+	global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity;
+
+	if ( ! (is_single() || is_page() || $withcomments) )
+		return;
+
+	$req = get_option('require_name_email');
+	$commenter = wp_get_current_commenter();
+	extract($commenter, EXTR_SKIP);
+
+	// TODO: Use API instead of SELECTs.
+	if ( $user_ID) {
+		$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND (comment_approved = '1' OR ( user_id = '$user_ID' AND comment_approved = '0' ) )  ORDER BY comment_date");
+	} else if ( empty($comment_author) ) { 
+		$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND comment_approved = '1' ORDER BY comment_date");
+	} else {
+		$author_db = $wpdb->escape($comment_author);
+		$email_db  = $wpdb->escape($comment_author_email);
+		$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post->ID' AND ( comment_approved = '1' OR ( comment_author = '$author_db' AND comment_author_email = '$email_db' AND comment_approved = '0' ) ) ORDER BY comment_date");
+	}
+
+	// keep $comments for legacy's sake (remember $table*? ;) )
+	$comments = $wp_query->comments = apply_filters( 'comments_array', $comments, $post->ID );
+	$wp_query->comment_count = count($wp_query->comments);
+
+	define('COMMENTS_TEMPLATE', true);
+	$include = apply_filters('comments_template', TEMPLATEPATH . $file );
+	if ( file_exists( $include ) )
+		require( $include );
+	else
+		require( ABSPATH . 'wp-content/themes/default/comments.php');
+}
+
+function comments_popup_script($width=400, $height=400, $file='') {
+		global $wpcommentspopupfile, $wptrackbackpopupfile, $wppingbackpopupfile, $wpcommentsjavascript;
+
+		if (empty ($file)) {
+			$wpcommentspopupfile = '';  // Use the index.
+		} else {
+			$wpcommentspopupfile = $file;
+		}
+
+		$wpcommentsjavascript = 1;
+		$javascript = "<script type='text/javascript'>\nfunction wpopen (macagna) {\n    window.open(macagna, '_blank', 'width=$width,height=$height,scrollbars=yes,status=yes');\n}\n</script>\n";
+		echo $javascript;
+}
+
+function comments_popup_link($zero='No Comments', $one='1 Comment', $more='% Comments', $CSSclass='', $none='Comments Off') {
+	global $id, $wpcommentspopupfile, $wpcommentsjavascript, $post, $wpdb;
+
+	if ( is_single() || is_page() )
+		return;
+
+	$number = get_comments_number($id);
+
+	if ( 0 == $number && 'closed' == $post->comment_status && 'closed' == $post->ping_status ) {
+		echo '<span' . ((!empty($CSSclass)) ? ' class="' . $CSSclass . '"' : '') . '>' . $none . '</span>';
+		return;
+	}
+
+	if ( !empty($post->post_password) ) { // if there's a password
+		if ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) {  // and it doesn't match the cookie
+			echo(__('Enter your password to view comments'));
+			return;
+		}
+	}
+
+	echo '<a href="';
+	if ($wpcommentsjavascript) {
+		if ( empty($wpcommentspopupfile) )
+			$home = get_option('home');
+		else
+			$home = get_option('siteurl');
+		echo $home . '/' . $wpcommentspopupfile.'?comments_popup='.$id;
+		echo '" onclick="wpopen(this.href); return false"';
+	} else { // if comments_popup_script() is not in the template, display simple comment link
+		if ( 0 == $number )
+			echo get_permalink() . '#respond';
+		else
+			comments_link();
+		echo '"';
+	}
+
+	if (!empty($CSSclass)) {
+		echo ' class="'.$CSSclass.'"';
+	}
+	$title = attribute_escape(apply_filters('the_title', get_the_title()));
+	echo ' title="' . sprintf( __('Comment on %s'), $title ) .'">';
+	comments_number($zero, $one, $more, $number);
+	echo '</a>';
+}
+
+?>
diff -ruN 2.0.5/wp-includes/comment.php 2.2.2/wp-includes/comment.php
--- 2.0.5/wp-includes/comment.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/comment.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,817 @@
+<?php
+
+function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
+	global $wpdb;
+
+	if ( 1 == get_option('comment_moderation') )
+		return false; // If moderation is set to manual
+
+	if ( preg_match_all("|(href\t*?=\t*?['\"]?)?(https?:)?//|i", $comment, $out) >= get_option('comment_max_links') )
+		return false; // Check # of external links
+
+	$mod_keys = trim(get_option('moderation_keys'));
+	if ( !empty($mod_keys) ) {
+		$words = explode("\n", $mod_keys );
+
+		foreach ($words as $word) {
+			$word = trim($word);
+
+			// Skip empty lines
+			if ( empty($word) )
+				continue;
+
+			// Do some escaping magic so that '#' chars in the
+			// spam words don't break things:
+			$word = preg_quote($word, '#');
+
+			$pattern = "#$word#i";
+			if ( preg_match($pattern, $author) ) return false;
+			if ( preg_match($pattern, $email) ) return false;
+			if ( preg_match($pattern, $url) ) return false;
+			if ( preg_match($pattern, $comment) ) return false;
+			if ( preg_match($pattern, $user_ip) ) return false;
+			if ( preg_match($pattern, $user_agent) ) return false;
+		}
+	}
+
+	// Comment whitelisting:
+	if ( 1 == get_option('comment_whitelist')) {
+		if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll
+			$uri = parse_url($url);
+			$domain = $uri['host'];
+			$uri = parse_url( get_option('home') );
+			$home_domain = $uri['host'];
+			if ( $wpdb->get_var("SELECT link_id FROM $wpdb->links WHERE link_url LIKE ('%$domain%') LIMIT 1") || $domain == $home_domain )
+				return true;
+			else
+				return false;
+		} elseif ( $author != '' && $email != '' ) {
+			$ok_to_comment = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_author = '$author' AND comment_author_email = '$email' and comment_approved = '1' LIMIT 1");
+			if ( ( 1 == $ok_to_comment ) &&
+				( empty($mod_keys) || false === strpos( $email, $mod_keys) ) )
+					return true;
+			else
+				return false;
+		} else {
+			return false;
+		}
+	}
+	return true;
+}
+
+
+function get_approved_comments($post_id) {
+	global $wpdb;
+
+	$post_id = (int) $post_id;
+	return $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post_id' AND comment_approved = '1' ORDER BY comment_date");
+}
+
+
+// Retrieves comment data given a comment ID or comment object.
+// Handles comment caching.
+function &get_comment(&$comment, $output = OBJECT) {
+	global $comment_cache, $wpdb;
+
+	if ( empty($comment) )
+		return null;
+
+	if ( is_object($comment) ) {
+		if ( !isset($comment_cache[$comment->comment_ID]) )
+			$comment_cache[$comment->comment_ID] = &$comment;
+		$_comment = & $comment_cache[$comment->comment_ID];
+	} else {
+		$comment = (int) $comment;
+		if ( !isset($comment_cache[$comment]) ) {
+			$_comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment' LIMIT 1");
+			$comment_cache[$comment->comment_ID] = & $_comment;
+		} else {
+			$_comment = & $comment_cache[$comment];
+		}
+	}
+
+	if ( $output == OBJECT ) {
+		return $_comment;
+	} elseif ( $output == ARRAY_A ) {
+		return get_object_vars($_comment);
+	} elseif ( $output == ARRAY_N ) {
+		return array_values(get_object_vars($_comment));
+	} else {
+		return $_comment;
+	}
+}
+
+
+// Deprecate in favor of get_comment()?
+function get_commentdata( $comment_ID, $no_cache = 0, $include_unapproved = false ) { // less flexible, but saves DB queries
+	global $postc, $id, $commentdata, $wpdb;
+	if ( $no_cache ) {
+		$query = "SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_ID'";
+		if ( false == $include_unapproved )
+			$query .= " AND comment_approved = '1'";
+		$myrow = $wpdb->get_row($query, ARRAY_A);
+	} else {
+		$myrow['comment_ID']           = $postc->comment_ID;
+		$myrow['comment_post_ID']      = $postc->comment_post_ID;
+		$myrow['comment_author']       = $postc->comment_author;
+		$myrow['comment_author_email'] = $postc->comment_author_email;
+		$myrow['comment_author_url']   = $postc->comment_author_url;
+		$myrow['comment_author_IP']    = $postc->comment_author_IP;
+		$myrow['comment_date']         = $postc->comment_date;
+		$myrow['comment_content']      = $postc->comment_content;
+		$myrow['comment_karma']        = $postc->comment_karma;
+		$myrow['comment_approved']     = $postc->comment_approved;
+		$myrow['comment_type']         = $postc->comment_type;
+	}
+	return $myrow;
+}
+
+
+function get_lastcommentmodified($timezone = 'server') {
+	global $cache_lastcommentmodified, $pagenow, $wpdb;
+	$add_seconds_blog = get_option('gmt_offset') * 3600;
+	$add_seconds_server = date('Z');
+	$now = current_time('mysql', 1);
+	if ( !isset($cache_lastcommentmodified[$timezone]) ) {
+		switch ( strtolower($timezone)) {
+			case 'gmt':
+				$lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
+				break;
+			case 'blog':
+				$lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
+				break;
+			case 'server':
+				$lastcommentmodified = $wpdb->get_var("SELECT DATE_ADD(comment_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->comments WHERE comment_date_gmt <= '$now' ORDER BY comment_date_gmt DESC LIMIT 1");
+				break;
+		}
+		$cache_lastcommentmodified[$timezone] = $lastcommentmodified;
+	} else {
+		$lastcommentmodified = $cache_lastcommentmodified[$timezone];
+	}
+	return $lastcommentmodified;
+}
+
+
+function sanitize_comment_cookies() {
+	if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) ) {
+		$comment_author = apply_filters('pre_comment_author_name', $_COOKIE['comment_author_'.COOKIEHASH]);
+		$comment_author = stripslashes($comment_author);
+		$comment_author = attribute_escape($comment_author);
+		$_COOKIE['comment_author_'.COOKIEHASH] = $comment_author;
+	}
+
+	if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) ) {
+		$comment_author_email = apply_filters('pre_comment_author_email', $_COOKIE['comment_author_email_'.COOKIEHASH]);
+		$comment_author_email = stripslashes($comment_author_email);
+		$comment_author_email = attribute_escape($comment_author_email);
+		$_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email;
+	}
+
+	if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) {
+		$comment_author_url = apply_filters('pre_comment_author_url', $_COOKIE['comment_author_url_'.COOKIEHASH]);
+		$comment_author_url = stripslashes($comment_author_url);
+		$comment_author_url = clean_url($comment_author_url);
+		$_COOKIE['comment_author_url_'.COOKIEHASH] = $comment_author_url;
+	}
+}
+
+
+function wp_allow_comment($commentdata) {
+	global $wpdb;
+	extract($commentdata, EXTR_SKIP);
+
+	// Simple duplicate check
+	$dupe = "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND ( comment_author = '$comment_author' ";
+	if ( $comment_author_email )
+		$dupe .= "OR comment_author_email = '$comment_author_email' ";
+	$dupe .= ") AND comment_content = '$comment_content' LIMIT 1";
+	if ( $wpdb->get_var($dupe) )
+		wp_die( __('Duplicate comment detected; it looks as though you\'ve already said that!') );
+
+	// Simple flood-protection
+	if ( $lasttime = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_author_IP = '$comment_author_IP' OR comment_author_email = '$comment_author_email' ORDER BY comment_date DESC LIMIT 1") ) {
+		$time_lastcomment = mysql2date('U', $lasttime);
+		$time_newcomment  = mysql2date('U', $comment_date_gmt);
+		$flood_die = apply_filters('comment_flood_filter', false, $time_lastcomment, $time_newcomment);
+		if ( $flood_die ) {
+			do_action('comment_flood_trigger', $time_lastcomment, $time_newcomment);
+			wp_die( __('You are posting comments too quickly.  Slow down.') );
+		}
+	}
+
+	if ( $user_id ) {
+		$userdata = get_userdata($user_id);
+		$user = new WP_User($user_id);
+		$post_author = $wpdb->get_var("SELECT post_author FROM $wpdb->posts WHERE ID = '$comment_post_ID' LIMIT 1");
+	}
+
+	if ( $userdata && ( $user_id == $post_author || $user->has_cap('level_9') ) ) {
+		// The author and the admins get respect.
+		$approved = 1;
+	 } else {
+		// Everyone else's comments will be checked.
+		if ( check_comment($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent, $comment_type) )
+			$approved = 1;
+		else
+			$approved = 0;
+		if ( wp_blacklist_check($comment_author, $comment_author_email, $comment_author_url, $comment_content, $comment_author_IP, $comment_agent) )
+			$approved = 'spam';
+	}
+
+	$approved = apply_filters('pre_comment_approved', $approved);
+	return $approved;
+}
+
+
+function wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent) {
+	global $wpdb;
+
+	do_action('wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent);
+
+	if ( preg_match_all('/&#(\d+);/', $comment . $author . $url, $chars) ) {
+		foreach ( (array) $chars[1] as $char ) {
+			// If it's an encoded char in the normal ASCII set, reject
+			if ( 38 == $char )
+				continue; // Unless it's &
+			if ( $char < 128 )
+				return true;
+		}
+	}
+
+	$mod_keys = trim( get_option('blacklist_keys') );
+	if ( '' == $mod_keys )
+		return false; // If moderation keys are empty
+	$words = explode("\n", $mod_keys );
+
+	foreach ( (array) $words as $word ) {
+		$word = trim($word);
+
+		// Skip empty lines
+		if ( empty($word) ) { continue; }
+
+		// Do some escaping magic so that '#' chars in the
+		// spam words don't break things:
+		$word = preg_quote($word, '#');
+
+		$pattern = "#$word#i";
+		if (
+			   preg_match($pattern, $author)
+			|| preg_match($pattern, $email)
+			|| preg_match($pattern, $url)
+			|| preg_match($pattern, $comment)
+			|| preg_match($pattern, $user_ip)
+			|| preg_match($pattern, $user_agent)
+		 )
+			return true;
+	}
+	return false;
+}
+
+
+function wp_delete_comment($comment_id) {
+	global $wpdb;
+	do_action('delete_comment', $comment_id);
+
+	$comment = get_comment($comment_id);
+
+	if ( ! $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1") )
+		return false;
+
+	$post_id = $comment->comment_post_ID;
+	if ( $post_id && $comment->comment_approved == 1 )
+		wp_update_comment_count($post_id);
+
+	do_action('wp_set_comment_status', $comment_id, 'delete');
+	return true;
+}
+
+
+function wp_get_comment_status($comment_id) {
+	global $wpdb;
+
+	$result = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1");
+
+	if ( $result == NULL )
+		return 'deleted';
+	elseif ( $result == '1' )
+		return 'approved';
+	elseif ( $result == '0' )
+		return 'unapproved';
+	elseif ( $result == 'spam' )
+		return 'spam';
+	else
+		return false;
+}
+
+
+function wp_get_current_commenter() {
+	// Cookies should already be sanitized.
+
+	$comment_author = '';
+	if ( isset($_COOKIE['comment_author_'.COOKIEHASH]) )
+		$comment_author = $_COOKIE['comment_author_'.COOKIEHASH];
+
+	$comment_author_email = '';
+	if ( isset($_COOKIE['comment_author_email_'.COOKIEHASH]) )
+		$comment_author_email = $_COOKIE['comment_author_email_'.COOKIEHASH];
+
+	$comment_author_url = '';
+	if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) )
+		$comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH];
+
+	return compact('comment_author', 'comment_author_email', 'comment_author_url');
+}
+
+
+function wp_insert_comment($commentdata) {
+	global $wpdb;
+	extract($commentdata, EXTR_SKIP);
+
+	if ( ! isset($comment_author_IP) )
+		$comment_author_IP = preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] );
+	if ( ! isset($comment_date) )
+		$comment_date = current_time('mysql');
+	if ( ! isset($comment_date_gmt) )
+		$comment_date_gmt = get_gmt_from_date($comment_date);
+	if ( ! isset($comment_parent) )
+		$comment_parent = 0;
+	if ( ! isset($comment_approved) )
+		$comment_approved = 1;
+	if ( ! isset($user_id) )
+		$user_id = 0;
+
+	$result = $wpdb->query("INSERT INTO $wpdb->comments
+	(comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_approved, comment_agent, comment_type, comment_parent, user_id)
+	VALUES
+	('$comment_post_ID', '$comment_author', '$comment_author_email', '$comment_author_url', '$comment_author_IP', '$comment_date', '$comment_date_gmt', '$comment_content', '$comment_approved', '$comment_agent', '$comment_type', '$comment_parent', '$user_id')
+	");
+
+	$id = (int) $wpdb->insert_id;
+
+	if ( $comment_approved == 1)
+		wp_update_comment_count($comment_post_ID);
+
+	return $id;
+}
+
+
+function wp_filter_comment($commentdata) {
+	$commentdata['user_id']              = apply_filters('pre_user_id', $commentdata['user_ID']);
+	$commentdata['comment_agent']        = apply_filters('pre_comment_user_agent', $commentdata['comment_agent']);
+	$commentdata['comment_author']       = apply_filters('pre_comment_author_name', $commentdata['comment_author']);
+	$commentdata['comment_content']      = apply_filters('pre_comment_content', $commentdata['comment_content']);
+	$commentdata['comment_author_IP']    = apply_filters('pre_comment_user_ip', $commentdata['comment_author_IP']);
+	$commentdata['comment_author_url']   = apply_filters('pre_comment_author_url', $commentdata['comment_author_url']);
+	$commentdata['comment_author_email'] = apply_filters('pre_comment_author_email', $commentdata['comment_author_email']);
+	$commentdata['filtered'] = true;
+	return $commentdata;
+}
+
+
+function wp_throttle_comment_flood($block, $time_lastcomment, $time_newcomment) {
+	if ( $block ) // a plugin has already blocked... we'll let that decision stand
+		return $block;
+	if ( ($time_newcomment - $time_lastcomment) < 15 )
+		return true;
+	return false;
+}
+
+
+function wp_new_comment( $commentdata ) {
+	$commentdata = apply_filters('preprocess_comment', $commentdata);
+
+	$commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
+	$commentdata['user_ID']         = (int) $commentdata['user_ID'];
+
+	$commentdata['comment_author_IP'] = preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] );
+	$commentdata['comment_agent']     = $_SERVER['HTTP_USER_AGENT'];
+
+	$commentdata['comment_date']     = current_time('mysql');
+	$commentdata['comment_date_gmt'] = current_time('mysql', 1);
+
+	$commentdata = wp_filter_comment($commentdata);
+
+	$commentdata['comment_approved'] = wp_allow_comment($commentdata);
+
+	$comment_ID = wp_insert_comment($commentdata);
+
+	do_action('comment_post', $comment_ID, $commentdata['comment_approved']);
+
+	if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
+		if ( '0' == $commentdata['comment_approved'] )
+			wp_notify_moderator($comment_ID);
+
+		$post = &get_post($commentdata['comment_post_ID']); // Don't notify if it's your own comment
+
+		if ( get_option('comments_notify') && $commentdata['comment_approved'] && $post->post_author != $commentdata['user_ID'] )
+			wp_notify_postauthor($comment_ID, $commentdata['comment_type']);
+	}
+
+	return $comment_ID;
+}
+
+
+function wp_set_comment_status($comment_id, $comment_status) {
+	global $wpdb;
+
+	switch ( $comment_status ) {
+		case 'hold':
+			$query = "UPDATE $wpdb->comments SET comment_approved='0' WHERE comment_ID='$comment_id' LIMIT 1";
+			break;
+		case 'approve':
+			$query = "UPDATE $wpdb->comments SET comment_approved='1' WHERE comment_ID='$comment_id' LIMIT 1";
+			break;
+		case 'spam':
+			$query = "UPDATE $wpdb->comments SET comment_approved='spam' WHERE comment_ID='$comment_id' LIMIT 1";
+			break;
+		case 'delete':
+			return wp_delete_comment($comment_id);
+			break;
+		default:
+			return false;
+	}
+
+	if ( !$wpdb->query($query) )
+		return false;
+
+	do_action('wp_set_comment_status', $comment_id, $comment_status);
+	$comment = get_comment($comment_id);
+	wp_update_comment_count($comment->comment_post_ID);
+	return true;
+}
+
+
+function wp_update_comment($commentarr) {
+	global $wpdb;
+
+	// First, get all of the original fields
+	$comment = get_comment($commentarr['comment_ID'], ARRAY_A);
+
+	// Escape data pulled from DB.
+	foreach ( (array) $comment as $key => $value )
+		$comment[$key] = $wpdb->escape($value);
+
+	// Merge old and new fields with new fields overwriting old ones.
+	$commentarr = array_merge($comment, $commentarr);
+
+	$commentarr = wp_filter_comment( $commentarr );
+
+	// Now extract the merged array.
+	extract($commentarr, EXTR_SKIP);
+
+	$comment_content = apply_filters('comment_save_pre', $comment_content);
+
+	$comment_date_gmt = get_gmt_from_date($comment_date);
+
+	$result = $wpdb->query(
+		"UPDATE $wpdb->comments SET
+			comment_content      = '$comment_content',
+			comment_author       = '$comment_author',
+			comment_author_email = '$comment_author_email',
+			comment_approved     = '$comment_approved',
+			comment_author_url   = '$comment_author_url',
+			comment_date         = '$comment_date',
+			comment_date_gmt     = '$comment_date_gmt'
+		WHERE comment_ID = $comment_ID" );
+
+	$rval = $wpdb->rows_affected;
+	wp_update_comment_count($comment_post_ID);
+	do_action('edit_comment', $comment_ID);
+	return $rval;
+}
+
+
+function wp_update_comment_count($post_id) {
+	global $wpdb, $comment_count_cache;
+	$post_id = (int) $post_id;
+	if ( !$post_id )
+		return false;
+	$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = '$post_id' AND comment_approved = '1'");
+	$wpdb->query("UPDATE $wpdb->posts SET comment_count = $count WHERE ID = '$post_id'");
+	$comment_count_cache[$post_id] = $count;
+
+	$post = get_post($post_id);
+	if ( 'page' == $post->post_type )
+		clean_page_cache( $post_id );
+	else
+		clean_post_cache( $post_id );
+
+	do_action('edit_post', $post_id);
+
+	return true;
+}
+
+
+//
+// Ping and trackback functions.
+//
+
+function discover_pingback_server_uri($url, $timeout_bytes = 2048) {
+	global $wp_version;
+
+	$byte_count = 0;
+	$contents = '';
+	$headers = '';
+	$pingback_str_dquote = 'rel="pingback"';
+	$pingback_str_squote = 'rel=\'pingback\'';
+	$x_pingback_str = 'x-pingback: ';
+	$pingback_href_original_pos = 27;
+
+	extract(parse_url($url), EXTR_SKIP);
+
+	if ( !isset($host) ) // Not an URL. This should never happen.
+		return false;
+
+	$path  = ( !isset($path) ) ? '/'          : $path;
+	$path .= ( isset($query) ) ? '?' . $query : '';
+	$port  = ( isset($port)  ) ? $port        : 80;
+
+	// Try to connect to the server at $host
+	$fp = @fsockopen($host, $port, $errno, $errstr, 2);
+	if ( !$fp ) // Couldn't open a connection to $host
+		return false;
+
+	// Send the GET request
+	$request = "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: WordPress/$wp_version \r\n\r\n";
+	// ob_end_flush();
+	fputs($fp, $request);
+
+	// Let's check for an X-Pingback header first
+	while ( !feof($fp) ) {
+		$line = fgets($fp, 512);
+		if ( trim($line) == '' )
+			break;
+		$headers .= trim($line)."\n";
+		$x_pingback_header_offset = strpos(strtolower($headers), $x_pingback_str);
+		if ( $x_pingback_header_offset ) {
+			// We got it!
+			preg_match('#x-pingback: (.+)#is', $headers, $matches);
+			$pingback_server_url = trim($matches[1]);
+			return $pingback_server_url;
+		}
+		if ( strpos(strtolower($headers), 'content-type: ') ) {
+			preg_match('#content-type: (.+)#is', $headers, $matches);
+			$content_type = trim($matches[1]);
+		}
+	}
+
+	if ( preg_match('#(image|audio|video|model)/#is', $content_type) ) // Not an (x)html, sgml, or xml page, no use going further
+		return false;
+
+	while ( !feof($fp) ) {
+		$line = fgets($fp, 1024);
+		$contents .= trim($line);
+		$pingback_link_offset_dquote = strpos($contents, $pingback_str_dquote);
+		$pingback_link_offset_squote = strpos($contents, $pingback_str_squote);
+		if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) {
+			$quote = ($pingback_link_offset_dquote) ? '"' : '\'';
+			$pingback_link_offset = ($quote=='"') ? $pingback_link_offset_dquote : $pingback_link_offset_squote;
+			$pingback_href_pos = @strpos($contents, 'href=', $pingback_link_offset);
+			$pingback_href_start = $pingback_href_pos+6;
+			$pingback_href_end = @strpos($contents, $quote, $pingback_href_start);
+			$pingback_server_url_len = $pingback_href_end - $pingback_href_start;
+			$pingback_server_url = substr($contents, $pingback_href_start, $pingback_server_url_len);
+			// We may find rel="pingback" but an incomplete pingback URL
+			if ( $pingback_server_url_len > 0 ) // We got it!
+				return $pingback_server_url;
+		}
+		$byte_count += strlen($line);
+		if ( $byte_count > $timeout_bytes ) {
+			// It's no use going further, there probably isn't any pingback
+			// server to find in this file. (Prevents loading large files.)
+			return false;
+		}
+	}
+
+	// We didn't find anything.
+	return false;
+}
+
+
+function do_all_pings() {
+	global $wpdb;
+
+	// Do pingbacks
+	while ($ping = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1")) {
+		$wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE post_id = {$ping->ID} AND meta_key = '_pingme';");
+		pingback($ping->post_content, $ping->ID);
+	}
+
+	// Do Enclosures
+	while ($enclosure = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1")) {
+		$wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE post_id = {$enclosure->ID} AND meta_key = '_encloseme';");
+		do_enclose($enclosure->post_content, $enclosure->ID);
+	}
+
+	// Do Trackbacks
+	$trackbacks = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE CHAR_LENGTH(TRIM(to_ping)) > 7 AND post_status = 'publish'");
+	if ( is_array($trackbacks) ) {
+		foreach ( $trackbacks as $trackback )
+			do_trackbacks($trackback->ID);
+	}
+
+	//Do Update Services/Generic Pings
+	generic_ping();
+}
+
+function do_trackbacks($post_id) {
+	global $wpdb;
+
+	$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = $post_id");
+	$to_ping = get_to_ping($post_id);
+	$pinged  = get_pung($post_id);
+	if ( empty($to_ping) ) {
+		$wpdb->query("UPDATE $wpdb->posts SET to_ping = '' WHERE ID = '$post_id'");
+		return;
+	}
+
+	if ( empty($post->post_excerpt) )
+		$excerpt = apply_filters('the_content', $post->post_content);
+	else
+		$excerpt = apply_filters('the_excerpt', $post->post_excerpt);
+	$excerpt = str_replace(']]>', ']]&gt;', $excerpt);
+	$excerpt = strip_tags($excerpt);
+	if ( function_exists('mb_strcut') ) // For international trackbacks
+    	$excerpt = mb_strcut($excerpt, 0, 252, get_option('blog_charset')) . '...';
+	else
+		$excerpt = substr($excerpt, 0, 252) . '...';
+
+	$post_title = apply_filters('the_title', $post->post_title);
+	$post_title = strip_tags($post_title);
+
+	if ( $to_ping ) {
+		foreach ( (array) $to_ping as $tb_ping ) {
+			$tb_ping = trim($tb_ping);
+			if ( !in_array($tb_ping, $pinged) ) {
+				trackback($tb_ping, $post_title, $excerpt, $post_id);
+				$pinged[] = $tb_ping;
+			} else {
+				$wpdb->query("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '$tb_ping', '')) WHERE ID = '$post_id'");
+			}
+		}
+	}
+}
+
+
+function generic_ping($post_id = 0) {
+	$services = get_option('ping_sites');
+	$services = preg_replace("|(\s)+|", '$1', $services); // Kill dupe lines
+	$services = trim($services);
+	if ( '' != $services ) {
+		$services = explode("\n", $services);
+		foreach ( (array) $services as $service )
+			weblog_ping($service);
+	}
+
+	return $post_id;
+}
+
+
+function pingback($content, $post_ID) {
+	global $wp_version, $wpdb;
+	include_once(ABSPATH . WPINC . '/class-IXR.php');
+
+	// original code by Mort (http://mort.mine.nu:8080)
+	$log = debug_fopen(ABSPATH . '/pingback.log', 'a');
+	$post_links = array();
+	debug_fwrite($log, 'BEGIN ' . date('YmdHis', time()) . "\n");
+
+	$pung = get_pung($post_ID);
+
+	// Variables
+	$ltrs = '\w';
+	$gunk = '/#~:.?+=&%@!\-';
+	$punc = '.:?\-';
+	$any = $ltrs . $gunk . $punc;
+
+	// Step 1
+	// Parsing the post, external links (if any) are stored in the $post_links array
+	// This regexp comes straight from phpfreaks.com
+	// http://www.phpfreaks.com/quickcode/Extract_All_URLs_on_a_Page/15.php
+	preg_match_all("{\b http : [$any] +? (?= [$punc] * [^$any] | $)}x", $content, $post_links_temp);
+
+	// Debug
+	debug_fwrite($log, 'Post contents:');
+	debug_fwrite($log, $content."\n");
+
+	// Step 2.
+	// Walking thru the links array
+	// first we get rid of links pointing to sites, not to specific files
+	// Example:
+	// http://dummy-weblog.org
+	// http://dummy-weblog.org/
+	// http://dummy-weblog.org/post.php
+	// We don't wanna ping first and second types, even if they have a valid <link/>
+
+	foreach ( $post_links_temp[0] as $link_test ) :
+		if ( !in_array($link_test, $pung) && (url_to_postid($link_test) != $post_ID) // If we haven't pung it already and it isn't a link to itself
+				&& !is_local_attachment($link_test) ) : // Also, let's never ping local attachments.
+			$test = parse_url($link_test);
+			if ( isset($test['query']) )
+				$post_links[] = $link_test;
+			elseif ( ($test['path'] != '/') && ($test['path'] != '') )
+				$post_links[] = $link_test;
+		endif;
+	endforeach;
+
+	do_action_ref_array('pre_ping', array(&$post_links, &$pung));
+
+	foreach ( (array) $post_links as $pagelinkedto ) {
+		debug_fwrite($log, "Processing -- $pagelinkedto\n");
+		$pingback_server_url = discover_pingback_server_uri($pagelinkedto, 2048);
+
+		if ( $pingback_server_url ) {
+			@ set_time_limit( 60 );
+			 // Now, the RPC call
+			debug_fwrite($log, "Page Linked To: $pagelinkedto \n");
+			debug_fwrite($log, 'Page Linked From: ');
+			$pagelinkedfrom = get_permalink($post_ID);
+			debug_fwrite($log, $pagelinkedfrom."\n");
+
+			// using a timeout of 3 seconds should be enough to cover slow servers
+			$client = new IXR_Client($pingback_server_url);
+			$client->timeout = 3;
+			$client->useragent .= ' -- WordPress/' . $wp_version;
+
+			// when set to true, this outputs debug messages by itself
+			$client->debug = false;
+
+			if ( $client->query('pingback.ping', $pagelinkedfrom, $pagelinkedto ) )
+				add_ping( $post_ID, $pagelinkedto );
+			else
+				debug_fwrite($log, "Error.\n Fault code: ".$client->getErrorCode()." : ".$client->getErrorMessage()."\n");
+		}
+	}
+
+	debug_fwrite($log, "\nEND: ".time()."\n****************************\n");
+	debug_fclose($log);
+}
+
+
+function privacy_ping_filter($sites) {
+	if ( '0' != get_option('blog_public') )
+		return $sites;
+	else
+		return '';
+}
+
+// Send a Trackback
+function trackback($trackback_url, $title, $excerpt, $ID) {
+	global $wpdb, $wp_version;
+
+	if ( empty($trackback_url) )
+		return;
+
+	$title = urlencode($title);
+	$excerpt = urlencode($excerpt);
+	$blog_name = urlencode(get_option('blogname'));
+	$tb_url = $trackback_url;
+	$url = urlencode(get_permalink($ID));
+	$query_string = "title=$title&url=$url&blog_name=$blog_name&excerpt=$excerpt";
+	$trackback_url = parse_url($trackback_url);
+	$http_request = 'POST ' . $trackback_url['path'] . ($trackback_url['query'] ? '?'.$trackback_url['query'] : '') . " HTTP/1.0\r\n";
+	$http_request .= 'Host: '.$trackback_url['host']."\r\n";
+	$http_request .= 'Content-Type: application/x-www-form-urlencoded; charset='.get_option('blog_charset')."\r\n";
+	$http_request .= 'Content-Length: '.strlen($query_string)."\r\n";
+	$http_request .= "User-Agent: WordPress/" . $wp_version;
+	$http_request .= "\r\n\r\n";
+	$http_request .= $query_string;
+	if ( '' == $trackback_url['port'] )
+		$trackback_url['port'] = 80;
+	$fs = @fsockopen($trackback_url['host'], $trackback_url['port'], $errno, $errstr, 4);
+	@fputs($fs, $http_request);
+/*
+	$debug_file = 'trackback.log';
+	$fp = fopen($debug_file, 'a');
+	fwrite($fp, "\n*****\nRequest:\n\n$http_request\n\nResponse:\n\n");
+	while(!@feof($fs)) {
+		fwrite($fp, @fgets($fs, 4096));
+	}
+	fwrite($fp, "\n\n");
+	fclose($fp);
+*/
+	@fclose($fs);
+
+	$tb_url = addslashes( $tb_url );
+	$wpdb->query("UPDATE $wpdb->posts SET pinged = CONCAT(pinged, '\n', '$tb_url') WHERE ID = '$ID'");
+	return $wpdb->query("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '$tb_url', '')) WHERE ID = '$ID'");
+}
+
+
+function weblog_ping($server = '', $path = '') {
+	global $wp_version;
+	include_once(ABSPATH . WPINC . '/class-IXR.php');
+
+	// using a timeout of 3 seconds should be enough to cover slow servers
+	$client = new IXR_Client($server, ((!strlen(trim($path)) || ('/' == $path)) ? false : $path));
+	$client->timeout = 3;
+	$client->useragent .= ' -- WordPress/'.$wp_version;
+
+	// when set to true, this outputs debug messages by itself
+	$client->debug = false;
+	$home = trailingslashit( get_option('home') );
+	if ( !$client->query('weblogUpdates.extendedPing', get_option('blogname'), $home, get_bloginfo('rss2_url') ) ) // then try a normal ping
+		$client->query('weblogUpdates.ping', get_option('blogname'), $home);
+}
+
+?>
diff -ruN 2.0.5/wp-includes/compat.php 2.2.2/wp-includes/compat.php
--- 2.0.5/wp-includes/compat.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/compat.php	2007-04-05 21:54:12.000000000 -0500
@@ -0,0 +1,128 @@
+<?php
+
+/* Functions missing from older PHP versions */
+
+
+/* Added in PHP 4.2.0 */
+
+if (!function_exists('floatval')) {
+	function floatval($string) {
+		return ((float) $string);
+	}
+}
+
+if (!function_exists('is_a')) {
+	function is_a($object, $class) {
+		// by Aidan Lister <aidan@php.net>
+		if (get_class($object) == strtolower($class)) {
+			return true;
+		} else {
+			return is_subclass_of($object, $class);
+		}
+	}
+}
+
+if (!function_exists('ob_clean')) {
+	function ob_clean() {
+		// by Aidan Lister <aidan@php.net>
+		if (@ob_end_clean()) {
+			return ob_start();
+		}
+		return false;
+	}
+}
+
+
+/* Added in PHP 4.3.0 */
+
+function printr($var, $do_not_echo = false) {
+	// from php.net/print_r user contributed notes
+	ob_start();
+	print_r($var);
+	$code =  htmlentities(ob_get_contents());
+	ob_clean();
+	if (!$do_not_echo) {
+		echo "<pre>$code</pre>";
+	}
+	ob_end_clean();
+	return $code;
+}
+
+/* compatibility with PHP versions older than 4.3 */
+if ( !function_exists('file_get_contents') ) {
+	function file_get_contents( $file ) {
+		$file = file($file);
+		return !$file ? false : implode('', $file);
+	}
+}
+
+if (!defined('CASE_LOWER')) {
+		define('CASE_LOWER', 0);
+}
+
+if (!defined('CASE_UPPER')) {
+		define('CASE_UPPER', 1);
+}
+
+
+/**
+ * Replace array_change_key_case()
+ *
+ * @category    PHP
+ * @package     PHP_Compat
+ * @link        http://php.net/function.array_change_key_case
+ * @author      Stephan Schmidt <schst@php.net>
+ * @author      Aidan Lister <aidan@php.net>
+ * @version     $Revision: 5187 $
+ * @since       PHP 4.2.0
+ * @require     PHP 4.0.0 (user_error)
+ */
+if (!function_exists('array_change_key_case')) {
+		function array_change_key_case($input, $case = CASE_LOWER)
+		{
+				if (!is_array($input)) {
+						user_error('array_change_key_case(): The argument should be an array',
+								E_USER_WARNING);
+						return false;
+				}
+
+				$output   = array ();
+				$keys     = array_keys($input);
+				$casefunc = ($case == CASE_LOWER) ? 'strtolower' : 'strtoupper';
+
+				foreach ($keys as $key) {
+						$output[$casefunc($key)] = $input[$key];
+				}
+
+				return $output;
+		}
+}
+
+// From php.net
+if(!function_exists('http_build_query')) {
+	 function http_build_query( $formdata, $numeric_prefix = null, $key = null ) {
+			 $res = array();
+			 foreach ((array)$formdata as $k=>$v) {
+					 $tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
+					 if ($key) $tmp_key = $key.'['.$tmp_key.']';
+					 $res[] = ( ( is_array($v) || is_object($v) ) ? http_build_query($v, null, $tmp_key) : $tmp_key."=".urlencode($v) );
+			 }
+			 $separator = ini_get('arg_separator.output');
+			 return implode($separator, $res);
+	 }
+}
+
+if ( !function_exists('_') ) {
+	function _($string) {
+		return $string;
+	}
+}
+
+// Added in PHP 5.0
+if (!function_exists('stripos')) {
+	function stripos($haystack, $needle, $offset = 0) {
+		return strpos(strtolower($haystack), strtolower($needle), $offset);
+	}
+}
+
+?>
diff -ruN 2.0.5/wp-includes/cron.php 2.2.2/wp-includes/cron.php
--- 2.0.5/wp-includes/cron.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/cron.php	2007-04-16 15:47:23.000000000 -0500
@@ -0,0 +1,191 @@
+<?php
+
+function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
+	$crons = _get_cron_array();
+	$key = md5(serialize($args));
+	$crons[$timestamp][$hook][$key] = array( 'schedule' => false, 'args' => $args );
+	uksort( $crons, "strnatcasecmp" );
+	_set_cron_array( $crons );
+}
+
+function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
+	$crons = _get_cron_array();
+	$schedules = wp_get_schedules();
+	$key = md5(serialize($args));
+	if ( !isset( $schedules[$recurrence] ) )
+		return false;
+	$crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
+	uksort( $crons, "strnatcasecmp" );
+	_set_cron_array( $crons );
+}
+
+function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
+	$crons = _get_cron_array();
+	$schedules = wp_get_schedules();
+	$key = md5(serialize($args));
+	$interval = 0;
+
+	// First we try to get it from the schedule
+	if ( 0 == $interval )
+		$interval = $schedules[$recurrence]['interval'];
+	// Now we try to get it from the saved interval in case the schedule disappears
+	if ( 0 == $interval )
+		$interval = $crons[$timestamp][$hook][$key]['interval'];
+	// Now we assume something is wrong and fail to schedule
+	if ( 0 == $interval )
+		return false;
+
+	while ( $timestamp < time() + 1 )
+		$timestamp += $interval;
+
+	wp_schedule_event( $timestamp, $recurrence, $hook, $args );
+}
+
+function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
+	$crons = _get_cron_array();
+	$key = md5(serialize($args));
+	unset( $crons[$timestamp][$hook][$key] );
+	if ( empty($crons[$timestamp][$hook]) )
+		unset( $crons[$timestamp][$hook] );
+	if ( empty($crons[$timestamp]) )
+		unset( $crons[$timestamp] );
+	_set_cron_array( $crons );
+}
+
+function wp_clear_scheduled_hook( $hook ) {
+	$args = array_slice( func_get_args(), 1 );
+
+	while ( $timestamp = wp_next_scheduled( $hook, $args ) )
+		wp_unschedule_event( $timestamp, $hook, $args );
+}
+
+function wp_next_scheduled( $hook, $args = array() ) {
+	$crons = _get_cron_array();
+	$key = md5(serialize($args));
+	if ( empty($crons) )
+		return false;
+	foreach ( $crons as $timestamp => $cron ) {
+		if ( isset( $cron[$hook][$key] ) )
+			return $timestamp;
+	}
+	return false;
+}
+
+function spawn_cron() {
+	$crons = _get_cron_array();
+
+	if ( !is_array($crons) )
+		return;
+
+	$keys = array_keys( $crons );
+	if ( array_shift( $keys ) > time() )
+		return;
+
+	$cron_url = get_option( 'siteurl' ) . '/wp-cron.php';
+	$parts = parse_url( $cron_url );
+	
+	if ($parts['scheme'] == 'https') {
+		// support for SSL was added in 4.3.0
+		if (version_compare(phpversion(), '4.3.0', '>=') && function_exists('openssl_open')) {
+			$argyle = @fsockopen('ssl://' . $parts['host'], $_SERVER['SERVER_PORT'], $errno, $errstr, 0.01);
+		} else {
+			return false;
+		}
+	} else {
+		$argyle = @ fsockopen( $parts['host'], $_SERVER['SERVER_PORT'], $errno, $errstr, 0.01 );
+	}
+	
+	if ( $argyle )
+		fputs( $argyle,
+			  "GET {$parts['path']}?check=" . wp_hash('187425') . " HTTP/1.0\r\n"
+			. "Host: {$_SERVER['HTTP_HOST']}\r\n\r\n"
+		);
+}
+
+function wp_cron() {
+	// Prevent infinite loops caused by lack of wp-cron.php
+	if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false )
+		return;
+
+	$crons = _get_cron_array();
+
+	if ( !is_array($crons) )
+		return;
+
+	$keys = array_keys( $crons );
+	if ( isset($keys[0]) && $keys[0] > time() )
+		return;
+
+	$schedules = wp_get_schedules();
+	foreach ( $crons as $timestamp => $cronhooks ) {
+		if ( $timestamp > time() ) break;
+		foreach ( $cronhooks as $hook => $args ) {
+			if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
+				continue;
+			spawn_cron();
+			break 2;
+		}
+	}
+}
+
+function wp_get_schedules() {
+	$schedules = array(
+		'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ),
+		'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ),
+	);
+	return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
+}
+
+function wp_get_schedule($hook, $args = array()) {
+	$crons = _get_cron_array();
+	$key = md5(serialize($args));
+	if ( empty($crons) )
+		return false;
+	foreach ( $crons as $timestamp => $cron ) {
+		if ( isset( $cron[$hook][$key] ) )
+			return $cron[$hook][$key]['schedule'];
+	}
+	return false;
+}
+
+//
+// Private functions
+//
+
+function _get_cron_array()  {
+	$cron = get_option('cron');
+	if ( ! is_array($cron) )
+		return false;
+
+	if ( !isset($cron['version']) )
+		$cron = _upgrade_cron_array($cron);
+
+	unset($cron['version']);
+
+	return $cron;
+}
+
+function _set_cron_array($cron) {
+	$cron['version'] = 2;
+	update_option( 'cron', $cron );
+}
+
+function _upgrade_cron_array($cron) {
+	if ( isset($cron['version']) && 2 == $cron['version'])
+		return $cron;
+
+	$new_cron = array();
+
+	foreach ($cron as $timestamp => $hooks) {
+		foreach ( $hooks as $hook => $args ) {
+			$key = md5(serialize($args['args']));
+			$new_cron[$timestamp][$hook][$key] = $args;
+		}
+	}
+
+	$new_cron['version'] = 2;
+	update_option( 'cron', $new_cron );
+	return $new_cron;
+}
+
+?>
diff -ruN 2.0.5/wp-includes/default-filters.php 2.2.2/wp-includes/default-filters.php
--- 2.0.5/wp-includes/default-filters.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/default-filters.php	2007-05-12 17:37:07.000000000 -0500
@@ -24,15 +24,15 @@
 add_filter('pre_comment_author_url', 'trim');
 add_filter('pre_comment_author_url', 'clean_url');
 
-add_filter('pre_comment_content', 'stripslashes', 1);
 add_filter('pre_comment_content', 'wp_rel_nofollow', 15);
 add_filter('pre_comment_content', 'balanceTags', 30);
-add_filter('pre_comment_content', 'addslashes', 50);
 
 add_filter('pre_comment_author_name', 'wp_filter_kses');
 add_filter('pre_comment_author_email', 'wp_filter_kses');
 add_filter('pre_comment_author_url', 'wp_filter_kses');
 
+add_action('comment_form', 'wp_comment_form_unfiltered_html_nonce');
+
 // Default filters for these functions
 add_filter('comment_author', 'wptexturize');
 add_filter('comment_author', 'convert_chars');
@@ -40,10 +40,12 @@
 
 add_filter('comment_email', 'antispambot');
 
+add_filter('comment_flood_filter', 'wp_throttle_comment_flood', 10, 3);
+
 add_filter('comment_url', 'clean_url');
 
 add_filter('comment_text', 'convert_chars');
-add_filter('comment_text', 'make_clickable');
+add_filter('comment_text', 'make_clickable', 9);
 add_filter('comment_text', 'force_balance_tags', 25);
 add_filter('comment_text', 'wpautop', 30);
 add_filter('comment_text', 'convert_smilies', 20);
@@ -141,11 +143,37 @@
 add_filter('the_author', 'ent2ncr', 8);
 
 // Misc filters
+add_filter('option_ping_sites', 'privacy_ping_filter');
 add_filter('option_blog_charset', 'wp_specialchars');
+add_filter('option_home', '_config_wp_home');
+add_filter('option_siteurl', '_config_wp_siteurl');
+add_filter('mce_plugins', '_mce_load_rtl_plugin');
+add_filter('mce_buttons', '_mce_add_direction_buttons');
+
+// Redirect Old Slugs
+add_action('template_redirect', 'wp_old_slug_redirect');
+add_action('edit_post', 'wp_check_for_changed_slugs');
+add_action('edit_form_advanced', 'wp_remember_old_slug');
 
 // Actions
-add_action('publish_post', 'generic_ping');
 add_action('wp_head', 'rsd_link');
+add_action('wp_head', 'locale_stylesheet');
+add_action('publish_future_post', 'wp_publish_post', 10, 1);
+add_action('wp_head', 'noindex', 1);
+add_action('wp_head', 'wp_print_scripts');
+if(!defined('DOING_CRON'))
+	add_action('init', 'wp_cron');
+add_action('do_feed_rdf', 'do_feed_rdf', 10, 1);
+add_action('do_feed_rss', 'do_feed_rss', 10, 1);
+add_action('do_feed_rss2', 'do_feed_rss2', 10, 1);
+add_action('do_feed_atom', 'do_feed_atom', 10, 1);
+add_action('do_pings', 'do_all_pings', 10, 1);
+add_action('do_robots', 'do_robots');
 add_action('sanitize_comment_cookies', 'sanitize_comment_cookies');
+add_action('admin_print_scripts', 'wp_print_scripts', 20);
+add_action('mce_options', '_mce_set_direction');
+add_action('init', 'smilies_init', 5);
+add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );
+add_action( 'shutdown', 'wp_ob_end_flush_all', 1);
 
-?>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/deprecated.php 2.2.2/wp-includes/deprecated.php
--- 2.0.5/wp-includes/deprecated.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/deprecated.php	2007-01-23 03:15:17.000000000 -0600
@@ -0,0 +1,515 @@
+<?php
+
+/*
+ * Deprecated global variables.
+ */
+
+$tableposts = $wpdb->posts;
+$tableusers = $wpdb->users;
+$tablecategories = $wpdb->categories;
+$tablepost2cat = $wpdb->post2cat;
+$tablecomments = $wpdb->comments;
+$tablelinks = $wpdb->links;
+$tablelinkcategories = 'linkcategories_is_gone';
+$tableoptions = $wpdb->options;
+$tablepostmeta = $wpdb->postmeta;
+
+/*
+ * Deprecated functions come here to die.
+ */
+
+// Use get_post().
+function get_postdata($postid) {
+	$post = &get_post($postid);
+
+	$postdata = array (
+		'ID' => $post->ID,
+		'Author_ID' => $post->post_author,
+		'Date' => $post->post_date,
+		'Content' => $post->post_content,
+		'Excerpt' => $post->post_excerpt,
+		'Title' => $post->post_title,
+		'Category' => $post->post_category,
+		'post_status' => $post->post_status,
+		'comment_status' => $post->comment_status,
+		'ping_status' => $post->ping_status,
+		'post_password' => $post->post_password,
+		'to_ping' => $post->to_ping,
+		'pinged' => $post->pinged,
+		'post_type' => $post->post_type,
+		'post_name' => $post->post_name
+	);
+
+	return $postdata;
+}
+
+// Use the new post loop.
+function start_wp() {
+	global $wp_query, $post;
+
+	// Since the old style loop is being used, advance the query iterator here.
+	$wp_query->next_post();
+
+	setup_postdata($post);
+}
+
+function the_category_ID($echo = true) {
+	// Grab the first cat in the list.
+	$categories = get_the_category();
+	$cat = $categories[0]->cat_ID;
+
+	if ( $echo )
+		echo $cat;
+
+	return $cat;
+}
+
+function the_category_head($before='', $after='') {
+	global $currentcat, $previouscat;
+	// Grab the first cat in the list.
+	$categories = get_the_category();
+	$currentcat = $categories[0]->category_id;
+	if ( $currentcat != $previouscat ) {
+		echo $before;
+		echo get_the_category_by_ID($currentcat);
+		echo $after;
+		$previouscat = $currentcat;
+	}
+}
+
+// Use previous_post_link().
+function previous_post($format='%', $previous='previous post: ', $title='yes', $in_same_cat='no', $limitprev=1, $excluded_categories='') {
+
+	if ( empty($in_same_cat) || 'no' == $in_same_cat )
+		$in_same_cat = false;
+	else
+		$in_same_cat = true;
+
+	$post = get_previous_post($in_same_cat, $excluded_categories);
+
+	if ( !$post )
+		return;
+
+	$string = '<a href="'.get_permalink($post->ID).'">'.$previous;
+	if ( 'yes' == $title )
+		$string .= apply_filters('the_title', $post->post_title, $post);
+	$string .= '</a>';
+	$format = str_replace('%', $string, $format);
+	echo $format;
+}
+
+// Use next_post_link().
+function next_post($format='%', $next='next post: ', $title='yes', $in_same_cat='no', $limitnext=1, $excluded_categories='') {
+
+	if ( empty($in_same_cat) || 'no' == $in_same_cat )
+		$in_same_cat = false;
+	else
+		$in_same_cat = true;
+
+	$post = get_next_post($in_same_cat, $excluded_categories);
+
+	if ( !$post	)
+		return;
+
+	$string = '<a href="'.get_permalink($post->ID).'">'.$next;
+	if ( 'yes' == $title )
+		$string .= apply_filters('the_title', $post->post_title, $nextpost);
+	$string .= '</a>';
+	$format = str_replace('%', $string, $format);
+	echo $format;
+}
+
+//
+// Use current_user_can() for these.
+//
+
+/* returns true if $user_id can create a new post */
+function user_can_create_post($user_id, $blog_id = 1, $category_id = 'None') {
+	$author_data = get_userdata($user_id);
+	return ($author_data->user_level > 1);
+}
+
+/* returns true if $user_id can create a new post */
+function user_can_create_draft($user_id, $blog_id = 1, $category_id = 'None') {
+	$author_data = get_userdata($user_id);
+	return ($author_data->user_level >= 1);
+}
+
+/* returns true if $user_id can edit $post_id */
+function user_can_edit_post($user_id, $post_id, $blog_id = 1) {
+	$author_data = get_userdata($user_id);
+	$post = get_post($post_id);
+	$post_author_data = get_userdata($post->post_author);
+
+	if ( (($user_id == $post_author_data->ID) && !($post->post_status == 'publish' &&  $author_data->user_level < 2))
+			 || ($author_data->user_level > $post_author_data->user_level)
+			 || ($author_data->user_level >= 10) ) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+/* returns true if $user_id can delete $post_id */
+function user_can_delete_post($user_id, $post_id, $blog_id = 1) {
+	// right now if one can edit, one can delete
+	return user_can_edit_post($user_id, $post_id, $blog_id);
+}
+
+/* returns true if $user_id can set new posts' dates on $blog_id */
+function user_can_set_post_date($user_id, $blog_id = 1, $category_id = 'None') {
+	$author_data = get_userdata($user_id);
+	return (($author_data->user_level > 4) && user_can_create_post($user_id, $blog_id, $category_id));
+}
+
+/* returns true if $user_id can edit $post_id's date */
+function user_can_edit_post_date($user_id, $post_id, $blog_id = 1) {
+	$author_data = get_userdata($user_id);
+	return (($author_data->user_level > 4) && user_can_edit_post($user_id, $post_id, $blog_id));
+}
+
+/* returns true if $user_id can edit $post_id's comments */
+function user_can_edit_post_comments($user_id, $post_id, $blog_id = 1) {
+	// right now if one can edit a post, one can edit comments made on it
+	return user_can_edit_post($user_id, $post_id, $blog_id);
+}
+
+/* returns true if $user_id can delete $post_id's comments */
+function user_can_delete_post_comments($user_id, $post_id, $blog_id = 1) {
+	// right now if one can edit comments, one can delete comments
+	return user_can_edit_post_comments($user_id, $post_id, $blog_id);
+}
+
+function user_can_edit_user($user_id, $other_user) {
+	$user  = get_userdata($user_id);
+	$other = get_userdata($other_user);
+	if ( $user->user_level > $other->user_level || $user->user_level > 8 || $user->ID == $other->ID )
+		return true;
+	else
+		return false;
+}
+
+/** function get_linksbyname()
+ ** Gets the links associated with category 'cat_name'.
+ ** Parameters:
+ **   cat_name (default 'noname')  - The category name to use. If no
+ **     match is found uses all
+ **   before (default '')  - the html to output before the link
+ **   after (default '<br />')  - the html to output after the link
+ **   between (default ' ')  - the html to output between the link/image
+ **     and it's description. Not used if no image or show_images == true
+ **   show_images (default true) - whether to show images (if defined).
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url', 'description' or 'rating'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   show_description (default true) - whether to show the description if
+ **     show_images=false/not defined
+ **   show_rating (default false) - show rating stars/chars
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **   show_updated (default 0) - whether to show last updated timestamp
+ */
+function get_linksbyname($cat_name = "noname", $before = '', $after = '<br />',
+												 $between = " ", $show_images = true, $orderby = 'id',
+												 $show_description = true, $show_rating = false,
+												 $limit = -1, $show_updated = 0) {
+		global $wpdb;
+		$cat_id = -1;
+		$results = $wpdb->get_results("SELECT cat_ID FROM $wpdb->categories WHERE cat_name='$cat_name'");
+		if ($results) {
+				foreach ($results as $result) {
+						$cat_id = $result->cat_ID;
+				}
+		}
+		get_links($cat_id, $before, $after, $between, $show_images, $orderby,
+							$show_description, $show_rating, $limit, $show_updated);
+}
+
+/** function wp_get_linksbyname()
+ ** Gets the links associated with the named category.
+ ** Parameters:
+ **   category (no default)  - The category to use.
+ **/
+function wp_get_linksbyname($category, $args = '') {
+	global $wpdb;
+
+	$cat_id = $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE cat_name='$category' LIMIT 1");
+
+	if (! $cat_id)
+		return;
+
+	$args = add_query_arg('category', $cat_id, $args);
+	wp_get_links($args);
+}
+
+/** function get_linkobjectsbyname()
+ ** Gets an array of link objects associated with category 'cat_name'.
+ ** Parameters:
+ **   cat_name (default 'noname')  - The category name to use. If no
+ **     match is found uses all
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url', 'description', or 'rating'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **
+ ** Use this like:
+ ** $links = get_linkobjectsbyname('fred');
+ ** foreach ($links as $link) {
+ **   echo '<li>'.$link->link_name.'</li>';
+ ** }
+ **/
+// Deprecate in favor of get_linkz().
+function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit = -1) {
+		global $wpdb;
+		$cat_id = -1;
+		//$results = $wpdb->get_results("SELECT cat_id FROM $wpdb->linkcategories WHERE cat_name='$cat_name'");
+		// TODO: Fix me.
+		if ($results) {
+				foreach ($results as $result) {
+						$cat_id = $result->cat_id;
+				}
+		}
+		return get_linkobjects($cat_id, $orderby, $limit);
+}
+
+/** function get_linkobjects()
+ ** Gets an array of link objects associated with category n.
+ ** Parameters:
+ **   category (default -1)  - The category to use. If no category supplied
+ **      uses all
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url', 'description', or 'rating'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **
+ ** Use this like:
+ ** $links = get_linkobjects(1);
+ ** if ($links) {
+ **   foreach ($links as $link) {
+ **     echo '<li>'.$link->link_name.'<br />'.$link->link_description.'</li>';
+ **   }
+ ** }
+ ** Fields are:
+ ** link_id
+ ** link_url
+ ** link_name
+ ** link_image
+ ** link_target
+ ** link_category
+ ** link_description
+ ** link_visible
+ ** link_owner
+ ** link_rating
+ ** link_updated
+ ** link_rel
+ ** link_notes
+ **/
+// Deprecate in favor of get_linkz().
+function get_linkobjects($category = -1, $orderby = 'name', $limit = -1) {
+		global $wpdb;
+
+		$sql = "SELECT * FROM $wpdb->links WHERE link_visible = 'Y'";
+		if ($category != -1) {
+				$sql .= " AND link_category = $category ";
+		}
+		if ($orderby == '')
+				$orderby = 'id';
+		if (substr($orderby,0,1) == '_') {
+				$direction = ' DESC';
+				$orderby = substr($orderby,1);
+		}
+		if (strcasecmp('rand',$orderby) == 0) {
+				$orderby = 'rand()';
+		} else {
+				$orderby = " link_" . $orderby;
+		}
+		$sql .= ' ORDER BY ' . $orderby;
+		$sql .= $direction;
+		/* The next 2 lines implement LIMIT TO processing */
+		if ($limit != -1)
+				$sql .= " LIMIT $limit";
+
+		$results = $wpdb->get_results($sql);
+		if ($results) {
+				foreach ($results as $result) {
+						$result->link_url         = $result->link_url;
+						$result->link_name        = $result->link_name;
+						$result->link_description = $result->link_description;
+						$result->link_notes       = $result->link_notes;
+						$newresults[] = $result;
+				}
+		}
+		return $newresults;
+}
+
+/** function get_linksbyname_withrating()
+ ** Gets the links associated with category 'cat_name' and display rating stars/chars.
+ ** Parameters:
+ **   cat_name (default 'noname')  - The category name to use. If no
+ **     match is found uses all
+ **   before (default '')  - the html to output before the link
+ **   after (default '<br />')  - the html to output after the link
+ **   between (default ' ')  - the html to output between the link/image
+ **     and it's description. Not used if no image or show_images == true
+ **   show_images (default true) - whether to show images (if defined).
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url' or 'description'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   show_description (default true) - whether to show the description if
+ **     show_images=false/not defined
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **   show_updated (default 0) - whether to show last updated timestamp
+ */
+function get_linksbyname_withrating($cat_name = "noname", $before = '',
+																		$after = '<br />', $between = " ",
+																		$show_images = true, $orderby = 'id',
+																		$show_description = true, $limit = -1, $show_updated = 0) {
+
+		get_linksbyname($cat_name, $before, $after, $between, $show_images,
+										$orderby, $show_description, true, $limit, $show_updated);
+}
+
+/** function get_links_withrating()
+ ** Gets the links associated with category n and display rating stars/chars.
+ ** Parameters:
+ **   category (default -1)  - The category to use. If no category supplied
+ **      uses all
+ **   before (default '')  - the html to output before the link
+ **   after (default '<br />')  - the html to output after the link
+ **   between (default ' ')  - the html to output between the link/image
+ **     and it's description. Not used if no image or show_images == true
+ **   show_images (default true) - whether to show images (if defined).
+ **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
+ **     'url' or 'description'. Or maybe owner. If you start the
+ **     name with an underscore the order will be reversed.
+ **     You can also specify 'rand' as the order which will return links in a
+ **     random order.
+ **   show_description (default true) - whether to show the description if
+ **    show_images=false/not defined .
+ **   limit (default -1) - Limit to X entries. If not specified, all entries
+ **     are shown.
+ **   show_updated (default 0) - whether to show last updated timestamp
+ */
+function get_links_withrating($category = -1, $before = '', $after = '<br />',
+															$between = " ", $show_images = true,
+															$orderby = 'id', $show_description = true,
+															$limit = -1, $show_updated = 0) {
+
+		get_links($category, $before, $after, $between, $show_images, $orderby,
+							$show_description, true, $limit, $show_updated);
+}
+
+/** function get_get_autotoggle()
+ ** Gets the auto_toggle setting of category n.
+ ** Parameters: id (default 0)  - The category to get. If no category supplied
+ **                uses 0
+ */
+function get_autotoggle($id = 0) {
+	return 0;
+}
+
+// Use wp_list_cats().
+function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc', $file = '', $list = true, $optiondates = 0, $optioncount = 0, $hide_empty = 1, $use_desc_for_title = 1, $children=FALSE, $child_of=0, $categories=0, $recurse=0, $feed = '', $feed_image = '', $exclude = '', $hierarchical=FALSE) {
+	$query = compact('optionall', 'all', 'sort_column', 'sort_order', 'file', 'list', 'optiondates', 'optioncount', 'hide_empty', 'use_desc_for_title', 'children',
+		'child_of', 'categories', 'recurse', 'feed', 'feed_image', 'exclude', 'hierarchical');
+	return wp_list_cats($query);
+}
+
+function wp_list_cats($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	// Map to new names.
+	if ( isset($r['optionall']) && isset($r['all']))
+		$r['show_option_all'] = $r['all'];
+	if ( isset($r['sort_column']) )
+		$r['orderby'] = $r['sort_column'];
+	if ( isset($r['sort_order']) )
+		$r['order'] = $r['sort_order'];
+	if ( isset($r['optiondates']) )
+		$r['show_last_update'] = $r['optiondates'];
+	if ( isset($r['optioncount']) )
+		$r['show_count'] = $r['optioncount'];
+	if ( isset($r['list']) )
+		$r['style'] = $r['list'] ? 'list' : 'break';
+	$r['title_li'] = '';
+
+	return wp_list_categories($r);
+}
+
+function dropdown_cats($optionall = 1, $all = 'All', $orderby = 'ID', $order = 'asc',
+		$show_last_update = 0, $show_count = 0, $hide_empty = 1, $optionnone = FALSE,
+		$selected = 0, $exclude = 0) {
+
+	$show_option_all = '';
+	if ( $optionall )
+		$show_option_all = $all;
+
+	$show_option_none = '';
+	if ( $optionnone )
+		$show_option_none = __('None');
+
+	$vars = compact('show_option_all', 'show_option_none', 'orderby', 'order',
+					'show_last_update', 'show_count', 'hide_empty', 'selected', 'exclude');
+	$query = add_query_arg($vars, '');
+	return wp_dropdown_categories($query);
+}
+
+// Use wp_print_scripts() or WP_Scripts.
+function tinymce_include() {
+	wp_print_script('wp_tiny_mce');
+}
+
+function list_authors($optioncount = false, $exclude_admin = true, $show_fullname = false, $hide_empty = true, $feed = '', $feed_image = '') {
+	$args = compact('optioncount', 'exclude_admin', 'show_fullname', 'hide_empty', 'feed', 'feed_image');
+	return wp_list_authors($args);
+}
+
+function wp_get_post_cats($blogid = '1', $post_ID = 0) {
+	return wp_get_post_categories($post_ID);
+}
+
+function wp_set_post_cats($blogid = '1', $post_ID = 0, $post_categories = array()) {
+	return wp_set_post_categories($post_ID, $post_categories);
+}
+
+// Use wp_get_archives().
+function get_archives($type='', $limit='', $format='html', $before = '', $after = '', $show_post_count = false) {
+	$args = compact('type', 'limit', 'format', 'before', 'after', 'show_post_count');
+	return wp_get_archives($args);
+}
+
+// Use get_author_posts_url().
+function get_author_link($echo = false, $author_id, $author_nicename = '') {
+	$link = get_author_posts_url($author_id, $author_nicename);
+
+	if ( $echo )
+		echo $link;
+	return $link;
+}
+
+// Use wp_link_pages().
+function link_pages($before='<br />', $after='<br />', $next_or_number='number', $nextpagelink='next page', $previouspagelink='previous page', $pagelink='%', $more_file='') {
+	$args = compact('before', 'after', 'next_or_number', 'nextpagelink', 'previouspagelink', 'pagelink', 'more_file');
+	return wp_link_pages($args);
+}
+
+// Use get_option().
+function get_settings($option) {
+	return get_option($option);
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/feed-atom-comments.php 2.2.2/wp-includes/feed-atom-comments.php
--- 2.0.5/wp-includes/feed-atom-comments.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-atom-comments.php	2007-05-31 17:14:42.000000000 -0500
@@ -0,0 +1,63 @@
+<?php
+header('Content-Type: application/atom+xml; charset=' . get_option('blog_charset'), true);
+echo '<?xml version="1.0" encoding="' . get_option('blog_charset') . '" ?' . '>';
+?>
+<feed
+	xmlns="http://www.w3.org/2005/Atom"
+	xml:lang="<?php echo get_option('rss_language'); ?>"
+	<?php do_action('atom_ns'); ?>
+>
+	<title type="text"><?php 
+		if ( is_singular() )
+			printf(__('Comments on: %s'), get_the_title_rss());
+		elseif ( is_search() )
+			printf(__('Comments for %s searching on %s'), get_bloginfo_rss( 'name' ), attribute_escape($wp_query->query_vars['s']));
+		else
+			printf(__('Comments for %s'), get_bloginfo_rss( 'name' ) . get_wp_title_rss());
+	?></title>
+	<subtitle type="text"><?php bloginfo_rss('description'); ?></subtitle>
+
+	<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastcommentmodified('GMT')); ?></updated>
+	<generator uri="http://wordpress.org/" version="<?php bloginfo('version'); ?>">WordPress</generator>
+
+	<link rel="alternate" type="<?php bloginfo_rss('html_type'); ?>" href="<?php bloginfo_rss('home'); ?>" />
+	<link rel="self" type="application/atom+xml" href="<?php bloginfo_rss('comments_atom_url'); ?>" />
+	<id><?php bloginfo_rss('comments_atom_url'); ?></id>
+
+<?php
+if ( have_comments() ) : while ( have_comments() ) : the_comment();
+	$comment_post = get_post($comment->comment_post_ID);
+	get_post_custom($comment_post->ID);
+?>
+	<entry>
+		<title><?php
+			if ( !is_singular() ) {
+				$title = get_the_title($comment_post->ID);
+				$title = apply_filters('the_title', $title);
+				$title = apply_filters('the_title_rss', $title);
+				printf(__('Comment on %1$s by %2$s'), $title, get_comment_author_rss());
+			} else {
+				printf(__('By: %s'), get_comment_author_rss());
+			}
+		?></title>
+		<link rel="alternate" href="<?php comment_link(); ?>" type="<?php bloginfo_rss('html_type'); ?>" />
+
+		<author>
+			<name><?php comment_author_rss(); ?></name>
+			<?php if (get_comment_author_url()) echo '<uri>' . get_comment_author_url() . '</uri>'; ?>
+
+		</author>
+
+		<id><?php comment_link(); ?></id>
+		<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_comment_time('Y-m-d H:i:s', true), false); ?></updated>
+		<published><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_comment_time('Y-m-d H:i:s', true), false); ?></published>
+<?php if (!empty($comment_post->post_password) && $_COOKIE['wp-postpass'] != $comment_post->post_password) : ?>
+		<content type="html" xml:base="<?php comment_link(); ?>"><![CDATA[<?php echo get_the_password_form(); ?>]]></content>
+<?php else : // post pass ?>
+		<content type="html" xml:base="<?php comment_link(); ?>"><![CDATA[<?php comment_text(); ?>]]></content>
+<?php endif; // post pass
+	do_action('comment_atom_entry', $comment->comment_ID, $comment_post->ID);
+?>
+	</entry>
+<?php endwhile; endif; ?>
+</feed>
diff -ruN 2.0.5/wp-includes/feed-atom.php 2.2.2/wp-includes/feed-atom.php
--- 2.0.5/wp-includes/feed-atom.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-atom.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,45 @@
+<?php
+header('Content-type: application/atom+xml; charset=' . get_option('blog_charset'), true);
+$more = 1;
+
+?>
+<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
+<feed
+  xmlns="http://www.w3.org/2005/Atom"
+  xmlns:thr="http://purl.org/syndication/thread/1.0"
+  xml:lang="<?php echo get_option('rss_language'); ?>"
+  xml:base="<?php bloginfo_rss('home') ?>/wp-atom.php"
+  <?php do_action('atom_ns'); ?>
+ >
+	<title type="text"><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
+	<subtitle type="text"><?php bloginfo_rss("description") ?></subtitle>
+
+	<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT')); ?></updated>
+	<generator uri="http://wordpress.org/" version="<?php bloginfo_rss('version'); ?>">WordPress</generator>
+
+	<link rel="alternate" type="text/html" href="<?php bloginfo_rss('home') ?>" />
+	<id><?php bloginfo('atom_url'); ?></id>
+	<link rel="self" type="application/atom+xml" href="<?php bloginfo('atom_url'); ?>" />
+
+	<?php do_action('atom_head'); ?>
+	<?php while (have_posts()) : the_post(); ?>
+	<entry>
+		<author>
+			<name><?php the_author() ?></name>
+			<uri><?php the_author_url()?></uri>
+		</author>
+		<title type="<?php html_type_rss(); ?>"><![CDATA[<?php the_title_rss() ?>]]></title>
+		<link rel="alternate" type="text/html" href="<?php permalink_single_rss() ?>" />
+		<id><?php the_guid(); ?></id>
+		<updated><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></updated>
+		<published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published>
+		<?php the_category_rss('atom') ?>
+		<summary type="<?php html_type_rss(); ?>"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
+<?php if ( !get_option('rss_use_excerpt') ) : ?>
+		<content type="<?php html_type_rss(); ?>" xml:base="<?php permalink_single_rss() ?>"><![CDATA[<?php the_content('', 0, '') ?>]]></content>
+<?php endif; ?>
+<?php atom_enclosure(); ?>
+<?php do_action('atom_entry'); ?>
+	</entry>
+	<?php endwhile ; ?>
+</feed>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/feed-functions.php 2.2.2/wp-includes/feed-functions.php
--- 2.0.5/wp-includes/feed-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/feed-functions.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,164 +0,0 @@
-<?php
-
-function get_bloginfo_rss($show = '') {
-	$info = strip_tags(get_bloginfo($show));
-	return convert_chars($info);
-}
-
-function bloginfo_rss($show = '') {
-	echo get_bloginfo_rss($show);
-}
-
-function get_the_title_rss() {
-	$title = get_the_title();
-	$title = apply_filters('the_title', $title);
-	$title = apply_filters('the_title_rss', $title);
-	return $title;
-}
-
-function the_title_rss() {
-	echo get_the_title_rss();
-}
-
-function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file='', $cut = 0, $encode_html = 0) {
-	$content = get_the_content($more_link_text, $stripteaser, $more_file);
-	$content = apply_filters('the_content_rss', $content);
-	if ($cut && !$encode_html) {
-		$encode_html = 2;
-	}
-	if ($encode_html == 1) {
-		$content = wp_specialchars($content);
-		$cut = 0;
-	} elseif ($encode_html == 0) {
-		$content = make_url_footnote($content);
-	} elseif ($encode_html == 2) {
-		$content = strip_tags($content);
-	}
-	if ($cut) {
-		$blah = explode(' ', $content);
-		if (count($blah) > $cut) {
-			$k = $cut;
-			$use_dotdotdot = 1;
-		} else {
-			$k = count($blah);
-			$use_dotdotdot = 0;
-		}
-		for ($i=0; $i<$k; $i++) {
-			$excerpt .= $blah[$i].' ';
-		}
-		$excerpt .= ($use_dotdotdot) ? '...' : '';
-		$content = $excerpt;
-	}
-	$content = str_replace(']]>', ']]&gt;', $content);
-	echo $content;
-}
-
-function the_excerpt_rss() {
-	$output = get_the_excerpt(true);
-	echo apply_filters('the_excerpt_rss', $output);
-}
-
-function permalink_single_rss($file = '') {
-    echo get_permalink();
-}
-
-function comment_link() {
-	echo get_comment_link();
-}
-
-function get_comment_author_rss() {
-	return apply_filters('comment_author_rss', get_comment_author() );
-}
-function comment_author_rss() {
-	echo get_comment_author_rss();
-}
-
-function comment_text_rss() {
-	$comment_text = get_comment_text();
-	$comment_text = apply_filters('comment_text_rss', $comment_text);
-	echo $comment_text;
-}
-
-function comments_rss_link($link_text = 'Comments RSS', $commentsrssfilename = '') {
-	$url = comments_rss($commentsrssfilename);
-	echo "<a href='$url'>$link_text</a>";
-}
-
-function comments_rss($commentsrssfilename = '') {
-	global $id;
-
-	if ('' != get_settings('permalink_structure'))
-		$url = trailingslashit( get_permalink() ) . 'feed/';
-	else
-		$url = get_settings('home') . "/$commentsrssfilename?feed=rss2&amp;p=$id";
-
-	return apply_filters('post_comments_feed_link', $url);
-}
-
-function get_author_rss_link($echo = false, $author_id, $author_nicename) {
-       $auth_ID = $author_id;
-       $permalink_structure = get_settings('permalink_structure');
-
-       if ('' == $permalink_structure) {
-				 $link = get_settings('home') . '?feed=rss2&amp;author=' . $author_id;
-       } else {
-				 $link = get_author_link(0, $author_id, $author_nicename);
-				 $link = $link . "feed/";
-       }
-			 
-			 $link = apply_filters('author_feed_link', $link);
-
-       if ($echo) echo $link;
-       return $link;
-}
-
-function get_category_rss_link($echo = false, $cat_ID, $category_nicename) {
-       $permalink_structure = get_settings('permalink_structure');
-
-       if ('' == $permalink_structure) {
-				 $link = get_settings('home') . '?feed=rss2&amp;cat=' . $cat_ID;
-       } else {
-				 $link = get_category_link($cat_ID);
-				 $link = $link . "feed/";
-       }
-
-			 $link = apply_filters('category_feed_link', $link);
-
-       if ($echo) echo $link;
-       return $link;
-}
-
-function the_category_rss($type = 'rss') {
-    $categories = get_the_category();
-    $the_list = '';
-    foreach ($categories as $category) {
-        $category->cat_name = convert_chars($category->cat_name);
-        if ('rdf' == $type) {
-            $the_list .= "\n\t\t<dc:subject>$category->cat_name</dc:subject>\n";
-        } else {
-            $the_list .= "\n\t\t<category>$category->cat_name</category>\n";
-        }
-    }
-    echo apply_filters('the_category_rss', $the_list, $type);
-}
-
-function rss_enclosure() {
-	global $id, $post;
-	if (!empty($post->post_password) && ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password)) return;
-
-	$custom_fields = get_post_custom();
-	if( is_array( $custom_fields ) ) {
-		while( list( $key, $val ) = each( $custom_fields ) ) { 
-			if( $key == 'enclosure' ) {
-				if (is_array($val)) {
-					foreach($val as $enc) {
-						$enclosure = split( "\n", $enc );
-						print "<enclosure url='".trim( htmlspecialchars($enclosure[ 0 ]) )."' length='".trim( $enclosure[ 1 ] )."' type='".trim( $enclosure[ 2 ] )."'/>\n";
-					}
-				}
-			}
-		}
-	}
-}
-
-?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/feed-rdf.php 2.2.2/wp-includes/feed-rdf.php
--- 2.0.5/wp-includes/feed-rdf.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-rdf.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,51 @@
+<?php
+header('Content-type: application/rdf+xml; charset=' . get_option('blog_charset'), true);
+$more = 1;
+
+?>
+<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
+<!-- generator="wordpress/<?php echo $wp_version ?>" -->
+<rdf:RDF
+	xmlns="http://purl.org/rss/1.0/"
+	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	xmlns:dc="http://purl.org/dc/elements/1.1/"
+	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+	xmlns:admin="http://webns.net/mvcb/"
+	xmlns:content="http://purl.org/rss/1.0/modules/content/"
+	<?php do_action('rdf_ns'); ?>
+>
+<channel rdf:about="<?php bloginfo_rss("url") ?>">
+	<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
+	<link><?php bloginfo_rss('url') ?></link>
+	<description><?php bloginfo_rss('description') ?></description>
+	<dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></dc:date>
+	<admin:generatorAgent rdf:resource="http://wordpress.org/?v=<?php echo $wp_version ?>"/>
+	<sy:updatePeriod>hourly</sy:updatePeriod>
+	<sy:updateFrequency>1</sy:updateFrequency>
+	<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
+	<?php do_action('rdf_header'); ?>
+	<items>
+		<rdf:Seq>
+		<?php while (have_posts()): the_post(); ?>
+			<rdf:li rdf:resource="<?php permalink_single_rss() ?>"/>
+		<?php endwhile; ?>
+		</rdf:Seq>
+	</items>
+</channel>
+<?php rewind_posts(); while (have_posts()): the_post(); ?>
+<item rdf:about="<?php permalink_single_rss() ?>">
+	<title><?php the_title_rss() ?></title>
+	<link><?php permalink_single_rss() ?></link>
+	 <dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', $post->post_date_gmt, false); ?></dc:date>
+	<dc:creator><?php the_author() ?></dc:creator>
+	<?php the_category_rss('rdf') ?>
+<?php if (get_option('rss_use_excerpt')) : ?>
+	<description><?php the_excerpt_rss() ?></description>
+<?php else : ?>
+	<description><?php the_content_rss('', 0, '', get_option('rss_excerpt_length'), 2) ?></description>
+	<content:encoded><![CDATA[<?php the_content('', 0, '') ?>]]></content:encoded>
+<?php endif; ?>
+	<?php do_action('rdf_item'); ?>
+</item>
+<?php endwhile;  ?>
+</rdf:RDF>
diff -ruN 2.0.5/wp-includes/feed-rss.php 2.2.2/wp-includes/feed-rss.php
--- 2.0.5/wp-includes/feed-rss.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-rss.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,31 @@
+<?php
+header('Content-type: text/xml; charset=' . get_option('blog_charset'), true);
+$more = 1;
+
+?>
+<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
+<!-- generator="wordpress/<?php echo $wp_version ?>" -->
+<rss version="0.92">
+<channel>
+	<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
+	<link><?php bloginfo_rss('url') ?></link>
+	<description><?php bloginfo_rss('description') ?></description>
+	<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
+	<docs>http://backend.userland.com/rss092</docs>
+	<language><?php echo get_option('rss_language'); ?></language>
+	<?php do_action('rss_head'); ?>
+
+<?php while (have_posts()) : the_post(); ?>
+	<item>
+		<title><?php the_title_rss() ?></title>
+<?php if (get_option('rss_use_excerpt')) { ?>
+		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
+<?php } else { // use content ?>
+		<description><?php the_content_rss('', 0, '', get_option('rss_excerpt_length')) ?></description>
+<?php } ?>
+		<link><?php permalink_single_rss() ?></link>
+		<?php do_action('rss_item'); ?>
+	</item>
+<?php endwhile; ?>
+</channel>
+</rss>
diff -ruN 2.0.5/wp-includes/feed-rss2-comments.php 2.2.2/wp-includes/feed-rss2-comments.php
--- 2.0.5/wp-includes/feed-rss2-comments.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-rss2-comments.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,55 @@
+<?php
+header('Content-type: text/xml;charset=' . get_option('blog_charset'), true);
+
+echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; 
+?>
+<!-- generator="wordpress/<?php echo $wp_version ?>" -->
+<rss version="2.0" 
+	xmlns:content="http://purl.org/rss/1.0/modules/content/">
+<channel>
+	<title><?php
+		if ( is_singular() )
+			printf(__('Comments on: %s'), get_the_title_rss());
+		elseif ( is_search() )
+			printf(__('Comments for %s searching on %s'), get_bloginfo_rss( 'name' ), attribute_escape($wp_query->query_vars['s']));
+		else
+			printf(__('Comments for %s'), get_bloginfo_rss( 'name' ) . get_wp_title_rss());
+	?></title>
+	<link><?php (is_single()) ? permalink_single_rss() : bloginfo_rss("url") ?></link>
+	<description><?php bloginfo_rss("description") ?></description>
+	<pubDate><?php echo gmdate('r'); ?></pubDate>
+	<generator>http://wordpress.org/?v=<?php echo $wp_version ?></generator>
+
+<?php 
+if ( have_comments() ) : while ( have_comments() ) : the_comment();
+	$comment_post = get_post($comment->comment_post_ID);
+	get_post_custom($comment_post->ID);
+?>
+	<item>
+		<title><?php
+			if ( !is_singular() ) {
+				$title = get_the_title($comment_post->ID);
+				$title = apply_filters('the_title', $title);
+				$title = apply_filters('the_title_rss', $title);
+				printf(__('Comment on %1$s by %2$s'), $title, get_comment_author_rss());
+			} else {
+				printf(__('By: %s'), get_comment_author_rss());
+			}
+		?></title>
+		<link><?php comment_link() ?></link>
+		<author><?php echo get_comment_author_rss() ?></author>
+		<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_comment_time('Y-m-d H:i:s', true), false); ?></pubDate>
+		<guid><?php comment_link() ?></guid>
+<?php if (!empty($comment_post->post_password) && $_COOKIE['wp-postpass'] != $comment_post->post_password) : ?>
+		<description><?php _e('Protected Comments: Please enter your password to view comments.'); ?></description>
+		<content:encoded><![CDATA[<?php echo get_the_password_form() ?>]]></content:encoded>
+<?php else : // post pass ?>
+		<description><?php comment_text_rss() ?></description>
+		<content:encoded><![CDATA[<?php comment_text() ?>]]></content:encoded>
+<?php endif; // post pass
+	do_action('commentrss2_item', $comment->comment_ID, $comment_post->ID);
+?>
+	</item>
+<?php endwhile; endif; ?>
+</channel>
+</rss>
diff -ruN 2.0.5/wp-includes/feed-rss2.php 2.2.2/wp-includes/feed-rss2.php
--- 2.0.5/wp-includes/feed-rss2.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed-rss2.php	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,50 @@
+<?php
+header('Content-type: text/xml; charset=' . get_option('blog_charset'), true);
+$more = 1;
+
+?>
+<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
+
+<!-- generator="wordpress/<?php bloginfo_rss('version') ?>" -->
+<rss version="2.0"
+	xmlns:content="http://purl.org/rss/1.0/modules/content/"
+	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+	xmlns:dc="http://purl.org/dc/elements/1.1/"
+	<?php do_action('rss2_ns'); ?>
+>
+
+<channel>
+	<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
+	<link><?php bloginfo_rss('url') ?></link>
+	<description><?php bloginfo_rss("description") ?></description>
+	<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></pubDate>
+	<generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator>
+	<language><?php echo get_option('rss_language'); ?></language>
+	<?php do_action('rss2_head'); ?>
+	<?php while( have_posts()) : the_post(); ?>
+	<item>
+		<title><?php the_title_rss() ?></title>
+		<link><?php permalink_single_rss() ?></link>
+		<comments><?php comments_link(); ?></comments>
+		<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
+		<dc:creator><?php the_author() ?></dc:creator>
+		<?php the_category_rss() ?>
+
+		<guid isPermaLink="false"><?php the_guid(); ?></guid>
+<?php if (get_option('rss_use_excerpt')) : ?>
+		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
+<?php else : ?>
+		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
+	<?php if ( strlen( $post->post_content ) > 0 ) : ?>
+		<content:encoded><![CDATA[<?php the_content() ?>]]></content:encoded>
+	<?php else : ?>
+		<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
+	<?php endif; ?>
+<?php endif; ?>
+		<wfw:commentRss><?php echo comments_rss(); ?></wfw:commentRss>
+<?php rss_enclosure(); ?>
+	<?php do_action('rss2_item'); ?>
+	</item>
+	<?php endwhile; ?>
+</channel>
+</rss>
diff -ruN 2.0.5/wp-includes/feed.php 2.2.2/wp-includes/feed.php
--- 2.0.5/wp-includes/feed.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/feed.php	2007-05-25 10:55:30.000000000 -0500
@@ -0,0 +1,210 @@
+<?php
+
+function get_bloginfo_rss($show = '') {
+	$info = strip_tags(get_bloginfo($show));
+	return apply_filters('get_bloginfo_rss', convert_chars($info));
+}
+
+
+function bloginfo_rss($show = '') {
+	echo apply_filters('bloginfo_rss', get_bloginfo_rss($show));
+}
+
+function get_wp_title_rss($sep = '&#187;') {
+	$title = wp_title($sep, false);
+	$title = apply_filters('get_wp_title_rss', $title);
+	return $title;
+}
+
+function wp_title_rss($sep = '&#187;') {
+	echo apply_filters('wp_title_rss', get_wp_title_rss($sep));
+}
+
+function get_the_title_rss() {
+	$title = get_the_title();
+	$title = apply_filters('the_title', $title);
+	$title = apply_filters('the_title_rss', $title);
+	return $title;
+}
+
+
+function the_title_rss() {
+	echo get_the_title_rss();
+}
+
+
+function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file='', $cut = 0, $encode_html = 0) {
+	$content = get_the_content($more_link_text, $stripteaser, $more_file);
+	$content = apply_filters('the_content_rss', $content);
+	if ( $cut && !$encode_html )
+		$encode_html = 2;
+	if ( 1== $encode_html ) {
+		$content = wp_specialchars($content);
+		$cut = 0;
+	} elseif ( 0 == $encode_html ) {
+		$content = make_url_footnote($content);
+	} elseif ( 2 == $encode_html ) {
+		$content = strip_tags($content);
+	}
+	if ( $cut ) {
+		$blah = explode(' ', $content);
+		if ( count($blah) > $cut ) {
+			$k = $cut;
+			$use_dotdotdot = 1;
+		} else {
+			$k = count($blah);
+			$use_dotdotdot = 0;
+		}
+		for ( $i=0; $i<$k; $i++ )
+			$excerpt .= $blah[$i].' ';
+		$excerpt .= ($use_dotdotdot) ? '...' : '';
+		$content = $excerpt;
+	}
+	$content = str_replace(']]>', ']]&gt;', $content);
+	echo $content;
+}
+
+
+function the_excerpt_rss() {
+	$output = get_the_excerpt(true);
+	echo apply_filters('the_excerpt_rss', $output);
+}
+
+
+function permalink_single_rss($file = '') {
+	echo get_permalink();
+}
+
+
+function comment_link() {
+	echo get_comment_link();
+}
+
+
+function get_comment_author_rss() {
+	return apply_filters('comment_author_rss', get_comment_author() );
+}
+
+
+function comment_author_rss() {
+	echo get_comment_author_rss();
+}
+
+
+function comment_text_rss() {
+	$comment_text = get_comment_text();
+	$comment_text = apply_filters('comment_text_rss', $comment_text);
+	echo $comment_text;
+}
+
+
+function comments_rss_link($link_text = 'Comments RSS', $commentsrssfilename = 'nolongerused') {
+	$url = get_post_comments_feed_link();
+	echo "<a href='$url'>$link_text</a>";
+}
+
+
+function comments_rss($commentsrssfilename = 'nolongerused') {
+	return get_post_comments_feed_link();
+}
+
+
+function get_author_rss_link($echo = false, $author_id, $author_nicename) {
+	$auth_ID = (int) $author_id;
+	$permalink_structure = get_option('permalink_structure');
+
+	if ( '' == $permalink_structure ) {
+		$link = get_option('home') . '?feed=rss2&amp;author=' . $author_id;
+	} else {
+		$link = get_author_posts_url($author_id, $author_nicename);
+		$link = $link . user_trailingslashit('feed', 'feed');
+	}
+
+	$link = apply_filters('author_feed_link', $link);
+
+	if ( $echo )
+		echo $link;
+	return $link;
+}
+
+
+function get_category_rss_link($echo = false, $cat_ID, $category_nicename) {
+	$permalink_structure = get_option('permalink_structure');
+
+	if ( '' == $permalink_structure ) {
+		$link = get_option('home') . '?feed=rss2&amp;cat=' . $cat_ID;
+	} else {
+		$link = get_category_link($cat_ID);
+		$link = $link . user_trailingslashit('feed', 'feed');
+	}
+
+	$link = apply_filters('category_feed_link', $link);
+
+	if ( $echo )
+		echo $link;
+	return $link;
+}
+
+
+function get_the_category_rss($type = 'rss') {
+	$categories = get_the_category();
+	$home = get_bloginfo_rss('home');
+	$the_list = '';
+	foreach ( (array) $categories as $category ) {
+		$cat_name = convert_chars($category->cat_name);
+		if ( 'rdf' == $type )
+			$the_list .= "\n\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
+		if ( 'atom' == $type )
+			$the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', attribute_escape( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), attribute_escape( $category->cat_name ) );
+		else
+			$the_list .= "\n\t\t<category><![CDATA[$cat_name]]></category>\n";
+	}
+	return apply_filters('the_category_rss', $the_list, $type);
+}
+
+
+function the_category_rss($type = 'rss') {
+	echo get_the_category_rss($type);
+}
+
+function html_type_rss() {
+	$type = get_bloginfo('html_type');
+	if (strpos($type, 'xhtml') !== false)
+		$type = 'xhtml';
+	else
+		$type = 'html';
+	echo $type;
+}
+
+
+function rss_enclosure() {
+	global $id, $post;
+	if ( !empty($post->post_password) && ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) )
+		return;
+
+	foreach (get_post_custom() as $key => $val) {
+		if ($key == 'enclosure') {
+			foreach ((array)$val as $enc) {
+				$enclosure = split("\n", $enc);
+				echo apply_filters('rss_enclosure', '<enclosure url="' . trim(htmlspecialchars($enclosure[0])) . '" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
+			}
+		}
+	}
+}
+
+function atom_enclosure() {
+	global $id, $post;
+	if ( !empty($post->post_password) && ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) )
+		return;
+
+	foreach (get_post_custom() as $key => $val) {
+		if ($key == 'enclosure') {
+			foreach ((array)$val as $enc) {
+				$enclosure = split("\n", $enc);
+				echo apply_filters('atom_enclosure', '<link href="' . trim(htmlspecialchars($enclosure[0])) . '" rel="enclosure" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
+			}
+		}
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/formatting.php 2.2.2/wp-includes/formatting.php
--- 2.0.5/wp-includes/formatting.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/formatting.php	2007-06-19 17:47:01.000000000 -0500
@@ -0,0 +1,1128 @@
+<?php
+
+function wptexturize($text) {
+	global $wp_cockneyreplace;
+	$next = true;
+	$output = '';
+	$curl = '';
+	$textarr = preg_split('/(<.*>)/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+	$stop = count($textarr);
+
+	// if a plugin has provided an autocorrect array, use it
+	if ( isset($wp_cockneyreplace) ) {
+		$cockney = array_keys($wp_cockneyreplace);
+		$cockney_replace = array_values($wp_cockneyreplace);
+	} else {
+		$cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause");
+		$cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause");
+	}
+
+	$static_characters = array_merge(array('---', ' -- ', '--', 'xn&#8211;', '...', '``', '\'s', '\'\'', ' (tm)'), $cockney); 
+	$static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', 'xn--', '&#8230;', '&#8220;', '&#8217;s', '&#8221;', ' &#8482;'), $cockneyreplace);
+
+	$dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/(\s|\A|")\'/', '/(\d+)"/', '/(\d+)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A)"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/(\d+)x(\d+)/');
+	$dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1&#8220;$2', '&#8221;$1', '&#8217;$1', '$1&#215;$2');
+
+	for ( $i = 0; $i < $stop; $i++ ) {
+ 		$curl = $textarr[$i];
+
+		if (isset($curl{0}) && '<' != $curl{0} && $next) { // If it's not a tag
+			// static strings
+			$curl = str_replace($static_characters, $static_replacements, $curl);
+			// regular expressions
+			$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
+		} elseif (strpos($curl, '<code') !== false || strpos($curl, '<pre') !== false || strpos($curl, '<kbd') !== false || strpos($curl, '<style') !== false || strpos($curl, '<script') !== false) {
+			$next = false;
+		} else {
+			$next = true;
+		}
+
+		$curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
+		$output .= $curl;
+	}
+
+  	return $output;
+}
+
+function clean_pre($text) {
+	$text = str_replace('<br />', '', $text);
+	$text = str_replace('<p>', "\n", $text);
+	$text = str_replace('</p>', '', $text);
+	return $text;
+}
+
+function wpautop($pee, $br = 1) {
+	$pee = $pee . "\n"; // just to make things a little easier, pad the end
+	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
+	// Space things out a little
+	$allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
+	$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
+	$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
+	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
+	$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
+	$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
+	$pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
+	$pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
+	$pee = preg_replace( '|<p>|', "$1<p>", $pee );
+	$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
+	$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
+	$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
+	$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
+	$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
+	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
+	if ($br) {
+		$pee = preg_replace('/<(script|style).*?<\/\\1>/se', 'str_replace("\n", "<WPPreserveNewline />", "\\0")', $pee);
+		$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
+		$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
+	}
+	$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
+	$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
+	if (strpos($pee, '<pre') !== false)
+		$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') .  stripslashes(clean_pre('$2'))  . '</pre>' ", $pee);
+	$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
+
+	return $pee;
+}
+
+
+function seems_utf8($Str) { # by bmorel at ssi dot fr
+	for ($i=0; $i<strlen($Str); $i++) {
+		if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
+		elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
+		elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
+		elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
+		elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
+		elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
+		else return false; # Does not match any model
+		for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
+			if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
+			return false;
+		}
+	}
+	return true;
+}
+
+function wp_specialchars( $text, $quotes = 0 ) {
+	// Like htmlspecialchars except don't double-encode HTML entities
+	$text = str_replace('&&', '&#038;&', $text);
+	$text = str_replace('&&', '&#038;&', $text);
+	$text = preg_replace('/&(?:$|([^#])(?![a-z1-4]{1,8};))/', '&#038;$1', $text);
+	$text = str_replace('<', '&lt;', $text);
+	$text = str_replace('>', '&gt;', $text);
+	if ( 'double' === $quotes ) {
+		$text = str_replace('"', '&quot;', $text);
+	} elseif ( 'single' === $quotes ) {
+		$text = str_replace("'", '&#039;', $text);
+	} elseif ( $quotes ) {
+		$text = str_replace('"', '&quot;', $text);
+		$text = str_replace("'", '&#039;', $text);
+	}
+	return $text;
+}
+
+function utf8_uri_encode( $utf8_string, $length = 0 ) {
+	$unicode = '';
+	$values = array();
+	$num_octets = 1;
+
+	for ($i = 0; $i < strlen( $utf8_string ); $i++ ) {
+
+		$value = ord( $utf8_string[ $i ] );
+
+		if ( $value < 128 ) {
+			if ( $length && ( strlen($unicode) + 1 > $length ) )
+				break; 
+			$unicode .= chr($value);
+		} else {
+			if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;
+
+			$values[] = $value;
+
+			if ( $length && ( (strlen($unicode) + ($num_octets * 3)) > $length ) )
+				break;
+			if ( count( $values ) == $num_octets ) {
+				if ($num_octets == 3) {
+					$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
+				} else {
+					$unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
+				}
+
+				$values = array();
+				$num_octets = 1;
+			}
+		}
+	}
+
+	return $unicode;
+}
+
+function remove_accents($string) {
+	if ( !preg_match('/[\x80-\xff]/', $string) )
+		return $string;
+
+	if (seems_utf8($string)) {
+		$chars = array(
+		// Decompositions for Latin-1 Supplement
+		chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
+		chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
+		chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
+		chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
+		chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
+		chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
+		chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
+		chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
+		chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
+		chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
+		chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
+		chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
+		chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
+		chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
+		chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
+		chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
+		chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
+		chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
+		chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
+		chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
+		chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
+		chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
+		chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
+		chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
+		chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
+		chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
+		chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
+		chr(195).chr(191) => 'y',
+		// Decompositions for Latin Extended-A
+		chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
+		chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
+		chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
+		chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
+		chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
+		chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
+		chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
+		chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
+		chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
+		chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
+		chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
+		chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
+		chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
+		chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
+		chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
+		chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
+		chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
+		chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
+		chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
+		chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
+		chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
+		chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
+		chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
+		chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
+		chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
+		chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
+		chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
+		chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
+		chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
+		chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
+		chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
+		chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
+		chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
+		chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
+		chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
+		chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
+		chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
+		chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
+		chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
+		chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
+		chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
+		chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
+		chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
+		chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
+		chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
+		chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
+		chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
+		chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
+		chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
+		chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
+		chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
+		chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
+		chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
+		chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
+		chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
+		chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
+		chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
+		chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
+		chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
+		chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
+		chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
+		chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
+		chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
+		chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
+		// Euro Sign
+		chr(226).chr(130).chr(172) => 'E',
+		// GBP (Pound) Sign
+		chr(194).chr(163) => '');
+
+		$string = strtr($string, $chars);
+	} else {
+		// Assume ISO-8859-1 if not UTF-8
+		$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
+			.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
+			.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
+			.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
+			.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
+			.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
+			.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
+			.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
+			.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
+			.chr(252).chr(253).chr(255);
+
+		$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
+
+		$string = strtr($string, $chars['in'], $chars['out']);
+		$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
+		$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
+		$string = str_replace($double_chars['in'], $double_chars['out'], $string);
+	}
+
+	return $string;
+}
+
+function sanitize_file_name( $name ) { // Like sanitize_title, but with periods
+	$name = strtolower( $name );
+	$name = preg_replace('/&.+?;/', '', $name); // kill entities
+	$name = str_replace( '_', '-', $name );
+	$name = preg_replace('/[^a-z0-9\s-.]/', '', $name);
+	$name = preg_replace('/\s+/', '-', $name);
+	$name = preg_replace('|-+|', '-', $name);
+	$name = trim($name, '-');
+	return $name;
+}
+
+function sanitize_user( $username, $strict = false ) {
+	$raw_username = $username;
+	$username = strip_tags($username);
+	// Kill octets
+	$username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
+	$username = preg_replace('/&.+?;/', '', $username); // Kill entities
+
+	// If strict, reduce to ASCII for max portability.
+	if ( $strict )
+		$username = preg_replace('|[^a-z0-9 _.\-@]|i', '', $username);
+
+	return apply_filters('sanitize_user', $username, $raw_username, $strict);
+}
+
+function sanitize_title($title, $fallback_title = '') {
+	$title = strip_tags($title);
+	$title = apply_filters('sanitize_title', $title);
+
+	if (empty($title)) {
+		$title = $fallback_title;
+	}
+
+	return $title;
+}
+
+function sanitize_title_with_dashes($title) {
+	$title = strip_tags($title);
+	// Preserve escaped octets.
+	$title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
+	// Remove percent signs that are not part of an octet.
+	$title = str_replace('%', '', $title);
+	// Restore octets.
+	$title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
+
+	$title = remove_accents($title);
+	if (seems_utf8($title)) {
+		if (function_exists('mb_strtolower')) {
+			$title = mb_strtolower($title, 'UTF-8');
+		}
+		$title = utf8_uri_encode($title, 200);
+	}
+
+	$title = strtolower($title);
+	$title = preg_replace('/&.+?;/', '', $title); // kill entities
+	$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
+	$title = preg_replace('/\s+/', '-', $title);
+	$title = preg_replace('|-+|', '-', $title);
+	$title = trim($title, '-');
+
+	return $title;
+}
+
+function convert_chars($content, $flag = 'obsolete') {
+	// Translation of invalid Unicode references range to valid range
+	$wp_htmltranswinuni = array(
+	'&#128;' => '&#8364;', // the Euro sign
+	'&#129;' => '',
+	'&#130;' => '&#8218;', // these are Windows CP1252 specific characters
+	'&#131;' => '&#402;',  // they would look weird on non-Windows browsers
+	'&#132;' => '&#8222;',
+	'&#133;' => '&#8230;',
+	'&#134;' => '&#8224;',
+	'&#135;' => '&#8225;',
+	'&#136;' => '&#710;',
+	'&#137;' => '&#8240;',
+	'&#138;' => '&#352;',
+	'&#139;' => '&#8249;',
+	'&#140;' => '&#338;',
+	'&#141;' => '',
+	'&#142;' => '&#382;',
+	'&#143;' => '',
+	'&#144;' => '',
+	'&#145;' => '&#8216;',
+	'&#146;' => '&#8217;',
+	'&#147;' => '&#8220;',
+	'&#148;' => '&#8221;',
+	'&#149;' => '&#8226;',
+	'&#150;' => '&#8211;',
+	'&#151;' => '&#8212;',
+	'&#152;' => '&#732;',
+	'&#153;' => '&#8482;',
+	'&#154;' => '&#353;',
+	'&#155;' => '&#8250;',
+	'&#156;' => '&#339;',
+	'&#157;' => '',
+	'&#158;' => '',
+	'&#159;' => '&#376;'
+	);
+
+	// Remove metadata tags
+	$content = preg_replace('/<title>(.+?)<\/title>/','',$content);
+	$content = preg_replace('/<category>(.+?)<\/category>/','',$content);
+
+	// Converts lone & characters into &#38; (a.k.a. &amp;)
+	$content = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content);
+
+	// Fix Word pasting
+	$content = strtr($content, $wp_htmltranswinuni);
+
+	// Just a little XHTML help
+	$content = str_replace('<br>', '<br />', $content);
+	$content = str_replace('<hr>', '<hr />', $content);
+
+	return $content;
+}
+
+function funky_javascript_fix($text) {
+	// Fixes for browsers' javascript bugs
+	global $is_macIE, $is_winIE;
+
+	if ( $is_winIE || $is_macIE )
+		$text =  preg_replace("/\%u([0-9A-F]{4,4})/e",  "'&#'.base_convert('\\1',16,10).';'", $text);
+
+	return $text;
+}
+
+/*
+ balanceTags
+
+ Balances Tags of string using a modified stack.
+
+ @param text      Text to be balanced
+ @param force     Forces balancing, ignoring the value of the option
+ @return          Returns balanced text
+ @author          Leonard Lin (leonard@acm.org)
+ @version         v1.1
+ @date            November 4, 2001
+ @license         GPL v2.0
+ @notes
+ @changelog
+ ---  Modified by Scott Reilly (coffee2code) 02 Aug 2004
+	1.2  ***TODO*** Make better - change loop condition to $text
+	1.1  Fixed handling of append/stack pop order of end text
+	     Added Cleaning Hooks
+	1.0  First Version
+*/
+function balanceTags($text, $force = false) {
+
+	if ( !$force && get_option('use_balanceTags') == 0 )
+		return $text;
+
+	$tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
+
+	# WP bug fix for comments - in case you REALLY meant to type '< !--'
+	$text = str_replace('< !--', '<    !--', $text);
+	# WP bug fix for LOVE <3 (and other situations with '<' before a number)
+	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
+
+	while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
+		$newtext .= $tagqueue;
+
+		$i = strpos($text,$regex[0]);
+		$l = strlen($regex[0]);
+
+		// clear the shifter
+		$tagqueue = '';
+		// Pop or Push
+		if ($regex[1][0] == "/") { // End Tag
+			$tag = strtolower(substr($regex[1],1));
+			// if too many closing tags
+			if($stacksize <= 0) {
+				$tag = '';
+				//or close to be safe $tag = '/' . $tag;
+			}
+			// if stacktop value = tag close value then pop
+			else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
+				$tag = '</' . $tag . '>'; // Close Tag
+				// Pop
+				array_pop ($tagstack);
+				$stacksize--;
+			} else { // closing tag not at top, search for it
+				for ($j=$stacksize-1;$j>=0;$j--) {
+					if ($tagstack[$j] == $tag) {
+					// add tag to tagqueue
+						for ($k=$stacksize-1;$k>=$j;$k--){
+							$tagqueue .= '</' . array_pop ($tagstack) . '>';
+							$stacksize--;
+						}
+						break;
+					}
+				}
+				$tag = '';
+			}
+		} else { // Begin Tag
+			$tag = strtolower($regex[1]);
+
+			// Tag Cleaning
+
+			// If self-closing or '', don't do anything.
+			if((substr($regex[2],-1) == '/') || ($tag == '')) {
+			}
+			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
+			elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input') {
+				$regex[2] .= '/';
+			} else {	// Push the tag onto the stack
+				// If the top of the stack is the same as the tag we want to push, close previous tag
+				if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag)) {
+					$tagqueue = '</' . array_pop ($tagstack) . '>';
+					$stacksize--;
+				}
+				$stacksize = array_push ($tagstack, $tag);
+			}
+
+			// Attributes
+			$attributes = $regex[2];
+			if($attributes) {
+				$attributes = ' '.$attributes;
+			}
+			$tag = '<'.$tag.$attributes.'>';
+			//If already queuing a close tag, then put this tag on, too
+			if ($tagqueue) {
+				$tagqueue .= $tag;
+				$tag = '';
+			}
+		}
+		$newtext .= substr($text,0,$i) . $tag;
+		$text = substr($text,$i+$l);
+	}
+
+	// Clear Tag Queue
+	$newtext .= $tagqueue;
+
+	// Add Remaining text
+	$newtext .= $text;
+
+	// Empty Stack
+	while($x = array_pop($tagstack)) {
+		$newtext .= '</' . $x . '>'; // Add remaining tags to close
+	}
+
+	// WP fix for the bug with HTML comments
+	$newtext = str_replace("< !--","<!--",$newtext);
+	$newtext = str_replace("<    !--","< !--",$newtext);
+
+	return $newtext;
+}
+
+function force_balance_tags($text) {
+	return balanceTags($text, true);
+}
+
+function format_to_edit($content, $richedit = false) {
+	$content = apply_filters('format_to_edit', $content);
+	if (! $richedit )
+		$content = htmlspecialchars($content);
+	return $content;
+}
+
+function format_to_post($content) {
+	global $wpdb;
+	$content = apply_filters('format_to_post', $content);
+	return $content;
+}
+
+function zeroise($number,$threshold) { // function to add leading zeros when necessary
+	return sprintf('%0'.$threshold.'s', $number);
+}
+
+
+function backslashit($string) {
+	$string = preg_replace('/^([0-9])/', '\\\\\\\\\1', $string);
+	$string = preg_replace('/([a-z])/i', '\\\\\1', $string);
+	return $string;
+}
+
+function trailingslashit($string) {
+	return untrailingslashit($string) . '/';
+}
+
+function untrailingslashit($string) {
+	return rtrim($string, '/');
+}
+
+function addslashes_gpc($gpc) {
+	global $wpdb;
+
+	if (get_magic_quotes_gpc()) {
+		$gpc = stripslashes($gpc);
+	}
+
+	return $wpdb->escape($gpc);
+}
+
+
+function stripslashes_deep($value) {
+	 $value = is_array($value) ?
+		 array_map('stripslashes_deep', $value) :
+		 stripslashes($value);
+
+	 return $value;
+}
+
+function urlencode_deep($value) {
+	 $value = is_array($value) ?
+		 array_map('urlencode_deep', $value) :
+		 urlencode($value);
+
+	 return $value;
+}
+
+function antispambot($emailaddy, $mailto=0) {
+	$emailNOSPAMaddy = '';
+	srand ((float) microtime() * 1000000);
+	for ($i = 0; $i < strlen($emailaddy); $i = $i + 1) {
+		$j = floor(rand(0, 1+$mailto));
+		if ($j==0) {
+			$emailNOSPAMaddy .= '&#'.ord(substr($emailaddy,$i,1)).';';
+		} elseif ($j==1) {
+			$emailNOSPAMaddy .= substr($emailaddy,$i,1);
+		} elseif ($j==2) {
+			$emailNOSPAMaddy .= '%'.zeroise(dechex(ord(substr($emailaddy, $i, 1))), 2);
+		}
+	}
+	$emailNOSPAMaddy = str_replace('@','&#64;',$emailNOSPAMaddy);
+	return $emailNOSPAMaddy;
+}
+
+function make_clickable($ret) {
+	$ret = ' ' . $ret;
+	// in testing, using arrays here was found to be faster
+	$ret = preg_replace(
+		array(
+			'#([\s>])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
+			'#([\s>])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
+			'#([\s>])([a-z0-9\-_.]+)@([^,< \n\r]+)#i'),
+		array(
+			'$1<a href="$2" rel="nofollow">$2</a>',
+			'$1<a href="http://$2" rel="nofollow">$2</a>',
+			'$1<a href="mailto:$2@$3">$2@$3</a>'),$ret);
+	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
+	$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
+	$ret = trim($ret);
+	return $ret;
+}
+
+function wp_rel_nofollow( $text ) {
+	global $wpdb;
+	// This is a pre save filter, so text is already escaped.
+	$text = stripslashes($text);
+	$text = preg_replace('|<a (.+?)>|ie', "'<a ' . str_replace(' rel=\"nofollow\"','',stripslashes('$1')) . ' rel=\"nofollow\">'", $text);
+	$text = $wpdb->escape($text);
+	return $text;
+}
+
+function convert_smilies($text) {
+	global $wp_smiliessearch, $wp_smiliesreplace;
+    $output = '';
+	if (get_option('use_smilies')) {
+		// HTML loop taken from texturize function, could possible be consolidated
+		$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
+		$stop = count($textarr);// loop stuff 
+		for ($i = 0; $i < $stop; $i++) { 
+			$content = $textarr[$i]; 
+			if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag 
+				$content = preg_replace($wp_smiliessearch, $wp_smiliesreplace, $content); 
+			} 
+			$output .= $content; 
+		}
+	} else {
+		// return default text.
+		$output = $text;
+	}
+	return $output;
+}
+
+
+function is_email($user_email) {
+	$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
+	if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) {
+		if (preg_match($chars, $user_email)) {
+			return true;
+		} else {
+			return false;
+		}
+	} else {
+		return false;
+	}
+}
+
+// used by wp-mail to handle charsets in email subjects
+function wp_iso_descrambler($string) {
+  /* this may only work with iso-8859-1, I'm afraid */
+  if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
+    return $string;
+  } else {
+    $subject = str_replace('_', ' ', $matches[2]);
+    $subject = preg_replace('#\=([0-9a-f]{2})#ei', "chr(hexdec(strtolower('$1')))", $subject);
+    return $subject;
+  }
+}
+
+
+// give it a date, it will give you the same date as GMT
+function get_gmt_from_date($string) {
+  // note: this only substracts $time_difference from the given date
+  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
+  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
+  $string_gmt = gmdate('Y-m-d H:i:s', $string_time - get_option('gmt_offset') * 3600);
+  return $string_gmt;
+}
+
+// give it a GMT date, it will give you the same date with $time_difference added
+function get_date_from_gmt($string) {
+  // note: this only adds $time_difference to the given date
+  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
+  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
+  $string_localtime = gmdate('Y-m-d H:i:s', $string_time + get_option('gmt_offset')*3600);
+  return $string_localtime;
+}
+
+// computes an offset in seconds from an iso8601 timezone
+function iso8601_timezone_to_offset($timezone) {
+  // $timezone is either 'Z' or '[+|-]hhmm'
+  if ($timezone == 'Z') {
+    $offset = 0;
+  } else {
+    $sign    = (substr($timezone, 0, 1) == '+') ? 1 : -1;
+    $hours   = intval(substr($timezone, 1, 2));
+    $minutes = intval(substr($timezone, 3, 4)) / 60;
+    $offset  = $sign * 3600 * ($hours + $minutes);
+  }
+  return $offset;
+}
+
+// converts an iso8601 date to MySQL DateTime format used by post_date[_gmt]
+function iso8601_to_datetime($date_string, $timezone = USER) {
+  if ($timezone == GMT) {
+    preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
+    if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
+      $offset = iso8601_timezone_to_offset($date_bits[7]);
+    } else { // we don't have a timezone, so we assume user local timezone (not server's!)
+      $offset = 3600 * get_option('gmt_offset');
+    }
+    $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
+    $timestamp -= $offset;
+    return gmdate('Y-m-d H:i:s', $timestamp);
+  } elseif ($timezone == USER) {
+    return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string);
+  }
+}
+
+function popuplinks($text) {
+	// Comment text in popup windows should be filtered through this.
+	// Right now it's a moderately dumb function, ideally it would detect whether
+	// a target or rel attribute was already there and adjust its actions accordingly.
+	$text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text);
+	return $text;
+}
+
+function sanitize_email($email) {
+	return preg_replace('/[^a-z0-9+_.@-]/i', '', $email);
+}
+
+function human_time_diff( $from, $to = '' ) {
+	if ( empty($to) )
+		$to = time();
+	$diff = (int) abs($to - $from);
+	if ($diff <= 3600) {
+		$mins = round($diff / 60);
+		if ($mins <= 1) {
+			$mins = 1;
+		}
+		$since = sprintf(__ngettext('%s min', '%s mins', $mins), $mins);
+	} else if (($diff <= 86400) && ($diff > 3600)) {
+		$hours = round($diff / 3600);
+		if ($hours <= 1) {
+			$hour = 1;
+		}
+		$since = sprintf(__ngettext('%s hour', '%s hours', $hours), $hours);
+	} elseif ($diff >= 86400) {
+		$days = round($diff / 86400);
+		if ($days <= 1) {
+			$days = 1;
+		}
+		$since = sprintf(__ngettext('%s day', '%s days', $days), $days);
+	}
+	return $since;
+}
+
+function wp_trim_excerpt($text) { // Fakes an excerpt if needed
+	global $post;
+	if ( '' == $text ) {
+		$text = get_the_content('');
+		$text = apply_filters('the_content', $text);
+		$text = str_replace(']]>', ']]&gt;', $text);
+		$text = strip_tags($text);
+		$excerpt_length = 55;
+		$words = explode(' ', $text, $excerpt_length + 1);
+		if (count($words) > $excerpt_length) {
+			array_pop($words);
+			array_push($words, '[...]');
+			$text = implode(' ', $words);
+		}
+	}
+	return $text;
+}
+
+function ent2ncr($text) {
+	$to_ncr = array(
+		'&quot;' => '&#34;',
+		'&amp;' => '&#38;',
+		'&frasl;' => '&#47;',
+		'&lt;' => '&#60;',
+		'&gt;' => '&#62;',
+		'|' => '&#124;',
+		'&nbsp;' => '&#160;',
+		'&iexcl;' => '&#161;',
+		'&cent;' => '&#162;',
+		'&pound;' => '&#163;',
+		'&curren;' => '&#164;',
+		'&yen;' => '&#165;',
+		'&brvbar;' => '&#166;',
+		'&brkbar;' => '&#166;',
+		'&sect;' => '&#167;',
+		'&uml;' => '&#168;',
+		'&die;' => '&#168;',
+		'&copy;' => '&#169;',
+		'&ordf;' => '&#170;',
+		'&laquo;' => '&#171;',
+		'&not;' => '&#172;',
+		'&shy;' => '&#173;',
+		'&reg;' => '&#174;',
+		'&macr;' => '&#175;',
+		'&hibar;' => '&#175;',
+		'&deg;' => '&#176;',
+		'&plusmn;' => '&#177;',
+		'&sup2;' => '&#178;',
+		'&sup3;' => '&#179;',
+		'&acute;' => '&#180;',
+		'&micro;' => '&#181;',
+		'&para;' => '&#182;',
+		'&middot;' => '&#183;',
+		'&cedil;' => '&#184;',
+		'&sup1;' => '&#185;',
+		'&ordm;' => '&#186;',
+		'&raquo;' => '&#187;',
+		'&frac14;' => '&#188;',
+		'&frac12;' => '&#189;',
+		'&frac34;' => '&#190;',
+		'&iquest;' => '&#191;',
+		'&Agrave;' => '&#192;',
+		'&Aacute;' => '&#193;',
+		'&Acirc;' => '&#194;',
+		'&Atilde;' => '&#195;',
+		'&Auml;' => '&#196;',
+		'&Aring;' => '&#197;',
+		'&AElig;' => '&#198;',
+		'&Ccedil;' => '&#199;',
+		'&Egrave;' => '&#200;',
+		'&Eacute;' => '&#201;',
+		'&Ecirc;' => '&#202;',
+		'&Euml;' => '&#203;',
+		'&Igrave;' => '&#204;',
+		'&Iacute;' => '&#205;',
+		'&Icirc;' => '&#206;',
+		'&Iuml;' => '&#207;',
+		'&ETH;' => '&#208;',
+		'&Ntilde;' => '&#209;',
+		'&Ograve;' => '&#210;',
+		'&Oacute;' => '&#211;',
+		'&Ocirc;' => '&#212;',
+		'&Otilde;' => '&#213;',
+		'&Ouml;' => '&#214;',
+		'&times;' => '&#215;',
+		'&Oslash;' => '&#216;',
+		'&Ugrave;' => '&#217;',
+		'&Uacute;' => '&#218;',
+		'&Ucirc;' => '&#219;',
+		'&Uuml;' => '&#220;',
+		'&Yacute;' => '&#221;',
+		'&THORN;' => '&#222;',
+		'&szlig;' => '&#223;',
+		'&agrave;' => '&#224;',
+		'&aacute;' => '&#225;',
+		'&acirc;' => '&#226;',
+		'&atilde;' => '&#227;',
+		'&auml;' => '&#228;',
+		'&aring;' => '&#229;',
+		'&aelig;' => '&#230;',
+		'&ccedil;' => '&#231;',
+		'&egrave;' => '&#232;',
+		'&eacute;' => '&#233;',
+		'&ecirc;' => '&#234;',
+		'&euml;' => '&#235;',
+		'&igrave;' => '&#236;',
+		'&iacute;' => '&#237;',
+		'&icirc;' => '&#238;',
+		'&iuml;' => '&#239;',
+		'&eth;' => '&#240;',
+		'&ntilde;' => '&#241;',
+		'&ograve;' => '&#242;',
+		'&oacute;' => '&#243;',
+		'&ocirc;' => '&#244;',
+		'&otilde;' => '&#245;',
+		'&ouml;' => '&#246;',
+		'&divide;' => '&#247;',
+		'&oslash;' => '&#248;',
+		'&ugrave;' => '&#249;',
+		'&uacute;' => '&#250;',
+		'&ucirc;' => '&#251;',
+		'&uuml;' => '&#252;',
+		'&yacute;' => '&#253;',
+		'&thorn;' => '&#254;',
+		'&yuml;' => '&#255;',
+		'&OElig;' => '&#338;',
+		'&oelig;' => '&#339;',
+		'&Scaron;' => '&#352;',
+		'&scaron;' => '&#353;',
+		'&Yuml;' => '&#376;',
+		'&fnof;' => '&#402;',
+		'&circ;' => '&#710;',
+		'&tilde;' => '&#732;',
+		'&Alpha;' => '&#913;',
+		'&Beta;' => '&#914;',
+		'&Gamma;' => '&#915;',
+		'&Delta;' => '&#916;',
+		'&Epsilon;' => '&#917;',
+		'&Zeta;' => '&#918;',
+		'&Eta;' => '&#919;',
+		'&Theta;' => '&#920;',
+		'&Iota;' => '&#921;',
+		'&Kappa;' => '&#922;',
+		'&Lambda;' => '&#923;',
+		'&Mu;' => '&#924;',
+		'&Nu;' => '&#925;',
+		'&Xi;' => '&#926;',
+		'&Omicron;' => '&#927;',
+		'&Pi;' => '&#928;',
+		'&Rho;' => '&#929;',
+		'&Sigma;' => '&#931;',
+		'&Tau;' => '&#932;',
+		'&Upsilon;' => '&#933;',
+		'&Phi;' => '&#934;',
+		'&Chi;' => '&#935;',
+		'&Psi;' => '&#936;',
+		'&Omega;' => '&#937;',
+		'&alpha;' => '&#945;',
+		'&beta;' => '&#946;',
+		'&gamma;' => '&#947;',
+		'&delta;' => '&#948;',
+		'&epsilon;' => '&#949;',
+		'&zeta;' => '&#950;',
+		'&eta;' => '&#951;',
+		'&theta;' => '&#952;',
+		'&iota;' => '&#953;',
+		'&kappa;' => '&#954;',
+		'&lambda;' => '&#955;',
+		'&mu;' => '&#956;',
+		'&nu;' => '&#957;',
+		'&xi;' => '&#958;',
+		'&omicron;' => '&#959;',
+		'&pi;' => '&#960;',
+		'&rho;' => '&#961;',
+		'&sigmaf;' => '&#962;',
+		'&sigma;' => '&#963;',
+		'&tau;' => '&#964;',
+		'&upsilon;' => '&#965;',
+		'&phi;' => '&#966;',
+		'&chi;' => '&#967;',
+		'&psi;' => '&#968;',
+		'&omega;' => '&#969;',
+		'&thetasym;' => '&#977;',
+		'&upsih;' => '&#978;',
+		'&piv;' => '&#982;',
+		'&ensp;' => '&#8194;',
+		'&emsp;' => '&#8195;',
+		'&thinsp;' => '&#8201;',
+		'&zwnj;' => '&#8204;',
+		'&zwj;' => '&#8205;',
+		'&lrm;' => '&#8206;',
+		'&rlm;' => '&#8207;',
+		'&ndash;' => '&#8211;',
+		'&mdash;' => '&#8212;',
+		'&lsquo;' => '&#8216;',
+		'&rsquo;' => '&#8217;',
+		'&sbquo;' => '&#8218;',
+		'&ldquo;' => '&#8220;',
+		'&rdquo;' => '&#8221;',
+		'&bdquo;' => '&#8222;',
+		'&dagger;' => '&#8224;',
+		'&Dagger;' => '&#8225;',
+		'&bull;' => '&#8226;',
+		'&hellip;' => '&#8230;',
+		'&permil;' => '&#8240;',
+		'&prime;' => '&#8242;',
+		'&Prime;' => '&#8243;',
+		'&lsaquo;' => '&#8249;',
+		'&rsaquo;' => '&#8250;',
+		'&oline;' => '&#8254;',
+		'&frasl;' => '&#8260;',
+		'&euro;' => '&#8364;',
+		'&image;' => '&#8465;',
+		'&weierp;' => '&#8472;',
+		'&real;' => '&#8476;',
+		'&trade;' => '&#8482;',
+		'&alefsym;' => '&#8501;',
+		'&crarr;' => '&#8629;',
+		'&lArr;' => '&#8656;',
+		'&uArr;' => '&#8657;',
+		'&rArr;' => '&#8658;',
+		'&dArr;' => '&#8659;',
+		'&hArr;' => '&#8660;',
+		'&forall;' => '&#8704;',
+		'&part;' => '&#8706;',
+		'&exist;' => '&#8707;',
+		'&empty;' => '&#8709;',
+		'&nabla;' => '&#8711;',
+		'&isin;' => '&#8712;',
+		'&notin;' => '&#8713;',
+		'&ni;' => '&#8715;',
+		'&prod;' => '&#8719;',
+		'&sum;' => '&#8721;',
+		'&minus;' => '&#8722;',
+		'&lowast;' => '&#8727;',
+		'&radic;' => '&#8730;',
+		'&prop;' => '&#8733;',
+		'&infin;' => '&#8734;',
+		'&ang;' => '&#8736;',
+		'&and;' => '&#8743;',
+		'&or;' => '&#8744;',
+		'&cap;' => '&#8745;',
+		'&cup;' => '&#8746;',
+		'&int;' => '&#8747;',
+		'&there4;' => '&#8756;',
+		'&sim;' => '&#8764;',
+		'&cong;' => '&#8773;',
+		'&asymp;' => '&#8776;',
+		'&ne;' => '&#8800;',
+		'&equiv;' => '&#8801;',
+		'&le;' => '&#8804;',
+		'&ge;' => '&#8805;',
+		'&sub;' => '&#8834;',
+		'&sup;' => '&#8835;',
+		'&nsub;' => '&#8836;',
+		'&sube;' => '&#8838;',
+		'&supe;' => '&#8839;',
+		'&oplus;' => '&#8853;',
+		'&otimes;' => '&#8855;',
+		'&perp;' => '&#8869;',
+		'&sdot;' => '&#8901;',
+		'&lceil;' => '&#8968;',
+		'&rceil;' => '&#8969;',
+		'&lfloor;' => '&#8970;',
+		'&rfloor;' => '&#8971;',
+		'&lang;' => '&#9001;',
+		'&rang;' => '&#9002;',
+		'&larr;' => '&#8592;',
+		'&uarr;' => '&#8593;',
+		'&rarr;' => '&#8594;',
+		'&darr;' => '&#8595;',
+		'&harr;' => '&#8596;',
+		'&loz;' => '&#9674;',
+		'&spades;' => '&#9824;',
+		'&clubs;' => '&#9827;',
+		'&hearts;' => '&#9829;',
+		'&diams;' => '&#9830;'
+	);
+
+	return str_replace( array_keys($to_ncr), array_values($to_ncr), $text );
+}
+
+function wp_richedit_pre($text) {
+	// Filtering a blank results in an annoying <br />\n
+	if ( empty($text) ) return apply_filters('richedit_pre', '');
+
+	$output = $text;
+	$output = convert_chars($output);
+	$output = wpautop($output);
+
+	// These must be double-escaped or planets will collide.
+	$output = str_replace('&lt;', '&amp;lt;', $output);
+	$output = str_replace('&gt;', '&amp;gt;', $output);
+
+	return apply_filters('richedit_pre', $output);
+}
+
+function clean_url( $url, $protocols = null ) {
+	if ('' == $url) return $url;
+	$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%]|i', '', $url);
+	$strip = array('%0d', '%0a');
+	$url = str_replace($strip, '', $url);
+	$url = str_replace(';//', '://', $url);
+	// Append http unless a relative link starting with / or a php file.
+	if ( strpos($url, '://') === false &&
+		substr( $url, 0, 1 ) != '/' && !preg_match('/^[a-z0-9-]+?\.php/i', $url) )
+		$url = 'http://' . $url;
+	
+	$url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
+	if ( !is_array($protocols) )
+		$protocols = array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'); 
+	if ( wp_kses_bad_protocol( $url, $protocols ) != $url )
+		return '';
+	return $url;
+}
+
+// Borrowed from the PHP Manual user notes. Convert entities, while
+// preserving already-encoded entities:
+function htmlentities2($myHTML) {
+	$translation_table=get_html_translation_table (HTML_ENTITIES,ENT_QUOTES);
+	$translation_table[chr(38)] = '&';
+	return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/","&amp;" , strtr($myHTML, $translation_table));
+}
+
+// Escape single quotes, specialchar double quotes, and fix line endings.
+function js_escape($text) {
+	$safe_text = wp_specialchars($text, 'double');
+	$safe_text = preg_replace('/&#(x)?0*(?(1)27|39);?/i', "'", stripslashes($safe_text));
+	$safe_text = preg_replace("/\r?\n/", "\\n", addslashes($safe_text));
+	return apply_filters('js_escape', $safe_text, $text);
+}
+
+// Escaping for HTML attributes
+function attribute_escape($text) {
+	$safe_text = wp_specialchars($text, true);
+	return apply_filters('attribute_escape', $safe_text, $text);
+}
+
+function wp_make_link_relative( $link ) {
+	return preg_replace('|https?://[^/]+(/.*)|i', '$1', $link );
+}
+
+function wp_parse_str( $string, &$array ) {
+	parse_str( $string, $array );
+	if ( get_magic_quotes_gpc() )
+		$array = stripslashes_deep( $array ); // parse_str() adds slashes if magicquotes is on.  See: http://php.net/parse_str
+	$array = apply_filters( 'wp_parse_str', $array );
+}
+
+?>
diff -ruN 2.0.5/wp-includes/functions-compat.php 2.2.2/wp-includes/functions-compat.php
--- 2.0.5/wp-includes/functions-compat.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/functions-compat.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,113 +0,0 @@
-<?php
-
-/* Functions missing from older PHP versions */
-
-
-/* Added in PHP 4.2.0 */
-
-if (!function_exists('floatval')) {
-	function floatval($string) {
-		return ((float) $string);
-	}
-}
-
-if (!function_exists('is_a')) {
-	function is_a($object, $class) {
-		// by Aidan Lister <aidan@php.net>
-		if (get_class($object) == strtolower($class)) {
-			return true;
-		} else {
-			return is_subclass_of($object, $class);
-		}
-	}
-}
-
-if (!function_exists('ob_clean')) {
-	function ob_clean() {
-		// by Aidan Lister <aidan@php.net>
-		if (@ob_end_clean()) {
-			return ob_start();
-		}
-		return false;
-	}
-}
-
-
-/* Added in PHP 4.3.0 */
-
-function printr($var, $do_not_echo = false) {
-	// from php.net/print_r user contributed notes 
-	ob_start();
-	print_r($var);
-	$code =  htmlentities(ob_get_contents());
-	ob_clean();
-	if (!$do_not_echo) {
-	  echo "<pre>$code</pre>";
-	}
-	return $code;
-}
-
-/* compatibility with PHP versions older than 4.3 */
-if ( !function_exists('file_get_contents') ) {
-	function file_get_contents( $file ) {
-		$file = file($file);
-		return !$file ? false : implode('', $file);
-	}
-}
-
-if (!defined('CASE_LOWER')) {
-    define('CASE_LOWER', 0);
-}
-
-if (!defined('CASE_UPPER')) {
-    define('CASE_UPPER', 1);
-}
-
-
-/**
- * Replace array_change_key_case()
- *
- * @category    PHP
- * @package     PHP_Compat
- * @link        http://php.net/function.array_change_key_case
- * @author      Stephan Schmidt <schst@php.net>
- * @author      Aidan Lister <aidan@php.net>
- * @version     $Revision: 3771 $
- * @since       PHP 4.2.0
- * @require     PHP 4.0.0 (user_error)
- */
-if (!function_exists('array_change_key_case')) {
-    function array_change_key_case($input, $case = CASE_LOWER)
-    {
-        if (!is_array($input)) {
-            user_error('array_change_key_case(): The argument should be an array',
-                E_USER_WARNING);
-            return false;
-        }
-
-        $output   = array ();
-        $keys     = array_keys($input);
-        $casefunc = ($case == CASE_LOWER) ? 'strtolower' : 'strtoupper';
-
-        foreach ($keys as $key) {
-            $output[$casefunc($key)] = $input[$key];
-        }
-
-        return $output;
-    }
-}
-
-// From php.net
-if(!function_exists('http_build_query')) {
-   function http_build_query( $formdata, $numeric_prefix = null, $key = null ) {
-       $res = array();
-       foreach ((array)$formdata as $k=>$v) {
-           $tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
-           if ($key) $tmp_key = $key.'['.$tmp_key.']';
-           $res[] = ( ( is_array($v) || is_object($v) ) ? http_build_query($v, null, $tmp_key) : $tmp_key."=".urlencode($v) );
-       }
-       $separator = ini_get('arg_separator.output');
-       return implode($separator, $res);
-   }
-}
-?>
diff -ruN 2.0.5/wp-includes/functions-formatting.php 2.2.2/wp-includes/functions-formatting.php
--- 2.0.5/wp-includes/functions-formatting.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/functions-formatting.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,1053 +0,0 @@
-<?php
-
-function wptexturize($text) {
-	global $wp_cockneyreplace;
-	$output = '';
-	// Capture tags and everything inside them
-	$textarr = preg_split("/(<.*>)/Us", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
-	$stop = count($textarr); $next = true; // loop stuff
-	for ($i = 0; $i < $stop; $i++) {
-		$curl = $textarr[$i];
-
-		if (isset($curl{0}) && '<' != $curl{0} && $next) { // If it's not a tag
-			$curl = str_replace('---', '&#8212;', $curl);
-			$curl = str_replace(' -- ', ' &#8212; ', $curl);
-			$curl = str_replace('--', '&#8211;', $curl);
-			$curl = str_replace('xn&#8211;', 'xn--', $curl);
-			$curl = str_replace('...', '&#8230;', $curl);
-			$curl = str_replace('``', '&#8220;', $curl);
-
-			// if a plugin has provided an autocorrect array, use it
-			if ( isset($wp_cockneyreplace) ) {
-				$cockney = array_keys($wp_cockneyreplace);
-				$cockney_replace = array_values($wp_cockneyreplace);
-			} else {
-				$cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause");
-				$cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause");
-			}
-
-			$curl = str_replace($cockney, $cockneyreplace, $curl);
-
-			$curl = preg_replace("/'s/", '&#8217;s', $curl);
-			$curl = preg_replace("/'(\d\d(?:&#8217;|')?s)/", "&#8217;$1", $curl);
-			$curl = preg_replace('/(\s|\A|")\'/', '$1&#8216;', $curl);
-			$curl = preg_replace('/(\d+)"/', '$1&#8243;', $curl);
-			$curl = preg_replace("/(\d+)'/", '$1&#8242;', $curl);
-			$curl = preg_replace("/(\S)'([^'\s])/", "$1&#8217;$2", $curl);
-			$curl = preg_replace('/(\s|\A)"(?!\s)/', '$1&#8220;$2', $curl);
-			$curl = preg_replace('/"(\s|\S|\Z)/', '&#8221;$1', $curl);
-			$curl = preg_replace("/'([\s.]|\Z)/", '&#8217;$1', $curl);
-			$curl = preg_replace("/ \(tm\)/i", ' &#8482;', $curl);
-			$curl = str_replace("''", '&#8221;', $curl);
-			
-			$curl = preg_replace('/(\d+)x(\d+)/', "$1&#215;$2", $curl);
-
-		} elseif (strstr($curl, '<code') || strstr($curl, '<pre') || strstr($curl, '<kbd' || strstr($curl, '<style') || strstr($curl, '<script'))) {
-			// strstr is fast
-			$next = false;
-		} else {
-			$next = true;
-		}
-		$curl = preg_replace('/&([^#])(?![a-zA-Z1-4]{1,8};)/', '&#038;$1', $curl);
-		$output .= $curl;
-	}
-	return $output;
-}
-
-function clean_pre($text) {
-	$text = str_replace('<br />', '', $text);
-	$text = str_replace('<p>', "\n", $text);
-	$text = str_replace('</p>', '', $text);
-	return $text;
-}
-
-function wpautop($pee, $br = 1) {
-	$pee = $pee . "\n"; // just to make things a little easier, pad the end
-	$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
-	// Space things out a little
-	$pee = preg_replace('!(<(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "\n$1", $pee); 
-	$pee = preg_replace('!(</(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])>)!', "$1\n\n", $pee);
-	$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines 
-	$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
-	$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end 
-	$pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace 
-	$pee = preg_replace('!<p>\s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
-	$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
-	$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
-	$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
-	$pee = preg_replace('!<p>\s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "$1", $pee);
-	$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\s*</p>!', "$1", $pee); 
-	if ($br) $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
-	$pee = preg_replace('!(</?(?:table|thead|tfoot|caption|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\s*<br />!', "$1", $pee);
-	$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
-	$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') .  stripslashes(clean_pre('$2'))  . '</pre>' ", $pee);
-	
-	return $pee; 
-}
-
-
-function seems_utf8($Str) { # by bmorel at ssi dot fr
-	for ($i=0; $i<strlen($Str); $i++) {
-		if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
-		elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
-		elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
-		elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
-		elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
-		elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
-		else return false; # Does not match any model
-		for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
-			if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
-			return false;
-		}
-	}
-	return true;
-}
-
-function wp_specialchars( $text, $quotes = 0 ) {
-	// Like htmlspecialchars except don't double-encode HTML entities
-	$text = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/', '&#038;$1', $text);
-	$text = str_replace('<', '&lt;', $text);
-	$text = str_replace('>', '&gt;', $text);
-	if ( 'double' === $quotes ) {
-		$text = str_replace('"', '&quot;', $text);
-	} elseif ( 'single' === $quotes ) {
-		$text = str_replace("'", '&#039;', $text);
-	} elseif ( $quotes ) {
-		$text = str_replace('"', '&quot;', $text);
-		$text = str_replace("'", '&#039;', $text);
-	}
-	return $text;
-}
-
-function utf8_uri_encode( $utf8_string ) {
-  $unicode = '';        
-  $values = array();
-  $num_octets = 1;
-        
-  for ($i = 0; $i < strlen( $utf8_string ); $i++ ) {
-
-    $value = ord( $utf8_string[ $i ] );
-            
-    if ( $value < 128 ) {
-      $unicode .= chr($value);
-    } else {
-      if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3;
-                
-      $values[] = $value;
-      
-      if ( count( $values ) == $num_octets ) {
-	if ($num_octets == 3) {
-	  $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]);
-	} else {
-	  $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]);
-	}
-
-	$values = array();
-	$num_octets = 1;
-      }
-    }
-  }
-
-  return $unicode;    
-}
-
-function remove_accents($string) {
-	if ( !preg_match('/[\x80-\xff]/', $string) )
-		return $string;
-
-	if (seems_utf8($string)) {
-		$chars = array(
-		// Decompositions for Latin-1 Supplement
-		chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
-		chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
-		chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
-		chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
-		chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
-		chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
-		chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
-		chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
-		chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
-		chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
-		chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
-		chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
-		chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
-		chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
-		chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
-		chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
-		chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
-		chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
-		chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
-		chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
-		chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
-		chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
-		chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
-		chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
-		chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
-		chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
-		chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
-		chr(195).chr(191) => 'y',
-		// Decompositions for Latin Extended-A
-		chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
-		chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
-		chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
-		chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
-		chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
-		chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
-		chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
-		chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
-		chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
-		chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
-		chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
-		chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
-		chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
-		chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
-		chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
-		chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
-		chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
-		chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
-		chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
-		chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
-		chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
-		chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
-		chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
-		chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
-		chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
-		chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
-		chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
-		chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
-		chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
-		chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
-		chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
-		chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
-		chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
-		chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
-		chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
-		chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
-		chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
-		chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
-		chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
-		chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
-		chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
-		chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
-		chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
-		chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
-		chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
-		chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
-		chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
-		chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
-		chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
-		chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
-		chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
-		chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
-		chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
-		chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
-		chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
-		chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
-		chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
-		chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
-		chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
-		chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
-		chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
-		chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
-		chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
-		chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
-		// Euro Sign
-		chr(226).chr(130).chr(172) => 'E',
-		// GBP (Pound) Sign
-		chr(194).chr(163) => '');
-
-		$string = strtr($string, $chars);
-	} else {
-		// Assume ISO-8859-1 if not UTF-8
-		$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
-			.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
-			.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
-			.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
-			.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
-			.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
-			.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
-			.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
-			.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
-			.chr(252).chr(253).chr(255);
-
-		$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
-
-		$string = strtr($string, $chars['in'], $chars['out']);
-		$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
-		$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
-		$string = str_replace($double_chars['in'], $double_chars['out'], $string);
-	}
-
-	return $string;
-}
-
-function sanitize_user( $username, $strict = false ) {
-	$raw_username = $username;
-	$username = strip_tags($username);
-	// Kill octets
-	$username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '', $username);
-	$username = preg_replace('/&.+?;/', '', $username); // Kill entities
-
-	// If strict, reduce to ASCII for max portability.
-	if ( $strict )
-		$username = preg_replace('|[^a-z0-9 _.\-@]|i', '', $username);
-
-	return apply_filters('sanitize_user', $username, $raw_username, $strict);
-}
-
-function sanitize_title($title, $fallback_title = '') {
-	$title = strip_tags($title);
-	$title = apply_filters('sanitize_title', $title);
-
-	if (empty($title)) {
-		$title = $fallback_title;
-	}
-
-	return $title;
-}
-
-function sanitize_title_with_dashes($title) {
-	$title = strip_tags($title);
-	// Preserve escaped octets.
-	$title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title);
-	// Remove percent signs that are not part of an octet.
-	$title = str_replace('%', '', $title);
-	// Restore octets.
-	$title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title);
-
-	$title = remove_accents($title);
-	if (seems_utf8($title)) {
-		if (function_exists('mb_strtolower')) {
-			$title = mb_strtolower($title, 'UTF-8');
-		}
-		$title = utf8_uri_encode($title);
-	}
-
-	$title = strtolower($title);
-	$title = preg_replace('/&.+?;/', '', $title); // kill entities
-	$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
-	$title = preg_replace('/\s+/', '-', $title);
-	$title = preg_replace('|-+|', '-', $title);
-	$title = trim($title, '-');
-
-	return $title;
-}
-
-function convert_chars($content, $flag = 'obsolete') { 
-	// Translation of invalid Unicode references range to valid range
-	$wp_htmltranswinuni = array(
-	'&#128;' => '&#8364;', // the Euro sign
-	'&#129;' => '',
-	'&#130;' => '&#8218;', // these are Windows CP1252 specific characters
-	'&#131;' => '&#402;',  // they would look weird on non-Windows browsers
-	'&#132;' => '&#8222;',
-	'&#133;' => '&#8230;',
-	'&#134;' => '&#8224;',
-	'&#135;' => '&#8225;',
-	'&#136;' => '&#710;',
-	'&#137;' => '&#8240;',
-	'&#138;' => '&#352;',
-	'&#139;' => '&#8249;',
-	'&#140;' => '&#338;',
-	'&#141;' => '',
-	'&#142;' => '&#382;',
-	'&#143;' => '',
-	'&#144;' => '',
-	'&#145;' => '&#8216;',
-	'&#146;' => '&#8217;',
-	'&#147;' => '&#8220;',
-	'&#148;' => '&#8221;',
-	'&#149;' => '&#8226;',
-	'&#150;' => '&#8211;',
-	'&#151;' => '&#8212;',
-	'&#152;' => '&#732;',
-	'&#153;' => '&#8482;',
-	'&#154;' => '&#353;',
-	'&#155;' => '&#8250;',
-	'&#156;' => '&#339;',
-	'&#157;' => '',
-	'&#158;' => '',
-	'&#159;' => '&#376;'
-	);
-
-	// Remove metadata tags
-	$content = preg_replace('/<title>(.+?)<\/title>/','',$content);
-	$content = preg_replace('/<category>(.+?)<\/category>/','',$content);
-
-	// Converts lone & characters into &#38; (a.k.a. &amp;)
-	$content = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content);
-
-	// Fix Word pasting
-	$content = strtr($content, $wp_htmltranswinuni);
-
-	// Just a little XHTML help
-	$content = str_replace('<br>', '<br />', $content);
-	$content = str_replace('<hr>', '<hr />', $content);
-
-	return $content;
-}
-
-function funky_javascript_fix($text) {
-	// Fixes for browsers' javascript bugs
-	global $is_macIE, $is_winIE;
-	
-	if ( $is_winIE || $is_macIE )
-		$text =  preg_replace("/\%u([0-9A-F]{4,4})/e",  "'&#'.base_convert('\\1',16,10).';'", $text);
-	
-	return $text;
-}
-
-/*
- balanceTags
- 
- Balances Tags of string using a modified stack.
- 
- @param text      Text to be balanced
- @return          Returns balanced text
- @author          Leonard Lin (leonard@acm.org)
- @version         v1.1
- @date            November 4, 2001
- @license         GPL v2.0
- @notes           
- @changelog       
- ---  Modified by Scott Reilly (coffee2code) 02 Aug 2004
-             1.2  ***TODO*** Make better - change loop condition to $text
-             1.1  Fixed handling of append/stack pop order of end text
-                  Added Cleaning Hooks
-             1.0  First Version
-*/
-function balanceTags($text, $is_comment = 0) {
-	
-	if ( get_option('use_balanceTags') == 0)
-		return $text;
-
-	$tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
-
-	# WP bug fix for comments - in case you REALLY meant to type '< !--'
-	$text = str_replace('< !--', '<    !--', $text);
-	# WP bug fix for LOVE <3 (and other situations with '<' before a number)
-	$text = preg_replace('#<([0-9]{1})#', '&lt;$1', $text);
-
-	while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
-		$newtext .= $tagqueue;
-
-		$i = strpos($text,$regex[0]);
-		$l = strlen($regex[0]);
-
-		// clear the shifter
-		$tagqueue = '';
-		// Pop or Push
-		if ($regex[1][0] == "/") { // End Tag
-			$tag = strtolower(substr($regex[1],1));
-			// if too many closing tags
-			if($stacksize <= 0) { 
-				$tag = '';
-				//or close to be safe $tag = '/' . $tag;
-			}
-			// if stacktop value = tag close value then pop
-			else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
-				$tag = '</' . $tag . '>'; // Close Tag
-				// Pop
-				array_pop ($tagstack);
-				$stacksize--;
-			} else { // closing tag not at top, search for it
-				for ($j=$stacksize-1;$j>=0;$j--) {
-					if ($tagstack[$j] == $tag) {
-					// add tag to tagqueue
-						for ($k=$stacksize-1;$k>=$j;$k--){
-							$tagqueue .= '</' . array_pop ($tagstack) . '>';
-							$stacksize--;
-						}
-						break;
-					}
-				}
-				$tag = '';
-			}
-		} else { // Begin Tag
-			$tag = strtolower($regex[1]);
-
-			// Tag Cleaning
-
-			// If self-closing or '', don't do anything.
-			if((substr($regex[2],-1) == '/') || ($tag == '')) {
-			}
-			// ElseIf it's a known single-entity tag but it doesn't close itself, do so
-			elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input') {
-				$regex[2] .= '/';
-			} else {	// Push the tag onto the stack
-				// If the top of the stack is the same as the tag we want to push, close previous tag
-				if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag)) {
-					$tagqueue = '</' . array_pop ($tagstack) . '>';
-					$stacksize--;
-				}
-				$stacksize = array_push ($tagstack, $tag);
-			}
-
-			// Attributes
-			$attributes = $regex[2];
-			if($attributes) {
-				$attributes = ' '.$attributes;
-			}
-			$tag = '<'.$tag.$attributes.'>';
-			//If already queuing a close tag, then put this tag on, too
-			if ($tagqueue) {
-				$tagqueue .= $tag;
-				$tag = '';
-			}
-		}
-		$newtext .= substr($text,0,$i) . $tag;
-		$text = substr($text,$i+$l);
-	}  
-
-	// Clear Tag Queue
-	$newtext .= $tagqueue;
-
-	// Add Remaining text
-	$newtext .= $text;
-
-	// Empty Stack
-	while($x = array_pop($tagstack)) {
-		$newtext .= '</' . $x . '>'; // Add remaining tags to close
-	}
-
-	// WP fix for the bug with HTML comments
-	$newtext = str_replace("< !--","<!--",$newtext);
-	$newtext = str_replace("<    !--","< !--",$newtext);
-
-	return $newtext;
-}
-
-function force_balance_tags($text) {
-	return balanceTags($text, 0, true);
-}
-
-function format_to_edit($content, $richedit = false) {
-	$content = apply_filters('format_to_edit', $content);
-	if (! $richedit )
-		$content = htmlspecialchars($content);
-	return $content;
-}
-
-function format_to_post($content) {
-	global $wpdb;
-	$content = apply_filters('format_to_post', $content);
-	return $content;
-}
-
-function zeroise($number,$threshold) { // function to add leading zeros when necessary
-	return sprintf('%0'.$threshold.'s', $number);
-}
-
-
-function backslashit($string) {
-	$string = preg_replace('/^([0-9])/', '\\\\\\\\\1', $string);
-	$string = preg_replace('/([a-z])/i', '\\\\\1', $string);
-	return $string;
-}
-
-function trailingslashit($string) {
-    if ( '/' != substr($string, -1)) {
-        $string .= '/';
-    }
-    return $string;
-}
-
-function addslashes_gpc($gpc) {
-	global $wpdb;
-
-	if (get_magic_quotes_gpc()) {
-		$gpc = stripslashes($gpc);
-	}
-
-	return $wpdb->escape($gpc);
-}
-
-
-function stripslashes_deep($value)
-{
-   $value = is_array($value) ?
-               array_map('stripslashes_deep', $value) :
-               stripslashes($value);
-
-   return $value;
-}
-
-function antispambot($emailaddy, $mailto=0) {
-	$emailNOSPAMaddy = '';
-	srand ((float) microtime() * 1000000);
-	for ($i = 0; $i < strlen($emailaddy); $i = $i + 1) {
-		$j = floor(rand(0, 1+$mailto));
-		if ($j==0) {
-			$emailNOSPAMaddy .= '&#'.ord(substr($emailaddy,$i,1)).';';
-		} elseif ($j==1) {
-			$emailNOSPAMaddy .= substr($emailaddy,$i,1);
-		} elseif ($j==2) {
-			$emailNOSPAMaddy .= '%'.zeroise(dechex(ord(substr($emailaddy, $i, 1))), 2);
-		}
-	}
-	$emailNOSPAMaddy = str_replace('@','&#64;',$emailNOSPAMaddy);
-	return $emailNOSPAMaddy;
-}
-
-function make_clickable($ret) {
-	$ret = ' ' . $ret;
-	// in testing, using arrays here was found to be faster
-	$ret = preg_replace(
-		array(
-			'#([\s>])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
-			'#([\s>])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is',
-			'#([\s>])([a-z0-9\-_.]+)@([^,< \n\r]+)#i'),
-		array(
-			'$1<a href="$2" rel="nofollow">$2</a>',
-			'$1<a href="http://$2" rel="nofollow">$2</a>',
-			'$1<a href="mailto:$2@$3">$2@$3</a>'),$ret);
-	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
-	$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
-	$ret = trim($ret);
-	return $ret;
-}
-
-function wp_rel_nofollow( $text ) {
-	$text = preg_replace('|<a (.+?)>|ie', "'<a ' . str_replace(' rel=\"nofollow\"','',stripslashes('$1')) . ' rel=\"nofollow\">'", $text);
-	return $text;
-}
-
-function convert_smilies($text) {
-	global $wp_smiliessearch, $wp_smiliesreplace;
-    $output = '';
-	if (get_settings('use_smilies')) {
-		// HTML loop taken from texturize function, could possible be consolidated
-		$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between
-		$stop = count($textarr);// loop stuff
-		for ($i = 0; $i < $stop; $i++) {
-			$content = $textarr[$i];
-			if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag
-				$content = str_replace($wp_smiliessearch, $wp_smiliesreplace, $content);
-			}
-			$output .= $content;
-		}
-	} else {
-		// return default text.
-		$output = $text;
-	}
-	return $output;
-}
-
-
-function is_email($user_email) {
-	$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
-	if(strstr($user_email, '@') && strstr($user_email, '.')) {
-		if (preg_match($chars, $user_email)) {
-			return true;
-		} else {
-			return false;
-		}
-	} else {
-		return false;
-	}
-}
-
-// used by wp-mail to handle charsets in email subjects
-function wp_iso_descrambler($string) {
-  /* this may only work with iso-8859-1, I'm afraid */
-  if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) {
-    return $string;
-  } else {
-    $subject = str_replace('_', ' ', $matches[2]);
-    $subject = preg_replace('#\=([0-9a-f]{2})#ei', "chr(hexdec(strtolower('$1')))", $subject);
-    return $subject;
-  }
-}
-
-
-// give it a date, it will give you the same date as GMT
-function get_gmt_from_date($string) {
-  // note: this only substracts $time_difference from the given date
-  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
-  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
-  $string_gmt = gmdate('Y-m-d H:i:s', $string_time - get_settings('gmt_offset') * 3600);
-  return $string_gmt;
-}
-
-// give it a GMT date, it will give you the same date with $time_difference added
-function get_date_from_gmt($string) {
-  // note: this only adds $time_difference to the given date
-  preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
-  $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
-  $string_localtime = gmdate('Y-m-d H:i:s', $string_time + get_settings('gmt_offset')*3600);
-  return $string_localtime;
-}
-
-// computes an offset in seconds from an iso8601 timezone
-function iso8601_timezone_to_offset($timezone) {
-  // $timezone is either 'Z' or '[+|-]hhmm'
-  if ($timezone == 'Z') {
-    $offset = 0;
-  } else {
-    $sign    = (substr($timezone, 0, 1) == '+') ? 1 : -1;
-    $hours   = intval(substr($timezone, 1, 2));
-    $minutes = intval(substr($timezone, 3, 4)) / 60;
-    $offset  = $sign * 3600 * ($hours + $minutes);
-  }
-  return $offset;
-}
-
-// converts an iso8601 date to MySQL DateTime format used by post_date[_gmt]
-function iso8601_to_datetime($date_string, $timezone = USER) {
-  if ($timezone == GMT) {
-    preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits);
-    if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset
-      $offset = iso8601_timezone_to_offset($date_bits[7]);
-    } else { // we don't have a timezone, so we assume user local timezone (not server's!)
-      $offset = 3600 * get_settings('gmt_offset');
-    }
-    $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]);
-    $timestamp -= $offset;
-    return gmdate('Y-m-d H:i:s', $timestamp);
-  } elseif ($timezone == USER) {
-    return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string);
-  }
-}
-
-function popuplinks($text) {
-	// Comment text in popup windows should be filtered through this.
-	// Right now it's a moderately dumb function, ideally it would detect whether
-	// a target or rel attribute was already there and adjust its actions accordingly.
-	$text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text);
-	return $text;
-}
-
-function sanitize_email($email) {
-	return preg_replace('/[^a-z0-9+_.@-]/i', '', $email);
-}
-
-function human_time_diff( $from, $to = '' ) {     
-	if ( empty($to) )
-		$to = time();
-	$diff = (int) abs($to - $from);
-	if ($diff <= 3600) {
-		$mins = round($diff / 60);
-		if ($mins <= 1)
-			$since = __('1 min');
-		else
-			$since = sprintf( __('%s mins'), $mins);
-	} else if (($diff <= 86400) && ($diff > 3600)) {
-		$hours = round($diff / 3600);
-		if ($hours <= 1)
-			$since = __('1 hour');
-		else 
-			$since = sprintf( __('%s hours'), $hours );
-	} elseif ($diff >= 86400) {
-		$days = round($diff / 86400);
-		if ($days <= 1)
-			$since = __('1 day');
-		else
-			$since = sprintf( __('%s days'), $days );
-	}
-	return $since;
-}
-
-function wp_trim_excerpt($text) { // Fakes an excerpt if needed
-	global $post;
-	if ( '' == $text ) {
-		$text = $post->post_content;
-		$text = apply_filters('the_content', $text);
-		$text = str_replace(']]>', ']]&gt;', $text);
-		$text = strip_tags($text);
-		$excerpt_length = 55;
-		$words = explode(' ', $text, $excerpt_length + 1);
-		if (count($words) > $excerpt_length) {
-			array_pop($words);
-			array_push($words, '[...]');
-			$text = implode(' ', $words);
-		}
-	}
-	return $text;
-}
-
-function ent2ncr($text) {
-	$to_ncr = array(
-		'&quot;' => '&#34;',
-		'&amp;' => '&#38;',
-		'&frasl;' => '&#47;',
-		'&lt;' => '&#60;',
-		'&gt;' => '&#62;',
-		'|' => '&#124;',
-		'&nbsp;' => '&#160;',
-		'&iexcl;' => '&#161;',
-		'&cent;' => '&#162;',
-		'&pound;' => '&#163;',
-		'&curren;' => '&#164;',
-		'&yen;' => '&#165;',
-		'&brvbar;' => '&#166;',
-		'&brkbar;' => '&#166;',
-		'&sect;' => '&#167;',
-		'&uml;' => '&#168;',
-		'&die;' => '&#168;',
-		'&copy;' => '&#169;',
-		'&ordf;' => '&#170;',
-		'&laquo;' => '&#171;',
-		'&not;' => '&#172;',
-		'&shy;' => '&#173;',
-		'&reg;' => '&#174;',
-		'&macr;' => '&#175;',
-		'&hibar;' => '&#175;',
-		'&deg;' => '&#176;',
-		'&plusmn;' => '&#177;',
-		'&sup2;' => '&#178;',
-		'&sup3;' => '&#179;',
-		'&acute;' => '&#180;',
-		'&micro;' => '&#181;',
-		'&para;' => '&#182;',
-		'&middot;' => '&#183;',
-		'&cedil;' => '&#184;',
-		'&sup1;' => '&#185;',
-		'&ordm;' => '&#186;',
-		'&raquo;' => '&#187;',
-		'&frac14;' => '&#188;',
-		'&frac12;' => '&#189;',
-		'&frac34;' => '&#190;',
-		'&iquest;' => '&#191;',
-		'&Agrave;' => '&#192;',
-		'&Aacute;' => '&#193;',
-		'&Acirc;' => '&#194;',
-		'&Atilde;' => '&#195;',
-		'&Auml;' => '&#196;',
-		'&Aring;' => '&#197;',
-		'&AElig;' => '&#198;',
-		'&Ccedil;' => '&#199;',
-		'&Egrave;' => '&#200;',
-		'&Eacute;' => '&#201;',
-		'&Ecirc;' => '&#202;',
-		'&Euml;' => '&#203;',
-		'&Igrave;' => '&#204;',
-		'&Iacute;' => '&#205;',
-		'&Icirc;' => '&#206;',
-		'&Iuml;' => '&#207;',
-		'&ETH;' => '&#208;',
-		'&Ntilde;' => '&#209;',
-		'&Ograve;' => '&#210;',
-		'&Oacute;' => '&#211;',
-		'&Ocirc;' => '&#212;',
-		'&Otilde;' => '&#213;',
-		'&Ouml;' => '&#214;',
-		'&times;' => '&#215;',
-		'&Oslash;' => '&#216;',
-		'&Ugrave;' => '&#217;',
-		'&Uacute;' => '&#218;',
-		'&Ucirc;' => '&#219;',
-		'&Uuml;' => '&#220;',
-		'&Yacute;' => '&#221;',
-		'&THORN;' => '&#222;',
-		'&szlig;' => '&#223;',
-		'&agrave;' => '&#224;',
-		'&aacute;' => '&#225;',
-		'&acirc;' => '&#226;',
-		'&atilde;' => '&#227;',
-		'&auml;' => '&#228;',
-		'&aring;' => '&#229;',
-		'&aelig;' => '&#230;',
-		'&ccedil;' => '&#231;',
-		'&egrave;' => '&#232;',
-		'&eacute;' => '&#233;',
-		'&ecirc;' => '&#234;',
-		'&euml;' => '&#235;',
-		'&igrave;' => '&#236;',
-		'&iacute;' => '&#237;',
-		'&icirc;' => '&#238;',
-		'&iuml;' => '&#239;',
-		'&eth;' => '&#240;',
-		'&ntilde;' => '&#241;',
-		'&ograve;' => '&#242;',
-		'&oacute;' => '&#243;',
-		'&ocirc;' => '&#244;',
-		'&otilde;' => '&#245;',
-		'&ouml;' => '&#246;',
-		'&divide;' => '&#247;',
-		'&oslash;' => '&#248;',
-		'&ugrave;' => '&#249;',
-		'&uacute;' => '&#250;',
-		'&ucirc;' => '&#251;',
-		'&uuml;' => '&#252;',
-		'&yacute;' => '&#253;',
-		'&thorn;' => '&#254;',
-		'&yuml;' => '&#255;',
-		'&OElig;' => '&#338;',
-		'&oelig;' => '&#339;',
-		'&Scaron;' => '&#352;',
-		'&scaron;' => '&#353;',
-		'&Yuml;' => '&#376;',
-		'&fnof;' => '&#402;',
-		'&circ;' => '&#710;',
-		'&tilde;' => '&#732;',
-		'&Alpha;' => '&#913;',
-		'&Beta;' => '&#914;',
-		'&Gamma;' => '&#915;',
-		'&Delta;' => '&#916;',
-		'&Epsilon;' => '&#917;',
-		'&Zeta;' => '&#918;',
-		'&Eta;' => '&#919;',
-		'&Theta;' => '&#920;',
-		'&Iota;' => '&#921;',
-		'&Kappa;' => '&#922;',
-		'&Lambda;' => '&#923;',
-		'&Mu;' => '&#924;',
-		'&Nu;' => '&#925;',
-		'&Xi;' => '&#926;',
-		'&Omicron;' => '&#927;',
-		'&Pi;' => '&#928;',
-		'&Rho;' => '&#929;',
-		'&Sigma;' => '&#931;',
-		'&Tau;' => '&#932;',
-		'&Upsilon;' => '&#933;',
-		'&Phi;' => '&#934;',
-		'&Chi;' => '&#935;',
-		'&Psi;' => '&#936;',
-		'&Omega;' => '&#937;',
-		'&alpha;' => '&#945;',
-		'&beta;' => '&#946;',
-		'&gamma;' => '&#947;',
-		'&delta;' => '&#948;',
-		'&epsilon;' => '&#949;',
-		'&zeta;' => '&#950;',
-		'&eta;' => '&#951;',
-		'&theta;' => '&#952;',
-		'&iota;' => '&#953;',
-		'&kappa;' => '&#954;',
-		'&lambda;' => '&#955;',
-		'&mu;' => '&#956;',
-		'&nu;' => '&#957;',
-		'&xi;' => '&#958;',
-		'&omicron;' => '&#959;',
-		'&pi;' => '&#960;',
-		'&rho;' => '&#961;',
-		'&sigmaf;' => '&#962;',
-		'&sigma;' => '&#963;',
-		'&tau;' => '&#964;',
-		'&upsilon;' => '&#965;',
-		'&phi;' => '&#966;',
-		'&chi;' => '&#967;',
-		'&psi;' => '&#968;',
-		'&omega;' => '&#969;',
-		'&thetasym;' => '&#977;',
-		'&upsih;' => '&#978;',
-		'&piv;' => '&#982;',
-		'&ensp;' => '&#8194;',
-		'&emsp;' => '&#8195;',
-		'&thinsp;' => '&#8201;',
-		'&zwnj;' => '&#8204;',
-		'&zwj;' => '&#8205;',
-		'&lrm;' => '&#8206;',
-		'&rlm;' => '&#8207;',
-		'&ndash;' => '&#8211;',
-		'&mdash;' => '&#8212;',
-		'&lsquo;' => '&#8216;',
-		'&rsquo;' => '&#8217;',
-		'&sbquo;' => '&#8218;',
-		'&ldquo;' => '&#8220;',
-		'&rdquo;' => '&#8221;',
-		'&bdquo;' => '&#8222;',
-		'&dagger;' => '&#8224;',
-		'&Dagger;' => '&#8225;',
-		'&bull;' => '&#8226;',
-		'&hellip;' => '&#8230;',
-		'&permil;' => '&#8240;',
-		'&prime;' => '&#8242;',
-		'&Prime;' => '&#8243;',
-		'&lsaquo;' => '&#8249;',
-		'&rsaquo;' => '&#8250;',
-		'&oline;' => '&#8254;',
-		'&frasl;' => '&#8260;',
-		'&euro;' => '&#8364;',
-		'&image;' => '&#8465;',
-		'&weierp;' => '&#8472;',
-		'&real;' => '&#8476;',
-		'&trade;' => '&#8482;',
-		'&alefsym;' => '&#8501;',
-		'&crarr;' => '&#8629;',
-		'&lArr;' => '&#8656;',
-		'&uArr;' => '&#8657;',
-		'&rArr;' => '&#8658;',
-		'&dArr;' => '&#8659;',
-		'&hArr;' => '&#8660;',
-		'&forall;' => '&#8704;',
-		'&part;' => '&#8706;',
-		'&exist;' => '&#8707;',
-		'&empty;' => '&#8709;',
-		'&nabla;' => '&#8711;',
-		'&isin;' => '&#8712;',
-		'&notin;' => '&#8713;',
-		'&ni;' => '&#8715;',
-		'&prod;' => '&#8719;',
-		'&sum;' => '&#8721;',
-		'&minus;' => '&#8722;',
-		'&lowast;' => '&#8727;',
-		'&radic;' => '&#8730;',
-		'&prop;' => '&#8733;',
-		'&infin;' => '&#8734;',
-		'&ang;' => '&#8736;',
-		'&and;' => '&#8743;',
-		'&or;' => '&#8744;',
-		'&cap;' => '&#8745;',
-		'&cup;' => '&#8746;',
-		'&int;' => '&#8747;',
-		'&there4;' => '&#8756;',
-		'&sim;' => '&#8764;',
-		'&cong;' => '&#8773;',
-		'&asymp;' => '&#8776;',
-		'&ne;' => '&#8800;',
-		'&equiv;' => '&#8801;',
-		'&le;' => '&#8804;',
-		'&ge;' => '&#8805;',
-		'&sub;' => '&#8834;',
-		'&sup;' => '&#8835;',
-		'&nsub;' => '&#8836;',
-		'&sube;' => '&#8838;',
-		'&supe;' => '&#8839;',
-		'&oplus;' => '&#8853;',
-		'&otimes;' => '&#8855;',
-		'&perp;' => '&#8869;',
-		'&sdot;' => '&#8901;',
-		'&lceil;' => '&#8968;',
-		'&rceil;' => '&#8969;',
-		'&lfloor;' => '&#8970;',
-		'&rfloor;' => '&#8971;',
-		'&lang;' => '&#9001;',
-		'&rang;' => '&#9002;',
-		'&larr;' => '&#8592;',
-		'&uarr;' => '&#8593;',
-		'&rarr;' => '&#8594;',
-		'&darr;' => '&#8595;',
-		'&harr;' => '&#8596;',
-		'&loz;' => '&#9674;',
-		'&spades;' => '&#9824;',
-		'&clubs;' => '&#9827;',
-		'&hearts;' => '&#9829;',
-		'&diams;' => '&#9830;'
-	);
-
-	return str_replace( array_keys($to_ncr), array_values($to_ncr), $text );
-}
-
-function wp_richedit_pre($text) {
-	// Filtering a blank results in an annoying <br />\n
-	if ( empty($text) ) return apply_filters('richedit_pre', '');
-
-	$output = $text;
-	$output = convert_chars($output);
-	$output = wpautop($output);
-
-	// These must be double-escaped or planets will collide.
-	$output = str_replace('&lt;', '&amp;lt;', $output);
-	$output = str_replace('&gt;', '&amp;gt;', $output);
-
-	return apply_filters('richedit_pre', $output);
-}
-
-// Escape single quotes, specialchar double quotes, and fix line endings.
-function js_escape($text) {
-	$text = wp_specialchars($text, 'double');
-	$text = str_replace('&#039;', "'", $text);
-	return preg_replace("/\r?\n/", "\\n", addslashes($text));
-}
-?>
diff -ruN 2.0.5/wp-includes/functions-post.php 2.2.2/wp-includes/functions-post.php
--- 2.0.5/wp-includes/functions-post.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/functions-post.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,1026 +0,0 @@
-<?php
-
-/**** DB Functions ****/
-
-/*
- * generic function for inserting data into the posts table.
- */
-function wp_insert_post($postarr = array()) {
-	global $wpdb, $wp_rewrite, $allowedtags, $user_ID;
-
-	if ( is_object($postarr) )
-		$postarr = get_object_vars($postarr);
-
-	// export array as variables
-	extract($postarr);
-
-	// Are we updating or creating?
-	$update = false;
-	if ( !empty($ID) ) {
-		$update = true;
-		$post = & get_post($ID);
-		$previous_status = $post->post_status;
-	}
-
-	// Get the basics.
-	$post_content    = apply_filters('content_save_pre',   $post_content);
-	$post_excerpt    = apply_filters('excerpt_save_pre',   $post_excerpt);
-	$post_title      = apply_filters('title_save_pre',     $post_title);
-	$post_category   = apply_filters('category_save_pre',  $post_category);
-	$post_status     = apply_filters('status_save_pre',    $post_status);
-	$post_name       = apply_filters('name_save_pre',      $post_name);
-	$comment_status  = apply_filters('comment_status_pre', $comment_status);
-	$ping_status     = apply_filters('ping_status_pre',    $ping_status);
-	
-	// Make sure we set a valid category
-	if (0 == count($post_category) || !is_array($post_category)) {
-		$post_category = array(get_option('default_category'));
-	}
-	$post_cat = $post_category[0];
-
-	if ( empty($post_author) )
-		$post_author = $user_ID;
-
-	if ( empty($post_status) )
-		$post_status = 'draft';
-	
-	// Get the post ID.
-	if ( $update )
-		$post_ID = $ID;
-
-	// Create a valid post name.  Drafts are allowed to have an empty
-	// post name.
-	if ( empty($post_name) ) {
-		if ( 'draft' != $post_status )
-			$post_name = sanitize_title($post_title);
-	} else {
-		$post_name = sanitize_title($post_name);
-	}
-	
-
-	// If the post date is empty (due to having been new or a draft) and status is not 'draft', set date to now
-	if (empty($post_date)) {
-		if ( 'draft' != $post_status )
-			$post_date = current_time('mysql');
-	}
-
-	if (empty($post_date_gmt)) {
-		if ( 'draft' != $post_status )
-			$post_date_gmt = get_gmt_from_date($post_date);
-	}
-
-	if ( empty($comment_status) ) {
-		if ( $update )
-			$comment_status = 'closed';
-		else
-			$comment_status = get_settings('default_comment_status');
-	}
-	if ( empty($ping_status) )
-		$ping_status = get_settings('default_ping_status');
-	if ( empty($post_pingback) )
-		$post_pingback = get_option('default_pingback_flag');
-
-	if ( isset($to_ping) )
-		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
-	else
-		$to_ping = '';
-
-	if ( ! isset($pinged) )
-		$pinged = '';
-
-	if ( isset($post_parent) )
-		$post_parent = (int) $post_parent;
-	else
-		$post_parent = 0;
-
-	if ( isset($menu_order) )
-		$menu_order = (int) $menu_order;
-	else
-		$menu_order = 0;
-
-	if ( !isset($post_password) )
-		$post_password = '';
-
-	if ( ('publish' == $post_status) || ('static' == $post_status) ) {
-		$post_name_check = ('publish' == $post_status)
-			? $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_status = 'publish' AND ID != '$post_ID' LIMIT 1")
-			: $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_status = 'static' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");
-
-		if ($post_name_check) {
-			$suffix = 2;
-			while ($post_name_check) {
-				$alt_post_name = $post_name . "-$suffix";
-				$post_name_check = ('publish' == $post_status)
-					? $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_status = 'publish' AND ID != '$post_ID' LIMIT 1")
-					: $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_status = 'static' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");
-				$suffix++;
-			}
-			$post_name = $alt_post_name;
-		}
-	}
-
-	if ($update) {
-		$wpdb->query(
-			"UPDATE IGNORE $wpdb->posts SET
-			post_author = '$post_author',
-			post_date = '$post_date',
-			post_date_gmt = '$post_date_gmt',
-			post_content = '$post_content',
-			post_content_filtered = '$post_content_filtered',
-			post_title = '$post_title',
-			post_excerpt = '$post_excerpt',
-			post_status = '$post_status',
-			comment_status = '$comment_status',
-			ping_status = '$ping_status',
-			post_password = '$post_password',
-			post_name = '$post_name',
-			to_ping = '$to_ping',
-			pinged = '$pinged',
-			post_modified = '".current_time('mysql')."',
-			post_modified_gmt = '".current_time('mysql',1)."',
-			post_parent = '$post_parent',
-			menu_order = '$menu_order'
-			WHERE ID = $post_ID");
-	} else {
-		$wpdb->query(
-			"INSERT IGNORE INTO $wpdb->posts
-			(post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt,  post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
-			VALUES
-			('$post_author', '$post_date', '$post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', '$post_status', '$comment_status', '$ping_status', '$post_password', '$post_name', '$to_ping', '$pinged', '$post_date', '$post_date_gmt', '$post_parent', '$menu_order', '$post_mime_type')");
-			$post_ID = $wpdb->insert_id;			
-	}
-
-	if ( empty($post_name) && 'draft' != $post_status ) {
-		$post_name = sanitize_title($post_title, $post_ID);
-		$wpdb->query( "UPDATE $wpdb->posts SET post_name = '$post_name' WHERE ID = '$post_ID'" );
-	}
-
-	wp_set_post_cats('', $post_ID, $post_category);
-
-	if ( 'static' == $post_status ) {
-		clean_page_cache($post_ID);
-		wp_cache_delete($post_ID, 'pages');
-	} else {
-		clean_post_cache($post_ID);
-	}
-
-	// Set GUID
-	if ( ! $update )
-		$wpdb->query("UPDATE $wpdb->posts SET guid = '" . get_permalink($post_ID) . "' WHERE ID = '$post_ID'");
-
-	if ( $update) {
-		if ($previous_status != 'publish' && $post_status == 'publish') {
-			// Reset GUID if transitioning to publish.
-			$wpdb->query("UPDATE $wpdb->posts SET guid = '" . get_permalink($post_ID) . "' WHERE ID = '$post_ID'");
-			do_action('private_to_published', $post_ID);
-		}
-		
-		do_action('edit_post', $post_ID);
-	}
-
-	if ($post_status == 'publish') {
-		do_action('publish_post', $post_ID);
-
-		if ( !defined('WP_IMPORTING') ) {
-			if ( $post_pingback )
-				$result = $wpdb->query("
-					INSERT INTO $wpdb->postmeta 
-					(post_id,meta_key,meta_value) 
-					VALUES ('$post_ID','_pingme','1')
-				");
-			$result = $wpdb->query("
-				INSERT INTO $wpdb->postmeta 
-				(post_id,meta_key,meta_value) 
-				VALUES ('$post_ID','_encloseme','1')
-			");
-			spawn_pinger();
-		}
-	} else if ($post_status == 'static') {
-		wp_cache_delete('all_page_ids', 'pages');
-		$wp_rewrite->flush_rules();
-
-		if ( !empty($page_template) )
-			if ( ! update_post_meta($post_ID, '_wp_page_template',  $page_template))
-				add_post_meta($post_ID, '_wp_page_template',  $page_template, true);
-	}
-
-	do_action('save_post', $post_ID);
-	do_action('wp_insert_post', $post_ID);
-
-	return $post_ID;
-}
-
-function wp_insert_attachment($object, $file = false, $post_parent = 0) {
-	global $wpdb, $user_ID;
-
-	if ( is_object($object) )
-		$object = get_object_vars($object);
-
-	// Export array as variables
-	extract($object);
-
-	// Get the basics.
-	$post_content    = apply_filters('content_save_pre',   $post_content);
-	$post_excerpt    = apply_filters('excerpt_save_pre',   $post_excerpt);
-	$post_title      = apply_filters('title_save_pre',     $post_title);
-	$post_category   = apply_filters('category_save_pre',  $post_category);
-	$post_name       = apply_filters('name_save_pre',      $post_name);
-	$comment_status  = apply_filters('comment_status_pre', $comment_status);
-	$ping_status     = apply_filters('ping_status_pre',    $ping_status);
-	$post_mime_type  = apply_filters('post_mime_type_pre', $post_mime_type);
-
-	// Make sure we set a valid category
-	if (0 == count($post_category) || !is_array($post_category)) {
-		$post_category = array(get_option('default_category'));
-	}
-	$post_cat = $post_category[0];
-
-	if ( empty($post_author) )
-		$post_author = $user_ID;
-
-	$post_status = 'attachment';
-
-	// Are we updating or creating?
-	$update = false;
-	if ( !empty($ID) ) {
-		$update = true;
-		$post_ID = $ID;	
-	}
-
-	// Create a valid post name.
-	if ( empty($post_name) )
-		$post_name = sanitize_title($post_title);
-	else
-		$post_name = sanitize_title($post_name);
-	
-	if (empty($post_date))
-		$post_date = current_time('mysql');
-	if (empty($post_date_gmt)) 
-		$post_date_gmt = current_time('mysql', 1);
-
-	if ( empty($comment_status) ) {
-		if ( $update )
-			$comment_status = 'closed';
-		else
-			$comment_status = get_settings('default_comment_status');
-	}
-	if ( empty($ping_status) )
-		$ping_status = get_settings('default_ping_status');
-	if ( empty($post_pingback) )
-		$post_pingback = get_option('default_pingback_flag');
-
-	if ( isset($to_ping) )
-		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
-	else
-		$to_ping = '';
-
-	if ( isset($post_parent) )
-		$post_parent = (int) $post_parent;
-	else
-		$post_parent = 0;
-
-	if ( isset($menu_order) )
-		$menu_order = (int) $menu_order;
-	else
-		$menu_order = 0;
-
-	if ( !isset($post_password) )
-		$post_password = '';
-
-	if ( isset($to_ping) )
-		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
-	else
-		$to_ping = '';
-
-	if ( ! isset($pinged) )
-		$pinged = '';
-
-	if ($update) {
-		$wpdb->query(
-			"UPDATE $wpdb->posts SET
-			post_author = '$post_author',
-			post_date = '$post_date',
-			post_date_gmt = '$post_date_gmt',
-			post_content = '$post_content',
-			post_title = '$post_title',
-			post_excerpt = '$post_excerpt',
-			post_status = '$post_status',
-			comment_status = '$comment_status',
-			ping_status = '$ping_status',
-			post_password = '$post_password',
-			post_name = '$post_name',
-			to_ping = '$to_ping',
-			pinged = '$pinged',
-			post_modified = '".current_time('mysql')."',
-			post_modified_gmt = '".current_time('mysql',1)."',
-			post_parent = '$post_parent',
-			menu_order = '$menu_order',
-			post_mime_type = '$post_mime_type',
-			guid = '$guid'
-			WHERE ID = $post_ID");
-	} else {
-		$wpdb->query(
-			"INSERT INTO $wpdb->posts
-			(post_author, post_date, post_date_gmt, post_content, post_title, post_excerpt,  post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid)
-			VALUES
-			('$post_author', '$post_date', '$post_date_gmt', '$post_content', '$post_title', '$post_excerpt', '$post_status', '$comment_status', '$ping_status', '$post_password', '$post_name', '$to_ping', '$pinged', '$post_date', '$post_date_gmt', '$post_parent', '$menu_order', '$post_mime_type', '$guid')");
-			$post_ID = $wpdb->insert_id;			
-	}
-	
-	if ( empty($post_name) ) {
-		$post_name = sanitize_title($post_title, $post_ID);
-		$wpdb->query( "UPDATE $wpdb->posts SET post_name = '$post_name' WHERE ID = '$post_ID'" );
-	}
-
-	wp_set_post_cats('', $post_ID, $post_category);
-
-	if ( $file )
-		add_post_meta($post_ID, '_wp_attached_file', $file);
-
-	clean_post_cache($post_ID);
-
-	if ( $update) {
-		do_action('edit_attachment', $post_ID);
-	} else {
-		do_action('add_attachment', $post_ID);
-	}
-	
-	return $post_ID;
-}
-
-function wp_delete_attachment($postid) {
-	global $wpdb;
-	$postid = (int) $postid;
-
-	if ( !$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = '$postid'") )
-		return $post;
-
-	if ( 'attachment' != $post->post_status )
-		return false;
-
-	$meta = get_post_meta($postid, '_wp_attachment_metadata', true);
-	$file = get_post_meta($postid, '_wp_attached_file', true);
-
-	$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = '$postid'");
-
-	$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_post_ID = '$postid'");
-
-	$wpdb->query("DELETE FROM $wpdb->post2cat WHERE post_id = '$postid'");
-
-	$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$postid'");
-
-	if ( ! empty($meta['thumb']) ) {
-		// Don't delete the thumb if another attachment uses it
-		if (! $foo = $wpdb->get_row("SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE '%".$wpdb->escape($meta['thumb'])."%' AND post_id <> '$postid'"))
-			@ unlink(str_replace(basename($file), $meta['thumb'], $file));
-	}
-
-	if ( ! empty($file) )
-		@ unlink($file);
-
-	do_action('delete_attachment', $postid);
-
-	return $post;
-}
-
-function wp_get_single_post($postid = 0, $mode = OBJECT) {
-	global $wpdb;
-
-	$post = get_post($postid, $mode);
-	
-	// Set categories
-	if($mode == OBJECT) {
-		$post->post_category = wp_get_post_cats('',$postid);
-	} 
-	else {
-		$post['post_category'] = wp_get_post_cats('',$postid);
-	}
-
-	return $post;
-}
-
-function wp_get_recent_posts($num = 10) {
-	global $wpdb;
-
-	// Set the limit clause, if we got a limit
-	if ($num) {
-		$limit = "LIMIT $num";
-	}
-
-	$sql = "SELECT * FROM $wpdb->posts WHERE post_status IN ('publish', 'draft', 'private') ORDER BY post_date DESC $limit";
-	$result = $wpdb->get_results($sql,ARRAY_A);
-
-	return $result?$result:array();
-}
-
-function wp_update_post($postarr = array()) {
-	global $wpdb;
-
-	if ( is_object($postarr) )
-		$postarr = get_object_vars($postarr);
-
-	// First, get all of the original fields
-	$post = wp_get_single_post($postarr['ID'], ARRAY_A);	
-
-	// Escape data pulled from DB.
-	$post = add_magic_quotes($post);
-
-	// Passed post category list overwrites existing category list if not empty.
- 	if ( isset($postarr['post_category']) && is_array($postarr['post_category'])
-			 && 0 != count($postarr['post_category']) )
- 		$post_cats = $postarr['post_category'];
- 	else 
- 		$post_cats = $post['post_category'];
-
-	// Drafts shouldn't be assigned a date unless explicitly done so by the user
-	if ( 'draft' == $post['post_status'] && empty($postarr['edit_date']) && empty($postarr['post_date']) && 
-	     ('0000-00-00 00:00:00' == $post['post_date']) )
-		$clear_date = true;
-	else
-		$clear_date = false;
-
- 	// Merge old and new fields with new fields overwriting old ones.
- 	$postarr = array_merge($post, $postarr);
- 	$postarr['post_category'] = $post_cats;	
-	if ( $clear_date ) {
-		$postarr['post_date'] = '';
-		$postarr['post_date_gmt'] = '';
-	}
-
-	if ($postarr['post_status'] == 'attachment')
-		return wp_insert_attachment($postarr);
-
-	return wp_insert_post($postarr);
-}
-
-function wp_get_post_cats($blogid = '1', $post_ID = 0) {
-	global $wpdb;
-	
-	$post_ID = (int) $post_ID;
-
-	$sql = "SELECT category_id 
-		FROM $wpdb->post2cat 
-		WHERE post_id = '$post_ID' 
-		ORDER BY category_id";
-
-	$result = $wpdb->get_col($sql);
-
-	if ( !$result )
-		$result = array();
-
-	return array_unique($result);
-}
-
-function wp_set_post_cats($blogid = '1', $post_ID = 0, $post_categories = array()) {
-	global $wpdb;
-	// If $post_categories isn't already an array, make it one:
-	if (!is_array($post_categories) || 0 == count($post_categories))
-		$post_categories = array(get_option('default_category'));
-	
-	$post_categories = array_unique($post_categories);
-
-	// First the old categories
-	$old_categories = $wpdb->get_col("
-		SELECT category_id 
-		FROM $wpdb->post2cat 
-		WHERE post_id = $post_ID");
-	
-	if (!$old_categories) {
-		$old_categories = array();
-	} else {
-		$old_categories = array_unique($old_categories);
-	}
-
-	// Delete any?
-	$delete_cats = array_diff($old_categories,$post_categories);
-
-	if ($delete_cats) {
-		foreach ($delete_cats as $del) {
-			$wpdb->query("
-				DELETE FROM $wpdb->post2cat 
-				WHERE category_id = $del 
-					AND post_id = $post_ID 
-				");
-		}
-	}
-
-	// Add any?
-	$add_cats = array_diff($post_categories, $old_categories);
-
-	if ($add_cats) {
-		foreach ($add_cats as $new_cat) {
-			$wpdb->query("
-				INSERT INTO $wpdb->post2cat (post_id, category_id) 
-				VALUES ($post_ID, $new_cat)");
-		}
-	}
-	
-	// Update category counts.
-	$all_affected_cats = array_unique(array_merge($post_categories, $old_categories));
-	foreach ( $all_affected_cats as $cat_id ) {
-		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status='publish' AND category_id = '$cat_id'");
-		$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
-		wp_cache_delete($cat_id, 'category');		
-	}
-}	// wp_set_post_cats()
-
-function wp_delete_post($postid = 0) {
-	global $wpdb, $wp_rewrite;
-	$postid = (int) $postid;
-
-	if ( !$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = $postid") )
-		return $post;
-
-	if ( 'attachment' == $post->post_status )
-		return wp_delete_attachment($postid);
-
-	do_action('delete_post', $postid);
-
-	if ( 'publish' == $post->post_status) {
-		$categories = wp_get_post_cats('', $post->ID);
-		if( is_array( $categories ) ) {
-			foreach ( $categories as $cat_id ) {
-				$wpdb->query("UPDATE $wpdb->categories SET category_count = category_count - 1 WHERE cat_ID = '$cat_id'");
-				wp_cache_delete($cat_id, 'category');
-			}
-		}
-	}
-
-	if ( 'static' == $post->post_status )
-		$wpdb->query("UPDATE $wpdb->posts SET post_parent = $post->post_parent WHERE post_parent = $postid AND post_status = 'static'");
-
-	$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = $postid");
-	
-	$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_post_ID = $postid");
-
-	$wpdb->query("DELETE FROM $wpdb->post2cat WHERE post_id = $postid");
-
-	$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = $postid");
-
-	if ( 'static' == $post->post_status ) {
-		wp_cache_delete('all_page_ids', 'pages');
-		$wp_rewrite->flush_rules();
-	}
-
-	return $post;
-}
-
-/**** /DB Functions ****/
-
-/**** Misc ****/
-
-// get permalink from post ID
-function post_permalink($post_id = 0, $mode = '') { // $mode legacy
-	return get_permalink($post_id);
-}
-
-// Get the name of a category from its ID
-function get_cat_name($cat_id) {
-	global $wpdb;
-	
-	$cat_id -= 0; 	// force numeric
-	$name = $wpdb->get_var("SELECT cat_name FROM $wpdb->categories WHERE cat_ID=$cat_id");
-	
-	return $name;
-}
-
-// Get the ID of a category from its name
-function get_cat_ID($cat_name='General') {
-	global $wpdb;
-	
-	$cid = $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE cat_name='$cat_name'");
-
-	return $cid?$cid:1;	// default to cat 1
-}
-
-// Get author's preferred display name
-function get_author_name( $auth_id ) {
-	$authordata = get_userdata( $auth_id );
-
-	return $authordata->display_name;
-}
-
-// get extended entry info (<!--more-->)
-function get_extended($post) {
-	list($main,$extended) = explode('<!--more-->', $post, 2);
-
-	// Strip leading and trailing whitespace
-	$main = preg_replace('/^[\s]*(.*)[\s]*$/','\\1',$main);
-	$extended = preg_replace('/^[\s]*(.*)[\s]*$/','\\1',$extended);
-
-	return array('main' => $main, 'extended' => $extended);
-}
-
-// do trackbacks for a list of urls
-// borrowed from edit.php
-// accepts a comma-separated list of trackback urls and a post id
-function trackback_url_list($tb_list, $post_id) {
-	if (!empty($tb_list)) {
-		// get post data
-		$postdata = wp_get_single_post($post_id, ARRAY_A);
-
-		// import postdata as variables
-		extract($postdata);
-		
-		// form an excerpt
-		$excerpt = strip_tags($post_excerpt?$post_excerpt:$post_content);
-		
-		if (strlen($excerpt) > 255) {
-			$excerpt = substr($excerpt,0,252) . '...';
-		}
-		
-		$trackback_urls = explode(',', $tb_list);
-		foreach($trackback_urls as $tb_url) {
-		    $tb_url = trim($tb_url);
-		    trackback($tb_url, stripslashes($post_title), $excerpt, $post_id);
-		}
-    }
-}
-
-function wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent) {
-	global $wpdb;
-
-	do_action('wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent);
-
-	if ( preg_match_all('/&#(\d+);/', $comment . $author . $url, $chars) ) {
-		foreach ($chars[1] as $char) {
-			// If it's an encoded char in the normal ASCII set, reject
-			if ($char < 128)
-				return true;
-		}
-	}
-
-	$mod_keys = trim( get_settings('blacklist_keys') );
-	if ('' == $mod_keys )
-		return false; // If moderation keys are empty
-	$words = explode("\n", $mod_keys );
-
-	foreach ($words as $word) {
-		$word = trim($word);
-
-		// Skip empty lines
-		if ( empty($word) ) { continue; }
-
-		// Do some escaping magic so that '#' chars in the 
-		// spam words don't break things:
-		$word = preg_quote($word, '#');
-		
-		$pattern = "#$word#i"; 
-		if ( preg_match($pattern, $author    ) ) return true;
-		if ( preg_match($pattern, $email     ) ) return true;
-		if ( preg_match($pattern, $url       ) ) return true;
-		if ( preg_match($pattern, $comment   ) ) return true;
-		if ( preg_match($pattern, $user_ip   ) ) return true;
-		if ( preg_match($pattern, $user_agent) ) return true;
-	}
-	
-	if ( isset($_SERVER['REMOTE_ADDR']) ) {
-		if ( wp_proxy_check($_SERVER['REMOTE_ADDR']) ) return true;
-	}
-
-	return false;
-}
-
-function wp_proxy_check($ipnum) {
-	if ( get_option('open_proxy_check') && isset($ipnum) ) {
-		$ipnum = preg_replace( '/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/', '$1', $ipnum );
-		$rev_ip = implode( '.', array_reverse( explode( '.', $ipnum ) ) );
-		$lookup = $rev_ip . '.sbl-xbl.spamhaus.org.';
-		if ( $lookup != gethostbyname( $lookup ) )
-			return true;
-	}
-
-	return false;
-}
-
-function do_trackbacks($post_id) {
-	global $wpdb;
-
-	$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = $post_id");
-	$to_ping = get_to_ping($post_id);
-	$pinged  = get_pung($post_id);
-	if ( empty($to_ping) ) {
-		$wpdb->query("UPDATE $wpdb->posts SET to_ping = '' WHERE ID = '$post_id'");
-		return;
-	}
-	
-	if (empty($post->post_excerpt))
-		$excerpt = apply_filters('the_content', $post->post_content);
-	else
-		$excerpt = apply_filters('the_excerpt', $post->post_excerpt);
-	$excerpt = str_replace(']]>', ']]&gt;', $excerpt);
-	$excerpt = strip_tags($excerpt);
-	if ( function_exists('mb_strcut') ) // For international trackbacks
-    	$excerpt = mb_strcut($excerpt, 0, 252, get_settings('blog_charset')) . '...';
-	else
-		$excerpt = substr($excerpt, 0, 252) . '...';
-
-	$post_title = apply_filters('the_title', $post->post_title);
-	$post_title = strip_tags($post_title);
-
-	if ($to_ping) : foreach ($to_ping as $tb_ping) :
-		$tb_ping = trim($tb_ping);
-		if ( !in_array($tb_ping, $pinged) ) {
-			trackback($tb_ping, $post_title, $excerpt, $post_id);
-			$pinged[] = $tb_ping;
-		} else {
-			$wpdb->query("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '$tb_ping', '')) WHERE ID = '$post_id'");
-		}
-	endforeach; endif;
-}
-
-function get_pung($post_id) { // Get URIs already pung for a post
-	global $wpdb;
-	$pung = $wpdb->get_var("SELECT pinged FROM $wpdb->posts WHERE ID = $post_id");
-	$pung = trim($pung);
-	$pung = preg_split('/\s/', $pung);
-	$pung = apply_filters('get_pung', $pung);
-	return $pung;
-}
-
-function get_enclosed($post_id) { // Get enclosures already enclosed for a post
-	global $wpdb;
-	$custom_fields = get_post_custom( $post_id );
-	$pung = array();
-	if ( !is_array( $custom_fields ) )
-		return $pung;
-
-	foreach ( $custom_fields as $key => $val ) {
-		if ( 'enclosure' != $key || !is_array( $val ) )
-			continue;
-		foreach( $val as $enc ) {
-			$enclosure = split( "\n", $enc );
-			$pung[] = trim( $enclosure[ 0 ] );
-		}
-	}
-	$pung = apply_filters('get_enclosed', $pung);
-	return $pung;
-}
-
-function get_to_ping($post_id) { // Get any URIs in the todo list
-	global $wpdb;
-	$to_ping = $wpdb->get_var("SELECT to_ping FROM $wpdb->posts WHERE ID = $post_id");
-	$to_ping = trim($to_ping);
-	$to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);
-	$to_ping = apply_filters('get_to_ping',  $to_ping);
-	return $to_ping;
-}
-
-function add_ping($post_id, $uri) { // Add a URI to those already pung
-	global $wpdb;
-	$pung = $wpdb->get_var("SELECT pinged FROM $wpdb->posts WHERE ID = $post_id");
-	$pung = trim($pung);
-	$pung = preg_split('/\s/', $pung);
-	$pung[] = $uri;
-	$new = implode("\n", $pung);
-	$new = apply_filters('add_ping', $new);
-	return $wpdb->query("UPDATE $wpdb->posts SET pinged = '$new' WHERE ID = $post_id");
-}
-
-//fetches the pages returned as a FLAT list, but arranged in order of their hierarchy, i.e., child parents
-//immediately follow their parents
-function get_page_hierarchy($posts, $parent = 0) {
-	$result = array ( );
-	if ($posts) { foreach ($posts as $post) {
-		if ($post->post_parent == $parent) {
-			$result[$post->ID] = $post->post_name;
-			$children = get_page_hierarchy($posts, $post->ID);
-			$result += $children; //append $children to $result
-		}
-	} }
-	return $result;
-}
-
-function generate_page_rewrite_rules() {
-	global $wpdb;
-	
-	//get pages in order of hierarchy, i.e. children after parents
-	$posts = get_page_hierarchy($wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_status = 'static'"));
-	//now reverse it, because we need parents after children for rewrite rules to work properly
-	$posts = array_reverse($posts, true);
-
-	$page_rewrite_rules = array();
-	$page_attachment_rewrite_rules = array();
-
-	if ($posts) {
-		
-		foreach ($posts as $id => $post) {
-
-			// URI => page name
-			$uri = get_page_uri($id);
-			$attachments = $wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_status = 'attachment' AND post_parent = '$id'");
-			if ( $attachments ) {
-				foreach ( $attachments as $attachment ) {
-					$attach_uri = get_page_uri($attachment->ID);
-					$page_attachment_rewrite_rules[$attach_uri] = $attachment->post_name;
-				}
-			}
-
-			$page_rewrite_rules[$uri] = $post;
-		}
-
-		update_option('page_uris', $page_rewrite_rules);
-		
-		if ( $page_attachment_rewrite_rules )
-			update_option('page_attachment_uris', $page_attachment_rewrite_rules);
-	}
-}
-
-function get_post_status($ID = '') {
-	$post = get_post($ID);
-
-	if ( is_object($post) ) {
-		if ( ('attachment' == $post->post_status) && $post->post_parent && ($post->ID != $post->post_parent) )
-			return get_post_status($post->post_parent);
-		else
-			return $post->post_status;
-	}
-
-	return false;
-}
-
-// Takes a post ID, returns its mime type.
-function get_post_mime_type($ID = '') {
-	$post = & get_post($ID);
-
-	if ( is_object($post) )
-		return $post->post_mime_type;
-
-	return false;
-}
-
-function get_attached_file($attachment_id) {
-	return get_post_meta($attachment_id, '_wp_attached_file', true);
-}
-
-function wp_mkdir_p($target) {
-	// from php.net/mkdir user contributed notes
-	if (file_exists($target)) {
-		if (! @ is_dir($target))
-			return false;
-		else
-			return true;
-	}
-
-	// Attempting to create the directory may clutter up our display.
-	if (@ mkdir($target)) {
-		$stat = @ stat(dirname($target));
-		$dir_perms = $stat['mode'] & 0007777;  // Get the permission bits.
-		@ chmod($target, $dir_perms);
-		return true;
-	} else {
-		if ( is_dir(dirname($target)) )
-			return false;	
-	}
-
-	// If the above failed, attempt to create the parent node, then try again.
-	if (wp_mkdir_p(dirname($target)))
-		return wp_mkdir_p($target);
-
-	return false;
-}
-
-// Returns an array containing the current upload directory's path and url, or an error message.
-function wp_upload_dir() {
-	$siteurl = get_settings('siteurl');
-	//prepend ABSPATH to $dir and $siteurl to $url if they're not already there
-	$path = str_replace(ABSPATH, '', trim(get_settings('upload_path')));
-	$dir = ABSPATH . $path;
-	$url = trailingslashit($siteurl) . $path;
-
-	if ( $dir == ABSPATH ) { //the option was empty
-		$dir = ABSPATH . 'wp-content/uploads';
-	}
-
-	if ( defined('UPLOADS') ) {
-		$dir = ABSPATH . UPLOADS;
-		$url = trailingslashit($siteurl) . UPLOADS;
-	}
-
-	if ( get_settings('uploads_use_yearmonth_folders')) {
-		// Generate the yearly and monthly dirs
-		$time = current_time( 'mysql' );
-		$y = substr( $time, 0, 4 );
-		$m = substr( $time, 5, 2 );
-		$dir = $dir . "/$y/$m";
-		$url = $url . "/$y/$m";
-	}
-
-	// Make sure we have an uploads dir
-	if ( ! wp_mkdir_p( $dir ) ) {
-		$message = sprintf(__('Unable to create directory %s. Is its parent directory writable by the server?'), $dir);
-		return array('error' => $message);
-	}
-
-    $uploads = array('path' => $dir, 'url' => $url, 'error' => false);
-	return apply_filters('upload_dir', $uploads);
-}
-
-function wp_upload_bits($name, $type, $bits) {
-	if ( empty($name) )
-		return array('error' => __("Empty filename"));
-
-	$wp_filetype = wp_check_filetype($name);
-	if ( !$wp_filetype['ext'] )
-		return array('error' => __("Invalid file type"));
-
-	$upload = wp_upload_dir();
-	
-	if ( $upload['error'] !== false )
-		return $upload;
-
-	$number = '';
-	$filename = $name;
-	$path_parts = pathinfo($filename);
-	$ext = $path_parts['extension'];
-	if ( empty($ext) )
-		$ext = '';
-	else
-		$ext = ".$ext";
-	while ( file_exists($upload['path'] . "/$filename") ) {
-		if ( '' == "$number$ext" )
-			$filename = $filename . ++$number . $ext;
-		else
-			$filename = str_replace("$number$ext", ++$number . $ext, $filename);
-	}
-		
-	$new_file = $upload['path'] . "/$filename";
-	if ( ! wp_mkdir_p( dirname($new_file) ) ) {
-		$message = sprintf(__('Unable to create directory %s. Is its parent directory writable by the server?'), dirname($new_file));
-		return array('error' => $message);
-	}
-
-	$ifp = @ fopen($new_file, 'wb');
-	if ( ! $ifp )
-		return array('error' => "Could not write file $new_file.");
-		
-	$success = @ fwrite($ifp, $bits);
-	fclose($ifp);
-	// Set correct file permissions
-	$stat = @ stat(dirname($new_file));
-	$perms = $stat['mode'] & 0007777;
-	$perms = $perms & 0000666;
-	@ chmod($new_file, $perms);
-
-	// Compute the URL
-	$url = $upload['url'] . "/$filename";
-
-	return array('file' => $new_file, 'url' => $url, 'error' => false);
-}
-
-function wp_check_filetype($filename, $mimes = null) {
-	// Accepted MIME types are set here as PCRE unless provided.
-	$mimes = is_array($mimes) ? $mimes : apply_filters('upload_mimes', array (
-		'jpg|jpeg|jpe' => 'image/jpeg',
-		'gif' => 'image/gif',
-		'png' => 'image/png',
-		'bmp' => 'image/bmp',
-		'tif|tiff' => 'image/tiff',
-		'ico' => 'image/x-icon',
-		'asf|asx|wax|wmv|wmx' => 'video/asf',
-		'avi' => 'video/avi',
-		'mov|qt' => 'video/quicktime',
-		'mpeg|mpg|mpe' => 'video/mpeg',
-		'txt|c|cc|h' => 'text/plain',
-		'rtx' => 'text/richtext',
-		'css' => 'text/css',
-		'htm|html' => 'text/html',
-		'mp3|mp4' => 'audio/mpeg',
-		'ra|ram' => 'audio/x-realaudio',
-		'wav' => 'audio/wav',
-		'ogg' => 'audio/ogg',
-		'mid|midi' => 'audio/midi',
-		'wma' => 'audio/wma',
-		'rtf' => 'application/rtf',
-		'js' => 'application/javascript',
-		'pdf' => 'application/pdf',
-		'doc' => 'application/msword',
-		'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
-		'wri' => 'application/vnd.ms-write',
-		'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
-		'mdb' => 'application/vnd.ms-access',
-		'mpp' => 'application/vnd.ms-project',
-		'swf' => 'application/x-shockwave-flash',
-		'class' => 'application/java',
-		'tar' => 'application/x-tar',
-		'zip' => 'application/zip',
-		'gz|gzip' => 'application/x-gzip',
-		'exe' => 'application/x-msdownload'
-	));
-
-	$type = false;
-	$ext = false;
-
-	foreach ($mimes as $ext_preg => $mime_match) {
-		$ext_preg = '!\.(' . $ext_preg . ')$!i';
-		if ( preg_match($ext_preg, $filename, $ext_matches) ) {
-			$type = $mime_match;
-			$ext = $ext_matches[1];
-			break;
-		}
-	}
-
-	return compact('ext', 'type');
-}
-
-?>
diff -ruN 2.0.5/wp-includes/functions.php 2.2.2/wp-includes/functions.php
--- 2.0.5/wp-includes/functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/functions.php	2007-08-01 14:14:28.000000000 -0500
@@ -1,41 +1,38 @@
 <?php
 
-require_once(dirname(__FILE__).'/functions-compat.php');
-
-if ( !function_exists('_') ) {
-	function _($string) {
-		return $string;
-	}
-}
-
-function get_profile($field, $user = false) {
-	global $wpdb;
-	if ( !$user )
-		$user = $wpdb->escape($_COOKIE[USER_COOKIE]);
-	return $wpdb->get_var("SELECT $field FROM $wpdb->users WHERE user_login = '$user'");
-}
+require_once(dirname(__FILE__).'/compat.php');
 
 function mysql2date($dateformatstring, $mysqlstring, $translate = true) {
-	global $month, $weekday, $month_abbrev, $weekday_abbrev;
+	global $wp_locale;
 	$m = $mysqlstring;
 	if ( empty($m) ) {
 		return false;
 	}
-	$i = mktime(substr($m,11,2),substr($m,14,2),substr($m,17,2),substr($m,5,2),substr($m,8,2),substr($m,0,4));
-	
+	$i = mktime( 
+		(int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ), (int) substr( $m, 17, 2 ), 
+		(int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int) substr( $m, 0, 4 ) 
+	);
+
+	if( 'U' == $dateformatstring )
+		return $i;
+
 	if ( -1 == $i || false == $i )
 		$i = 0;
 
-	if ( !empty($month) && !empty($weekday) && $translate ) {
-		$datemonth = $month[date('m', $i)];
-		$datemonth_abbrev = $month_abbrev[$datemonth];
-		$dateweekday = $weekday[date('w', $i)];
-		$dateweekday_abbrev = $weekday_abbrev[$dateweekday];
+	if ( !empty($wp_locale->month) && !empty($wp_locale->weekday) && $translate ) {
+		$datemonth = $wp_locale->get_month(date('m', $i));
+		$datemonth_abbrev = $wp_locale->get_month_abbrev($datemonth);
+		$dateweekday = $wp_locale->get_weekday(date('w', $i));
+		$dateweekday_abbrev = $wp_locale->get_weekday_abbrev($dateweekday);
+		$datemeridiem = $wp_locale->get_meridiem(date('a', $i));
+		$datemeridiem_capital = $wp_locale->get_meridiem(date('A', $i));
 		$dateformatstring = ' '.$dateformatstring;
 		$dateformatstring = preg_replace("/([^\\\])D/", "\\1".backslashit($dateweekday_abbrev), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])F/", "\\1".backslashit($datemonth), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])l/", "\\1".backslashit($dateweekday), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])M/", "\\1".backslashit($datemonth_abbrev), $dateformatstring);
+		$dateformatstring = preg_replace("/([^\\\])a/", "\\1".backslashit($datemeridiem), $dateformatstring);
+		$dateformatstring = preg_replace("/([^\\\])A/", "\\1".backslashit($datemeridiem_capital), $dateformatstring);
 
 		$dateformatstring = substr($dateformatstring, 1, strlen($dateformatstring)-1);
 	}
@@ -51,35 +48,40 @@
 	switch ($type) {
 		case 'mysql':
 			if ( $gmt ) $d = gmdate('Y-m-d H:i:s');
-			else $d = gmdate('Y-m-d H:i:s', (time() + (get_settings('gmt_offset') * 3600)));
+			else $d = gmdate('Y-m-d H:i:s', (time() + (get_option('gmt_offset') * 3600)));
 			return $d;
 			break;
 		case 'timestamp':
 			if ( $gmt ) $d = time();
-			else $d = time() + (get_settings('gmt_offset') * 3600);
+			else $d = time() + (get_option('gmt_offset') * 3600);
 			return $d;
 			break;
 	}
 }
 
 function date_i18n($dateformatstring, $unixtimestamp) {
-	global $month, $weekday, $month_abbrev, $weekday_abbrev;
+	global $wp_locale;
 	$i = $unixtimestamp;
-	if ( (!empty($month)) && (!empty($weekday)) ) {
-		$datemonth = $month[date('m', $i)];
-		$datemonth_abbrev = $month_abbrev[$datemonth];
-		$dateweekday = $weekday[date('w', $i)];
-		$dateweekday_abbrev = $weekday_abbrev[$dateweekday];
+	if ( (!empty($wp_locale->month)) && (!empty($wp_locale->weekday)) ) {
+		$datemonth = $wp_locale->get_month(date('m', $i));
+		$datemonth_abbrev = $wp_locale->get_month_abbrev($datemonth);
+		$dateweekday = $wp_locale->get_weekday(date('w', $i));
+		$dateweekday_abbrev = $wp_locale->get_weekday_abbrev($dateweekday);
+		$datemeridiem = $wp_locale->get_meridiem(date('a', $i));
+		$datemeridiem_capital = $wp_locale->get_meridiem(date('A', $i));
 		$dateformatstring = ' '.$dateformatstring;
 		$dateformatstring = preg_replace("/([^\\\])D/", "\\1".backslashit($dateweekday_abbrev), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])F/", "\\1".backslashit($datemonth), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])l/", "\\1".backslashit($dateweekday), $dateformatstring);
 		$dateformatstring = preg_replace("/([^\\\])M/", "\\1".backslashit($datemonth_abbrev), $dateformatstring);
+		$dateformatstring = preg_replace("/([^\\\])a/", "\\1".backslashit($datemeridiem), $dateformatstring);
+		$dateformatstring = preg_replace("/([^\\\])A/", "\\1".backslashit($datemeridiem_capital), $dateformatstring);
+
 		$dateformatstring = substr($dateformatstring, 1, strlen($dateformatstring)-1);
 	}
 	$j = @date($dateformatstring, $i);
 	return $j;
-	}
+}
 
 function get_weekstartend($mysqlstring, $start_of_week) {
 	$my = substr($mysqlstring,0,4);
@@ -89,13 +91,13 @@
 	$weekday = date('w',$day);
 	$i = 86400;
 
-	if ( $weekday < get_settings('start_of_week') )
-		$weekday = 7 - (get_settings('start_of_week') - $weekday);
+	if ( $weekday < get_option('start_of_week') )
+		$weekday = 7 - (get_option('start_of_week') - $weekday);
 
-	while ($weekday > get_settings('start_of_week')) {
+	while ($weekday > get_option('start_of_week')) {
 		$weekday = date('w',$day);
-		if ( $weekday < get_settings('start_of_week') )
-			$weekday = 7 - (get_settings('start_of_week') - $weekday);
+		if ( $weekday < get_option('start_of_week') )
+			$weekday = 7 - (get_option('start_of_week') - $weekday);
 
 		$day = $day - 86400;
 		$i = 0;
@@ -107,160 +109,55 @@
 }
 
 function get_lastpostdate($timezone = 'server') {
-	global $cache_lastpostdate, $pagenow, $wpdb;
-	$add_seconds_blog = get_settings('gmt_offset') * 3600;
+	global $cache_lastpostdate, $pagenow, $wpdb, $blog_id;
+	$add_seconds_blog = get_option('gmt_offset') * 3600;
 	$add_seconds_server = date('Z');
-	$now = current_time('mysql', 1);
-	if ( !isset($cache_lastpostdate[$timezone]) ) {
+	if ( !isset($cache_lastpostdate[$blog_id][$timezone]) ) {
 		switch(strtolower($timezone)) {
 			case 'gmt':
-				$lastpostdate = $wpdb->get_var("SELECT post_date_gmt FROM $wpdb->posts WHERE post_date_gmt <= '$now' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
+				$lastpostdate = $wpdb->get_var("SELECT post_date_gmt FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
 				break;
 			case 'blog':
-				$lastpostdate = $wpdb->get_var("SELECT post_date FROM $wpdb->posts WHERE post_date_gmt <= '$now' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
+				$lastpostdate = $wpdb->get_var("SELECT post_date FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
 				break;
 			case 'server':
-				$lastpostdate = $wpdb->get_var("SELECT DATE_ADD(post_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_date_gmt <= '$now' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
+				$lastpostdate = $wpdb->get_var("SELECT DATE_ADD(post_date_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT 1");
 				break;
 		}
-		$cache_lastpostdate[$timezone] = $lastpostdate;
+		$cache_lastpostdate[$blog_id][$timezone] = $lastpostdate;
 	} else {
-		$lastpostdate = $cache_lastpostdate[$timezone];
+		$lastpostdate = $cache_lastpostdate[$blog_id][$timezone];
 	}
 	return $lastpostdate;
 }
 
 function get_lastpostmodified($timezone = 'server') {
-	global $cache_lastpostmodified, $pagenow, $wpdb;
-	$add_seconds_blog = get_settings('gmt_offset') * 3600;
+	global $cache_lastpostmodified, $pagenow, $wpdb, $blog_id;
+	$add_seconds_blog = get_option('gmt_offset') * 3600;
 	$add_seconds_server = date('Z');
-	$now = current_time('mysql', 1);
-	if ( !isset($cache_lastpostmodified[$timezone]) ) {
+	if ( !isset($cache_lastpostmodified[$blog_id][$timezone]) ) {
 		switch(strtolower($timezone)) {
 			case 'gmt':
-				$lastpostmodified = $wpdb->get_var("SELECT post_modified_gmt FROM $wpdb->posts WHERE post_modified_gmt <= '$now' AND post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
+				$lastpostmodified = $wpdb->get_var("SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
 				break;
 			case 'blog':
-				$lastpostmodified = $wpdb->get_var("SELECT post_modified FROM $wpdb->posts WHERE post_modified_gmt <= '$now' AND post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
+				$lastpostmodified = $wpdb->get_var("SELECT post_modified FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
 				break;
 			case 'server':
-				$lastpostmodified = $wpdb->get_var("SELECT DATE_ADD(post_modified_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_modified_gmt <= '$now' AND post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
+				$lastpostmodified = $wpdb->get_var("SELECT DATE_ADD(post_modified_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_modified_gmt DESC LIMIT 1");
 				break;
 		}
 		$lastpostdate = get_lastpostdate($timezone);
 		if ( $lastpostdate > $lastpostmodified ) {
 			$lastpostmodified = $lastpostdate;
 		}
-		$cache_lastpostmodified[$timezone] = $lastpostmodified;
+		$cache_lastpostmodified[$blog_id][$timezone] = $lastpostmodified;
 	} else {
-		$lastpostmodified = $cache_lastpostmodified[$timezone];
+		$lastpostmodified = $cache_lastpostmodified[$blog_id][$timezone];
 	}
 	return $lastpostmodified;
 }
 
-function user_pass_ok($user_login,$user_pass) {
-	global $cache_userdata;
-	if ( empty($cache_userdata[$user_login]) ) {
-		$userdata = get_userdatabylogin($user_login);
-	} else {
-		$userdata = $cache_userdata[$user_login];
-	}
-	return (md5($user_pass) == $userdata->user_pass);
-}
-
-
-function get_usernumposts($userid) {
-	global $wpdb;
-	return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = '$userid' AND post_status = 'publish'");
-}
-
-
-// examine a url (supposedly from this blog) and try to
-// determine the post ID it represents.
-function url_to_postid($url) {
-	global $wp_rewrite;
-
-	// First, check to see if there is a 'p=N' or 'page_id=N' to match against
-	preg_match('#[?&](p|page_id)=(\d+)#', $url, $values);
-	$id = intval($values[2]);
-	if ( $id ) return $id;
-
-	// Check to see if we are using rewrite rules
-	$rewrite = $wp_rewrite->wp_rewrite_rules();
-
-	// Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options
-	if ( empty($rewrite) )
-		return 0;
-
-	// $url cleanup by Mark Jaquith
-	// This fixes things like #anchors, ?query=strings, missing 'www.',
-	// added 'www.', or added 'index.php/' that will mess up our WP_Query
-	// and return a false negative
-
-	// Get rid of the #anchor
-	$url_split = explode('#', $url);
-	$url = $url_split[0];
-
-	// Get rid of URI ?query=string
-	$url_split = explode('?', $url);
-	$url = $url_split[0];
-
-	// Add 'www.' if it is absent and should be there
-	if ( false !== strpos(get_settings('home'), '://www.') && false === strpos($url, '://www.') )
-		$url = str_replace('://', '://www.', $url);
-
-	// Strip 'www.' if it is present and shouldn't be
-	if ( false === strpos(get_settings('home'), '://www.') )
-		$url = str_replace('://www.', '://', $url);
-
-	// Strip 'index.php/' if we're not using path info permalinks
-	if ( false === strpos($rewrite, 'index.php/') )
-		$url = str_replace('index.php/', '', $url);
-
-	if ( false !== strpos($url, get_settings('home')) ) {
-		// Chop off http://domain.com
-		$url = str_replace(get_settings('home'), '', $url);
-	} else {
-		// Chop off /path/to/blog
-		$home_path = parse_url(get_settings('home'));
-		$home_path = $home_path['path'];
-		$url = str_replace($home_path, '', $url);
-	}
-
-	// Trim leading and lagging slashes
-	$url = trim($url, '/');
-
-	$request = $url;
-
-	// Done with cleanup
-
-	// Look for matches.
-	$request_match = $request;
-	foreach ($rewrite as $match => $query) {
-		// If the requesting file is the anchor of the match, prepend it
-		// to the path info.
-		if ( (! empty($url)) && (strpos($match, $url) === 0) ) {
-			$request_match = $url . '/' . $request;
-		}
-
-		if ( preg_match("!^$match!", $request_match, $matches) ) {
-			// Got a match.
-			// Trim the query of everything up to the '?'.
-			$query = preg_replace("!^.+\?!", '', $query);
-
-			// Substitute the substring matches into the query.
-			eval("\$query = \"$query\";");
-			$query = new WP_Query($query);
-			if ( $query->is_single || $query->is_page )
-				return $query->post->ID;
-			else
-				return 0;
-		}
-	}
-	return 0;
-}
-
-
 function maybe_unserialize($original) {
 	if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in
 		if ( false !== $gm = @ unserialize($original) )
@@ -268,59 +165,86 @@
 	return $original;
 }
 
-function maybe_serialize($data) {
-	if ( is_string($data) )
-		$data = trim($data);
-	elseif ( is_array($data) || is_object($data) )
-		return serialize($data);
-	if ( is_serialized($data) )
-		return serialize($data);
-	return $data;
-}
-
 function is_serialized($data) {
-	if ( !is_string($data) ) // if it isn't a string, it isn't serialized
+	// if it isn't a string, it isn't serialized
+	if ( !is_string($data) )
 		return false;
 	$data = trim($data);
-	if ( preg_match("/^[adobis]:[0-9]+:.*[;}]/si",$data) ) // this should fetch all legitimately serialized data
+	if ( 'N;' == $data )
 		return true;
+	if ( !preg_match('/^([adObis]):/', $data, $badions) )
+		return false;
+	switch ( $badions[1] ) :
+	case 'a' :
+	case 'O' :
+	case 's' :
+		if ( preg_match("/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data) )
+			return true;
+		break;
+	case 'b' :
+	case 'i' :
+	case 'd' :
+		if ( preg_match("/^{$badions[1]}:[0-9.E-]+;\$/", $data) )
+			return true;
+		break;
+	endswitch;
 	return false;
 }
 
 function is_serialized_string($data) {
-	if ( !is_string($data) ) // if it isn't a string, it isn't a serialized string
+	// if it isn't a string, it isn't a serialized string
+	if ( !is_string($data) )
 		return false;
 	$data = trim($data);
-	if ( preg_match("/^s:[0-9]+:.*[;}]/si",$data) ) // this should fetch all serialized strings
+	if ( preg_match('/^s:[0-9]+:.*;$/s',$data) ) // this should fetch all serialized strings
 		return true;
 	return false;
 }
 
 /* Options functions */
 
-function get_settings($setting) {
+// expects $setting to already be SQL-escaped
+function get_option($setting) {
 	global $wpdb;
 
-	$value = wp_cache_get($setting, 'options');
+	// Allow plugins to short-circuit options.
+	$pre = apply_filters( 'pre_option_' . $setting, false ); 
+	if ( $pre ) 
+		return $pre; 
+
+	// prevent non-existent options from triggering multiple queries
+	$notoptions = wp_cache_get('notoptions', 'options');
+	if ( isset($notoptions[$setting]) )
+		return false;
 
-	if ( false === $value ) {
-		if ( defined('WP_INSTALLING') )
-			$wpdb->hide_errors();
-		$row = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1");
-		if ( defined('WP_INSTALLING') )
-			$wpdb->show_errors();
-
-		if( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values
-			$value = $row->option_value;
-			wp_cache_set($setting, $value, 'options');
-		} else {
-			return false;
+	$alloptions = wp_load_alloptions();
+
+	if ( isset($alloptions[$setting]) ) {
+		$value = $alloptions[$setting];
+	} else {
+		$value = wp_cache_get($setting, 'options');
+
+		if ( false === $value ) {
+			if ( defined('WP_INSTALLING') )
+				$wpdb->hide_errors();
+			$row = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1");
+			if ( defined('WP_INSTALLING') )
+				$wpdb->show_errors();
+
+			if( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values
+				$value = $row->option_value;
+				wp_cache_add($setting, $value, 'options');
+			} else { // option does not exist, so we must cache its non-existence
+				$notoptions[$setting] = true;
+				wp_cache_set('notoptions', $notoptions, 'options');
+				return false;
+			}
 		}
 	}
 
 	// If home is not set use siteurl.
 	if ( 'home' == $setting && '' == $value )
-		return get_settings('siteurl');
+		return get_option('siteurl');
 
 	if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting )
 		$value = preg_replace('|/+$|', '', $value);
@@ -328,28 +252,14 @@
 	return apply_filters( 'option_' . $setting, maybe_unserialize($value) );
 }
 
-function get_option($option) {
-	return get_settings($option);
-}
-
-function get_user_option( $option, $user = 0 ) {
-	global $wpdb;
-	
-	if ( empty($user) )
-		$user = wp_get_current_user();
-	else
-		$user = get_userdata($user);
-
-	if ( isset( $user->{$wpdb->prefix . $option} ) ) // Blog specific
-		return $user->{$wpdb->prefix . $option};
-	elseif ( isset( $user->{$option} ) ) // User specific and cross-blog
-		return $user->{$option};
-	else // Blog global
-		return get_option( $option );
+function wp_protect_special_option($option) {
+	$protected = array('alloptions', 'notoptions');
+	if ( in_array($option, $protected) )
+		die(sprintf(__('%s is a protected WP option and may not be modified'), wp_specialchars($option)));
 }
 
 function form_option($option) {
-	echo wp_specialchars( get_option($option), 1 );
+	echo attribute_escape(get_option($option));
 }
 
 function get_alloptions() {
@@ -375,15 +285,38 @@
 	return apply_filters('all_options', $all_options);
 }
 
+function wp_load_alloptions() {
+	global $wpdb;
+
+	$alloptions = wp_cache_get('alloptions', 'options');
+
+	if ( !$alloptions ) {
+		$wpdb->hide_errors();
+		if ( !$alloptions_db = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'") )
+			$alloptions_db = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options");
+		$wpdb->show_errors();
+		$alloptions = array();
+		foreach ( (array) $alloptions_db as $o )
+			$alloptions[$o->option_name] = $o->option_value;
+		wp_cache_add('alloptions', $alloptions, 'options');
+	}
+	return $alloptions;
+}
+
+// expects $option_name to NOT be SQL-escaped
 function update_option($option_name, $newvalue) {
 	global $wpdb;
 
+	wp_protect_special_option($option_name);
+
+	$safe_option_name = $wpdb->escape($option_name);
+
 	if ( is_string($newvalue) )
 		$newvalue = trim($newvalue);
 
 	// If the new and old values are the same, no need to update.
-	$oldvalue = get_option($option_name);
-	if ( $newvalue == $oldvalue ) {
+	$oldvalue = get_option($safe_option_name);
+	if ( $newvalue === $oldvalue ) {
 		return false;
 	}
 
@@ -392,39 +325,64 @@
 		return true;
 	}
 
+	$notoptions = wp_cache_get('notoptions', 'options');
+	if ( is_array($notoptions) && isset($notoptions[$option_name]) ) {
+		unset($notoptions[$option_name]);
+		wp_cache_set('notoptions', $notoptions, 'options');
+	}
+
 	$_newvalue = $newvalue;
 	$newvalue = maybe_serialize($newvalue);
 
-	wp_cache_set($option_name, $newvalue, 'options');
+	$alloptions = wp_load_alloptions();
+	if ( isset($alloptions[$option_name]) ) {
+		$alloptions[$option_name] = $newvalue;
+		wp_cache_set('alloptions', $alloptions, 'options');
+	} else {
+		wp_cache_set($option_name, $newvalue, 'options');
+	}
 
 	$newvalue = $wpdb->escape($newvalue);
 	$option_name = $wpdb->escape($option_name);
 	$wpdb->query("UPDATE $wpdb->options SET option_value = '$newvalue' WHERE option_name = '$option_name'");
 	if ( $wpdb->rows_affected == 1 ) {
-		do_action("update_option_{$option_name}", array('old'=>$oldvalue, 'new'=>$_newvalue));
+		do_action("update_option_{$option_name}", $oldvalue, $_newvalue);
 		return true;
 	}
 	return false;
 }
 
-function update_user_option( $user_id, $option_name, $newvalue, $global = false ) {
-	global $wpdb;
-	if ( !$global )
-		$option_name = $wpdb->prefix . $option_name;
-	return update_usermeta( $user_id, $option_name, $newvalue );
-}
-
 // thx Alex Stapleton, http://alex.vort-x.net/blog/
+// expects $name to NOT be SQL-escaped
 function add_option($name, $value = '', $description = '', $autoload = 'yes') {
 	global $wpdb;
 
-	// Make sure the option doesn't already exist
-	if ( false !== get_option($name) )
-		return;
+	wp_protect_special_option($name);
+	$safe_name = $wpdb->escape($name);
+
+	// Make sure the option doesn't already exist. We can check the 'notoptions' cache before we ask for a db query
+	$notoptions = wp_cache_get('notoptions', 'options');
+	if ( !is_array($notoptions) || !isset($notoptions[$name]) )
+		if ( false !== get_option($safe_name) )
+			return;
 
 	$value = maybe_serialize($value);
+	$autoload = ( 'no' === $autoload ) ? 'no' : 'yes';
+
+	if ( 'yes' == $autoload ) {
+		$alloptions = wp_load_alloptions();
+		$alloptions[$name] = $value;
+		wp_cache_set('alloptions', $alloptions, 'options');
+	} else {
+		wp_cache_set($name, $value, 'options');
+	}
 
-	wp_cache_set($name, $value, 'options');
+	// This option exists now
+	$notoptions = wp_cache_get('notoptions', 'options'); // yes, again... we need it to be fresh
+	if ( is_array($notoptions) && isset($notoptions[$name]) ) {
+		unset($notoptions[$name]);
+		wp_cache_set('notoptions', $notoptions, 'options');
+	}
 
 	$name = $wpdb->escape($name);
 	$value = $wpdb->escape($value);
@@ -436,517 +394,43 @@
 
 function delete_option($name) {
 	global $wpdb;
-	// Get the ID, if no ID then return
-	$option_id = $wpdb->get_var("SELECT option_id FROM $wpdb->options WHERE option_name = '$name'");
-	if ( !$option_id ) return false;
-	$wpdb->query("DELETE FROM $wpdb->options WHERE option_name = '$name'");
-	wp_cache_delete($name, 'options');
-	return true;
-}
-
-function add_post_meta($post_id, $key, $value, $unique = false) {
-	global $wpdb, $post_meta_cache;
-
-	$post_id = (int) $post_id;
-
-	if ( $unique ) {
-		if ( $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
-			return false;
-		}
-	}
-
-	$post_meta_cache[$post_id][$key][] = $value;
-
-	$value = maybe_serialize($value);
-	$value = $wpdb->escape($value);
-
-	$wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
-
-	return true;
-}
 
-function delete_post_meta($post_id, $key, $value = '') {
-	global $wpdb, $post_meta_cache;
+	wp_protect_special_option($name);
 
-	$post_id = (int) $post_id;
-
-	if ( empty($value) ) {
-		$meta_id = $wpdb->get_var("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'");
-	} else {
-		$meta_id = $wpdb->get_var("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key' AND meta_value = '$value'");
-	}
-
-	if ( !$meta_id )
-		return false;
-
-	if ( empty($value) ) {
-		$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'");
-		unset($post_meta_cache[$post_id][$key]);
-	} else {
-		$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key' AND meta_value = '$value'");
-		$cache_key = $post_meta_cache[$post_id][$key];
-		if ($cache_key) foreach ( $cache_key as $index => $data )
-			if ( $data == $value )
-				unset($post_meta_cache[$post_id][$key][$index]);
-	}
-
-	unset($post_meta_cache[$post_id][$key]);
-
-	return true;
-}
-
-function get_post_meta($post_id, $key, $single = false) {
-	global $wpdb, $post_meta_cache;
-
-	$post_id = (int) $post_id;
-
-	if ( isset($post_meta_cache[$post_id][$key]) ) {
-		if ( $single ) {
-			return maybe_unserialize( $post_meta_cache[$post_id][$key][0] );
-		} else {
-			return maybe_unserialize( $post_meta_cache[$post_id][$key] );
-		}
-	}
-
-	$metalist = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'", ARRAY_N);
-
-	$values = array();
-	if ( $metalist ) {
-		foreach ($metalist as $metarow) {
-			$values[] = $metarow[0];
-		}
-	}
-
-	if ( $single ) {
-		if ( count($values) ) {
-			$return = maybe_unserialize( $values[0] );
-		} else {
-			return '';
+	// Get the ID, if no ID then return
+	$option = $wpdb->get_row("SELECT option_id, autoload FROM $wpdb->options WHERE option_name = '$name'");
+	if ( !$option->option_id ) return false;
+	$wpdb->query("DELETE FROM $wpdb->options WHERE option_name = '$name'");
+	if ( 'yes' == $option->autoload ) {
+		$alloptions = wp_load_alloptions();
+		if ( isset($alloptions[$name]) ) {
+			unset($alloptions[$name]);
+			wp_cache_set('alloptions', $alloptions, 'options');
 		}
 	} else {
-		$return = $values;
-	}
-
-	return maybe_unserialize($return);
-}
-
-function update_post_meta($post_id, $key, $value, $prev_value = '') {
-	global $wpdb, $post_meta_cache;
-
-	$post_id = (int) $post_id;
-
-	$original_value = $value;
-	$value = maybe_serialize($value);
-	$value = $wpdb->escape($value);
-
-	$original_prev = $prev_value;
-	$prev_value = maybe_serialize($prev_value);
-	$prev_value = $wpdb->escape($prev_value);
-
-	if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
-		return false;
+		wp_cache_delete($name, 'options');
 	}
-
-	if ( empty($prev_value) ) {
-		$wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '$value' WHERE meta_key = '$key' AND post_id = '$post_id'");
-		$cache_key = $post_meta_cache[$post_id][$key];
-		if ( !empty($cache_key) )
-			foreach ($cache_key as $index => $data)
-				$post_meta_cache[$post_id][$key][$index] = $original_value;
-	} else {
-		$wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '$value' WHERE meta_key = '$key' AND post_id = '$post_id' AND meta_value = '$prev_value'");
-		$cache_key = $post_meta_cache[$post_id][$key];
-		if ( !empty($cache_key) )
-			foreach ($cache_key as $index => $data)
-				if ( $data == $original_prev )
-					$post_meta_cache[$post_id][$key][$index] = $original_value;
-	}
-
 	return true;
 }
 
-// Deprecated.  Use get_post().
-function get_postdata($postid) {
-	$post = &get_post($postid);
-
-	$postdata = array (
-		'ID' => $post->ID,
-		'Author_ID' => $post->post_author,
-		'Date' => $post->post_date,
-		'Content' => $post->post_content,
-		'Excerpt' => $post->post_excerpt,
-		'Title' => $post->post_title,
-		'Category' => $post->post_category,
-		'post_status' => $post->post_status,
-		'comment_status' => $post->comment_status,
-		'ping_status' => $post->ping_status,
-		'post_password' => $post->post_password,
-		'to_ping' => $post->to_ping,
-		'pinged' => $post->pinged,
-		'post_name' => $post->post_name
-	);
-
-	return $postdata;
-}
-
-// Retrieves post data given a post ID or post object.
-// Handles post caching.
-function &get_post(&$post, $output = OBJECT) {
-	global $post_cache, $wpdb;
-
-	if ( empty($post) ) {
-		if ( isset($GLOBALS['post']) )
-			$_post = & $GLOBALS['post'];
-		else
-			$_post = null;
-	} elseif ( is_object($post) ) {
-		if ( 'static' == $post->post_status )
-			return get_page($post, $output);
-		if ( !isset($post_cache[$post->ID]) )
-			$post_cache[$post->ID] = &$post;
-		$_post = & $post_cache[$post->ID];
-	} else {
-		if ( $_post = wp_cache_get($post, 'pages') )
-			return get_page($_post, $output);
-		elseif ( isset($post_cache[$post]) )
-			$_post = & $post_cache[$post];
-		else {
-			$query = "SELECT * FROM $wpdb->posts WHERE ID = '$post' LIMIT 1";
-			$_post = & $wpdb->get_row($query);
-			if ( 'static' == $_post->post_status )
-				return get_page($_post, $output);
-			$post_cache[$post] = & $_post;
-		}
-	}
-
-	if ( defined(WP_IMPORTING) )
-		unset($post_cache);
-
-	if ( $output == OBJECT ) {
-		return $_post;
-	} elseif ( $output == ARRAY_A ) {
-		return get_object_vars($_post);
-	} elseif ( $output == ARRAY_N ) {
-		return array_values(get_object_vars($_post));
-	} else {
-		return $_post;
-	}
-}
-
-function &get_children($post = 0, $output = OBJECT) {
-	global $post_cache, $wpdb;
-
-	if ( empty($post) ) {
-		if ( isset($GLOBALS['post']) )
-			$post_parent = & $GLOBALS['post']->post_parent;
-		else
-			return false;
-	} elseif ( is_object($post) ) {
-		$post_parent = $post->post_parent;
-	} else {
-		$post_parent = $post;
-	}
-
-	$post_parent = (int) $post_parent;
-
-	$query = "SELECT * FROM $wpdb->posts WHERE post_parent = $post_parent";
-
-	$children = $wpdb->get_results($query);
-
-	if ( $children ) {
-		foreach ( $children as $key => $child ) {
-			$post_cache[$child->ID] =& $children[$key];
-			$kids[$child->ID] =& $children[$key];
-		}
-	} else {
-		return false;
-	}
-
-	if ( $output == OBJECT ) {
-		return $kids;
-	} elseif ( $output == ARRAY_A ) {
-		foreach ( $kids as $kid )
-			$weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]);
-		return $weeuns;
-	} elseif ( $output == ARRAY_N ) {
-		foreach ( $kids as $kid )
-			$babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID]));
-		return $babes;
-	} else {
-		return $kids;
-	}
-}
-
-function set_page_path($page) {
-	$page->fullpath = '/' . $page->post_name;
-	$path = $page->fullpath;
-	$curpage = $page;
-	while ($curpage->post_parent != 0) {
-		$curpage = get_page($curpage->post_parent);
-		$path = '/' . $curpage->post_name . $path;
-	}
-	
-	$page->fullpath = $path;
-
-	return $page;
-}
-
-// Retrieves page data given a page ID or page object.
-// Handles page caching.
-function &get_page(&$page, $output = OBJECT) {
-	global $wpdb;
-
-	if ( empty($page) ) {
-		if ( isset($GLOBALS['page']) ) {
-			$_page = & $GLOBALS['page'];
-			wp_cache_add($_page->ID, $_page, 'pages');
-		} else {
-			$_page = null;
-		}
-	} elseif ( is_object($page) ) {
-		if ( 'static' != $page->post_status )
-			return get_post($page, $output);
-		wp_cache_add($page->ID, $page, 'pages');
-		$_page = $page;
-	} else {
-		if ( isset($GLOBALS['page']) && ($page == $GLOBALS['page']->ID) ) {
-			$_page = & $GLOBALS['page'];
-			wp_cache_add($_page->ID, $_page, 'pages');
-		} elseif ( $_page = $GLOBALS['post_cache'][$page] ) {
-			return get_post($page, $output);
-		} elseif ( $_page = wp_cache_get($page, 'pages') ) {
-			// Got it.
-		} else {
-			$query = "SELECT * FROM $wpdb->posts WHERE ID= '$page' LIMIT 1";
-			$_page = & $wpdb->get_row($query);
-			if ( 'static' != $_page->post_status )
-				return get_post($_page, $output);
-			wp_cache_add($_page->ID, $_page, 'pages');
-		}
-	}
-	
-	if (!isset($_page->fullpath)) {
-		$_page = set_page_path($_page);
-		wp_cache_replace($_page->cat_ID, $_page, 'pages');
-	}
-
-	if ( $output == OBJECT ) {
-		return $_page;
-	} elseif ( $output == ARRAY_A ) {
-		return get_object_vars($_page);
-	} elseif ( $output == ARRAY_N ) {
-		return array_values(get_object_vars($_page));
-	} else {
-		return $_page;
-	}
-}
-
-function set_category_path($cat) {
-	$cat->fullpath = '/' . $cat->category_nicename;
-	$path = $cat->fullpath;
-	$curcat = $cat;
-	while ($curcat->category_parent != 0) {
-		$curcat = get_category($curcat->category_parent);
-		$path = '/' . $curcat->category_nicename . $path;
-	}
-	
-	$cat->fullpath = $path;
-
-	return $cat;
-}
-
-// Retrieves category data given a category ID or category object.
-// Handles category caching.
-function &get_category(&$category, $output = OBJECT) {
-	global $wpdb;
-
-	if ( empty($category) )
-		return null;
-
-	if ( is_object($category) ) {
-		wp_cache_add($category->cat_ID, $category, 'category');
-		$_category = $category;
-	} else {
-		if ( ! $_category = wp_cache_get($category, 'category') ) {
-			$_category = $wpdb->get_row("SELECT * FROM $wpdb->categories WHERE cat_ID = '$category' LIMIT 1");
-			wp_cache_add($category, $_category, 'category');
-		}
-	}
-
-	$_category = apply_filters('get_category', $_category);
-
-	if ( !isset($_category->fullpath) ) {
-		$_category = set_category_path($_category);
-		wp_cache_replace($_category->cat_ID, $_category, 'category');	
-	}
-
-	if ( $output == OBJECT ) {
-		return $_category;
-	} elseif ( $output == ARRAY_A ) {
-		return get_object_vars($_category);
-	} elseif ( $output == ARRAY_N ) {
-		return array_values(get_object_vars($_category));
-	} else {
-		return $_category;
-	}
-}
-
-// Retrieves comment data given a comment ID or comment object.
-// Handles comment caching.
-function &get_comment(&$comment, $output = OBJECT) {
-	global $comment_cache, $wpdb;
-
-	if ( empty($comment) )
-		return null;
-
-	if ( is_object($comment) ) {
-		if ( !isset($comment_cache[$comment->comment_ID]) )
-			$comment_cache[$comment->comment_ID] = &$comment;
-		$_comment = & $comment_cache[$comment->comment_ID];
-	} else {
-		if ( !isset($comment_cache[$comment]) ) {
-			$_comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment' LIMIT 1");
-			$comment_cache[$comment->comment_ID] = & $_comment;
-		} else {
-			$_comment = & $comment_cache[$comment];
-		}
-	}
-
-	if ( $output == OBJECT ) {
-		return $_comment;
-	} elseif ( $output == ARRAY_A ) {
-		return get_object_vars($_comment);
-	} elseif ( $output == ARRAY_N ) {
-		return array_values(get_object_vars($_comment));
-	} else {
-		return $_comment;
-	}
-}
-
-function get_catname($cat_ID) {
-	$category = &get_category($cat_ID);
-	return $category->cat_name;
-}
-
-function get_all_category_ids() {
-	global $wpdb;
-	
-	if ( ! $cat_ids = wp_cache_get('all_category_ids', 'category') ) {
-		$cat_ids = $wpdb->get_col("SELECT cat_ID FROM $wpdb->categories");
-		wp_cache_add('all_category_ids', $cat_ids, 'category');
-	}
-	
-	return $cat_ids;
-}
-
-function get_all_page_ids() {
-	global $wpdb;
-	
-	if ( ! $page_ids = wp_cache_get('all_page_ids', 'pages') ) {
-		$page_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_status='static'");
-		wp_cache_add('all_page_ids', $page_ids, 'pages');
-	}
-	
-	return $page_ids;
+function maybe_serialize($data) {
+	if ( is_string($data) )
+		$data = trim($data);
+	elseif ( is_array($data) || is_object($data) )
+		return serialize($data);
+	if ( is_serialized($data) )
+		return serialize($data);
+	return $data;
 }
 
 function gzip_compression() {
-	if ( !get_settings('gzipcompression') ) return false;
+	if ( !get_option('gzipcompression') ) return false;
 
 	if ( extension_loaded('zlib') ) {
 		ob_start('ob_gzhandler');
 	}
 }
 
-
-// functions to count the page generation time (from phpBB2)
-// ( or just any time between timer_start() and timer_stop() )
-
-function timer_stop($display = 0, $precision = 3) { //if called like timer_stop(1), will echo $timetotal
-	global $timestart, $timeend;
-	$mtime = microtime();
-	$mtime = explode(' ',$mtime);
-	$mtime = $mtime[1] + $mtime[0];
-	$timeend = $mtime;
-	$timetotal = $timeend-$timestart;
-	$r = number_format($timetotal, $precision);
-	if ( $display )
-		echo $r;
-	return $r;
-}
-
-function weblog_ping($server = '', $path = '') {
-	global $wp_version;
-	include_once (ABSPATH . WPINC . '/class-IXR.php');
-
-	// using a timeout of 3 seconds should be enough to cover slow servers
-	$client = new IXR_Client($server, ((!strlen(trim($path)) || ('/' == $path)) ? false : $path));
-	$client->timeout = 3;
-	$client->useragent .= ' -- WordPress/'.$wp_version;
-
-	// when set to true, this outputs debug messages by itself
-	$client->debug = false;
-	$home = trailingslashit( get_option('home') );
-	if ( !$client->query('weblogUpdates.extendedPing', get_settings('blogname'), $home, get_bloginfo('rss2_url') ) ) // then try a normal ping
-		$client->query('weblogUpdates.ping', get_settings('blogname'), $home);
-}
-
-function generic_ping($post_id = 0) {
-	$services = get_settings('ping_sites');
-	$services = preg_replace("|(\s)+|", '$1', $services); // Kill dupe lines
-	$services = trim($services);
-	if ( '' != $services ) {
-		$services = explode("\n", $services);
-		foreach ($services as $service) {
-			weblog_ping($service);
-		}
-	}
-
-	return $post_id;
-}
-
-// Send a Trackback
-function trackback($trackback_url, $title, $excerpt, $ID) {
-	global $wpdb, $wp_version;
-
-	if ( empty($trackback_url) )
-		return;
-
-	$title = urlencode($title);
-	$excerpt = urlencode($excerpt);
-	$blog_name = urlencode(get_settings('blogname'));
-	$tb_url = $trackback_url;
-	$url = urlencode(get_permalink($ID));
-	$query_string = "title=$title&url=$url&blog_name=$blog_name&excerpt=$excerpt";
-	$trackback_url = parse_url($trackback_url);
-	$http_request = 'POST ' . $trackback_url['path'] . ($trackback_url['query'] ? '?'.$trackback_url['query'] : '') . " HTTP/1.0\r\n";
-	$http_request .= 'Host: '.$trackback_url['host']."\r\n";
-	$http_request .= 'Content-Type: application/x-www-form-urlencoded; charset='.get_settings('blog_charset')."\r\n";
-	$http_request .= 'Content-Length: '.strlen($query_string)."\r\n";
-	$http_request .= "User-Agent: WordPress/" . $wp_version;
-	$http_request .= "\r\n\r\n";
-	$http_request .= $query_string;
-	if ( '' == $trackback_url['port'] )
-		$trackback_url['port'] = 80;
-	$fs = @fsockopen($trackback_url['host'], $trackback_url['port'], $errno, $errstr, 4);
-	@fputs($fs, $http_request);
-/*
-	$debug_file = 'trackback.log';
-	$fp = fopen($debug_file, 'a');
-	fwrite($fp, "\n*****\nRequest:\n\n$http_request\n\nResponse:\n\n");
-	while(!@feof($fs)) {
-		fwrite($fp, @fgets($fs, 4096));
-	}
-	fwrite($fp, "\n\n");
-	fclose($fp);
-*/
-	@fclose($fs);
-
-	$tb_url = addslashes( $tb_url );
-	$wpdb->query("UPDATE $wpdb->posts SET pinged = CONCAT(pinged, '\n', '$tb_url') WHERE ID = '$ID'");
-	return $wpdb->query("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '$tb_url', '')) WHERE ID = '$ID'");
-}
-
 function make_url_footnote($content) {
 	preg_match_all('/<a(.+?)href=\"(.+?)\"(.*?)>(.+?)<\/a>/', $content, $matches);
 	$j = 0;
@@ -958,7 +442,7 @@
 		$link_url = $matches[2][$i];
 		$link_text = $matches[4][$i];
 		$content = str_replace($link_match, $link_text.' '.$link_number, $content);
-		$link_url = ((strtolower(substr($link_url,0,7)) != 'http://') && (strtolower(substr($link_url,0,8)) != 'https://')) ? get_settings('home') . $link_url : $link_url;
+		$link_url = ((strtolower(substr($link_url,0,7)) != 'http://') && (strtolower(substr($link_url,0,8)) != 'https://')) ? get_option('home') . $link_url : $link_url;
 		$links_summary .= "\n".$link_number.' '.$link_url;
 	}
 	$content = strip_tags($content);
@@ -1021,27 +505,6 @@
 	}
 }
 
-function spawn_pinger() {
-	global $wpdb, $wp_version;
-	$doping = false;
-	if ( $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE TRIM(to_ping) != '' LIMIT 1") )
-		$doping = true;
-
-	if ( $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pingme' OR meta_key = '_encloseme' LIMIT 1") )
-		$doping = true;
-
-	if ( substr(php_sapi_name(), 0, 3) == 'cgi' )
-		return $doping;
-
-	if ( $doping ) {
-		$ping_url = get_settings('siteurl') .'/wp-admin/execute-pings.php';
-		$parts = parse_url($ping_url);
-		$argyle = @ fsockopen($parts['host'], $_SERVER['SERVER_PORT'], $errno, $errstr, 0.01);
-		if ( $argyle )
-			fputs($argyle, "GET {$parts['path']}?time=".time()." HTTP/1.0\r\nHost: {$_SERVER['HTTP_HOST']}\r\nUser-Agent: WordPress/{$wp_version}\r\n\r\n");
-       }
-}
-
 function do_enclose( $content, $post_ID ) {
 	global $wp_version, $wpdb;
 	include_once (ABSPATH . WPINC . '/class-IXR.php');
@@ -1093,7 +556,7 @@
 	@set_time_limit( 60 );
 
 	if ( $red > 5 )
-	   return false;
+		 return false;
 
 	$parts = parse_url( $url );
 	$file = $parts['path'] . ($parts['query'] ? '?'.$parts['query'] : '');
@@ -1122,79 +585,13 @@
 	preg_match('/.*([0-9]{3}).*/', $response, $return);
 	$headers['response'] = $return[1]; // HTTP response code eg 204, 200, 404
 
-    $code = $headers['response'];
-    if ( ('302' == $code || '301' == $code) && isset($headers['location']) )
-        return wp_get_http_headers( $headers['location'], ++$red );
+		$code = $headers['response'];
+		if ( ('302' == $code || '301' == $code) && isset($headers['location']) )
+				return wp_get_http_headers( $headers['location'], ++$red );
 
 	return $headers;
 }
 
-// Deprecated.  Use the new post loop.
-function start_wp() {
-	global $wp_query, $post;
-
-	// Since the old style loop is being used, advance the query iterator here.
-	$wp_query->next_post();
-
-	setup_postdata($post);
-}
-
-// Setup global post data.
-function setup_postdata($post) {
-	global $id, $postdata, $authordata, $day, $page, $pages, $multipage, $more, $numpages, $wp_query;
-	global $pagenow;
-
-	$id = $post->ID;
-
-	$authordata = get_userdata($post->post_author);
-
-	$day = mysql2date('d.m.y', $post->post_date);
-	$currentmonth = mysql2date('m', $post->post_date);
-	$numpages = 1;
-	$page = get_query_var('page');
-	if ( !$page )
-		$page = 1;
-	if ( is_single() || is_page() )
-		$more = 1;
-	$content = $post->post_content;
-	if ( preg_match('/<!--nextpage-->/', $content) ) {
-		if ( $page > 1 )
-			$more = 1;
-		$multipage = 1;
-		$content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
-		$content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
-		$content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
-		$pages = explode('<!--nextpage-->', $content);
-		$numpages = count($pages);
-	} else {
-		$pages[0] = $post->post_content;
-		$multipage = 0;
-	}
-	return true;
-}
-
-// Setup global user vars.  Used by set_current_user() for back compat.
-function setup_userdata($user_id = '') {
-	global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity;
-
-	if ( '' == $user_id )
-		$user = wp_get_current_user();
-	else 
-		$user = new WP_User($user_id);
-
-	if ( 0 == $user->ID )
-		return;
-
-	$userdata = $user->data;
-	$user_login	= $user->user_login;
-	$user_level	= $user->user_level;
-	$user_ID	= $user->ID;
-	$user_email	= $user->user_email;
-	$user_url	= $user->user_url;
-	$user_pass_md5	= md5($user->user_pass);
-	$user_identity	= $user->display_name;
-}
-
 function is_new_day() {
 	global $day, $previousday;
 	if ( $day != $previousday ) {
@@ -1204,887 +601,162 @@
 	}
 }
 
-// Filters: these are the core of WP's plugin architecture
-
-function merge_filters($tag) {
-	global $wp_filter;
-	if ( isset($wp_filter['all']) ) {
-		foreach ($wp_filter['all'] as $priority => $functions) {
-			if ( isset($wp_filter[$tag][$priority]) )
-				$wp_filter[$tag][$priority] = array_merge($wp_filter['all'][$priority], $wp_filter[$tag][$priority]);
-			else
-				$wp_filter[$tag][$priority] = array_merge($wp_filter['all'][$priority], array());
-			$wp_filter[$tag][$priority] = array_unique($wp_filter[$tag][$priority]);
-		}
-	}
-
-	if ( isset($wp_filter[$tag]) )
-		uksort( $wp_filter[$tag], "strnatcasecmp" );
-}
-
-function apply_filters($tag, $string) {
-	global $wp_filter;
-
-	$args = array_slice(func_get_args(), 2);
-
-	merge_filters($tag);
-
-	if ( !isset($wp_filter[$tag]) ) {
-		return $string;
-	}
-	foreach ($wp_filter[$tag] as $priority => $functions) {
-		if ( !is_null($functions) ) {
-			foreach($functions as $function) {
-
-				$all_args = array_merge(array($string), $args);
-				$function_name = $function['function'];
-				$accepted_args = $function['accepted_args'];
-
-				if ( $accepted_args == 1 )
-					$the_args = array($string);
-				elseif ( $accepted_args > 1 )
-					$the_args = array_slice($all_args, 0, $accepted_args);
-				elseif ( $accepted_args == 0 )
-					$the_args = NULL;
-				else
-					$the_args = $all_args;
-
-				$string = call_user_func_array($function_name, $the_args);
-			}
-		}
-	}
-	return $string;
-}
-
-function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
-	global $wp_filter;
-
-	// check that we don't already have the same filter at the same priority
-	if ( isset($wp_filter[$tag]["$priority"]) ) {
-		foreach($wp_filter[$tag]["$priority"] as $filter) {
-			// uncomment if we want to match function AND accepted_args
-			// if ( $filter == array($function, $accepted_args) ) {
-			if ( $filter['function'] == $function_to_add ) {
-				return true;
-			}
-		}
-	}
-
-	// So the format is wp_filter['tag']['array of priorities']['array of ['array (functions, accepted_args)]']
-	$wp_filter[$tag]["$priority"][] = array('function'=>$function_to_add, 'accepted_args'=>$accepted_args);
-	return true;
-}
-
-function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
-	global $wp_filter;
-
-	// rebuild the list of filters
-	if ( isset($wp_filter[$tag]["$priority"]) ) {
-		$new_function_list = array();
-		foreach($wp_filter[$tag]["$priority"] as $filter) {
-			if ( $filter['function'] != $function_to_remove ) {
-				$new_function_list[] = $filter;
-			}
-		}
-		$wp_filter[$tag]["$priority"] = $new_function_list;
-	}
-	return true;
-}
-
-// The *_action functions are just aliases for the *_filter functions, they take special strings instead of generic content
-
-function do_action($tag, $arg = '') {
-	global $wp_filter;
-	$extra_args = array_slice(func_get_args(), 2);
- 	if ( is_array($arg) )
- 		$args = array_merge($arg, $extra_args);
-	else
-		$args = array_merge(array($arg), $extra_args);
-
-	merge_filters($tag);
-
-	if ( !isset($wp_filter[$tag]) ) {
-		return;
-	}
-	foreach ($wp_filter[$tag] as $priority => $functions) {
-		if ( !is_null($functions) ) {
-			foreach($functions as $function) {
-
-				$function_name = $function['function'];
-				$accepted_args = $function['accepted_args'];
-
-				if ( $accepted_args == 1 ) {
-					if ( is_array($arg) )
-						$the_args = $arg;
-					else
-						$the_args = array($arg);
-				} elseif ( $accepted_args > 1 ) {
-					$the_args = array_slice($args, 0, $accepted_args);
-				} elseif ( $accepted_args == 0 ) {
-					$the_args = NULL;
-				} else {
-					$the_args = $args;
-				}
-
-				$string = call_user_func_array($function_name, $the_args);
-			}
-		}
-	}
-}
-
-function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
-	add_filter($tag, $function_to_add, $priority, $accepted_args);
-}
-
-function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
-	remove_filter($tag, $function_to_remove, $priority, $accepted_args);
-}
-
-function get_page_uri($page_id) {
-	$page = get_page($page_id);
-	$uri = urldecode($page->post_name);
-
-	// A page cannot be it's own parent.
-	if ( $page->post_parent == $page->ID )
-		return $uri;
-
-	while ($page->post_parent != 0) {
-		$page = get_page($page->post_parent);
-		$uri = urldecode($page->post_name) . "/" . $uri;
-	}
-
-	return $uri;
-}
-
-function get_posts($args) {
-	global $wpdb;
-	parse_str($args, $r);
-	if ( !isset($r['numberposts']) )
-		$r['numberposts'] = 5;
-	if ( !isset($r['offset']) )
-		$r['offset'] = 0;
-	if ( !isset($r['category']) )
-		$r['category'] = '';
-	if ( !isset($r['orderby']) )
-		$r['orderby'] = 'post_date';
-	if ( !isset($r['order']) )
-		$r['order'] = 'DESC';
-
-	$now = current_time('mysql');
-
-	$posts = $wpdb->get_results(
-		"SELECT DISTINCT * FROM $wpdb->posts " .
-		( empty( $r['category'] ) ? "" : ", $wpdb->post2cat " ) .
-		" WHERE post_date <= '$now' AND (post_status = 'publish') ".
-		( empty( $r['category'] ) ? "" : "AND $wpdb->posts.ID = $wpdb->post2cat.post_id AND $wpdb->post2cat.category_id = " . $r['category']. " " ) .
-		" GROUP BY $wpdb->posts.ID ORDER BY " . $r['orderby'] . " " . $r['order'] . " LIMIT " . $r['offset'] . ',' . $r['numberposts'] );
-
-	update_post_caches($posts);
-
-	return $posts;
-}
-
-function &query_posts($query) {
-	global $wp_query;
-	return $wp_query->query($query);
-}
-
-function update_post_cache(&$posts) {
-	global $post_cache;
-
-	if ( !$posts )
-		return;
-
-	for ($i = 0; $i < count($posts); $i++) {
-		$post_cache[$posts[$i]->ID] = &$posts[$i];
-	}
-}
-
-function clean_post_cache($id) {
-	global $post_cache;
-
-	if ( isset( $post_cache[$id] ) )
-		unset( $post_cache[$id] );
-}
-
-function update_page_cache(&$pages) {
-	global $page_cache;
-
-	if ( !$pages )
-		return;
-
-	for ($i = 0; $i < count($pages); $i++) {
-		$page_cache[$pages[$i]->ID] = &$pages[$i];
-		wp_cache_add($pages[$i]->ID, $pages[$i], 'pages');
-	}
-}
-
-
-function clean_page_cache($id) {
-	global $page_cache;
-
-	if ( isset( $page_cache[$id] ) )
-		unset( $page_cache[$id] );
-}
-
-function update_post_category_cache($post_ids) {
-	global $wpdb, $category_cache;
-
-	if ( empty($post_ids) )
-		return;
-
-	if ( is_array($post_ids) )
-		$post_ids = implode(',', $post_ids);
-
-	$dogs = $wpdb->get_results("SELECT post_id, category_id FROM $wpdb->post2cat WHERE post_id IN ($post_ids)");
-
-	if ( empty($dogs) )
-		return;
-		
-	foreach ($dogs as $catt)
-		$category_cache[$catt->post_id][$catt->category_id] = &get_category($catt->category_id);
-}
-
-function update_post_caches(&$posts) {
-	global $post_cache, $category_cache, $comment_count_cache, $post_meta_cache;
-	global $wpdb;
-
-	// No point in doing all this work if we didn't match any posts.
-	if ( !$posts )
-		return;
-
-	// Get the categories for all the posts
-	for ($i = 0; $i < count($posts); $i++) {
-		$post_id_array[] = $posts[$i]->ID;
-		$post_cache[$posts[$i]->ID] = &$posts[$i];
-		$comment_count_cache[$posts[$i]->ID] = $posts[$i]->comment_count;
-	}
-
-	$post_id_list = implode(',', $post_id_array);
-
-	update_post_category_cache($post_id_list);
-
-	// Get post-meta info
-	if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id IN($post_id_list) ORDER BY post_id, meta_key", ARRAY_A) ) {
-		// Change from flat structure to hierarchical:
-		$post_meta_cache = array();
-		foreach ($meta_list as $metarow) {
-			$mpid = (int) $metarow['post_id'];
-			$mkey = $metarow['meta_key'];
-			$mval = $metarow['meta_value'];
-
-			// Force subkeys to be array type:
-			if ( !isset($post_meta_cache[$mpid]) || !is_array($post_meta_cache[$mpid]) )
-				$post_meta_cache[$mpid] = array();
-			if ( !isset($post_meta_cache[$mpid]["$mkey"]) || !is_array($post_meta_cache[$mpid]["$mkey"]) )
-				$post_meta_cache[$mpid]["$mkey"] = array();
-
-			// Add a value to the current pid/key:
-			$post_meta_cache[$mpid][$mkey][] = $mval;
-		}
-	}
-}
-
-function update_category_cache() {
-	return true;
-}
-
-function wp_head() {
-	do_action('wp_head');
-}
-
-function wp_footer() {
-	do_action('wp_footer');
-}
-
-function is_single ($post = '') {
-	global $wp_query;
-
-	if ( !$wp_query->is_single )
-		return false;
-
-	if ( empty( $post) )
-		return true;
-
-	$post_obj = $wp_query->get_queried_object();
-
-	if ( $post == $post_obj->ID )
-		return true;
-	elseif ( $post == $post_obj->post_title )
-		return true;
-	elseif ( $post == $post_obj->post_name )
-		return true;
-
-	return false;
-}
-
-function is_page ($page = '') {
-	global $wp_query;
-
-	if ( !$wp_query->is_page )
-		return false;
-
-	if ( empty($page) )
-		return true;
-
-	$page_obj = $wp_query->get_queried_object();
-
-	if ( $page == $page_obj->ID )
-		return true;
-	elseif ( $page == $page_obj->post_title )
-		return true;
-	else if ( $page == $page_obj->post_name )
-		return true;
-
-	return false;
-}
-
-function is_attachment () {
-	global $wp_query;
-
-	return $wp_query->is_attachment;
-}
-
-function is_preview() {
-	global $wp_query;
-	
-	return $wp_query->is_preview;
-}
-
-function is_archive () {
-	global $wp_query;
-
-	return $wp_query->is_archive;
-}
-
-function is_date () {
-	global $wp_query;
-
-	return $wp_query->is_date;
-}
-
-function is_year () {
-	global $wp_query;
-
-	return $wp_query->is_year;
-}
-
-function is_month () {
-	global $wp_query;
-
-	return $wp_query->is_month;
-}
-
-function is_day () {
-	global $wp_query;
-
-	return $wp_query->is_day;
-}
-
-function is_time () {
-	global $wp_query;
-
-	return $wp_query->is_time;
-}
-
-function is_author ($author = '') {
-	global $wp_query;
-
-	if ( !$wp_query->is_author )
-		return false;
-
-	if ( empty($author) )
-		return true;
-
-	$author_obj = $wp_query->get_queried_object();
-
-	if ( $author == $author_obj->ID )
-		return true;
-	elseif ( $author == $author_obj->nickname )
-		return true;
-	elseif ( $author == $author_obj->user_nicename )
-		return true;
-
-	return false;
-}
-
-function is_category ($category = '') {
-	global $wp_query;
-
-	if ( !$wp_query->is_category )
-		return false;
-
-	if ( empty($category) )
-		return true;
-
-	$cat_obj = $wp_query->get_queried_object();
-
-	if ( $category == $cat_obj->cat_ID )
-		return true;
-	else if ( $category == $cat_obj->cat_name )
-		return true;
-	elseif ( $category == $cat_obj->category_nicename )
-		return true;
-
-	return false;
-}
-
-function is_search () {
-	global $wp_query;
-
-	return $wp_query->is_search;
-}
-
-function is_feed () {
-	global $wp_query;
-
-	return $wp_query->is_feed;
-}
-
-function is_trackback () {
-	global $wp_query;
-
-	return $wp_query->is_trackback;
-}
-
-function is_admin () {
-	global $wp_query;
-
-	return ( $wp_query->is_admin || strstr($_SERVER['REQUEST_URI'], 'wp-admin/') );
-}
-
-function is_home () {
-	global $wp_query;
-
-	return $wp_query->is_home;
-}
-
-function is_404 () {
-	global $wp_query;
-
-	return $wp_query->is_404;
-}
-
-function is_comments_popup () {
-	global $wp_query;
-
-	return $wp_query->is_comments_popup;
-}
-
-function is_paged () {
-	global $wp_query;
-
-	return $wp_query->is_paged;
-}
-
-function in_the_loop() {
-	global $wp_query;
-
-	return $wp_query->in_the_loop;
-}
-
-function get_query_var($var) {
-	global $wp_query;
-
-	return $wp_query->get($var);
-}
-
-function have_posts() {
-	global $wp_query;
-
-	return $wp_query->have_posts();
-}
-
-function rewind_posts() {
-	global $wp_query;
-
-	return $wp_query->rewind_posts();
-}
-
-function the_post() {
-	global $wp_query;
-
-	$wp_query->the_post();
-}
-
-function get_theme_root() {
-	return apply_filters('theme_root', ABSPATH . "wp-content/themes");
-}
-
-function get_theme_root_uri() {
-	return apply_filters('theme_root_uri', get_settings('siteurl') . "/wp-content/themes", get_settings('siteurl'));
-}
-
-function get_stylesheet() {
-	return apply_filters('stylesheet', get_settings('stylesheet'));
-}
-
-function get_stylesheet_directory() {
-	$stylesheet = get_stylesheet();
-	$stylesheet_dir = get_theme_root() . "/$stylesheet";
-	return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
-}
-
-function get_stylesheet_directory_uri() {
-	$stylesheet = rawurlencode( get_stylesheet() );
-	$stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
-	return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
-}
-
-function get_stylesheet_uri() {
-	$stylesheet_dir_uri = get_stylesheet_directory_uri();
-	$stylesheet_uri = $stylesheet_dir_uri . "/style.css";
-	return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
-}
-
-function get_template() {
-	$template = get_settings('template');
-	if (!file_exists(get_theme_root() . "/$template")) { //works for dirs too
-		update_option('template', 'default');
-		update_option('stylesheet', 'default');
-	}
-	return apply_filters('template', get_settings('template'));
-}
-
-function get_template_directory() {
-	$template = get_template();
-	$template_dir = get_theme_root() . "/$template";
-	return apply_filters('template_directory', $template_dir, $template);
-}
-
-function get_template_directory_uri() {
-	$template = get_template();
-	$template_dir_uri = get_theme_root_uri() . "/$template";
-	return apply_filters('template_directory_uri', $template_dir_uri, $template);
-}
-
-function get_theme_data($theme_file) {
-	$theme_data = implode('', file($theme_file));
-	preg_match("|Theme Name:(.*)|i", $theme_data, $theme_name);
-	preg_match("|Theme URI:(.*)|i", $theme_data, $theme_uri);
-	preg_match("|Description:(.*)|i", $theme_data, $description);
-	preg_match("|Author:(.*)|i", $theme_data, $author_name);
-	preg_match("|Author URI:(.*)|i", $theme_data, $author_uri);
-	preg_match("|Template:(.*)|i", $theme_data, $template);
-	if ( preg_match("|Version:(.*)|i", $theme_data, $version) )
-		$version = trim($version[1]);
-	else
-		$version ='';
-	if ( preg_match("|Status:(.*)|i", $theme_data, $status) )
-		$status = trim($status[1]);
-	else
-		$status = 'publish';
-
-	$description = wptexturize(trim($description[1]));
-
-	$name = $theme_name[1];
-	$name = trim($name);
-	$theme = $name;
-
-	if ( '' == $author_uri[1] ) {
-		$author = trim($author_name[1]);
-	} else {
-		$author = '<a href="' . trim($author_uri[1]) . '" title="' . __('Visit author homepage') . '">' . trim($author_name[1]) . '</a>';
-	}
-
-	return array('Name' => $name, 'Title' => $theme, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template[1], 'Status' => $status);
-}
-
-function get_themes() {
-	global $wp_themes;
-	global $wp_broken_themes;
-
-	if ( isset($wp_themes) )
-		return $wp_themes;
-
-	$themes = array();
-	$wp_broken_themes = array();
-	$theme_root = get_theme_root();
-	$theme_loc = str_replace(ABSPATH, '', $theme_root);
-
-	// Files in wp-content/themes directory
-	$themes_dir = @ dir($theme_root);
-	if ( $themes_dir ) {
-		while(($theme_dir = $themes_dir->read()) !== false) {
-			if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
-				if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' ) {
-					continue;
-				}
-				$stylish_dir = @ dir($theme_root . '/' . $theme_dir);
-				$found_stylesheet = false;
-				while (($theme_file = $stylish_dir->read()) !== false) {
-					if ( $theme_file == 'style.css' ) {
-						$theme_files[] = $theme_dir . '/' . $theme_file;
-						$found_stylesheet = true;
-						break;
-					}
-				}
-				if ( !$found_stylesheet ) {
-					$wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
-				}
-			}
-		}
-	}
-
-	if ( !$themes_dir || !$theme_files ) {
-		return $themes;
-	}
-
-	sort($theme_files);
-
-	foreach($theme_files as $theme_file) {
-		if ( ! is_readable("$theme_root/$theme_file") ) {
-			$wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
-			continue;
-		}
-
-		$theme_data = get_theme_data("$theme_root/$theme_file");
-
-		$name = $theme_data['Name'];
-		$title = $theme_data['Title'];
-		$description = wptexturize($theme_data['Description']);
-		$version = $theme_data['Version'];
-		$author = $theme_data['Author'];
-		$template = $theme_data['Template'];
-		$stylesheet = dirname($theme_file);
-
-		foreach (array('png', 'gif', 'jpg', 'jpeg') as $ext) {
-			if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {
-				$screenshot = "screenshot.$ext";
-				break;
-			}
-		}
+function update_post_cache(&$posts) {
+	global $post_cache, $blog_id;
 
-		if ( empty($name) ) {
-			$name = dirname($theme_file);
-			$title = $name;
-		}
+	if ( !$posts )
+		return;
 
-		if ( empty($template) ) {
-			if ( file_exists(dirname("$theme_root/$theme_file/index.php")) ) {
-				$template = dirname($theme_file);
-			} else {
-				continue;
-			}
-		}
+	for ($i = 0; $i < count($posts); $i++) {
+		$post_cache[$blog_id][$posts[$i]->ID] = &$posts[$i];
+	}
+}
 
-		$template = trim($template);
+function clean_post_cache($id) {
+	global $post_cache, $post_meta_cache, $category_cache, $blog_id;
 
-		if ( !file_exists("$theme_root/$template/index.php") ) {
-			$wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
-			continue;
-		}
+	if ( isset( $post_cache[$blog_id][$id] ) )
+		unset( $post_cache[$blog_id][$id] );
 
-		$stylesheet_files = array();
-		$stylesheet_dir = @ dir("$theme_root/$stylesheet");
-		if ( $stylesheet_dir ) {
-			while(($file = $stylesheet_dir->read()) !== false) {
-				if ( !preg_match('|^\.+$|', $file) && preg_match('|\.css$|', $file) )
-					$stylesheet_files[] = "$theme_loc/$stylesheet/$file";
-			}
-		}
+	if ( isset ($post_meta_cache[$blog_id][$id] ) )
+		unset( $post_meta_cache[$blog_id][$id] );
 
-		$template_files = array();
-		$template_dir = @ dir("$theme_root/$template");
-		if ( $template_dir ) {
-			while(($file = $template_dir->read()) !== false) {
-				if ( !preg_match('|^\.+$|', $file) && preg_match('|\.php$|', $file) )
-					$template_files[] = "$theme_loc/$template/$file";
-			}
-		}
+	if ( isset( $category_cache[$blog_id][$id]) )
+		unset ( $category_cache[$blog_id][$id] );
+}
 
-		$template_dir = dirname($template_files[0]);
-		$stylesheet_dir = dirname($stylesheet_files[0]);
+function update_page_cache(&$pages) {
+	global $page_cache, $blog_id;
 
-		if ( empty($template_dir) )
-			$template_dir = '/';
-		if ( empty($stylesheet_dir) )
-			$stylesheet_dir = '/';
-
-		// Check for theme name collision.  This occurs if a theme is copied to
-		// a new theme directory and the theme header is not updated.  Whichever
-		// theme is first keeps the name.  Subsequent themes get a suffix applied.
-		// The Default and Classic themes always trump their pretenders.
-		if ( isset($themes[$name]) ) {
-			if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) &&
-					 ('default' == $stylesheet || 'classic' == $stylesheet) ) {
-				// If another theme has claimed to be one of our default themes, move
-				// them aside.
-				$suffix = $themes[$name]['Stylesheet'];
-				$new_name = "$name/$suffix";
-				$themes[$new_name] = $themes[$name];
-				$themes[$new_name]['Name'] = $new_name;
-			} else {
-				$name = "$name/$stylesheet";
-			}
-		}
+	if ( !$pages )
+		return;
 
-		$themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot);
+	for ($i = 0; $i < count($pages); $i++) {
+		$page_cache[$blog_id][$pages[$i]->ID] = &$pages[$i];
+		wp_cache_add($pages[$i]->ID, $pages[$i], 'pages');
 	}
+}
 
-	// Resolve theme dependencies.
-	$theme_names = array_keys($themes);
-
-	foreach ($theme_names as $theme_name) {
-		$themes[$theme_name]['Parent Theme'] = '';
-		if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) {
-			foreach ($theme_names as $parent_theme_name) {
-				if ( ($themes[$parent_theme_name]['Stylesheet'] == $themes[$parent_theme_name]['Template']) && ($themes[$parent_theme_name]['Template'] == $themes[$theme_name]['Template']) ) {
-					$themes[$theme_name]['Parent Theme'] = $themes[$parent_theme_name]['Name'];
-					break;
-				}
-			}
-		}
-	}
+function clean_page_cache($id) {
+	global $page_cache, $blog_id;
 
-	$wp_themes = $themes;
+	if ( isset( $page_cache[$blog_id][$id] ) )
+		unset( $page_cache[$blog_id][$id] );
 
-	return $themes;
+	wp_cache_delete($id, 'pages');
+	wp_cache_delete( 'all_page_ids', 'pages' );
+	wp_cache_delete( 'get_pages', 'page' );
 }
 
-function get_theme($theme) {
-	$themes = get_themes();
-
-	if ( array_key_exists($theme, $themes) )
-		return $themes[$theme];
+function update_post_category_cache($post_ids) {
+	global $wpdb, $category_cache, $blog_id;
 
-	return NULL;
-}
+	if ( empty($post_ids) )
+		return;
 
-function get_current_theme() {
-	$themes = get_themes();
-	$theme_names = array_keys($themes);
-	$current_template = get_settings('template');
-	$current_stylesheet = get_settings('stylesheet');
-	$current_theme = 'WordPress Default';
+	if ( is_array($post_ids) )
+		$post_id_list = implode(',', $post_ids);
 
-	if ( $themes ) {
-		foreach ($theme_names as $theme_name) {
-			if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet &&
-					$themes[$theme_name]['Template'] == $current_template ) {
-				$current_theme = $themes[$theme_name]['Name'];
-				break;
-			}
+	$post_id_array = (array) explode(',', $post_ids);
+	$count = count( $post_id_array);
+	for ( $i = 0; $i < $count; $i++ ) {
+		$post_id = (int) $post_id_array[ $i ];
+		if ( isset( $category_cache[$blog_id][$post_id] ) ) {
+			unset( $post_id_array[ $i ] );
+			continue;
 		}
 	}
+	if ( count( $post_id_array ) == 0 )
+		return;
+	$post_id_list = join( ',', $post_id_array ); // with already cached stuff removed
 
-	return $current_theme;
-}
-
-function get_query_template($type) {
-	$template = '';
-	if ( file_exists(TEMPLATEPATH . "/{$type}.php") )
-		$template = TEMPLATEPATH . "/{$type}.php";
-
-	return apply_filters("{$type}_template", $template);
-}
-
-function get_404_template() {
-	return get_query_template('404');
-}
+	$dogs = $wpdb->get_results("SELECT post_id, category_id FROM $wpdb->post2cat WHERE post_id IN ($post_id_list)");
 
-function get_archive_template() {
-	return get_query_template('archive');
-}
+	if ( empty($dogs) )
+		return;
 
-function get_author_template() {
-	return get_query_template('author');
+	foreach ($dogs as $catt)
+		$category_cache[$blog_id][$catt->post_id][$catt->category_id] = &get_category($catt->category_id);
 }
 
-function get_category_template() {
-	$template = '';
-	if ( file_exists(TEMPLATEPATH . "/category-" . get_query_var('cat') . '.php') )
-		$template = TEMPLATEPATH . "/category-" . get_query_var('cat') . '.php';
-	else if ( file_exists(TEMPLATEPATH . "/category.php") )
-		$template = TEMPLATEPATH . "/category.php";
+function update_post_caches(&$posts) {
+	global $post_cache, $category_cache, $post_meta_cache;
+	global $wpdb, $blog_id;
 
-	return apply_filters('category_template', $template);
-}
+	// No point in doing all this work if we didn't match any posts.
+	if ( !$posts )
+		return;
 
-function get_date_template() {
-	return get_query_template('date');
-}
+	// Get the categories for all the posts
+	for ($i = 0; $i < count($posts); $i++) {
+		$post_id_array[] = $posts[$i]->ID;
+		$post_cache[$blog_id][$posts[$i]->ID] = &$posts[$i];
+	}
 
-function get_home_template() {
-	$template = '';
+	$post_id_list = implode(',', $post_id_array);
 
-	if ( file_exists(TEMPLATEPATH . "/home.php") )
-		$template = TEMPLATEPATH . "/home.php";
-	else if ( file_exists(TEMPLATEPATH . "/index.php") )
-		$template = TEMPLATEPATH . "/index.php";
+	update_post_category_cache($post_id_list);
 
-	return apply_filters('home_template', $template);
+	update_postmeta_cache($post_id_list);
 }
 
-function get_page_template() {
-	global $wp_query;
-
-	$id = $wp_query->post->ID;
-	$template = get_post_meta($id, '_wp_page_template', true);
-
-	if ( 'default' == $template )
-		$template = '';
-
-	if ( ! empty($template) && file_exists(TEMPLATEPATH . "/$template") )
-		$template = TEMPLATEPATH . "/$template";
-	else if ( file_exists(TEMPLATEPATH . "/page.php") )
-		$template = TEMPLATEPATH . "/page.php";
-	else
-		$template = '';
+function update_postmeta_cache($post_id_list = '') {
+	global $wpdb, $post_meta_cache, $blog_id;
 
-	return apply_filters('page_template', $template);
-}
+	// We should validate this comma-separated list for the upcoming SQL query
+	$post_id_list = preg_replace('|[^0-9,]|', '', $post_id_list);
 
-function get_paged_template() {
-	return get_query_template('paged');
-}
+	if ( empty( $post_id_list ) )
+		return false;
 
-function get_search_template() {
-	return get_query_template('search');
-}
+	// we're marking each post as having its meta cached (with no keys... empty array), to prevent posts with no meta keys from being queried again
+	// any posts that DO have keys will have this empty array overwritten with a proper array, down below
+	$post_id_array = (array) explode(',', $post_id_list);
+	$count = count( $post_id_array);
+	for ( $i = 0; $i < $count; $i++ ) {
+		$post_id = (int) $post_id_array[ $i ];
+		if ( isset( $post_meta_cache[$blog_id][$post_id] ) ) { // If the meta is already cached
+			unset( $post_id_array[ $i ] );
+			continue;
+		}
+		$post_meta_cache[$blog_id][$post_id] = array();
+	}
+	if ( count( $post_id_array ) == 0 )
+		return;
+	$post_id_list = join( ',', $post_id_array ); // with already cached stuff removeds
 
-function get_single_template() {
-	return get_query_template('single');
-}
+	// Get post-meta info
+	if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id IN($post_id_list) ORDER BY post_id, meta_key", ARRAY_A) ) {
+		// Change from flat structure to hierarchical:
+		if ( !isset($post_meta_cache) )
+			$post_meta_cache[$blog_id] = array();
 
-function get_attachment_template() {
-	global $posts;
-	$type = explode('/', $posts[0]->post_mime_type);
-	if ( $template = get_query_template($type[0]) )
-		return $template;
-	elseif ( $template = get_query_template($type[1]) )
-		return $template;
-	elseif ( $template = get_query_template("$type[0]_$type[1]") )
-		return $template;
-	else
-		return get_query_template('attachment');
-}
+		foreach ($meta_list as $metarow) {
+			$mpid = (int) $metarow['post_id'];
+			$mkey = $metarow['meta_key'];
+			$mval = $metarow['meta_value'];
 
-function get_comments_popup_template() {
-	if ( file_exists( TEMPLATEPATH . '/comments-popup.php') )
-		$template = TEMPLATEPATH . '/comments-popup.php';
-	else
-		$template = get_theme_root() . '/default/comments-popup.php';
+			// Force subkeys to be array type:
+			if ( !isset($post_meta_cache[$blog_id][$mpid]) || !is_array($post_meta_cache[$blog_id][$mpid]) )
+				$post_meta_cache[$blog_id][$mpid] = array();
+			if ( !isset($post_meta_cache[$blog_id][$mpid]["$mkey"]) || !is_array($post_meta_cache[$blog_id][$mpid]["$mkey"]) )
+				$post_meta_cache[$blog_id][$mpid]["$mkey"] = array();
 
-	return apply_filters('comments_popup_template', $template);
+			// Add a value to the current pid/key:
+			$post_meta_cache[$blog_id][$mpid][$mkey][] = $mval;
+		}
+	}
 }
 
-// Borrowed from the PHP Manual user notes. Convert entities, while
-// preserving already-encoded entities:
-function htmlentities2($myHTML) {
-	$translation_table=get_html_translation_table (HTML_ENTITIES,ENT_QUOTES);
-	$translation_table[chr(38)] = '&';
-	return preg_replace("/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/","&amp;" , strtr($myHTML, $translation_table));
+function update_category_cache() {
+	return true;
 }
 
-
-function is_plugin_page() {
-	global $plugin_page;
-
-	if ( isset($plugin_page) )
-		return true;
-
-	return false;
+function clean_category_cache($id) {
+	wp_cache_delete($id, 'category');
+	wp_cache_delete('all_category_ids', 'category');
+	wp_cache_delete('get_categories', 'category');
+	delete_option('category_children');
 }
 
 /*
@@ -2100,12 +772,12 @@
 function add_query_arg() {
 	$ret = '';
 	if ( is_array(func_get_arg(0)) ) {
-		if ( @func_num_args() < 2 )
+		if ( @func_num_args() < 2 || false === @func_get_arg(1) )
 			$uri = $_SERVER['REQUEST_URI'];
 		else
 			$uri = @func_get_arg(1);
 	} else {
-		if ( @func_num_args() < 3 )
+		if ( @func_num_args() < 3 || false === @func_get_arg(2) )
 			$uri = $_SERVER['REQUEST_URI'];
 		else
 			$uri = @func_get_arg(2);
@@ -2123,7 +795,7 @@
 		$protocol = '';
 	}
 
-	if ( strstr($uri, '?') ) {
+	if (strpos($uri, '?') !== false) {
 		$parts = explode('?', $uri, 2);
 		if ( 1 == count($parts) ) {
 			$base = '?';
@@ -2132,7 +804,7 @@
 			$base = $parts[0] . '?';
 			$query = $parts[1];
 		}
-	} else if ( !empty($protocol) || strstr($uri, '/') ) {
+	} elseif (!empty($protocol) || strpos($uri, '/') !== false) {
 		$base = $uri . '?';
 		$query = '';
 	} else {
@@ -2140,7 +812,8 @@
 		$query = $uri;
 	}
 
-	parse_str($query, $qs);
+	wp_parse_str($query, $qs);
+	$qs = urlencode_deep($qs);
 	if ( is_array(func_get_arg(0)) ) {
 		$kayvees = func_get_arg(0);
 		$qs = array_merge($qs, $kayvees);
@@ -2149,27 +822,38 @@
 	}
 
 	foreach($qs as $k => $v) {
-		if ( $v != '' ) {
+		if ( $v !== FALSE ) {
 			if ( $ret != '' )
 				$ret .= '&';
-			$ret .= "$k=$v";
+			if ( empty($v) && !preg_match('|[?&]' . preg_quote($k, '|') . '=|', $query) )
+				$ret .= $k;
+			else
+				$ret .= "$k=$v";
 		}
 	}
+	$ret = trim($ret, '?');
 	$ret = $protocol . $base . $ret . $frag;
-	return trim($ret, '?');
-}
-
-function remove_query_arg($key, $query) {
-	return add_query_arg($key, '', $query);
+	$ret = rtrim($ret, '?');
+	return $ret;
 }
 
-function load_template($file) {
-	global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query,
-		$wp_rewrite, $wpdb;
+/*
+remove_query_arg: Returns a modified querystring by removing
+a single key or an array of keys.
+Omitting oldquery_or_uri uses the $_SERVER value.
 
-	extract($wp_query->query_vars);
+Parameters:
+remove_query_arg(removekey, [oldquery_or_uri]) or
+remove_query_arg(removekeyarray, [oldquery_or_uri])
+*/
 
-	require_once($file);
+function remove_query_arg($key, $query=FALSE) {
+	if ( is_array($key) ) { // removing multiple keys
+		foreach ( (array) $key as $k )
+			$query = add_query_arg($k, FALSE, $query);
+		return $query;
+	}
+	return add_query_arg($key, FALSE, $query);
 }
 
 function add_magic_quotes($array) {
@@ -2186,10 +870,21 @@
 }
 
 function wp_remote_fopen( $uri ) {
+	$timeout = 10;
+	$parsed_url = @parse_url($uri);
+
+	if ( !$parsed_url || !is_array($parsed_url) )
+		return false;
+
+	if ( !isset($parsed_url['scheme']) || !in_array($parsed_url['scheme'], array('http','https')) )
+		$uri = 'http://' . $uri;
+
 	if ( ini_get('allow_url_fopen') ) {
-		$fp = fopen( $uri, 'r' );
+		$fp = @fopen( $uri, 'r' );
 		if ( !$fp )
 			return false;
+
+		//stream_set_timeout($fp, $timeout); // Requires php 4.3
 		$linea = '';
 		while( $remote_read = fread($fp, 4096) )
 			$linea .= $remote_read;
@@ -2200,6 +895,7 @@
 		curl_setopt ($handle, CURLOPT_URL, $uri);
 		curl_setopt ($handle, CURLOPT_CONNECTTIMEOUT, 1);
 		curl_setopt ($handle, CURLOPT_RETURNTRANSFER, 1);
+		curl_setopt ($handle, CURLOPT_TIMEOUT, $timeout);
 		$buffer = curl_exec($handle);
 		curl_close($handle);
 		return $buffer;
@@ -2210,7 +906,7 @@
 
 function wp($query_vars = '') {
 	global $wp;
-	
+
 	$wp->main($query_vars);
 }
 
@@ -2228,8 +924,17 @@
 	elseif ( 410 == $header )
 		$text = 'Gone';
 
-	@header("HTTP/1.1 $header $text");
-	@header("Status: $header $text");
+	$protocol = $_SERVER["SERVER_PROTOCOL"];
+	if ( ('HTTP/1.1' != $protocol) && ('HTTP/1.0' != $protocol) )
+		$protocol = 'HTTP/1.0';
+	$status_header = "$protocol $header $text";
+	$status_header = apply_filters('status_header', $status_header, $header, $text, $protocol);
+
+	if ( version_compare( phpversion(), '4.3.0', '>=' ) ) {
+		return @header( $status_header, true, $header );
+	} else {
+		return @header( $status_header );
+	}
 }
 
 function nocache_headers() {
@@ -2239,137 +944,108 @@
 	@ header('Pragma: no-cache');
 }
 
-function get_usermeta( $user_id, $meta_key = '') {
-	global $wpdb;
-	$user_id = (int) $user_id;
+function cache_javascript_headers() {
+	$expiresOffset = 864000; // 10 days
+	header("Content-type: text/javascript; charset=" . get_bloginfo('charset'));
+	header("Vary: Accept-Encoding"); // Handle proxies
+	header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
+}
 
-	if ( !empty($meta_key) ) {
-		$meta_key = preg_replace('|a-z0-9_|i', '', $meta_key);
-		$metas = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
-	} else {
-		$metas = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id'");
-	}
+function get_num_queries() {
+	global $wpdb;
+	return $wpdb->num_queries;
+}
 
-	if ( empty($metas) ) {
-		if ( empty($meta_key) )
-			return array();
-		else
-			return '';
-	}
+function bool_from_yn($yn) {
+		if ($yn == 'Y') return 1;
+		return 0;
+}
 
-	foreach ($metas as $index => $meta) {
-		@ $value = unserialize($meta->meta_value);
-		if ( $value === FALSE )
-			$value = $meta->meta_value;
+function do_feed() {
+	global $wp_query;
 
-		$values[] = $value;
-	}
+	$feed = get_query_var('feed');
 
-	if ( count($values) == 1 )
-		return $values[0];
-	else
-		return $values;
-}
+	// Remove the pad, if present.
+	$feed = preg_replace('/^_+/', '', $feed);
 
-function update_usermeta( $user_id, $meta_key, $meta_value ) {
-	global $wpdb;
-	if ( !is_numeric( $user_id ) )
-		return false;
-	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+	if ( $feed == '' || $feed == 'feed' )
+		$feed = 'rss2';
 
-	// FIXME: usermeta data is assumed to be already escaped
-	if ( is_string($meta_value) )
-		$meta_value = stripslashes($meta_value);
-	$meta_value = maybe_serialize($meta_value);
-	$meta_value = $wpdb->escape($meta_value);
-	
-	if (empty($meta_value)) {
-		delete_usermeta($user_id, $meta_key);
-	}
-
-	$cur = $wpdb->get_row("SELECT * FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
-	if ( !$cur ) {
-		$wpdb->query("INSERT INTO $wpdb->usermeta ( user_id, meta_key, meta_value )
-		VALUES
-		( '$user_id', '$meta_key', '$meta_value' )");
-	} else if ( $cur->meta_value != $meta_value ) {
-		$wpdb->query("UPDATE $wpdb->usermeta SET meta_value = '$meta_value' WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
-	} else {
-		return false;	
-	}
-	
-	$user = get_userdata($user_id);
-	wp_cache_delete($user_id, 'users');
-	wp_cache_delete($user->user_login, 'userlogins');
-	
-	return true;
+	$hook = 'do_feed_' . $feed;
+	do_action($hook, $wp_query->is_comment_feed);
 }
 
-function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) {
-	global $wpdb;
-	if ( !is_numeric( $user_id ) )
-		return false;
-	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
-
-	if ( is_array($meta_value) || is_object($meta_value) )
-		$meta_value = serialize($meta_value);
-	$meta_value = trim( $meta_value );
+function do_feed_rdf() {
+	load_template(ABSPATH . WPINC . '/feed-rdf.php');
+}
 
-	if ( ! empty($meta_value) )
-		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key' AND meta_value = '$meta_value'");
-	else
-		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
-		
-	$user = get_userdata($user_id);
-	wp_cache_delete($user_id, 'users');
-	wp_cache_delete($user->user_login, 'userlogins');
-	
-	return true;
+function do_feed_rss() {
+	load_template(ABSPATH . WPINC . '/feed-rss.php');
 }
 
-function register_activation_hook($file, $function) {
-	$file = plugin_basename($file);
+function do_feed_rss2($for_comments) {
+	if ( $for_comments ) {
+		load_template(ABSPATH . WPINC . '/feed-rss2-comments.php');
+	} else {
+		load_template(ABSPATH . WPINC . '/feed-rss2.php');
+	}
+}
 
-	add_action('activate_' . $file, $function);
+function do_feed_atom($for_comments) {
+	if ($for_comments) {
+		load_template(ABSPATH . WPINC . '/feed-atom-comments.php');
+	} else {
+		load_template(ABSPATH . WPINC . '/feed-atom.php');
+	}
 }
 
-function register_deactivation_hook($file, $function) {
-	$file = plugin_basename($file);
+function do_robots() {
+	header('Content-type: text/plain; charset=utf-8');
 
-	add_action('deactivate_' . $file, $function);
-}
+	do_action('do_robotstxt');
 
-function plugin_basename($file) {
-	$file = preg_replace('|\\\\+|', '\\\\', $file);
-	$file = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', $file);
-	return $file;
+	if ( '0' == get_option('blog_public') ) {
+		echo "User-agent: *\n";
+		echo "Disallow: /\n";
+	} else {
+		echo "User-agent: *\n";
+		echo "Disallow:\n";
+	}
 }
 
-function get_num_queries() {
+function is_blog_installed() {
 	global $wpdb;
-	return $wpdb->num_queries;
+	$wpdb->hide_errors();
+	$installed = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'");
+	$wpdb->show_errors();
+
+	$install_status = !empty( $installed ) ? TRUE : FALSE;
+	return $install_status;
 }
 
 function wp_nonce_url($actionurl, $action = -1) {
 	return wp_specialchars(add_query_arg('_wpnonce', wp_create_nonce($action), $actionurl));
 }
 
-function wp_nonce_field($action = -1) {
-	echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce($action) . '" />';
-	wp_referer_field();
+function wp_nonce_field($action = -1, $name = "_wpnonce", $referer = true) {
+	$name = attribute_escape($name);
+	echo '<input type="hidden" name="' . $name . '" value="' . wp_create_nonce($action) . '" />';
+	if ( $referer )
+		wp_referer_field();
 }
 
 function wp_referer_field() {
-	$ref = wp_specialchars($_SERVER['REQUEST_URI']);
+	$ref = attribute_escape($_SERVER['REQUEST_URI']);
 	echo '<input type="hidden" name="_wp_http_referer" value="'. $ref . '" />';
 	if ( wp_get_original_referer() ) {
-		$original_ref = wp_specialchars(stripslashes(wp_get_original_referer()));
+		$original_ref = attribute_escape(stripslashes(wp_get_original_referer()));
 		echo '<input type="hidden" name="_wp_original_http_referer" value="'. $original_ref . '" />';
 	}
 }
 
 function wp_original_referer_field() {
-	echo '<input type="hidden" name="_wp_original_http_referer" value="' . wp_specialchars(stripslashes($_SERVER['REQUEST_URI'])) . '" />';
+	echo '<input type="hidden" name="_wp_original_http_referer" value="' . attribute_escape(stripslashes($_SERVER['REQUEST_URI'])) . '" />';
 }
 
 function wp_get_referer() {
@@ -2385,6 +1061,176 @@
 	return false;
 }
 
+function wp_mkdir_p($target) {
+	// from php.net/mkdir user contributed notes
+	if (file_exists($target)) {
+		if (! @ is_dir($target))
+			return false;
+		else
+			return true;
+	}
+
+	// Attempting to create the directory may clutter up our display.
+	if (@ mkdir($target)) {
+		$stat = @ stat(dirname($target));
+		$dir_perms = $stat['mode'] & 0007777;  // Get the permission bits.
+		@ chmod($target, $dir_perms);
+		return true;
+	} else {
+		if ( is_dir(dirname($target)) )
+			return false;
+	}
+
+	// If the above failed, attempt to create the parent node, then try again.
+	if (wp_mkdir_p(dirname($target)))
+		return wp_mkdir_p($target);
+
+	return false;
+}
+
+// Returns an array containing the current upload directory's path and url, or an error message.
+function wp_upload_dir() {
+	$siteurl = get_option('siteurl');
+	//prepend ABSPATH to $dir and $siteurl to $url if they're not already there
+	$path = str_replace(ABSPATH, '', trim(get_option('upload_path')));
+	$dir = ABSPATH . $path;
+	$url = trailingslashit($siteurl) . $path;
+
+	if ( $dir == ABSPATH ) { //the option was empty
+		$dir = ABSPATH . 'wp-content/uploads';
+	}
+
+	if ( defined('UPLOADS') ) {
+		$dir = ABSPATH . UPLOADS;
+		$url = trailingslashit($siteurl) . UPLOADS;
+	}
+
+	if ( get_option('uploads_use_yearmonth_folders')) {
+		// Generate the yearly and monthly dirs
+		$time = current_time( 'mysql' );
+		$y = substr( $time, 0, 4 );
+		$m = substr( $time, 5, 2 );
+		$dir = $dir . "/$y/$m";
+		$url = $url . "/$y/$m";
+	}
+
+	// Make sure we have an uploads dir
+	if ( ! wp_mkdir_p( $dir ) ) {
+		$message = sprintf(__('Unable to create directory %s. Is its parent directory writable by the server?'), $dir);
+		return array('error' => $message);
+	}
+
+		$uploads = array('path' => $dir, 'url' => $url, 'error' => false);
+	return apply_filters('upload_dir', $uploads);
+}
+
+function wp_upload_bits($name, $type, $bits) {
+	if ( empty($name) )
+		return array('error' => __("Empty filename"));
+
+	$wp_filetype = wp_check_filetype($name);
+	if ( !$wp_filetype['ext'] )
+		return array('error' => __("Invalid file type"));
+
+	$upload = wp_upload_dir();
+
+	if ( $upload['error'] !== false )
+		return $upload;
+
+	$number = '';
+	$filename = $name;
+	$path_parts = pathinfo($filename);
+	$ext = $path_parts['extension'];
+	if ( empty($ext) )
+		$ext = '';
+	else
+		$ext = ".$ext";
+	while ( file_exists($upload['path'] . "/$filename") ) {
+		if ( '' == "$number$ext" )
+			$filename = $filename . ++$number . $ext;
+		else
+			$filename = str_replace("$number$ext", ++$number . $ext, $filename);
+	}
+
+	$new_file = $upload['path'] . "/$filename";
+	if ( ! wp_mkdir_p( dirname($new_file) ) ) {
+		$message = sprintf(__('Unable to create directory %s. Is its parent directory writable by the server?'), dirname($new_file));
+		return array('error' => $message);
+	}
+
+	$ifp = @ fopen($new_file, 'wb');
+	if ( ! $ifp )
+		return array('error' => sprintf(__('Could not write file %s'), $new_file));
+
+	$success = @ fwrite($ifp, $bits);
+	fclose($ifp);
+	// Set correct file permissions
+	$stat = @ stat(dirname($new_file));
+	$perms = $stat['mode'] & 0007777;
+	$perms = $perms & 0000666;
+	@ chmod($new_file, $perms);
+
+	// Compute the URL
+	$url = $upload['url'] . "/$filename";
+
+	return array('file' => $new_file, 'url' => $url, 'error' => false);
+}
+
+function wp_check_filetype($filename, $mimes = null) {
+	// Accepted MIME types are set here as PCRE unless provided.
+	$mimes = is_array($mimes) ? $mimes : apply_filters('upload_mimes', array (
+		'jpg|jpeg|jpe' => 'image/jpeg',
+		'gif' => 'image/gif',
+		'png' => 'image/png',
+		'bmp' => 'image/bmp',
+		'tif|tiff' => 'image/tiff',
+		'ico' => 'image/x-icon',
+		'asf|asx|wax|wmv|wmx' => 'video/asf',
+		'avi' => 'video/avi',
+		'mov|qt' => 'video/quicktime',
+		'mpeg|mpg|mpe' => 'video/mpeg',
+		'txt|c|cc|h' => 'text/plain',
+		'rtx' => 'text/richtext',
+		'css' => 'text/css',
+		'htm|html' => 'text/html',
+		'mp3|mp4' => 'audio/mpeg',
+		'ra|ram' => 'audio/x-realaudio',
+		'wav' => 'audio/wav',
+		'ogg' => 'audio/ogg',
+		'mid|midi' => 'audio/midi',
+		'wma' => 'audio/wma',
+		'rtf' => 'application/rtf',
+		'js' => 'application/javascript',
+		'pdf' => 'application/pdf',
+		'doc' => 'application/msword',
+		'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
+		'wri' => 'application/vnd.ms-write',
+		'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
+		'mdb' => 'application/vnd.ms-access',
+		'mpp' => 'application/vnd.ms-project',
+		'swf' => 'application/x-shockwave-flash',
+		'class' => 'application/java',
+		'tar' => 'application/x-tar',
+		'zip' => 'application/zip',
+		'gz|gzip' => 'application/x-gzip',
+		'exe' => 'application/x-msdownload'
+	));
+
+	$type = false;
+	$ext = false;
+
+	foreach ($mimes as $ext_preg => $mime_match) {
+		$ext_preg = '!\.(' . $ext_preg . ')$!i';
+		if ( preg_match($ext_preg, $filename, $ext_matches) ) {
+			$type = $mime_match;
+			$ext = $ext_matches[1];
+			break;
+		}
+	}
+
+	return compact('ext', 'type');
+}
+
 function wp_explain_nonce($action) {
 	if ( $action !== -1 && preg_match('/([a-z]+)-([a-z]+)(_(.+))?/', $action, $matches) ) {
 		$verb = $matches[1];
@@ -2404,10 +1250,10 @@
 		$trans['bulk']['comments'] = array(__('Are you sure you want to bulk modify comments?'), false);
 		$trans['moderate']['comments'] = array(__('Are you sure you want to moderate comments?'), false);
 
-		$trans['add']['bookmark'] = array(__('Are you sure you want to add this bookmark?'), false);
-		$trans['delete']['bookmark'] = array(__('Are you sure you want to delete this bookmark: &quot;%s&quot;?'), 'use_id');
-		$trans['update']['bookmark'] = array(__('Are you sure you want to edit this bookmark: &quot;%s&quot;?'), 'use_id');
-		$trans['bulk']['bookmarks'] = array(__('Are you sure you want to bulk modify bookmarks?'), false);
+		$trans['add']['bookmark'] = array(__('Are you sure you want to add this link?'), false);
+		$trans['delete']['bookmark'] = array(__('Are you sure you want to delete this link: &quot;%s&quot;?'), 'use_id');
+		$trans['update']['bookmark'] = array(__('Are you sure you want to edit this link: &quot;%s&quot;?'), 'use_id');
+		$trans['bulk']['bookmarks'] = array(__('Are you sure you want to bulk modify links?'), false);
 
 		$trans['add']['page'] = array(__('Are you sure you want to add this page?'), false);
 		$trans['delete']['page'] = array(__('Are you sure you want to delete this page: &quot;%s&quot;?'), 'get_the_title');
@@ -2446,15 +1292,15 @@
 		}
 	}
 
-	return __('Are you sure you want to do this?');
+	return apply_filters( 'explain_nonce_' . $verb . '-' . $noun, __('Are you sure you want to do this?'), $matches[4] );
 }
 
 function wp_nonce_ays($action) {
 	global $pagenow, $menu, $submenu, $parent_file, $submenu_file;
 
-	$adminurl = get_settings('siteurl') . '/wp-admin';
+	$adminurl = get_option('siteurl') . '/wp-admin';
 	if ( wp_get_referer() )
-		$adminurl = wp_get_referer();
+		$adminurl = clean_url(wp_get_referer());
 
 	$title = __('WordPress Confirmation');
 	// Remove extra layer of slashes.
@@ -2462,78 +1308,217 @@
 	if ( $_POST ) {
 		$q = http_build_query($_POST);
 		$q = explode( ini_get('arg_separator.output'), $q);
-		$html .= "\t<form method='post' action='$pagenow'>\n";
+		$html .= "\t<form method='post' action='" . attribute_escape($pagenow) . "'>\n";
 		foreach ( (array) $q as $a ) {
 			$v = substr(strstr($a, '='), 1);
 			$k = substr($a, 0, -(strlen($v)+1));
-			$html .= "\t\t<input type='hidden' name='" . wp_specialchars( urldecode($k), 1 ) . "' value='" . wp_specialchars( urldecode($v), 1 ) . "' />\n";
+			$html .= "\t\t<input type='hidden' name='" . attribute_escape(urldecode($k)) . "' value='" . attribute_escape(urldecode($v)) . "' />\n";
 		}
 		$html .= "\t\t<input type='hidden' name='_wpnonce' value='" . wp_create_nonce($action) . "' />\n";
-		$html .= "\t\t<div id='message' class='confirm fade'>\n\t\t<p>" . wp_explain_nonce($action) . "</p>\n\t\t<p><a href='$adminurl'>" . __('No') . "</a> <input type='submit' value='" . __('Yes') . "' /></p>\n\t\t</div>\n\t</form>\n";
+		$html .= "\t\t<div id='message' class='confirm fade'>\n\t\t<p>" . wp_specialchars(wp_explain_nonce($action)) . "</p>\n\t\t<p><a href='$adminurl'>" . __('No') . "</a> <input type='submit' value='" . __('Yes') . "' /></p>\n\t\t</div>\n\t</form>\n";
 	} else {
-		$html .= "\t<div id='message' class='confirm fade'>\n\t<p>" . wp_explain_nonce($action) . "</p>\n\t<p><a href='$adminurl'>" . __('No') . "</a> <a href='" . add_query_arg( '_wpnonce', wp_create_nonce($action), $_SERVER['REQUEST_URI'] ) . "'>" . __('Yes') . "</a></p>\n\t</div>\n";
+		$html .= "\t<div id='message' class='confirm fade'>\n\t<p>" . wp_specialchars(wp_explain_nonce($action)) . "</p>\n\t<p><a href='$adminurl'>" . __('No') . "</a> <a href='" . clean_url(add_query_arg( '_wpnonce', wp_create_nonce($action), $_SERVER['REQUEST_URI'] )) . "'>" . __('Yes') . "</a></p>\n\t</div>\n";
 	}
 	$html .= "</body>\n</html>";
 	wp_die($html, $title);
 }
 
-function wp_die($message, $title = '') {
+function wp_die( $message, $title = '' ) {
+	global $wp_locale;
+
+	if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
+		if ( empty($title) ) {
+			$error_data = $message->get_error_data();
+			if ( is_array($error_data) && isset($error_data['title']) )
+				$title = $error_data['title'];
+		}
+		$errors = $message->get_error_messages();
+		switch ( count($errors) ) :
+		case 0 :
+			$message = '';
+			break;
+		case 1 :
+			$message = "<p>{$errors[0]}</p>";
+			break;
+		default :
+			$message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
+			break;
+		endswitch;
+	} elseif ( is_string($message) ) {
+		$message = "<p>$message</p>";
+	}
+
+	if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false)
+		$admin_dir = '';
+	else
+		$admin_dir = 'wp-admin/';
+
+	if ( !did_action('admin_head') ) :
 	header('Content-Type: text/html; charset=utf-8');
 
 	if ( empty($title) )
 		$title = __('WordPress &rsaquo; Error');
+
+
+
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists('language_attributes') ) language_attributes(); ?>>
 <head>
 	<title><?php echo $title ?></title>
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-	<style media="screen" type="text/css">
-	<!--
-	html {
-		background: #eee;
-	}
-	body {
-		background: #fff;
-		color: #000;
-		font-family: Georgia, "Times New Roman", Times, serif;
-		margin-left: 25%;
-		margin-right: 25%;
-		padding: .2em 2em;
-	}
+	<link rel="stylesheet" href="<?php echo $admin_dir; ?>install.css" type="text/css" />
+<?php 
+if ( ( $wp_locale ) && ('rtl' == $wp_locale->text_direction) ) : ?>
+	<link rel="stylesheet" href="<?php echo $admin_dir; ?>install-rtl.css" type="text/css" />
+<?php endif; ?>
+</head>
+<body>
+<?php endif; ?>
+	<h1 id="logo"><img alt="WordPress" src="<?php echo $admin_dir; ?>images/wordpress-logo.png" /></h1>
+	<?php echo $message; ?>
 
-	h1 {
-		color: #006;
-		font-size: 18px;
-		font-weight: lighter;
-	}
+</body>
+</html>
+<?php
+	die();
+}
 
-	h2 {
-		font-size: 16px;
+function _config_wp_home($url = '') {
+	if ( defined( 'WP_HOME' ) ) 
+		return WP_HOME;
+	else return $url;
+}
+
+function _config_wp_siteurl($url = '') {
+	if ( defined( 'WP_SITEURL' ) ) 
+		return WP_SITEURL;
+	else return $url;
+}
+
+function _mce_set_direction() {
+	global $wp_locale;
+
+	if ('rtl' == $wp_locale->text_direction) {
+		echo 'directionality : "rtl" ,';
+		echo 'theme_advanced_toolbar_align : "right" ,';
 	}
+}
+
+function _mce_load_rtl_plugin($input) {
+	global $wp_locale;
+
+	if ('rtl' == $wp_locale->text_direction)
+		$input[] = 'directionality';
 
-	p, li, dt {
-		line-height: 140%;
-		padding-bottom: 2px;
+	return $input;
+}
+
+function _mce_add_direction_buttons($input) {
+	global $wp_locale;
+
+	if ('rtl' == $wp_locale->text_direction) {
+		$new_buttons = array('separator', 'ltr', 'rtl');
+		$input = array_merge($input, $new_buttons);
 	}
 
-	ul, ol {
-		padding: 5px 5px 5px 20px;
+	return $input;
+}
+
+function smilies_init() {
+	global $wpsmiliestrans, $wp_smiliessearch, $wp_smiliesreplace;
+
+	// don't bother setting up smilies if they are disabled
+	if ( !get_option('use_smilies') )
+		return;
+
+	if (!isset($wpsmiliestrans)) {
+		$wpsmiliestrans = array(
+		':mrgreen:' => 'icon_mrgreen.gif',
+		':neutral:' => 'icon_neutral.gif',
+		':twisted:' => 'icon_twisted.gif',
+		  ':arrow:' => 'icon_arrow.gif',
+		  ':shock:' => 'icon_eek.gif',
+		  ':smile:' => 'icon_smile.gif',
+		    ':???:' => 'icon_confused.gif',
+		   ':cool:' => 'icon_cool.gif',
+		   ':evil:' => 'icon_evil.gif',
+		   ':grin:' => 'icon_biggrin.gif',
+		   ':idea:' => 'icon_idea.gif',
+		   ':oops:' => 'icon_redface.gif',
+		   ':razz:' => 'icon_razz.gif',
+		   ':roll:' => 'icon_rolleyes.gif',
+		   ':wink:' => 'icon_wink.gif',
+		    ':cry:' => 'icon_cry.gif',
+		    ':eek:' => 'icon_surprised.gif',
+		    ':lol:' => 'icon_lol.gif',
+		    ':mad:' => 'icon_mad.gif',
+		    ':sad:' => 'icon_sad.gif',
+		      '8-)' => 'icon_cool.gif',
+		      '8-O' => 'icon_eek.gif',
+		      ':-(' => 'icon_sad.gif',
+		      ':-)' => 'icon_smile.gif',
+		      ':-?' => 'icon_confused.gif',
+		      ':-D' => 'icon_biggrin.gif',
+		      ':-P' => 'icon_razz.gif',
+		      ':-o' => 'icon_surprised.gif',
+		      ':-x' => 'icon_mad.gif',
+		      ':-|' => 'icon_neutral.gif',
+		      ';-)' => 'icon_wink.gif',
+		       '8)' => 'icon_cool.gif',
+		       '8O' => 'icon_eek.gif',
+		       ':(' => 'icon_sad.gif',
+		       ':)' => 'icon_smile.gif',
+		       ':?' => 'icon_confused.gif',
+		       ':D' => 'icon_biggrin.gif',
+		       ':P' => 'icon_razz.gif',
+		       ':o' => 'icon_surprised.gif',
+		       ':x' => 'icon_mad.gif',
+		       ':|' => 'icon_neutral.gif',
+		       ';)' => 'icon_wink.gif',
+		      ':!:' => 'icon_exclaim.gif',
+		      ':?:' => 'icon_question.gif',
+		);
+	}
+
+	$siteurl = get_option('siteurl');
+	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
+		$wp_smiliessearch[] = '/(\s|^)'.preg_quote($smiley, '/').'(\s|$)/';
+		$smiley_masked = htmlspecialchars(trim($smiley), ENT_QUOTES);
+		$wp_smiliesreplace[] = " <img src='$siteurl/wp-includes/images/smilies/$img' alt='$smiley_masked' class='wp-smiley' /> ";
 	}
-	#logo {
-		margin-bottom: 2em;
+}
+
+function wp_parse_args( $args, $defaults = '' ) {
+	if ( is_array( $args ) )
+		$r =& $args;
+	else
+		wp_parse_str( $args, $r );
+
+	if ( is_array( $defaults ) )
+		return array_merge( $defaults, $r );
+	else
+		return $r;
+}
+
+function wp_maybe_load_widgets() {
+	if ( !function_exists( 'dynamic_sidebar' ) ) {
+		require_once ABSPATH . WPINC . '/widgets.php';
+		add_action( '_admin_menu', 'wp_widgets_add_menu' );
 	}
-	-->
-	</style>
-</head>
-<body>
-	<h1 id="logo"><img alt="WordPress" src="<?php echo get_settings('siteurl'); ?>/wp-admin/images/wordpress-logo.png" /></h1>
-	<p><?php echo $message; ?></p>
-</body>
-</html>
-<?php
+}
 
-	die();
+function wp_widgets_add_menu() {
+	global $submenu;
+	$submenu['themes.php'][7] = array( __( 'Widgets' ), 'switch_themes', 'widgets.php' );
+	ksort($submenu['themes.php'], SORT_NUMERIC);
+}
+
+// For PHP 5.2, make sure all output buffers are flushed
+// before our singletons our destroyed.
+function wp_ob_end_flush_all()
+{
+	while ( @ob_end_flush() );
 }
 
 ?>
diff -ruN 2.0.5/wp-includes/general-template.php 2.2.2/wp-includes/general-template.php
--- 2.0.5/wp-includes/general-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/general-template.php	2007-07-05 15:12:07.000000000 -0500
@@ -0,0 +1,1040 @@
+<?php
+
+/* Note: these tags go anywhere in the template */
+
+function get_header() {
+	do_action( 'get_header' );
+	if ( file_exists( TEMPLATEPATH . '/header.php') )
+		load_template( TEMPLATEPATH . '/header.php');
+	else
+		load_template( ABSPATH . 'wp-content/themes/default/header.php');
+}
+
+
+function get_footer() {
+	do_action( 'get_footer' );
+	if ( file_exists( TEMPLATEPATH . '/footer.php') )
+		load_template( TEMPLATEPATH . '/footer.php');
+	else
+		load_template( ABSPATH . 'wp-content/themes/default/footer.php');
+}
+
+
+function get_sidebar() {
+	do_action( 'get_sidebar' );
+	if ( file_exists( TEMPLATEPATH . '/sidebar.php') )
+		load_template( TEMPLATEPATH . '/sidebar.php');
+	else
+		load_template( ABSPATH . 'wp-content/themes/default/sidebar.php');
+}
+
+
+function wp_loginout() {
+	if ( ! is_user_logged_in() )
+		$link = '<a href="' . get_option('siteurl') . '/wp-login.php">' . __('Login') . '</a>';
+	else
+		$link = '<a href="' . get_option('siteurl') . '/wp-login.php?action=logout">' . __('Logout') . '</a>';
+
+	echo apply_filters('loginout', $link);
+}
+
+
+function wp_register( $before = '<li>', $after = '</li>' ) {
+
+	if ( ! is_user_logged_in() ) {
+		if ( get_option('users_can_register') )
+			$link = $before . '<a href="' . get_option('siteurl') . '/wp-login.php?action=register">' . __('Register') . '</a>' . $after;
+		else
+			$link = '';
+	} else {
+		$link = $before . '<a href="' . get_option('siteurl') . '/wp-admin/">' . __('Site Admin') . '</a>' . $after;
+	}
+
+	echo apply_filters('register', $link);
+}
+
+
+function wp_meta() {
+	do_action('wp_meta');
+}
+
+
+function bloginfo($show='') {
+	$info = get_bloginfo($show);
+	
+	// Don't filter URL's.
+	if (strpos($show, 'url') === false &&
+		strpos($show, 'directory') === false &&
+		strpos($show, 'home') === false) {
+		$info = apply_filters('bloginfo', $info, $show);
+		$info = convert_chars($info);
+	} else {
+		$info = apply_filters('bloginfo_url', $info, $show);
+	}
+
+	echo $info;
+}
+
+/**
+ * Note: some of these values are DEPRECATED. Meaning they could be 
+ * taken out at any time and shouldn't be relied upon. Options 
+ * without "// DEPRECATED" are the preferred and recommended ways 
+ * to get the information.
+ */
+function get_bloginfo($show='') {
+
+	switch($show) {
+		case 'url' :
+		case 'home' : // DEPRECATED
+		case 'siteurl' : // DEPRECATED
+			$output = get_option('home');
+			break;
+		case 'wpurl' :
+			$output = get_option('siteurl');
+			break;
+		case 'description':
+			$output = get_option('blogdescription');
+			break;
+		case 'rdf_url':
+			$output = get_feed_link('rdf');
+			break;
+		case 'rss_url':
+			$output = get_feed_link('rss');
+			break;
+		case 'rss2_url':
+			$output = get_feed_link('rss2');
+			break;
+		case 'atom_url':
+			$output = get_feed_link('atom');
+			break;
+		case 'comments_atom_url':
+			$output = get_feed_link('comments_atom');
+			break;
+		case 'comments_rss2_url':
+			$output = get_feed_link('comments_rss2');
+			break;
+		case 'pingback_url':
+			$output = get_option('siteurl') .'/xmlrpc.php';
+			break;
+		case 'stylesheet_url':
+			$output = get_stylesheet_uri();
+			break;
+		case 'stylesheet_directory':
+			$output = get_stylesheet_directory_uri();
+			break;
+		case 'template_directory':
+		case 'template_url':
+			$output = get_template_directory_uri();
+			break;
+		case 'admin_email':
+			$output = get_option('admin_email');
+			break;
+		case 'charset':
+			$output = get_option('blog_charset');
+			if ('' == $output) $output = 'UTF-8';
+			break;
+		case 'html_type' :
+			$output = get_option('html_type');
+			break;
+		case 'version':
+			global $wp_version;
+			$output = $wp_version;
+			break;
+		case 'language':
+			$output = get_locale();
+			$output = str_replace('_', '-', $output);
+			break;
+		case 'text_direction':
+			global $wp_locale;
+			$output = $wp_locale->text_direction;
+			break;
+		case 'name':
+		default:
+			$output = get_option('blogname');
+			break;
+	}
+	return $output;
+}
+
+
+function wp_title($sep = '&raquo;', $display = true) {
+	global $wpdb, $wp_locale, $wp_query;
+
+	$cat = get_query_var('cat');
+	$p = get_query_var('p');
+	$name = get_query_var('name');
+	$category_name = get_query_var('category_name');
+	$author = get_query_var('author');
+	$author_name = get_query_var('author_name');
+	$m = get_query_var('m');
+	$year = get_query_var('year');
+	$monthnum = get_query_var('monthnum');
+	$day = get_query_var('day');
+	$title = '';
+
+	// If there's a category
+	if ( !empty($cat) ) {
+			// category exclusion
+			if ( !stristr($cat,'-') )
+				$title = apply_filters('single_cat_title', get_the_category_by_ID($cat));
+	} elseif ( !empty($category_name) ) {
+		if ( stristr($category_name,'/') ) {
+				$category_name = explode('/',$category_name);
+				if ( $category_name[count($category_name)-1] )
+					$category_name = $category_name[count($category_name)-1]; // no trailing slash
+				else
+					$category_name = $category_name[count($category_name)-2]; // there was a trailling slash
+		}
+		$title = $wpdb->get_var("SELECT cat_name FROM $wpdb->categories WHERE category_nicename = '$category_name'");
+		$title = apply_filters('single_cat_title', $title);
+	}
+
+	// If there's an author
+	if ( !empty($author) ) {
+		$title = get_userdata($author);
+		$title = $title->display_name;
+	}
+	if ( !empty($author_name) ) {
+		// We do a direct query here because we don't cache by nicename.
+		$title = $wpdb->get_var("SELECT display_name FROM $wpdb->users WHERE user_nicename = '$author_name'");
+	}
+
+	// If there's a month
+	if ( !empty($m) ) {
+		$my_year = substr($m, 0, 4);
+		$my_month = $wp_locale->get_month(substr($m, 4, 2));
+		$my_day = intval(substr($m, 6, 2));
+		$title = "$my_year" . ($my_month ? "$sep $my_month" : "") . ($my_day ? "$sep $my_day" : "");
+	}
+
+	if ( !empty($year) ) {
+		$title = $year;
+		if ( !empty($monthnum) )
+			$title .= " $sep " . $wp_locale->get_month($monthnum);
+		if ( !empty($day) )
+			$title .= " $sep " . zeroise($day, 2);
+	}
+
+	// If there is a post
+	if ( is_single() || is_page() ) {
+		$post = $wp_query->get_queried_object();
+		$title = strip_tags( apply_filters( 'single_post_title', $post->post_title ) );
+	}
+
+	$prefix = '';
+	if ( !empty($title) )
+		$prefix = " $sep ";
+
+	$title = $prefix . $title;
+	$title = apply_filters('wp_title', $title, $sep);
+
+	// Send it out
+	if ( $display )
+		echo $title;
+	else
+		return $title;
+}
+
+
+function single_post_title($prefix = '', $display = true) {
+	global $wpdb;
+	$p = get_query_var('p');
+	$name = get_query_var('name');
+
+	if ( intval($p) || '' != $name ) {
+		if ( !$p )
+			$p = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_name = '$name'");
+		$post = & get_post($p);
+		$title = $post->post_title;
+		$title = apply_filters('single_post_title', $title);
+		if ( $display )
+			echo $prefix.strip_tags($title);
+		else
+			return strip_tags($title);
+	}
+}
+
+
+function single_cat_title($prefix = '', $display = true ) {
+	$cat = intval( get_query_var('cat') );
+	if ( !empty($cat) && !(strtoupper($cat) == 'ALL') ) {
+		$my_cat_name = apply_filters('single_cat_title', get_the_category_by_ID($cat));
+		if ( !empty($my_cat_name) ) {
+			if ( $display )
+				echo $prefix.strip_tags($my_cat_name);
+			else
+				return strip_tags($my_cat_name);
+		}
+	}
+}
+
+
+function single_month_title($prefix = '', $display = true ) {
+	global $wp_locale;
+
+	$m = get_query_var('m');
+	$year = get_query_var('year');
+	$monthnum = get_query_var('monthnum');
+
+	if ( !empty($monthnum) && !empty($year) ) {
+		$my_year = $year;
+		$my_month = $wp_locale->get_month($monthnum);
+	} elseif ( !empty($m) ) {
+		$my_year = substr($m, 0, 4);
+		$my_month = $wp_locale->get_month(substr($m, 4, 2));
+	}
+
+	if ( empty($my_month) )
+		return false;
+
+	$result = $prefix . $my_month . $prefix . $my_year;
+
+	if ( !$display )
+		return $result;
+	echo $result;
+}
+
+
+/* link navigation hack by Orien http://icecode.com/ */
+function get_archives_link($url, $text, $format = 'html', $before = '', $after = '') {
+	$text = wptexturize($text);
+	$title_text = attribute_escape($text);
+	$url = clean_url($url);
+
+	if ('link' == $format)
+		return "\t<link rel='archives' title='$title_text' href='$url' />\n";
+	elseif ('option' == $format)
+		return "\t<option value='$url'>$before $text $after</option>\n";
+	elseif ('html' == $format)
+		return "\t<li>$before<a href='$url' title='$title_text'>$text</a>$after</li>\n";
+	else // custom
+		return "\t$before<a href='$url' title='$title_text'>$text</a>$after\n";
+}
+
+
+function wp_get_archives($args = '') {
+	global $wp_locale, $wpdb;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('type' => 'monthly', 'limit' => '', 'format' => 'html', 'before' => '', 'after' => '', 'show_post_count' => false);
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	if ( '' == $type )
+		$type = 'monthly';
+
+	if ( '' != $limit ) {
+		$limit = (int) $limit;
+		$limit = ' LIMIT '.$limit;
+	}
+
+	// this is what will separate dates on weekly archive links
+	$archive_week_separator = '&#8211;';
+
+	// over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
+	$archive_date_format_over_ride = 0;
+
+	// options for daily archive (only if you over-ride the general date format)
+	$archive_day_date_format = 'Y/m/d';
+
+	// options for weekly archive (only if you over-ride the general date format)
+	$archive_week_start_date_format = 'Y/m/d';
+	$archive_week_end_date_format	= 'Y/m/d';
+
+	if ( !$archive_date_format_over_ride ) {
+		$archive_day_date_format = get_option('date_format');
+		$archive_week_start_date_format = get_option('date_format');
+		$archive_week_end_date_format = get_option('date_format');
+	}
+
+	$add_hours = intval(get_option('gmt_offset'));
+	$add_minutes = intval(60 * (get_option('gmt_offset') - $add_hours));
+
+	//filters
+	$where = apply_filters('getarchives_where', "WHERE post_type = 'post' AND post_status = 'publish'", $r );
+	$join = apply_filters('getarchives_join', "", $r);
+
+	if ( 'monthly' == $type ) {
+		$arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC" . $limit);
+		if ( $arcresults ) {
+			$afterafter = $after;
+			foreach ( $arcresults as $arcresult ) {
+				$url	= get_month_link($arcresult->year,	$arcresult->month);
+				$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
+				if ( $show_post_count ) 
+					$after = '&nbsp;('.$arcresult->posts.')' . $afterafter;
+				echo get_archives_link($url, $text, $format, $before, $after);
+			}
+		}
+	} elseif ('yearly' == $type) {
+         $arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date DESC" . $limit);
+		if ($arcresults) {
+			$afterafter = $after;
+			foreach ($arcresults as $arcresult) {
+				$url = get_year_link($arcresult->year);
+				$text = sprintf('%d', $arcresult->year);
+				if ($show_post_count)
+					$after = '&nbsp;('.$arcresult->posts.')' . $afterafter;
+				echo get_archives_link($url, $text, $format, $before, $after);
+			}
+		}
+	} elseif ( 'daily' == $type ) {
+		$arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date DESC" . $limit);
+		if ( $arcresults ) {
+			$afterafter = $after;
+			foreach ( $arcresults as $arcresult ) {
+				$url	= get_day_link($arcresult->year, $arcresult->month, $arcresult->dayofmonth);
+				$date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $arcresult->year, $arcresult->month, $arcresult->dayofmonth);
+				$text = mysql2date($archive_day_date_format, $date);
+				if ($show_post_count)
+					$after = '&nbsp;('.$arcresult->posts.')'.$afterafter;
+				echo get_archives_link($url, $text, $format, $before, $after);
+			}
+		}
+	} elseif ( 'weekly' == $type ) {
+		$start_of_week = get_option('start_of_week');
+		$arcresults = $wpdb->get_results("SELECT DISTINCT WEEK(post_date, $start_of_week) AS `week`, YEAR(post_date) AS yr, DATE_FORMAT(post_date, '%Y-%m-%d') AS yyyymmdd, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY WEEK(post_date, $start_of_week), YEAR(post_date) ORDER BY post_date DESC" . $limit);
+		$arc_w_last = '';
+		$afterafter = $after;
+		if ( $arcresults ) {
+				foreach ( $arcresults as $arcresult ) {
+					if ( $arcresult->week != $arc_w_last ) {
+						$arc_year = $arcresult->yr;
+						$arc_w_last = $arcresult->week;
+						$arc_week = get_weekstartend($arcresult->yyyymmdd, get_option('start_of_week'));
+						$arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
+						$arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
+						$url  = sprintf('%1$s/%2$s%3$sm%4$s%5$s%6$sw%7$s%8$d', get_option('home'), '', '?', '=', $arc_year, '&amp;', '=', $arcresult->week);
+						$text = $arc_week_start . $archive_week_separator . $arc_week_end;
+						if ($show_post_count)
+							$after = '&nbsp;('.$arcresult->posts.')'.$afterafter;
+						echo get_archives_link($url, $text, $format, $before, $after);
+					}
+				}
+		}
+	} elseif ( ( 'postbypost' == $type ) || ('alpha' == $type) ) {
+		('alpha' == $type) ? $orderby = "post_title ASC " : $orderby = "post_date DESC ";
+		$arcresults = $wpdb->get_results("SELECT * FROM $wpdb->posts $join $where ORDER BY $orderby $limit");
+		if ( $arcresults ) {
+			foreach ( $arcresults as $arcresult ) {
+				if ( $arcresult->post_date != '0000-00-00 00:00:00' ) {
+					$url  = get_permalink($arcresult);
+					$arc_title = $arcresult->post_title;
+					if ( $arc_title )
+						$text = strip_tags(apply_filters('the_title', $arc_title));
+					else
+						$text = $arcresult->ID;
+					echo get_archives_link($url, $text, $format, $before, $after);
+				}
+			}
+		}
+	}
+}
+
+
+// Used in get_calendar
+function calendar_week_mod($num) {
+	$base = 7;
+	return ($num - $base*floor($num/$base));
+}
+
+
+function get_calendar($initial = true) {
+	global $wpdb, $m, $monthnum, $year, $timedifference, $wp_locale, $posts;
+
+	$key = md5( $m . $monthnum . $year );
+	if ( $cache = wp_cache_get( 'get_calendar', 'calendar' ) ) {
+		if ( isset( $cache[ $key ] ) ) {
+			echo $cache[ $key ];
+			return;
+		}
+	}
+
+	ob_start();
+	// Quick check. If we have no posts at all, abort!
+	if ( !$posts ) {
+		$gotsome = $wpdb->get_var("SELECT ID from $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1");
+		if ( !$gotsome )
+			return;
+	}
+
+	if ( isset($_GET['w']) )
+		$w = ''.intval($_GET['w']);
+
+	// week_begins = 0 stands for Sunday
+	$week_begins = intval(get_option('start_of_week'));
+	$add_hours = intval(get_option('gmt_offset'));
+	$add_minutes = intval(60 * (get_option('gmt_offset') - $add_hours));
+
+	// Let's figure out when we are
+	if ( !empty($monthnum) && !empty($year) ) {
+		$thismonth = ''.zeroise(intval($monthnum), 2);
+		$thisyear = ''.intval($year);
+	} elseif ( !empty($w) ) {
+		// We need to get the month from MySQL
+		$thisyear = ''.intval(substr($m, 0, 4));
+		$d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
+		$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('${thisyear}0101', INTERVAL $d DAY) ), '%m')");
+	} elseif ( !empty($m) ) {
+		$calendar = substr($m, 0, 6);
+		$thisyear = ''.intval(substr($m, 0, 4));
+		if ( strlen($m) < 6 )
+				$thismonth = '01';
+		else
+				$thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
+	} else {
+		$thisyear = gmdate('Y', current_time('timestamp'));
+		$thismonth = gmdate('m', current_time('timestamp'));
+	}
+
+	$unixmonth = mktime(0, 0 , 0, $thismonth, 1, $thisyear);
+
+	// Get the next and previous month and year with at least one post
+	$previous = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
+		FROM $wpdb->posts
+		WHERE post_date < '$thisyear-$thismonth-01'
+		AND post_type = 'post' AND post_status = 'publish'
+			ORDER BY post_date DESC
+			LIMIT 1");
+	$next = $wpdb->get_row("SELECT	DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
+		FROM $wpdb->posts
+		WHERE post_date >	'$thisyear-$thismonth-01'
+		AND MONTH( post_date ) != MONTH( '$thisyear-$thismonth-01' )
+		AND post_type = 'post' AND post_status = 'publish'
+			ORDER	BY post_date ASC
+			LIMIT 1");
+
+	echo '<table id="wp-calendar" summary="' . __('Calendar') . '">
+	<caption>' . $wp_locale->get_month($thismonth) . ' ' . date('Y', $unixmonth) . '</caption>
+	<thead>
+	<tr>';
+
+	$myweek = array();
+
+	for ( $wdcount=0; $wdcount<=6; $wdcount++ ) {
+		$myweek[] = $wp_locale->get_weekday(($wdcount+$week_begins)%7);
+	}
+
+	foreach ( $myweek as $wd ) {
+		$day_name = (true == $initial) ? $wp_locale->get_weekday_initial($wd) : $wp_locale->get_weekday_abbrev($wd);
+		echo "\n\t\t<th abbr=\"$wd\" scope=\"col\" title=\"$wd\">$day_name</th>";
+	}
+
+	echo '
+	</tr>
+	</thead>
+
+	<tfoot>
+	<tr>';
+
+	if ( $previous ) {
+		echo "\n\t\t".'<td abbr="' . $wp_locale->get_month($previous->month) . '" colspan="3" id="prev"><a href="' .
+		get_month_link($previous->year, $previous->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($previous->month),
+			date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year))) . '">&laquo; ' . $wp_locale->get_month_abbrev($wp_locale->get_month($previous->month)) . '</a></td>';
+	} else {
+		echo "\n\t\t".'<td colspan="3" id="prev" class="pad">&nbsp;</td>';
+	}
+
+	echo "\n\t\t".'<td class="pad">&nbsp;</td>';
+
+	if ( $next ) {
+		echo "\n\t\t".'<td abbr="' . $wp_locale->get_month($next->month) . '" colspan="3" id="next"><a href="' .
+		get_month_link($next->year, $next->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($next->month),
+			date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year))) . '">' . $wp_locale->get_month_abbrev($wp_locale->get_month($next->month)) . ' &raquo;</a></td>';
+	} else {
+		echo "\n\t\t".'<td colspan="3" id="next" class="pad">&nbsp;</td>';
+	}
+
+	echo '
+	</tr>
+	</tfoot>
+
+	<tbody>
+	<tr>';
+
+	// Get days with posts
+	$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
+		FROM $wpdb->posts WHERE MONTH(post_date) = '$thismonth'
+		AND YEAR(post_date) = '$thisyear'
+		AND post_type = 'post' AND post_status = 'publish'
+		AND post_date < '" . current_time('mysql') . '\'', ARRAY_N);
+	if ( $dayswithposts ) {
+		foreach ( $dayswithposts as $daywith ) {
+			$daywithpost[] = $daywith[0];
+		}
+	} else {
+		$daywithpost = array();
+	}
+
+	if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'camino') !== false || strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari') !== false)
+		$ak_title_separator = "\n";
+	else
+		$ak_title_separator = ', ';
+
+	$ak_titles_for_day = array();
+	$ak_post_titles = $wpdb->get_results("SELECT post_title, DAYOFMONTH(post_date) as dom "
+		."FROM $wpdb->posts "
+		."WHERE YEAR(post_date) = '$thisyear' "
+		."AND MONTH(post_date) = '$thismonth' "
+		."AND post_date < '".current_time('mysql')."' "
+		."AND post_type = 'post' AND post_status = 'publish'"
+	);
+	if ( $ak_post_titles ) {
+		foreach ( $ak_post_titles as $ak_post_title ) {
+			
+				$post_title = apply_filters( "the_title", $ak_post_title->post_title );
+				$post_title = str_replace('"', '&quot;', wptexturize( $post_title ));
+								
+				if ( empty($ak_titles_for_day['day_'.$ak_post_title->dom]) )
+					$ak_titles_for_day['day_'.$ak_post_title->dom] = '';
+				if ( empty($ak_titles_for_day["$ak_post_title->dom"]) ) // first one
+					$ak_titles_for_day["$ak_post_title->dom"] = $post_title;
+				else
+					$ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . $post_title;
+		}
+	}
+
+
+	// See how much we should pad in the beginning
+	$pad = calendar_week_mod(date('w', $unixmonth)-$week_begins);
+	if ( 0 != $pad )
+		echo "\n\t\t".'<td colspan="'.$pad.'" class="pad">&nbsp;</td>';
+
+	$daysinmonth = intval(date('t', $unixmonth));
+	for ( $day = 1; $day <= $daysinmonth; ++$day ) {
+		if ( isset($newrow) && $newrow )
+			echo "\n\t</tr>\n\t<tr>\n\t\t";
+		$newrow = false;
+
+		if ( $day == gmdate('j', (time() + (get_option('gmt_offset') * 3600))) && $thismonth == gmdate('m', time()+(get_option('gmt_offset') * 3600)) && $thisyear == gmdate('Y', time()+(get_option('gmt_offset') * 3600)) )
+			echo '<td id="today">';
+		else
+			echo '<td>';
+
+		if ( in_array($day, $daywithpost) ) // any posts today?
+				echo '<a href="' . get_day_link($thisyear, $thismonth, $day) . "\" title=\"$ak_titles_for_day[$day]\">$day</a>";
+		else
+			echo $day;
+		echo '</td>';
+
+		if ( 6 == calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins) )
+			$newrow = true;
+	}
+
+	$pad = 7 - calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins);
+	if ( $pad != 0 && $pad != 7 )
+		echo "\n\t\t".'<td class="pad" colspan="'.$pad.'">&nbsp;</td>';
+
+	echo "\n\t</tr>\n\t</tbody>\n\t</table>";
+
+	$output = ob_get_contents();
+	ob_end_clean();
+	echo $output;
+	$cache[ $key ] = $output;
+	wp_cache_add( 'get_calendar', $cache, 'calendar' );
+}
+
+function delete_get_calendar_cache() {
+	wp_cache_delete( 'get_calendar', 'calendar' );
+}
+add_action( 'save_post', 'delete_get_calendar_cache' );
+add_action( 'delete_post', 'delete_get_calendar_cache' );
+add_action( 'update_option_start_of_week', 'delete_get_calendar_cache' );
+add_action( 'update_option_gmt_offset', 'delete_get_calendar_cache' );
+add_action( 'update_option_start_of_week', 'delete_get_calendar_cache' );
+
+
+function allowed_tags() {
+	global $allowedtags;
+	$allowed = '';
+	foreach ( $allowedtags as $tag => $attributes ) {
+		$allowed .= '<'.$tag;
+		if ( 0 < count($attributes) ) {
+			foreach ( $attributes as $attribute => $limits ) {
+				$allowed .= ' '.$attribute.'=""';
+			}
+		}
+		$allowed .= '> ';
+	}
+	return htmlentities($allowed);
+}
+
+
+/***** Date/Time tags *****/
+
+
+function the_date_xml() {
+	global $post;
+	echo mysql2date('Y-m-d', $post->post_date);
+	//echo ""+$post->post_date;
+}
+
+
+function the_date($d='', $before='', $after='', $echo = true) {
+	global $id, $post, $day, $previousday, $newday;
+	$the_date = '';
+	if ( $day != $previousday ) {
+		$the_date .= $before;
+		if ( $d=='' )
+			$the_date .= mysql2date(get_option('date_format'), $post->post_date);
+		else
+			$the_date .= mysql2date($d, $post->post_date);
+		$the_date .= $after;
+		$previousday = $day;
+	}
+	$the_date = apply_filters('the_date', $the_date, $d, $before, $after);
+	if ( $echo )
+		echo $the_date;
+	else
+		return $the_date;
+}
+
+
+function the_modified_date($d = '') {
+	echo apply_filters('the_modified_date', get_the_modified_date($d), $d);
+}
+
+
+function get_the_modified_date($d = '') {
+	if ( '' == $d )
+		$the_time = get_post_modified_time(get_option('date_format'));
+	else
+		$the_time = get_post_modified_time($d);
+	return apply_filters('get_the_modified_date', $the_time, $d);
+}
+
+
+function the_time( $d = '' ) {
+	echo apply_filters('the_time', get_the_time( $d ), $d);
+}
+
+
+function get_the_time( $d = '' ) {
+	if ( '' == $d )
+		$the_time = get_post_time(get_option('time_format'));
+	else
+		$the_time = get_post_time($d);
+	return apply_filters('get_the_time', $the_time, $d);
+}
+
+
+function get_post_time( $d = 'U', $gmt = false ) { // returns timestamp
+	global $post;
+	if ( $gmt )
+		$time = $post->post_date_gmt;
+	else
+		$time = $post->post_date;
+
+	$time = mysql2date($d, $time);
+	return apply_filters('get_the_time', $time, $d, $gmt);
+}
+
+
+function the_modified_time($d = '') {
+	echo apply_filters('the_modified_time', get_the_modified_time($d), $d);
+}
+
+
+function get_the_modified_time($d = '') {
+	if ( '' == $d )
+		$the_time = get_post_modified_time(get_option('time_format'));
+	else
+		$the_time = get_post_modified_time($d);
+	return apply_filters('get_the_modified_time', $the_time, $d);
+}
+
+
+function get_post_modified_time( $d = 'U', $gmt = false ) { // returns timestamp
+	global $post;
+
+	if ( $gmt )
+		$time = $post->post_modified_gmt;
+	else
+		$time = $post->post_modified;
+	$time = mysql2date($d, $time);
+
+	return apply_filters('get_the_modified_time', $time, $d, $gmt);
+}
+
+
+function the_weekday() {
+	global $wp_locale, $id, $post;
+	$the_weekday = $wp_locale->get_weekday(mysql2date('w', $post->post_date));
+	$the_weekday = apply_filters('the_weekday', $the_weekday);
+	echo $the_weekday;
+}
+
+
+function the_weekday_date($before='',$after='') {
+	global $wp_locale, $id, $post, $day, $previousweekday;
+	$the_weekday_date = '';
+	if ( $day != $previousweekday ) {
+		$the_weekday_date .= $before;
+		$the_weekday_date .= $wp_locale->get_weekday(mysql2date('w', $post->post_date));
+		$the_weekday_date .= $after;
+		$previousweekday = $day;
+	}
+	$the_weekday_date = apply_filters('the_weekday_date', $the_weekday_date, $before, $after);
+	echo $the_weekday_date;
+}
+
+function wp_head() {
+	do_action('wp_head');
+}
+
+function wp_footer() {
+	do_action('wp_footer');
+}
+
+function rsd_link() {
+	echo '	<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . get_bloginfo('wpurl') . "/xmlrpc.php?rsd\" />\n";
+}
+
+function noindex() {
+	// If the blog is not public, tell robots to go away.
+	if ( '0' == get_option('blog_public') )
+		echo "<meta name='robots' content='noindex,nofollow' />\n";
+}
+
+function rich_edit_exists() {
+	global $wp_rich_edit_exists;
+	if ( !isset($wp_rich_edit_exists) )
+		$wp_rich_edit_exists = file_exists(ABSPATH . WPINC . '/js/tinymce/tiny_mce.js');
+	return $wp_rich_edit_exists;
+}
+
+function user_can_richedit() {
+	global $wp_rich_edit, $pagenow;
+	
+	if ( !isset( $wp_rich_edit) ) {
+		if ( get_user_option( 'rich_editing' ) == 'true' && 
+			( ( preg_match( '!AppleWebKit/(\d+)!', $_SERVER['HTTP_USER_AGENT'], $match ) && intval($match[1]) >= 420 ) || 
+				!preg_match( '!opera[ /][2-8]|konqueror|safari!i', $_SERVER['HTTP_USER_AGENT'] ) )
+				&& 'comment.php' != $pagenow ) {
+			$wp_rich_edit = true;
+		} else {
+			$wp_rich_edit = false;
+		}
+	}
+
+	return apply_filters('user_can_richedit', $wp_rich_edit);
+}
+
+function the_editor($content, $id = 'content', $prev_id = 'title') {
+	$rows = get_option('default_post_edit_rows');
+	if (($rows < 3) || ($rows > 100))
+		$rows = 12;
+
+	$rows = "rows='$rows'";
+
+	if ( user_can_richedit() ) :
+		add_filter('the_editor_content', 'wp_richedit_pre');
+
+		//	The following line moves the border so that the active button "attaches" to the toolbar. Only IE needs it.
+	?>
+	<style type="text/css">
+		#postdivrich table, #postdivrich #quicktags {border-top: none;}
+		#quicktags {border-bottom: none; padding-bottom: 2px; margin-bottom: -1px;}
+		#edButtons {border-bottom: 1px solid #ccc;}
+	</style>
+	<div id='edButtons' style='display:none;'>
+		<div class='zerosize'><input accesskey='e' type='button' onclick='switchEditors("<?php echo $id; ?>")' /></div>
+		<input id='edButtonPreview' class='edButtonFore' type='button' value='<?php _e('Visual'); ?>' />
+		<input id='edButtonHTML' class='edButtonBack' type='button' value='<?php _e('Code'); ?>' onclick='switchEditors("<?php echo $id; ?>")' />
+	</div>
+	<script type="text/javascript">
+	// <![CDATA[
+		if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0 )
+			document.getElementById('edButtons').style.display = 'block';
+	// ]]>
+	</script>
+
+	<?php endif; ?>
+	<div id="quicktags">
+	<?php wp_print_scripts( 'quicktags' ); ?>
+	<script type="text/javascript">edToolbar()</script>
+	</div>
+	<script type="text/javascript">
+	// <![CDATA[
+		if ( typeof tinyMCE != "undefined" && tinyMCE.configs.length > 0 )
+			document.getElementById("quicktags").style.display="none";
+
+		function edInsertContent(myField, myValue) {
+			//IE support
+			if (document.selection) {
+				myField.focus();
+				sel = document.selection.createRange();
+				sel.text = myValue;
+				myField.focus();
+			}
+			//MOZILLA/NETSCAPE support
+			else if (myField.selectionStart || myField.selectionStart == "0") {
+				var startPos = myField.selectionStart;
+				var endPos = myField.selectionEnd;
+				myField.value = myField.value.substring(0, startPos)
+				              + myValue 
+		                      + myField.value.substring(endPos, myField.value.length);
+				myField.focus();
+				myField.selectionStart = startPos + myValue.length;
+				myField.selectionEnd = startPos + myValue.length;
+			} else {
+				myField.value += myValue;
+				myField.focus();
+			}
+		}
+	// ]]>
+	</script>
+	<?php
+
+	$the_editor = apply_filters('the_editor', "<div><textarea class='mceEditor' $rows cols='40' name='$id' tabindex='2' id='$id'>%s</textarea></div>\n");
+	$the_editor_content = apply_filters('the_editor_content', $content);
+
+	printf($the_editor, $the_editor_content);
+
+	?>
+	<script type="text/javascript">
+	//<!--
+	edCanvas = document.getElementById('<?php echo $id; ?>');
+	<?php if ( $prev_id && user_can_richedit() ) : ?>
+	// If tinyMCE is defined.
+	if ( typeof tinyMCE != 'undefined' ) {
+	// This code is meant to allow tabbing from Title to Post (TinyMCE).
+		if ( tinyMCE.isMSIE ) {
+			document.getElementById('<?php echo $prev_id; ?>').onkeydown = function (e) {
+				e = e ? e : window.event;
+				if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
+					var i = tinyMCE.getInstanceById('<?php echo $id; ?>');
+					if(typeof i ==  'undefined')
+						return true;
+					tinyMCE.execCommand("mceStartTyping");
+					this.blur();
+					i.contentWindow.focus();
+					e.returnValue = false;
+					return false;
+				}
+			}
+		} else {
+			document.getElementById('<?php echo $prev_id; ?>').onkeypress = function (e) {
+				e = e ? e : window.event;
+				if (e.keyCode == 9 && !e.shiftKey && !e.controlKey && !e.altKey) {
+					var i = tinyMCE.getInstanceById('<?php echo $id; ?>');
+					if(typeof i ==  'undefined')
+						return true;
+					tinyMCE.execCommand("mceStartTyping");
+					this.blur();
+					i.contentWindow.focus();
+					e.returnValue = false;
+					return false;
+				}
+			}
+		}
+	}
+	<?php endif; ?>
+	//-->
+	</script>
+	<?php
+}
+
+function the_search_query() {
+	global $s;
+	echo attribute_escape(stripslashes($s));
+}
+
+function language_attributes() {
+	$output = '';
+	if ( $dir = get_bloginfo('text_direction') )
+		$output = "dir=\"$dir\"";
+	if ( $lang = get_bloginfo('language') ) {
+		if ( $dir ) $output .= ' ';
+		if ( get_option('html_type') == 'text/html' )
+			$output .= "lang=\"$lang\"";
+		else $output .= "xml:lang=\"$lang\"";
+	}
+
+	echo $output;
+}
+
+function paginate_links( $args = '' ) {
+	$defaults = array( 
+		'base' => '%_%', // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
+		'format' => '?page=%#%', // ?page=%#% : %#% is replaced by the page number
+		'total' => 1,
+		'current' => 0,
+		'show_all' => false,
+		'prev_next' => true,
+		'prev_text' => __('&laquo; Previous'),
+		'next_text' => __('Next &raquo;'),
+		'end_size' => 1, // How many numbers on either end including the end
+		'mid_size' => 2, // How many numbers to either side of current not including current
+		'type' => 'plain',
+		'add_args' => false // array of query args to aadd
+	);
+
+	$args = wp_parse_args( $args, $defaults );
+	extract($args, EXTR_SKIP);
+
+	// Who knows what else people pass in $args
+	$total    = (int) $total;
+	if ( $total < 2 )
+		return;
+	$current  = (int) $current;
+	$end_size = 0  < (int) $end_size ? (int) $end_size : 1; // Out of bounds?  Make it the default.
+	$mid_size = 0 <= (int) $mid_size ? (int) $mid_size : 2;
+	$add_args = is_array($add_args) ? $add_args : false;
+	$r = '';
+	$page_links = array();
+	$n = 0;
+	$dots = false;
+
+	if ( $prev_next && $current && 1 < $current ) :
+		$link = str_replace('%_%', 2 == $current ? '' : $format, $base);
+		$link = str_replace('%#%', $current - 1, $link);
+		if ( $add_args )
+			$link = add_query_arg( $add_args, $link );
+		$page_links[] = "<a class='prev page-numbers' href='" . clean_url($link) . "'>$prev_text</a>";
+	endif;
+	for ( $n = 1; $n <= $total; $n++ ) :
+		if ( $n == $current ) :
+			$page_links[] = "<span class='page-numbers current'>$n</span>";
+			$dots = true;
+		else :
+			if ( $show_all || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
+				$link = str_replace('%_%', 1 == $n ? '' : $format, $base);
+				$link = str_replace('%#%', $n, $link);
+				if ( $add_args )
+					$link = add_query_arg( $add_args, $link );
+				$page_links[] = "<a class='page-numbers' href='" . clean_url($link) . "'>$n</a>";
+				$dots = true;
+			elseif ( $dots && !$show_all ) :
+				$page_links[] = "<span class='page-numbers dots'>...</span>";
+				$dots = false;
+			endif;
+		endif;
+	endfor;
+	if ( $prev_next && $current && ( $current < $total || -1 == $total ) ) :
+		$link = str_replace('%_%', $format, $base);
+		$link = str_replace('%#%', $current + 1, $link);
+		if ( $add_args )
+			$link = add_query_arg( $add_args, $link );
+		$page_links[] = "<a class='next page-numbers' href='" . clean_url($link) . "'>$next_text</a>";
+	endif;
+	switch ( $type ) :
+		case 'array' :
+			return $page_links;
+			break;
+		case 'list' :
+			$r .= "<ul class='page-numbers'>\n\t<li>";
+			$r .= join("</li>\n\t<li>", $page_links);
+			$r .= "</li>\n</ul>\n";
+			break;
+		default :
+			$r = join("\n", $page_links);
+			break;
+	endswitch;
+	return $r;
+}
+?>
diff -ruN 2.0.5/wp-includes/gettext.php 2.2.2/wp-includes/gettext.php
--- 2.0.5/wp-includes/gettext.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/gettext.php	2007-04-13 18:29:47.000000000 -0500
@@ -1,32 +1,32 @@
 <?php
 /*
-   Copyright (c) 2003 Danilo Segan <danilo@kvota.net>.
-   Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
-   
-   This file is part of PHP-gettext.
-
-   PHP-gettext is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   PHP-gettext is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with PHP-gettext; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+	 Copyright (c) 2003 Danilo Segan <danilo@kvota.net>.
+	 Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
+
+	 This file is part of PHP-gettext.
+
+	 PHP-gettext is free software; you can redistribute it and/or modify
+	 it under the terms of the GNU General Public License as published by
+	 the Free Software Foundation; either version 2 of the License, or
+	 (at your option) any later version.
+
+	 PHP-gettext is distributed in the hope that it will be useful,
+	 but WITHOUT ANY WARRANTY; without even the implied warranty of
+	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	 GNU General Public License for more details.
+
+	 You should have received a copy of the GNU General Public License
+	 along with PHP-gettext; if not, write to the Free Software
+	 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 */
- 
+
 /**
  * Provides a simple gettext replacement that works independently from
  * the system's gettext abilities.
  * It can read MO files and use them for translating strings.
  * The files are passed to gettext_reader as a Stream (see streams.php)
- * 
+ *
  * This version has the ability to cache all strings and translations to
  * speed up the string lookup.
  * While the cache is enabled by default, it can be switched off with the
@@ -34,324 +34,360 @@
  * that you don't want to keep in memory)
  */
 class gettext_reader {
-  //public:
-   var $error = 0; // public variable that holds error code (0 if no error)
-   
-   //private:
-  var $BYTEORDER = 0;        // 0: low endian, 1: big endian
-  var $STREAM = NULL;
-  var $short_circuit = false;
-  var $enable_cache = false;
-  var $originals = NULL;      // offset of original table
-  var $translations = NULL;    // offset of translation table
-  var $pluralheader = NULL;    // cache header field for plural forms
-  var $total = 0;          // total string count
-  var $table_originals = NULL;  // table for original strings (offsets)
-  var $table_translations = NULL;  // table for translated strings (offsets)
-  var $cache_translations = NULL;  // original -> translation mapping
-
-
-  /* Methods */
-  
-    
-  /**
-   * Reads a 32bit Integer from the Stream
-   * 
-   * @access private
-   * @return Integer from the Stream
-   */
-  function readint() {
-      if ($this->BYTEORDER == 0) {
-        // low endian
-        return array_shift(unpack('V', $this->STREAM->read(4)));
-      } else {
-        // big endian
-        return array_shift(unpack('N', $this->STREAM->read(4)));
-      }
-    }
-
-  /**
-   * Reads an array of Integers from the Stream
-   * 
-   * @param int count How many elements should be read
-   * @return Array of Integers
-   */
-  function readintarray($count) {
-    if ($this->BYTEORDER == 0) {
-        // low endian
-        return unpack('V'.$count, $this->STREAM->read(4 * $count));
-      } else {
-        // big endian
-        return unpack('N'.$count, $this->STREAM->read(4 * $count));
-      }
-  }
-  
-  /**
-   * Constructor
-   * 
-   * @param object Reader the StreamReader object
-   * @param boolean enable_cache Enable or disable caching of strings (default on)
-   */
-  function gettext_reader($Reader, $enable_cache = true) {
-    // If there isn't a StreamReader, turn on short circuit mode.
-    if (! $Reader || isset($Reader->error) ) {
-      $this->short_circuit = true;
-      return;
-    }
-    
-    // Caching can be turned off
-    $this->enable_cache = $enable_cache;
-
-    // $MAGIC1 = (int)0x950412de; //bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
-    $MAGIC1 = (int) - 1794895138;
-    // $MAGIC2 = (int)0xde120495; //bug
-    $MAGIC2 = (int) - 569244523;
-
-    $this->STREAM = $Reader;
-    $magic = $this->readint();
-    if ($magic == ($MAGIC1 & 0xFFFFFFFF)) { // to make sure it works for 64-bit platforms
-      $this->BYTEORDER = 0;
-    } elseif ($magic == ($MAGIC2 & 0xFFFFFFFF)) {
-      $this->BYTEORDER = 1;
-    } else {
-      $this->error = 1; // not MO file
-      return false;
-    }
-    
-    // FIXME: Do we care about revision? We should.
-    $revision = $this->readint();
-    
-    $this->total = $this->readint();
-    $this->originals = $this->readint();
-    $this->translations = $this->readint();
-  }
-  
-  /**
-   * Loads the translation tables from the MO file into the cache
-   * If caching is enabled, also loads all strings into a cache
-   * to speed up translation lookups
-   * 
-   * @access private
-   */
-  function load_tables() {
-    if (is_array($this->cache_translations) &&
-      is_array($this->table_originals) &&
-      is_array($this->table_translations))
-      return;
-    
-    /* get original and translations tables */
-    $this->STREAM->seekto($this->originals);
-    $this->table_originals = $this->readintarray($this->total * 2);
-    $this->STREAM->seekto($this->translations);
-    $this->table_translations = $this->readintarray($this->total * 2);
-    
-    if ($this->enable_cache) {
-      $this->cache_translations = array ();
-      /* read all strings in the cache */
-      for ($i = 0; $i < $this->total; $i++) {
-        $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
-        $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
-        $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
-        $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
-        $this->cache_translations[$original] = $translation;
-      }
-    }
-  }
-  
-  /**
-   * Returns a string from the "originals" table
-   * 
-   * @access private
-   * @param int num Offset number of original string
-   * @return string Requested string if found, otherwise ''
-   */
-  function get_original_string($num) {
-    $length = $this->table_originals[$num * 2 + 1];
-    $offset = $this->table_originals[$num * 2 + 2];
-    if (! $length)
-      return '';
-    $this->STREAM->seekto($offset);
-    $data = $this->STREAM->read($length);
-    return (string)$data;
-  }
-  
-  /**
-   * Returns a string from the "translations" table
-   * 
-   * @access private
-   * @param int num Offset number of original string
-   * @return string Requested string if found, otherwise ''
-   */
-  function get_translation_string($num) {
-    $length = $this->table_translations[$num * 2 + 1];
-    $offset = $this->table_translations[$num * 2 + 2];
-    if (! $length)
-      return '';
-    $this->STREAM->seekto($offset);
-    $data = $this->STREAM->read($length);
-    return (string)$data;
-  }
-  
-  /**
-   * Binary search for string
-   * 
-   * @access private
-   * @param string string
-   * @param int start (internally used in recursive function)
-   * @param int end (internally used in recursive function)
-   * @return int string number (offset in originals table)
-   */
-  function find_string($string, $start = -1, $end = -1) {
-    if (($start == -1) or ($end == -1)) {
-      // find_string is called with only one parameter, set start end end
-      $start = 0;
-      $end = $this->total;
-    }
-    if (abs($start - $end) <= 1) {
-      // We're done, now we either found the string, or it doesn't exist
-      $txt = $this->get_original_string($start);
-      if ($string == $txt)
-        return $start;
-      else
-        return -1;
-    } else if ($start > $end) {
-      // start > end -> turn around and start over
-      return $this->find_string($string, $end, $start);
-    } else {
-      // Divide table in two parts
-      $half = (int)(($start + $end) / 2);
-      $cmp = strcmp($string, $this->get_original_string($half));
-      if ($cmp == 0)
-        // string is exactly in the middle => return it
-        return $half;
-      else if ($cmp < 0)
-        // The string is in the upper half
-        return $this->find_string($string, $start, $half);
-      else
-        // The string is in the lower half
-        return $this->find_string($string, $half, $end);
-    }
-  }
-  
-  /**
-   * Translates a string
-   * 
-   * @access public
-   * @param string string to be translated
-   * @return string translated string (or original, if not found)
-   */
-  function translate($string) {
-    if ($this->short_circuit)
-      return $string;
-    $this->load_tables();     
-    
-    if ($this->enable_cache) {
-      // Caching enabled, get translated string from cache
-      if (array_key_exists($string, $this->cache_translations))
-        return $this->cache_translations[$string];
-      else
-        return $string;
-    } else {
-      // Caching not enabled, try to find string
-      $num = $this->find_string($string);
-      if ($num == -1)
-        return $string;
-      else
-        return $this->get_translation_string($num);
-    }
-  }
-
-  /**
-   * Get possible plural forms from MO header
-   * 
-   * @access private
-   * @return string plural form header
-   */
-  function get_plural_forms() {
-    // lets assume message number 0 is header  
-    // this is true, right?
-    $this->load_tables();
-    
-    // cache header field for plural forms
-    if (! is_string($this->pluralheader)) {
-      if ($this->enable_cache) {
-        $header = $this->cache_translations[""];
-      } else {
-        $header = $this->get_translation_string(0);
-      }
-      if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
-        $expr = $regs[1];
-      else
-        $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
-      $this->pluralheader = $expr;
-    }
-    return $this->pluralheader;
-  }
-
-  /**
-   * Detects which plural form to take
-   * 
-   * @access private
-   * @param n count
-   * @return int array index of the right plural form
-   */
-  function select_string($n) {
-    $string = $this->get_plural_forms();
-    $string = str_replace('nplurals',"\$total",$string);
-    $string = str_replace("n",$n,$string);
-    $string = str_replace('plural',"\$plural",$string);
-    
-    $total = 0;
-    $plural = 0;
-
-    eval("$string");
-    if ($plural >= $total) $plural = $total - 1;
-    return $plural;
-  }
-
-  /**
-   * Plural version of gettext
-   * 
-   * @access public
-   * @param string single
-   * @param string plural
-   * @param string number
-   * @return translated plural form
-   */
-  function ngettext($single, $plural, $number) {
-    if ($this->short_circuit) {
-      if ($number != 1)
-        return $plural;
-      else
-        return $single;
-    }
-
-    // find out the appropriate form
-    $select = $this->select_string($number); 
-    
-    // this should contains all strings separated by NULLs
-    $key = $single.chr(0).$plural;
-    
-    
-    if ($this->enable_cache) {
-      if (! array_key_exists($key, $this->cache_translations)) {
-        return ($number != 1) ? $plural : $single;
-      } else {
-        $result = $this->cache_translations[$key];
-        $list = explode(chr(0), $result);
-        return $list[$select];
-      }
-    } else {
-      $num = $this->find_string($key);
-      if ($num == -1) {
-        return ($number != 1) ? $plural : $single;
-      } else {
-        $result = $this->get_translation_string($num);
-        $list = explode(chr(0), $result);
-        return $list[$select];
-      }
-    }
-  }
+	//public:
+	 var $error = 0; // public variable that holds error code (0 if no error)
+
+	 //private:
+	var $BYTEORDER = 0;        // 0: low endian, 1: big endian
+	var $STREAM = NULL;
+	var $short_circuit = false;
+	var $enable_cache = false;
+	var $originals = NULL;      // offset of original table
+	var $translations = NULL;    // offset of translation table
+	var $pluralheader = NULL;    // cache header field for plural forms
+	var $select_string_function = NULL; // cache function, which chooses plural forms
+	var $total = 0;          // total string count
+	var $table_originals = NULL;  // table for original strings (offsets)
+	var $table_translations = NULL;  // table for translated strings (offsets)
+	var $cache_translations = NULL;  // original -> translation mapping
+
+
+	/* Methods */
+
+
+	/**
+	 * Reads a 32bit Integer from the Stream
+	 *
+	 * @access private
+	 * @return Integer from the Stream
+	 */
+	function readint() {
+		if ($this->BYTEORDER == 0) {
+			// low endian
+			$low_end = unpack('V', $this->STREAM->read(4));
+			return array_shift($low_end);
+		} else {
+			// big endian
+			$big_end = unpack('N', $this->STREAM->read(4));
+			return array_shift($big_end);
+		}
+	}
+
+	/**
+	 * Reads an array of Integers from the Stream
+	 *
+	 * @param int count How many elements should be read
+	 * @return Array of Integers
+	 */
+	function readintarray($count) {
+	if ($this->BYTEORDER == 0) {
+			// low endian
+			return unpack('V'.$count, $this->STREAM->read(4 * $count));
+		} else {
+			// big endian
+			return unpack('N'.$count, $this->STREAM->read(4 * $count));
+		}
+	}
+
+	/**
+	 * Constructor
+	 *
+	 * @param object Reader the StreamReader object
+	 * @param boolean enable_cache Enable or disable caching of strings (default on)
+	 */
+	function gettext_reader($Reader, $enable_cache = true) {
+		// If there isn't a StreamReader, turn on short circuit mode.
+		if (! $Reader || isset($Reader->error) ) {
+			$this->short_circuit = true;
+			return;
+		}
+
+		// Caching can be turned off
+		$this->enable_cache = $enable_cache;
+
+		// $MAGIC1 = (int)0x950412de; //bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
+		$MAGIC1 = (int) - 1794895138;
+		// $MAGIC2 = (int)0xde120495; //bug
+		$MAGIC2 = (int) - 569244523;
+		// 64-bit fix
+		$MAGIC3 = (int) 2500072158;
+
+		$this->STREAM = $Reader;
+		$magic = $this->readint();
+		if ($magic == ($MAGIC1 & 0xFFFFFFFF) || $magic == ($MAGIC3 & 0xFFFFFFFF)) { // to make sure it works for 64-bit platforms
+			$this->BYTEORDER = 0;
+		} elseif ($magic == ($MAGIC2 & 0xFFFFFFFF)) {
+			$this->BYTEORDER = 1;
+		} else {
+			$this->error = 1; // not MO file
+			return false;
+		}
+
+		// FIXME: Do we care about revision? We should.
+		$revision = $this->readint();
+
+		$this->total = $this->readint();
+		$this->originals = $this->readint();
+		$this->translations = $this->readint();
+	}
+
+	/**
+	 * Loads the translation tables from the MO file into the cache
+	 * If caching is enabled, also loads all strings into a cache
+	 * to speed up translation lookups
+	 *
+	 * @access private
+	 */
+	function load_tables() {
+		if (is_array($this->cache_translations) &&
+			is_array($this->table_originals) &&
+			is_array($this->table_translations))
+			return;
+
+		/* get original and translations tables */
+		$this->STREAM->seekto($this->originals);
+		$this->table_originals = $this->readintarray($this->total * 2);
+		$this->STREAM->seekto($this->translations);
+		$this->table_translations = $this->readintarray($this->total * 2);
+
+		if ($this->enable_cache) {
+			$this->cache_translations = array ();
+			/* read all strings in the cache */
+			for ($i = 0; $i < $this->total; $i++) {
+				$this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
+				$original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
+				$this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
+				$translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
+				$this->cache_translations[$original] = $translation;
+			}
+		}
+	}
+
+	/**
+	 * Returns a string from the "originals" table
+	 *
+	 * @access private
+	 * @param int num Offset number of original string
+	 * @return string Requested string if found, otherwise ''
+	 */
+	function get_original_string($num) {
+		$length = $this->table_originals[$num * 2 + 1];
+		$offset = $this->table_originals[$num * 2 + 2];
+		if (! $length)
+			return '';
+		$this->STREAM->seekto($offset);
+		$data = $this->STREAM->read($length);
+		return (string)$data;
+	}
+
+	/**
+	 * Returns a string from the "translations" table
+	 *
+	 * @access private
+	 * @param int num Offset number of original string
+	 * @return string Requested string if found, otherwise ''
+	 */
+	function get_translation_string($num) {
+		$length = $this->table_translations[$num * 2 + 1];
+		$offset = $this->table_translations[$num * 2 + 2];
+		if (! $length)
+			return '';
+		$this->STREAM->seekto($offset);
+		$data = $this->STREAM->read($length);
+		return (string)$data;
+	}
+
+	/**
+	 * Binary search for string
+	 *
+	 * @access private
+	 * @param string string
+	 * @param int start (internally used in recursive function)
+	 * @param int end (internally used in recursive function)
+	 * @return int string number (offset in originals table)
+	 */
+	function find_string($string, $start = -1, $end = -1) {
+		if (($start == -1) or ($end == -1)) {
+			// find_string is called with only one parameter, set start end end
+			$start = 0;
+			$end = $this->total;
+		}
+		if (abs($start - $end) <= 1) {
+			// We're done, now we either found the string, or it doesn't exist
+			$txt = $this->get_original_string($start);
+			if ($string == $txt)
+				return $start;
+			else
+				return -1;
+		} else if ($start > $end) {
+			// start > end -> turn around and start over
+			return $this->find_string($string, $end, $start);
+		} else {
+			// Divide table in two parts
+			$half = (int)(($start + $end) / 2);
+			$cmp = strcmp($string, $this->get_original_string($half));
+			if ($cmp == 0)
+				// string is exactly in the middle => return it
+				return $half;
+			else if ($cmp < 0)
+				// The string is in the upper half
+				return $this->find_string($string, $start, $half);
+			else
+				// The string is in the lower half
+				return $this->find_string($string, $half, $end);
+		}
+	}
+
+	/**
+	 * Translates a string
+	 *
+	 * @access public
+	 * @param string string to be translated
+	 * @return string translated string (or original, if not found)
+	 */
+	function translate($string) {
+		if ($this->short_circuit)
+			return $string;
+		$this->load_tables();
+
+		if ($this->enable_cache) {
+			// Caching enabled, get translated string from cache
+			if (array_key_exists($string, $this->cache_translations))
+				return $this->cache_translations[$string];
+			else
+				return $string;
+		} else {
+			// Caching not enabled, try to find string
+			$num = $this->find_string($string);
+			if ($num == -1)
+				return $string;
+			else
+				return $this->get_translation_string($num);
+		}
+	}
+
+	/**
+	 * Get possible plural forms from MO header
+	 *
+	 * @access private
+	 * @return string plural form header
+	 */
+	function get_plural_forms() {
+		// lets assume message number 0 is header
+		// this is true, right?
+		$this->load_tables();
+
+		// cache header field for plural forms
+		if (! is_string($this->pluralheader)) {
+			if ($this->enable_cache) {
+				$header = $this->cache_translations[""];
+			} else {
+				$header = $this->get_translation_string(0);
+			}
+			$header .= "\n"; //make sure our regex matches
+			if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
+				$expr = $regs[1];
+			else
+				$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
+
+			// add parentheses
+ 			// important since PHP's ternary evaluates from left to right
+ 			$expr.= ';';
+ 			$res= '';
+ 			$p= 0;
+ 			for ($i= 0; $i < strlen($expr); $i++) {
+				$ch= $expr[$i];
+				switch ($ch) {
+					case '?':
+						$res.= ' ? (';
+						$p++;
+						break;
+					case ':':
+						$res.= ') : (';
+						break;
+					case ';':
+						$res.= str_repeat( ')', $p) . ';';
+						$p= 0;
+						break;
+					default:
+						$res.= $ch;
+				}
+			}
+			$this->pluralheader = $res;
+		}
+
+		return $this->pluralheader;
+	}
+
+	/**
+	 * Detects which plural form to take
+	 *
+	 * @access private
+	 * @param n count
+	 * @return int array index of the right plural form
+	 */
+	function select_string($n) {
+		if (is_null($this->select_string_function)) {
+			$string = $this->get_plural_forms();
+			if (preg_match("/nplurals\s*=\s*(\d+)\s*\;\s*plural\s*=\s*(.*?)\;+/", $string, $matches)) {
+				$nplurals = $matches[1];
+				$expression = $matches[2];
+				$expression = str_replace("n", '$n', $expression);
+			} else {
+				$nplurals = 2;
+				$expression = ' $n == 1 ? 0 : 1 ';
+			}
+			$func_body = "
+				\$plural = ($expression);
+				return (\$plural <= $nplurals)? \$plural : \$plural - 1;";
+			$this->select_string_function = create_function('$n', $func_body);
+		}
+		return call_user_func($this->select_string_function, $n);
+	}
+
+	/**
+	 * Plural version of gettext
+	 *
+	 * @access public
+	 * @param string single
+	 * @param string plural
+	 * @param string number
+	 * @return translated plural form
+	 */
+	function ngettext($single, $plural, $number) {
+		if ($this->short_circuit) {
+			if ($number != 1)
+				return $plural;
+			else
+				return $single;
+		}
+
+		// find out the appropriate form
+		$select = $this->select_string($number);
+
+		// this should contains all strings separated by NULLs
+		$key = $single.chr(0).$plural;
+
+
+		if ($this->enable_cache) {
+			if (! array_key_exists($key, $this->cache_translations)) {
+				return ($number != 1) ? $plural : $single;
+			} else {
+				$result = $this->cache_translations[$key];
+				$list = explode(chr(0), $result);
+				return $list[$select];
+			}
+		} else {
+			$num = $this->find_string($key);
+			if ($num == -1) {
+				return ($number != 1) ? $plural : $single;
+			} else {
+				$result = $this->get_translation_string($num);
+				$list = explode(chr(0), $result);
+				return $list[$select];
+			}
+		}
+	}
 
 }
 
Binary files 2.0.5/wp-includes/images/rss.png and 2.2.2/wp-includes/images/rss.png differ
diff -ruN 2.0.5/wp-includes/js/autosave.js 2.2.2/wp-includes/js/autosave.js
--- 2.0.5/wp-includes/js/autosave.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/autosave.js	2007-03-06 11:35:01.000000000 -0600
@@ -0,0 +1,158 @@
+var autosaveLast = '';
+var autosavePeriodical;
+
+function autosave_start_timer() {
+	var form = $('post');
+	autosaveLast = form.post_title.value+form.content.value;
+	// Keep autosave_interval in sync with edit_post().
+	autosavePeriodical = new PeriodicalExecuter(autosave, autosaveL10n.autosaveInterval);
+	//Disable autosave after the form has been submitted
+	if(form.addEventListener) {
+		form.addEventListener("submit", function () { autosavePeriodical.currentlyExecuting = true; }, false);
+	}
+	if(form.attachEvent) {
+		form.save ? form.save.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
+		form.submit ? form.submit.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
+		form.publish ? form.publish.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
+		form.deletepost ? form.deletepost.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
+	}
+}
+addLoadEvent(autosave_start_timer)
+
+function autosave_cur_time() {
+	var now = new Date();
+	return "" + ((now.getHours() >12) ? now.getHours() -12 : now.getHours()) + 
+	((now.getMinutes() < 10) ? ":0" : ":") + now.getMinutes() +
+	((now.getSeconds() < 10) ? ":0" : ":") + now.getSeconds();
+}
+
+function autosave_update_nonce() {
+	var response = nonceAjax.response;
+	document.getElementsByName('_wpnonce')[0].value = response;
+}
+
+function autosave_update_post_ID() {
+	var response = autosaveAjax.response;
+	var res = parseInt(response);
+	var message;
+
+	if(isNaN(res)) {
+		message = autosaveL10n.errorText.replace(/%response%/g, response);
+	} else {
+		message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
+		$('post_ID').name = "post_ID";
+		$('post_ID').value = res;
+		// We need new nonces
+		nonceAjax = new sack();
+		nonceAjax.element = null;
+		nonceAjax.setVar("action", "autosave-generate-nonces");
+		nonceAjax.setVar("post_ID", res);
+		nonceAjax.setVar("cookie", document.cookie);
+		nonceAjax.setVar("post_type", $('post_type').value);
+		nonceAjax.requestFile = autosaveL10n.requestFile;
+		nonceAjax.onCompletion = autosave_update_nonce;
+		nonceAjax.method = "POST";
+		nonceAjax.runAJAX();
+		$('hiddenaction').value = 'editpost';
+	}
+	$('autosave').innerHTML = message;
+	autosave_enable_buttons();
+}
+
+function autosave_loading() {
+	$('autosave').innerHTML = autosaveL10n.savingText;
+}
+
+function autosave_saved() {
+	var response = autosaveAjax.response;
+	var res = parseInt(response);
+	var message;
+
+	if(isNaN(res)) {
+		message = autosaveL10n.errorText.replace(/%response%/g, response);
+	} else {
+		message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
+	}
+	$('autosave').innerHTML = message;
+	autosave_enable_buttons();
+}
+
+function autosave_disable_buttons() {
+	var form = $('post');
+	form.save ? form.save.disabled = 'disabled' : null;
+	form.submit ? form.submit.disabled = 'disabled' : null;
+	form.publish ? form.publish.disabled = 'disabled' : null;
+	form.deletepost ? form.deletepost.disabled = 'disabled' : null;
+	setTimeout('autosave_enable_buttons();', 1000); // Re-enable 1 sec later.  Just gives autosave a head start to avoid collisions.
+}
+
+function autosave_enable_buttons() {
+	var form = $('post');
+	form.save ? form.save.disabled = '' : null;
+	form.submit ? form.submit.disabled = '' : null;
+	form.publish ? form.publish.disabled = '' : null;
+	form.deletepost ? form.deletepost.disabled = '' : null;
+}
+
+function autosave() {
+	var form = $('post');
+	var rich = ((typeof tinyMCE != "undefined") && tinyMCE.getInstanceById('content')) ? true : false;
+
+	autosaveAjax = new sack();
+
+	/* Gotta do this up here so we can check the length when tinyMCE is in use */
+	if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) {
+		autosaveAjax.setVar("content", form.content.value);
+	} else {
+		// Don't run while the TinyMCE spellcheck is on.
+		if(tinyMCE.selectedInstance.spellcheckerOn) return;
+		tinyMCE.wpTriggerSave();
+		autosaveAjax.setVar("content", form.content.value);
+	}
+
+	if(form.post_title.value.length==0 || form.content.value.length==0 || form.post_title.value+form.content.value == autosaveLast)
+		return;
+
+	autosave_disable_buttons();
+
+	autosaveLast = form.post_title.value+form.content.value;
+
+	cats = document.getElementsByName("post_category[]");
+	goodcats = ([]);
+	for(i=0;i<cats.length;i++) {
+		if(cats[i].checked)
+			goodcats.push(cats[i].value);
+	}
+	catslist = goodcats.join(",");
+
+	autosaveAjax.setVar("action", "autosave");
+	autosaveAjax.setVar("cookie", document.cookie);
+	autosaveAjax.setVar("catslist", catslist);
+	autosaveAjax.setVar("post_ID", $("post_ID").value);
+	autosaveAjax.setVar("post_title", form.post_title.value);
+	autosaveAjax.setVar("post_type", form.post_type.value);
+	if ( form.comment_status.checked )
+		autosaveAjax.setVar("comment_status", 'open');
+	if ( form.ping_status.checked )
+		autosaveAjax.setVar("ping_status", 'open');
+	if(form.excerpt)
+		autosaveAjax.setVar("excerpt", form.excerpt.value);
+
+	if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) {
+		autosaveAjax.setVar("content", form.content.value);
+	} else {
+		tinyMCE.wpTriggerSave();
+		autosaveAjax.setVar("content", form.content.value);
+	}
+
+	autosaveAjax.requestFile = autosaveL10n.requestFile;
+	autosaveAjax.method = "POST";
+	autosaveAjax.element = null;
+	autosaveAjax.onLoading = autosave_loading;
+	autosaveAjax.onInteractive = autosave_loading;
+	if(parseInt($("post_ID").value) < 1)
+		autosaveAjax.onCompletion = autosave_update_post_ID;
+	else
+		autosaveAjax.onCompletion = autosave_saved;
+	autosaveAjax.runAJAX();
+}
diff -ruN 2.0.5/wp-includes/js/colorpicker.js 2.2.2/wp-includes/js/colorpicker.js
--- 2.0.5/wp-includes/js/colorpicker.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/colorpicker.js	2006-02-12 01:53:23.000000000 -0600
@@ -139,7 +139,7 @@
 	}
 function AnchorPosition_getWindowOffsetLeft (el) {
 	return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
-	}	
+	}
 function AnchorPosition_getPageOffsetTop (el) {
 	var ot=el.offsetTop;
 	while((el=el.offsetParent) != null) { ot += el.offsetTop; }
@@ -434,7 +434,7 @@
 	this.populated = false;
 	this.visible = false;
 	this.autoHideEnabled = false;
-	
+
 	this.contents = "";
 	this.url="";
 	this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
@@ -556,7 +556,7 @@
 	window.ColorPicker_targetInput = inputobj;
 	this.show(linkname);
 	}
-	
+
 // This function runs when you move your mouse over a color block, if you have a newer browser
 function ColorPicker_highlightColor(c) {
 	var thedoc = (arguments.length>1)?arguments[1]:window.document;
@@ -579,7 +579,7 @@
 	else {
 		var divname = arguments[0];
 		}
-	
+
 	if (divname != "") {
 		var cp = new PopupWindow(divname);
 		}
@@ -590,7 +590,7 @@
 
 	// Object variables
 	cp.currentValue = "#FFFFFF";
-	
+
 	// Method Mappings
 	cp.writeDiv = ColorPicker_writeDiv;
 	cp.highlightColor = ColorPicker_highlightColor;
diff -ruN 2.0.5/wp-includes/js/crop/cropper.css 2.2.2/wp-includes/js/crop/cropper.css
--- 2.0.5/wp-includes/js/crop/cropper.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/crop/cropper.css	2006-12-07 18:10:58.000000000 -0600
@@ -0,0 +1,165 @@
+.imgCrop_wrap {
+	/* width: 500px;   @done_in_js */
+	/* height: 375px;  @done_in_js */
+	position: relative;
+	cursor: crosshair;
+}
+
+/* an extra classname is applied for Opera < 9.0 to fix it's lack of opacity support */
+.imgCrop_wrap.opera8 .imgCrop_overlay,
+.imgCrop_wrap.opera8 .imgCrop_clickArea { 
+	background-color: transparent;
+}
+
+/* fix for IE displaying all boxes at line-height by default, although they are still 1 pixel high until we combine them with the pointless span */
+.imgCrop_wrap,
+.imgCrop_wrap * {
+	font-size: 0;
+}
+
+.imgCrop_overlay {
+	background-color: #000;
+	opacity: 0.5;
+	filter:alpha(opacity=50);
+	position: absolute;
+	width: 100%;
+	height: 100%;
+}
+
+.imgCrop_selArea {
+	position: absolute;
+	/* @done_in_js 
+	top: 20px;
+	left: 20px;
+	width: 200px;
+	height: 200px;
+	background: transparent url(castle.jpg) no-repeat  -210px -110px;
+	*/
+	cursor: move;
+	z-index: 2;
+}
+
+/* clickArea is all a fix for IE 5.5 & 6 to allow the user to click on the given area */
+.imgCrop_clickArea {
+	width: 100%;
+	height: 100%;
+	background-color: #FFF;
+	opacity: 0.01;
+	filter:alpha(opacity=01);
+}
+
+.imgCrop_marqueeHoriz {
+	position: absolute;
+	width: 100%;
+	height: 1px;
+	background: transparent url(marqueeHoriz.gif) repeat-x 0 0;
+	z-index: 3;
+}
+
+.imgCrop_marqueeVert {
+	position: absolute;
+	height: 100%;
+	width: 1px;
+	background: transparent url(marqueeVert.gif) repeat-y 0 0;
+	z-index: 3;
+}
+
+.imgCrop_marqueeNorth { top: 0; left: 0; }
+.imgCrop_marqueeEast  { top: 0; right: 0; }
+.imgCrop_marqueeSouth { bottom: 0px; left: 0; }
+.imgCrop_marqueeWest  { top: 0; left: 0; }
+
+
+.imgCrop_handle {
+	position: absolute;
+	border: 1px solid #333;
+	width: 6px;
+	height: 6px;
+	background: #FFF;
+	opacity: 0.5;
+	filter:alpha(opacity=50);
+	z-index: 4;
+}
+
+/* fix IE 5 box model */
+* html .imgCrop_handle {
+	width: 8px;
+	height: 8px;
+	wid\th: 6px;
+	hei\ght: 6px;
+}
+
+.imgCrop_handleN {
+	top: -3px;
+	left: 0;
+	/* margin-left: 49%;    @done_in_js */
+	cursor: n-resize;
+}
+
+.imgCrop_handleNE { 
+	top: -3px;
+	right: -3px;
+	cursor: ne-resize;
+}
+
+.imgCrop_handleE {
+	top: 0;
+	right: -3px;
+	/* margin-top: 49%;    @done_in_js */
+	cursor: e-resize;
+}
+
+.imgCrop_handleSE {
+	right: -3px;
+	bottom: -3px;
+	cursor: se-resize;
+}
+
+.imgCrop_handleS {
+	right: 0;
+	bottom: -3px;
+	/* margin-right: 49%; @done_in_js */
+	cursor: s-resize;
+}
+
+.imgCrop_handleSW {
+	left: -3px;
+	bottom: -3px;
+	cursor: sw-resize;
+}
+
+.imgCrop_handleW {
+	top: 0;
+	left: -3px;
+	/* margin-top: 49%;  @done_in_js */
+	cursor: e-resize;
+}
+
+.imgCrop_handleNW {
+	top: -3px;
+	left: -3px;
+	cursor: nw-resize;
+}
+
+/**
+ * Create an area to click & drag around on as the default browser behaviour is to let you drag the image 
+ */
+.imgCrop_dragArea {
+	width: 100%;
+	height: 100%;
+	z-index: 200;
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+
+.imgCrop_previewWrap {
+	/* width: 200px;  @done_in_js */
+	/* height: 200px; @done_in_js */
+	overflow: hidden;
+	position: relative;
+}
+
+.imgCrop_previewWrap img {
+	position: absolute;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/crop/cropper.js 2.2.2/wp-includes/js/crop/cropper.js
--- 2.0.5/wp-includes/js/crop/cropper.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/crop/cropper.js	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,516 @@
+/**
+ * Copyright (c) 2006, David Spurr (http://www.defusion.org.uk/)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * See scriptaculous.js for full scriptaculous licence
+ */
+
+var CropDraggable=Class.create();
+Object.extend(Object.extend(CropDraggable.prototype,Draggable.prototype),{initialize:function(_1){
+this.options=Object.extend({drawMethod:function(){
+}},arguments[1]||{});
+this.element=$(_1);
+this.handle=this.element;
+this.delta=this.currentDelta();
+this.dragging=false;
+this.eventMouseDown=this.initDrag.bindAsEventListener(this);
+Event.observe(this.handle,"mousedown",this.eventMouseDown);
+Draggables.register(this);
+},draw:function(_2){
+var _3=Position.cumulativeOffset(this.element);
+var d=this.currentDelta();
+_3[0]-=d[0];
+_3[1]-=d[1];
+var p=[0,1].map(function(i){
+return (_2[i]-_3[i]-this.offset[i]);
+}.bind(this));
+this.options.drawMethod(p);
+}});
+var Cropper={};
+Cropper.Img=Class.create();
+Cropper.Img.prototype={initialize:function(_7,_8){
+this.options=Object.extend({ratioDim:{x:0,y:0},minWidth:0,minHeight:0,displayOnInit:false,onEndCrop:Prototype.emptyFunction,captureKeys:true},_8||{});
+if(this.options.minWidth>0&&this.options.minHeight>0){
+this.options.ratioDim.x=this.options.minWidth;
+this.options.ratioDim.y=this.options.minHeight;
+}
+this.img=$(_7);
+this.clickCoords={x:0,y:0};
+this.dragging=false;
+this.resizing=false;
+this.isWebKit=/Konqueror|Safari|KHTML/.test(navigator.userAgent);
+this.isIE=/MSIE/.test(navigator.userAgent);
+this.isOpera8=/Opera\s[1-8]/.test(navigator.userAgent);
+this.ratioX=0;
+this.ratioY=0;
+this.attached=false;
+$A(document.getElementsByTagName("script")).each(function(s){
+if(s.src.match(/cropper\.js/)){
+var _a=s.src.replace(/cropper\.js(.*)?/,"");
+var _b=document.createElement("link");
+_b.rel="stylesheet";
+_b.type="text/css";
+_b.href=_a+"cropper.css";
+_b.media="screen";
+document.getElementsByTagName("head")[0].appendChild(_b);
+}
+});
+if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0){
+var _c=this.getGCD(this.options.ratioDim.x,this.options.ratioDim.y);
+this.ratioX=this.options.ratioDim.x/_c;
+this.ratioY=this.options.ratioDim.y/_c;
+}
+this.subInitialize();
+if(this.img.complete||this.isWebKit){
+this.onLoad();
+}else{
+Event.observe(this.img,"load",this.onLoad.bindAsEventListener(this));
+}
+},getGCD:function(a,b){return 1;
+if(b==0){
+return a;
+}
+return this.getGCD(b,a%b);
+},onLoad:function(){
+var _f="imgCrop_";
+var _10=this.img.parentNode;
+var _11="";
+if(this.isOpera8){
+_11=" opera8";
+}
+this.imgWrap=Builder.node("div",{"class":_f+"wrap"+_11});
+if(this.isIE){
+this.north=Builder.node("div",{"class":_f+"overlay "+_f+"north"},[Builder.node("span")]);
+this.east=Builder.node("div",{"class":_f+"overlay "+_f+"east"},[Builder.node("span")]);
+this.south=Builder.node("div",{"class":_f+"overlay "+_f+"south"},[Builder.node("span")]);
+this.west=Builder.node("div",{"class":_f+"overlay "+_f+"west"},[Builder.node("span")]);
+var _12=[this.north,this.east,this.south,this.west];
+}else{
+this.overlay=Builder.node("div",{"class":_f+"overlay"});
+var _12=[this.overlay];
+}
+this.dragArea=Builder.node("div",{"class":_f+"dragArea"},_12);
+this.handleN=Builder.node("div",{"class":_f+"handle "+_f+"handleN"});
+this.handleNE=Builder.node("div",{"class":_f+"handle "+_f+"handleNE"});
+this.handleE=Builder.node("div",{"class":_f+"handle "+_f+"handleE"});
+this.handleSE=Builder.node("div",{"class":_f+"handle "+_f+"handleSE"});
+this.handleS=Builder.node("div",{"class":_f+"handle "+_f+"handleS"});
+this.handleSW=Builder.node("div",{"class":_f+"handle "+_f+"handleSW"});
+this.handleW=Builder.node("div",{"class":_f+"handle "+_f+"handleW"});
+this.handleNW=Builder.node("div",{"class":_f+"handle "+_f+"handleNW"});
+this.selArea=Builder.node("div",{"class":_f+"selArea"},[Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeNorth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeEast"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeHoriz "+_f+"marqueeSouth"},[Builder.node("span")]),Builder.node("div",{"class":_f+"marqueeVert "+_f+"marqueeWest"},[Builder.node("span")]),this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW,Builder.node("div",{"class":_f+"clickArea"})]);
+Element.setStyle($(this.selArea),{backgroundColor:"transparent",backgroundRepeat:"no-repeat",backgroundPosition:"0 0"});
+this.imgWrap.appendChild(this.img);
+this.imgWrap.appendChild(this.dragArea);
+this.dragArea.appendChild(this.selArea);
+this.dragArea.appendChild(Builder.node("div",{"class":_f+"clickArea"}));
+_10.appendChild(this.imgWrap);
+Event.observe(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this));
+Event.observe(document,"mousemove",this.onDrag.bindAsEventListener(this));
+Event.observe(document,"mouseup",this.endCrop.bindAsEventListener(this));
+var _13=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW];
+for(var i=0;i<_13.length;i++){
+Event.observe(_13[i],"mousedown",this.startResize.bindAsEventListener(this));
+}
+if(this.options.captureKeys){
+Event.observe(document,"keydown",this.handleKeys.bindAsEventListener(this));
+}
+new CropDraggable(this.selArea,{drawMethod:this.moveArea.bindAsEventListener(this)});
+this.setParams();
+},setParams:function(){
+this.imgW=this.img.width;
+this.imgH=this.img.height;
+if(!this.isIE){
+Element.setStyle($(this.overlay),{width:this.imgW+"px",height:this.imgH+"px"});
+Element.hide($(this.overlay));
+Element.setStyle($(this.selArea),{backgroundImage:"url("+this.img.src+")"});
+}else{
+Element.setStyle($(this.north),{height:0});
+Element.setStyle($(this.east),{width:0,height:0});
+Element.setStyle($(this.south),{height:0});
+Element.setStyle($(this.west),{width:0,height:0});
+}
+Element.setStyle($(this.imgWrap),{"width":this.imgW+"px","height":this.imgH+"px"});
+Element.hide($(this.selArea));
+var _15=Position.positionedOffset(this.imgWrap);
+this.wrapOffsets={"top":_15[1],"left":_15[0]};
+var _16={x1:0,y1:0,x2:0,y2:0};
+this.setAreaCoords(_16);
+if(this.options.ratioDim.x>0&&this.options.ratioDim.y>0&&this.options.displayOnInit){
+_16.x1=Math.ceil((this.imgW-this.options.ratioDim.x)/2);
+_16.y1=Math.ceil((this.imgH-this.options.ratioDim.y)/2);
+_16.x2=_16.x1+this.options.ratioDim.x;
+_16.y2=_16.y1+this.options.ratioDim.y;
+Element.show(this.selArea);
+this.drawArea();
+this.endCrop();
+}
+this.attached=true;
+},remove:function(){
+this.attached=false;
+this.imgWrap.parentNode.insertBefore(this.img,this.imgWrap);
+this.imgWrap.parentNode.removeChild(this.imgWrap);
+Event.stopObserving(this.dragArea,"mousedown",this.startDrag.bindAsEventListener(this));
+Event.stopObserving(document,"mousemove",this.onDrag.bindAsEventListener(this));
+Event.stopObserving(document,"mouseup",this.endCrop.bindAsEventListener(this));
+var _17=[this.handleN,this.handleNE,this.handleE,this.handleSE,this.handleS,this.handleSW,this.handleW,this.handleNW];
+for(var i=0;i<_17.length;i++){
+Event.stopObserving(_17[i],"mousedown",this.startResize.bindAsEventListener(this));
+}
+if(this.options.captureKeys){
+Event.stopObserving(document,"keydown",this.handleKeys.bindAsEventListener(this));
+}
+},reset:function(){
+if(!this.attached){
+this.onLoad();
+}else{
+this.setParams();
+}
+this.endCrop();
+},handleKeys:function(e){
+var dir={x:0,y:0};
+if(!this.dragging){
+switch(e.keyCode){
+case (37):
+dir.x=-1;
+break;
+case (38):
+dir.y=-1;
+break;
+case (39):
+dir.x=1;
+break;
+case (40):
+dir.y=1;
+break;
+}
+if(dir.x!=0||dir.y!=0){
+if(e.shiftKey){
+dir.x*=10;
+dir.y*=10;
+}
+this.moveArea([this.areaCoords.x1+dir.x,this.areaCoords.y1+dir.y]);
+Event.stop(e);
+}
+}
+},calcW:function(){
+return (this.areaCoords.x2-this.areaCoords.x1);
+},calcH:function(){
+return (this.areaCoords.y2-this.areaCoords.y1);
+},moveArea:function(_1b){
+this.setAreaCoords({x1:_1b[0],y1:_1b[1],x2:_1b[0]+this.calcW(),y2:_1b[1]+this.calcH()},true);
+this.drawArea();
+},cloneCoords:function(_1c){
+return {x1:_1c.x1,y1:_1c.y1,x2:_1c.x2,y2:_1c.y2};
+},setAreaCoords:function(_1d,_1e,_1f,_20,_21){
+var _22=typeof _1e!="undefined"?_1e:false;
+var _23=typeof _1f!="undefined"?_1f:false;
+if(_1e){
+var _24=_1d.x2-_1d.x1;
+var _25=_1d.y2-_1d.y1;
+if(_1d.x1<0){
+_1d.x1=0;
+_1d.x2=_24;
+}
+if(_1d.y1<0){
+_1d.y1=0;
+_1d.y2=_25;
+}
+if(_1d.x2>this.imgW){
+_1d.x2=this.imgW;
+_1d.x1=this.imgW-_24;
+}
+if(_1d.y2>this.imgH){
+_1d.y2=this.imgH;
+_1d.y1=this.imgH-_25;
+}
+}else{
+if(_1d.x1<0){
+_1d.x1=0;
+}
+if(_1d.y1<0){
+_1d.y1=0;
+}
+if(_1d.x2>this.imgW){
+_1d.x2=this.imgW;
+}
+if(_1d.y2>this.imgH){
+_1d.y2=this.imgH;
+}
+if(typeof (_20)!="undefined"){
+if(this.ratioX>0){
+this.applyRatio(_1d,{x:this.ratioX,y:this.ratioY},_20,_21);
+}else{
+if(_23){
+this.applyRatio(_1d,{x:1,y:1},_20,_21);
+}
+}
+var _26={a1:_1d.x1,a2:_1d.x2};
+var _27={a1:_1d.y1,a2:_1d.y2};
+var _28=this.options.minWidth;
+var _29=this.options.minHeight;
+if((_28==0||_29==0)&&_23){
+if(_28>0){
+_29=_28;
+}else{
+if(_29>0){
+_28=_29;
+}
+}
+}
+this.applyMinDimension(_26,_28,_20.x,{min:0,max:this.imgW});
+this.applyMinDimension(_27,_29,_20.y,{min:0,max:this.imgH});
+_1d={x1:_26.a1,y1:_27.a1,x2:_26.a2,y2:_27.a2};
+}
+}
+this.areaCoords=_1d;
+},applyMinDimension:function(_2a,_2b,_2c,_2d){
+if((_2a.a2-_2a.a1)<_2b){
+if(_2c==1){
+_2a.a2=_2a.a1+_2b;
+}else{
+_2a.a1=_2a.a2-_2b;
+}
+if(_2a.a1<_2d.min){
+_2a.a1=_2d.min;
+_2a.a2=_2b;
+}else{
+if(_2a.a2>_2d.max){
+_2a.a1=_2d.max-_2b;
+_2a.a2=_2d.max;
+}
+}
+}
+},applyRatio:function(_2e,_2f,_30,_31){
+var _32;
+if(_31=="N"||_31=="S"){
+_32=this.applyRatioToAxis({a1:_2e.y1,b1:_2e.x1,a2:_2e.y2,b2:_2e.x2},{a:_2f.y,b:_2f.x},{a:_30.y,b:_30.x},{min:0,max:this.imgW});
+_2e.x1=_32.b1;
+_2e.y1=_32.a1;
+_2e.x2=_32.b2;
+_2e.y2=_32.a2;
+}else{
+_32=this.applyRatioToAxis({a1:_2e.x1,b1:_2e.y1,a2:_2e.x2,b2:_2e.y2},{a:_2f.x,b:_2f.y},{a:_30.x,b:_30.y},{min:0,max:this.imgH});
+_2e.x1=_32.a1;
+_2e.y1=_32.b1;
+_2e.x2=_32.a2;
+_2e.y2=_32.b2;
+}
+},applyRatioToAxis:function(_33,_34,_35,_36){
+var _37=Object.extend(_33,{});
+var _38=_37.a2-_37.a1;
+var _3a=Math.floor(_38*_34.b/_34.a);
+var _3b;
+var _3c;
+var _3d=null;
+if(_35.b==1){
+_3b=_37.b1+_3a;
+if(_3b>_36.max){
+_3b=_36.max;
+_3d=_3b-_37.b1;
+}
+_37.b2=_3b;
+}else{
+_3b=_37.b2-_3a;
+if(_3b<_36.min){
+_3b=_36.min;
+_3d=_3b+_37.b2;
+}
+_37.b1=_3b;
+}
+if(_3d!=null){
+_3c=Math.floor(_3d*_34.a/_34.b);
+if(_35.a==1){
+_37.a2=_37.a1+_3c;
+}else{
+_37.a1=_37.a1=_37.a2-_3c;
+}
+}
+return _37;
+},drawArea:function(){
+if(!this.isIE){
+Element.show($(this.overlay));
+}
+var _3e=this.calcW();
+var _3f=this.calcH();
+var _40=this.areaCoords.x2;
+var _41=this.areaCoords.y2;
+var _42=this.selArea.style;
+_42.left=this.areaCoords.x1+"px";
+_42.top=this.areaCoords.y1+"px";
+_42.width=_3e+"px";
+_42.height=_3f+"px";
+var _43=Math.ceil((_3e-6)/2)+"px";
+var _44=Math.ceil((_3f-6)/2)+"px";
+this.handleN.style.left=_43;
+this.handleE.style.top=_44;
+this.handleS.style.left=_43;
+this.handleW.style.top=_44;
+if(this.isIE){
+this.north.style.height=this.areaCoords.y1+"px";
+var _45=this.east.style;
+_45.top=this.areaCoords.y1+"px";
+_45.height=_3f+"px";
+_45.left=_40+"px";
+_45.width=(this.img.width-_40)+"px";
+var _46=this.south.style;
+_46.top=_41+"px";
+_46.height=(this.img.height-_41)+"px";
+var _47=this.west.style;
+_47.top=this.areaCoords.y1+"px";
+_47.height=_3f+"px";
+_47.width=this.areaCoords.x1+"px";
+}else{
+_42.backgroundPosition="-"+this.areaCoords.x1+"px "+"-"+this.areaCoords.y1+"px";
+}
+this.subDrawArea();
+this.forceReRender();
+},forceReRender:function(){
+if(this.isIE||this.isWebKit){
+var n=document.createTextNode(" ");
+var d,el,fixEL,i;
+if(this.isIE){
+fixEl=this.selArea;
+}else{
+if(this.isWebKit){
+fixEl=document.getElementsByClassName("imgCrop_marqueeSouth",this.imgWrap)[0];
+d=Builder.node("div","");
+d.style.visibility="hidden";
+var _4a=["SE","S","SW"];
+for(i=0;i<_4a.length;i++){
+el=document.getElementsByClassName("imgCrop_handle"+_4a[i],this.selArea)[0];
+if(el.childNodes.length){
+el.removeChild(el.childNodes[0]);
+}
+el.appendChild(d);
+}
+}
+}
+fixEl.appendChild(n);
+fixEl.removeChild(n);
+}
+},startResize:function(e){
+this.startCoords=this.cloneCoords(this.areaCoords);
+this.resizing=true;
+this.resizeHandle=Element.classNames(Event.element(e)).toString().replace(/([^N|NE|E|SE|S|SW|W|NW])+/,"");
+Event.stop(e);
+},startDrag:function(e){
+Element.show(this.selArea);
+this.clickCoords=this.getCurPos(e);
+this.setAreaCoords({x1:this.clickCoords.x,y1:this.clickCoords.y,x2:this.clickCoords.x,y2:this.clickCoords.y});
+this.dragging=true;
+this.onDrag(e);
+Event.stop(e);
+},getCurPos:function(e){
+return curPos={x:Event.pointerX(e)-this.wrapOffsets.left,y:Event.pointerY(e)-this.wrapOffsets.top};
+},onDrag:function(e){
+var _4f=null;
+if(this.dragging||this.resizing){
+var _50=this.getCurPos(e);
+var _51=this.cloneCoords(this.areaCoords);
+var _52={x:1,y:1};
+}
+if(this.dragging){
+if(_50.x<this.clickCoords.x){
+_52.x=-1;
+}
+if(_50.y<this.clickCoords.y){
+_52.y=-1;
+}
+this.transformCoords(_50.x,this.clickCoords.x,_51,"x");
+this.transformCoords(_50.y,this.clickCoords.y,_51,"y");
+}else{
+if(this.resizing){
+_4f=this.resizeHandle;
+if(_4f.match(/E/)){
+this.transformCoords(_50.x,this.startCoords.x1,_51,"x");
+if(_50.x<this.startCoords.x1){
+_52.x=-1;
+}
+}else{
+if(_4f.match(/W/)){
+this.transformCoords(_50.x,this.startCoords.x2,_51,"x");
+if(_50.x<this.startCoords.x2){
+_52.x=-1;
+}
+}
+}
+if(_4f.match(/N/)){
+this.transformCoords(_50.y,this.startCoords.y2,_51,"y");
+if(_50.y<this.startCoords.y2){
+_52.y=-1;
+}
+}else{
+if(_4f.match(/S/)){
+this.transformCoords(_50.y,this.startCoords.y1,_51,"y");
+if(_50.y<this.startCoords.y1){
+_52.y=-1;
+}
+}
+}
+}
+}
+if(this.dragging||this.resizing){
+this.setAreaCoords(_51,false,e.shiftKey,_52,_4f);
+this.drawArea();
+Event.stop(e);
+}
+},transformCoords:function(_53,_54,_55,_56){
+var _57=new Array();
+if(_53<_54){
+_57[0]=_53;
+_57[1]=_54;
+}else{
+_57[0]=_54;
+_57[1]=_53;
+}
+if(_56=="x"){
+_55.x1=_57[0];
+_55.x2=_57[1];
+}else{
+_55.y1=_57[0];
+_55.y2=_57[1];
+}
+},endCrop:function(){
+this.dragging=false;
+this.resizing=false;
+this.options.onEndCrop(this.areaCoords,{width:this.calcW(),height:this.calcH()});
+},subInitialize:function(){
+},subDrawArea:function(){
+}};
+Cropper.ImgWithPreview=Class.create();
+Object.extend(Object.extend(Cropper.ImgWithPreview.prototype,Cropper.Img.prototype),{subInitialize:function(){
+this.hasPreviewImg=false;
+if(typeof (this.options.previewWrap)!="undefined"&&this.options.minWidth>0&&this.options.minHeight>0){
+this.previewWrap=$(this.options.previewWrap);
+this.previewImg=this.img.cloneNode(false);
+this.options.displayOnInit=true;
+this.hasPreviewImg=true;
+Element.addClassName(this.previewWrap,"imgCrop_previewWrap");
+Element.setStyle(this.previewWrap,{width:this.options.minWidth+"px",height:this.options.minHeight+"px"});
+this.previewWrap.appendChild(this.previewImg);
+}
+},subDrawArea:function(){
+if(this.hasPreviewImg){
+var _58=this.calcW();
+var _59=this.calcH();
+var _5a={x:this.imgW/_58,y:this.imgH/_59};
+var _5b={x:_58/this.options.minWidth,y:_59/this.options.minHeight};
+var _5c={w:Math.ceil(this.options.minWidth*_5a.x)+"px",h:Math.ceil(this.options.minHeight*_5a.y)+"px",x:"-"+Math.ceil(this.areaCoords.x1/_5b.x)+"px",y:"-"+Math.ceil(this.areaCoords.y1/_5b.y)+"px"};
+var _5d=this.previewImg.style;
+_5d.width=_5c.w;
+_5d.height=_5c.h;
+_5d.left=_5c.x;
+_5d.top=_5c.y;
+}
+}});
Binary files 2.0.5/wp-includes/js/crop/marqueeHoriz.gif and 2.2.2/wp-includes/js/crop/marqueeHoriz.gif differ
Binary files 2.0.5/wp-includes/js/crop/marqueeVert.gif and 2.2.2/wp-includes/js/crop/marqueeVert.gif differ
diff -ruN 2.0.5/wp-includes/js/dbx-key.js 2.2.2/wp-includes/js/dbx-key.js
--- 2.0.5/wp-includes/js/dbx-key.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/dbx-key.js	1969-12-31 18:00:00.000000000 -0600
@@ -1,39 +0,0 @@
-
-//initialisation function
-addLoadEvent( function()
-{
-	//create new docking boxes group
-	var meta = new dbxGroup(
-		'grabit', 		// container ID [/-_a-zA-Z0-9/]
-		'vertical', 	// orientation ['vertical'|'horizontal']
-		'10', 			// drag threshold ['n' pixels]
-		'no',			// restrict drag movement to container axis ['yes'|'no']
-		'10', 			// animate re-ordering [frames per transition, or '0' for no effect]
-		'yes', 			// include open/close toggle buttons ['yes'|'no']
-		'closed', 		// default state ['open'|'closed']
-		'open', 		// word for "open", as in "open this box"
-		'close', 		// word for "close", as in "close this box"
-		'click-down and drag to move this box', // sentence for "move this box" by mouse
-		'click to %toggle% this box', // pattern-match sentence for "(open|close) this box" by mouse
-		'use the arrow keys to move this box', // sentence for "move this box" by keyboard
-		', or press the enter key to %toggle% it',  // pattern-match sentence-fragment for "(open|close) this box" by keyboard
-		'%mytitle%  [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts
-		);
-
-	var advanced = new dbxGroup(
-		'advancedstuff', 		// container ID [/-_a-zA-Z0-9/]
-		'vertical', 		// orientation ['vertical'|'horizontal']
-		'10', 			// drag threshold ['n' pixels]
-		'yes',			// restrict drag movement to container axis ['yes'|'no']
-		'10', 			// animate re-ordering [frames per transition, or '0' for no effect]
-		'yes', 			// include open/close toggle buttons ['yes'|'no']
-		'closed', 		// default state ['open'|'closed']
-		'open', 		// word for "open", as in "open this box"
-		'close', 		// word for "close", as in "close this box"
-		'click-down and drag to move this box', // sentence for "move this box" by mouse
-		'click to %toggle% this box', // pattern-match sentence for "(open|close) this box" by mouse
-		'use the arrow keys to move this box', // sentence for "move this box" by keyboard
-		', or press the enter key to %toggle% it',  // pattern-match sentence-fragment for "(open|close) this box" by keyboard
-		'%mytitle%  [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts
-		);
-});
diff -ruN 2.0.5/wp-includes/js/dbx.js 2.2.2/wp-includes/js/dbx.js
--- 2.0.5/wp-includes/js/dbx.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/dbx.js	2006-08-09 14:39:17.000000000 -0500
@@ -1,6 +1,6 @@
-// DBX2.01 :: Docking Boxes (dbx)
+// DBX2.05 :: Docking Boxes (dbx)
 // *****************************************************
 // DOM scripting by brothercake -- http://www.brothercake.com/
 // GNU Lesser General Public License -- http://www.gnu.org/licenses/lgpl.html
 //******************************************************
-var dbx;function dbxManager(sid){dbx = this;if(!/^[-_a-z0-9]+$/i.test(sid)) { alert('Error from dbxManager:\n"' + sid + '" is an invalid session ID'); return; }this.supported = !(document.getElementsByTagName('*').length == 0 || (navigator.vendor == 'KDE' && typeof window.sidebar == 'undefined'));if(!this.supported) { return; }this.etype = typeof document.addEventListener != 'undefined' ? 'addEventListener' : typeof document.attachEvent != 'undefined' ? 'attachEvent' : 'none';this.eprefix = (this.etype == 'attachEvent' ? 'on' : '');if(typeof window.opera != 'undefined' && parseFloat(navigator.userAgent.toLowerCase().split(/opera[\/ ]/)[1].split(' ')[0], 10) < 7.5){this.etype = 'none';}if(this.etype == 'none') { this.supported = false; return; }this.running = 0;this.sid = sid;this.savedata = {};this.cookiestate = this.getCookieState();};dbxManager.prototype.setCookieState = function(){var now = new Date();now.setTime(now.getTime() + (365*24*60*60*1000));var str = '';for(j in this.savedata){if(typeof this.savedata[j]!='function'){str += j + '=' + this.savedata[j] + '&'}}this.state = str.replace(/^(.+)&$/, '$1');if(typeof this.onstatechange == 'undefined' || this.onstatechange()){document.cookie = 'dbx-' + this.sid + '='+ this.state+ '; expires=' + now.toGMTString()+ '; path=/';}};dbxManager.prototype.getCookieState = function(){this.cookiestate = null;if(document.cookie){if(document.cookie.indexOf('dbx-' + this.sid)!=-1){this.cookie = document.cookie.split('dbx-' + this.sid + '=')[1].split('&');for(var i in this.cookie){if(typeof this.cookie[i]!='function'){this.cookie[i] = this.cookie[i].split('=');this.cookie[i][1] = this.cookie[i][1].split(',');}}this.cookiestate = {};for(i in this.cookie){if(typeof this.cookie[i]!='function'){this.cookiestate[this.cookie[i][0]] = this.cookie[i][1];}}}}return this.cookiestate;};dbxManager.prototype.addDataMember = function(gid, order){this.savedata[gid] = order;};dbxManager.prototype.createElement = function(tag){return typeof document.createElementNS != 'undefined' ? document.createElementNS('http://www.w3.org/1999/xhtml', tag) : document.createElement(tag);};dbxManager.prototype.getTarget = function(e, pattern, node){if(typeof node != 'undefined'){var target = node;}else{target = typeof e.target != 'undefined' ? e.target : e.srcElement;}var regex = new RegExp(pattern, '');while(!regex.test(target.className)){target = target.parentNode;}return target;};function dbxGroup(gid, dir, thresh, fix, ani, togs, def, open, close, move, toggle, kmove, ktoggle, syntax){if(!/^[-_a-z0-9]+$/i.test(gid)) { alert('Error from dbxGroup:\n"' + gid + '" is an invalid container ID'); return; }this.container = document.getElementById(gid);if(this.container == null || !dbx.supported) { return; }var self = this;this.gid = gid;this.dragok = false;this.box = null;this.vertical = dir == 'vertical';this.threshold = parseInt(thresh, 10);this.restrict = fix == 'yes';this.resolution = parseInt(ani, 10);this.toggles = togs == 'yes';this.defopen = def != 'closed';this.vocab = {'open' : open,'close' : close,'move' : move,'toggle' : toggle,'kmove' : kmove,'ktoggle' : ktoggle,'syntax' : syntax};this.container.style.position = 'relative';this.container.style.display = 'block';if(typeof window.opera != 'undefined'){this.container.style.display = 'run-in';}this.boxes = [];this.buttons = [];this.order = [];this.eles = this.container.getElementsByTagName('*');for(var i=0; i<this.eles.length; i++){if(/dbx\-box/i.test(this.eles[i].className) && !/dbx\-dummy/i.test(this.eles[i].className)){this.eles[i].style.position = 'relative';this.eles[i].style.display = 'block';this.boxes.push(this.eles[i]);this.eles[i].className += ' dbx-box-open';this.eles[i].className += ' dbxid' + this.order.length;this.order.push(this.order.length.toString() + '+');this.eles[i][dbx.etype](dbx.eprefix + 'mousedown', function(e){if(!e) { e = window.event; }self.mousedown(e, dbx.getTarget(e, 'dbx\-box'));}, false);}if(/dbx\-handle/i.test(this.eles[i].className)){this.eles[i].style.position = 'relative';this.eles[i].style.display = 'block';this.eles[i].className += ' dbx-handle-cursor';this.eles[i].setAttribute('title', this.eles[i].getAttribute('title') == null || this.eles[i].title == '' ? this.vocab.move : this.vocab.syntax.replace('%mytitle%', this.eles[i].title).replace('%dbxtitle%', this.vocab.move));if(this.toggles){this.buttons.push(this.addToggleBehavior(this.eles[i]));}else{this.eles[i][dbx.etype](dbx.eprefix + 'key' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press'), function(e){if(!e) { e = window.event; }return self.keypress(e, dbx.getTarget(e, 'dbx\-handle'));}, false);this.eles[i][dbx.etype](dbx.eprefix + 'focus', function(e){if(!e) { e = window.event; }self.createTooltip(null, dbx.getTarget(e, 'dbx\-handle'));}, false);this.eles[i][dbx.etype](dbx.eprefix + 'blur', function(){self.removeTooltip();}, false);}}}dbx.addDataMember(this.gid, this.order.join(','));var dummy = this.container.appendChild(dbx.createElement('span'));dummy.className = 'dbx-box dbx-dummy';dummy.style.display = 'block';dummy.style.width = '0';dummy.style.height = '0';dummy.style.overflow = 'hidden';if(this.vertical) { dummy.className += ' dbx-offdummy'; }this.boxes.push(dummy);if(dbx.cookiestate != null && typeof dbx.cookiestate[this.gid] != 'undefined'){var num = dbx.cookiestate[this.gid].length;if(num == this.boxes.length - 1){for(i=0; i<num; i++){var index = parseInt(dbx.cookiestate[this.gid][i], 10);this.container.insertBefore(this.boxes[index], dummy);if(this.toggles && dbx.cookiestate[this.gid][i].charAt(1) == '-'){this.toggleBoxState(this.buttons[index], false);}}this.getBoxOrder();}}else if(!this.defopen && this.toggles){var len = this.buttons.length;for(i=0; i<len; i++){this.toggleBoxState(this.buttons[i], true);}}document[dbx.etype](dbx.eprefix + 'mouseout', function(e){if(typeof e.target == 'undefined') { e = window.event; e.relatedTarget = e.toElement; }if(e.relatedTarget == null){self.mouseup(e);}}, false);document[dbx.etype](dbx.eprefix + 'mousemove', function(e){self.mousemove(e);}, false);document[dbx.etype](dbx.eprefix + 'mouseup', function(e){self.mouseup(e);}, false);this.keydown = false;document[dbx.etype](dbx.eprefix + 'keydown', function(){self.keydown = true;}, false);document[dbx.etype](dbx.eprefix + 'keyup', function(){self.keydown = false;}, false);};dbxGroup.prototype.addToggleBehavior = function(){var self = this;var button = arguments[0].appendChild(dbx.createElement('a'));button.appendChild(document.createTextNode('\u00a0'));button.style.cursor = 'pointer';button.href = 'javascript:void(null)';button.className = 'dbx-toggle dbx-toggle-open';button.setAttribute('title', this.vocab.toggle.replace('%toggle%', this.vocab.close));button.hasfocus = typeof window.opera != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? null : false;this.tooltip = null;button.onclick = function(){if(this.hasfocus === true || this.hasfocus === null){self.removeTooltip();self.toggleBoxState(this, true);}};button['onkey' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press')] = function(e){if(!e) { e = window.event; }return self.keypress(e, this);};button.onfocus = function(){var len = self.buttons.length;for(var i=0; i<len; i++){self.buttons[i].className = self.buttons[i].className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');}var isopen = (/dbx\-toggle\-open/.test(this.className));this.className += ' dbx-toggle-hilite-' + (isopen ? 'open' : 'closed');self.createTooltip(isopen, this);this.isactive = true;if(this.hasfocus !== null) { this.hasfocus = true; }};button.onblur = function(){this.className = this.className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');self.removeTooltip();if(this.hasfocus !== null) { this.hasfocus = false; }};return button;};dbxGroup.prototype.toggleBoxState = function(button, regen){var isopen = (/dbx\-toggle\-open/.test(button.className));var parent = dbx.getTarget(null, 'dbx\-box', button);dbx.box = parent;dbx.toggle = button;if(typeof dbx.container == 'undefined'){dbx.group = dbx.getTarget(null, 'dbx\-group', parent);}else { dbx.group = dbx.container; }if((!isopen && (typeof dbx.onboxopen == 'undefined' || dbx.onboxopen()))||(isopen && (typeof dbx.onboxclose == 'undefined' || dbx.onboxclose()))){button.className = 'dbx-toggle dbx-toggle-' + (isopen ? 'closed' : 'open');button.title = this.vocab.toggle.replace('%toggle%', isopen ? this.vocab.open : this.vocab.close);if(typeof button.isactive != 'undefined'){button.className += ' dbx-toggle-hilite-' + (isopen ? 'closed' : 'open')}parent.className = parent.className.replace(/[ ](dbx-box-)(open|closed)/, ' $1' + (isopen ? 'closed' : 'open'));if(regen) { this.getBoxOrder(); }}};dbxGroup.prototype.shiftBoxPosition = function(e, anchor, positive){var parent = dbx.getTarget(null, 'dbx\-box', anchor);dbx.group = this.container;dbx.box = parent;dbx.event = e;if(typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()){var positions = [];var len = this.boxes.length;for(var i=0; i<len; i++){positions[i] = [i, this.boxes[i][this.vertical ? 'offsetTop' : 'offsetLeft']];if(parent == this.boxes[i]) { this.idref = i; }}positions.sort(this.compare);for(i=0; i<len; i++){if(positions[i][0] == this.idref){if((positive && i < len - 2) || (!positive && i > 0)){var sibling = this.boxes[positions[i + (positive ? 1 : -1)][0]];if(this.resolution > 0){var visipos = { 'x' : parent.offsetLeft, 'y' : parent.offsetTop };var siblingpos = { 'x' : sibling.offsetLeft, 'y' : sibling.offsetTop };}var obj = { 'insert' : (positive ? sibling : parent), 'before' : (positive ? parent : sibling) };this.container.insertBefore(obj.insert, obj.before);if(this.resolution > 0){var animators ={'sibling' : new dbxAnimator(this, sibling, siblingpos, this.resolution, true, anchor),'parent' : new dbxAnimator(this, parent, visipos, this.resolution, true, anchor)};}else{anchor.focus();}break;}}}this.getBoxOrder();}};dbxGroup.prototype.compare = function(a, b){return a[1] - b[1];};dbxGroup.prototype.createTooltip = function(isopen, anchor){if(this.keydown){this.tooltip = this.container.appendChild(dbx.createElement('span'));this.tooltip.style.visibility = 'hidden';this.tooltip.className = 'dbx-tooltip';if(isopen != null){this.tooltip.appendChild(document.createTextNode(this.vocab.kmove + this.vocab.ktoggle.replace('%toggle%', isopen ? this.vocab.close : this.vocab.open)));}else{this.tooltip.appendChild(document.createTextNode(this.vocab.kmove));}var parent = dbx.getTarget(null, 'dbx\-box', anchor);this.tooltip.style.left = parent.offsetLeft + 'px';this.tooltip.style.top = parent.offsetTop + 'px';var tooltip = this.tooltip;window.setTimeout(function(){if(tooltip != null) { tooltip.style.visibility = 'visible'; }}, 500);}};dbxGroup.prototype.removeTooltip = function(){if(this.tooltip != null){this.tooltip.parentNode.removeChild(this.tooltip);this.tooltip = null;}};dbxGroup.prototype.mousedown = function(e, box){var node = typeof e.target != 'undefined' ? e.target : e.srcElement;if(node.nodeName == '#text') { node = node.parentNode; }if(!/dbx\-(toggle|box|group)/i.test(node.className)){while(!/dbx\-(handle|box|group)/i.test(node.className)){node = node.parentNode;}}if(/dbx\-handle/i.test(node.className)){this.removeTooltip();this.released = false;this.initial = { 'x' : e.clientX, 'y' : e.clientY };this.current = { 'x' : 0, 'y' : 0 };this.createCloneBox(box);if(typeof e.preventDefault != 'undefined' ) { e.preventDefault(); }if(typeof document.onselectstart != 'undefined'){document.onselectstart = function() { return false; }}}};dbxGroup.prototype.mousemove = function(e){if(this.dragok && this.box != null){this.positive = this.vertical ? (e.clientY > this.current.y ? true : false) : (e.clientX > this.current.x ? true : false);this.current = { 'x' : e.clientX, 'y' : e.clientY };var overall = { 'x' : this.current.x - this.initial.x, 'y' : this.current.y - this.initial.y };if(((overall.x >= 0 && overall.x <= this.threshold) || (overall.x <= 0 && overall.x >= 0 - this.threshold))&&((overall.y >= 0 && overall.y <= this.threshold) || (overall.y <= 0 && overall.y >= 0 - this.threshold))){this.current.x -= overall.x;this.current.y -= overall.y;}if(this.released || overall.x > this.threshold || overall.x < (0 - this.threshold) || overall.y > this.threshold || overall.y < (0 - this.threshold)){dbx.group = this.container;dbx.box = this.box;dbx.event = e;if(typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()){this.released = true;if(!this.restrict || !this.vertical) { this.boxclone.style.left = (this.current.x - this.difference.x) + 'px'; }if(!this.restrict || this.vertical) { this.boxclone.style.top = (this.current.y - this.difference.y) + 'px'; }this.moveOriginalToPosition(this.current.x, this.current.y);if(typeof e.preventDefault != 'undefined' ) { e.preventDefault(); }}}}return true;};dbxGroup.prototype.mouseup = function(e){if(this.box != null){this.moveOriginalToPosition(e.clientX, e.clientY);this.removeCloneBox();this.getBoxOrder();if(typeof document.onselectstart != 'undefined'){document.onselectstart = function() { return true; }}}this.dragok = false;};dbxGroup.prototype.keypress = function(e, anchor){if(/^(3[7-9])|(40)$/.test(e.keyCode)){this.removeTooltip();if((this.vertical && /^(38|40)$/.test(e.keyCode)) || (!this.vertical && /^(37|39)$/.test(e.keyCode))){this.shiftBoxPosition(e, anchor, /^[3][78]$/.test(e.keyCode) ? false : true);if(typeof e.preventDefault != 'undefined') { e.preventDefault(); }else { return false; }typeof e.stopPropagation != 'undefined' ? e.stopPropagation() : e.cancelBubble = true;this.keydown = false;}}return true;};dbxGroup.prototype.getBoxOrder = function(){this.order = [];var len = this.eles.length;for(var j=0; j<len; j++){if(/dbx\-box/i.test(this.eles[j].className) && !/dbx\-(clone|dummy)/i.test(this.eles[j].className)){this.order.push(this.eles[j].className.split('dbxid')[1] + (/dbx\-box\-open/i.test(this.eles[j].className) ? '+' : '-'));}}dbx.savedata[this.gid] = this.order.join(',');dbx.setCookieState();};dbxGroup.prototype.createClone = function(){var clone = this.container.appendChild(arguments[0].cloneNode(true));clone.className += ' dbx-clone';clone.style.position = 'absolute';clone.style.visibility = 'hidden';clone.style.zIndex = arguments[1];clone.style.left = arguments[2].x + 'px';clone.style.top = arguments[2].y + 'px';clone.style.width = arguments[0].offsetWidth + 'px';clone.style.height = arguments[0].offsetHeight + 'px';return clone;};dbxGroup.prototype.createCloneBox = function(box){this.box = box;this.position = { 'x' : this.box.offsetLeft, 'y' : this.box.offsetTop };this.difference = { 'x' : (this.initial.x - this.position.x), 'y' : (this.initial.y - this.position.y) };this.boxclone = this.createClone(this.box, 30000, this.position);this.boxclone.style.cursor = 'move';this.dragok = true;};dbxGroup.prototype.removeCloneBox = function(){this.container.removeChild(this.boxclone);this.box.style.visibility = 'visible';this.box = null;};dbxGroup.prototype.moveOriginalToPosition = function(clientX, clientY){var cloneprops = {'xy' : this.vertical ? clientY - this.difference.y : clientX - this.difference.x,'wh' : this.vertical ? this.boxclone.offsetHeight : this.boxclone.offsetWidth};this.box.style.visibility = 'hidden';this.boxclone.style.visibility = 'visible';var len = this.boxes.length;for(var i=0; i<len; i++){var boxprops = {'xy' : this.vertical ? this.boxes[i].offsetTop : this.boxes[i].offsetLeft,'wh' : this.vertical ? this.boxes[i].offsetHeight : this.boxes[i].offsetWidth};if((this.positive && cloneprops.xy + cloneprops.wh > boxprops.xy && cloneprops.xy < boxprops.xy)||(!this.positive && cloneprops.xy < boxprops.xy && cloneprops.xy + cloneprops.wh > boxprops.xy)){if(this.boxes[i] == this.box) { return; }var sibling = this.box.nextSibling;while(sibling.className == null || !/dbx\-box/.test(sibling.className)){sibling = sibling.nextSibling;}if(this.boxes[i] == sibling) { return; }if(this.resolution > 0){if(this.box[this.vertical ? 'offsetTop' : 'offsetLeft'] < boxprops.xy){var visibox = this.boxes[i].previousSibling;while(visibox.className == null || !/dbx\-box/.test(visibox.className)){visibox = visibox.previousSibling;}}else{visibox = this.boxes[i];}var visipos = { 'x' : visibox.offsetLeft, 'y' : visibox.offsetTop };}var prepos = { 'x' : this.box.offsetLeft, 'y' : this.box.offsetTop };this.container.insertBefore(this.box, this.boxes[i]);this.initial.x += (this.box.offsetLeft - prepos.x);this.initial.y += (this.box.offsetTop - prepos.y);if(this.resolution > 0 && visibox != this.box){var animator = new dbxAnimator(this, visibox, visipos, this.resolution, false, null);}else{}break;}}};function dbxAnimator(caller, box, pos, res, kbd, anchor){this.caller = caller;this.box = box;this.timer = null;var before = pos[this.caller.vertical ? 'y' : 'x'];var after = this.box[this.caller.vertical ? 'offsetTop' : 'offsetLeft'];if(before != after){if(dbx.running > this.caller.boxes.length - 1) { return; }var clone = this.caller.createClone(this.box, 29999, arguments[2]);clone.style.visibility = 'visible';this.box.style.visibility = 'hidden';this.animateClone(clone,before,after > before ? after - before : 0 - (before - after),this.caller.vertical ? 'top' : 'left',res,kbd,anchor);}};dbxAnimator.prototype.animateClone = function(clone, current, change, dir, res, kbd, anchor){var self = this;var count = 0;dbx.running ++;this.timer = window.setInterval(function(){count ++;current += change / res;clone.style[dir] = current + 'px';if(count == res){window.clearTimeout(self.timer);self.timer = null;dbx.running --;self.caller.container.removeChild(clone);self.box.style.visibility = 'visible';if(kbd){if(anchor != null && anchor.parentNode.style.visibility != 'hidden'){anchor.focus();}else if(self.caller.toggles){var button = self.caller.buttons[parseInt(self.box.className.split('dbxid')[1],10)];if(button != null && typeof button.isactive != 'undefined'){button.focus();}}}}}, 20);};if(typeof window.attachEvent != 'undefined'){window.attachEvent('onunload', function(){var ev = ['mousedown', 'mousemove', 'mouseup', 'mouseout', 'click', 'keydown', 'keyup', 'focus', 'blur', 'selectstart', 'statechange', 'boxdrag', 'boxopen', 'boxclose'];var el = ev.length;var dl = document.all.length;for(var i=0; i<dl; i++){for(var j=0; j<el; j++){document.all[i]['on' + ev[j]] = null;}}});}
\ No newline at end of file
+var dbx;function dbxManager(sid){dbx = this;if(!/^[-_a-z0-9]+$/i.test(sid)) { alert('Error from dbxManager:\n"' + sid + '" is an invalid session ID'); return; }this.supported = !(document.getElementsByTagName('*').length == 0 || (navigator.vendor == 'KDE' && typeof window.sidebar == 'undefined'));if(!this.supported) { return; }this.etype = typeof document.addEventListener != 'undefined' ? 'addEventListener' : typeof document.attachEvent != 'undefined' ? 'attachEvent' : 'none';this.eprefix = (this.etype == 'attachEvent' ? 'on' : '');if(typeof window.opera != 'undefined' && parseFloat(navigator.userAgent.toLowerCase().split(/opera[\/ ]/)[1].split(' ')[0], 10) < 7.5){this.etype = 'none';}if(this.etype == 'none') { this.supported = false; return; }this.running = 0;this.sid = sid;this.savedata = {};this.cookiestate = this.getCookieState();};dbxManager.prototype.setCookieState = function(){var now = new Date();now.setTime(now.getTime() + (365*24*60*60*1000));var str = '';for(j in this.savedata){if(typeof this.savedata[j]!='function'){str += j + '=' + this.savedata[j] + '&'}}this.state = str.replace(/^(.+)&$/, '$1');this.cookiestring = this.state.replace(/,/g, '|');this.cookiestring = this.cookiestring.replace(/=/g, ':');if(typeof this.onstatechange == 'undefined' || this.onstatechange()){document.cookie = 'dbx-' + this.sid + '='+ this.cookiestring+ '; expires=' + now.toGMTString()+ '; path=/';}};dbxManager.prototype.getCookieState = function(){this.cookiestate = null;if(document.cookie){if(document.cookie.indexOf('dbx-' + this.sid)!=-1){this.cookie = document.cookie.split('dbx-' + this.sid + '=')[1].split(';')[0].split('&');for(var i in this.cookie){if(typeof this.cookie[i]!='function'){this.cookie[i] = this.cookie[i].replace(/\|/g, ',');this.cookie[i]= this.cookie[i].replace(/:/g, '=');this.cookie[i] = this.cookie[i].split('=');this.cookie[i][1] = this.cookie[i][1].split(',');}}this.cookiestate = {};for(i in this.cookie){if(typeof this.cookie[i]!='function'){this.cookiestate[this.cookie[i][0]] = this.cookie[i][1];}}}}return this.cookiestate;};dbxManager.prototype.addDataMember = function(gid, order){this.savedata[gid] = order;};dbxManager.prototype.createElement = function(tag){return typeof document.createElementNS != 'undefined' ? document.createElementNS('http://www.w3.org/1999/xhtml', tag) : document.createElement(tag);};dbxManager.prototype.getTarget = function(e, pattern, node){if(typeof node != 'undefined'){var target = node;}else{target = typeof e.target != 'undefined' ? e.target : e.srcElement;}var regex = new RegExp(pattern, '');while(!regex.test(target.className)){target = target.parentNode;}return target;};function dbxGroup(gid, dir, thresh, fix, ani, togs, def, open, close, move, toggle, kmove, ktoggle, syntax){if(!/^[-_a-z0-9]+$/i.test(gid)) { alert('Error from dbxGroup:\n"' + gid + '" is an invalid container ID'); return; }this.container = document.getElementById(gid);if(this.container == null || !dbx.supported) { return; }var self = this;this.gid = gid;this.dragok = false;this.box = null;this.vertical = dir == 'vertical';this.threshold = parseInt(thresh, 10);this.restrict = fix == 'yes';this.resolution = parseInt(ani, 10);this.toggles = togs == 'yes';this.defopen = def != 'closed';this.vocab = {'open' : open,'close' : close,'move' : move,'toggle' : toggle,'kmove' : kmove,'ktoggle' : ktoggle,'syntax' : syntax};this.container.style.position = 'relative';this.container.style.display = 'block';if(typeof window.opera != 'undefined'){this.container.style.display = 'run-in';}this.boxes = [];this.buttons = [];this.order = [];this.eles = this.container.getElementsByTagName('*');for(var i=0; i<this.eles.length; i++){if(/dbx\-box/i.test(this.eles[i].className) && !/dbx\-dummy/i.test(this.eles[i].className)){this.eles[i].style.position = 'relative';this.eles[i].style.display = 'block';this.boxes.push(this.eles[i]);this.eles[i].className += ' dbx-box-open';this.eles[i].className += ' dbxid' + this.order.length;this.order.push(this.order.length.toString() + '+');this.eles[i][dbx.etype](dbx.eprefix + 'mousedown', function(e){if(!e) { e = window.event; }self.mousedown(e, dbx.getTarget(e, 'dbx\-box'));}, false);}if(/dbx\-handle/i.test(this.eles[i].className)){this.eles[i].style.position = 'relative';this.eles[i].style.display = 'block';this.eles[i].className += ' dbx-handle-cursor';this.eles[i].setAttribute('title', this.eles[i].getAttribute('title') == null || this.eles[i].title == '' ? this.vocab.move : this.vocab.syntax.replace('%mytitle%', this.eles[i].title).replace('%dbxtitle%', this.vocab.move));if(this.toggles){this.buttons.push(this.addToggleBehavior(this.eles[i]));}else{this.eles[i][dbx.etype](dbx.eprefix + 'key' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press'), function(e){if(!e) { e = window.event; }return self.keypress(e, dbx.getTarget(e, 'dbx\-handle'));}, false);this.eles[i][dbx.etype](dbx.eprefix + 'focus', function(e){if(!e) { e = window.event; }self.createTooltip(null, dbx.getTarget(e, 'dbx\-handle'));}, false);this.eles[i][dbx.etype](dbx.eprefix + 'blur', function(){self.removeTooltip();}, false);}}}dbx.addDataMember(this.gid, this.order.join(','));var dummy = this.container.appendChild(dbx.createElement('span'));dummy.className = 'dbx-box dbx-dummy';dummy.style.display = 'block';dummy.style.width = '0';dummy.style.height = '0';dummy.style.overflow = 'hidden';if(this.vertical) { dummy.className += ' dbx-offdummy'; }this.boxes.push(dummy);if(dbx.cookiestate != null && typeof dbx.cookiestate[this.gid] != 'undefined'){var num = dbx.cookiestate[this.gid].length;if(num == this.boxes.length - 1){for(i=0; i<num; i++){var index = parseInt(dbx.cookiestate[this.gid][i], 10);this.container.insertBefore(this.boxes[index], dummy);if(this.toggles && /\-$/.test(dbx.cookiestate[this.gid][i])){this.toggleBoxState(this.buttons[index], false);}}this.getBoxOrder();}}else if(!this.defopen && this.toggles){var len = this.buttons.length;for(i=0; i<len; i++){this.toggleBoxState(this.buttons[i], true);}}document[dbx.etype](dbx.eprefix + 'mouseout', function(e){if(typeof e.target == 'undefined') { e = window.event; e.relatedTarget = e.toElement; }if(e.relatedTarget == null){self.mouseup(e);}}, false);document[dbx.etype](dbx.eprefix + 'mousemove', function(e){self.mousemove(e);return !self.dragok;}, false);document[dbx.etype](dbx.eprefix + 'mouseup', function(e){self.mouseup(e);}, false);this.keydown = false;document[dbx.etype](dbx.eprefix + 'keydown', function(){self.keydown = true;}, false);document[dbx.etype](dbx.eprefix + 'keyup', function(){self.keydown = false;}, false);};dbxGroup.prototype.addToggleBehavior = function(){var self = this;var button = arguments[0].appendChild(dbx.createElement('a'));button.appendChild(document.createTextNode('\u00a0'));button.style.cursor = 'pointer';button.href = 'javascript:void(null)';button.className = 'dbx-toggle dbx-toggle-open';button.setAttribute('title', this.vocab.toggle.replace('%toggle%', this.vocab.close));button.hasfocus = typeof window.opera != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? null : false;this.tooltip = null;button.onclick = function(){if(this.hasfocus === true || this.hasfocus === null){self.removeTooltip();self.toggleBoxState(this, true);}};button['onkey' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press')] = function(e){if(!e) { e = window.event; }return self.keypress(e, this);};button.onfocus = function(){var len = self.buttons.length;for(var i=0; i<len; i++){self.buttons[i].className = self.buttons[i].className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');}var isopen = (/dbx\-toggle\-open/.test(this.className));this.className += ' dbx-toggle-hilite-' + (isopen ? 'open' : 'closed');self.createTooltip(isopen, this);this.isactive = true;if(this.hasfocus !== null) { this.hasfocus = true; }};button.onblur = function(){this.className = this.className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');self.removeTooltip();if(this.hasfocus !== null) { this.hasfocus = false; }};return button;};dbxGroup.prototype.toggleBoxState = function(button, regen){var isopen = (/dbx\-toggle\-open/.test(button.className));var parent = dbx.getTarget(null, 'dbx\-box', button);dbx.box = parent;dbx.toggle = button;if(typeof dbx.container == 'undefined'){dbx.group = dbx.getTarget(null, 'dbx\-group', parent);}else { dbx.group = dbx.container; }if((!isopen && (typeof dbx.onboxopen == 'undefined' || dbx.onboxopen()))||(isopen && (typeof dbx.onboxclose == 'undefined' || dbx.onboxclose()))){button.className = 'dbx-toggle dbx-toggle-' + (isopen ? 'closed' : 'open');button.title = this.vocab.toggle.replace('%toggle%', isopen ? this.vocab.open : this.vocab.close);if(typeof button.isactive != 'undefined'){button.className += ' dbx-toggle-hilite-' + (isopen ? 'closed' : 'open')}parent.className = parent.className.replace(/[ ](dbx-box-)(open|closed)/, ' $1' + (isopen ? 'closed' : 'open'));if(regen) { this.getBoxOrder(); }}};dbxGroup.prototype.shiftBoxPosition = function(e, anchor, positive){var parent = dbx.getTarget(null, 'dbx\-box', anchor);dbx.group = this.container;dbx.box = parent;dbx.event = e;if(typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()){var positions = [];var len = this.boxes.length;for(var i=0; i<len; i++){positions[i] = [i, this.boxes[i][this.vertical ? 'offsetTop' : 'offsetLeft']];if(parent == this.boxes[i]) { this.idref = i; }}positions.sort(this.compare);for(i=0; i<len; i++){if(positions[i][0] == this.idref){if((positive && i < len - 2) || (!positive && i > 0)){var sibling = this.boxes[positions[i + (positive ? 1 : -1)][0]];if(this.resolution > 0){var visipos = { 'x' : parent.offsetLeft, 'y' : parent.offsetTop };var siblingpos = { 'x' : sibling.offsetLeft, 'y' : sibling.offsetTop };}var obj = { 'insert' : (positive ? sibling : parent), 'before' : (positive ? parent : sibling) };this.container.insertBefore(obj.insert, obj.before);if(this.resolution > 0){var animators ={'sibling' : new dbxAnimator(this, sibling, siblingpos, this.resolution, true, anchor),'parent' : new dbxAnimator(this, parent, visipos, this.resolution, true, anchor)};}else{anchor.focus();}break;}}}this.getBoxOrder();}};dbxGroup.prototype.compare = function(a, b){return a[1] - b[1];};dbxGroup.prototype.createTooltip = function(isopen, anchor){if(this.keydown){this.tooltip = this.container.appendChild(dbx.createElement('span'));this.tooltip.style.visibility = 'hidden';this.tooltip.className = 'dbx-tooltip';if(isopen != null){this.tooltip.appendChild(document.createTextNode(this.vocab.kmove + this.vocab.ktoggle.replace('%toggle%', isopen ? this.vocab.close : this.vocab.open)));}else{this.tooltip.appendChild(document.createTextNode(this.vocab.kmove));}var parent = dbx.getTarget(null, 'dbx\-box', anchor);this.tooltip.style.left = parent.offsetLeft + 'px';this.tooltip.style.top = parent.offsetTop + 'px';var tooltip = this.tooltip;window.setTimeout(function(){if(tooltip != null) { tooltip.style.visibility = 'visible'; }}, 500);}};dbxGroup.prototype.removeTooltip = function(){if(this.tooltip != null){this.tooltip.parentNode.removeChild(this.tooltip);this.tooltip = null;}};dbxGroup.prototype.mousedown = function(e, box){var node = typeof e.target != 'undefined' ? e.target : e.srcElement;if(node.nodeName == '#text') { node = node.parentNode; }if(!/dbx\-(toggle|box|group)/i.test(node.className)){while(!/dbx\-(handle|box|group)/i.test(node.className)){node = node.parentNode;}}if(/dbx\-handle/i.test(node.className)){this.removeTooltip();this.released = false;this.initial = { 'x' : e.clientX, 'y' : e.clientY };this.current = { 'x' : 0, 'y' : 0 };this.createCloneBox(box);if(typeof e.preventDefault != 'undefined' ) { e.preventDefault(); }if(typeof document.onselectstart != 'undefined'){document.onselectstart = function() { return false; }}}};dbxGroup.prototype.mousemove = function(e){if(this.dragok && this.box != null){this.positive = this.vertical ? (e.clientY > this.current.y ? true : false) : (e.clientX > this.current.x ? true : false);this.current = { 'x' : e.clientX, 'y' : e.clientY };var overall = { 'x' : this.current.x - this.initial.x, 'y' : this.current.y - this.initial.y };if(((overall.x >= 0 && overall.x <= this.threshold) || (overall.x <= 0 && overall.x >= 0 - this.threshold))&&((overall.y >= 0 && overall.y <= this.threshold) || (overall.y <= 0 && overall.y >= 0 - this.threshold))){this.current.x -= overall.x;this.current.y -= overall.y;}if(this.released || overall.x > this.threshold || overall.x < (0 - this.threshold) || overall.y > this.threshold || overall.y < (0 - this.threshold)){dbx.group = this.container;dbx.box = this.box;dbx.event = e;if(typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()){this.released = true;if(!this.restrict || !this.vertical) { this.boxclone.style.left = (this.current.x - this.difference.x) + 'px'; }if(!this.restrict || this.vertical) { this.boxclone.style.top = (this.current.y - this.difference.y) + 'px'; }this.moveOriginalToPosition(this.current.x, this.current.y);if(typeof e.preventDefault != 'undefined' ) { e.preventDefault(); }}}}return true;};dbxGroup.prototype.mouseup = function(e){if(this.box != null){this.moveOriginalToPosition(e.clientX, e.clientY);this.removeCloneBox();this.getBoxOrder();if(typeof document.onselectstart != 'undefined'){document.onselectstart = function() { return true; }}}this.dragok = false;};dbxGroup.prototype.keypress = function(e, anchor){if(/^(3[7-9])|(40)$/.test(e.keyCode)){this.removeTooltip();if((this.vertical && /^(38|40)$/.test(e.keyCode)) || (!this.vertical && /^(37|39)$/.test(e.keyCode))){this.shiftBoxPosition(e, anchor, /^[3][78]$/.test(e.keyCode) ? false : true);if(typeof e.preventDefault != 'undefined') { e.preventDefault(); }else { return false; }typeof e.stopPropagation != 'undefined' ? e.stopPropagation() : e.cancelBubble = true;this.keydown = false;}}return true;};dbxGroup.prototype.getBoxOrder = function(){this.order = [];var len = this.eles.length;for(var j=0; j<len; j++){if(/dbx\-box/i.test(this.eles[j].className) && !/dbx\-(clone|dummy)/i.test(this.eles[j].className)){this.order.push(this.eles[j].className.split('dbxid')[1] + (/dbx\-box\-open/i.test(this.eles[j].className) ? '+' : '-'));}}dbx.savedata[this.gid] = this.order.join(',');dbx.setCookieState();};dbxGroup.prototype.createClone = function(){var clone = this.container.appendChild(arguments[0].cloneNode(true));clone.className += ' dbx-clone';clone.style.position = 'absolute';clone.style.visibility = 'hidden';clone.style.zIndex = arguments[1];clone.style.left = arguments[2].x + 'px';clone.style.top = arguments[2].y + 'px';clone.style.width = arguments[0].offsetWidth + 'px';clone.style.height = arguments[0].offsetHeight + 'px';return clone;};dbxGroup.prototype.createCloneBox = function(box){this.box = box;this.position = { 'x' : this.box.offsetLeft, 'y' : this.box.offsetTop };this.difference = { 'x' : (this.initial.x - this.position.x), 'y' : (this.initial.y - this.position.y) };this.boxclone = this.createClone(this.box, 30000, this.position);this.boxclone.style.cursor = 'move';this.dragok = true;};dbxGroup.prototype.removeCloneBox = function(){this.container.removeChild(this.boxclone);this.box.style.visibility = 'visible';this.box = null;};dbxGroup.prototype.moveOriginalToPosition = function(clientX, clientY){var cloneprops = {'xy' : this.vertical ? clientY - this.difference.y : clientX - this.difference.x,'wh' : this.vertical ? this.boxclone.offsetHeight : this.boxclone.offsetWidth};this.box.style.visibility = 'hidden';this.boxclone.style.visibility = 'visible';var len = this.boxes.length;for(var i=0; i<len; i++){var boxprops = {'xy' : this.vertical ? this.boxes[i].offsetTop : this.boxes[i].offsetLeft,'wh' : this.vertical ? this.boxes[i].offsetHeight : this.boxes[i].offsetWidth};if((this.positive && cloneprops.xy + cloneprops.wh > boxprops.xy && cloneprops.xy < boxprops.xy)||(!this.positive && cloneprops.xy < boxprops.xy && cloneprops.xy + cloneprops.wh > boxprops.xy)){if(this.boxes[i] == this.box) { return; }var sibling = this.box.nextSibling;while(sibling.className == null || !/dbx\-box/.test(sibling.className)){sibling = sibling.nextSibling;}if(this.boxes[i] == sibling) { return; }if(this.resolution > 0){if(this.box[this.vertical ? 'offsetTop' : 'offsetLeft'] < boxprops.xy){var visibox = this.boxes[i].previousSibling;while(visibox.className == null || !/dbx\-box/.test(visibox.className)){visibox = visibox.previousSibling;}}else{visibox = this.boxes[i];}var visipos = { 'x' : visibox.offsetLeft, 'y' : visibox.offsetTop };}var prepos = { 'x' : this.box.offsetLeft, 'y' : this.box.offsetTop };this.container.insertBefore(this.box, this.boxes[i]);this.initial.x += (this.box.offsetLeft - prepos.x);this.initial.y += (this.box.offsetTop - prepos.y);if(this.resolution > 0 && visibox != this.box){var animator = new dbxAnimator(this, visibox, visipos, this.resolution, false, null);}else{}break;}}};function dbxAnimator(caller, box, pos, res, kbd, anchor){this.caller = caller;this.box = box;this.timer = null;var before = pos[this.caller.vertical ? 'y' : 'x'];var after = this.box[this.caller.vertical ? 'offsetTop' : 'offsetLeft'];if(before != after){if(dbx.running > this.caller.boxes.length - 1) { return; }var clone = this.caller.createClone(this.box, 29999, arguments[2]);clone.style.visibility = 'visible';this.box.style.visibility = 'hidden';this.animateClone(clone,before,after > before ? after - before : 0 - (before - after),this.caller.vertical ? 'top' : 'left',res,kbd,anchor);}};dbxAnimator.prototype.animateClone = function(clone, current, change, dir, res, kbd, anchor){var self = this;var count = 0;dbx.running ++;this.timer = window.setInterval(function(){count ++;current += change / res;clone.style[dir] = current + 'px';if(count == res){window.clearTimeout(self.timer);self.timer = null;dbx.running --;self.caller.container.removeChild(clone);self.box.style.visibility = 'visible';if(kbd){if(anchor != null && anchor.parentNode.style.visibility != 'hidden'){anchor.focus();}else if(self.caller.toggles){var button = self.caller.buttons[parseInt(self.box.className.split('dbxid')[1],10)];if(button != null && typeof button.isactive != 'undefined'){button.focus();}}}}}, 20);};if(typeof window.attachEvent != 'undefined'){window.attachEvent('onunload', function(){var ev = ['mousedown', 'mousemove', 'mouseup', 'mouseout', 'click', 'keydown', 'keyup', 'focus', 'blur', 'selectstart', 'statechange', 'boxdrag', 'boxopen', 'boxclose'];var el = ev.length;var dl = document.all.length;for(var i=0; i<dl; i++){for(var j=0; j<el; j++){document.all[i]['on' + ev[j]] = null;}}});}
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/fat.js 2.2.2/wp-includes/js/fat.js
--- 2.0.5/wp-includes/js/fat.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/fat.js	2006-03-28 19:51:55.000000000 -0600
@@ -11,7 +11,7 @@
 		b = b.toString(16); if (b.length == 1) b = '0' + b;
 		return "#" + r + g + b;
 	},
-	fade_all : function ()
+	fade_all : function (dur)
 	{
 		var a = document.getElementsByTagName("*");
 		for (var i = 0; i < a.length; i++) 
@@ -21,7 +21,7 @@
 			if (r)
 			{
 				if (!r[1]) r[1] = "";
-				if (o.id) Fat.fade_element(o.id,null,null,"#"+r[1]);
+				if (o.id) Fat.fade_element(o.id,null,dur,"#"+r[1]);
 			}
 		}
 	},
@@ -31,22 +31,22 @@
 		if (!duration) duration = 3000;
 		if (!from || from=="#") from = "#FFFF33";
 		if (!to) to = this.get_bgcolor(id);
-		
+
 		var frames = Math.round(fps * (duration / 1000));
 		var interval = duration / frames;
 		var delay = interval;
 		var frame = 0;
-		
+
 		if (from.length < 7) from += from.substr(1,3);
 		if (to.length < 7) to += to.substr(1,3);
-		
+
 		var rf = parseInt(from.substr(1,2),16);
 		var gf = parseInt(from.substr(3,2),16);
 		var bf = parseInt(from.substr(5,2),16);
 		var rt = parseInt(to.substr(1,2),16);
 		var gt = parseInt(to.substr(3,2),16);
 		var bt = parseInt(to.substr(5,2),16);
-		
+
 		var r,g,b,h;
 		while (frame < frames)
 		{
@@ -54,7 +54,7 @@
 			g = Math.floor(gf * ((frames-frame)/frames) + gt * (frame/frames));
 			b = Math.floor(bf * ((frames-frame)/frames) + bt * (frame/frames));
 			h = this.make_hex(r,g,b);
-		
+
 			setTimeout("Fat.set_bgcolor('"+id+"','"+h+"')", delay);
 
 			frame++;
@@ -87,4 +87,4 @@
 
 addLoadEvent(function ()  {
 	Fat.fade_all();
-});
\ No newline at end of file
+});
diff -ruN 2.0.5/wp-includes/js/jquery/interface.js 2.2.2/wp-includes/js/jquery/interface.js
--- 2.0.5/wp-includes/js/jquery/interface.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/jquery/interface.js	2007-02-20 20:39:07.000000000 -0600
@@ -0,0 +1,12 @@
+/**
+ * Interface Elements for jQuery
+ * 
+ * http://interface.eyecon.ro
+ * 
+ * Copyright (c) 2006 Stefan Petre
+ * Dual licensed under the MIT (MIT-LICENSE.txt) 
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *   
+ *
+ */
+ eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('k.f2={2r:u(M){E q.1E(u(){if(!M.aR||!M.aZ)E;D el=q;el.2l={aq:M.aq||cO,aR:M.aR,aZ:M.aZ,8e:M.8e||\'fV\',aJ:M.aJ||\'fV\',2Y:M.2Y&&2g M.2Y==\'u\'?M.2Y:I,3i:M.2Y&&2g M.3i==\'u\'?M.3i:I,7U:M.7U&&2g M.7U==\'u\'?M.7U:I,as:k(M.aR,q),8f:k(M.aZ,q),H:M.H||8J,67:M.67||0};el.2l.8f.2G().B(\'W\',\'9R\').eq(0).B({W:el.2l.aq+\'U\',19:\'2B\'}).2T();el.2l.as.1E(u(2N){q.7X=2N}).gC(u(){k(q).2R(el.2l.aJ)},u(){k(q).4i(el.2l.aJ)}).1J(\'5h\',u(e){if(el.2l.67==q.7X)E;el.2l.as.eq(el.2l.67).4i(el.2l.8e).2T().eq(q.7X).2R(el.2l.8e).2T();el.2l.8f.eq(el.2l.67).5w({W:0},el.2l.H,u(){q.14.19=\'1o\';if(el.2l.3i){el.2l.3i.1D(el,[q])}}).2T().eq(q.7X).1Y().5w({W:el.2l.aq},el.2l.H,u(){q.14.19=\'2B\';if(el.2l.2Y){el.2l.2Y.1D(el,[q])}}).2T();if(el.2l.7U){el.2l.7U.1D(el,[q,el.2l.8f.K(q.7X),el.2l.as.K(el.2l.67),el.2l.8f.K(el.2l.67)])}el.2l.67=q.7X}).eq(0).2R(el.2l.8e).2T();k(q).B(\'W\',k(q).B(\'W\')).B(\'2U\',\'2K\')})}};k.fn.gN=k.f2.2r;k.aA={2r:u(M){E q.1E(u(){D el=q;D 7E=2*18.2Q/f1;D an=2*18.2Q;if(k(el).B(\'Y\')!=\'2s\'&&k(el).B(\'Y\')!=\'1P\'){k(el).B(\'Y\',\'2s\')}el.1l={1R:k(M.1R,q),2F:M.2F,6q:M.6q,aD:M.aD,an:an,1N:k.1a.2o(q),Y:k.1a.3w(q),26:18.2Q/2,bi:M.bi,8p:M.6r,6r:[],aG:I,7E:2*18.2Q/f1};el.1l.fB=(el.1l.1N.w-el.1l.2F)/2;el.1l.7D=(el.1l.1N.h-el.1l.6q-el.1l.6q*el.1l.8p)/2;el.1l.2D=2*18.2Q/el.1l.1R.1N();el.1l.ba=el.1l.1N.w/2;el.1l.b9=el.1l.1N.h/2-el.1l.6q*el.1l.8p;D ak=1h.3F(\'22\');k(ak).B({Y:\'1P\',3I:1,Q:0,O:0});k(el).1S(ak);el.1l.1R.1E(u(2N){a6=k(\'1T\',q).K(0);W=T(el.1l.6q*el.1l.8p);if(k.3a.4t){3E=1h.3F(\'1T\');k(3E).B(\'Y\',\'1P\');3E.2J=a6.2J;3E.14.5E=\'gE 9n:9w.9y.cC(1G=60, 14=1, gB=0, gA=0, gv=0, gF=0)\'}P{3E=1h.3F(\'3E\');if(3E.fD){4L=3E.fD("2d");3E.14.Y=\'1P\';3E.14.W=W+\'U\';3E.14.Z=el.1l.2F+\'U\';3E.W=W;3E.Z=el.1l.2F;4L.gu();4L.gO(0,W);4L.gk(1,-1);4L.gp(a6,0,0,el.1l.2F,W);4L.6H();4L.gm="gG-4l";D ap=4L.hy(0,0,0,W);ap.fs(1,"fr(1V, 1V, 1V, 1)");ap.fs(0,"fr(1V, 1V, 1V, 0.6)");4L.hx=ap;if(hA.hB.3J(\'hw\')!=-1){4L.hv()}P{4L.hu(0,0,el.1l.2F,W)}}}el.1l.6r[2N]=3E;k(ak).1S(3E)}).1J(\'9z\',u(e){el.1l.aG=1b;el.1l.H=el.1l.7E*0.1*el.1l.H/18.3S(el.1l.H);E I}).1J(\'8B\',u(e){el.1l.aG=I;E I});k.aA.7T(el);el.1l.H=el.1l.7E*0.2;el.1l.ht=1X.6V(u(){el.1l.26+=el.1l.H;if(el.1l.26>an)el.1l.26=0;k.aA.7T(el)},20);k(el).1J(\'8B\',u(){el.1l.H=el.1l.7E*0.2*el.1l.H/18.3S(el.1l.H)}).1J(\'3D\',u(e){if(el.1l.aG==I){1s=k.1a.4a(e);fz=el.1l.1N.w-1s.x+el.1l.Y.x;el.1l.H=el.1l.bi*el.1l.7E*(el.1l.1N.w/2-fz)/(el.1l.1N.w/2)}})})},7T:u(el){el.1l.1R.1E(u(2N){b8=el.1l.26+2N*el.1l.2D;x=el.1l.fB*18.5H(b8);y=el.1l.7D*18.83(b8);f9=T(2a*(el.1l.7D+y)/(2*el.1l.7D));fk=(el.1l.7D+y)/(2*el.1l.7D);Z=T((el.1l.2F-el.1l.aD)*fk+el.1l.aD);W=T(Z*el.1l.6q/el.1l.2F);q.14.Q=el.1l.b9+y-W/2+"U";q.14.O=el.1l.ba+x-Z/2+"U";q.14.Z=Z+"U";q.14.W=W+"U";q.14.3I=f9;el.1l.6r[2N].14.Q=T(el.1l.b9+y+W-1-W/2)+"U";el.1l.6r[2N].14.O=T(el.1l.ba+x-Z/2)+"U";el.1l.6r[2N].14.Z=Z+"U";el.1l.6r[2N].14.W=T(W*el.1l.8p)+"U"})}};k.fn.hI=k.aA.2r;k.23({G:{c8:u(p,n,1W,1H,1m){E((-18.5H(p*18.2Q)/2)+0.5)*1H+1W},hK:u(p,n,1W,1H,1m){E 1H*(n/=1m)*n*n+1W},fl:u(p,n,1W,1H,1m){E-1H*((n=n/1m-1)*n*n*n-1)+1W},hm:u(p,n,1W,1H,1m){if((n/=1m/2)<1)E 1H/2*n*n*n*n+1W;E-1H/2*((n-=2)*n*n*n-2)+1W},8l:u(p,n,1W,1H,1m){if((n/=1m)<(1/2.75)){E 1H*(7.aB*n*n)+1W}P if(n<(2/2.75)){E 1H*(7.aB*(n-=(1.5/2.75))*n+.75)+1W}P if(n<(2.5/2.75)){E 1H*(7.aB*(n-=(2.25/2.75))*n+.gY)+1W}P{E 1H*(7.aB*(n-=(2.h2/2.75))*n+.gX)+1W}},cr:u(p,n,1W,1H,1m){if(k.G.8l)E 1H-k.G.8l(p,1m-n,0,1H,1m)+1W;E 1W+1H},gW:u(p,n,1W,1H,1m){if(k.G.cr&&k.G.8l)if(n<1m/2)E k.G.cr(p,n*2,0,1H,1m)*.5+1W;E k.G.8l(p,n*2-1m,0,1H,1m)*.5+1H*.5+1W;E 1W+1H},gQ:u(p,n,1W,1H,1m){D a,s;if(n==0)E 1W;if((n/=1m)==1)E 1W+1H;a=1H*0.3;p=1m*.3;if(a<18.3S(1H)){a=1H;s=p/4}P{s=p/(2*18.2Q)*18.cb(1H/a)}E-(a*18.6b(2,10*(n-=1))*18.83((n*1m-s)*(2*18.2Q)/p))+1W},gT:u(p,n,1W,1H,1m){D a,s;if(n==0)E 1W;if((n/=1m/2)==2)E 1W+1H;a=1H*0.3;p=1m*.3;if(a<18.3S(1H)){a=1H;s=p/4}P{s=p/(2*18.2Q)*18.cb(1H/a)}E a*18.6b(2,-10*n)*18.83((n*1m-s)*(2*18.2Q)/p)+1H+1W},gV:u(p,n,1W,1H,1m){D a,s;if(n==0)E 1W;if((n/=1m/2)==2)E 1W+1H;a=1H*0.3;p=1m*.3;if(a<18.3S(1H)){a=1H;s=p/4}P{s=p/(2*18.2Q)*18.cb(1H/a)}if(n<1){E-.5*(a*18.6b(2,10*(n-=1))*18.83((n*1m-s)*(2*18.2Q)/p))+1W}E a*18.6b(2,-10*(n-=1))*18.83((n*1m-s)*(2*18.2Q)/p)*.5+1H+1W}}});k.6n={2r:u(M){E q.1E(u(){D el=q;el.1F={1R:k(M.1R,q),1Z:k(M.1Z,q),1M:k.1a.3w(q),2F:M.2F,ax:M.ax,7Y:M.7Y,ge:M.ge,51:M.51,6x:M.6x};k.6n.aH(el,0);k(1X).1J(\'gU\',u(){el.1F.1M=k.1a.3w(el);k.6n.aH(el,0);k.6n.7T(el)});k.6n.7T(el);el.1F.1R.1J(\'9z\',u(){k(el.1F.ax,q).K(0).14.19=\'2B\'}).1J(\'8B\',u(){k(el.1F.ax,q).K(0).14.19=\'1o\'});k(1h).1J(\'3D\',u(e){D 1s=k.1a.4a(e);D 5s=0;if(el.1F.51&&el.1F.51==\'cv\')D aI=1s.x-el.1F.1M.x-(el.4c-el.1F.2F*el.1F.1R.1N())/2-el.1F.2F/2;P if(el.1F.51&&el.1F.51==\'2L\')D aI=1s.x-el.1F.1M.x-el.4c+el.1F.2F*el.1F.1R.1N();P D aI=1s.x-el.1F.1M.x;D fP=18.6b(1s.y-el.1F.1M.y-el.5W/2,2);el.1F.1R.1E(u(2N){45=18.ez(18.6b(aI-2N*el.1F.2F,2)+fP);45-=el.1F.2F/2;45=45<0?0:45;45=45>el.1F.7Y?el.1F.7Y:45;45=el.1F.7Y-45;bB=el.1F.6x*45/el.1F.7Y;q.14.Z=el.1F.2F+bB+\'U\';q.14.O=el.1F.2F*2N+5s+\'U\';5s+=bB});k.6n.aH(el,5s)})})},aH:u(el,5s){if(el.1F.51)if(el.1F.51==\'cv\')el.1F.1Z.K(0).14.O=(el.4c-el.1F.2F*el.1F.1R.1N())/2-5s/2+\'U\';P if(el.1F.51==\'O\')el.1F.1Z.K(0).14.O=-5s/el.1F.1R.1N()+\'U\';P if(el.1F.51==\'2L\')el.1F.1Z.K(0).14.O=(el.4c-el.1F.2F*el.1F.1R.1N())-5s/2+\'U\';el.1F.1Z.K(0).14.Z=el.1F.2F*el.1F.1R.1N()+5s+\'U\'},7T:u(el){el.1F.1R.1E(u(2N){q.14.Z=el.1F.2F+\'U\';q.14.O=el.1F.2F*2N+\'U\'})}};k.fn.hi=k.6n.2r;k.N={1c:S,8R:S,3A:S,2I:S,4y:S,cl:S,1d:S,2h:S,1R:S,5o:u(){k.N.8R.5o();if(k.N.3A){k.N.3A.2G()}},4w:u(){k.N.1R=S;k.N.2h=S;k.N.4y=k.N.1d.2y;if(k.N.1c.B(\'19\')==\'2B\'){if(k.N.1d.1f.fx){3m(k.N.1d.1f.fx.1u){1e\'c6\':k.N.1c.7a(k.N.1d.1f.fx.1m,k.N.5o);1r;1e\'1z\':k.N.1c.fq(k.N.1d.1f.fx.1m,k.N.5o);1r;1e\'a7\':k.N.1c.g3(k.N.1d.1f.fx.1m,k.N.5o);1r}}P{k.N.1c.2G()}if(k.N.1d.1f.3i)k.N.1d.1f.3i.1D(k.N.1d,[k.N.1c,k.N.3A])}P{k.N.5o()}1X.bH(k.N.2I)},dQ:u(){D 1d=k.N.1d;D 4d=k.N.aY(1d);if(1d&&4d.3o!=k.N.4y&&4d.3o.1g>=1d.1f.aL){k.N.4y=4d.3o;k.N.cl=4d.3o;81={2n:k(1d).1p(\'hj\')||\'2n\',2y:4d.3o};k.hl({1u:\'hk\',81:k.hf(81),he:u(fZ){1d.1f.4e=k(\'3o\',fZ);1N=1d.1f.4e.1N();if(1N>0){D 5p=\'\';1d.1f.4e.1E(u(2N){5p+=\'<8P 4I="\'+k(\'2y\',q).3g()+\'" 8K="\'+2N+\'" 14="9b: ad;">\'+k(\'3g\',q).3g()+\'</8P>\'});if(1d.1f.aU){D 3M=k(\'2y\',1d.1f.4e.K(0)).3g();1d.2y=4d.3j+3M+1d.1f.3N+4d.66;k.N.6J(1d,4d.3o.1g!=3M.1g?(4d.3j.1g+4d.3o.1g):3M.1g,4d.3o.1g!=3M.1g?(4d.3j.1g+3M.1g):3M.1g)}if(1N>0){k.N.cj(1d,5p)}P{k.N.4w()}}P{k.N.4w()}},5N:1d.1f.aN})}},cj:u(1d,5p){k.N.8R.3x(5p);k.N.1R=k(\'8P\',k.N.8R.K(0));k.N.1R.9z(k.N.di).1J(\'5h\',k.N.dj);D Y=k.1a.3w(1d);D 1N=k.1a.2o(1d);k.N.1c.B(\'Q\',Y.y+1N.hb+\'U\').B(\'O\',Y.x+\'U\').2R(1d.1f.aM);if(k.N.3A){k.N.3A.B(\'19\',\'2B\').B(\'Q\',Y.y+1N.hb+\'U\').B(\'O\',Y.x+\'U\').B(\'Z\',k.N.1c.B(\'Z\')).B(\'W\',k.N.1c.B(\'W\'))}k.N.2h=0;k.N.1R.K(0).3l=1d.1f.7H;k.N.8Q(1d,1d.1f.4e.K(0),\'7J\');if(k.N.1c.B(\'19\')==\'1o\'){if(1d.1f.bV){D cp=k.1a.aT(1d,1b);D cm=k.1a.6U(1d,1b);k.N.1c.B(\'Z\',1d.4c-(k.dF?(cp.l+cp.r+cm.l+cm.r):0)+\'U\')}if(1d.1f.fx){3m(1d.1f.fx.1u){1e\'c6\':k.N.1c.7f(1d.1f.fx.1m);1r;1e\'1z\':k.N.1c.fo(1d.1f.fx.1m);1r;1e\'a7\':k.N.1c.gb(1d.1f.fx.1m);1r}}P{k.N.1c.1Y()}if(k.N.1d.1f.2Y)k.N.1d.1f.2Y.1D(k.N.1d,[k.N.1c,k.N.3A])}},dO:u(){D 1d=q;if(1d.1f.4e){k.N.4y=1d.2y;k.N.cl=1d.2y;D 5p=\'\';1d.1f.4e.1E(u(2N){2y=k(\'2y\',q).3g().6c();fY=1d.2y.6c();if(2y.3J(fY)==0){5p+=\'<8P 4I="\'+k(\'2y\',q).3g()+\'" 8K="\'+2N+\'" 14="9b: ad;">\'+k(\'3g\',q).3g()+\'</8P>\'}});if(5p!=\'\'){k.N.cj(1d,5p);q.1f.9x=1b;E}}1d.1f.4e=S;q.1f.9x=I},6J:u(2n,26,2T){if(2n.b1){D 6t=2n.b1();6t.hp(1b);6t.dI("ck",26);6t.ha("ck",-2T+26);6t.8C()}P if(2n.aF){2n.aF(26,2T)}P{if(2n.5q){2n.5q=26;2n.dN=2T}}2n.6K()},f0:u(2n){if(2n.5q)E 2n.5q;P if(2n.b1){D 6t=1h.6J.dZ();D eX=6t.h9();E 0-eX.dI(\'ck\',-h6)}},aY:u(2n){D 4P={2y:2n.2y,3j:\'\',66:\'\',3o:\'\'};if(2n.1f.aQ){D 8N=I;D 5q=k.N.f0(2n)||0;D 4T=4P.2y.7C(2n.1f.3N);24(D i=0;i<4T.1g;i++){if((4P.3j.1g+4T[i].1g>=5q||5q==0)&&!8N){if(4P.3j.1g<=5q)4P.3o=4T[i];P 4P.66+=4T[i]+(4T[i]!=\'\'?2n.1f.3N:\'\');8N=1b}P if(8N){4P.66+=4T[i]+(4T[i]!=\'\'?2n.1f.3N:\'\')}if(!8N){4P.3j+=4T[i]+(4T.1g>1?2n.1f.3N:\'\')}}}P{4P.3o=4P.2y}E 4P},bU:u(e){1X.bH(k.N.2I);D 1d=k.N.aY(q);D 3K=e.7L||e.7K||-1;if(/13|27|35|36|38|40|9/.48(3K)&&k.N.1R){if(1X.2k){1X.2k.bT=1b;1X.2k.c0=I}P{e.aP();e.aW()}if(k.N.2h!=S)k.N.1R.K(k.N.2h||0).3l=\'\';P k.N.2h=-1;3m(3K){1e 9:1e 13:if(k.N.2h==-1)k.N.2h=0;D 2h=k.N.1R.K(k.N.2h||0);D 3M=2h.5C(\'4I\');q.2y=1d.3j+3M+q.1f.3N+1d.66;k.N.4y=1d.3o;k.N.6J(q,1d.3j.1g+3M.1g+q.1f.3N.1g,1d.3j.1g+3M.1g+q.1f.3N.1g);k.N.4w();if(q.1f.68){4u=T(2h.5C(\'8K\'))||0;k.N.8Q(q,q.1f.4e.K(4u),\'68\')}if(q.7W)q.7W(I);E 3K!=13;1r;1e 27:q.2y=1d.3j+k.N.4y+q.1f.3N+1d.66;q.1f.4e=S;k.N.4w();if(q.7W)q.7W(I);E I;1r;1e 35:k.N.2h=k.N.1R.1N()-1;1r;1e 36:k.N.2h=0;1r;1e 38:k.N.2h--;if(k.N.2h<0)k.N.2h=k.N.1R.1N()-1;1r;1e 40:k.N.2h++;if(k.N.2h==k.N.1R.1N())k.N.2h=0;1r}k.N.8Q(q,q.1f.4e.K(k.N.2h||0),\'7J\');k.N.1R.K(k.N.2h||0).3l=q.1f.7H;if(k.N.1R.K(k.N.2h||0).7W)k.N.1R.K(k.N.2h||0).7W(I);if(q.1f.aU){D aK=k.N.1R.K(k.N.2h||0).5C(\'4I\');q.2y=1d.3j+aK+q.1f.3N+1d.66;if(k.N.4y.1g!=aK.1g)k.N.6J(q,1d.3j.1g+k.N.4y.1g,1d.3j.1g+aK.1g)}E I}k.N.dO.1D(q);if(q.1f.9x==I){if(1d.3o!=k.N.4y&&1d.3o.1g>=q.1f.aL)k.N.2I=1X.9T(k.N.dQ,q.1f.54);if(k.N.1R){k.N.4w()}}E 1b},8Q:u(2n,3o,1u){if(2n.1f[1u]){D 81={};ar=3o.f3(\'*\');24(i=0;i<ar.1g;i++){81[ar[i].4Y]=ar[i].7c.h4}2n.1f[1u].1D(2n,[81])}},di:u(e){if(k.N.1R){if(k.N.2h!=S)k.N.1R.K(k.N.2h||0).3l=\'\';k.N.1R.K(k.N.2h||0).3l=\'\';k.N.2h=T(q.5C(\'8K\'))||0;k.N.1R.K(k.N.2h||0).3l=k.N.1d.1f.7H}},dj:u(2k){1X.bH(k.N.2I);2k=2k||k.2k.gS(1X.2k);2k.aP();2k.aW();D 1d=k.N.aY(k.N.1d);D 3M=q.5C(\'4I\');k.N.1d.2y=1d.3j+3M+k.N.1d.1f.3N+1d.66;k.N.4y=q.5C(\'4I\');k.N.6J(k.N.1d,1d.3j.1g+3M.1g+k.N.1d.1f.3N.1g,1d.3j.1g+3M.1g+k.N.1d.1f.3N.1g);k.N.4w();if(k.N.1d.1f.68){4u=T(q.5C(\'8K\'))||0;k.N.8Q(k.N.1d,k.N.1d.1f.4e.K(4u),\'68\')}E I},eJ:u(e){3K=e.7L||e.7K||-1;if(/13|27|35|36|38|40/.48(3K)&&k.N.1R){if(1X.2k){1X.2k.bT=1b;1X.2k.c0=I}P{e.aP();e.aW()}E I}},2r:u(M){if(!M.aN||!k.1a){E}if(!k.N.1c){if(k.3a.4t){k(\'2e\',1h).1S(\'<3A 14="19:1o;Y:1P;5E:9n:9w.9y.cC(1G=0);" id="ds" 2J="ek:I;" ej="0" ep="cD"></3A>\');k.N.3A=k(\'#ds\')}k(\'2e\',1h).1S(\'<22 id="dr" 14="Y: 1P; Q: 0; O: 0; z-cZ: h3; 19: 1o;"><9h 14="6w: 0;8F: 0; h1-14: 1o; z-cZ: h0;">&7k;</9h></22>\');k.N.1c=k(\'#dr\');k.N.8R=k(\'9h\',k.N.1c)}E q.1E(u(){if(q.4Y!=\'ch\'&&q.5C(\'1u\')!=\'3g\')E;q.1f={};q.1f.aN=M.aN;q.1f.aL=18.3S(T(M.aL)||1);q.1f.aM=M.aM?M.aM:\'\';q.1f.7H=M.7H?M.7H:\'\';q.1f.68=M.68&&M.68.1K==2A?M.68:S;q.1f.2Y=M.2Y&&M.2Y.1K==2A?M.2Y:S;q.1f.3i=M.3i&&M.3i.1K==2A?M.3i:S;q.1f.7J=M.7J&&M.7J.1K==2A?M.7J:S;q.1f.bV=M.bV||I;q.1f.aQ=M.aQ||I;q.1f.3N=q.1f.aQ?(M.3N||\', \'):\'\';q.1f.aU=M.aU?1b:I;q.1f.54=18.3S(T(M.54)||aC);if(M.fx&&M.fx.1K==7M){if(!M.fx.1u||!/c6|1z|a7/.48(M.fx.1u)){M.fx.1u=\'1z\'}if(M.fx.1u==\'1z\'&&!k.fx.1z)E;if(M.fx.1u==\'a7\'&&!k.fx.61)E;M.fx.1m=18.3S(T(M.fx.1m)||8J);if(M.fx.1m>q.1f.54){M.fx.1m=q.1f.54-2a}q.1f.fx=M.fx}q.1f.4e=S;q.1f.9x=I;k(q).1p(\'bU\',\'eN\').6K(u(){k.N.1d=q;k.N.4y=q.2y}).dH(k.N.eJ).6y(k.N.bU).5B(u(){k.N.2I=1X.9T(k.N.4w,hM)})})}};k.fn.hR=k.N.2r;k.1y={2I:S,4Q:S,29:S,2D:10,26:u(el,4J,2D,eG){k.1y.4Q=el;k.1y.29=4J;k.1y.2D=T(2D)||10;k.1y.2I=1X.6V(k.1y.eF,T(eG)||40)},eF:u(){24(i=0;i<k.1y.29.1g;i++){if(!k.1y.29[i].2X){k.1y.29[i].2X=k.23(k.1a.7G(k.1y.29[i]),k.1a.74(k.1y.29[i]),k.1a.6z(k.1y.29[i]))}P{k.1y.29[i].2X.t=k.1y.29[i].3d;k.1y.29[i].2X.l=k.1y.29[i].3c}if(k.1y.4Q.A&&k.1y.4Q.A.7q==1b){69={x:k.1y.4Q.A.2v,y:k.1y.4Q.A.2q,1C:k.1y.4Q.A.1B.1C,hb:k.1y.4Q.A.1B.hb}}P{69=k.23(k.1a.7G(k.1y.4Q),k.1a.74(k.1y.4Q))}if(k.1y.29[i].2X.t>0&&k.1y.29[i].2X.y+k.1y.29[i].2X.t>69.y){k.1y.29[i].3d-=k.1y.2D}P if(k.1y.29[i].2X.t<=k.1y.29[i].2X.h&&k.1y.29[i].2X.t+k.1y.29[i].2X.hb<69.y+69.hb){k.1y.29[i].3d+=k.1y.2D}if(k.1y.29[i].2X.l>0&&k.1y.29[i].2X.x+k.1y.29[i].2X.l>69.x){k.1y.29[i].3c-=k.1y.2D}P if(k.1y.29[i].2X.l<=k.1y.29[i].2X.hP&&k.1y.29[i].2X.l+k.1y.29[i].2X.1C<69.x+69.1C){k.1y.29[i].3c+=k.1y.2D}}},8o:u(){1X.5T(k.1y.2I);k.1y.4Q=S;k.1y.29=S;24(i in k.1y.29){k.1y.29[i].2X=S}}};k.11={1c:S,F:S,4U:u(){E q.1E(u(){if(q.9I){q.A.5e.3q(\'5v\',k.11.bN);q.A=S;q.9I=I;if(k.3a.4t){q.bE="eN"}P{q.14.hq=\'\';q.14.e1=\'\';q.14.e7=\'\'}}})},bN:u(e){if(k.11.F!=S){k.11.9A(e);E I}D C=q.3U;k(1h).1J(\'3D\',k.11.bX).1J(\'5P\',k.11.9A);C.A.1s=k.1a.4a(e);C.A.4B=C.A.1s;C.A.7q=I;C.A.ho=q!=q.3U;k.11.F=C;if(C.A.5i&&q!=q.3U){bS=k.1a.3w(C.31);bQ=k.1a.2o(C);bR={x:T(k.B(C,\'O\'))||0,y:T(k.B(C,\'Q\'))||0};dx=C.A.4B.x-bS.x-bQ.1C/2-bR.x;dy=C.A.4B.y-bS.y-bQ.hb/2-bR.y;k.3b.5c(C,[dx,dy])}E k.7n||I},ea:u(e){D C=k.11.F;C.A.7q=1b;D 9G=C.14;C.A.7V=k.B(C,\'19\');C.A.4n=k.B(C,\'Y\');if(!C.A.cz)C.A.cz=C.A.4n;C.A.2c={x:T(k.B(C,\'O\'))||0,y:T(k.B(C,\'Q\'))||0};C.A.9B=0;C.A.ai=0;if(k.3a.4t){D bW=k.1a.6U(C,1b);C.A.9B=bW.l||0;C.A.ai=bW.t||0}C.A.1B=k.23(k.1a.3w(C),k.1a.2o(C));if(C.A.4n!=\'2s\'&&C.A.4n!=\'1P\'){9G.Y=\'2s\'}k.11.1c.5o();D 5g=C.fI(1b);k(5g).B({19:\'2B\',O:\'2P\',Q:\'2P\'});5g.14.5K=\'0\';5g.14.5z=\'0\';5g.14.5k=\'0\';5g.14.5j=\'0\';k.11.1c.1S(5g);D 3Y=k.11.1c.K(0).14;if(C.A.bD){3Y.Z=\'9F\';3Y.W=\'9F\'}P{3Y.W=C.A.1B.hb+\'U\';3Y.Z=C.A.1B.1C+\'U\'}3Y.19=\'2B\';3Y.5K=\'2P\';3Y.5z=\'2P\';3Y.5k=\'2P\';3Y.5j=\'2P\';k.23(C.A.1B,k.1a.2o(5g));if(C.A.2V){if(C.A.2V.O){C.A.2c.x+=C.A.1s.x-C.A.1B.x-C.A.2V.O;C.A.1B.x=C.A.1s.x-C.A.2V.O}if(C.A.2V.Q){C.A.2c.y+=C.A.1s.y-C.A.1B.y-C.A.2V.Q;C.A.1B.y=C.A.1s.y-C.A.2V.Q}if(C.A.2V.2L){C.A.2c.x+=C.A.1s.x-C.A.1B.x-C.A.1B.hb+C.A.2V.2L;C.A.1B.x=C.A.1s.x-C.A.1B.1C+C.A.2V.2L}if(C.A.2V.4D){C.A.2c.y+=C.A.1s.y-C.A.1B.y-C.A.1B.hb+C.A.2V.4D;C.A.1B.y=C.A.1s.y-C.A.1B.hb+C.A.2V.4D}}C.A.2v=C.A.2c.x;C.A.2q=C.A.2c.y;if(C.A.8s||C.A.2p==\'94\'){8U=k.1a.6U(C.31,1b);C.A.1B.x=C.8t+(k.3a.4t?0:k.3a.7I?-8U.l:8U.l);C.A.1B.y=C.8G+(k.3a.4t?0:k.3a.7I?-8U.t:8U.t);k(C.31).1S(k.11.1c.K(0))}if(C.A.2p){k.11.c5(C);C.A.5t.2p=k.11.ce}if(C.A.5i){k.3b.ct(C)}3Y.O=C.A.1B.x-C.A.9B+\'U\';3Y.Q=C.A.1B.y-C.A.ai+\'U\';3Y.Z=C.A.1B.1C+\'U\';3Y.W=C.A.1B.hb+\'U\';k.11.F.A.9E=I;if(C.A.gx){C.A.5t.6a=k.11.c7}if(C.A.3I!=I){k.11.1c.B(\'3I\',C.A.3I)}if(C.A.1G){k.11.1c.B(\'1G\',C.A.1G);if(1X.71){k.11.1c.B(\'5E\',\'8V(1G=\'+C.A.1G*2a+\')\')}}if(C.A.7O){k.11.1c.2R(C.A.7O);k.11.1c.K(0).7c.14.19=\'1o\'}if(C.A.4o)C.A.4o.1D(C,[5g,C.A.2c.x,C.A.2c.y]);if(k.1x&&k.1x.8D>0){k.1x.ed(C)}if(C.A.46==I){9G.19=\'1o\'}E I},c5:u(C){if(C.A.2p.1K==b0){if(C.A.2p==\'94\'){C.A.28=k.23({x:0,y:0},k.1a.2o(C.31));D 8S=k.1a.6U(C.31,1b);C.A.28.w=C.A.28.1C-8S.l-8S.r;C.A.28.h=C.A.28.hb-8S.t-8S.b}P if(C.A.2p==\'1h\'){D bY=k.1a.bm();C.A.28={x:0,y:0,w:bY.w,h:bY.h}}}P if(C.A.2p.1K==7F){C.A.28={x:T(C.A.2p[0])||0,y:T(C.A.2p[1])||0,w:T(C.A.2p[2])||0,h:T(C.A.2p[3])||0}}C.A.28.dx=C.A.28.x-C.A.1B.x;C.A.28.dy=C.A.28.y-C.A.1B.y},9H:u(F){if(F.A.8s||F.A.2p==\'94\'){k(\'2e\',1h).1S(k.11.1c.K(0))}k.11.1c.5o().2G().B(\'1G\',1);if(1X.71){k.11.1c.B(\'5E\',\'8V(1G=2a)\')}},9A:u(e){k(1h).3q(\'3D\',k.11.bX).3q(\'5P\',k.11.9A);if(k.11.F==S){E}D F=k.11.F;k.11.F=S;if(F.A.7q==I){E I}if(F.A.44==1b){k(F).B(\'Y\',F.A.4n)}D 9G=F.14;if(F.5i){k.11.1c.B(\'9b\',\'8j\')}if(F.A.7O){k.11.1c.4i(F.A.7O)}if(F.A.6N==I){if(F.A.fx>0){if(!F.A.1O||F.A.1O==\'4j\'){D x=12 k.fx(F,{1m:F.A.fx},\'O\');x.1L(F.A.2c.x,F.A.8y)}if(!F.A.1O||F.A.1O==\'49\'){D y=12 k.fx(F,{1m:F.A.fx},\'Q\');y.1L(F.A.2c.y,F.A.8v)}}P{if(!F.A.1O||F.A.1O==\'4j\')F.14.O=F.A.8y+\'U\';if(!F.A.1O||F.A.1O==\'49\')F.14.Q=F.A.8v+\'U\'}k.11.9H(F);if(F.A.46==I){k(F).B(\'19\',F.A.7V)}}P if(F.A.fx>0){F.A.9E=1b;D dh=I;if(k.1x&&k.1t&&F.A.44){dh=k.1a.3w(k.1t.1c.K(0))}k.11.1c.5w({O:dh?dh.x:F.A.1B.x,Q:dh?dh.y:F.A.1B.y},F.A.fx,u(){F.A.9E=I;if(F.A.46==I){F.14.19=F.A.7V}k.11.9H(F)})}P{k.11.9H(F);if(F.A.46==I){k(F).B(\'19\',F.A.7V)}}if(k.1x&&k.1x.8D>0){k.1x.eO(F)}if(k.1t&&F.A.44){k.1t.fC(F)}if(F.A.2Z&&(F.A.8y!=F.A.2c.x||F.A.8v!=F.A.2c.y)){F.A.2Z.1D(F,F.A.b3||[0,0,F.A.8y,F.A.8v])}if(F.A.3T)F.A.3T.1D(F);E I},c7:u(x,y,dx,dy){if(dx!=0)dx=T((dx+(q.A.gx*dx/18.3S(dx))/2)/q.A.gx)*q.A.gx;if(dy!=0)dy=T((dy+(q.A.gy*dy/18.3S(dy))/2)/q.A.gy)*q.A.gy;E{dx:dx,dy:dy,x:0,y:0}},ce:u(x,y,dx,dy){dx=18.3L(18.3r(dx,q.A.28.dx),q.A.28.w+q.A.28.dx-q.A.1B.1C);dy=18.3L(18.3r(dy,q.A.28.dy),q.A.28.h+q.A.28.dy-q.A.1B.hb);E{dx:dx,dy:dy,x:0,y:0}},bX:u(e){if(k.11.F==S||k.11.F.A.9E==1b){E}D F=k.11.F;F.A.4B=k.1a.4a(e);if(F.A.7q==I){45=18.ez(18.6b(F.A.1s.x-F.A.4B.x,2)+18.6b(F.A.1s.y-F.A.4B.y,2));if(45<F.A.6M){E}P{k.11.ea(e)}}D dx=F.A.4B.x-F.A.1s.x;D dy=F.A.4B.y-F.A.1s.y;24(D i in F.A.5t){D 3y=F.A.5t[i].1D(F,[F.A.2c.x+dx,F.A.2c.y+dy,dx,dy]);if(3y&&3y.1K==7M){dx=i!=\'7R\'?3y.dx:(3y.x-F.A.2c.x);dy=i!=\'7R\'?3y.dy:(3y.y-F.A.2c.y)}}F.A.2v=F.A.1B.x+dx-F.A.9B;F.A.2q=F.A.1B.y+dy-F.A.ai;if(F.A.5i&&(F.A.3H||F.A.2Z)){k.3b.3H(F,F.A.2v,F.A.2q)}if(F.A.4m)F.A.4m.1D(F,[F.A.2c.x+dx,F.A.2c.y+dy]);if(!F.A.1O||F.A.1O==\'4j\'){F.A.8y=F.A.2c.x+dx;k.11.1c.K(0).14.O=F.A.2v+\'U\'}if(!F.A.1O||F.A.1O==\'49\'){F.A.8v=F.A.2c.y+dy;k.11.1c.K(0).14.Q=F.A.2q+\'U\'}if(k.1x&&k.1x.8D>0){k.1x.al(F)}E I},2r:u(o){if(!k.11.1c){k(\'2e\',1h).1S(\'<22 id="e8"></22>\');k.11.1c=k(\'#e8\');D el=k.11.1c.K(0);D 4J=el.14;4J.Y=\'1P\';4J.19=\'1o\';4J.9b=\'8j\';4J.eu=\'1o\';4J.2U=\'2K\';if(1X.71){el.bE="e4"}P{4J.gi=\'1o\';4J.e7=\'1o\';4J.e1=\'1o\'}}if(!o){o={}}E q.1E(u(){if(q.9I||!k.1a)E;if(1X.71){q.gh=u(){E I};q.gj=u(){E I}}D el=q;D 5e=o.3v?k(q).gf(o.3v):k(q);if(k.3a.4t){5e.1E(u(){q.bE="e4"})}P{5e.B(\'-gI-7R-8C\',\'1o\');5e.B(\'7R-8C\',\'1o\');5e.B(\'-gH-7R-8C\',\'1o\')}q.A={5e:5e,6N:o.6N?1b:I,46:o.46?1b:I,44:o.44?o.44:I,5i:o.5i?o.5i:I,8s:o.8s?o.8s:I,3I:o.3I?T(o.3I)||0:I,1G:o.1G?2m(o.1G):I,fx:T(o.fx)||S,6R:o.6R?o.6R:I,5t:{},1s:{},4o:o.4o&&o.4o.1K==2A?o.4o:I,3T:o.3T&&o.3T.1K==2A?o.3T:I,2Z:o.2Z&&o.2Z.1K==2A?o.2Z:I,1O:/49|4j/.48(o.1O)?o.1O:I,6M:o.6M?T(o.6M)||0:0,2V:o.2V?o.2V:I,bD:o.bD?1b:I,7O:o.7O||I};if(o.5t&&o.5t.1K==2A)q.A.5t.7R=o.5t;if(o.4m&&o.4m.1K==2A)q.A.4m=o.4m;if(o.2p&&((o.2p.1K==b0&&(o.2p==\'94\'||o.2p==\'1h\'))||(o.2p.1K==7F&&o.2p.1g==4))){q.A.2p=o.2p}if(o.2O){q.A.2O=o.2O}if(o.6a){if(2g o.6a==\'gz\'){q.A.gx=T(o.6a)||1;q.A.gy=T(o.6a)||1}P if(o.6a.1g==2){q.A.gx=T(o.6a[0])||1;q.A.gy=T(o.6a[1])||1}}if(o.3H&&o.3H.1K==2A){q.A.3H=o.3H}q.9I=1b;5e.1E(u(){q.3U=el});5e.1J(\'5v\',k.11.bN)})}};k.fn.23({aS:k.11.4U,7t:k.11.2r});k.1x={du:u(5J,5G,7Q,7S){E 5J<=k.11.F.A.2v&&(5J+7Q)>=(k.11.F.A.2v+k.11.F.A.1B.w)&&5G<=k.11.F.A.2q&&(5G+7S)>=(k.11.F.A.2q+k.11.F.A.1B.h)?1b:I},cV:u(5J,5G,7Q,7S){E!(5J>(k.11.F.A.2v+k.11.F.A.1B.w)||(5J+7Q)<k.11.F.A.2v||5G>(k.11.F.A.2q+k.11.F.A.1B.h)||(5G+7S)<k.11.F.A.2q)?1b:I},1s:u(5J,5G,7Q,7S){E 5J<k.11.F.A.4B.x&&(5J+7Q)>k.11.F.A.4B.x&&5G<k.11.F.A.4B.y&&(5G+7S)>k.11.F.A.4B.y?1b:I},5r:I,3Q:{},8D:0,3P:{},ed:u(C){if(k.11.F==S){E}D i;k.1x.3Q={};D bJ=I;24(i in k.1x.3P){if(k.1x.3P[i]!=S){D 1j=k.1x.3P[i].K(0);if(k(k.11.F).is(\'.\'+1j.1i.a)){if(1j.1i.m==I){1j.1i.p=k.23(k.1a.7G(1j),k.1a.74(1j));1j.1i.m=1b}if(1j.1i.ac){k.1x.3P[i].2R(1j.1i.ac)}k.1x.3Q[i]=k.1x.3P[i];if(k.1t&&1j.1i.s&&k.11.F.A.44){1j.1i.el=k(\'.\'+1j.1i.a,1j);C.14.19=\'1o\';k.1t.cT(1j);1j.1i.ay=k.1t.8x(k.1p(1j,\'id\')).7l;C.14.19=C.A.7V;bJ=1b}if(1j.1i.9i){1j.1i.9i.1D(k.1x.3P[i].K(0),[k.11.F])}}}}if(bJ){k.1t.26()}},dS:u(){k.1x.3Q={};24(i in k.1x.3P){if(k.1x.3P[i]!=S){D 1j=k.1x.3P[i].K(0);if(k(k.11.F).is(\'.\'+1j.1i.a)){1j.1i.p=k.23(k.1a.7G(1j),k.1a.74(1j));if(1j.1i.ac){k.1x.3P[i].2R(1j.1i.ac)}k.1x.3Q[i]=k.1x.3P[i];if(k.1t&&1j.1i.s&&k.11.F.A.44){1j.1i.el=k(\'.\'+1j.1i.a,1j);C.14.19=\'1o\';k.1t.cT(1j);C.14.19=C.A.7V}}}}},al:u(e){if(k.11.F==S){E}k.1x.5r=I;D i;D bK=I;D eQ=0;24(i in k.1x.3Q){D 1j=k.1x.3Q[i].K(0);if(k.1x.5r==I&&k.1x[1j.1i.t](1j.1i.p.x,1j.1i.p.y,1j.1i.p.1C,1j.1i.p.hb)){if(1j.1i.hc&&1j.1i.h==I){k.1x.3Q[i].2R(1j.1i.hc)}if(1j.1i.h==I&&1j.1i.7x){bK=1b}1j.1i.h=1b;k.1x.5r=1j;if(k.1t&&1j.1i.s&&k.11.F.A.44){k.1t.1c.K(0).3l=1j.1i.eV;k.1t.al(1j)}eQ++}P if(1j.1i.h==1b){if(1j.1i.7y){1j.1i.7y.1D(1j,[e,k.11.1c.K(0).7c,1j.1i.fx])}if(1j.1i.hc){k.1x.3Q[i].4i(1j.1i.hc)}1j.1i.h=I}}if(k.1t&&!k.1x.5r&&k.11.F.44){k.1t.1c.K(0).14.19=\'1o\'}if(bK){k.1x.5r.1i.7x.1D(k.1x.5r,[e,k.11.1c.K(0).7c])}},eO:u(e){D i;24(i in k.1x.3Q){D 1j=k.1x.3Q[i].K(0);if(1j.1i.ac){k.1x.3Q[i].4i(1j.1i.ac)}if(1j.1i.hc){k.1x.3Q[i].4i(1j.1i.hc)}if(1j.1i.s){k.1t.7s[k.1t.7s.1g]=i}if(1j.1i.9l&&1j.1i.h==1b){1j.1i.h=I;1j.1i.9l.1D(1j,[e,1j.1i.fx])}1j.1i.m=I;1j.1i.h=I}k.1x.3Q={}},4U:u(){E q.1E(u(){if(q.9j){if(q.1i.s){id=k.1p(q,\'id\');k.1t.5L[id]=S;k(\'.\'+q.1i.a,q).aS()}k.1x.3P[\'d\'+q.c2]=S;q.9j=I;q.f=S}})},2r:u(o){E q.1E(u(){if(q.9j==1b||!o.3C||!k.1a||!k.11){E}q.1i={a:o.3C,ac:o.9J||I,hc:o.a5||I,eV:o.58||I,9l:o.gq||o.9l||I,7x:o.7x||o.dC||I,7y:o.7y||o.fO||I,9i:o.9i||I,t:o.6I&&(o.6I==\'du\'||o.6I==\'cV\')?o.6I:\'1s\',fx:o.fx?o.fx:I,m:I,h:I};if(o.cQ==1b&&k.1t){id=k.1p(q,\'id\');k.1t.5L[id]=q.1i.a;q.1i.s=1b;if(o.2Z){q.1i.2Z=o.2Z;q.1i.ay=k.1t.8x(id).7l}}q.9j=1b;q.c2=T(18.6o()*c9);k.1x.3P[\'d\'+q.c2]=k(q);k.1x.8D++})}};k.fn.23({dR:k.1x.4U,do:k.1x.2r});k.gD=k.1x.dS;k.3B={1c:S,8L:u(){3g=q.2y;if(!3g)E;14={dz:k(q).B(\'dz\')||\'\',4A:k(q).B(\'4A\')||\'\',8Z:k(q).B(\'8Z\')||\'\',dP:k(q).B(\'dP\')||\'\',dT:k(q).B(\'dT\')||\'\',dU:k(q).B(\'dU\')||\'\',c3:k(q).B(\'c3\')||\'\',dY:k(q).B(\'dY\')||\'\'};k.3B.1c.B(14);3x=k.3B.dX(3g);3x=3x.4E(12 bb("\\\\n","g"),"<br />");k.3B.1c.3x(\'gL\');ci=k.3B.1c.K(0).4c;k.3B.1c.3x(3x);Z=k.3B.1c.K(0).4c+ci;if(q.6l.2M&&Z>q.6l.2M[0]){Z=q.6l.2M[0]}q.14.Z=Z+\'U\';if(q.4Y==\'cf\'){W=k.3B.1c.K(0).5W+ci;if(q.6l.2M&&W>q.6l.2M[1]){W=q.6l.2M[1]}q.14.W=W+\'U\'}},dX:u(3g){cg={\'&\':\'&gK;\',\'<\':\'&gJ;\',\'>\':\'&gt;\',\'"\':\'&gs;\'};24(i in cg){3g=3g.4E(12 bb(i,\'g\'),cg[i])}E 3g},2r:u(2M){if(k.3B.1c==S){k(\'2e\',1h).1S(\'<22 id="dE" 14="Y: 1P; Q: 0; O: 0; 3n: 2K;"></22>\');k.3B.1c=k(\'#dE\')}E q.1E(u(){if(/cf|ch/.48(q.4Y)){if(q.4Y==\'ch\'){dB=q.5C(\'1u\');if(!/3g|gr/.48(dB)){E}}if(2M&&(2M.1K==bn||(2M.1K==7F&&2M.1g==2))){if(2M.1K==bn)2M=[2M,2M];P{2M[0]=T(2M[0])||8J;2M[1]=T(2M[1])||8J}q.6l={2M:2M}}k(q).5B(k.3B.8L).6y(k.3B.8L).dH(k.3B.8L);k.3B.8L.1D(q)}})}};k.fn.kc=k.3B.2r;k.4K=u(e){if(/^kd$|^ke$|^ka$|^6L$|^k9$|^k5$|^k4$|^k6$|^k7$|^2e$|^k8$|^kf$|^kg$|^kn$|^ko$|^kp$|^kq$/i.48(e.9N))E I;P E 1b};k.fx.a0=u(e,65){D c=e.7c;D cs=c.14;cs.Y=65.Y;cs.5K=65.3G.t;cs.5j=65.3G.l;cs.5k=65.3G.b;cs.5z=65.3G.r;cs.Q=65.Q+\'U\';cs.O=65.O+\'U\';e.31.ew(c,e);e.31.km(e)};k.fx.9P=u(e){if(!k.4K(e))E I;D t=k(e);D es=e.14;D 73=I;if(t.B(\'19\')==\'1o\'){5Y=t.B(\'3n\');t.B(\'3n\',\'2K\').1Y();73=1b}D V={};V.Y=t.B(\'Y\');V.1q=k.1a.2o(e);V.3G=k.1a.cy(e);D co=e.4Z?e.4Z.ei:t.B(\'hU\');V.Q=T(t.B(\'Q\'))||0;V.O=T(t.B(\'O\'))||0;D eo=\'kl\'+T(18.6o()*c9);D 6u=1h.3F(/^1T$|^br$|^kh$|^hr$|^8C$|^kj$|^8T$|^3A$|^kk$|^k3$|^k2$|^9h$|^dl$|^jM$/i.48(e.9N)?\'22\':e.9N);k.1p(6u,\'id\',eo);D jN=k(6u).2R(\'jO\');D 4h=6u.14;D Q=0;D O=0;if(V.Y==\'2s\'||V.Y==\'1P\'){Q=V.Q;O=V.O}4h.Q=Q+\'U\';4h.O=O+\'U\';4h.Y=V.Y!=\'2s\'&&V.Y!=\'1P\'?\'2s\':V.Y;4h.W=V.1q.hb+\'U\';4h.Z=V.1q.1C+\'U\';4h.5K=V.3G.t;4h.5z=V.3G.r;4h.5k=V.3G.b;4h.5j=V.3G.l;4h.2U=\'2K\';if(k.3a.4t){4h.ei=co}P{4h.jK=co}if(k.3a=="4t"){es.5E="8V(1G="+0.ex*2a+")"}es.1G=0.ex;e.31.ew(6u,e);6u.jF(e);es.5K=\'2P\';es.5z=\'2P\';es.5k=\'2P\';es.5j=\'2P\';es.Y=\'1P\';es.eu=\'1o\';es.Q=\'2P\';es.O=\'2P\';if(73){t.2G();es.3n=5Y}E{V:V,3p:k(6u)}};k.fx.8E={jE:[0,1V,1V],jG:[eD,1V,1V],jH:[e6,e6,jI],jP:[0,0,0],ks:[0,0,1V],jY:[dv,42,42],jZ:[0,1V,1V],k0:[0,0,7w],k1:[0,7w,7w],jX:[cn,cn,cn],jS:[0,2a,0],jR:[jT,jU,eb],jV:[7w,0,7w],kr:[85,eb,47],kP:[1V,eA,0],kN:[kO,50,kx],kF:[7w,0,0],kD:[ku,f8,kt],ky:[kH,0,9C],kL:[1V,0,1V],kM:[1V,kJ,0],kv:[0,6C,0],kA:[75,0,kE],kC:[eD,eB,eA],kG:[kI,kB,eB],kw:[e0,1V,1V],kz:[eL,kK,eL],kQ:[9C,9C,9C],jC:[1V,iy,iz],iA:[1V,1V,e0],iB:[0,1V,0],ix:[1V,0,1V],iv:[6C,0,0],iq:[0,0,6C],ip:[6C,6C,0],ir:[1V,dv,0],it:[1V,ah,iu],iC:[6C,0,6C],iD:[1V,0,0],iK:[ah,ah,ah],iL:[1V,1V,1V],iM:[1V,1V,0]};k.fx.6D=u(4x,dm){if(k.fx.8E[4x])E{r:k.fx.8E[4x][0],g:k.fx.8E[4x][1],b:k.fx.8E[4x][2]};P if(2W=/^6Y\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)$/.a4(4x))E{r:T(2W[1]),g:T(2W[2]),b:T(2W[3])};P if(2W=/6Y\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)$/.a4(4x))E{r:2m(2W[1])*2.55,g:2m(2W[2])*2.55,b:2m(2W[3])*2.55};P if(2W=/^#([a-fA-79-9])([a-fA-79-9])([a-fA-79-9])$/.a4(4x))E{r:T("77"+2W[1]+2W[1]),g:T("77"+2W[2]+2W[2]),b:T("77"+2W[3]+2W[3])};P if(2W=/^#([a-fA-79-9]{2})([a-fA-79-9]{2})([a-fA-79-9]{2})$/.a4(4x))E{r:T("77"+2W[1]),g:T("77"+2W[2]),b:T("77"+2W[3])};P E dm==1b?I:{r:1V,g:1V,b:1V}};k.fx.dD={5Q:1,5b:1,5O:1,4S:1,4D:1,4A:1,W:1,O:1,c3:1,iI:1,5k:1,5j:1,5z:1,5K:1,8b:1,6x:1,8c:1,av:1,1G:1,iE:1,iF:1,5n:1,4X:1,5U:1,5M:1,2L:1,jD:1,Q:1,Z:1,3I:1};k.fx.dA={7i:1,iG:1,iH:1,io:1,im:1,4x:1,i2:1};k.fx.8A=[\'i3\',\'i4\',\'i5\',\'i1\'];k.fx.cc={\'cd\':[\'2E\',\'dK\'],\'a8\':[\'2E\',\'bh\'],\'6w\':[\'6w\',\'\'],\'8F\':[\'8F\',\'\']};k.fn.23({5w:u(5X,H,G,J){E q.1w(u(){D a1=k.H(H,G,J);D e=12 k.dM(q,a1,5X)})},c4:u(H,J){E q.1w(u(){D a1=k.H(H,J);D e=12 k.c4(q,a1)})},8o:u(2D){E q.1E(u(){if(q.6d)k.by(q,2D)})},i0:u(2D){E q.1E(u(){if(q.6d)k.by(q,2D);if(q.1w&&q.1w[\'fx\'])q.1w.fx=[]})}});k.23({c4:u(2f,M){D z=q,3t;z.2D=u(){if(k.fQ(M.21))M.21.1D(2f)};z.2I=6V(u(){z.2D()},M.1m);2f.6d=z},G:{c8:u(p,n,1W,1H,1m){E((-18.5H(p*18.2Q)/2)+0.5)*1H+1W}},dM:u(2f,M,5X){D z=q,3t;D y=2f.14;D fR=k.B(2f,"2U");D 72=k.B(2f,"19");D 2j={};z.9O=(12 7g()).7z();M.G=M.G&&k.G[M.G]?M.G:\'c8\';z.ag=u(2w,43){if(k.fx.dD[2w]){if(43==\'1Y\'||43==\'2G\'||43==\'3R\'){if(!2f.6v)2f.6v={};D r=2m(k.6E(2f,2w));2f.6v[2w]=r&&r>-c9?r:(2m(k.B(2f,2w))||0);43=43==\'3R\'?(72==\'1o\'?\'1Y\':\'2G\'):43;M[43]=1b;2j[2w]=43==\'1Y\'?[0,2f.6v[2w]]:[2f.6v[2w],0];if(2w!=\'1G\')y[2w]=2j[2w][0]+(2w!=\'3I\'&&2w!=\'8Z\'?\'U\':\'\');P k.1p(y,"1G",2j[2w][0])}P{2j[2w]=[2m(k.6E(2f,2w)),2m(43)||0]}}P if(k.fx.dA[2w])2j[2w]=[k.fx.6D(k.6E(2f,2w)),k.fx.6D(43)];P if(/^6w$|8F$|2E$|a8$|cd$/i.48(2w)){D m=43.4E(/\\s+/g,\' \').4E(/6Y\\s*\\(\\s*/g,\'6Y(\').4E(/\\s*,\\s*/g,\',\').4E(/\\s*\\)/g,\')\').d5(/([^\\s]+)/g);3m(2w){1e\'6w\':1e\'8F\':1e\'cd\':1e\'a8\':m[3]=m[3]||m[1]||m[0];m[2]=m[2]||m[0];m[1]=m[1]||m[0];24(D i=0;i<k.fx.8A.1g;i++){D 64=k.fx.cc[2w][0]+k.fx.8A[i]+k.fx.cc[2w][1];2j[64]=2w==\'a8\'?[k.fx.6D(k.6E(2f,64)),k.fx.6D(m[i])]:[2m(k.6E(2f,64)),2m(m[i])]}1r;1e\'2E\':24(D i=0;i<m.1g;i++){D bd=2m(m[i]);D a9=!hX(bd)?\'dK\':(!/cu|1o|2K|hY|hZ|i6|i7|ii|ij|ik|il/i.48(m[i])?\'bh\':I);if(a9){24(D j=0;j<k.fx.8A.1g;j++){64=\'2E\'+k.fx.8A[j]+a9;2j[64]=a9==\'bh\'?[k.fx.6D(k.6E(2f,64)),k.fx.6D(m[i])]:[2m(k.6E(2f,64)),bd]}}P{y[\'ie\']=m[i]}}1r}}P{y[2w]=43}E I};24(p in 5X){if(p==\'14\'){D 5f=k.bl(5X[p]);24(7A in 5f){q.ag(7A,5f[7A])}}P if(p==\'3l\'){if(1h.af)24(D i=0;i<1h.af.1g;i++){D 7e=1h.af[i].7e||1h.af[i].i9||S;if(7e){24(D j=0;j<7e.1g;j++){if(7e[j].i8==\'.\'+5X[p]){D 6X=12 bb(\'\\.\'+5X[p]+\' {\');D 5Z=7e[j].14.9X;D 5f=k.bl(5Z.4E(6X,\'\').4E(/}/g,\'\'));24(7A in 5f){q.ag(7A,5f[7A])}}}}}}P{q.ag(p,5X[p])}}y.19=72==\'1o\'?\'2B\':72;y.2U=\'2K\';z.2D=u(){D t=(12 7g()).7z();if(t>M.1m+z.9O){5T(z.2I);z.2I=S;24(p in 2j){if(p=="1G")k.1p(y,"1G",2j[p][1]);P if(2g 2j[p][1]==\'8T\')y[p]=\'6Y(\'+2j[p][1].r+\',\'+2j[p][1].g+\',\'+2j[p][1].b+\')\';P y[p]=2j[p][1]+(p!=\'3I\'&&p!=\'8Z\'?\'U\':\'\')}if(M.2G||M.1Y)24(D p in 2f.6v)if(p=="1G")k.1p(y,p,2f.6v[p]);P y[p]="";y.19=M.2G?\'1o\':(72!=\'1o\'?72:\'2B\');y.2U=fR;2f.6d=S;if(k.fQ(M.21))M.21.1D(2f)}P{D n=t-q.9O;D 8w=n/M.1m;24(p in 2j){if(2g 2j[p][1]==\'8T\'){y[p]=\'6Y(\'+T(k.G[M.G](8w,n,2j[p][0].r,(2j[p][1].r-2j[p][0].r),M.1m))+\',\'+T(k.G[M.G](8w,n,2j[p][0].g,(2j[p][1].g-2j[p][0].g),M.1m))+\',\'+T(k.G[M.G](8w,n,2j[p][0].b,(2j[p][1].b-2j[p][0].b),M.1m))+\')\'}P{D bz=k.G[M.G](8w,n,2j[p][0],(2j[p][1]-2j[p][0]),M.1m);if(p=="1G")k.1p(y,"1G",bz);P y[p]=bz+(p!=\'3I\'&&p!=\'8Z\'?\'U\':\'\')}}}};z.2I=6V(u(){z.2D()},13);2f.6d=z},by:u(2f,2D){if(2D)2f.6d.9O-=iO;P{1X.5T(2f.6d.2I);2f.6d=S;k.2H(2f,"fx")}}});k.bl=u(5Z){D 5f={};if(2g 5Z==\'4V\'){5Z=5Z.6c().7C(\';\');24(D i=0;i<5Z.1g;i++){6X=5Z[i].7C(\':\');if(6X.1g==2){5f[k.g6(6X[0].4E(/\\-(\\w)/g,u(m,c){E c.jo()}))]=k.g6(6X[1])}}}E 5f};k.fn.23({g3:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'4F\',G)})},gb:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'4r\',G)})},jl:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'fJ\',G)})},jk:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'O\',G)})},jg:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'2L\',G)})},jf:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.61(q,H,J,\'fh\',G)})}});k.fx.61=u(e,H,J,2S,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;z.el=k(e);z.1N=k.1a.2o(e);z.G=2g J==\'4V\'?J:G||S;if(!e.4s)e.4s=z.el.B(\'19\');if(2S==\'fJ\'){2S=z.el.B(\'19\')==\'1o\'?\'4r\':\'4F\'}P if(2S==\'fh\'){2S=z.el.B(\'19\')==\'1o\'?\'2L\':\'O\'}z.el.1Y();z.H=H;z.J=2g J==\'u\'?J:S;z.fx=k.fx.9P(e);z.2S=2S;z.21=u(){if(z.J&&z.J.1K==2A){z.J.1D(z.el.K(0))}if(z.2S==\'4r\'||z.2S==\'2L\'){z.el.B(\'19\',z.el.K(0).4s==\'1o\'?\'2B\':z.el.K(0).4s)}P{z.el.2G()}k.fx.a0(z.fx.3p.K(0),z.fx.V);k.2H(z.el.K(0),\'1n\')};3m(z.2S){1e\'4F\':63=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'W\');63.1L(z.fx.V.1q.hb,0);1r;1e\'4r\':z.fx.3p.B(\'W\',\'9R\');z.el.1Y();63=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'W\');63.1L(0,z.fx.V.1q.hb);1r;1e\'O\':63=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'Z\');63.1L(z.fx.V.1q.1C,0);1r;1e\'2L\':z.fx.3p.B(\'Z\',\'9R\');z.el.1Y();63=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'Z\');63.1L(0,z.fx.V.1q.1C);1r}};k.fn.ji=u(5D,J){E q.1w(\'1n\',u(){if(!k.4K(q)){k.2H(q,\'1n\');E I}D e=12 k.fx.f4(q,5D,J);e.bp()})};k.fx.f4=u(e,5D,J){D z=q;z.el=k(e);z.el.1Y();z.J=J;z.5D=T(5D)||40;z.V={};z.V.Y=z.el.B(\'Y\');z.V.Q=T(z.el.B(\'Q\'))||0;z.V.O=T(z.el.B(\'O\'))||0;if(z.V.Y!=\'2s\'&&z.V.Y!=\'1P\'){z.el.B(\'Y\',\'2s\')}z.3V=5;z.5y=1;z.bp=u(){z.5y++;z.e=12 k.fx(z.el.K(0),{1m:jj,21:u(){z.e=12 k.fx(z.el.K(0),{1m:80,21:u(){z.5D=T(z.5D/2);if(z.5y<=z.3V)z.bp();P{z.el.B(\'Y\',z.V.Y).B(\'Q\',z.V.Q+\'U\').B(\'O\',z.V.O+\'U\');k.2H(z.el.K(0),\'1n\');if(z.J&&z.J.1K==2A){z.J.1D(z.el.K(0))}}}},\'Q\');z.e.1L(z.V.Q-z.5D,z.V.Q)}},\'Q\');z.e.1L(z.V.Q,z.V.Q-z.5D)}};k.fn.23({jy:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4r\',\'4l\',G)})},jz:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4r\',\'in\',G)})},jA:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4r\',\'3R\',G)})},jB:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4F\',\'4l\',G)})},jx:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4F\',\'in\',G)})},jw:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'4F\',\'3R\',G)})},js:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'O\',\'4l\',G)})},jt:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'O\',\'in\',G)})},ju:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'O\',\'3R\',G)})},jv:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'2L\',\'4l\',G)})},je:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'2L\',\'in\',G)})},jd:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.4f(q,H,J,\'2L\',\'3R\',G)})}});k.fx.4f=u(e,H,J,2S,1u,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;z.el=k(e);z.G=2g J==\'4V\'?J:G||S;z.V={};z.V.Y=z.el.B(\'Y\');z.V.Q=z.el.B(\'Q\');z.V.O=z.el.B(\'O\');if(!e.4s)e.4s=z.el.B(\'19\');if(1u==\'3R\'){1u=z.el.B(\'19\')==\'1o\'?\'in\':\'4l\'}z.el.1Y();if(z.V.Y!=\'2s\'&&z.V.Y!=\'1P\'){z.el.B(\'Y\',\'2s\')}z.1u=1u;J=2g J==\'u\'?J:S;8H=1;3m(2S){1e\'4F\':z.e=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'Q\');z.62=2m(z.V.Q)||0;z.9K=z.fG;8H=-1;1r;1e\'4r\':z.e=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'Q\');z.62=2m(z.V.Q)||0;z.9K=z.fG;1r;1e\'2L\':z.e=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'O\');z.62=2m(z.V.O)||0;z.9K=z.fy;1r;1e\'O\':z.e=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'O\');z.62=2m(z.V.O)||0;z.9K=z.fy;8H=-1;1r}z.e2=12 k.fx(z.el.K(0),k.H(H,z.G,u(){z.el.B(z.V);if(z.1u==\'4l\'){z.el.B(\'19\',\'1o\')}P z.el.B(\'19\',z.el.K(0).4s==\'1o\'?\'2B\':z.el.K(0).4s);k.2H(z.el.K(0),\'1n\')}),\'1G\');if(1u==\'in\'){z.e.1L(z.62+2a*8H,z.62);z.e2.1L(0,1)}P{z.e.1L(z.62,z.62+2a*8H);z.e2.1L(1,0)}};k.fn.23({j0:u(H,W,J,G){E q.1w(\'1n\',u(){12 k.fx.9L(q,H,W,J,\'fp\',G)})},iW:u(H,W,J,G){E q.1w(\'1n\',u(){12 k.fx.9L(q,H,W,J,\'9M\',G)})},iV:u(H,W,J,G){E q.1w(\'1n\',u(){12 k.fx.9L(q,H,W,J,\'3R\',G)})}});k.fx.9L=u(e,H,W,J,1u,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;z.el=k(e);z.G=2g J==\'4V\'?J:G||S;z.J=2g J==\'u\'?J:S;if(1u==\'3R\'){1u=z.el.B(\'19\')==\'1o\'?\'9M\':\'fp\'}z.H=H;z.W=W&&W.1K==bn?W:20;z.fx=k.fx.9P(e);z.1u=1u;z.21=u(){if(z.J&&z.J.1K==2A){z.J.1D(z.el.K(0))}if(z.1u==\'9M\'){z.el.1Y()}P{z.el.2G()}k.fx.a0(z.fx.3p.K(0),z.fx.V);k.2H(z.el.K(0),\'1n\')};if(z.1u==\'9M\'){z.el.1Y();z.fx.3p.B(\'W\',z.W+\'U\').B(\'Z\',\'9R\');z.ef=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,u(){z.ef=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'W\');z.ef.1L(z.W,z.fx.V.1q.hb)}),\'Z\');z.ef.1L(0,z.fx.V.1q.1C)}P{z.ef=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,u(){z.ef=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G,z.21),\'Z\');z.ef.1L(z.fx.V.1q.1C,0)}),\'W\');z.ef.1L(z.fx.V.1q.hb,z.W)}};k.fn.iR=u(H,4x,J,G){E q.1w(\'fv\',u(){q.6W=k(q).1p("14")||\'\';G=2g J==\'4V\'?J:G||S;J=2g J==\'u\'?J:S;D 9S=k(q).B(\'7i\');D 8I=q.31;7d(9S==\'cu\'&&8I){9S=k(8I).B(\'7i\');8I=8I.31}k(q).B(\'7i\',4x);if(2g q.6W==\'8T\')q.6W=q.6W["9X"];k(q).5w({\'7i\':9S},H,G,u(){k.2H(q,\'fv\');if(2g k(q).1p("14")==\'8T\'){k(q).1p("14")["9X"]="";k(q).1p("14")["9X"]=q.6W}P{k(q).1p("14",q.6W)}if(J)J.1D(q)})})};k.fn.23({iT:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.5m(q,H,J,\'49\',\'6g\',G)})},iU:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.5m(q,H,J,\'4j\',\'6g\',G)})},j1:u(H,J,G){E q.1w(\'1n\',u(){if(k.B(q,\'19\')==\'1o\'){12 k.fx.5m(q,H,J,\'4j\',\'6Z\',G)}P{12 k.fx.5m(q,H,J,\'4j\',\'6g\',G)}})},j2:u(H,J,G){E q.1w(\'1n\',u(){if(k.B(q,\'19\')==\'1o\'){12 k.fx.5m(q,H,J,\'49\',\'6Z\',G)}P{12 k.fx.5m(q,H,J,\'49\',\'6g\',G)}})},j9:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.5m(q,H,J,\'49\',\'6Z\',G)})},ja:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.5m(q,H,J,\'4j\',\'6Z\',G)})}});k.fx.5m=u(e,H,J,2S,1u,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;D 73=I;z.el=k(e);z.G=2g J==\'4V\'?J:G||S;z.J=2g J==\'u\'?J:S;z.1u=1u;z.H=H;z.2i=k.1a.2o(e);z.V={};z.V.Y=z.el.B(\'Y\');z.V.19=z.el.B(\'19\');if(z.V.19==\'1o\'){5Y=z.el.B(\'3n\');z.el.1Y();73=1b}z.V.Q=z.el.B(\'Q\');z.V.O=z.el.B(\'O\');if(73){z.el.2G();z.el.B(\'3n\',5Y)}z.V.Z=z.2i.w+\'U\';z.V.W=z.2i.h+\'U\';z.V.2U=z.el.B(\'2U\');z.2i.Q=T(z.V.Q)||0;z.2i.O=T(z.V.O)||0;if(z.V.Y!=\'2s\'&&z.V.Y!=\'1P\'){z.el.B(\'Y\',\'2s\')}z.el.B(\'2U\',\'2K\').B(\'W\',1u==\'6Z\'&&2S==\'49\'?1:z.2i.h+\'U\').B(\'Z\',1u==\'6Z\'&&2S==\'4j\'?1:z.2i.w+\'U\');z.21=u(){z.el.B(z.V);if(z.1u==\'6g\')z.el.2G();P z.el.1Y();k.2H(z.el.K(0),\'1n\')};3m(2S){1e\'49\':z.eh=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'W\');z.et=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'Q\');if(z.1u==\'6g\'){z.eh.1L(z.2i.h,0);z.et.1L(z.2i.Q,z.2i.Q+z.2i.h/2)}P{z.eh.1L(0,z.2i.h);z.et.1L(z.2i.Q+z.2i.h/2,z.2i.Q)}1r;1e\'4j\':z.eh=12 k.fx(z.el.K(0),k.H(H-15,z.G,J),\'Z\');z.et=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'O\');if(z.1u==\'6g\'){z.eh.1L(z.2i.w,0);z.et.1L(z.2i.O,z.2i.O+z.2i.w/2)}P{z.eh.1L(0,z.2i.w);z.et.1L(z.2i.O+z.2i.w/2,z.2i.O)}1r}};k.fn.bg=u(H,3V,J){E q.1w(\'1n\',u(){if(!k.4K(q)){k.2H(q,\'1n\');E I}D fx=12 k.fx.bg(q,H,3V,J);fx.bf()})};k.fx.bg=u(el,H,3V,J){D z=q;z.3V=3V;z.5y=1;z.el=el;z.H=H;z.J=J;k(z.el).1Y();z.bf=u(){z.5y++;z.e=12 k.fx(z.el,k.H(z.H,u(){z.ef=12 k.fx(z.el,k.H(z.H,u(){if(z.5y<=z.3V)z.bf();P{k.2H(z.el,\'1n\');if(z.J&&z.J.1K==2A){z.J.1D(z.el)}}}),\'1G\');z.ef.1L(0,1)}),\'1G\');z.e.1L(1,0)}};k.fn.23({jb:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.6G(q,H,1,2a,1b,J,\'fa\',G)})},jc:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.6G(q,H,2a,1,1b,J,\'b4\',G)})},j8:u(H,J,G){E q.1w(\'1n\',u(){D G=G||\'fl\';12 k.fx.6G(q,H,2a,f8,1b,J,\'6h\',G)})},6G:u(H,57,30,6H,J,G){E q.1w(\'1n\',u(){12 k.fx.6G(q,H,57,30,6H,J,\'6G\',G)})}});k.fx.6G=u(e,H,57,30,6H,J,1u,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;z.el=k(e);z.57=T(57)||2a;z.30=T(30)||2a;z.G=2g J==\'4V\'?J:G||S;z.J=2g J==\'u\'?J:S;z.1m=k.H(H).1m;z.6H=6H||S;z.2i=k.1a.2o(e);z.V={Z:z.el.B(\'Z\'),W:z.el.B(\'W\'),4A:z.el.B(\'4A\')||\'2a%\',Y:z.el.B(\'Y\'),19:z.el.B(\'19\'),Q:z.el.B(\'Q\'),O:z.el.B(\'O\'),2U:z.el.B(\'2U\'),4S:z.el.B(\'4S\'),5O:z.el.B(\'5O\'),5Q:z.el.B(\'5Q\'),5b:z.el.B(\'5b\'),5M:z.el.B(\'5M\'),5U:z.el.B(\'5U\'),5n:z.el.B(\'5n\'),4X:z.el.B(\'4X\')};z.Z=T(z.V.Z)||e.4c||0;z.W=T(z.V.W)||e.5W||0;z.Q=T(z.V.Q)||0;z.O=T(z.V.O)||0;1q=[\'em\',\'U\',\'j7\',\'%\'];24(i in 1q){if(z.V.4A.3J(1q[i])>0){z.fg=1q[i];z.4A=2m(z.V.4A)}if(z.V.4S.3J(1q[i])>0){z.fc=1q[i];z.bw=2m(z.V.4S)||0}if(z.V.5O.3J(1q[i])>0){z.fe=1q[i];z.bc=2m(z.V.5O)||0}if(z.V.5Q.3J(1q[i])>0){z.fL=1q[i];z.bA=2m(z.V.5Q)||0}if(z.V.5b.3J(1q[i])>0){z.g8=1q[i];z.bt=2m(z.V.5b)||0}if(z.V.5M.3J(1q[i])>0){z.g4=1q[i];z.bx=2m(z.V.5M)||0}if(z.V.5U.3J(1q[i])>0){z.g9=1q[i];z.bv=2m(z.V.5U)||0}if(z.V.5n.3J(1q[i])>0){z.gc=1q[i];z.bj=2m(z.V.5n)||0}if(z.V.4X.3J(1q[i])>0){z.fK=1q[i];z.b7=2m(z.V.4X)||0}}if(z.V.Y!=\'2s\'&&z.V.Y!=\'1P\'){z.el.B(\'Y\',\'2s\')}z.el.B(\'2U\',\'2K\');z.1u=1u;3m(z.1u){1e\'fa\':z.4b=z.Q+z.2i.h/2;z.5a=z.Q;z.4k=z.O+z.2i.w/2;z.59=z.O;1r;1e\'b4\':z.5a=z.Q+z.2i.h/2;z.4b=z.Q;z.59=z.O+z.2i.w/2;z.4k=z.O;1r;1e\'6h\':z.5a=z.Q-z.2i.h/4;z.4b=z.Q;z.59=z.O-z.2i.w/4;z.4k=z.O;1r}z.be=I;z.t=(12 7g).7z();z.4w=u(){5T(z.2I);z.2I=S};z.2D=u(){if(z.be==I){z.el.1Y();z.be=1b}D t=(12 7g).7z();D n=t-z.t;D p=n/z.1m;if(t>=z.1m+z.t){9T(u(){o=1;if(z.1u){t=z.5a;l=z.59;if(z.1u==\'6h\')o=0}z.bs(z.30,l,t,1b,o)},13);z.4w()}P{o=1;if(!k.G||!k.G[z.G]){s=((-18.5H(p*18.2Q)/2)+0.5)*(z.30-z.57)+z.57}P{s=k.G[z.G](p,n,z.57,(z.30-z.57),z.1m)}if(z.1u){if(!k.G||!k.G[z.G]){t=((-18.5H(p*18.2Q)/2)+0.5)*(z.5a-z.4b)+z.4b;l=((-18.5H(p*18.2Q)/2)+0.5)*(z.59-z.4k)+z.4k;if(z.1u==\'6h\')o=((-18.5H(p*18.2Q)/2)+0.5)*(-0.9Y)+0.9Y}P{t=k.G[z.G](p,n,z.4b,(z.5a-z.4b),z.1m);l=k.G[z.G](p,n,z.4k,(z.59-z.4k),z.1m);if(z.1u==\'6h\')o=k.G[z.G](p,n,0.9Y,-0.9Y,z.1m)}}z.bs(s,l,t,I,o)}};z.2I=6V(u(){z.2D()},13);z.bs=u(4q,O,Q,fM,1G){z.el.B(\'W\',z.W*4q/2a+\'U\').B(\'Z\',z.Z*4q/2a+\'U\').B(\'O\',O+\'U\').B(\'Q\',Q+\'U\').B(\'4A\',z.4A*4q/2a+z.fg);if(z.bw)z.el.B(\'4S\',z.bw*4q/2a+z.fc);if(z.bc)z.el.B(\'5O\',z.bc*4q/2a+z.fe);if(z.bA)z.el.B(\'5Q\',z.bA*4q/2a+z.fL);if(z.bt)z.el.B(\'5b\',z.bt*4q/2a+z.g8);if(z.bx)z.el.B(\'5M\',z.bx*4q/2a+z.g4);if(z.bv)z.el.B(\'5U\',z.bv*4q/2a+z.g9);if(z.bj)z.el.B(\'5n\',z.bj*4q/2a+z.gc);if(z.b7)z.el.B(\'4X\',z.b7*4q/2a+z.fK);if(z.1u==\'6h\'){if(1X.71)z.el.K(0).14.5E="8V(1G="+1G*2a+")";z.el.K(0).14.1G=1G}if(fM){if(z.6H){z.el.B(z.V)}if(z.1u==\'b4\'||z.1u==\'6h\'){z.el.B(\'19\',\'1o\');if(z.1u==\'6h\'){if(1X.71)z.el.K(0).14.5E="8V(1G="+2a+")";z.el.K(0).14.1G=1}}P z.el.B(\'19\',\'2B\');if(z.J)z.J.1D(z.el.K(0));k.2H(z.el.K(0),\'1n\')}}};k.fn.23({9U:u(H,1O,G){o=k.H(H);E q.1w(\'1n\',u(){12 k.fx.9U(q,o,1O,G)})},j6:u(H,1O,G){E q.1E(u(){k(\'a[@3h*="#"]\',q).5h(u(e){fW=q.3h.7C(\'#\');k(\'#\'+fW[1]).9U(H,1O,G);E I})})}});k.fx.9U=u(e,o,1O,G){D z=q;z.o=o;z.e=e;z.1O=/fT|gd/.48(1O)?1O:I;z.G=G;p=k.1a.3w(e);s=k.1a.6z();z.4w=u(){5T(z.2I);z.2I=S;k.2H(z.e,\'1n\')};z.t=(12 7g).7z();s.h=s.h>s.ih?(s.h-s.ih):s.h;s.w=s.w>s.iw?(s.w-s.iw):s.w;z.5a=p.y>s.h?s.h:p.y;z.59=p.x>s.w?s.w:p.x;z.4b=s.t;z.4k=s.l;z.2D=u(){D t=(12 7g).7z();D n=t-z.t;D p=n/z.o.1m;if(t>=z.o.1m+z.t){z.4w();9T(u(){z.d3(z.5a,z.59)},13)}P{if(!z.1O||z.1O==\'fT\'){if(!k.G||!k.G[z.G]){9V=((-18.5H(p*18.2Q)/2)+0.5)*(z.5a-z.4b)+z.4b}P{9V=k.G[z.G](p,n,z.4b,(z.5a-z.4b),z.o.1m)}}P{9V=z.4b}if(!z.1O||z.1O==\'gd\'){if(!k.G||!k.G[z.G]){9W=((-18.5H(p*18.2Q)/2)+0.5)*(z.59-z.4k)+z.4k}P{9W=k.G[z.G](p,n,z.4k,(z.59-z.4k),z.o.1m)}}P{9W=z.4k}z.d3(9V,9W)}};z.d3=u(t,l){1X.j4(l,t)};z.2I=6V(u(){z.2D()},13)};k.fn.cY=u(3V,J){E q.1w(\'1n\',u(){if(!k.4K(q)){k.2H(q,\'1n\');E I}D e=12 k.fx.cY(q,3V,J);e.cG()})};k.fx.cY=u(e,3V,J){D z=q;z.el=k(e);z.el.1Y();z.3V=T(3V)||3;z.J=J;z.5y=1;z.V={};z.V.Y=z.el.B(\'Y\');z.V.Q=T(z.el.B(\'Q\'))||0;z.V.O=T(z.el.B(\'O\'))||0;if(z.V.Y!=\'2s\'&&z.V.Y!=\'1P\'){z.el.B(\'Y\',\'2s\')}z.cG=u(){z.5y++;z.e=12 k.fx(z.el.K(0),{1m:60,21:u(){z.e=12 k.fx(z.el.K(0),{1m:60,21:u(){z.e=12 k.fx(e,{1m:60,21:u(){if(z.5y<=z.3V)z.cG();P{z.el.B(\'Y\',z.V.Y).B(\'Q\',z.V.Q+\'U\').B(\'O\',z.V.O+\'U\');k.2H(z.el.K(0),\'1n\');if(z.J&&z.J.1K==2A){z.J.1D(z.el.K(0))}}}},\'O\');z.e.1L(z.V.O-20,z.V.O)}},\'O\');z.e.1L(z.V.O+20,z.V.O-20)}},\'O\');z.e.1L(z.V.O,z.V.O+20)}};k.fn.23({fo:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4F\',\'in\',G)})},fq:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4F\',\'4l\',G)})},iY:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4F\',\'3R\',G)})},iX:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4r\',\'in\',G)})},jr:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4r\',\'4l\',G)})},jq:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'4r\',\'3R\',G)})},jp:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'O\',\'in\',G)})},jn:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'O\',\'4l\',G)})},jm:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'O\',\'3R\',G)})},iP:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'2L\',\'in\',G)})},ic:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'2L\',\'4l\',G)})},ib:u(H,J,G){E q.1w(\'1n\',u(){12 k.fx.1z(q,H,J,\'2L\',\'3R\',G)})}});k.fx.1z=u(e,H,J,2S,1u,G){if(!k.4K(e)){k.2H(e,\'1n\');E I}D z=q;z.el=k(e);z.G=2g J==\'4V\'?J:G||S;z.J=2g J==\'u\'?J:S;if(1u==\'3R\'){1u=z.el.B(\'19\')==\'1o\'?\'in\':\'4l\'}if(!e.4s)e.4s=z.el.B(\'19\');z.el.1Y();z.H=H;z.fx=k.fx.9P(e);z.1u=1u;z.2S=2S;z.21=u(){if(z.1u==\'4l\')z.el.B(\'3n\',\'2K\');k.fx.a0(z.fx.3p.K(0),z.fx.V);if(z.1u==\'in\'){z.el.B(\'19\',z.el.K(0).4s==\'1o\'?\'2B\':z.el.K(0).4s)}P{z.el.B(\'19\',\'1o\');z.el.B(\'3n\',\'dd\')}if(z.J&&z.J.1K==2A){z.J.1D(z.el.K(0))}k.2H(z.el.K(0),\'1n\')};3m(z.2S){1e\'4F\':z.ef=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'Q\');z.7v=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G),\'W\');if(z.1u==\'in\'){z.ef.1L(-z.fx.V.1q.hb,0);z.7v.1L(0,z.fx.V.1q.hb)}P{z.ef.1L(0,-z.fx.V.1q.hb);z.7v.1L(z.fx.V.1q.hb,0)}1r;1e\'4r\':z.ef=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'Q\');if(z.1u==\'in\'){z.ef.1L(z.fx.V.1q.hb,0)}P{z.ef.1L(0,z.fx.V.1q.hb)}1r;1e\'O\':z.ef=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'O\');z.7v=12 k.fx(z.fx.3p.K(0),k.H(z.H,z.G),\'Z\');if(z.1u==\'in\'){z.ef.1L(-z.fx.V.1q.1C,0);z.7v.1L(0,z.fx.V.1q.1C)}P{z.ef.1L(0,-z.fx.V.1q.1C);z.7v.1L(z.fx.V.1q.1C,0)}1r;1e\'2L\':z.ef=12 k.fx(z.el.K(0),k.H(z.H,z.G,z.21),\'O\');if(z.1u==\'in\'){z.ef.1L(z.fx.V.1q.1C,0)}P{z.ef.1L(0,z.fx.V.1q.1C)}1r}};k.3f=S;k.fn.ig=u(o){E q.1w(\'1n\',u(){12 k.fx.dG(q,o)})};k.fx.dG=u(e,o){if(k.3f==S){k(\'2e\',1h).1S(\'<22 id="3f"></22>\');k.3f=k(\'#3f\')}k.3f.B(\'19\',\'2B\').B(\'Y\',\'1P\');D z=q;z.el=k(e);if(!o||!o.30){E}if(o.30.1K==b0&&1h.9e(o.30)){o.30=1h.9e(o.30)}P if(!o.30.dq){E}if(!o.1m){o.1m=g5}z.1m=o.1m;z.30=o.30;z.8r=o.3l;z.21=o.21;if(z.8r){k.3f.2R(z.8r)}z.a3=0;z.a2=0;if(k.dF){z.a3=(T(k.3f.B(\'5b\'))||0)+(T(k.3f.B(\'5O\'))||0)+(T(k.3f.B(\'4X\'))||0)+(T(k.3f.B(\'5U\'))||0);z.a2=(T(k.3f.B(\'4S\'))||0)+(T(k.3f.B(\'5Q\'))||0)+(T(k.3f.B(\'5M\'))||0)+(T(k.3f.B(\'5n\'))||0)}z.26=k.23(k.1a.3w(z.el.K(0)),k.1a.2o(z.el.K(0)));z.2T=k.23(k.1a.3w(z.30),k.1a.2o(z.30));z.26.1C-=z.a3;z.26.hb-=z.a2;z.2T.1C-=z.a3;z.2T.hb-=z.a2;z.J=o.21;k.3f.B(\'Z\',z.26.1C+\'U\').B(\'W\',z.26.hb+\'U\').B(\'Q\',z.26.y+\'U\').B(\'O\',z.26.x+\'U\').5w({Q:z.2T.y,O:z.2T.x,Z:z.2T.1C,W:z.2T.hb},z.1m,u(){if(z.8r)k.3f.4i(z.8r);k.3f.B(\'19\',\'1o\');if(z.21&&z.21.1K==2A){z.21.1D(z.el.K(0),[z.30])}k.2H(z.el.K(0),\'1n\')})};k.1v={M:{2E:10,ec:\'1Q/iJ.eZ\',e3:\'<1T 2J="1Q/6g.da" />\',eW:0.8,d8:\'iN a6\',dc:\'57\',3W:8J},jQ:I,jW:I,6j:S,8m:I,8k:I,d1:u(2k){if(!k.1v.8k||k.1v.8m)E;D 3K=2k.7L||2k.7K||-1;3m(3K){1e 35:if(k.1v.6j)k.1v.26(S,k(\'a[@4I=\'+k.1v.6j+\']:jJ\').K(0));1r;1e 36:if(k.1v.6j)k.1v.26(S,k(\'a[@4I=\'+k.1v.6j+\']:jL\').K(0));1r;1e 37:1e 8:1e 33:1e 80:1e kb:D 9p=k(\'#87\');if(9p.K(0).53!=S){9p.K(0).53.1D(9p.K(0))}1r;1e 38:1r;1e 39:1e 34:1e 32:1e gl:1e 78:D 9k=k(\'#88\');if(9k.K(0).53!=S){9k.K(0).53.1D(9k.K(0))}1r;1e 40:1r;1e 27:k.1v.au();1r}},7q:u(M){if(M)k.23(k.1v.M,M);if(1X.2k){k(\'2e\',1h).1J(\'6y\',k.1v.d1)}P{k(1h).1J(\'6y\',k.1v.d1)}k(\'a\').1E(u(){el=k(q);en=el.1p(\'4I\')||\'\';e9=el.1p(\'3h\')||\'\';ev=/\\.da|\\.gw|\\.8X|\\.eZ|\\.gn/g;if(e9.6c().d5(ev)!=S&&en.6c().3J(\'eU\')==0){el.1J(\'5h\',k.1v.26)}});if(k.3a.4t){3A=1h.3F(\'3A\');k(3A).1p({id:\'cN\',2J:\'ek:I;\',ej:\'cD\',ep:\'cD\'}).B({19:\'1o\',Y:\'1P\',Q:\'0\',O:\'0\',5E:\'9n:9w.9y.cC(1G=0)\'});k(\'2e\').1S(3A)}8n=1h.3F(\'22\');k(8n).1p(\'id\',\'cP\').B({Y:\'1P\',19:\'1o\',Q:\'0\',O:\'0\',1G:0}).1S(1h.8M(\' \')).1J(\'5h\',k.1v.au);6A=1h.3F(\'22\');k(6A).1p(\'id\',\'eK\').B({4X:k.1v.M.2E+\'U\'}).1S(1h.8M(\' \'));cE=1h.3F(\'22\');k(cE).1p(\'id\',\'dg\').B({4X:k.1v.M.2E+\'U\',5n:k.1v.M.2E+\'U\'}).1S(1h.8M(\' \'));cF=1h.3F(\'a\');k(cF).1p({id:\'gg\',3h:\'#\'}).B({Y:\'1P\',2L:k.1v.M.2E+\'U\',Q:\'0\'}).1S(k.1v.M.e3).1J(\'5h\',k.1v.au);7m=1h.3F(\'22\');k(7m).1p(\'id\',\'cM\').B({Y:\'2s\',cA:\'O\',6w:\'0 9F\',3I:1}).1S(6A).1S(cE).1S(cF);2b=1h.3F(\'1T\');2b.2J=k.1v.M.ec;k(2b).1p(\'id\',\'eM\').B({Y:\'1P\'});4G=1h.3F(\'a\');k(4G).1p({id:\'87\',3h:\'#\'}).B({Y:\'1P\',19:\'1o\',2U:\'2K\',ey:\'1o\'}).1S(1h.8M(\' \'));4M=1h.3F(\'a\');k(4M).1p({id:\'88\',3h:\'#\'}).B({Y:\'1P\',2U:\'2K\',ey:\'1o\'}).1S(1h.8M(\' \'));1Z=1h.3F(\'22\');k(1Z).1p(\'id\',\'eE\').B({19:\'1o\',Y:\'2s\',2U:\'2K\',cA:\'O\',6w:\'0 9F\',Q:\'0\',O:\'0\',3I:2}).1S([2b,4G,4M]);6F=1h.3F(\'22\');k(6F).1p(\'id\',\'ao\').B({19:\'1o\',Y:\'1P\',2U:\'2K\',Q:\'0\',O:\'0\',cA:\'cv\',7i:\'cu\',hC:\'0\'}).1S([1Z,7m]);k(\'2e\').1S(8n).1S(6F)},26:u(e,C){el=C?k(C):k(q);9t=el.1p(\'4I\');D 6B,4u,4G,4M;if(9t!=\'eU\'){k.1v.6j=9t;8Y=k(\'a[@4I=\'+9t+\']\');6B=8Y.1N();4u=8Y.cZ(C?C:q);4G=8Y.K(4u-1);4M=8Y.K(4u+1)}89=el.1p(\'3h\');6A=el.1p(\'4g\');3O=k.1a.6z();8n=k(\'#cP\');if(!k.1v.8k){k.1v.8k=1b;if(k.3a.4t){k(\'#cN\').B(\'W\',18.3r(3O.ih,3O.h)+\'U\').B(\'Z\',18.3r(3O.iw,3O.w)+\'U\').1Y()}8n.B(\'W\',18.3r(3O.ih,3O.h)+\'U\').B(\'Z\',18.3r(3O.iw,3O.w)+\'U\').1Y().fX(cO,k.1v.M.eW,u(){k.1v.cw(89,6A,3O,6B,4u,4G,4M)});k(\'#ao\').B(\'Z\',18.3r(3O.iw,3O.w)+\'U\')}P{k(\'#87\').K(0).53=S;k(\'#88\').K(0).53=S;k.1v.cw(89,6A,3O,6B,4u,4G,4M)}E I},cw:u(89,gP,3O,6B,4u,4G,4M){k(\'#cW\').bk();aX=k(\'#87\');aX.2G();aO=k(\'#88\');aO.2G();2b=k(\'#eM\');1Z=k(\'#eE\');6F=k(\'#ao\');7m=k(\'#cM\').B(\'3n\',\'2K\');k(\'#eK\').3x(6A);k.1v.8m=1b;if(6B)k(\'#dg\').3x(k.1v.M.d8+\' \'+(4u+1)+\' \'+k.1v.M.dc+\' \'+6B);if(4G){aX.K(0).53=u(){q.5B();k.1v.26(S,4G);E I}}if(4M){aO.K(0).53=u(){q.5B();k.1v.26(S,4M);E I}}2b.1Y();82=k.1a.2o(1Z.K(0));56=18.3r(82.1C,2b.K(0).Z+k.1v.M.2E*2);6f=18.3r(82.hb,2b.K(0).W+k.1v.M.2E*2);2b.B({O:(56-2b.K(0).Z)/2+\'U\',Q:(6f-2b.K(0).W)/2+\'U\'});1Z.B({Z:56+\'U\',W:6f+\'U\'}).1Y();dw=k.1a.bm();6F.B(\'Q\',3O.t+(dw.h/15)+\'U\');if(6F.B(\'19\')==\'1o\'){6F.1Y().7f(k.1v.M.3W)}6k=12 9s;k(6k).1p(\'id\',\'cW\').1J(\'hJ\',u(){56=6k.Z+k.1v.M.2E*2;6f=6k.W+k.1v.M.2E*2;2b.2G();1Z.5w({W:6f},82.hb!=6f?k.1v.M.3W:1,u(){1Z.5w({Z:56},82.1C!=56?k.1v.M.3W:1,u(){1Z.bG(6k);k(6k).B({Y:\'1P\',O:k.1v.M.2E+\'U\',Q:k.1v.M.2E+\'U\'}).7f(k.1v.M.3W,u(){db=k.1a.2o(7m.K(0));if(4G){aX.B({O:k.1v.M.2E+\'U\',Q:k.1v.M.2E+\'U\',Z:56/2-k.1v.M.2E*3+\'U\',W:6f-k.1v.M.2E*2+\'U\'}).1Y()}if(4M){aO.B({O:56/2+k.1v.M.2E*2+\'U\',Q:k.1v.M.2E+\'U\',Z:56/2-k.1v.M.2E*3+\'U\',W:6f-k.1v.M.2E*2+\'U\'}).1Y()}7m.B({Z:56+\'U\',Q:-db.hb+\'U\',3n:\'dd\'}).5w({Q:-1},k.1v.M.3W,u(){k.1v.8m=I})})})})});6k.2J=89},au:u(){k(\'#cW\').bk();k(\'#ao\').2G();k(\'#cM\').B(\'3n\',\'2K\');k(\'#cP\').fX(cO,0,u(){k(q).2G();if(k.3a.4t){k(\'#cN\').2G()}});k(\'#87\').K(0).53=S;k(\'#88\').K(0).53=S;k.1v.6j=S;k.1v.8k=I;k.1v.8m=I;E I}};k.R={1A:S,41:S,F:S,1s:S,1q:S,Y:S,9a:u(e){k.R.F=(q.d0)?q.d0:q;k.R.1s=k.1a.4a(e);k.R.1q={Z:T(k(k.R.F).B(\'Z\'))||0,W:T(k(k.R.F).B(\'W\'))||0};k.R.Y={Q:T(k(k.R.F).B(\'Q\'))||0,O:T(k(k.R.F).B(\'O\'))||0};k(1h).1J(\'3D\',k.R.cR).1J(\'5P\',k.R.cK);if(2g k.R.F.1k.g2===\'u\'){k.R.F.1k.g2.1D(k.R.F)}E I},cK:u(e){k(1h).3q(\'3D\',k.R.cR).3q(\'5P\',k.R.cK);if(2g k.R.F.1k.fN===\'u\'){k.R.F.1k.fN.1D(k.R.F)}k.R.F=S},cR:u(e){if(!k.R.F){E}1s=k.1a.4a(e);7p=k.R.Y.Q-k.R.1s.y+1s.y;7r=k.R.Y.O-k.R.1s.x+1s.x;7p=18.3r(18.3L(7p,k.R.F.1k.8g-k.R.1q.W),k.R.F.1k.7h);7r=18.3r(18.3L(7r,k.R.F.1k.8h-k.R.1q.Z),k.R.F.1k.70);if(2g k.R.F.1k.4m===\'u\'){D 8a=k.R.F.1k.4m.1D(k.R.F,[7r,7p]);if(2g 8a==\'hh\'&&8a.1g==2){7r=8a[0];7p=8a[1]}}k.R.F.14.Q=7p+\'U\';k.R.F.14.O=7r+\'U\';E I},26:u(e){k(1h).1J(\'3D\',k.R.8j).1J(\'5P\',k.R.8o);k.R.1A=q.1A;k.R.41=q.41;k.R.1s=k.1a.4a(e);k.R.1q={Z:T(k(q.1A).B(\'Z\'))||0,W:T(k(q.1A).B(\'W\'))||0};k.R.Y={Q:T(k(q.1A).B(\'Q\'))||0,O:T(k(q.1A).B(\'O\'))||0};if(k.R.1A.1k.4o){k.R.1A.1k.4o.1D(k.R.1A,[q])}E I},8o:u(){k(1h).3q(\'3D\',k.R.8j).3q(\'5P\',k.R.8o);if(k.R.1A.1k.3T){k.R.1A.1k.3T.1D(k.R.1A,[k.R.41])}k.R.1A=S;k.R.41=S},6i:u(dx,az){E 18.3L(18.3r(k.R.1q.Z+dx*az,k.R.1A.1k.av),k.R.1A.1k.6x)},6m:u(dy,az){E 18.3L(18.3r(k.R.1q.W+dy*az,k.R.1A.1k.8c),k.R.1A.1k.8b)},fb:u(W){E 18.3L(18.3r(W,k.R.1A.1k.8c),k.R.1A.1k.8b)},8j:u(e){if(k.R.1A==S){E}1s=k.1a.4a(e);dx=1s.x-k.R.1s.x;dy=1s.y-k.R.1s.y;1I={Z:k.R.1q.Z,W:k.R.1q.W};2z={Q:k.R.Y.Q,O:k.R.Y.O};3m(k.R.41){1e\'e\':1I.Z=k.R.6i(dx,1);1r;1e\'fj\':1I.Z=k.R.6i(dx,1);1I.W=k.R.6m(dy,1);1r;1e\'w\':1I.Z=k.R.6i(dx,-1);2z.O=k.R.Y.O-1I.Z+k.R.1q.Z;1r;1e\'5F\':1I.Z=k.R.6i(dx,-1);2z.O=k.R.Y.O-1I.Z+k.R.1q.Z;1I.W=k.R.6m(dy,1);1r;1e\'76\':1I.W=k.R.6m(dy,-1);2z.Q=k.R.Y.Q-1I.W+k.R.1q.W;1I.Z=k.R.6i(dx,-1);2z.O=k.R.Y.O-1I.Z+k.R.1q.Z;1r;1e\'n\':1I.W=k.R.6m(dy,-1);2z.Q=k.R.Y.Q-1I.W+k.R.1q.W;1r;1e\'at\':1I.W=k.R.6m(dy,-1);2z.Q=k.R.Y.Q-1I.W+k.R.1q.W;1I.Z=k.R.6i(dx,1);1r;1e\'s\':1I.W=k.R.6m(dy,1);1r}if(k.R.1A.1k.4v){if(k.R.41==\'n\'||k.R.41==\'s\')4p=1I.W*k.R.1A.1k.4v;P 4p=1I.Z;4W=k.R.fb(4p*k.R.1A.1k.4v);4p=4W/k.R.1A.1k.4v;3m(k.R.41){1e\'n\':1e\'76\':1e\'at\':2z.Q+=1I.W-4W;1r}3m(k.R.41){1e\'76\':1e\'w\':1e\'5F\':2z.O+=1I.Z-4p;1r}1I.W=4W;1I.Z=4p}if(2z.Q<k.R.1A.1k.7h){4W=1I.W+2z.Q-k.R.1A.1k.7h;2z.Q=k.R.1A.1k.7h;if(k.R.1A.1k.4v){4p=4W/k.R.1A.1k.4v;3m(k.R.41){1e\'76\':1e\'w\':1e\'5F\':2z.O+=1I.Z-4p;1r}1I.Z=4p}1I.W=4W}if(2z.O<k.R.1A.1k.70){4p=1I.Z+2z.O-k.R.1A.1k.70;2z.O=k.R.1A.1k.70;if(k.R.1A.1k.4v){4W=4p*k.R.1A.1k.4v;3m(k.R.41){1e\'n\':1e\'76\':1e\'at\':2z.Q+=1I.W-4W;1r}1I.W=4W}1I.Z=4p}if(2z.Q+1I.W>k.R.1A.1k.8g){1I.W=k.R.1A.1k.8g-2z.Q;if(k.R.1A.1k.4v){1I.Z=1I.W/k.R.1A.1k.4v}}if(2z.O+1I.Z>k.R.1A.1k.8h){1I.Z=k.R.1A.1k.8h-2z.O;if(k.R.1A.1k.4v){1I.W=1I.Z*k.R.1A.1k.4v}}D 6p=I;if(k.R.1A.1k.f7){6p=k.R.1A.1k.f7.1D(k.R.1A,[1I,2z]);if(6p){if(6p.1q){k.23(1I,6p.1q)}if(6p.Y){k.23(2z,6p.Y)}}}8d=k.R.1A.14;8d.O=2z.O+\'U\';8d.Q=2z.Q+\'U\';8d.Z=1I.Z+\'U\';8d.W=1I.W+\'U\';E I},2r:u(M){if(!M||!M.3Z||M.3Z.1K!=7M){E}E q.1E(u(){D el=q;el.1k=M;el.1k.av=M.av||10;el.1k.8c=M.8c||10;el.1k.6x=M.6x||6P;el.1k.8b=M.8b||6P;el.1k.7h=M.7h||-aC;el.1k.70=M.70||-aC;el.1k.8h=M.8h||6P;el.1k.8g=M.8g||6P;d6=k(el).B(\'Y\');if(!(d6==\'2s\'||d6==\'1P\')){el.14.Y=\'2s\'}fS=/n|at|e|fj|s|5F|w|76/g;24(i in el.1k.3Z){if(i.6c().d5(fS)!=S){if(el.1k.3Z[i].1K==b0){3v=k(el.1k.3Z[i]);if(3v.1N()>0){el.1k.3Z[i]=3v.K(0)}}if(el.1k.3Z[i].4Y){el.1k.3Z[i].1A=el;el.1k.3Z[i].41=i;k(el.1k.3Z[i]).1J(\'5v\',k.R.26)}}}if(el.1k.5S){if(2g el.1k.5S===\'4V\'){aV=k(el.1k.5S);if(aV.1N()>0){aV.1E(u(){q.d0=el});aV.1J(\'5v\',k.R.9a)}}P if(el.1k.5S==1b){k(q).1J(\'5v\',k.R.9a)}}})},4U:u(){E q.1E(u(){D el=q;24(i in el.1k.3Z){el.1k.3Z[i].1A=S;el.1k.3Z[i].41=S;k(el.1k.3Z[i]).3q(\'5v\',k.R.26)}if(el.1k.5S){if(2g el.1k.5S===\'4V\'){3v=k(el.1k.5S);if(3v.1N()>0){3v.3q(\'5v\',k.R.9a)}}P if(el.1k.5S==1b){k(q).3q(\'5v\',k.R.9a)}}el.1k=S})}};k.fn.23({hz:k.R.2r,hs:k.R.4U});k.2C=S;k.7n=I;k.3k=S;k.7o=[];k.9v=u(e){D 3K=e.7L||e.7K||-1;if(3K==17||3K==16){k.7n=1b}};k.9u=u(e){k.7n=I};k.dL=u(e){q.f.1s=k.1a.4a(e);q.f.1M=k.23(k.1a.3w(q),k.1a.2o(q));q.f.3e=k.1a.6z(q);q.f.1s.x-=q.f.1M.x;q.f.1s.y-=q.f.1M.y;k(q).1S(k.2C.K(0));if(q.f.hc)k.2C.2R(q.f.hc).B(\'19\',\'2B\');k.2C.B({19:\'2B\',Z:\'2P\',W:\'2P\'});if(q.f.o){k.2C.B(\'1G\',q.f.o)}k.3k=q;k.96=I;k.7o=[];q.f.el.1E(u(){q.1M={x:q.8t+(q.4Z&&!k.3a.7I?T(q.4Z.5b)||0:0)+(k.3k.3c||0),y:q.8G+(q.4Z&&!k.3a.7I?T(q.4Z.4S)||0:0)+(k.3k.3d||0),1C:q.4c,hb:q.5W};if(q.s==1b){if(k.7n==I){q.s=I;k(q).4i(k.3k.f.7j)}P{k.96=1b;k.7o[k.7o.1g]=k.1p(q,\'id\')}}});k.am.1D(q,[e]);k(1h).1J(\'3D\',k.am).1J(\'5P\',k.cX);E I};k.am=u(e){if(!k.3k)E;k.fd.1D(k.3k,[e])};k.fd=u(e){if(!k.3k)E;D 1s=k.1a.4a(e);D 3e=k.1a.6z(k.3k);1s.x+=3e.l-q.f.3e.l-q.f.1M.x;1s.y+=3e.t-q.f.3e.t-q.f.1M.y;D 93=18.3L(1s.x,q.f.1s.x);D 5F=18.3L(18.3S(1s.x-q.f.1s.x),18.3S(q.f.3e.w-93));D 99=18.3L(1s.y,q.f.1s.y);D 9g=18.3L(18.3S(1s.y-q.f.1s.y),18.3S(q.f.3e.h-99));if(q.3d>0&&1s.y-20<q.3d){D 3X=18.3L(3e.t,10);99-=3X;9g+=3X;q.3d-=3X}P if(q.3d+q.f.1M.h<q.f.3e.h&&1s.y+20>q.3d+q.f.1M.h){D 3X=18.3L(q.f.3e.h-q.3d,10);q.3d+=3X;if(q.3d!=3e.t)9g+=3X}if(q.3c>0&&1s.x-20<q.3c){D 3X=18.3L(3e.l,10);93-=3X;5F+=3X;q.3c-=3X}P if(q.3c+q.f.1M.w<q.f.3e.w&&1s.x+20>q.3c+q.f.1M.w){D 3X=18.3L(q.f.3e.w-q.3c,10);q.3c+=3X;if(q.3c!=3e.l)5F+=3X}k.2C.B({O:93+\'U\',Q:99+\'U\',Z:5F+\'U\',W:9g+\'U\'});k.2C.l=93+q.f.3e.l;k.2C.t=99+q.f.3e.t;k.2C.r=k.2C.l+5F;k.2C.b=k.2C.t+9g;k.96=I;q.f.el.1E(u(){aw=k.7o.3J(k.1p(q,\'id\'));if(!(q.1M.x>k.2C.r||(q.1M.x+q.1M.1C)<k.2C.l||q.1M.y>k.2C.b||(q.1M.y+q.1M.hb)<k.2C.t)){k.96=1b;if(q.s!=1b){q.s=1b;k(q).2R(k.3k.f.7j)}if(aw!=-1){q.s=I;k(q).4i(k.3k.f.7j)}}P if((q.s==1b)&&(aw==-1)){q.s=I;k(q).4i(k.3k.f.7j)}P if((!q.s)&&(k.7n==1b)&&(aw!=-1)){q.s=1b;k(q).2R(k.3k.f.7j)}});E I};k.cX=u(e){if(!k.3k)E;k.g0.1D(k.3k,[e])};k.g0=u(e){k(1h).3q(\'3D\',k.am).3q(\'5P\',k.cX);if(!k.3k)E;k.2C.B(\'19\',\'1o\');if(q.f.hc)k.2C.4i(q.f.hc);k.3k=I;k(\'2e\').1S(k.2C.K(0));if(k.96==1b){if(q.f.98)q.f.98(k.cJ(k.1p(q,\'id\')))}P{if(q.f.9d)q.f.9d(k.cJ(k.1p(q,\'id\')))}k.7o=[]};k.cJ=u(s){D h=\'\';D o=[];if(a=k(\'#\'+s)){a.K(0).f.el.1E(u(){if(q.s==1b){if(h.1g>0){h+=\'&\'}h+=s+\'[]=\'+k.1p(q,\'id\');o[o.1g]=k.1p(q,\'id\')}})}E{7l:h,o:o}};k.fn.gZ=u(o){if(!k.2C){k(\'2e\',1h).1S(\'<22 id="2C"></22>\').1J(\'7B\',k.9v).1J(\'6y\',k.9u);k.2C=k(\'#2C\');k.2C.B({Y:\'1P\',19:\'1o\'});if(1X.2k){k(\'2e\',1h).1J(\'7B\',k.9v).1J(\'6y\',k.9u)}P{k(1h).1J(\'7B\',k.9v).1J(\'6y\',k.9u)}}if(!o){o={}}E q.1E(u(){if(q.eP)E;q.eP=1b;q.f={a:o.3C,o:o.1G?2m(o.1G):I,7j:o.eS?o.eS:I,hc:o.58?o.58:I,98:o.98?o.98:I,9d:o.9d?o.9d:I};q.f.el=k(\'.\'+o.3C);k(q).1J(\'5v\',k.dL).B(\'Y\',\'2s\')})};k.3b={bM:1,eH:u(3t){D 3t=3t;E q.1E(u(){q.4z.6s.1E(u(ab){k.3b.5c(q,3t[ab])})})},K:u(){D 3t=[];q.1E(u(cL){if(q.bI){3t[cL]=[];D C=q;D 1q=k.1a.2o(q);q.4z.6s.1E(u(ab){D x=q.8t;D y=q.8G;92=T(x*2a/(1q.w-q.4c));91=T(y*2a/(1q.h-q.5W));3t[cL][ab]=[92||0,91||0,x||0,y||0]})}});E 3t},ct:u(C){C.A.fu=C.A.28.w-C.A.1B.1C;C.A.fw=C.A.28.h-C.A.1B.hb;if(C.9r.4z.bC){9Z=C.9r.4z.6s.K(C.bF+1);if(9Z){C.A.28.w=(T(k(9Z).B(\'O\'))||0)+C.A.1B.1C;C.A.28.h=(T(k(9Z).B(\'Q\'))||0)+C.A.1B.hb}9Q=C.9r.4z.6s.K(C.bF-1);if(9Q){D cU=T(k(9Q).B(\'O\'))||0;D cH=T(k(9Q).B(\'O\'))||0;C.A.28.x+=cU;C.A.28.y+=cH;C.A.28.w-=cU;C.A.28.h-=cH}}C.A.g7=C.A.28.w-C.A.1B.1C;C.A.eC=C.A.28.h-C.A.1B.hb;if(C.A.2O){C.A.gx=((C.A.28.w-C.A.1B.1C)/C.A.2O)||1;C.A.gy=((C.A.28.h-C.A.1B.hb)/C.A.2O)||1;C.A.fU=C.A.g7/C.A.2O;C.A.fH=C.A.eC/C.A.2O}C.A.28.dx=C.A.28.x-C.A.2c.x;C.A.28.dy=C.A.28.y-C.A.2c.y;k.11.1c.B(\'9b\',\'ad\')},3H:u(C,x,y){if(C.A.2O){fE=T(x/C.A.fU);92=fE*2a/C.A.2O;ft=T(y/C.A.fH);91=ft*2a/C.A.2O}P{92=T(x*2a/C.A.fu);91=T(y*2a/C.A.fw)}C.A.b3=[92||0,91||0,x||0,y||0];if(C.A.3H)C.A.3H.1D(C,C.A.b3)},eI:u(2k){3K=2k.7L||2k.7K||-1;3m(3K){1e 35:k.3b.5c(q.3U,[ae,ae]);1r;1e 36:k.3b.5c(q.3U,[-ae,-ae]);1r;1e 37:k.3b.5c(q.3U,[-q.3U.A.gx||-1,0]);1r;1e 38:k.3b.5c(q.3U,[0,-q.3U.A.gy||-1]);1r;1e 39:k.3b.5c(q.3U,[q.3U.A.gx||1,0]);1r;1e 40:k.11.5c(q.3U,[0,q.3U.A.gy||1]);1r}},5c:u(C,Y){if(!C.A){E}C.A.1B=k.23(k.1a.3w(C),k.1a.2o(C));C.A.2c={x:T(k.B(C,\'O\'))||0,y:T(k.B(C,\'Q\'))||0};C.A.4n=k.B(C,\'Y\');if(C.A.4n!=\'2s\'&&C.A.4n!=\'1P\'){C.14.Y=\'2s\'}k.11.c5(C);k.3b.ct(C);dx=T(Y[0])||0;dy=T(Y[1])||0;2v=C.A.2c.x+dx;2q=C.A.2c.y+dy;if(C.A.2O){3y=k.11.c7.1D(C,[2v,2q,dx,dy]);if(3y.1K==7M){dx=3y.dx;dy=3y.dy}2v=C.A.2c.x+dx;2q=C.A.2c.y+dy}3y=k.11.ce.1D(C,[2v,2q,dx,dy]);if(3y&&3y.1K==7M){dx=3y.dx;dy=3y.dy}2v=C.A.2c.x+dx;2q=C.A.2c.y+dy;if(C.A.5i&&(C.A.3H||C.A.2Z)){k.3b.3H(C,2v,2q)}2v=!C.A.1O||C.A.1O==\'4j\'?2v:C.A.2c.x||0;2q=!C.A.1O||C.A.1O==\'49\'?2q:C.A.2c.y||0;C.14.O=2v+\'U\';C.14.Q=2q+\'U\'},2r:u(o){E q.1E(u(){if(q.bI==1b||!o.3C||!k.1a||!k.11||!k.1x){E}5x=k(o.3C,q);if(5x.1N()==0){E}D 4N={2p:\'94\',5i:1b,3H:o.3H&&o.3H.1K==2A?o.3H:S,2Z:o.2Z&&o.2Z.1K==2A?o.2Z:S,3v:q,1G:o.1G||I};if(o.2O&&T(o.2O)){4N.2O=T(o.2O)||1;4N.2O=4N.2O>0?4N.2O:1}if(5x.1N()==1)5x.7t(4N);P{k(5x.K(0)).7t(4N);4N.3v=S;5x.7t(4N)}5x.7B(k.3b.eI);5x.1p(\'bM\',k.3b.bM++);q.bI=1b;q.4z={};q.4z.er=4N.er;q.4z.2O=4N.2O;q.4z.6s=5x;q.4z.bC=o.bC?1b:I;bZ=q;bZ.4z.6s.1E(u(2N){q.bF=2N;q.9r=bZ});if(o.3t&&o.3t.1K==7F){24(i=o.3t.1g-1;i>=0;i--){if(o.3t[i].1K==7F&&o.3t[i].1g==2){el=q.4z.6s.K(i);if(el.4Y){k.3b.5c(el,o.3t[i])}}}}})}};k.fn.23({hN:k.3b.2r,hS:k.3b.eH,hG:k.3b.K});k.2u={5I:[],eg:u(){q.5B();X=q.31;id=k.1p(X,\'id\');if(k.2u.5I[id]!=S){1X.5T(k.2u.5I[id])}1z=X.L.3u+1;if(X.L.1Q.1g<1z){1z=1}1Q=k(\'1T\',X.L.5u);X.L.3u=1z;if(1Q.1N()>0){1Q.7a(X.L.3W,k.2u.95)}},dp:u(){q.5B();X=q.31;id=k.1p(X,\'id\');if(k.2u.5I[id]!=S){1X.5T(k.2u.5I[id])}1z=X.L.3u-1;1Q=k(\'1T\',X.L.5u);if(1z<1){1z=X.L.1Q.1g}X.L.3u=1z;if(1Q.1N()>0){1Q.7a(X.L.3W,k.2u.95)}},2I:u(c){X=1h.9e(c);if(X.L.6o){1z=X.L.3u;7d(1z==X.L.3u){1z=1+T(18.6o()*X.L.1Q.1g)}}P{1z=X.L.3u+1;if(X.L.1Q.1g<1z){1z=1}}1Q=k(\'1T\',X.L.5u);X.L.3u=1z;if(1Q.1N()>0){1Q.7a(X.L.3W,k.2u.95)}},go:u(o){D X;if(o&&o.1K==7M){if(o.2b){X=1h.9e(o.2b.X);5N=1X.hn.3h.7C("#");o.2b.6S=S;if(5N.1g==2){1z=T(5N[1]);1Y=5N[1].4E(1z,\'\');if(k.1p(X,\'id\')!=1Y){1z=1}}P{1z=1}}if(o.90){o.90.5B();X=o.90.31.31;id=k.1p(X,\'id\');if(k.2u.5I[id]!=S){1X.5T(k.2u.5I[id])}5N=o.90.3h.7C("#");1z=T(5N[1]);1Y=5N[1].4E(1z,\'\');if(k.1p(X,\'id\')!=1Y){1z=1}}if(X.L.1Q.1g<1z||1z<1){1z=1}X.L.3u=1z;52=k.1a.2o(X);dt=k.1a.aT(X);d9=k.1a.6U(X);if(X.L.3z){X.L.3z.o.B(\'19\',\'1o\')}if(X.L.3s){X.L.3s.o.B(\'19\',\'1o\')}if(X.L.2b){y=T(dt.t)+T(d9.t);if(X.L.1U){if(X.L.1U.5A==\'Q\'){y+=X.L.1U.4C.hb}P{52.h-=X.L.1U.4C.hb}}if(X.L.2x){if(X.L.2x&&X.L.2x.6Q==\'Q\'){y+=X.L.2x.4C.hb}P{52.h-=X.L.2x.4C.hb}}if(!X.L.c1){X.L.df=o.2b?o.2b.W:(T(X.L.2b.B(\'W\'))||0);X.L.c1=o.2b?o.2b.Z:(T(X.L.2b.B(\'Z\'))||0)}X.L.2b.B(\'Q\',y+(52.h-X.L.df)/2+\'U\');X.L.2b.B(\'O\',(52.1C-X.L.c1)/2+\'U\');X.L.2b.B(\'19\',\'2B\')}1Q=k(\'1T\',X.L.5u);if(1Q.1N()>0){1Q.7a(X.L.3W,k.2u.95)}P{aj=k(\'a\',X.L.1U.o).K(1z-1);k(aj).2R(X.L.1U.5R);D 1T=12 9s();1T.X=k.1p(X,\'id\');1T.1z=1z-1;1T.2J=X.L.1Q[X.L.3u-1].2J;if(1T.21){1T.6S=S;k.2u.19.1D(1T)}P{1T.6S=k.2u.19}if(X.L.2x){X.L.2x.o.3x(X.L.1Q[1z-1].6L)}}}},95:u(){X=q.31.31;X.L.5u.B(\'19\',\'1o\');if(X.L.1U.5R){aj=k(\'a\',X.L.1U.o).4i(X.L.1U.5R).K(X.L.3u-1);k(aj).2R(X.L.1U.5R)}D 1T=12 9s();1T.X=k.1p(X,\'id\');1T.1z=X.L.3u-1;1T.2J=X.L.1Q[X.L.3u-1].2J;if(1T.21){1T.6S=S;k.2u.19.1D(1T)}P{1T.6S=k.2u.19}if(X.L.2x){X.L.2x.o.3x(X.L.1Q[X.L.3u-1].6L)}},19:u(){X=1h.9e(q.X);if(X.L.3z){X.L.3z.o.B(\'19\',\'1o\')}if(X.L.3s){X.L.3s.o.B(\'19\',\'1o\')}52=k.1a.2o(X);y=0;if(X.L.1U){if(X.L.1U.5A==\'Q\'){y+=X.L.1U.4C.hb}P{52.h-=X.L.1U.4C.hb}}if(X.L.2x){if(X.L.2x&&X.L.2x.6Q==\'Q\'){y+=X.L.2x.4C.hb}P{52.h-=X.L.2x.4C.hb}}hg=k(\'.ca\',X);y=y+(52.h-q.W)/2;x=(52.1C-q.Z)/2;X.L.5u.B(\'Q\',y+\'U\').B(\'O\',x+\'U\').3x(\'<1T 2J="\'+q.2J+\'" />\');X.L.5u.7f(X.L.3W);3s=X.L.3u+1;if(3s>X.L.1Q.1g){3s=1}3z=X.L.3u-1;if(3z<1){3z=X.L.1Q.1g}X.L.3s.o.B(\'19\',\'2B\').B(\'Q\',y+\'U\').B(\'O\',x+2*q.Z/3+\'U\').B(\'Z\',q.Z/3+\'U\').B(\'W\',q.W+\'U\').1p(\'4g\',X.L.1Q[3s-1].6L);X.L.3s.o.K(0).3h=\'#\'+3s+k.1p(X,\'id\');X.L.3z.o.B(\'19\',\'2B\').B(\'Q\',y+\'U\').B(\'O\',x+\'U\').B(\'Z\',q.Z/3+\'U\').B(\'W\',q.W+\'U\').1p(\'4g\',X.L.1Q[3z-1].6L);X.L.3z.o.K(0).3h=\'#\'+3z+k.1p(X,\'id\')},2r:u(o){if(!o||!o.1Z||k.2u.5I[o.1Z])E;D 1Z=k(\'#\'+o.1Z);D el=1Z.K(0);if(el.14.Y!=\'1P\'&&el.14.Y!=\'2s\'){el.14.Y=\'2s\'}el.14.2U=\'2K\';if(1Z.1N()==0)E;el.L={};el.L.1Q=o.1Q?o.1Q:[];el.L.6o=o.6o&&o.6o==1b||I;97=el.f3(\'hL\');24(i=0;i<97.1g;i++){7Z=el.L.1Q.1g;el.L.1Q[7Z]={2J:97[i].2J,6L:97[i].4g||97[i].hD||\'\'}}if(el.L.1Q.1g==0){E}el.L.4n=k.23(k.1a.3w(el),k.1a.2o(el));el.L.b5=k.1a.aT(el);el.L.bu=k.1a.6U(el);t=T(el.L.b5.t)+T(el.L.bu.t);b=T(el.L.b5.b)+T(el.L.bu.b);k(\'1T\',el).bk();el.L.3W=o.3W?o.3W:g5;if(o.5A||o.9f||o.5R){el.L.1U={};1Z.1S(\'<22 6T="g1"></22>\');el.L.1U.o=k(\'.g1\',el);if(o.9f){el.L.1U.9f=o.9f;el.L.1U.o.2R(o.9f)}if(o.5R){el.L.1U.5R=o.5R}el.L.1U.o.B(\'Y\',\'1P\').B(\'Z\',el.L.4n.w+\'U\');if(o.5A&&o.5A==\'Q\'){el.L.1U.5A=\'Q\';el.L.1U.o.B(\'Q\',t+\'U\')}P{el.L.1U.5A=\'4D\';el.L.1U.o.B(\'4D\',b+\'U\')}el.L.1U.aE=o.aE?o.aE:\' \';24(D i=0;i<el.L.1Q.1g;i++){7Z=T(i)+1;el.L.1U.o.1S(\'<a 3h="#\'+7Z+o.1Z+\'" 6T="gR" 4g="\'+el.L.1Q[i].6L+\'">\'+7Z+\'</a>\'+(7Z!=el.L.1Q.1g?el.L.1U.aE:\'\'))}k(\'a\',el.L.1U.o).1J(\'5h\',u(){k.2u.go({90:q})});el.L.1U.4C=k.1a.2o(el.L.1U.o.K(0))}if(o.6Q||o.9c){el.L.2x={};1Z.1S(\'<22 6T="dn">&7k;</22>\');el.L.2x.o=k(\'.dn\',el);if(o.9c){el.L.2x.9c=o.9c;el.L.2x.o.2R(o.9c)}el.L.2x.o.B(\'Y\',\'1P\').B(\'Z\',el.L.4n.w+\'U\');if(o.6Q&&o.6Q==\'Q\'){el.L.2x.6Q=\'Q\';el.L.2x.o.B(\'Q\',(el.L.1U&&el.L.1U.5A==\'Q\'?el.L.1U.4C.hb+t:t)+\'U\')}P{el.L.2x.6Q=\'4D\';el.L.2x.o.B(\'4D\',(el.L.1U&&el.L.1U.5A==\'4D\'?el.L.1U.4C.hb+b:b)+\'U\')}el.L.2x.4C=k.1a.2o(el.L.2x.o.K(0))}if(o.9D){el.L.3s={9D:o.9D};1Z.1S(\'<a 3h="#2\'+o.1Z+\'" 6T="eY">&7k;</a>\');el.L.3s.o=k(\'.eY\',el);el.L.3s.o.B(\'Y\',\'1P\').B(\'19\',\'1o\').B(\'2U\',\'2K\').B(\'4A\',\'eR\').2R(el.L.3s.9D);el.L.3s.o.1J(\'5h\',k.2u.eg)}if(o.9o){el.L.3z={9o:o.9o};1Z.1S(\'<a 3h="#0\'+o.1Z+\'" 6T="ee">&7k;</a>\');el.L.3z.o=k(\'.ee\',el);el.L.3z.o.B(\'Y\',\'1P\').B(\'19\',\'1o\').B(\'2U\',\'2K\').B(\'4A\',\'eR\').2R(el.L.3z.9o);el.L.3z.o.1J(\'5h\',k.2u.dp)}1Z.bG(\'<22 6T="ca"></22>\');el.L.5u=k(\'.ca\',el);el.L.5u.B(\'Y\',\'1P\').B(\'Q\',\'2P\').B(\'O\',\'2P\').B(\'19\',\'1o\');if(o.2b){1Z.bG(\'<22 6T="dW" 14="19: 1o;"><1T 2J="\'+o.2b+\'" /></22>\');el.L.2b=k(\'.dW\',el);el.L.2b.B(\'Y\',\'1P\');D 1T=12 9s();1T.X=o.1Z;1T.2J=o.2b;if(1T.21){1T.6S=S;k.2u.go({2b:1T})}P{1T.6S=u(){k.2u.go({2b:q})}}}P{k.2u.go({1Z:el})}if(o.cS){fi=T(o.cS)*aC}k.2u.5I[o.1Z]=o.cS?1X.6V(\'k.2u.2I(\\\'\'+o.1Z+\'\\\')\',fi):S}};k.X=k.2u.2r;k.1t={7s:[],5L:{},1c:I,7u:S,26:u(){if(k.11.F==S){E}D 4O,3G,c,cs;k.1t.1c.K(0).3l=k.11.F.A.6R;4O=k.1t.1c.K(0).14;4O.19=\'2B\';k.1t.1c.1B=k.23(k.1a.3w(k.1t.1c.K(0)),k.1a.2o(k.1t.1c.K(0)));4O.Z=k.11.F.A.1B.1C+\'U\';4O.W=k.11.F.A.1B.hb+\'U\';3G=k.1a.cy(k.11.F);4O.5K=3G.t;4O.5z=3G.r;4O.5k=3G.b;4O.5j=3G.l;if(k.11.F.A.46==1b){c=k.11.F.fI(1b);cs=c.14;cs.5K=\'2P\';cs.5z=\'2P\';cs.5k=\'2P\';cs.5j=\'2P\';cs.19=\'2B\';k.1t.1c.5o().1S(c)}k(k.11.F).f5(k.1t.1c.K(0));k.11.F.14.19=\'1o\'},fC:u(e){if(!e.A.44&&k.1x.5r.cQ){if(e.A.3T)e.A.3T.1D(F);k(e).B(\'Y\',e.A.cz||e.A.4n);k(e).aS();k(k.1x.5r).f6(e)}k.1t.1c.4i(e.A.6R).3x(\'&7k;\');k.1t.7u=S;D 4O=k.1t.1c.K(0).14;4O.19=\'1o\';k.1t.1c.f5(e);if(e.A.fx>0){k(e).7f(e.A.fx)}k(\'2e\').1S(k.1t.1c.K(0));D 86=[];D 8q=I;24(D i=0;i<k.1t.7s.1g;i++){D 1j=k.1x.3P[k.1t.7s[i]].K(0);D id=k.1p(1j,\'id\');D 8i=k.1t.8x(id);if(1j.1i.ay!=8i.7l){1j.1i.ay=8i.7l;if(8q==I&&1j.1i.2Z){8q=1j.1i.2Z}8i.id=id;86[86.1g]=8i}}k.1t.7s=[];if(8q!=I&&86.1g>0){8q(86)}},al:u(e,o){if(!k.11.F)E;D 6e=I;D i=0;if(e.1i.el.1N()>0){24(i=e.1i.el.1N();i>0;i--){if(e.1i.el.K(i-1)!=k.11.F){if(!e.5V.b2){if((e.1i.el.K(i-1).1M.y+e.1i.el.K(i-1).1M.hb/2)>k.11.F.A.2q){6e=e.1i.el.K(i-1)}P{1r}}P{if((e.1i.el.K(i-1).1M.x+e.1i.el.K(i-1).1M.1C/2)>k.11.F.A.2v&&(e.1i.el.K(i-1).1M.y+e.1i.el.K(i-1).1M.hb/2)>k.11.F.A.2q){6e=e.1i.el.K(i-1)}}}}}if(6e&&k.1t.7u!=6e){k.1t.7u=6e;k(6e).h5(k.1t.1c.K(0))}P if(!6e&&(k.1t.7u!=S||k.1t.1c.K(0).31!=e)){k.1t.7u=S;k(e).1S(k.1t.1c.K(0))}k.1t.1c.K(0).14.19=\'2B\'},cT:u(e){if(k.11.F==S){E}e.1i.el.1E(u(){q.1M=k.23(k.1a.74(q),k.1a.7G(q))})},8x:u(s){D i;D h=\'\';D o={};if(s){if(k.1t.5L[s]){o[s]=[];k(\'#\'+s+\' .\'+k.1t.5L[s]).1E(u(){if(h.1g>0){h+=\'&\'}h+=s+\'[]=\'+k.1p(q,\'id\');o[s][o[s].1g]=k.1p(q,\'id\')})}P{24(a in s){if(k.1t.5L[s[a]]){o[s[a]]=[];k(\'#\'+s[a]+\' .\'+k.1t.5L[s[a]]).1E(u(){if(h.1g>0){h+=\'&\'}h+=s[a]+\'[]=\'+k.1p(q,\'id\');o[s[a]][o[s[a]].1g]=k.1p(q,\'id\')})}}}}P{24(i in k.1t.5L){o[i]=[];k(\'#\'+i+\' .\'+k.1t.5L[i]).1E(u(){if(h.1g>0){h+=\'&\'}h+=i+\'[]=\'+k.1p(q,\'id\');o[i][o[i].1g]=k.1p(q,\'id\')})}}E{7l:h,o:o}},fF:u(e){if(!e.dq){E}E q.1E(u(){if(!q.5V||!k(e).is(\'.\'+q.5V.3C))k(e).2R(q.5V.3C);k(e).7t(q.5V.A)})},4U:u(){E q.1E(u(){k(\'.\'+q.5V.3C).aS();k(q).dR();q.5V=S;q.fm=S})},2r:u(o){if(o.3C&&k.1a&&k.11&&k.1x){if(!k.1t.1c){k(\'2e\',1h).1S(\'<22 id="e5">&7k;</22>\');k.1t.1c=k(\'#e5\');k.1t.1c.K(0).14.19=\'1o\'}q.do({3C:o.3C,9J:o.9J?o.9J:I,a5:o.a5?o.a5:I,58:o.58?o.58:I,7x:o.7x||o.dC,7y:o.7y||o.fO,cQ:1b,2Z:o.2Z||o.ia,fx:o.fx?o.fx:I,46:o.46?1b:I,6I:o.6I?o.6I:\'cV\'});E q.1E(u(){D A={6N:o.6N?1b:I,ff:6P,1G:o.1G?2m(o.1G):I,6R:o.58?o.58:I,fx:o.fx?o.fx:I,44:1b,46:o.46?1b:I,3v:o.3v?o.3v:S,2p:o.2p?o.2p:S,4o:o.4o&&o.4o.1K==2A?o.4o:I,4m:o.4m&&o.4m.1K==2A?o.4m:I,3T:o.3T&&o.3T.1K==2A?o.3T:I,1O:/49|4j/.48(o.1O)?o.1O:I,6M:o.6M?T(o.6M)||0:I,2V:o.2V?o.2V:I};k(\'.\'+o.3C,q).7t(A);q.fm=1b;q.5V={3C:o.3C,6N:o.6N?1b:I,ff:6P,1G:o.1G?2m(o.1G):I,6R:o.58?o.58:I,fx:o.fx?o.fx:I,44:1b,46:o.46?1b:I,3v:o.3v?o.3v:S,2p:o.2p?o.2p:S,b2:o.b2?1b:I,A:A}})}}};k.fn.23({j3:k.1t.2r,f6:k.1t.fF,iS:k.1t.4U});k.iZ=k.1t.8x;k.2t={6O:S,7b:I,9m:S,6K:u(e){k.2t.7b=1b;k.2t.1Y(e,q,1b)},cq:u(e){if(k.2t.6O!=q)E;k.2t.7b=I;k.2t.2G(e,q)},1Y:u(e,el,7b){if(k.2t.6O!=S)E;if(!el){el=q}k.2t.6O=el;1M=k.23(k.1a.3w(el),k.1a.2o(el));8u=k(el);4g=8u.1p(\'4g\');3h=8u.1p(\'3h\');if(4g){k.2t.9m=4g;8u.1p(\'4g\',\'\');k(\'#eT\').3x(4g);if(3h)k(\'#bL\').3x(3h.4E(\'jh://\',\'\'));P k(\'#bL\').3x(\'\');1c=k(\'#8z\');if(el.4H.3l){1c.K(0).3l=el.4H.3l}P{1c.K(0).3l=\'\'}bo=k.1a.2o(1c.K(0));ga=7b&&el.4H.Y==\'bO\'?\'4D\':el.4H.Y;3m(ga){1e\'Q\':2q=1M.y-bo.hb;2v=1M.x;1r;1e\'O\':2q=1M.y;2v=1M.x-bo.1C;1r;1e\'2L\':2q=1M.y;2v=1M.x+1M.1C;1r;1e\'bO\':k(\'2e\').1J(\'3D\',k.2t.3D);1s=k.1a.4a(e);2q=1s.y+15;2v=1s.x+15;1r;ad:2q=1M.y+1M.hb;2v=1M.x;1r}1c.B({Q:2q+\'U\',O:2v+\'U\'});if(el.4H.54==I){1c.1Y()}P{1c.7f(el.4H.54)}if(el.4H.2Y)el.4H.2Y.1D(el);8u.1J(\'8B\',k.2t.2G).1J(\'5B\',k.2t.cq)}},3D:u(e){if(k.2t.6O==S){k(\'2e\').3q(\'3D\',k.2t.3D);E}1s=k.1a.4a(e);k(\'#8z\').B({Q:1s.y+15+\'U\',O:1s.x+15+\'U\'})},2G:u(e,el){if(!el){el=q}if(k.2t.7b!=1b&&k.2t.6O==el){k.2t.6O=S;k(\'#8z\').7a(1);k(el).1p(\'4g\',k.2t.9m).3q(\'8B\',k.2t.2G).3q(\'5B\',k.2t.cq);if(el.4H.3i)el.4H.3i.1D(el);k.2t.9m=S}},2r:u(M){if(!k.2t.1c){k(\'2e\').1S(\'<22 id="8z"><22 id="eT"></22><22 id="bL"></22></22>\');k(\'#8z\').B({Y:\'1P\',3I:6P,19:\'1o\'});k.2t.1c=1b}E q.1E(u(){if(k.1p(q,\'4g\')){q.4H={Y:/Q|4D|O|2L|bO/.48(M.Y)?M.Y:\'4D\',3l:M.3l?M.3l:I,54:M.54?M.54:I,2Y:M.2Y&&M.2Y.1K==2A?M.2Y:I,3i:M.3i&&M.3i.1K==2A?M.3i:I};D el=k(q);el.1J(\'9z\',k.2t.1Y);el.1J(\'6K\',k.2t.6K)}})}};k.fn.hO=k.2t.2r;k.84={bq:u(e){3K=e.7L||e.7K||-1;if(3K==9){if(1X.2k){1X.2k.bT=1b;1X.2k.c0=I}P{e.aP();e.aW()}if(q.b1){1h.6J.dZ().3g="\\t";q.dV=u(){q.6K();q.dV=S}}P if(q.aF){26=q.5q;2T=q.dN;q.2y=q.2y.hd(0,26)+"\\t"+q.2y.h8(2T);q.aF(26+1,26+1);q.6K()}E I}},4U:u(){E q.1E(u(){if(q.7P&&q.7P==1b){k(q).3q(\'7B\',k.84.bq);q.7P=I}})},2r:u(){E q.1E(u(){if(q.4Y==\'cf\'&&(!q.7P||q.7P==I)){k(q).1J(\'7B\',k.84.bq);q.7P=1b}})}};k.fn.23({j5:k.84.2r,hH:k.84.4U});k.1a={3w:u(e){D x=0;D y=0;D es=e.14;D bP=I;if(k(e).B(\'19\')==\'1o\'){D 5Y=es.3n;D 9q=es.Y;bP=1b;es.3n=\'2K\';es.19=\'2B\';es.Y=\'1P\'}D el=e;7d(el){x+=el.8t+(el.4Z&&!k.3a.7I?T(el.4Z.5b)||0:0);y+=el.8G+(el.4Z&&!k.3a.7I?T(el.4Z.4S)||0:0);el=el.dJ}el=e;7d(el&&el.4Y&&el.4Y.6c()!=\'2e\'){x-=el.3c||0;y-=el.3d||0;el=el.31}if(bP==1b){es.19=\'1o\';es.Y=9q;es.3n=5Y}E{x:x,y:y}},7G:u(el){D x=0,y=0;7d(el){x+=el.8t||0;y+=el.8G||0;el=el.dJ}E{x:x,y:y}},2o:u(e){D w=k.B(e,\'Z\');D h=k.B(e,\'W\');D 1C=0;D hb=0;D es=e.14;if(k(e).B(\'19\')!=\'1o\'){1C=e.4c;hb=e.5W}P{D 5Y=es.3n;D 9q=es.Y;es.3n=\'2K\';es.19=\'2B\';es.Y=\'1P\';1C=e.4c;hb=e.5W;es.19=\'1o\';es.Y=9q;es.3n=5Y}E{w:w,h:h,1C:1C,hb:hb}},74:u(el){E{1C:el.4c||0,hb:el.5W||0}},bm:u(e){D h,w,de;if(e){w=e.8W;h=e.8O}P{de=1h.5d;w=1X.d4||aa.d4||(de&&de.8W)||1h.2e.8W;h=1X.cB||aa.cB||(de&&de.8O)||1h.2e.8O}E{w:w,h:h}},6z:u(e){D t=0,l=0,w=0,h=0,iw=0,ih=0;if(e&&e.9N.6c()!=\'2e\'){t=e.3d;l=e.3c;w=e.d7;h=e.d2;iw=0;ih=0}P{if(1h.5d){t=1h.5d.3d;l=1h.5d.3c;w=1h.5d.d7;h=1h.5d.d2}P if(1h.2e){t=1h.2e.3d;l=1h.2e.3c;w=1h.2e.d7;h=1h.2e.d2}iw=aa.d4||1h.5d.8W||1h.2e.8W||0;ih=aa.cB||1h.5d.8O||1h.2e.8O||0}E{t:t,l:l,w:w,h:h,iw:iw,ih:ih}},cy:u(e,7N){D el=k(e);D t=el.B(\'5K\')||\'\';D r=el.B(\'5z\')||\'\';D b=el.B(\'5k\')||\'\';D l=el.B(\'5j\')||\'\';if(7N)E{t:T(t)||0,r:T(r)||0,b:T(b)||0,l:T(l)};P E{t:t,r:r,b:b,l:l}},aT:u(e,7N){D el=k(e);D t=el.B(\'5M\')||\'\';D r=el.B(\'5U\')||\'\';D b=el.B(\'5n\')||\'\';D l=el.B(\'4X\')||\'\';if(7N)E{t:T(t)||0,r:T(r)||0,b:T(b)||0,l:T(l)};P E{t:t,r:r,b:b,l:l}},6U:u(e,7N){D el=k(e);D t=el.B(\'4S\')||\'\';D r=el.B(\'5O\')||\'\';D b=el.B(\'5Q\')||\'\';D l=el.B(\'5b\')||\'\';if(7N)E{t:T(t)||0,r:T(r)||0,b:T(b)||0,l:T(l)||0};P E{t:t,r:r,b:b,l:l}},4a:u(2k){D x=2k.hT||(2k.gM+(1h.5d.3c||1h.2e.3c))||0;D y=2k.ki||(2k.iQ+(1h.5d.3d||1h.2e.3d))||0;E{x:x,y:y}},cI:u(4R,cx){cx(4R);4R=4R.7c;7d(4R){k.1a.cI(4R,cx);4R=4R.hQ}},h7:u(4R){k.1a.cI(4R,u(el){24(D 1p in el){if(2g el[1p]===\'u\'){el[1p]=S}}})},hV:u(el,1O){D 5l=k.1a.6z();D b6=k.1a.2o(el);if(!1O||1O==\'49\')k(el).B({Q:5l.t+((18.3r(5l.h,5l.ih)-5l.t-b6.hb)/2)+\'U\'});if(!1O||1O==\'4j\')k(el).B({O:5l.l+((18.3r(5l.w,5l.iw)-5l.l-b6.1C)/2)+\'U\'})},hW:u(el,dk){D 1Q=k(\'1T[@2J*="8X"]\',el||1h),8X;1Q.1E(u(){8X=q.2J;q.2J=dk;q.14.5E="9n:9w.9y.hE(2J=\'"+8X+"\')"})}};[].3J||(7F.hF.3J=u(v,n){n=(n==S)?0:n;D m=q.1g;24(D i=n;i<m;i++)if(q[i]==v)E i;E-1});',62,1293,'||||||||||||||||||||jQuery||||||this||||function||||||dragCfg|css|elm|var|return|dragged|easing|speed|false|callback|get|ss|options|iAuto|left|else|top|iResize|null|parseInt|px|oldStyle|height|slideshow|position|width||iDrag|new||style||||Math|display|iUtil|true|helper|subject|case|autoCFG|length|document|dropCfg|iEL|resizeOptions|carouselCfg|duration|interfaceFX|none|attr|sizes|break|pointer|iSort|type|ImageBox|queue|iDrop|iAutoscroller|slide|resizeElement|oC|wb|apply|each|fisheyeCfg|opacity|delta|newSizes|bind|constructor|custom|pos|size|axis|absolute|images|items|append|img|slideslinks|255|firstNum|window|show|container||complete|div|extend|for||start||cont|elsToScroll|100|loader|oR||body|elem|typeof|selectedItem|oldP|props|event|accordionCfg|parseFloat|field|getSize|containment|ny|build|relative|iTooltip|islideshow|nx|tp|slideCaption|value|newPosition|Function|block|selectHelper|step|border|itemWidth|hide|dequeue|timer|src|hidden|right|limit|nr|fractions|0px|PI|addClass|direction|end|overflow|cursorAt|result|parentData|onShow|onChange|to|parentNode|||||||||browser|iSlider|scrollLeft|scrollTop|scr|transferHelper|text|href|onHide|pre|selectdrug|className|switch|visibility|item|wrapper|unbind|max|nextslide|values|currentslide|handle|getPosition|html|newCoords|prevslide|iframe|iExpander|accept|mousemove|canvas|createElement|margins|onSlide|zIndex|indexOf|pressedKey|min|valueToAdd|multipleSeparator|pageSize|zones|highlighted|toggle|abs|onStop|dragElem|times|fadeDuration|diff|dhs|handlers||resizeDirection||vp|so|distance|ghosting||test|vertically|getPointer|startTop|offsetWidth|subjectValue|lastSuggestion|DropOutDirectiont|title|wrs|removeClass|horizontally|startLeft|out|onDrag|oP|onStart|nWidth|percent|down|ifxFirstDisplay|msie|iteration|ratio|clear|color|lastValue|slideCfg|fontSize|currentPointer|dimm|bottom|replace|up|prevImage|tooltipCFG|rel|els|fxCheckTag|context|nextImage|params|shs|fieldData|elToScroll|nodeEl|borderTopWidth|chunks|destroy|string|nHeight|paddingLeft|tagName|currentStyle||halign|slidePos|onclick|delay||containerW|from|helperclass|endLeft|endTop|borderLeftWidth|dragmoveBy|documentElement|dhe|newStyles|clonedEl|click|si|marginLeft|marginBottom|clientScroll|OpenClose|paddingBottom|empty|toWrite|selectionStart|overzone|toAdd|onDragModifier|holder|mousedown|animate|toDrag|cnt|marginRight|linksPosition|blur|getAttribute|hight|filter|sw|zoney|cos|slideshows|zonex|marginTop|collected|paddingTop|url|borderRightWidth|mouseup|borderBottomWidth|activeLinkClass|dragHandle|clearInterval|paddingRight|sortCfg|offsetHeight|prop|oldVisibility|styles||BlindDirection|point|fxh|nmp|old|post|currentPanel|onSelect|elementData|grid|pow|toLowerCase|animationHandler|cur|containerH|close|puff|getWidth|currentRel|imageEl|Expander|getHeight|iFisheye|random|newDimensions|itemHeight|reflections|sliders|selRange|wr|orig|margin|maxWidth|keyup|getScroll|captionText|totalImages|128|parseColor|curCSS|outerContainer|Scale|restore|tolerance|selection|focus|caption|snapDistance|revert|current|3000|captionPosition|hpc|onload|class|getBorder|setInterval|oldStyleAttr|rule|rgb|open|minLeft|ActiveXObject|oldDisplay|restoreStyle|getSizeLite||nw|0x||F0|fadeOut|focused|firstChild|while|cssRules|fadeIn|Date|minTop|backgroundColor|sc|nbsp|hash|captionEl|selectKeyHelper|selectCurrent|newTop|init|newLeft|changed|Draggable|inFrontOf|efx|139|onHover|onOut|getTime|np|keydown|split|radiusY|increment|Array|getPositionLite|selectClass|opera|onHighlight|keyCode|charCode|Object|toInteger|frameClass|hasTabsEnabled|zonew|user|zoneh|positionItems|onClick|oD|scrollIntoView|accordionPos|proximity|indic||data|containerSize|sin|iTTabs||ts|ImageBoxPrevImage|ImageBoxNextImage|imageSrc|newPos|maxHeight|minHeight|elS|activeClass|panels|maxBottom|maxRight|ser|move|opened|bounceout|animationInProgress|overlay|stop|reflectionSize|fnc|classname|insideParent|offsetLeft|jEl|nRy|pr|serialize|nRx|tooltipHelper|cssSides|mouseout|select|count|namedColors|padding|offsetTop|directionIncrement|parentEl|400|dir|expand|createTextNode|finishedPre|clientHeight|li|applyOn|content|contBorders|object|parentBorders|alpha|clientWidth|png|gallery|fontWeight|link|yproc|xproc|sx|parent|showImage|selectedone|imgs|onselect|sy|startDrag|cursor|captionClass|onselectstop|getElementById|linksClass|sh|ul|onActivate|isDroppable|nextEl|onDrop|oldTitle|progid|prevslideClass|prevEl|oldPosition|SliderContainer|Image|linkRel|selectKeyUp|selectKeyDown|DXImageTransform|inCache|Microsoft|mouseover|dragstop|diffX|211|nextslideClass|prot|auto|dEs|hidehelper|isDraggable|activeclass|unit|DoFold|unfold|nodeName|startTime|buildWrapper|prev|1px|oldColor|setTimeout|ScrollTo|st|sl|cssText|9999|next|destroyWrapper|opt|diffHeight|diffWidth|exec|hoverclass|image|blind|borderColor|sideEnd|self|key||default|2000|styleSheets|getValues|192|diffY|lnk|reflexions|checkhover|selectcheck|maxRotation|ImageBoxOuterContainer|gradient|panelHeight|childs|headers|ne|hideImage|minWidth|iIndex|itemsText|os|side|iCarousel|5625|1000|itemMinWidth|linksSeparator|setSelectionRange|protectRotation|positionContainer|posx|hoverClass|valToAdd|minchars|helperClass|source|nextImageEl|preventDefault|multiple|headerSelector|DraggableDestroy|getPadding|autofill|handleEl|stopPropagation|prevImageEl|getFieldValues|panelSelector|String|createTextRange|floats|lastSi|shrink|oPad|windowSize|paddingLeftSize|angle|paddingY|paddingX|RegExp|borderRightSize|floatVal|firstStep|pulse|Pulsate|Color|rotationSpeed|paddingBottomSize|remove|parseStyle|getClient|Number|helperSize|bounce|doTab||zoom|borderLeftSize|oBor|paddingRightSize|borderTopSize|paddingTopSize|stopAnim|pValue|borderBottomSize|extraWidth|restricted|autoSize|unselectable|SliderIteration|prepend|clearTimeout|isSlider|oneIsSortable|applyOnHover|tooltipURL|tabindex|draginit|mouse|restoreStyles|sliderSize|sliderPos|parentPos|cancelBubble|autocomplete|inputWidth|oldBorder|dragmove|clnt|sliderEl|returnValue|loaderWidth|idsa|letterSpacing|pause|getContainment|fade|snapToGrid|linear|10000|slideshowHolder|asin|cssSidesEnd|borderWidth|fitToContainer|TEXTAREA|entities|INPUT|spacer|writeItems|character|currentValue|paddings|169|oldFloat|borders|hidefocused|bouncein||modifyContainer|transparent|center|loadImage|func|getMargins|initialPosition|textAlign|innerHeight|Alpha|no|captionImages|closeEl|shake|prevTop|traverseDOM|Selectserialize|stopDrag|slider|ImageBoxCaption|ImageBoxIframe|300|ImageBoxOverlay|sortable|moveDrag|autoplay|measure|prevLeft|intersect|ImageBoxCurrentImage|selectstop|Shake|index|dragEl|keyPressed|scrollHeight|scroll|innerWidth|match|elPosition|scrollWidth|textImage|slideBor|jpg|captionSize|textImageFrom|visible||loaderHeight|ImageBoxCaptionImages||hoverItem|clickItem|emptyGIF||notColor|slideshowCaption|Droppable|goprev|childNodes|autocompleteHelper|autocompleteIframe|slidePad|fit|165|clientSize|||fontFamily|colorCssProps|elType|onhover|cssProps|expanderHelper|boxModel|itransferTo|keypress|moveStart|offsetParent|Width|selectstart|fxe|selectionEnd|checkCache|fontStyle|update|DroppableDestroy|remeasure|fontStretch|fontVariant|onblur|slideshowLoader|htmlEntities|wordSpacing|createRange|224|KhtmlUserSelect||closeHTML|on|sortHelper|245|userSelect|dragHelper|hrefAttr|dragstart|107|loaderSRC|highlight|slideshowPrevslide||gonext||styleFloat|frameborder|javascript|||relAttr|wid|scrolling||onslide|||listStyle|imageTypes|insertBefore|999|textDecoration|sqrt|140|230|maxy|240|ImageBoxContainer|doScroll|interval|set|dragmoveByKey|protect|ImageBoxCaptionText|144|ImageBoxLoader|off|checkdrop|isSelectable|hlt|30px|selectedclass|tooltipTitle|imagebox|shc|overlayOpacity|selRange2|slideshowNextSlide|gif|getSelectionStart|360|iAccordion|getElementsByTagName|iBounce|after|SortableAddItem|onResize|150|itemZIndex|grow|getHeightMinMax|borderTopUnit|selectcheckApply|borderRightUnit|zindex|fontUnit|togglehor|time|se|parte|easeout|isSortable||SlideInUp|fold|SlideOutUp|rgba|addColorStop|yfrac|containerMaxx|interfaceColorFX|containerMaxy||leftUnit|mousex||radiusX|check|getContext|xfrac|addItem|topUnit|fracH|cloneNode|togglever|paddingLeftUnit|borderBottomUnit|finish|onDragStop|onout|posy|isFunction|oldOverflow|directions|vertical|fracW|fakeAccordionClass|parts|fadeTo|inputValue|xml|selectstopApply|slideshowLinks|onDragStart|BlindUp|paddingTopUnit|500|trim|maxx|borderLeftUnit|paddingRightUnit|filteredPosition|BlindDown|paddingBottomUnit|horizontal|valign|find|ImageBoxClose|onselectstart|mozUserSelect|ondragstart|scale|110|globalCompositeOperation|bmp||drawImage|ondrop|password|quot||save|starty|jpeg|||number|startx|finishOpacity|hover|recallDroppables|flipv|finishx|destination|khtml|moz|lt|amp|pW|clientX|Accordion|translate|captiontext|elasticin|slideshowLink|fix|elasticout|resize|elasticboth|bounceboth|984375|9375|Selectable|30002|list|625|30001|nodeValue|before|100000|purgeEvents|substr|duplicate|moveEnd|||substring|success|param|par|array|Fisheye|name|POST|ajax|easeboth|location|fromHandler|collapse|MozUserSelect||ResizableDestroy|rotationTimer|fillRect|fill|WebKit|fillStyle|createLinearGradient|Resizable|navigator|appVersion|lineHeigt|alt|AlphaImageLoader|prototype|SliderGetValues|DisableTabs|Carousel|load|easein|IMG|200|Slider|ToolTip|wh|nextSibling|Autocomplete|SliderSetValues|pageX|float|centerEl|fixPNG|isNaN|dotted|dashed|stopAll|Left|outlineColor|Top|Right|Bottom|solid|double|selectorText|rules|onchange|SlideToggleRight|SlideOutRight||borderStyle||TransferTo||groove|ridge|inset|outset|borderTopColor||borderRightColor|olive|navy|orange||pink|203|maroon||magenta|182|193|lightyellow|lime|purple|red|outlineOffset|outlineWidth|borderBottomColor|borderLeftColor|lineHeight|loading|silver|white|yellow|Showing|100000000|SlideInRight|clientY|Highlight|SortableDestroy|CloseVertically|CloseHorizontally|FoldToggle|UnFold|SlideInDown|SlideToggleUp|SortSerialize|Fold|SwitchHorizontally|SwitchVertically|Sortable|scrollTo|EnableTabs|ScrollToAnchors|pt|Puff|OpenVertically|OpenHorizontally|Grow|Shrink|DropToggleRight|DropInRight|BlindToggleHorizontally|BlindRight|http|Bounce|120|BlindLeft|BlindToggleVertically|SlideToggleLeft|SlideOutLeft|toUpperCase|SlideInLeft|SlideToggleDown|SlideOutDown|DropOutLeft|DropInLeft|DropToggleLeft|DropOutRight|DropToggleUp|DropInUp|DropOutDown|DropInDown|DropToggleDown|DropOutUp|lightpink|textIndent|aqua|appendChild|azure|beige|220|last|cssFloat|first|ol|wrapEl|fxWrapper|black|imageLoaded|darkkhaki|darkgreen|189|183|darkmagenta|firstResize|darkgrey|brown|cyan|darkblue|darkcyan|table|form|col|tfoot|colgroup|th|header|thead|tbody|112|Autoexpand|tr|td|script|frame|input|pageY|textarea|button|w_|removeChild|frameset|option|optgroup|meta|darkolivegreen|blue|122|233|green|lightcyan|204|darkviolet|lightgreen|indigo|216|khaki|darksalmon|130|darkred|lightblue|148|173|215|238|fuchsia|gold|darkorchid|153|darkorange|lightgrey'.split('|'),0,{}))
diff -ruN 2.0.5/wp-includes/js/jquery/jquery.form.js 2.2.2/wp-includes/js/jquery/jquery.form.js
--- 2.0.5/wp-includes/js/jquery/jquery.form.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/jquery/jquery.form.js	2007-03-02 17:26:35.000000000 -0600
@@ -0,0 +1,644 @@
+/*
+ * jQuery form plugin
+ * @requires jQuery v1.0.3
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id$
+ * Version: 0.9
+ */
+
+/**
+ * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
+ *
+ * ajaxSubmit accepts a single argument which can be either a success callback function
+ * or an options Object.  If a function is provided it will be invoked upon successful
+ * completion of the submit and will be passed the response from the server.
+ * If an options Object is provided, the following attributes are supported:
+ *
+ *  target:   Identifies the element(s) in the page to be updated with the server response.
+ *            This value may be specified as a jQuery selection string, a jQuery object,
+ *            or a DOM element.
+ *            default value: null
+ *
+ *  url:      URL to which the form data will be submitted.
+ *            default value: value of form's 'action' attribute
+ *
+ *  method:   @deprecated use 'type'
+ *  type:     The method in which the form data should be submitted, 'GET' or 'POST'.
+ *            default value: value of form's 'method' attribute (or 'GET' if none found)
+ *
+ *  before:   @deprecated use 'beforeSubmit'
+ *  beforeSubmit:  Callback method to be invoked before the form is submitted.
+ *            default value: null
+ *
+ *  after:    @deprecated use 'success'
+ *  success:  Callback method to be invoked after the form has been successfully submitted
+ *            and the response has been returned from the server
+ *            default value: null
+ *
+ *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json'
+ *            default value: null
+ *
+ *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
+ *            default value: false
+ *
+ *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
+ *
+ *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
+ *
+ *
+ * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
+ * validating the form data.  If the 'beforeSubmit' callback returns false then the form will
+ * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
+ * in array format, the jQuery object, and the options object passed into ajaxSubmit.
+ * The form data array takes the following form:
+ *
+ *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * If a 'success' callback method is provided it is invoked after the response has been returned
+ * from the server.  It is passed the responseText or responseXML value (depending on dataType).
+ * See jQuery.ajax for further details.
+ *
+ *
+ * The dataType option provides a means for specifying how the server response should be handled.
+ * This maps directly to the jQuery.httpData method.  The following values are supported:
+ *
+ *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'after'
+ *                   callback method, if specified, will be passed the responseXML value
+ *      'json':   if dataType == 'json' the server response will be evaluted and passed to
+ *                   the 'after' callback, if specified
+ *      'script': if dataType == 'script' the server response is evaluated in the global context
+ *
+ *
+ * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both
+ * are provided the target will be ignored.
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * This is normally true anyway, unless the form contains input elements of type='image'.
+ * If your form must be submitted with name/value pairs in semantic order and your form
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
+ * (or nothing) to avoid the overhead for this logic.
+ *
+ *
+ * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
+ *
+ * $("#form-id").submit(function() {
+ *     $(this).ajaxSubmit(options);
+ *     return false; // cancel conventional submit
+ * });
+ *
+ * When using ajaxForm(), however, this is done for you.
+ *
+ * @example
+ * $('#myForm').ajaxSubmit(function(data) {
+ *     alert('Form submit succeeded! Server returned: ' + data);
+ * });
+ * @desc Submit form and alert server response
+ *
+ *
+ * @example
+ * var options = {
+ *     target: '#myTargetDiv'
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Submit form and update page element with server response
+ *
+ *
+ * @example
+ * var options = {
+ *     success: function(responseText) {
+ *         alert(responseText);
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Submit form and alert the server response
+ *
+ *
+ * @example
+ * var options = {
+ *     beforeSubmit: function(formArray, jqForm) {
+ *         if (formArray.length == 0) {
+ *             alert('Please enter data.');
+ *             return false;
+ *         }
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Pre-submit validation which aborts the submit operation if form data is empty
+ *
+ *
+ * @example
+ * var options = {
+ *     url: myJsonUrl.php,
+ *     dataType: 'json',
+ *     success: function(data) {
+ *        // 'data' is an object representing the the evaluated json data
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc json data returned and evaluated
+ *
+ *
+ * @example
+ * var options = {
+ *     url: myXmlUrl.php,
+ *     dataType: 'xml',
+ *     success: function(responseXML) {
+ *        // responseXML is XML document object
+ *        var data = $('myElement', responseXML).text();
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc XML data returned from server
+ *
+ *
+ * @example
+ * var options = {
+ *     resetForm: true
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc submit form and reset it if successful
+ *
+ * @example
+ * $('#myForm).submit(function() {
+ *    $(this).ajaxSubmit();
+ *    return false;
+ * });
+ * @desc Bind form's submit event to use ajaxSubmit
+ *
+ *
+ * @name ajaxSubmit
+ * @type jQuery
+ * @param options  object literal containing options which control the form submission process
+ * @cat Plugins/Form
+ * @return jQuery
+ * @see formToArray
+ * @see ajaxForm
+ * @see $.ajax
+ * @author jQuery Community
+ */
+jQuery.fn.ajaxSubmit = function(options) {
+    if (typeof options == 'function')
+        options = { success: options };
+
+    options = jQuery.extend({
+        url:    this.attr('action') || '',
+        method: this.attr('method') || 'GET'
+    }, options || {});
+
+    // remap deprecated options (temporarily)
+    options.success = options.success || options.after;
+    options.beforeSubmit = options.beforeSubmit || options.before;
+    options.type = options.type || options.method;
+
+    var a = this.formToArray(options.semantic);
+
+    // give pre-submit callback an opportunity to abort the submit
+    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
+
+    var q = jQuery.param(a);
+
+    if (options.type.toUpperCase() == 'GET') {
+        // if url already has a '?' then append args after '&'
+        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
+        options.data = null;  // data is null for 'get'
+    }
+    else
+        options.data = q; // data is the query string for 'post'
+
+    var $form = this, callbacks = [];
+    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
+    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
+
+    // perform a load on the target only if dataType is not provided
+    if (!options.dataType && options.target) {
+        var oldSuccess = options.success || function(){};
+        callbacks.push(function(data, status) {
+            jQuery(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, [data, status]);
+        });
+    }
+    else if (options.success)
+        callbacks.push(options.success);
+
+    options.success = function(data, status) {
+        for (var i=0, max=callbacks.length; i < max; i++)
+            callbacks[i](data, status);
+    };
+
+    jQuery.ajax(options);
+    return this;
+};
+
+/**
+ * ajaxForm() provides a mechanism for fully automating form submission.
+ *
+ * The advantages of using this method instead of ajaxSubmit() are:
+ *
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
+ *    is used to submit the form).
+ * 2. This method will include the submit element's name/value data (for the element that was
+ *    used to submit the form).
+ * 3. This method binds the submit() method to the form for you.
+ *
+ * Note that for accurate x/y coordinates of image submit elements in all browsers
+ * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
+ *
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
+ * passes the options argument along after properly binding events for submit elements and
+ * the form itself.  See ajaxSubmit for a full description of the options argument.
+ *
+ *
+ * @example
+ * var options = {
+ *     target: '#myTargetDiv'
+ * };
+ * $('#myForm').ajaxSForm(options);
+ * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
+ *       when the form is submitted.
+ *
+ *
+ * @example
+ * var options = {
+ *     success: function(responseText) {
+ *         alert(responseText);
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Bind form's submit event so that server response is alerted after the form is submitted.
+ *
+ *
+ * @example
+ * var options = {
+ *     beforeSubmit: function(formArray, jqForm) {
+ *         if (formArray.length == 0) {
+ *             alert('Please enter data.');
+ *             return false;
+ *         }
+ *     }
+ * };
+ * $('#myForm').ajaxSubmit(options);
+ * @desc Bind form's submit event so that pre-submit callback is invoked before the form
+ *       is submitted.
+ *
+ *
+ * @name   ajaxForm
+ * @param  options  object literal containing options which control the form submission process
+ * @return jQuery
+ * @cat    Plugins/Form
+ * @type   jQuery
+ * @see    ajaxSubmit
+ * @author jQuery Community
+ */
+jQuery.fn.ajaxForm = function(options) {
+    return this.each(function() {
+        jQuery("input:submit,input:image,button:submit", this).click(function(ev) {
+            var $form = this.form;
+            $form.clk = this;
+            if (this.type == 'image') {
+                if (ev.offsetX != undefined) {
+                    $form.clk_x = ev.offsetX;
+                    $form.clk_y = ev.offsetY;
+                } else if (typeof jQuery.fn.offset == 'function') { // try to use dimensions plugin
+                    var offset = jQuery(this).offset();
+                    $form.clk_x = ev.pageX - offset.left;
+                    $form.clk_y = ev.pageY - offset.top;
+                } else {
+                    $form.clk_x = ev.pageX - this.offsetLeft;
+                    $form.clk_y = ev.pageY - this.offsetTop;
+                }
+            }
+            // clear form vars
+            setTimeout(function() {
+                $form.clk = $form.clk_x = $form.clk_y = null;
+                }, 10);
+        })
+    }).submit(function(e) {
+        jQuery(this).ajaxSubmit(options);
+        return false;
+    });
+};
+
+
+/**
+ * formToArray() gathers form element data into an array of objects that can
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
+ * Each object in the array has both a 'name' and 'value' property.  An example of
+ * an array for a simple login form might be:
+ *
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
+ *
+ * It is this array that is passed to pre-submit callback functions provided to the
+ * ajaxSubmit() and ajaxForm() methods.
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * This is normally true anyway, unless the form contains input elements of type='image'.
+ * If your form must be submitted with name/value pairs in semantic order and your form
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
+ * (or nothing) to avoid the overhead for this logic.
+ *
+ * @example var data = $("#myForm").formToArray();
+ * $.post( "myscript.cgi", data );
+ * @desc Collect all the data from a form and submit it to the server.
+ *
+ * @name formToArray
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type Array<Object>
+ * @cat Plugins/Form
+ * @see ajaxForm
+ * @see ajaxSubmit
+ * @author jQuery Community
+ */
+jQuery.fn.formToArray = function(semantic) {
+    var a = [];
+    if (this.length == 0) return a;
+
+    var form = this[0];
+    var els = semantic ? form.getElementsByTagName('*') : form.elements;
+    if (!els) return a;
+    for(var i=0, max=els.length; i < max; i++) {
+        var el = els[i];
+        var n = el.name;
+        if (!n) continue;
+
+        if (semantic && form.clk && el.type == "image") {
+            // handle image inputs on the fly when semantic == true
+            if(!el.disabled && form.clk == el)
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+            continue;
+        }
+        var v = jQuery.fieldValue(el, true);
+        if (v === null) continue;
+        if (v.constructor == Array) {
+            for(var j=0, jmax=v.length; j < jmax; j++)
+                a.push({name: n, value: v[j]});
+        }
+        else
+            a.push({name: n, value: v});
+    }
+
+    if (!semantic && form.clk) {
+        // input type=='image' are not found in elements array! handle them here
+        var inputs = form.getElementsByTagName("input");
+        for(var i=0, max=inputs.length; i < max; i++) {
+            var input = inputs[i];
+            var n = input.name;
+            if(n && !input.disabled && input.type == "image" && form.clk == input)
+                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
+        }
+    }
+    return a;
+};
+
+
+/**
+ * Serializes form data into a 'submittable' string. This method will return a string
+ * in the format: name1=value1&amp;name2=value2
+ *
+ * The semantic argument can be used to force form serialization in semantic order.
+ * If your form must be submitted with name/value pairs in semantic order then pass
+ * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
+ * this logic (which can be significant for very large forms).
+ *
+ * @example var data = $("#myForm").formSerialize();
+ * $.ajax('POST', "myscript.cgi", data);
+ * @desc Collect all the data from a form into a single string
+ *
+ * @name formSerialize
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
+ * @type String
+ * @cat Plugins/Form
+ * @see formToArray
+ * @author jQuery Community
+ */
+jQuery.fn.formSerialize = function(semantic) {
+    //hand off to jQuery.param for proper encoding
+    return jQuery.param(this.formToArray(semantic));
+};
+
+
+/**
+ * Serializes all field elements in the jQuery object into a query string.
+ * This method will return a string in the format: name1=value1&amp;name2=value2
+ *
+ * The successful argument controls whether or not serialization is limited to
+ * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.
+ *
+ * @example var data = $("input").formSerialize();
+ * @desc Collect the data from all successful input elements into a query string
+ *
+ * @example var data = $(":radio").formSerialize();
+ * @desc Collect the data from all successful radio input elements into a query string
+ *
+ * @example var data = $("#myForm :checkbox").formSerialize();
+ * @desc Collect the data from all successful checkbox input elements in myForm into a query string
+ *
+ * @example var data = $("#myForm :checkbox").formSerialize(false);
+ * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
+ *
+ * @example var data = $(":input").formSerialize();
+ * @desc Collect the data from all successful input, select, textarea and button elements into a query string
+ *
+ * @name fieldSerialize
+ * @param successful true if only successful controls should be serialized (default is true)
+ * @type String
+ * @cat Plugins/Form
+ */
+jQuery.fn.fieldSerialize = function(successful) {
+    var a = [];
+    this.each(function() {
+        var n = this.name;
+        if (!n) return;
+        var v = jQuery.fieldValue(this, successful);
+        if (v && v.constructor == Array) {
+            for (var i=0,max=v.length; i < max; i++)
+                a.push({name: n, value: v[i]});
+        }
+        else if (v !== null && typeof v != 'undefined')
+            a.push({name: this.name, value: v});
+    });
+    //hand off to jQuery.param for proper encoding
+    return jQuery.param(a);
+};
+
+
+/**
+ * Returns the value of the field element in the jQuery object.  If there is more than one field element
+ * in the jQuery object the value of the first successful one is returned.
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If this value is false then
+ * the value of the first field element in the jQuery object is returned.
+ *
+ * Note: If no valid value can be determined the return value will be undifined.
+ *
+ * Note: The fieldValue returned for a select-multiple element or for a checkbox input will
+ *       always be an array if it is not undefined.
+ *
+ *
+ * @example var data = $("#myPasswordElement").formValue();
+ * @desc Gets the current value of the myPasswordElement element
+ *
+ * @example var data = $("#myForm :input").formValue();
+ * @desc Get the value of the first successful control in the jQuery object.
+ *
+ * @example var data = $("#myForm :checkbox").formValue();
+ * @desc Get the array of values for the first set of successful checkbox controls in the jQuery object.
+ *
+ * @example var data = $("#mySingleSelect").formValue();
+ * @desc Get the value of the select control
+ *
+ * @example var data = $("#myMultiSelect").formValue();
+ * @desc Get the array of selected values for the select-multiple control
+ *
+ * @name fieldValue
+ * @param Boolean successful true if value returned must be for a successful controls (default is true)
+ * @type String or Array<String>
+ * @cat Plugins/Form
+ */
+jQuery.fn.fieldValue = function(successful) {
+    var cbVal, cbName;
+
+    // loop until we find a value
+    for (var i=0, max=this.length; i < max; i++) {
+        var el = this[i];
+        var v = jQuery.fieldValue(el, successful);
+        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
+            continue;
+
+        // for checkboxes, consider multiple elements, for everything else just return first valid value
+        if (el.type != 'checkbox') return v;
+
+        cbName = cbName || el.name;
+        if (cbName != el.name) // return if we hit a checkbox with a different name
+            return cbVal;
+        cbVal = cbVal || [];
+        cbVal.push(v);
+    }
+    return cbVal;
+};
+
+/**
+ * Returns the value of the field element.
+ *
+ * The successful argument controls whether or not the field element must be 'successful'
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
+ * The default value of the successful argument is true.  If the given element is not
+ * successful and the successful arg is not false then the returned value will be null.
+ *
+ * Note: The fieldValue returned for a select-multiple element will always be an array.
+ *
+ * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
+ * @desc Gets the current value of the myPasswordElement element
+ *
+ * @name fieldValue
+ * @param Element el The DOM element for which the value will be returned
+ * @param Boolean successful true if value returned must be for a successful controls (default is true)
+ * @type String or Array<String>
+ * @cat Plugins/Form
+ */
+jQuery.fieldValue = function(el, successful) {
+    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
+    if (typeof successful == 'undefined') successful = true;
+
+    if (successful && ( !n || el.disabled || t == 'reset' ||
+        (t == 'checkbox' || t == 'radio') && !el.checked ||
+        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
+        tag == 'select' && el.selectedIndex == -1))
+            return null;
+
+    if (tag == 'select') {
+        var index = el.selectedIndex;
+        if (index < 0) return null;
+        var a = [], ops = el.options;
+        var one = (t == 'select-one');
+        var max = (one ? index+1 : ops.length);
+        for(var i=(one ? index : 0); i < max; i++) {
+            var op = ops[i];
+            if (op.selected) {
+                // extra pain for IE...
+                var v = jQuery.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
+                if (one) return v;
+                a.push(v);
+            }
+        }
+        return a;
+    }
+    return el.value;
+};
+
+
+/**
+ * Clears the form data.  Takes the following actions on the form's input fields:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ * @example $('form').clearForm();
+ * @desc Clears all forms on the page.
+ *
+ * @name clearForm
+ * @type jQuery
+ * @cat Plugins/Form
+ * @see resetForm
+ */
+jQuery.fn.clearForm = function() {
+    return this.each(function() {
+        jQuery('input,select,textarea', this).clearFields();
+    });
+};
+
+/**
+ * Clears the selected form elements.  Takes the following actions on the matched elements:
+ *  - input text fields will have their 'value' property set to the empty string
+ *  - select elements will have their 'selectedIndex' property set to -1
+ *  - checkbox and radio inputs will have their 'checked' property set to false
+ *  - inputs of type submit, button, reset, and hidden will *not* be effected
+ *  - button elements will *not* be effected
+ *
+ * @example $('.myInputs').clearFields();
+ * @desc Clears all inputs with class myInputs
+ *
+ * @name clearFields
+ * @type jQuery
+ * @cat Plugins/Form
+ * @see clearForm
+ */
+jQuery.fn.clearFields = jQuery.fn.clearInputs = function() {
+    return this.each(function() {
+        var t = this.type, tag = this.tagName.toLowerCase();
+        if (t == 'text' || t == 'password' || tag == 'textarea')
+            this.value = '';
+        else if (t == 'checkbox' || t == 'radio')
+            this.checked = false;
+        else if (tag == 'select')
+            this.selectedIndex = -1;
+    });
+};
+
+
+/**
+ * Resets the form data.  Causes all form elements to be reset to their original value.
+ *
+ * @example $('form').resetForm();
+ * @desc Resets all forms on the page.
+ *
+ * @name resetForm
+ * @type jQuery
+ * @cat Plugins/Form
+ * @see clearForm
+ */
+jQuery.fn.resetForm = function() {
+    return this.each(function() {
+        // guard against an input with the name of 'reset'
+        // note that IE reports the reset function as an 'object'
+        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
+            this.reset();
+    });
+};
diff -ruN 2.0.5/wp-includes/js/jquery/jquery.js 2.2.2/wp-includes/js/jquery/jquery.js
--- 2.0.5/wp-includes/js/jquery/jquery.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/jquery/jquery.js	2007-03-03 11:55:36.000000000 -0600
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('7(1C 1w.6=="T"){1w.T=1w.T;B 6=u(a,c){7(1w==q)v 1p 6(a,c);a=a||17;7(6.1t(a))v 1p 6(17)[6.E.27?"27":"2O"](a);7(1C a=="23"){B m=/^[^<]*(<(.|\\s)+>)[^>]*$/.2Q(a);7(m)a=6.3k([m[1]]);J v 1p 6(c).2o(a)}v q.6r(a.1l==2y&&a||(a.3Y||a.I&&a!=1w&&!a.24&&a[0]!=T&&a[0].24)&&6.3M(a)||[a])};7(1C $!="T")6.2S$=$;B $=6;6.E=6.8p={3Y:"1.1.2",8q:u(){v q.I},I:0,2b:u(1T){v 1T==T?6.3M(q):q[1T]},2r:u(a){B L=6(a);L.6p=q;v L},6r:u(a){q.I=0;[].1g.14(q,a);v q},K:u(E,1E){v 6.K(q,E,1E)},2h:u(1c){B 4c=-1;q.K(u(i){7(q==1c)4c=i});v 4c},1I:u(1Y,O,C){B 1c=1Y;7(1Y.1l==3t)7(O==T)v q.I&&6[C||"1I"](q[0],1Y)||T;J{1c={};1c[1Y]=O}v q.K(u(2h){P(B H 1x 1c)6.1I(C?q.1q:q,H,6.H(q,1c[H],C,2h,H))})},1m:u(1Y,O){v q.1I(1Y,O,"30")},2L:u(e){7(1C e=="23")v q.3u().3r(17.8t(e));B t="";6.K(e||q,u(){6.K(q.2I,u(){7(q.24!=8)t+=q.24!=1?q.60:6.E.2L([q])})});v t},2K:u(){B a=6.3k(1A);v q.K(u(){B b=a[0].3l(U);q.11.2X(b,q);22(b.1b)b=b.1b;b.4C(q)})},3r:u(){v q.3j(1A,U,1,u(a){q.4C(a)})},5i:u(){v q.3j(1A,U,-1,u(a){q.2X(a,q.1b)})},5j:u(){v q.3j(1A,12,1,u(a){q.11.2X(a,q)})},5t:u(){v q.3j(1A,12,-1,u(a){q.11.2X(a,q.2e)})},4g:u(){v q.6p||6([])},2o:u(t){v q.2r(6.31(q,u(a){v 6.2o(t,a)}),t)},4Y:u(4N){v q.2r(6.31(q,u(a){B a=a.3l(4N!=T?4N:U);a.$1H=16;v a}))},1D:u(t){v q.2r(6.1t(t)&&6.2q(q,u(2z,2h){v t.14(2z,[2h])})||6.3z(t,q))},2g:u(t){v q.2r(t.1l==3t&&6.3z(t,q,U)||6.2q(q,u(a){v(t.1l==2y||t.3Y)?6.3y(a,t)<0:a!=t}))},1M:u(t){v q.2r(6.2k(q.2b(),t.1l==3t?6(t).2b():t.I!=T&&(!t.1f||t.1f=="8v")?t:[t]))},4l:u(1s){v 1s?6.1D(1s,q).r.I>0:12},1a:u(1a){v 1a==T?(q.I?q[0].O:16):q.1I("O",1a)},4U:u(1a){v 1a==T?(q.I?q[0].2t:16):q.3u().3r(1a)},3j:u(1E,1P,3Z,E){B 4Y=q.I>1;B a=6.3k(1E);7(3Z<0)a.8w();v q.K(u(){B 1c=q;7(1P&&6.1f(q,"1P")&&6.1f(a[0],"3m"))1c=q.5J("20")[0]||q.4C(17.6n("20"));6.K(a,u(){E.14(1c,[4Y?q.3l(U):q])})})}};6.1z=6.E.1z=u(){B 1O=1A[0],a=1;7(1A.I==1){1O=q;a=0}B H;22(H=1A[a++])P(B i 1x H)1O[i]=H[i];v 1O};6.1z({8x:u(){7(6.2S$)$=6.2S$;v 6},1t:u(E){v!!E&&1C E!="23"&&!E.1f&&1C E[0]=="T"&&/u/i.1n(E+"")},4B:u(D){v D.66&&D.5I&&!D.5I.64},1f:u(D,Y){v D.1f&&D.1f.3K()==Y.3K()},K:u(1c,E,1E){7(1c.I==T)P(B i 1x 1c)E.14(1c[i],1E||[i,1c[i]]);J P(B i=0,6q=1c.I;i<6q;i++)7(E.14(1c[i],1E||[i,1c[i]])===12)3O;v 1c},H:u(D,O,C,2h,H){7(6.1t(O))O=O.3n(D,[2h]);B 6s=/z-?2h|7P-?8A|1d|58|8B-?28/i;v O&&O.1l==3Q&&C=="30"&&!6s.1n(H)?O+"4S":O},19:{1M:u(D,c){6.K(c.3o(/\\s+/),u(i,Q){7(!6.19.2V(D.19,Q))D.19+=(D.19?" ":"")+Q})},2f:u(D,c){D.19=c?6.2q(D.19.3o(/\\s+/),u(Q){v!6.19.2V(c,Q)}).6t(" "):""},2V:u(t,c){t=t.19||t;c=c.1R(/([\\.\\\\\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:])/g,"\\\\$1");v t&&1p 4v("(^|\\\\s)"+c+"(\\\\s|$)").1n(t)}},4d:u(e,o,f){P(B i 1x o){e.1q["1N"+i]=e.1q[i];e.1q[i]=o[i]}f.14(e,[]);P(B i 1x o)e.1q[i]=e.1q["1N"+i]},1m:u(e,p){7(p=="28"||p=="3V"){B 1N={},46,3P,d=["7d","8C","8D","8E"];6.K(d,u(){1N["8F"+q]=0;1N["8G"+q+"8H"]=0});6.4d(e,1N,u(){7(6.1m(e,"1h")!="1Z"){46=e.8I;3P=e.8J}J{e=6(e.3l(U)).2o(":4j").5l("2Z").4g().1m({4n:"1G",45:"8K",1h:"2D",7I:"0",8M:"0"}).5z(e.11)[0];B 3d=6.1m(e.11,"45");7(3d==""||3d=="4b")e.11.1q.45="6x";46=e.6y;3P=e.6z;7(3d==""||3d=="4b")e.11.1q.45="4b";e.11.33(e)}});v p=="28"?46:3P}v 6.30(e,p)},30:u(D,H,53){B L;7(H=="1d"&&6.W.1j)v 6.1I(D.1q,"1d");7(H=="4h"||H=="2v")H=6.W.1j?"3T":"2v";7(!53&&D.1q[H])L=D.1q[H];J 7(17.44&&17.44.4W){7(H=="2v"||H=="3T")H="4h";H=H.1R(/([A-Z])/g,"-$1").4m();B Q=17.44.4W(D,16);7(Q)L=Q.55(H);J 7(H=="1h")L="1Z";J 6.4d(D,{1h:"2D"},u(){B c=17.44.4W(q,"");L=c&&c.55(H)||""})}J 7(D.51){B 56=H.1R(/\\-(\\w)/g,u(m,c){v c.3K()});L=D.51[H]||D.51[56]}v L},3k:u(a){B r=[];6.K(a,u(i,1r){7(!1r)v;7(1r.1l==3Q)1r=1r.6C();7(1C 1r=="23"){B s=6.35(1r),1V=17.6n("1V"),2i=[];B 2K=!s.18("<1u")&&[1,"<42>","</42>"]||(!s.18("<6D")||!s.18("<20")||!s.18("<6E"))&&[1,"<1P>","</1P>"]||!s.18("<3m")&&[2,"<1P><20>","</20></1P>"]||(!s.18("<6F")||!s.18("<6G"))&&[3,"<1P><20><3m>","</3m></20></1P>"]||[0,"",""];1V.2t=2K[1]+s+2K[2];22(2K[0]--)1V=1V.1b;7(6.W.1j){7(!s.18("<1P")&&s.18("<20")<0)2i=1V.1b&&1V.1b.2I;J 7(2K[1]=="<1P>"&&s.18("<20")<0)2i=1V.2I;P(B n=2i.I-1;n>=0;--n)7(6.1f(2i[n],"20")&&!2i[n].2I.I)2i[n].11.33(2i[n])}1r=[];P(B i=0,l=1V.2I.I;i<l;i++)1r.1g(1V.2I[i])}7(1r.I===0&&!6.1f(1r,"3w"))v;7(1r[0]==T||6.1f(1r,"3w"))r.1g(1r);J r=6.2k(r,1r)});v r},1I:u(D,Y,O){B 2j=6.4B(D)?{}:{"P":"6J","6L":"19","4h":6.W.1j?"3T":"2v",2v:6.W.1j?"3T":"2v",2t:"2t",19:"19",O:"O",2W:"2W",2Z:"2Z",89:"6N",2Y:"2Y"};7(Y=="1d"&&6.W.1j&&O!=T){D.58=1;v D.1D=D.1D.1R(/4i\\([^\\)]*\\)/6O,"")+(O==1?"":"4i(1d="+O*6g+")")}J 7(Y=="1d"&&6.W.1j)v D.1D?4T(D.1D.6P(/4i\\(1d=(.*)\\)/)[1])/6g:1;7(Y=="1d"&&6.W.3h&&O==1)O=0.6R;7(2j[Y]){7(O!=T)D[2j[Y]]=O;v D[2j[Y]]}J 7(O==T&&6.W.1j&&6.1f(D,"3w")&&(Y=="81"||Y=="80"))v D.6T(Y).60;J 7(D.66){7(O!=T)D.6V(Y,O);7(6.W.1j&&/5E|3e/.1n(Y)&&!6.4B(D))v D.36(Y,2);v D.36(Y)}J{Y=Y.1R(/-([a-z])/6W,u(z,b){v b.3K()});7(O!=T)D[Y]=O;v D[Y]}},35:u(t){v t.1R(/^\\s+|\\s+$/g,"")},3M:u(a){B r=[];7(a.1l!=2y)P(B i=0,2R=a.I;i<2R;i++)r.1g(a[i]);J r=a.3N(0);v r},3y:u(b,a){P(B i=0,2R=a.I;i<2R;i++)7(a[i]==b)v i;v-1},2k:u(2u,3H){B r=[].3N.3n(2u,0);P(B i=0,5b=3H.I;i<5b;i++)7(6.3y(3H[i],r)==-1)2u.1g(3H[i]);v 2u},2q:u(1U,E,4k){7(1C E=="23")E=1p 4w("a","i","v "+E);B 1i=[];P(B i=0,2z=1U.I;i<2z;i++)7(!4k&&E(1U[i],i)||4k&&!E(1U[i],i))1i.1g(1U[i]);v 1i},31:u(1U,E){7(1C E=="23")E=1p 4w("a","v "+E);B 1i=[],r=[];P(B i=0,2z=1U.I;i<2z;i++){B 1a=E(1U[i],i);7(1a!==16&&1a!=T){7(1a.1l!=2y)1a=[1a];1i=1i.6Z(1a)}}B r=1i.I?[1i[0]]:[];5f:P(B i=1,5e=1i.I;i<5e;i++){P(B j=0;j<i;j++)7(1i[i]==r[j])5F 5f;r.1g(1i[i])}v r}});1p u(){B b=7L.71.4m();6.W={2N:/5D/.1n(b),3f:/3f/.1n(b),1j:/1j/.1n(b)&&!/3f/.1n(b),3h:/3h/.1n(b)&&!/(72|5D)/.1n(b)};6.7H=!6.W.1j||17.74=="75"};6.K({5u:"a.11",4z:"6.4z(a)",76:"6.2a(a,2,\'2e\')",7D:"6.2a(a,2,\'5s\')",78:"6.2B(a.11.1b,a)",79:"6.2B(a.1b)"},u(i,n){6.E[i]=u(a){B L=6.31(q,n);7(a&&1C a=="23")L=6.3z(a,L);v q.2r(L)}});6.K({5z:"3r",7b:"5i",2X:"5j",7e:"5t"},u(i,n){6.E[i]=u(){B a=1A;v q.K(u(){P(B j=0,2R=a.I;j<2R;j++)6(a[j])[n](q)})}});6.K({5l:u(1Y){6.1I(q,1Y,"");q.7g(1Y)},7h:u(c){6.19.1M(q,c)},7i:u(c){6.19.2f(q,c)},7k:u(c){6.19[6.19.2V(q,c)?"2f":"1M"](q,c)},2f:u(a){7(!a||6.1D(a,[q]).r.I)q.11.33(q)},3u:u(){22(q.1b)q.33(q.1b)}},u(i,n){6.E[i]=u(){v q.K(n,1A)}});6.K(["5q","5n","5p","5v"],u(i,n){6.E[n]=u(1T,E){v q.1D(":"+n+"("+1T+")",E)}});6.K(["28","3V"],u(i,n){6.E[n]=u(h){v h==T?(q.I?6.1m(q[0],n):16):q.1m(n,h.1l==3t?h:h+"4S")}});6.1z({1s:{"":"m[2]==\'*\'||6.1f(a,m[2])","#":"a.36(\'2J\')==m[2]",":":{5n:"i<m[3]-0",5p:"i>m[3]-0",2a:"m[3]-0==i",5q:"m[3]-0==i",2u:"i==0",2T:"i==r.I-1",5R:"i%2==0",5S:"i%2","2a-3s":"6.2a(a.11.1b,m[3],\'2e\',a)==a","2u-3s":"6.2a(a.11.1b,1,\'2e\')==a","2T-3s":"6.2a(a.11.7n,1,\'5s\')==a","7p-3s":"6.2B(a.11.1b).I==1",5u:"a.1b",3u:"!a.1b",5v:"6.E.2L.14([a]).18(m[3])>=0",3i:\'a.C!="1G"&&6.1m(a,"1h")!="1Z"&&6.1m(a,"4n")!="1G"\',1G:\'a.C=="1G"||6.1m(a,"1h")=="1Z"||6.1m(a,"4n")=="1G"\',7v:"!a.2W",2W:"a.2W",2Z:"a.2Z",2Y:"a.2Y||6.1I(a,\'2Y\')",2L:"a.C==\'2L\'",4j:"a.C==\'4j\'",5x:"a.C==\'5x\'",4G:"a.C==\'4G\'",5y:"a.C==\'5y\'",4R:"a.C==\'4R\'",5A:"a.C==\'5A\'",5B:"a.C==\'5B\'",3x:\'a.C=="3x"||6.1f(a,"3x")\',5C:"/5C|42|7A|3x/i.1n(a.1f)"},".":"6.19.2V(a,m[2])","@":{"=":"z==m[4]","!=":"z!=m[4]","^=":"z&&!z.18(m[4])","$=":"z&&z.2U(z.I - m[4].I,m[4].I)==m[4]","*=":"z&&z.18(m[4])>=0","":"z",4u:u(m){v["",m[1],m[3],m[2],m[5]]},5P:"z=a[m[3]];7(!z||/5E|3e/.1n(m[3]))z=6.1I(a,m[3]);"},"[":"6.2o(m[2],a).I"},5M:[/^\\[ *(@)([a-2m-3C-]*) *([!*$^=]*) *(\'?"?)(.*?)\\4 *\\]/i,/^(\\[)\\s*(.*?(\\[.*?\\])?[^[]*?)\\s*\\]/,/^(:)([a-2m-3C-]*)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/i,/^([:.#]*)([a-2m-3C*-]*)/i],1Q:[/^(\\/?\\.\\.)/,"a.11",/^(>|\\/)/,"6.2B(a.1b)",/^(\\+)/,"6.2a(a,2,\'2e\')",/^(~)/,u(a){B s=6.2B(a.11.1b);v s.3N(6.3y(a,s)+1)}],3z:u(1s,1U,2g){B 1N,Q=[];22(1s&&1s!=1N){1N=1s;B f=6.1D(1s,1U,2g);1s=f.t.1R(/^\\s*,\\s*/,"");Q=2g?1U=f.r:6.2k(Q,f.r)}v Q},2o:u(t,1B){7(1C t!="23")v[t];7(1B&&!1B.24)1B=16;1B=1B||17;7(!t.18("//")){1B=1B.4H;t=t.2U(2,t.I)}J 7(!t.18("/")){1B=1B.4H;t=t.2U(1,t.I);7(t.18("/")>=1)t=t.2U(t.18("/"),t.I)}B L=[1B],2c=[],2T=16;22(t&&2T!=t){B r=[];2T=t;t=6.35(t).1R(/^\\/\\//i,"");B 3B=12;B 1J=/^[\\/>]\\s*([a-2m-9*-]+)/i;B m=1J.2Q(t);7(m){6.K(L,u(){P(B c=q.1b;c;c=c.2e)7(c.24==1&&(6.1f(c,m[1])||m[1]=="*"))r.1g(c)});L=r;t=t.1R(1J,"");7(t.18(" ")==0)5F;3B=U}J{P(B i=0;i<6.1Q.I;i+=2){B 1J=6.1Q[i];B m=1J.2Q(t);7(m){r=L=6.31(L,6.1t(6.1Q[i+1])?6.1Q[i+1]:u(a){v 40(6.1Q[i+1])});t=6.35(t.1R(1J,""));3B=U;3O}}}7(t&&!3B){7(!t.18(",")){7(L[0]==1B)L.4L();6.2k(2c,L);r=L=[1B];t=" "+t.2U(1,t.I)}J{B 34=/^([a-2m-3C-]+)(#)([a-2m-9\\\\*2S-]*)/i;B m=34.2Q(t);7(m){m=[0,m[2],m[3],m[1]]}J{34=/^([#.]?)([a-2m-9\\\\*2S-]*)/i;m=34.2Q(t)}7(m[1]=="#"&&L[L.I-1].4X){B 2l=L[L.I-1].4X(m[2]);7(6.W.1j&&2l&&2l.2J!=m[2])2l=6(\'[@2J="\'+m[2]+\'"]\',L[L.I-1])[0];L=r=2l&&(!m[3]||6.1f(2l,m[3]))?[2l]:[]}J{7(m[1]==".")B 4r=1p 4v("(^|\\\\s)"+m[2]+"(\\\\s|$)");6.K(L,u(){B 3E=m[1]!=""||m[0]==""?"*":m[2];7(6.1f(q,"7J")&&3E=="*")3E="3g";6.2k(r,m[1]!=""&&L.I!=1?6.4x(q,[],m[1],m[2],4r):q.5J(3E))});7(m[1]=="."&&L.I==1)r=6.2q(r,u(e){v 4r.1n(e.19)});7(m[1]=="#"&&L.I==1){B 5K=r;r=[];6.K(5K,u(){7(q.36("2J")==m[2]){r=[q];v 12}})}L=r}t=t.1R(34,"")}}7(t){B 1a=6.1D(t,r);L=r=1a.r;t=6.35(1a.t)}}7(L&&L[0]==1B)L.4L();6.2k(2c,L);v 2c},1D:u(t,r,2g){22(t&&/^[a-z[({<*:.#]/i.1n(t)){B p=6.5M,m;6.K(p,u(i,1J){m=1J.2Q(t);7(m){t=t.7M(m[0].I);7(6.1s[m[1]].4u)m=6.1s[m[1]].4u(m);v 12}});7(m[1]==":"&&m[2]=="2g")r=6.1D(m[3],r,U).r;J 7(m[1]=="."){B 1J=1p 4v("(^|\\\\s)"+m[2]+"(\\\\s|$)");r=6.2q(r,u(e){v 1J.1n(e.19||"")},2g)}J{B f=6.1s[m[1]];7(1C f!="23")f=6.1s[m[1]][m[2]];40("f = u(a,i){"+(6.1s[m[1]].5P||"")+"v "+f+"}");r=6.2q(r,f,2g)}}v{r:r,t:t}},4x:u(o,r,1Q,Y,1J){P(B s=o.1b;s;s=s.2e)7(s.24==1){B 1M=U;7(1Q==".")1M=s.19&&1J.1n(s.19);J 7(1Q=="#")1M=s.36("2J")==Y;7(1M)r.1g(s);7(1Q=="#"&&r.I)3O;7(s.1b)6.4x(s,r,1Q,Y,1J)}v r},4z:u(D){B 4A=[];B Q=D.11;22(Q&&Q!=17){4A.1g(Q);Q=Q.11}v 4A},2a:u(Q,1i,3Z,D){1i=1i||1;B 1T=0;P(;Q;Q=Q[3Z]){7(Q.24==1)1T++;7(1T==1i||1i=="5R"&&1T%2==0&&1T>1&&Q==D||1i=="5S"&&1T%2==1&&Q==D)v Q}},2B:u(n,D){B r=[];P(;n;n=n.2e){7(n.24==1&&(!D||n!=D))r.1g(n)}v r}});6.G={1M:u(S,C,1o,F){7(6.W.1j&&S.3L!=T)S=1w;7(F)1o.F=F;7(!1o.2A)1o.2A=q.2A++;7(!S.$1H)S.$1H={};B 38=S.$1H[C];7(!38){38=S.$1H[C]={};7(S["39"+C])38[0]=S["39"+C]}38[1o.2A]=1o;S["39"+C]=q.5Y;7(!q.1k[C])q.1k[C]=[];q.1k[C].1g(S)},2A:1,1k:{},2f:u(S,C,1o){7(S.$1H){B i,j,k;7(C&&C.C){1o=C.1o;C=C.C}7(C&&S.$1H[C])7(1o)5U S.$1H[C][1o.2A];J P(i 1x S.$1H[C])5U S.$1H[C][i];J P(j 1x S.$1H)q.2f(S,j);P(k 1x S.$1H[C])7(k){k=U;3O}7(!k)S["39"+C]=16}},1S:u(C,F,S){F=6.3M(F||[]);7(!S)6.K(q.1k[C]||[],u(){6.G.1S(C,F,q)});J{B 1o=S["39"+C],1a,E=6.1t(S[C]);7(1o){F.61(q.2j({C:C,1O:S}));7((1a=1o.14(S,F))!==12)q.4F=U}7(E&&1a!==12)S[C]();q.4F=12}},5Y:u(G){7(1C 6=="T"||6.G.4F)v;G=6.G.2j(G||1w.G||{});B 3R;B c=q.$1H[G.C];B 1E=[].3N.3n(1A,1);1E.61(G);P(B j 1x c){1E[0].1o=c[j];1E[0].F=c[j].F;7(c[j].14(q,1E)===12){G.2n();G.2H();3R=12}}7(6.W.1j)G.1O=G.2n=G.2H=G.1o=G.F=16;v 3R},2j:u(G){7(!G.1O&&G.63)G.1O=G.63;7(G.65==T&&G.67!=T){B e=17.4H,b=17.64;G.65=G.67+(e.68||b.68);G.7Y=G.7Z+(e.6c||b.6c)}7(6.W.2N&&G.1O.24==3){B 3a=G;G=6.1z({},3a);G.1O=3a.1O.11;G.2n=u(){v 3a.2n()};G.2H=u(){v 3a.2H()}}7(!G.2n)G.2n=u(){q.3R=12};7(!G.2H)G.2H=u(){q.82=U};v G}};6.E.1z({3U:u(C,F,E){v q.K(u(){6.G.1M(q,C,E||F,F)})},6u:u(C,F,E){v q.K(u(){6.G.1M(q,C,u(G){6(q).6f(G);v(E||F).14(q,1A)},F)})},6f:u(C,E){v q.K(u(){6.G.2f(q,C,E)})},1S:u(C,F){v q.K(u(){6.G.1S(C,F,q)})},3X:u(){B a=1A;v q.6j(u(e){q.4M=q.4M==0?1:0;e.2n();v a[q.4M].14(q,[e])||12})},83:u(f,g){u 4O(e){B p=(e.C=="41"?e.84:e.85)||e.86;22(p&&p!=q)2G{p=p.11}2w(e){p=q};7(p==q)v 12;v(e.C=="41"?f:g).14(q,[e])}v q.41(4O).6k(4O)},27:u(f){7(6.3W)f.14(17,[6]);J{6.3c.1g(u(){v f.14(q,[6])})}v q}});6.1z({3W:12,3c:[],27:u(){7(!6.3W){6.3W=U;7(6.3c){6.K(6.3c,u(){q.14(17)});6.3c=16}7(6.W.3h||6.W.3f)17.87("6o",6.27,12)}}});1p u(){6.K(("88,8a,2O,8b,8d,52,6j,8e,"+"8f,8g,8h,41,6k,8j,42,"+"4R,8k,8l,8m,2C").3o(","),u(i,o){6.E[o]=u(f){v f?q.3U(o,f):q.1S(o)}});7(6.W.3h||6.W.3f)17.8n("6o",6.27,12);J 7(6.W.1j){17.8o("<8r"+"8s 2J=62 8u=U "+"3e=//:><\\/2d>");B 2d=17.4X("62");7(2d)2d.37=u(){7(q.3D!="1X")v;q.11.33(q);6.27()};2d=16}J 7(6.W.2N)6.50=3L(u(){7(17.3D=="8y"||17.3D=="1X"){4p(6.50);6.50=16;6.27()}},10);6.G.1M(1w,"2O",6.27)};7(6.W.1j)6(1w).6u("52",u(){B 1k=6.G.1k;P(B C 1x 1k){B 4Z=1k[C],i=4Z.I;7(i&&C!=\'52\')6w 6.G.2f(4Z[i-1],C);22(--i)}});6.E.1z({6A:u(V,21,M){q.2O(V,21,M,1)},2O:u(V,21,M,1W){7(6.1t(V))v q.3U("2O",V);M=M||u(){};B C="5d";7(21)7(6.1t(21)){M=21;21=16}J{21=6.3g(21);C="5V"}B 4e=q;6.3v({V:V,C:C,F:21,1W:1W,1X:u(2P,15){7(15=="2M"||!1W&&15=="5L")4e.1I("2t",2P.3G).4V().K(M,[2P.3G,15,2P]);J M.14(4e,[2P.3G,15,2P])}});v q},6B:u(){v 6.3g(q)},4V:u(){v q.2o("2d").K(u(){7(q.3e)6.59(q.3e);J 6.4a(q.2L||q.6H||q.2t||"")}).4g()}});7(!1w.3p)3p=u(){v 1p 6I("6K.6M")};6.K("5m,5Q,5O,5W,5N,5H".3o(","),u(i,o){6.E[o]=u(f){v q.3U(o,f)}});6.1z({2b:u(V,F,M,C,1W){7(6.1t(F)){M=F;F=16}v 6.3v({V:V,F:F,2M:M,4t:C,1W:1W})},6Q:u(V,F,M,C){v 6.2b(V,F,M,C,1)},59:u(V,M){v 6.2b(V,16,M,"2d")},6S:u(V,F,M){v 6.2b(V,F,M,"6m")},6U:u(V,F,M,C){7(6.1t(F)){M=F;F={}}v 6.3v({C:"5V",V:V,F:F,2M:M,4t:C})},6X:u(29){6.3q.29=29},6Y:u(5c){6.1z(6.3q,5c)},3q:{1k:U,C:"5d",29:0,5r:"70/x-73-3w-77",5h:U,48:U,F:16},3S:{},3v:u(s){s=6.1z({},6.3q,s);7(s.F){7(s.5h&&1C s.F!="23")s.F=6.3g(s.F);7(s.C.4m()=="2b"){s.V+=((s.V.18("?")>-1)?"&":"?")+s.F;s.F=16}}7(s.1k&&!6.4E++)6.G.1S("5m");B 4y=12;B N=1p 3p();N.7j(s.C,s.V,s.48);7(s.F)N.3A("7l-7m",s.5r);7(s.1W)N.3A("7o-4K-7q",6.3S[s.V]||"7s, 7t 7w 7x 4o:4o:4o 7z");N.3A("X-7B-7C","3p");7(N.7E)N.3A("7F","7G");7(s.5G)s.5G(N);7(s.1k)6.G.1S("5H",[N,s]);B 37=u(4s){7(N&&(N.3D==4||4s=="29")){4y=U;7(3I){4p(3I);3I=16}B 15;2G{15=6.5Z(N)&&4s!="29"?s.1W&&6.69(N,s.V)?"5L":"2M":"2C";7(15!="2C"){B 3F;2G{3F=N.4P("6b-4K")}2w(e){}7(s.1W&&3F)6.3S[s.V]=3F;B F=6.6i(N,s.4t);7(s.2M)s.2M(F,15);7(s.1k)6.G.1S("5N",[N,s])}J 6.3J(s,N,15)}2w(e){15="2C";6.3J(s,N,15,e)}7(s.1k)6.G.1S("5O",[N,s]);7(s.1k&&!--6.4E)6.G.1S("5Q");7(s.1X)s.1X(N,15);7(s.48)N=16}};B 3I=3L(37,13);7(s.29>0)57(u(){7(N){N.7N();7(!4y)37("29")}},s.29);2G{N.7Q(s.F)}2w(e){6.3J(s,N,16,e)}7(!s.48)37();v N},3J:u(s,N,15,e){7(s.2C)s.2C(N,15,e);7(s.1k)6.G.1S("5W",[N,s,e])},4E:0,5Z:u(r){2G{v!r.15&&7V.7W=="4G:"||(r.15>=5X&&r.15<7X)||r.15==6d||6.W.2N&&r.15==T}2w(e){}v 12},69:u(N,V){2G{B 6e=N.4P("6b-4K");v N.15==6d||6e==6.3S[V]||6.W.2N&&N.15==T}2w(e){}v 12},6i:u(r,C){B 4Q=r.4P("8c-C");B F=!C&&4Q&&4Q.18("N")>=0;F=C=="N"||F?r.8i:r.3G;7(C=="2d")6.4a(F);7(C=="6m")40("F = "+F);7(C=="4U")6("<1V>").4U(F).4V();v F},3g:u(a){B s=[];7(a.1l==2y||a.3Y)6.K(a,u(){s.1g(2x(q.Y)+"="+2x(q.O))});J P(B j 1x a)7(a[j]&&a[j].1l==2y)6.K(a[j],u(){s.1g(2x(j)+"="+2x(q))});J s.1g(2x(j)+"="+2x(a[j]));v s.6t("&")},4a:u(F){7(1w.54)1w.54(F);J 7(6.W.2N)1w.57(F,0);J 40.3n(1w,F)}});6.E.1z({1L:u(R,M){B 1G=q.1D(":1G");R?1G.26({28:"1L",3V:"1L",1d:"1L"},R,M):1G.K(u(){q.1q.1h=q.2E?q.2E:"";7(6.1m(q,"1h")=="1Z")q.1q.1h="2D"});v q},1K:u(R,M){B 3i=q.1D(":3i");R?3i.26({28:"1K",3V:"1K",1d:"1K"},R,M):3i.K(u(){q.2E=q.2E||6.1m(q,"1h");7(q.2E=="1Z")q.2E="2D";q.1q.1h="1Z"});v q},5g:6.E.3X,3X:u(E,4I){B 1E=1A;v 6.1t(E)&&6.1t(4I)?q.5g(E,4I):q.K(u(){6(q)[6(q).4l(":1G")?"1L":"1K"].14(6(q),1E)})},7a:u(R,M){v q.26({28:"1L"},R,M)},7c:u(R,M){v q.26({28:"1K"},R,M)},7f:u(R,M){v q.K(u(){B 5k=6(q).4l(":1G")?"1L":"1K";6(q).26({28:5k},R,M)})},7r:u(R,M){v q.26({1d:"1L"},R,M)},7u:u(R,M){v q.26({1d:"1K"},R,M)},7y:u(R,43,M){v q.26({1d:43},R,M)},26:u(H,R,1v,M){v q.1F(u(){q.2F=6.1z({},H);B 1u=6.R(R,1v,M);P(B p 1x H){B e=1p 6.3b(q,1u,p);7(H[p].1l==3Q)e.2s(e.Q(),H[p]);J e[H[p]](H)}})},1F:u(C,E){7(!E){E=C;C="3b"}v q.K(u(){7(!q.1F)q.1F={};7(!q.1F[C])q.1F[C]=[];q.1F[C].1g(E);7(q.1F[C].I==1)E.14(q)})}});6.1z({R:u(R,1v,E){B 1u=R&&R.1l==7K?R:{1X:E||!E&&1v||6.1t(R)&&R,25:R,1v:E&&1v||1v&&1v.1l!=4w&&1v};1u.25=(1u.25&&1u.25.1l==3Q?1u.25:{7R:7S,7T:5X}[1u.25])||7U;1u.1N=1u.1X;1u.1X=u(){6.6a(q,"3b");7(6.1t(1u.1N))1u.1N.14(q)};v 1u},1v:{},1F:{},6a:u(D,C){C=C||"3b";7(D.1F&&D.1F[C]){D.1F[C].4L();B f=D.1F[C][0];7(f)f.14(D)}},3b:u(D,1e,H){B z=q;B y=D.1q;B 4D=6.1m(D,"1h");y.5T="1G";z.a=u(){7(1e.49)1e.49.14(D,[z.2p]);7(H=="1d")6.1I(y,"1d",z.2p);J 7(6l(z.2p))y[H]=6l(z.2p)+"4S";y.1h="2D"};z.6v=u(){v 4T(6.1m(D,H))};z.Q=u(){B r=4T(6.30(D,H));v r&&r>-8z?r:z.6v()};z.2s=u(4f,43){z.4J=(1p 5o()).5w();z.2p=4f;z.a();z.4q=3L(u(){z.49(4f,43)},13)};z.1L=u(){7(!D.1y)D.1y={};D.1y[H]=q.Q();1e.1L=U;z.2s(0,D.1y[H]);7(H!="1d")y[H]="5a"};z.1K=u(){7(!D.1y)D.1y={};D.1y[H]=q.Q();1e.1K=U;z.2s(D.1y[H],0)};z.3X=u(){7(!D.1y)D.1y={};D.1y[H]=q.Q();7(4D=="1Z"){1e.1L=U;7(H!="1d")y[H]="5a";z.2s(0,D.1y[H])}J{1e.1K=U;z.2s(D.1y[H],0)}};z.49=u(32,47){B t=(1p 5o()).5w();7(t>1e.25+z.4J){4p(z.4q);z.4q=16;z.2p=47;z.a();7(D.2F)D.2F[H]=U;B 2c=U;P(B i 1x D.2F)7(D.2F[i]!==U)2c=12;7(2c){y.5T="";y.1h=4D;7(6.1m(D,"1h")=="1Z")y.1h="2D";7(1e.1K)y.1h="1Z";7(1e.1K||1e.1L)P(B p 1x D.2F)7(p=="1d")6.1I(y,p,D.1y[p]);J y[p]=""}7(2c&&6.1t(1e.1X))1e.1X.14(D)}J{B n=t-q.4J;B p=n/1e.25;z.2p=1e.1v&&6.1v[1e.1v]?6.1v[1e.1v](p,n,32,(47-32),1e.25):((-6h.7O(p*6h.8L)/2)+0.5)*(47-32)+32;z.a()}}}})}',62,545,'||||||jQuery|if|||||||||||||||||||this||||function|return||||||var|type|elem|fn|data|event|prop|length|else|each|ret|callback|xml|value|for|cur|speed|element|undefined|true|url|browser||name|||parentNode|false||apply|status|null|document|indexOf|className|val|firstChild|obj|opacity|options|nodeName|push|display|result|msie|global|constructor|css|test|handler|new|style|arg|expr|isFunction|opt|easing|window|in|orig|extend|arguments|context|typeof|filter|args|queue|hidden|events|attr|re|hide|show|add|old|target|table|token|replace|trigger|num|elems|div|ifModified|complete|key|none|tbody|params|while|string|nodeType|duration|animate|ready|height|timeout|nth|get|done|script|nextSibling|remove|not|index|tb|fix|merge|oid|z0|preventDefault|find|now|grep|pushStack|custom|innerHTML|first|cssFloat|catch|encodeURIComponent|Array|el|guid|sibling|error|block|oldblock|curAnim|try|stopPropagation|childNodes|id|wrap|text|success|safari|load|res|exec|al|_|last|substr|has|disabled|insertBefore|selected|checked|curCSS|map|firstNum|removeChild|re2|trim|getAttribute|onreadystatechange|handlers|on|originalEvent|fx|readyList|parPos|src|opera|param|mozilla|visible|domManip|clean|cloneNode|tr|call|split|XMLHttpRequest|ajaxSettings|append|child|String|empty|ajax|form|button|inArray|multiFilter|setRequestHeader|foundToken|9_|readyState|tag|modRes|responseText|second|ival|handleError|toUpperCase|setInterval|makeArray|slice|break|oWidth|Number|returnValue|lastModified|styleFloat|bind|width|isReady|toggle|jquery|dir|eval|mouseover|select|to|defaultView|position|oHeight|lastNum|async|step|globalEval|static|pos|swap|self|from|end|float|alpha|radio|inv|is|toLowerCase|visibility|00|clearInterval|timer|rec|isTimeout|dataType|_resort|RegExp|Function|getAll|requestDone|parents|matched|isXMLDoc|appendChild|oldDisplay|active|triggered|file|documentElement|fn2|startTime|Modified|shift|lastToggle|deep|handleHover|getResponseHeader|ct|submit|px|parseFloat|html|evalScripts|getComputedStyle|getElementById|clone|els|safariTimer|currentStyle|unload|force|execScript|getPropertyValue|newProp|setTimeout|zoom|getScript|1px|sl|settings|GET|rl|check|_toggle|processData|prepend|before|state|removeAttr|ajaxStart|lt|Date|gt|eq|contentType|previousSibling|after|parent|contains|getTime|checkbox|password|appendTo|image|reset|input|webkit|href|continue|beforeSend|ajaxSend|ownerDocument|getElementsByTagName|tmp|notmodified|parse|ajaxSuccess|ajaxComplete|_prefix|ajaxStop|even|odd|overflow|delete|POST|ajaxError|200|handle|httpSuccess|nodeValue|unshift|__ie_init|srcElement|body|pageX|tagName|clientX|scrollLeft|httpNotModified|dequeue|Last|scrollTop|304|xmlRes|unbind|100|Math|httpData|click|mouseout|parseInt|json|createElement|DOMContentLoaded|prevObject|ol|setArray|exclude|join|one|max|do|relative|clientHeight|clientWidth|loadIfModified|serialize|toString|thead|tfoot|td|th|textContent|ActiveXObject|htmlFor|Microsoft|class|XMLHTTP|readOnly|gi|match|getIfModified|9999|getJSON|getAttributeNode|post|setAttribute|ig|ajaxTimeout|ajaxSetup|concat|application|userAgent|compatible|www|compatMode|CSS1Compat|next|urlencoded|siblings|children|slideDown|prependTo|slideUp|Top|insertAfter|slideToggle|removeAttribute|addClass|removeClass|open|toggleClass|Content|Type|lastChild|If|only|Since|fadeIn|Thu|01|fadeOut|enabled|Jan|1970|fadeTo|GMT|textarea|Requested|With|prev|overrideMimeType|Connection|close|boxModel|right|object|Object|navigator|substring|abort|cos|font|send|slow|600|fast|400|location|protocol|300|pageY|clientY|method|action|cancelBubble|hover|fromElement|toElement|relatedTarget|removeEventListener|blur|readonly|focus|resize|content|scroll|dblclick|mousedown|mouseup|mousemove|responseXML|change|keydown|keypress|keyup|addEventListener|write|prototype|size|scr|ipt|createTextNode|defer|FORM|reverse|noConflict|loaded|10000|weight|line|Bottom|Right|Left|padding|border|Width|offsetHeight|offsetWidth|absolute|PI|left'.split('|'),0,{}));jQuery.noConflict();
diff -ruN 2.0.5/wp-includes/js/list-manipulation.js 2.2.2/wp-includes/js/list-manipulation.js
--- 2.0.5/wp-includes/js/list-manipulation.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/list-manipulation.js	2007-03-06 11:35:01.000000000 -0600
@@ -0,0 +1,295 @@
+addLoadEvent( function() {
+	if ( 'undefined' != typeof listManL10n )
+		Object.extend(listMan.prototype, listManL10n);
+	theList = new listMan();
+} );
+
+function deleteSomething( what, id, message, obj ) {
+	if ( !obj )
+		obj=theList;
+	if ( !message )
+		message = obj.delText.replace(/%thing%/g, what);
+	if( confirm(message) )
+		return obj.ajaxDelete( what, id );
+	else return false;
+}
+
+function dimSomething( what, id, dimClass, obj ) {
+	if ( !obj )
+		obj = theList;
+	return obj.ajaxDimmer(what,id,dimClass);
+}
+
+var listMan = Class.create();
+Object.extend(listMan.prototype, {
+	ajaxRespEl: 'ajax-response',
+	ajaxHandler: false,
+	inputData: '',
+	clearInputs: [],
+	showLink: true,
+	topAdder: false,
+	alt: 'alternate',
+	altOffset: 0,
+	addComplete: null,
+	delComplete: null,
+	dimComplete: null,
+	dataStore: null,
+	formStore: null,
+
+	jumpText: '', // We get these from listManL10n
+	delText: '',
+
+	initialize: function(theListId) {
+		this.theList = $(theListId ? theListId : 'the-list');
+		if ( !this.theList )
+			return false;
+		Element.cleanWhitespace(this.theList);
+	},
+
+	// sends add-what and fields contained in where
+	// recieves html with top element having an id like what-#
+	ajaxAdder: function( what, where, update ) { // Do NOT wrap TR in TABLE TBODY
+		var ajaxAdd = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if ( ajaxAdd.notInitialized() )
+			return true;
+		var action = ( update ? 'update-' : 'add-' ) + what;
+		ajaxAdd.options.parameters = $H(ajaxAdd.options.parameters).merge({action: action}).merge(this.inputData.toQueryParams()).merge(this.grabInputs( where, ajaxAdd ).toQueryParams());
+
+		var tempObj=this;
+		ajaxAdd.addOnComplete( function(transport) {
+			var newItems = $A(transport.responseXML.getElementsByTagName(what));
+			if ( newItems ) {
+				var showLinkMessage = '';
+				var m = '';
+				newItems.each( function(i) {
+					var id = i.getAttribute('id');
+					var exists = $(what+'-'+id);
+					if ( exists )
+						tempObj.replaceListItem( exists, getNodeValue(i,'response_data'), update );
+					else
+						tempObj.addListItem( getNodeValue(i, 'response_data') );
+					m = getNodeValue(i, 'show-link');
+					showLinkMessage += showLinkMessage ? "<br />\n" : '';
+					if ( m )
+						showLinkMessage += m;
+					else
+						showLinkMessage += "<a href='#" + what + '-' + id + "'>" + tempObj.jumpText + "</a>";
+				});
+				if ( tempObj.showLink && showLinkMessage )
+					Element.update(ajaxAdd.myResponseElement,"<div id='jumplink' class='updated fade'><p>" + showLinkMessage + "</p></div>");
+			}
+			if ( tempObj.addComplete && typeof tempObj.addComplete == 'function' )
+				tempObj.addComplete( what, where, update, transport );
+			tempObj.recolorList();
+			ajaxAdd.restoreInputs = null;
+		});
+		if ( !update )
+			ajaxAdd.addOnWPError( function(transport) { tempObj.restoreForm(ajaxAdd.restoreInputs); });
+		ajaxAdd.request(ajaxAdd.url);
+		if ( !update )
+			this.clear();
+		return false;
+	},
+
+	// sends update-what and fields contained in where
+	// recieves html with top element having an id like what-#
+	ajaxUpdater: function( what, where ) { return this.ajaxAdder( what, where, true ); },
+
+	// sends delete-what and id#
+	ajaxDelete: function( what, id ) {
+		var ajaxDel = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if( ajaxDel.notInitialized() )
+			return true;
+		var tempObj = this;
+		var action = 'delete-' + what;
+		var actionId = action + '&id=' + id;
+		var idName = what.replace('-as-spam','') + '-' + id;
+		ajaxDel.addOnComplete( function(transport) {
+			Element.update(ajaxDel.myResponseElement,'');
+			tempObj.destore(actionId);
+			if( tempObj.delComplete && typeof tempObj.delComplete == 'function' )
+				tempObj.delComplete( what, id, transport );
+		});
+		ajaxDel.addOnWPError( function(transport) { tempObj.restore(actionId, true); });
+		ajaxDel.options.parameters = $H(ajaxDel.options.parameters).merge({action: action, id: id}).merge(this.inputData.toQueryParams());
+		ajaxDel.request(ajaxDel.url);
+		this.store(actionId, idName);
+		tempObj.removeListItem( idName );
+		return false;
+	},
+
+	// Toggles class nomes
+	// sends dim-what and id#
+	ajaxDimmer: function( what, id, dimClass ) {
+		ajaxDim = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if ( ajaxDim.notInitialized() )
+			return true;
+		var tempObj = this;
+		var action = 'dim-' + what;
+		var actionId = action + '&id=' + id;
+		var idName = what + '-' + id;
+		ajaxDim.addOnComplete( function(transport) {
+			Element.update(ajaxDim.myResponseElement,'');
+			tempObj.destore(actionId);
+			if ( tempObj.dimComplete && typeof tempObj.dimComplete == 'function' )
+				tempObj.dimComplete( what, id, dimClass, transport );
+		});
+		ajaxDim.addOnWPError( function(transport) { tempObj.restore(actionId, true); });
+		ajaxDim.options.parameters = $H(ajaxDim.options.parameters).merge({action: action, id: id}).merge(this.inputData.toQueryParams());
+		ajaxDim.request(ajaxDim.url);
+		this.store(actionId, idName);
+		this.dimItem( idName, dimClass );
+		return false;
+	},
+
+	addListItem: function( h ) {
+		new Insertion[this.topAdder ? 'Top' : 'Bottom'](this.theList,h);
+		Element.cleanWhitespace(this.theList);
+		var id = this.topAdder ? this.theList.firstChild.id : this.theList.lastChild.id;
+		if ( this.alt )
+			if ( ( this.theList.childNodes.length + this.altOffset ) % 2 )
+				Element.addClassName($(id),this.alt);
+		Fat.fade_element(id);
+	},
+
+	// only hides the element sa it can be put back again if necessary
+	removeListItem: function( id, noFade ) {
+		id = $(id);
+		if ( !noFade ) {
+			Fat.fade_element(id.id,null,700,'#FF3333');
+			var tempObj = this;
+			var func = function() { id.hide(); tempObj.recolorList(); }
+			setTimeout(func, 705);
+		} else {
+			id.hide();
+			this.recolorList();
+		}
+	},
+
+	replaceListItem: function( id, h, update ) {
+		id = $(id);
+		if ( !update ) {
+			Element.remove(id);
+			this.addListItem( h );
+			return;
+		}
+		id.replace(h);
+		Fat.fade_element(id.id);
+	},
+
+	// toggles class
+	dimItem: function( id, dimClass, noFade ) {
+		id = $(id);
+		if ( Element.hasClassName(id,dimClass) ) {
+			if ( !noFade )
+				Fat.fade_element(id.id,null,700,null);
+			Element.removeClassName(id,dimClass);
+		} else {
+			if ( !noFade )
+				Fat.fade_element(id.id,null,700,'#FF3333');
+			Element.addClassName(id,dimClass);
+		}
+	},
+
+	// store an element in case we need it later
+	store: function(action, id) {
+		if ( !this.dataStore )
+			this.dataStore = $H();
+		this.dataStore[action] = $(id).cloneNode(true);
+	},
+
+	// delete from store
+	destore: function(action) { delete(this.dataStore[action]); },
+
+	// restore element from store into existing (possibly hidden) element of same id
+	restore: function(action, error) {
+		var id = this.dataStore[action].id;
+		this.theList.replaceChild(this.dataStore[action], $(id));
+		delete(this.dataStore[action]);
+		if ( error ) {
+			func = function() { Element.setStyle($(id),{backgroundColor:'#FF3333'}); }
+			func(); setTimeout(func, 705); // Hit it twice in case it's still fading.
+		}
+	},
+
+	// Like Form.serialize, but excludes action and sets up clearInputs
+	grabInputs: function( where, ajaxObj ) {
+		if ( ajaxObj )
+			ajaxObj.restoreInputs = [];
+		var elements = Form.getElements($(where));
+		var queryComponents = new Array();
+		for (var i = 0; i < elements.length; i++) {
+			if ( 'action' == elements[i].name )
+				continue;
+			if ( 'hidden' != elements[i].type && 'submit' != elements[i].type && 'button' != elements[i].type ) {
+				this.clearInputs.push(elements[i]);
+				if ( ajaxObj )
+					ajaxObj.restoreInputs.push([elements[i], elements[i].value]);
+			}
+			var queryComponent = Form.Element.serialize(elements[i]);
+			if (queryComponent) {
+				queryComponents.push(queryComponent);
+			}
+		}
+		return queryComponents.join('&');
+	},
+
+	// form.reset() can only do whole forms.  This can do subsections.
+	clear: function() {
+		this.clearInputs.each( function(i) {
+			i = $(i);
+			if ( 'textarea' == i.tagName.toLowerCase() )
+				i.value = '';
+			else
+				switch ( i.type.toLowerCase() ) {
+					case 'password': case 'text':
+						i.value = '';
+						break;
+					case 'checkbox': case 'radio':
+						i.checked = false;
+						break;
+					case 'select': case 'select-one':
+						i.selectedIndex = null;
+						break;
+					case 'select-multiple':
+						for (var o = 0; o < i.length; o++) i.options[o].selected = false;
+						break;
+				}
+		});
+		this.clearInputs = [];
+	},
+
+	restoreForm: function(elements) {
+		elements.each( function(i) {
+			i[0].value = i[1];
+		});
+	},
+
+	recolorList: function() {
+		if ( !this.alt )
+			return;
+		var alt = this.alt;
+		var offset = this.altOffset;
+		var listItems = $A(this.theList.childNodes).findAll( function(i) { return Element.visible(i) } );
+		listItems.each( function(i,n) {
+			if ( ( n + offset ) % 2 )
+				Element.removeClassName(i,alt);
+			else
+				Element.addClassName(i,alt);
+		});
+	}
+});
+
+//No submit unless code returns true.
+function killSubmit ( code, e ) {
+	e = e ? e : window.event;
+	if ( !e ) return;
+	var t = e.target ? e.target : e.srcElement;
+	if ( ( 'text' == t.type && e.keyCode == 13 ) || ( 'submit' == t.type && 'click' == e.type ) ) {
+		if ( ( 'string' == typeof code && !eval(code) ) || ( 'function' == typeof code && !code() ) ) {
+			e.returnValue = false; e.cancelBubble = true; return false;
+		}
+	}
+}
+//Generic but lame JS closure
+function encloseFunc(f){var a=arguments[1];return function(){return f(a);}}
diff -ruN 2.0.5/wp-includes/js/prototype.js 2.2.2/wp-includes/js/prototype.js
--- 2.0.5/wp-includes/js/prototype.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/prototype.js	2007-05-04 16:48:43.000000000 -0500
@@ -0,0 +1,2515 @@
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
+
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  emptyFunction: function() {},
+  K: function(x) { return x }
+}
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+}
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
+  }
+});
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+  }
+}
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback(this);
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+}
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+}
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(replacement);
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = count === undefined ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return this;
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : this;
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (typeof replacement == 'function') return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern  = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    return this.template.gsub(this.pattern, function(match) {
+      var before = match[1];
+      if (before == '\\') return match[2];
+      return before + String.interpret(object[match[3]]);
+    });
+  }
+}
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    })
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+}
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0, length = iterable.length; i < length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+  Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value && value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0, length = this.length; i < length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+}
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+	  this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+        	key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.map(encodeURIComponent).join('='));
+	  });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+  _each: function(iterator) {
+    for (var key in this) {
+      var value = this[key];
+      if (value && value == Hash.prototype[key]) continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
+  toQueryString: function() {
+    return Hash.toQueryString(this);
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+});
+
+function $H(object) {
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+}
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   ''
+    }
+    Object.extend(this.options, options || {});
+
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
+
+      this.transport.send(body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    }
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, param) {
+      this.updateContent();
+      onComplete(transport, param);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts) response = response.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
+        new this.options.insertion(receiver, response);
+      else
+        receiver.update(response);
+    }
+
+    if (this.success()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
+}
+
+document.getElementsByClassName = function(className, parentElement) {
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+  var Element = new Object();
+
+Element.extend = function(element) {
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
+
+  if (!element._extended && element.tagName && element != window) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
+      var value = methods[property];
+      if (typeof value == 'function' && !(property in element))
+        element[property] = cache.findOrStore(value);
+    }
+  }
+
+  element._extended = true;
+  return element;
+};
+
+Element.extend.cache = {
+  findOrStore: function(value) {
+    return this[value] = this[value] || function() {
+      return value.apply(null, [this].concat($A(arguments)));
+    }
+  }
+};
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  replace: function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    if (element.outerHTML) {
+      element.outerHTML = html.stripScripts();
+    } else {
+      var range = element.ownerDocument.createRange();
+      range.selectNodeContents(element);
+      element.parentNode.replaceChild(
+        range.createContextualFragment(html.stripScripts()), element);
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).add(className);
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css[style] : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style];
+      }
+    }
+
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value == '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
+
+Element.addMethods = function(methods) {
+  Object.extend(Element.Methods, methods || {});
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
+    }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
+    _nativeExtensions = true;
+  }
+}
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+  initialize: function(expression) {
+    this.params = {classNames: []};
+    this.expression = expression.toString().strip();
+    this.parseExpression();
+    this.compileMatcher();
+  },
+
+  parseExpression: function() {
+    function abort(message) { throw 'Parse error in selector: ' + message; }
+
+    if (this.expression == '')  abort('empty expression');
+
+    var params = this.params, expr = this.expression, match, modifier, clause, rest;
+    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+      params.attributes = params.attributes || [];
+      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+      expr = match[1];
+    }
+
+    if (expr == '*') return this.params.wildcard = true;
+
+    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+      modifier = match[1], clause = match[2], rest = match[3];
+      switch (modifier) {
+        case '#':       params.id = clause; break;
+        case '.':       params.classNames.push(clause); break;
+        case '':
+        case undefined: params.tagName = clause.toUpperCase(); break;
+        default:        abort(expr.inspect());
+      }
+      expr = rest;
+    }
+
+    if (expr.length > 0) abort(expr.inspect());
+  },
+
+  buildMatchExpression: function() {
+    var params = this.params, conditions = [], clause;
+
+    if (params.wildcard)
+      conditions.push('true');
+    if (clause = params.id)
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
+    if (clause = params.tagName)
+      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+    if ((clause = params.classNames).length > 0)
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
+    if (clause = params.attributes) {
+      clause.each(function(attribute) {
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
+        var splitValueBy = function(delimiter) {
+          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+        }
+
+        switch (attribute.operator) {
+          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
+          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+          case '|=':      conditions.push(
+                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+                          ); break;
+          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
+          case '':
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
+          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
+        }
+      });
+    }
+
+    return conditions.join(' && ');
+  },
+
+  compileMatcher: function() {
+    this.match = new Function('element', 'if (!element.tagName) return false; \
+      element = $(element); \
+      return ' + this.buildMatchExpression());
+  },
+
+  findElements: function(scope) {
+    var element;
+
+    if (element = $(this.params.id))
+      if (this.match(element))
+        if (!scope || Element.childOf(element, scope))
+          return [element];
+
+    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+    var results = [];
+    for (var i = 0, length = scope.length; i < length; i++)
+      if (this.match(element = scope[i]))
+        results.push(Element.extend(element));
+
+    return results;
+  },
+
+  toString: function() {
+    return this.expression;
+  }
+}
+
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
+  },
+
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.blur();
+      element.disabled = 'true';
+    });
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.disabled = '';
+    });
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    return $(form).getElements().find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+}
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
+  }
+}
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
+    }
+  },
+
+  inputSelector: function(element) {
+    return element.checked ? element.value : null;
+  },
+
+  textarea: function(element) {
+    return element.value;
+  },
+
+  select: function(element) {
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+}
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    Event._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+  Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {})
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+}
+
+Element.addMethods();
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/quicktags.js 2.2.2/wp-includes/js/quicktags.js
--- 2.0.5/wp-includes/js/quicktags.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/quicktags.js	2007-04-01 11:06:19.000000000 -0500
@@ -168,7 +168,7 @@
 }
 
 function edShowLinks() {
-	var tempStr = '<select onchange="edQuickLink(this.options[this.selectedIndex].value, this);"><option value="-1" selected>(Quick Links)</option>';
+	var tempStr = '<select onchange="edQuickLink(this.options[this.selectedIndex].value, this);"><option value="-1" selected>' + quicktagsL10n.quickLinks + '</option>';
 	for (i = 0; i < edLinks.length; i++) {
 		tempStr += '<option value="' + i + '">' + edLinks[i].display + '</option>';
 	}
@@ -205,7 +205,7 @@
 	else {
 		return false; // tag not found
 	}
-}	
+}
 
 function edCloseAllTags() {
 	var count = edOpenTags.length;
@@ -248,7 +248,7 @@
 		}
 	}
 	if (word == '') {
-		word = prompt('Enter a word to look up:', '');
+		word = prompt(quicktagsL10n.wordLookup, '');
 	}
 	if (word !== null && /^\w[\w ]*$/.test(word)) {
 		window.open('http://www.answers.com/' + escape(word));
@@ -260,8 +260,8 @@
 	for (i = 0; i < edButtons.length; i++) {
 		edShowButton(edButtons[i], i);
 	}
-	document.write('<input type="button" id="ed_spell" class="ed_button" onclick="edSpell(edCanvas);" title="Dictionary lookup" value="lookup" />');
-	document.write('<input type="button" id="ed_close" class="ed_button" onclick="edCloseAllTags();" title="Close all open tags" value="Close Tags" />');
+	document.write('<input type="button" id="ed_spell" class="ed_button" onclick="edSpell(edCanvas);" title="' + quicktagsL10n.dictionaryLookup + '" value="' + quicktagsL10n.lookup + '" />');
+	document.write('<input type="button" id="ed_close" class="ed_button" onclick="edCloseAllTags();" title="' + quicktagsL10n.closeAllOpenTags + '" value="' + quicktagsL10n.closeTags + '" />');
 //	edShowLinks(); // disabled by default
 	document.write('</div>');
 }
@@ -366,7 +366,7 @@
 		defaultValue = 'http://';
 	}
 	if (!edCheckOpenTags(i)) {
-		var URL = prompt('Enter the URL' ,defaultValue);
+		var URL = prompt(quicktagsL10n.enterURL, defaultValue);
 		if (URL) {
 			edButtons[i].tagStart = '<a href="' + URL + '">';
 			edInsertTag(myField, i);
@@ -378,11 +378,11 @@
 }
 
 function edInsertImage(myField) {
-	var myValue = prompt('Enter the URL of the image', 'http://');
+	var myValue = prompt(quicktagsL10n.enterImageURL, 'http://');
 	if (myValue) {
 		myValue = '<img src="' 
 				+ myValue 
-				+ '" alt="' + prompt('Enter a description of the image', '') 
+				+ '" alt="' + prompt(quicktagsL10n.enterImageDescription, '') 
 				+ '" />';
 		edInsertContent(myField, myValue);
 	}
diff -ruN 2.0.5/wp-includes/js/scriptaculous/MIT-LICENSE 2.2.2/wp-includes/js/scriptaculous/MIT-LICENSE
--- 2.0.5/wp-includes/js/scriptaculous/MIT-LICENSE	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/MIT-LICENSE	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,20 @@
+Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/builder.js 2.2.2/wp-includes/js/scriptaculous/builder.js
--- 2.0.5/wp-includes/js/scriptaculous/builder.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/builder.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,131 @@
+// script.aculo.us builder.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Builder = {
+  NODEMAP: {
+    AREA: 'map',
+    CAPTION: 'table',
+    COL: 'table',
+    COLGROUP: 'table',
+    LEGEND: 'fieldset',
+    OPTGROUP: 'select',
+    OPTION: 'select',
+    PARAM: 'object',
+    TBODY: 'table',
+    TD: 'table',
+    TFOOT: 'table',
+    TH: 'table',
+    THEAD: 'table',
+    TR: 'table'
+  },
+  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+  //       due to a Firefox bug
+  node: function(elementName) {
+    elementName = elementName.toUpperCase();
+    
+    // try innerHTML approach
+    var parentTag = this.NODEMAP[elementName] || 'div';
+    var parentElement = document.createElement(parentTag);
+    try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+      parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+    } catch(e) {}
+    var element = parentElement.firstChild || null;
+      
+    // see if browser added wrapping tags
+    if(element && (element.tagName.toUpperCase() != elementName))
+      element = element.getElementsByTagName(elementName)[0];
+    
+    // fallback to createElement approach
+    if(!element) element = document.createElement(elementName);
+    
+    // abort if nothing could be created
+    if(!element) return;
+
+    // attributes (or text)
+    if(arguments[1])
+      if(this._isStringOrNumber(arguments[1]) ||
+        (arguments[1] instanceof Array)) {
+          this._children(element, arguments[1]);
+        } else {
+          var attrs = this._attributes(arguments[1]);
+          if(attrs.length) {
+            try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+              parentElement.innerHTML = "<" +elementName + " " +
+                attrs + "></" + elementName + ">";
+            } catch(e) {}
+            element = parentElement.firstChild || null;
+            // workaround firefox 1.0.X bug
+            if(!element) {
+              element = document.createElement(elementName);
+              for(attr in arguments[1]) 
+                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+            }
+            if(element.tagName.toUpperCase() != elementName)
+              element = parentElement.getElementsByTagName(elementName)[0];
+            }
+        } 
+
+    // text, or array of children
+    if(arguments[2])
+      this._children(element, arguments[2]);
+
+     return element;
+  },
+  _text: function(text) {
+     return document.createTextNode(text);
+  },
+
+  ATTR_MAP: {
+    'className': 'class',
+    'htmlFor': 'for'
+  },
+
+  _attributes: function(attributes) {
+    var attrs = [];
+    for(attribute in attributes)
+      attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
+          '="' + attributes[attribute].toString().escapeHTML() + '"');
+    return attrs.join(" ");
+  },
+  _children: function(element, children) {
+    if(typeof children=='object') { // array can hold nodes and text
+      children.flatten().each( function(e) {
+        if(typeof e=='object')
+          element.appendChild(e)
+        else
+          if(Builder._isStringOrNumber(e))
+            element.appendChild(Builder._text(e));
+      });
+    } else
+      if(Builder._isStringOrNumber(children)) 
+         element.appendChild(Builder._text(children));
+  },
+  _isStringOrNumber: function(param) {
+    return(typeof param=='string' || typeof param=='number');
+  },
+  build: function(html) {
+    var element = this.node('div');
+    $(element).update(html.strip());
+    return element.down();
+  },
+  dump: function(scope) { 
+    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
+  
+    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
+      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
+      "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
+      "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
+      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
+      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
+  
+    tags.each( function(tag){ 
+      scope[tag] = function() { 
+        return Builder.node.apply(Builder, [tag].concat($A(arguments)));  
+      } 
+    });
+  }
+}
diff -ruN 2.0.5/wp-includes/js/scriptaculous/controls.js 2.2.2/wp-includes/js/scriptaculous/controls.js
--- 2.0.5/wp-includes/js/scriptaculous/controls.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/controls.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,835 @@
+// script.aculo.us controls.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+//           (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+//  Richard Livsey
+//  Rahul Bhargava
+//  Rob Wills
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// Autocompleter.Base handles all the autocompletion functionality 
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least, 
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method 
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most 
+// useful when one of the tokens is \n (a newline), as it 
+// allows smart autocompletion after linebreaks.
+
+if(typeof Effect == 'undefined')
+  throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = {}
+Autocompleter.Base = function() {};
+Autocompleter.Base.prototype = {
+  baseInitialize: function(element, update, options) {
+    this.element     = $(element); 
+    this.update      = $(update);  
+    this.hasFocus    = false; 
+    this.changed     = false; 
+    this.active      = false; 
+    this.index       = 0;     
+    this.entryCount  = 0;
+
+    if(this.setOptions)
+      this.setOptions(options);
+    else
+      this.options = options || {};
+
+    this.options.paramName    = this.options.paramName || this.element.name;
+    this.options.tokens       = this.options.tokens || [];
+    this.options.frequency    = this.options.frequency || 0.4;
+    this.options.minChars     = this.options.minChars || 1;
+    this.options.onShow       = this.options.onShow || 
+      function(element, update){ 
+        if(!update.style.position || update.style.position=='absolute') {
+          update.style.position = 'absolute';
+          Position.clone(element, update, {
+            setHeight: false, 
+            offsetTop: element.offsetHeight
+          });
+        }
+        Effect.Appear(update,{duration:0.15});
+      };
+    this.options.onHide = this.options.onHide || 
+      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+
+    if(typeof(this.options.tokens) == 'string') 
+      this.options.tokens = new Array(this.options.tokens);
+
+    this.observer = null;
+    
+    this.element.setAttribute('autocomplete','off');
+
+    Element.hide(this.update);
+
+    Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
+    Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+  },
+
+  show: function() {
+    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
+    if(!this.iefix && 
+      (navigator.appVersion.indexOf('MSIE')>0) &&
+      (navigator.userAgent.indexOf('Opera')<0) &&
+      (Element.getStyle(this.update, 'position')=='absolute')) {
+      new Insertion.After(this.update, 
+       '<iframe id="' + this.update.id + '_iefix" '+
+       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+      this.iefix = $(this.update.id+'_iefix');
+    }
+    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+  },
+  
+  fixIEOverlapping: function() {
+    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+    this.iefix.style.zIndex = 1;
+    this.update.style.zIndex = 2;
+    Element.show(this.iefix);
+  },
+
+  hide: function() {
+    this.stopIndicator();
+    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
+    if(this.iefix) Element.hide(this.iefix);
+  },
+
+  startIndicator: function() {
+    if(this.options.indicator) Element.show(this.options.indicator);
+  },
+
+  stopIndicator: function() {
+    if(this.options.indicator) Element.hide(this.options.indicator);
+  },
+
+  onKeyPress: function(event) {
+    if(this.active)
+      switch(event.keyCode) {
+       case Event.KEY_TAB:
+       case Event.KEY_RETURN:
+         this.selectEntry();
+         Event.stop(event);
+       case Event.KEY_ESC:
+         this.hide();
+         this.active = false;
+         Event.stop(event);
+         return;
+       case Event.KEY_LEFT:
+       case Event.KEY_RIGHT:
+         return;
+       case Event.KEY_UP:
+         this.markPrevious();
+         this.render();
+         if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+         return;
+       case Event.KEY_DOWN:
+         this.markNext();
+         this.render();
+         if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+         return;
+      }
+     else 
+       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
+         (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
+
+    this.changed = true;
+    this.hasFocus = true;
+
+    if(this.observer) clearTimeout(this.observer);
+      this.observer = 
+        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
+  },
+
+  activate: function() {
+    this.changed = false;
+    this.hasFocus = true;
+    this.getUpdatedChoices();
+  },
+
+  onHover: function(event) {
+    var element = Event.findElement(event, 'LI');
+    if(this.index != element.autocompleteIndex) 
+    {
+        this.index = element.autocompleteIndex;
+        this.render();
+    }
+    Event.stop(event);
+  },
+  
+  onClick: function(event) {
+    var element = Event.findElement(event, 'LI');
+    this.index = element.autocompleteIndex;
+    this.selectEntry();
+    this.hide();
+  },
+  
+  onBlur: function(event) {
+    // needed to make click events working
+    setTimeout(this.hide.bind(this), 250);
+    this.hasFocus = false;
+    this.active = false;     
+  }, 
+  
+  render: function() {
+    if(this.entryCount > 0) {
+      for (var i = 0; i < this.entryCount; i++)
+        this.index==i ? 
+          Element.addClassName(this.getEntry(i),"selected") : 
+          Element.removeClassName(this.getEntry(i),"selected");
+        
+      if(this.hasFocus) { 
+        this.show();
+        this.active = true;
+      }
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+  
+  markPrevious: function() {
+    if(this.index > 0) this.index--
+      else this.index = this.entryCount-1;
+    this.getEntry(this.index).scrollIntoView(true);
+  },
+  
+  markNext: function() {
+    if(this.index < this.entryCount-1) this.index++
+      else this.index = 0;
+    this.getEntry(this.index).scrollIntoView(false);
+  },
+  
+  getEntry: function(index) {
+    return this.update.firstChild.childNodes[index];
+  },
+  
+  getCurrentEntry: function() {
+    return this.getEntry(this.index);
+  },
+  
+  selectEntry: function() {
+    this.active = false;
+    this.updateElement(this.getCurrentEntry());
+  },
+
+  updateElement: function(selectedElement) {
+    if (this.options.updateElement) {
+      this.options.updateElement(selectedElement);
+      return;
+    }
+    var value = '';
+    if (this.options.select) {
+      var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
+      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
+    } else
+      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+    
+    var lastTokenPos = this.findLastToken();
+    if (lastTokenPos != -1) {
+      var newValue = this.element.value.substr(0, lastTokenPos + 1);
+      var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
+      if (whitespace)
+        newValue += whitespace[0];
+      this.element.value = newValue + value;
+    } else {
+      this.element.value = value;
+    }
+    this.element.focus();
+    
+    if (this.options.afterUpdateElement)
+      this.options.afterUpdateElement(this.element, selectedElement);
+  },
+
+  updateChoices: function(choices) {
+    if(!this.changed && this.hasFocus) {
+      this.update.innerHTML = choices;
+      Element.cleanWhitespace(this.update);
+      Element.cleanWhitespace(this.update.down());
+
+      if(this.update.firstChild && this.update.down().childNodes) {
+        this.entryCount = 
+          this.update.down().childNodes.length;
+        for (var i = 0; i < this.entryCount; i++) {
+          var entry = this.getEntry(i);
+          entry.autocompleteIndex = i;
+          this.addObservers(entry);
+        }
+      } else { 
+        this.entryCount = 0;
+      }
+
+      this.stopIndicator();
+      this.index = 0;
+      
+      if(this.entryCount==1 && this.options.autoSelect) {
+        this.selectEntry();
+        this.hide();
+      } else {
+        this.render();
+      }
+    }
+  },
+
+  addObservers: function(element) {
+    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+  },
+
+  onObserverEvent: function() {
+    this.changed = false;   
+    if(this.getToken().length>=this.options.minChars) {
+      this.startIndicator();
+      this.getUpdatedChoices();
+    } else {
+      this.active = false;
+      this.hide();
+    }
+  },
+
+  getToken: function() {
+    var tokenPos = this.findLastToken();
+    if (tokenPos != -1)
+      var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
+    else
+      var ret = this.element.value;
+
+    return /\n/.test(ret) ? '' : ret;
+  },
+
+  findLastToken: function() {
+    var lastTokenPos = -1;
+
+    for (var i=0; i<this.options.tokens.length; i++) {
+      var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
+      if (thisTokenPos > lastTokenPos)
+        lastTokenPos = thisTokenPos;
+    }
+    return lastTokenPos;
+  }
+}
+
+Ajax.Autocompleter = Class.create();
+Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
+  initialize: function(element, update, url, options) {
+    this.baseInitialize(element, update, options);
+    this.options.asynchronous  = true;
+    this.options.onComplete    = this.onComplete.bind(this);
+    this.options.defaultParams = this.options.parameters || null;
+    this.url                   = url;
+  },
+
+  getUpdatedChoices: function() {
+    entry = encodeURIComponent(this.options.paramName) + '=' + 
+      encodeURIComponent(this.getToken());
+
+    this.options.parameters = this.options.callback ?
+      this.options.callback(this.element, entry) : entry;
+
+    if(this.options.defaultParams) 
+      this.options.parameters += '&' + this.options.defaultParams;
+
+    new Ajax.Request(this.url, this.options);
+  },
+
+  onComplete: function(request) {
+    this.updateChoices(request.responseText);
+  }
+
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+//                    text only at the beginning of strings in the 
+//                    autocomplete array. Defaults to true, which will
+//                    match text at the beginning of any *word* in the
+//                    strings in the autocomplete array. If you want to
+//                    search anywhere in the string, additionally set
+//                    the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+//                   a partial match (unlike minChars, which defines
+//                   how many characters are required to do any match
+//                   at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+//                 Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector' 
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create();
+Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
+  initialize: function(element, update, array, options) {
+    this.baseInitialize(element, update, options);
+    this.options.array = array;
+  },
+
+  getUpdatedChoices: function() {
+    this.updateChoices(this.options.selector(this));
+  },
+
+  setOptions: function(options) {
+    this.options = Object.extend({
+      choices: 10,
+      partialSearch: true,
+      partialChars: 2,
+      ignoreCase: true,
+      fullSearch: false,
+      selector: function(instance) {
+        var ret       = []; // Beginning matches
+        var partial   = []; // Inside matches
+        var entry     = instance.getToken();
+        var count     = 0;
+
+        for (var i = 0; i < instance.options.array.length &&  
+          ret.length < instance.options.choices ; i++) { 
+
+          var elem = instance.options.array[i];
+          var foundPos = instance.options.ignoreCase ? 
+            elem.toLowerCase().indexOf(entry.toLowerCase()) : 
+            elem.indexOf(entry);
+
+          while (foundPos != -1) {
+            if (foundPos == 0 && elem.length != entry.length) { 
+              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
+                elem.substr(entry.length) + "</li>");
+              break;
+            } else if (entry.length >= instance.options.partialChars && 
+              instance.options.partialSearch && foundPos != -1) {
+              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
+                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+                  foundPos + entry.length) + "</li>");
+                break;
+              }
+            }
+
+            foundPos = instance.options.ignoreCase ? 
+              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
+              elem.indexOf(entry, foundPos + 1);
+
+          }
+        }
+        if (partial.length)
+          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+        return "<ul>" + ret.join('') + "</ul>";
+      }
+    }, options || {});
+  }
+});
+
+// AJAX in-place editor
+//
+// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field) {
+  setTimeout(function() {
+    Field.activate(field);
+  }, 1);
+}
+
+Ajax.InPlaceEditor = Class.create();
+Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
+Ajax.InPlaceEditor.prototype = {
+  initialize: function(element, url, options) {
+    this.url = url;
+    this.element = $(element);
+
+    this.options = Object.extend({
+      paramName: "value",
+      okButton: true,
+      okText: "ok",
+      cancelLink: true,
+      cancelText: "cancel",
+      savingText: "Saving...",
+      clickToEditText: "Click to edit",
+      okText: "ok",
+      rows: 1,
+      onComplete: function(transport, element) {
+        new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
+      },
+      onFailure: function(transport) {
+        alert("Error communicating with the server: " + transport.responseText.stripTags());
+      },
+      callback: function(form) {
+        return Form.serialize(form);
+      },
+      handleLineBreaks: true,
+      loadingText: 'Loading...',
+      savingClassName: 'inplaceeditor-saving',
+      loadingClassName: 'inplaceeditor-loading',
+      formClassName: 'inplaceeditor-form',
+      highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
+      highlightendcolor: "#FFFFFF",
+      externalControl: null,
+      submitOnBlur: false,
+      ajaxOptions: {},
+      evalScripts: false
+    }, options || {});
+
+    if(!this.options.formId && this.element.id) {
+      this.options.formId = this.element.id + "-inplaceeditor";
+      if ($(this.options.formId)) {
+        // there's already a form with that name, don't specify an id
+        this.options.formId = null;
+      }
+    }
+    
+    if (this.options.externalControl) {
+      this.options.externalControl = $(this.options.externalControl);
+    }
+    
+    this.originalBackground = Element.getStyle(this.element, 'background-color');
+    if (!this.originalBackground) {
+      this.originalBackground = "transparent";
+    }
+    
+    this.element.title = this.options.clickToEditText;
+    
+    this.onclickListener = this.enterEditMode.bindAsEventListener(this);
+    this.mouseoverListener = this.enterHover.bindAsEventListener(this);
+    this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
+    Event.observe(this.element, 'click', this.onclickListener);
+    Event.observe(this.element, 'mouseover', this.mouseoverListener);
+    Event.observe(this.element, 'mouseout', this.mouseoutListener);
+    if (this.options.externalControl) {
+      Event.observe(this.options.externalControl, 'click', this.onclickListener);
+      Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+      Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+    }
+  },
+  enterEditMode: function(evt) {
+    if (this.saving) return;
+    if (this.editing) return;
+    this.editing = true;
+    this.onEnterEditMode();
+    if (this.options.externalControl) {
+      Element.hide(this.options.externalControl);
+    }
+    Element.hide(this.element);
+    this.createForm();
+    this.element.parentNode.insertBefore(this.form, this.element);
+    if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
+    // stop the event to avoid a page refresh in Safari
+    if (evt) {
+      Event.stop(evt);
+    }
+    return false;
+  },
+  createForm: function() {
+    this.form = document.createElement("form");
+    this.form.id = this.options.formId;
+    Element.addClassName(this.form, this.options.formClassName)
+    this.form.onsubmit = this.onSubmit.bind(this);
+
+    this.createEditField();
+
+    if (this.options.textarea) {
+      var br = document.createElement("br");
+      this.form.appendChild(br);
+    }
+
+    if (this.options.okButton) {
+      okButton = document.createElement("input");
+      okButton.type = "submit";
+      okButton.value = this.options.okText;
+      okButton.className = 'editor_ok_button';
+      this.form.appendChild(okButton);
+    }
+
+    if (this.options.cancelLink) {
+      cancelLink = document.createElement("a");
+      cancelLink.href = "#";
+      cancelLink.appendChild(document.createTextNode(this.options.cancelText));
+      cancelLink.onclick = this.onclickCancel.bind(this);
+      cancelLink.className = 'editor_cancel';      
+      this.form.appendChild(cancelLink);
+    }
+  },
+  hasHTMLLineBreaks: function(string) {
+    if (!this.options.handleLineBreaks) return false;
+    return string.match(/<br/i) || string.match(/<p>/i);
+  },
+  convertHTMLLineBreaks: function(string) {
+    return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
+  },
+  createEditField: function() {
+    var text;
+    if(this.options.loadTextURL) {
+      text = this.options.loadingText;
+    } else {
+      text = this.getText();
+    }
+
+    var obj = this;
+    
+    if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
+      this.options.textarea = false;
+      var textField = document.createElement("input");
+      textField.obj = this;
+      textField.type = "text";
+      textField.name = this.options.paramName;
+      textField.value = text;
+      textField.style.backgroundColor = this.options.highlightcolor;
+      textField.className = 'editor_field';
+      var size = this.options.size || this.options.cols || 0;
+      if (size != 0) textField.size = size;
+      if (this.options.submitOnBlur)
+        textField.onblur = this.onSubmit.bind(this);
+      this.editField = textField;
+    } else {
+      this.options.textarea = true;
+      var textArea = document.createElement("textarea");
+      textArea.obj = this;
+      textArea.name = this.options.paramName;
+      textArea.value = this.convertHTMLLineBreaks(text);
+      textArea.rows = this.options.rows;
+      textArea.cols = this.options.cols || 40;
+      textArea.className = 'editor_field';      
+      if (this.options.submitOnBlur)
+        textArea.onblur = this.onSubmit.bind(this);
+      this.editField = textArea;
+    }
+    
+    if(this.options.loadTextURL) {
+      this.loadExternalText();
+    }
+    this.form.appendChild(this.editField);
+  },
+  getText: function() {
+    return this.element.innerHTML;
+  },
+  loadExternalText: function() {
+    Element.addClassName(this.form, this.options.loadingClassName);
+    this.editField.disabled = true;
+    new Ajax.Request(
+      this.options.loadTextURL,
+      Object.extend({
+        asynchronous: true,
+        onComplete: this.onLoadedExternalText.bind(this)
+      }, this.options.ajaxOptions)
+    );
+  },
+  onLoadedExternalText: function(transport) {
+    Element.removeClassName(this.form, this.options.loadingClassName);
+    this.editField.disabled = false;
+    this.editField.value = transport.responseText.stripTags();
+    Field.scrollFreeActivate(this.editField);
+  },
+  onclickCancel: function() {
+    this.onComplete();
+    this.leaveEditMode();
+    return false;
+  },
+  onFailure: function(transport) {
+    this.options.onFailure(transport);
+    if (this.oldInnerHTML) {
+      this.element.innerHTML = this.oldInnerHTML;
+      this.oldInnerHTML = null;
+    }
+    return false;
+  },
+  onSubmit: function() {
+    // onLoading resets these so we need to save them away for the Ajax call
+    var form = this.form;
+    var value = this.editField.value;
+    
+    // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
+    // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
+    // to be displayed indefinitely
+    this.onLoading();
+    
+    if (this.options.evalScripts) {
+      new Ajax.Request(
+        this.url, Object.extend({
+          parameters: this.options.callback(form, value),
+          onComplete: this.onComplete.bind(this),
+          onFailure: this.onFailure.bind(this),
+          asynchronous:true, 
+          evalScripts:true
+        }, this.options.ajaxOptions));
+    } else  {
+      new Ajax.Updater(
+        { success: this.element,
+          // don't update on failure (this could be an option)
+          failure: null }, 
+        this.url, Object.extend({
+          parameters: this.options.callback(form, value),
+          onComplete: this.onComplete.bind(this),
+          onFailure: this.onFailure.bind(this)
+        }, this.options.ajaxOptions));
+    }
+    // stop the event to avoid a page refresh in Safari
+    if (arguments.length > 1) {
+      Event.stop(arguments[0]);
+    }
+    return false;
+  },
+  onLoading: function() {
+    this.saving = true;
+    this.removeForm();
+    this.leaveHover();
+    this.showSaving();
+  },
+  showSaving: function() {
+    this.oldInnerHTML = this.element.innerHTML;
+    this.element.innerHTML = this.options.savingText;
+    Element.addClassName(this.element, this.options.savingClassName);
+    this.element.style.backgroundColor = this.originalBackground;
+    Element.show(this.element);
+  },
+  removeForm: function() {
+    if(this.form) {
+      if (this.form.parentNode) Element.remove(this.form);
+      this.form = null;
+    }
+  },
+  enterHover: function() {
+    if (this.saving) return;
+    this.element.style.backgroundColor = this.options.highlightcolor;
+    if (this.effect) {
+      this.effect.cancel();
+    }
+    Element.addClassName(this.element, this.options.hoverClassName)
+  },
+  leaveHover: function() {
+    if (this.options.backgroundColor) {
+      this.element.style.backgroundColor = this.oldBackground;
+    }
+    Element.removeClassName(this.element, this.options.hoverClassName)
+    if (this.saving) return;
+    this.effect = new Effect.Highlight(this.element, {
+      startcolor: this.options.highlightcolor,
+      endcolor: this.options.highlightendcolor,
+      restorecolor: this.originalBackground
+    });
+  },
+  leaveEditMode: function() {
+    Element.removeClassName(this.element, this.options.savingClassName);
+    this.removeForm();
+    this.leaveHover();
+    this.element.style.backgroundColor = this.originalBackground;
+    Element.show(this.element);
+    if (this.options.externalControl) {
+      Element.show(this.options.externalControl);
+    }
+    this.editing = false;
+    this.saving = false;
+    this.oldInnerHTML = null;
+    this.onLeaveEditMode();
+  },
+  onComplete: function(transport) {
+    this.leaveEditMode();
+    this.options.onComplete.bind(this)(transport, this.element);
+  },
+  onEnterEditMode: function() {},
+  onLeaveEditMode: function() {},
+  dispose: function() {
+    if (this.oldInnerHTML) {
+      this.element.innerHTML = this.oldInnerHTML;
+    }
+    this.leaveEditMode();
+    Event.stopObserving(this.element, 'click', this.onclickListener);
+    Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
+    Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
+    if (this.options.externalControl) {
+      Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
+      Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
+      Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
+    }
+  }
+};
+
+Ajax.InPlaceCollectionEditor = Class.create();
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
+  createEditField: function() {
+    if (!this.cached_selectTag) {
+      var selectTag = document.createElement("select");
+      var collection = this.options.collection || [];
+      var optionTag;
+      collection.each(function(e,i) {
+        optionTag = document.createElement("option");
+        optionTag.value = (e instanceof Array) ? e[0] : e;
+        if((typeof this.options.value == 'undefined') && 
+          ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
+        if(this.options.value==optionTag.value) optionTag.selected = true;
+        optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
+        selectTag.appendChild(optionTag);
+      }.bind(this));
+      this.cached_selectTag = selectTag;
+    }
+
+    this.editField = this.cached_selectTag;
+    if(this.options.loadTextURL) this.loadExternalText();
+    this.form.appendChild(this.editField);
+    this.options.callback = function(form, value) {
+      return "value=" + encodeURIComponent(value);
+    }
+  }
+});
+
+// Delayed observer, like Form.Element.Observer, 
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create();
+Form.Element.DelayedObserver.prototype = {
+  initialize: function(element, delay, callback) {
+    this.delay     = delay || 0.5;
+    this.element   = $(element);
+    this.callback  = callback;
+    this.timer     = null;
+    this.lastValue = $F(this.element); 
+    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+  },
+  delayedListener: function(event) {
+    if(this.lastValue == $F(this.element)) return;
+    if(this.timer) clearTimeout(this.timer);
+    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+    this.lastValue = $F(this.element);
+  },
+  onTimerEvent: function() {
+    this.timer = null;
+    this.callback(this.element, $F(this.element));
+  }
+};
diff -ruN 2.0.5/wp-includes/js/scriptaculous/dragdrop.js 2.2.2/wp-includes/js/scriptaculous/dragdrop.js
--- 2.0.5/wp-includes/js/scriptaculous/dragdrop.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/dragdrop.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,944 @@
+// script.aculo.us dragdrop.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if(typeof Effect == 'undefined')
+  throw("dragdrop.js requires including script.aculo.us' effects.js library");
+
+var Droppables = {
+  drops: [],
+
+  remove: function(element) {
+    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
+  },
+
+  add: function(element) {
+    element = $(element);
+    var options = Object.extend({
+      greedy:     true,
+      hoverclass: null,
+      tree:       false
+    }, arguments[1] || {});
+
+    // cache containers
+    if(options.containment) {
+      options._containers = [];
+      var containment = options.containment;
+      if((typeof containment == 'object') && 
+        (containment.constructor == Array)) {
+        containment.each( function(c) { options._containers.push($(c)) });
+      } else {
+        options._containers.push($(containment));
+      }
+    }
+    
+    if(options.accept) options.accept = [options.accept].flatten();
+
+    Element.makePositioned(element); // fix IE
+    options.element = element;
+
+    this.drops.push(options);
+  },
+  
+  findDeepestChild: function(drops) {
+    deepest = drops[0];
+      
+    for (i = 1; i < drops.length; ++i)
+      if (Element.isParent(drops[i].element, deepest.element))
+        deepest = drops[i];
+    
+    return deepest;
+  },
+
+  isContained: function(element, drop) {
+    var containmentNode;
+    if(drop.tree) {
+      containmentNode = element.treeNode; 
+    } else {
+      containmentNode = element.parentNode;
+    }
+    return drop._containers.detect(function(c) { return containmentNode == c });
+  },
+  
+  isAffected: function(point, element, drop) {
+    return (
+      (drop.element!=element) &&
+      ((!drop._containers) ||
+        this.isContained(element, drop)) &&
+      ((!drop.accept) ||
+        (Element.classNames(element).detect( 
+          function(v) { return drop.accept.include(v) } ) )) &&
+      Position.within(drop.element, point[0], point[1]) );
+  },
+
+  deactivate: function(drop) {
+    if(drop.hoverclass)
+      Element.removeClassName(drop.element, drop.hoverclass);
+    this.last_active = null;
+  },
+
+  activate: function(drop) {
+    if(drop.hoverclass)
+      Element.addClassName(drop.element, drop.hoverclass);
+    this.last_active = drop;
+  },
+
+  show: function(point, element) {
+    if(!this.drops.length) return;
+    var affected = [];
+    
+    if(this.last_active) this.deactivate(this.last_active);
+    this.drops.each( function(drop) {
+      if(Droppables.isAffected(point, element, drop))
+        affected.push(drop);
+    });
+        
+    if(affected.length>0) {
+      drop = Droppables.findDeepestChild(affected);
+      Position.within(drop.element, point[0], point[1]);
+      if(drop.onHover)
+        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+      
+      Droppables.activate(drop);
+    }
+  },
+
+  fire: function(event, element) {
+    if(!this.last_active) return;
+    Position.prepare();
+
+    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
+      if (this.last_active.onDrop) 
+        this.last_active.onDrop(element, this.last_active.element, event);
+  },
+
+  reset: function() {
+    if(this.last_active)
+      this.deactivate(this.last_active);
+  }
+}
+
+var Draggables = {
+  drags: [],
+  observers: [],
+  
+  register: function(draggable) {
+    if(this.drags.length == 0) {
+      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
+      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
+      
+      Event.observe(document, "mouseup", this.eventMouseUp);
+      Event.observe(document, "mousemove", this.eventMouseMove);
+      Event.observe(document, "keypress", this.eventKeypress);
+    }
+    this.drags.push(draggable);
+  },
+  
+  unregister: function(draggable) {
+    this.drags = this.drags.reject(function(d) { return d==draggable });
+    if(this.drags.length == 0) {
+      Event.stopObserving(document, "mouseup", this.eventMouseUp);
+      Event.stopObserving(document, "mousemove", this.eventMouseMove);
+      Event.stopObserving(document, "keypress", this.eventKeypress);
+    }
+  },
+  
+  activate: function(draggable) {
+    if(draggable.options.delay) { 
+      this._timeout = setTimeout(function() { 
+        Draggables._timeout = null; 
+        window.focus(); 
+        Draggables.activeDraggable = draggable; 
+      }.bind(this), draggable.options.delay); 
+    } else {
+      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+      this.activeDraggable = draggable;
+    }
+  },
+  
+  deactivate: function() {
+    this.activeDraggable = null;
+  },
+  
+  updateDrag: function(event) {
+    if(!this.activeDraggable) return;
+    var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    // Mozilla-based browsers fire successive mousemove events with
+    // the same coordinates, prevent needless redrawing (moz bug?)
+    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
+    this._lastPointer = pointer;
+    
+    this.activeDraggable.updateDrag(event, pointer);
+  },
+  
+  endDrag: function(event) {
+    if(this._timeout) { 
+      clearTimeout(this._timeout); 
+      this._timeout = null; 
+    }
+    if(!this.activeDraggable) return;
+    this._lastPointer = null;
+    this.activeDraggable.endDrag(event);
+    this.activeDraggable = null;
+  },
+  
+  keyPress: function(event) {
+    if(this.activeDraggable)
+      this.activeDraggable.keyPress(event);
+  },
+  
+  addObserver: function(observer) {
+    this.observers.push(observer);
+    this._cacheObserverCallbacks();
+  },
+  
+  removeObserver: function(element) {  // element instead of observer fixes mem leaks
+    this.observers = this.observers.reject( function(o) { return o.element==element });
+    this._cacheObserverCallbacks();
+  },
+  
+  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
+    if(this[eventName+'Count'] > 0)
+      this.observers.each( function(o) {
+        if(o[eventName]) o[eventName](eventName, draggable, event);
+      });
+    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
+  },
+  
+  _cacheObserverCallbacks: function() {
+    ['onStart','onEnd','onDrag'].each( function(eventName) {
+      Draggables[eventName+'Count'] = Draggables.observers.select(
+        function(o) { return o[eventName]; }
+      ).length;
+    });
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Draggable = Class.create();
+Draggable._dragging    = {};
+
+Draggable.prototype = {
+  initialize: function(element) {
+    var defaults = {
+      handle: false,
+      reverteffect: function(element, top_offset, left_offset) {
+        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
+        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+          queue: {scope:'_draggable', position:'end'}
+        });
+      },
+      endeffect: function(element) {
+        var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 
+          queue: {scope:'_draggable', position:'end'},
+          afterFinish: function(){ 
+            Draggable._dragging[element] = false 
+          }
+        }); 
+      },
+      zindex: 1000,
+      revert: false,
+      scroll: false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
+      delay: 0
+    };
+    
+    if(!arguments[1] || typeof arguments[1].endeffect == 'undefined')
+      Object.extend(defaults, {
+        starteffect: function(element) {
+          element._opacity = Element.getOpacity(element);
+          Draggable._dragging[element] = true;
+          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 
+        }
+      });
+    
+    var options = Object.extend(defaults, arguments[1] || {});
+
+    this.element = $(element);
+    
+    if(options.handle && (typeof options.handle == 'string'))
+      this.handle = this.element.down('.'+options.handle, 0);
+    
+    if(!this.handle) this.handle = $(options.handle);
+    if(!this.handle) this.handle = this.element;
+    
+    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
+      options.scroll = $(options.scroll);
+      this._isScrollChild = Element.childOf(this.element, options.scroll);
+    }
+
+    Element.makePositioned(this.element); // fix IE    
+
+    this.delta    = this.currentDelta();
+    this.options  = options;
+    this.dragging = false;   
+
+    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+    Event.observe(this.handle, "mousedown", this.eventMouseDown);
+    
+    Draggables.register(this);
+  },
+  
+  destroy: function() {
+    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+    Draggables.unregister(this);
+  },
+  
+  currentDelta: function() {
+    return([
+      parseInt(Element.getStyle(this.element,'left') || '0'),
+      parseInt(Element.getStyle(this.element,'top') || '0')]);
+  },
+  
+  initDrag: function(event) {
+    if(typeof Draggable._dragging[this.element] != 'undefined' &&
+      Draggable._dragging[this.element]) return;
+    if(Event.isLeftClick(event)) {    
+      // abort on form elements, fixes a Firefox issue
+      var src = Event.element(event);
+      if((tag_name = src.tagName.toUpperCase()) && (
+        tag_name=='INPUT' ||
+        tag_name=='SELECT' ||
+        tag_name=='OPTION' ||
+        tag_name=='BUTTON' ||
+        tag_name=='TEXTAREA')) return;
+        
+      var pointer = [Event.pointerX(event), Event.pointerY(event)];
+      var pos     = Position.cumulativeOffset(this.element);
+      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
+      
+      Draggables.activate(this);
+      Event.stop(event);
+    }
+  },
+  
+  startDrag: function(event) {
+    this.dragging = true;
+    
+    if(this.options.zindex) {
+      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
+      this.element.style.zIndex = this.options.zindex;
+    }
+    
+    if(this.options.ghosting) {
+      this._clone = this.element.cloneNode(true);
+      Position.absolutize(this.element);
+      this.element.parentNode.insertBefore(this._clone, this.element);
+    }
+    
+    if(this.options.scroll) {
+      if (this.options.scroll == window) {
+        var where = this._getWindowScroll(this.options.scroll);
+        this.originalScrollLeft = where.left;
+        this.originalScrollTop = where.top;
+      } else {
+        this.originalScrollLeft = this.options.scroll.scrollLeft;
+        this.originalScrollTop = this.options.scroll.scrollTop;
+      }
+    }
+    
+    Draggables.notify('onStart', this, event);
+        
+    if(this.options.starteffect) this.options.starteffect(this.element);
+  },
+  
+  updateDrag: function(event, pointer) {
+    if(!this.dragging) this.startDrag(event);
+    Position.prepare();
+    Droppables.show(pointer, this.element);
+    Draggables.notify('onDrag', this, event);
+    
+    this.draw(pointer);
+    if(this.options.change) this.options.change(this);
+    
+    if(this.options.scroll) {
+      this.stopScrolling();
+      
+      var p;
+      if (this.options.scroll == window) {
+        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
+      } else {
+        p = Position.page(this.options.scroll);
+        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
+        p[1] += this.options.scroll.scrollTop + Position.deltaY;
+        p.push(p[0]+this.options.scroll.offsetWidth);
+        p.push(p[1]+this.options.scroll.offsetHeight);
+      }
+      var speed = [0,0];
+      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
+      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
+      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
+      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
+      this.startScrolling(speed);
+    }
+    
+    // fix AppleWebKit rendering
+    if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+    
+    Event.stop(event);
+  },
+  
+  finishDrag: function(event, success) {
+    this.dragging = false;
+
+    if(this.options.ghosting) {
+      Position.relativize(this.element);
+      Element.remove(this._clone);
+      this._clone = null;
+    }
+
+    if(success) Droppables.fire(event, this.element);
+    Draggables.notify('onEnd', this, event);
+
+    var revert = this.options.revert;
+    if(revert && typeof revert == 'function') revert = revert(this.element);
+    
+    var d = this.currentDelta();
+    if(revert && this.options.reverteffect) {
+      this.options.reverteffect(this.element, 
+        d[1]-this.delta[1], d[0]-this.delta[0]);
+    } else {
+      this.delta = d;
+    }
+
+    if(this.options.zindex)
+      this.element.style.zIndex = this.originalZ;
+
+    if(this.options.endeffect) 
+      this.options.endeffect(this.element);
+      
+    Draggables.deactivate(this);
+    Droppables.reset();
+  },
+  
+  keyPress: function(event) {
+    if(event.keyCode!=Event.KEY_ESC) return;
+    this.finishDrag(event, false);
+    Event.stop(event);
+  },
+  
+  endDrag: function(event) {
+    if(!this.dragging) return;
+    this.stopScrolling();
+    this.finishDrag(event, true);
+    Event.stop(event);
+  },
+  
+  draw: function(point) {
+    var pos = Position.cumulativeOffset(this.element);
+    if(this.options.ghosting) {
+      var r   = Position.realOffset(this.element);
+      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
+    }
+    
+    var d = this.currentDelta();
+    pos[0] -= d[0]; pos[1] -= d[1];
+    
+    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
+      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
+      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
+    }
+    
+    var p = [0,1].map(function(i){ 
+      return (point[i]-pos[i]-this.offset[i]) 
+    }.bind(this));
+    
+    if(this.options.snap) {
+      if(typeof this.options.snap == 'function') {
+        p = this.options.snap(p[0],p[1],this);
+      } else {
+      if(this.options.snap instanceof Array) {
+        p = p.map( function(v, i) {
+          return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
+      } else {
+        p = p.map( function(v) {
+          return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
+      }
+    }}
+    
+    var style = this.element.style;
+    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
+      style.left = p[0] + "px";
+    if((!this.options.constraint) || (this.options.constraint=='vertical'))
+      style.top  = p[1] + "px";
+    
+    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
+  },
+  
+  stopScrolling: function() {
+    if(this.scrollInterval) {
+      clearInterval(this.scrollInterval);
+      this.scrollInterval = null;
+      Draggables._lastScrollPointer = null;
+    }
+  },
+  
+  startScrolling: function(speed) {
+    if(!(speed[0] || speed[1])) return;
+    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
+    this.lastScrolled = new Date();
+    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
+  },
+  
+  scroll: function() {
+    var current = new Date();
+    var delta = current - this.lastScrolled;
+    this.lastScrolled = current;
+    if(this.options.scroll == window) {
+      with (this._getWindowScroll(this.options.scroll)) {
+        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
+          var d = delta / 1000;
+          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
+        }
+      }
+    } else {
+      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
+    }
+    
+    Position.prepare();
+    Droppables.show(Draggables._lastPointer, this.element);
+    Draggables.notify('onDrag', this);
+    if (this._isScrollChild) {
+      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+      if (Draggables._lastScrollPointer[0] < 0)
+        Draggables._lastScrollPointer[0] = 0;
+      if (Draggables._lastScrollPointer[1] < 0)
+        Draggables._lastScrollPointer[1] = 0;
+      this.draw(Draggables._lastScrollPointer);
+    }
+    
+    if(this.options.change) this.options.change(this);
+  },
+  
+  _getWindowScroll: function(w) {
+    var T, L, W, H;
+    with (w.document) {
+      if (w.document.documentElement && documentElement.scrollTop) {
+        T = documentElement.scrollTop;
+        L = documentElement.scrollLeft;
+      } else if (w.document.body) {
+        T = body.scrollTop;
+        L = body.scrollLeft;
+      }
+      if (w.innerWidth) {
+        W = w.innerWidth;
+        H = w.innerHeight;
+      } else if (w.document.documentElement && documentElement.clientWidth) {
+        W = documentElement.clientWidth;
+        H = documentElement.clientHeight;
+      } else {
+        W = body.offsetWidth;
+        H = body.offsetHeight
+      }
+    }
+    return { top: T, left: L, width: W, height: H };
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create();
+SortableObserver.prototype = {
+  initialize: function(element, observer) {
+    this.element   = $(element);
+    this.observer  = observer;
+    this.lastValue = Sortable.serialize(this.element);
+  },
+  
+  onStart: function() {
+    this.lastValue = Sortable.serialize(this.element);
+  },
+  
+  onEnd: function() {
+    Sortable.unmark();
+    if(this.lastValue != Sortable.serialize(this.element))
+      this.observer(this.element)
+  }
+}
+
+var Sortable = {
+  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
+  
+  sortables: {},
+  
+  _findRootElement: function(element) {
+    while (element.tagName.toUpperCase() != "BODY") {  
+      if(element.id && Sortable.sortables[element.id]) return element;
+      element = element.parentNode;
+    }
+  },
+
+  options: function(element) {
+    element = Sortable._findRootElement($(element));
+    if(!element) return;
+    return Sortable.sortables[element.id];
+  },
+  
+  destroy: function(element){
+    var s = Sortable.options(element);
+    
+    if(s) {
+      Draggables.removeObserver(s.element);
+      s.droppables.each(function(d){ Droppables.remove(d) });
+      s.draggables.invoke('destroy');
+      
+      delete Sortable.sortables[s.element.id];
+    }
+  },
+
+  create: function(element) {
+    element = $(element);
+    var options = Object.extend({ 
+      element:     element,
+      tag:         'li',       // assumes li children, override with tag: 'tagname'
+      dropOnEmpty: false,
+      tree:        false,
+      treeTag:     'ul',
+      overlap:     'vertical', // one of 'vertical', 'horizontal'
+      constraint:  'vertical', // one of 'vertical', 'horizontal', false
+      containment: element,    // also takes array of elements (or id's); or false
+      handle:      false,      // or a CSS class
+      only:        false,
+      delay:       0,
+      hoverclass:  null,
+      ghosting:    false,
+      scroll:      false,
+      scrollSensitivity: 20,
+      scrollSpeed: 15,
+      format:      this.SERIALIZE_RULE,
+      onChange:    Prototype.emptyFunction,
+      onUpdate:    Prototype.emptyFunction
+    }, arguments[1] || {});
+
+    // clear any old sortable with same element
+    this.destroy(element);
+
+    // build options for the draggables
+    var options_for_draggable = {
+      revert:      true,
+      scroll:      options.scroll,
+      scrollSpeed: options.scrollSpeed,
+      scrollSensitivity: options.scrollSensitivity,
+      delay:       options.delay,
+      ghosting:    options.ghosting,
+      constraint:  options.constraint,
+      handle:      options.handle };
+
+    if(options.starteffect)
+      options_for_draggable.starteffect = options.starteffect;
+
+    if(options.reverteffect)
+      options_for_draggable.reverteffect = options.reverteffect;
+    else
+      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
+        element.style.top  = 0;
+        element.style.left = 0;
+      };
+
+    if(options.endeffect)
+      options_for_draggable.endeffect = options.endeffect;
+
+    if(options.zindex)
+      options_for_draggable.zindex = options.zindex;
+
+    // build options for the droppables  
+    var options_for_droppable = {
+      overlap:     options.overlap,
+      containment: options.containment,
+      tree:        options.tree,
+      hoverclass:  options.hoverclass,
+      onHover:     Sortable.onHover
+    }
+    
+    var options_for_tree = {
+      onHover:      Sortable.onEmptyHover,
+      overlap:      options.overlap,
+      containment:  options.containment,
+      hoverclass:   options.hoverclass
+    }
+
+    // fix for gecko engine
+    Element.cleanWhitespace(element); 
+
+    options.draggables = [];
+    options.droppables = [];
+
+    // drop on empty handling
+    if(options.dropOnEmpty || options.tree) {
+      Droppables.add(element, options_for_tree);
+      options.droppables.push(element);
+    }
+
+    (this.findElements(element, options) || []).each( function(e) {
+      // handles are per-draggable
+      var handle = options.handle ? 
+        $(e).down('.'+options.handle,0) : e;    
+      options.draggables.push(
+        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+      Droppables.add(e, options_for_droppable);
+      if(options.tree) e.treeNode = element;
+      options.droppables.push(e);      
+    });
+    
+    if(options.tree) {
+      (Sortable.findTreeElements(element, options) || []).each( function(e) {
+        Droppables.add(e, options_for_tree);
+        e.treeNode = element;
+        options.droppables.push(e);
+      });
+    }
+
+    // keep reference
+    this.sortables[element.id] = options;
+
+    // for onupdate
+    Draggables.addObserver(new SortableObserver(element, options.onUpdate));
+
+  },
+
+  // return all suitable-for-sortable elements in a guaranteed order
+  findElements: function(element, options) {
+    return Element.findChildren(
+      element, options.only, options.tree ? true : false, options.tag);
+  },
+  
+  findTreeElements: function(element, options) {
+    return Element.findChildren(
+      element, options.only, options.tree ? true : false, options.treeTag);
+  },
+
+  onHover: function(element, dropon, overlap) {
+    if(Element.isParent(dropon, element)) return;
+
+    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
+      return;
+    } else if(overlap>0.5) {
+      Sortable.mark(dropon, 'before');
+      if(dropon.previousSibling != element) {
+        var oldParentNode = element.parentNode;
+        element.style.visibility = "hidden"; // fix gecko rendering
+        dropon.parentNode.insertBefore(element, dropon);
+        if(dropon.parentNode!=oldParentNode) 
+          Sortable.options(oldParentNode).onChange(element);
+        Sortable.options(dropon.parentNode).onChange(element);
+      }
+    } else {
+      Sortable.mark(dropon, 'after');
+      var nextElement = dropon.nextSibling || null;
+      if(nextElement != element) {
+        var oldParentNode = element.parentNode;
+        element.style.visibility = "hidden"; // fix gecko rendering
+        dropon.parentNode.insertBefore(element, nextElement);
+        if(dropon.parentNode!=oldParentNode) 
+          Sortable.options(oldParentNode).onChange(element);
+        Sortable.options(dropon.parentNode).onChange(element);
+      }
+    }
+  },
+  
+  onEmptyHover: function(element, dropon, overlap) {
+    var oldParentNode = element.parentNode;
+    var droponOptions = Sortable.options(dropon);
+        
+    if(!Element.isParent(dropon, element)) {
+      var index;
+      
+      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
+      var child = null;
+            
+      if(children) {
+        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+        
+        for (index = 0; index < children.length; index += 1) {
+          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
+            offset -= Element.offsetSize (children[index], droponOptions.overlap);
+          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
+            child = index + 1 < children.length ? children[index + 1] : null;
+            break;
+          } else {
+            child = children[index];
+            break;
+          }
+        }
+      }
+      
+      dropon.insertBefore(element, child);
+      
+      Sortable.options(oldParentNode).onChange(element);
+      droponOptions.onChange(element);
+    }
+  },
+
+  unmark: function() {
+    if(Sortable._marker) Sortable._marker.hide();
+  },
+
+  mark: function(dropon, position) {
+    // mark on ghosting only
+    var sortable = Sortable.options(dropon.parentNode);
+    if(sortable && !sortable.ghosting) return; 
+
+    if(!Sortable._marker) {
+      Sortable._marker = 
+        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
+          hide().addClassName('dropmarker').setStyle({position:'absolute'});
+      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+    }    
+    var offsets = Position.cumulativeOffset(dropon);
+    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
+    
+    if(position=='after')
+      if(sortable.overlap == 'horizontal') 
+        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
+      else
+        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
+    
+    Sortable._marker.show();
+  },
+  
+  _tree: function(element, options, parent) {
+    var children = Sortable.findElements(element, options) || [];
+  
+    for (var i = 0; i < children.length; ++i) {
+      var match = children[i].id.match(options.format);
+
+      if (!match) continue;
+      
+      var child = {
+        id: encodeURIComponent(match ? match[1] : null),
+        element: element,
+        parent: parent,
+        children: [],
+        position: parent.children.length,
+        container: $(children[i]).down(options.treeTag)
+      }
+      
+      /* Get the element containing the children and recurse over it */
+      if (child.container)
+        this._tree(child.container, options, child)
+      
+      parent.children.push (child);
+    }
+
+    return parent; 
+  },
+
+  tree: function(element) {
+    element = $(element);
+    var sortableOptions = this.options(element);
+    var options = Object.extend({
+      tag: sortableOptions.tag,
+      treeTag: sortableOptions.treeTag,
+      only: sortableOptions.only,
+      name: element.id,
+      format: sortableOptions.format
+    }, arguments[1] || {});
+    
+    var root = {
+      id: null,
+      parent: null,
+      children: [],
+      container: element,
+      position: 0
+    }
+    
+    return Sortable._tree(element, options, root);
+  },
+
+  /* Construct a [i] index for a particular node */
+  _constructIndex: function(node) {
+    var index = '';
+    do {
+      if (node.id) index = '[' + node.position + ']' + index;
+    } while ((node = node.parent) != null);
+    return index;
+  },
+
+  sequence: function(element) {
+    element = $(element);
+    var options = Object.extend(this.options(element), arguments[1] || {});
+    
+    return $(this.findElements(element, options) || []).map( function(item) {
+      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+    });
+  },
+
+  setSequence: function(element, new_sequence) {
+    element = $(element);
+    var options = Object.extend(this.options(element), arguments[2] || {});
+    
+    var nodeMap = {};
+    this.findElements(element, options).each( function(n) {
+        if (n.id.match(options.format))
+            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
+        n.parentNode.removeChild(n);
+    });
+   
+    new_sequence.each(function(ident) {
+      var n = nodeMap[ident];
+      if (n) {
+        n[1].appendChild(n[0]);
+        delete nodeMap[ident];
+      }
+    });
+  },
+  
+  serialize: function(element) {
+    element = $(element);
+    var options = Object.extend(Sortable.options(element), arguments[1] || {});
+    var name = encodeURIComponent(
+      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
+    
+    if (options.tree) {
+      return Sortable.tree(element, arguments[1]).children.map( function (item) {
+        return [name + Sortable._constructIndex(item) + "[id]=" + 
+                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+      }).flatten().join('&');
+    } else {
+      return Sortable.sequence(element, arguments[1]).map( function(item) {
+        return name + "[]=" + encodeURIComponent(item);
+      }).join('&');
+    }
+  }
+}
+
+// Returns true if child is contained within element
+Element.isParent = function(child, element) {
+  if (!child.parentNode || child == element) return false;
+  if (child.parentNode == element) return true;
+  return Element.isParent(child.parentNode, element);
+}
+
+Element.findChildren = function(element, only, recursive, tagName) {    
+  if(!element.hasChildNodes()) return null;
+  tagName = tagName.toUpperCase();
+  if(only) only = [only].flatten();
+  var elements = [];
+  $A(element.childNodes).each( function(e) {
+    if(e.tagName && e.tagName.toUpperCase()==tagName &&
+      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
+        elements.push(e);
+    if(recursive) {
+      var grandchildren = Element.findChildren(e, only, recursive, tagName);
+      if(grandchildren) elements.push(grandchildren);
+    }
+  });
+
+  return (elements.length>0 ? elements.flatten() : []);
+}
+
+Element.offsetSize = function (element, type) {
+  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
+}
diff -ruN 2.0.5/wp-includes/js/scriptaculous/effects.js 2.2.2/wp-includes/js/scriptaculous/effects.js
--- 2.0.5/wp-includes/js/scriptaculous/effects.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/effects.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,1090 @@
+// script.aculo.us effects.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+//  Justin Palmer (http://encytemedia.com/)
+//  Mark Pilgrim (http://diveintomark.org/)
+//  Martin Bialasinki
+// 
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/ 
+
+// converts rgb() and #xxx to #xxxxxx format,  
+// returns self (or first argument) if not convertable  
+String.prototype.parseColor = function() {  
+  var color = '#';
+  if(this.slice(0,4) == 'rgb(') {  
+    var cols = this.slice(4,this.length-1).split(',');  
+    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
+  } else {  
+    if(this.slice(0,1) == '#') {  
+      if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
+      if(this.length==7) color = this.toLowerCase();  
+    }  
+  }  
+  return(color.length==7 ? color : (arguments[0] || this));  
+}
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {  
+  return $A($(element).childNodes).collect( function(node) {
+    return (node.nodeType==3 ? node.nodeValue : 
+      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+  }).flatten().join('');
+}
+
+Element.collectTextNodesIgnoreClass = function(element, className) {  
+  return $A($(element).childNodes).collect( function(node) {
+    return (node.nodeType==3 ? node.nodeValue : 
+      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
+        Element.collectTextNodesIgnoreClass(node, className) : ''));
+  }).flatten().join('');
+}
+
+Element.setContentZoom = function(element, percent) {
+  element = $(element);  
+  element.setStyle({fontSize: (percent/100) + 'em'});   
+  if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+  return element;
+}
+
+Element.getOpacity = function(element){
+  return $(element).getStyle('opacity');
+}
+
+Element.setOpacity = function(element, value){
+  return $(element).setStyle({opacity:value});
+}
+
+Element.getInlineOpacity = function(element){
+  return $(element).style.opacity || '';
+}
+
+Element.forceRerendering = function(element) {
+  try {
+    element = $(element);
+    var n = document.createTextNode(' ');
+    element.appendChild(n);
+    element.removeChild(n);
+  } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Array.prototype.call = function() {
+  var args = arguments;
+  this.each(function(f){ f.apply(this, args) });
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+  _elementDoesNotExistError: {
+    name: 'ElementDoesNotExistError',
+    message: 'The specified DOM element does not exist, but is required for this effect to operate'
+  },
+  tagifyText: function(element) {
+    if(typeof Builder == 'undefined')
+      throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+      
+    var tagifyStyle = 'position:relative';
+    if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';
+    
+    element = $(element);
+    $A(element.childNodes).each( function(child) {
+      if(child.nodeType==3) {
+        child.nodeValue.toArray().each( function(character) {
+          element.insertBefore(
+            Builder.node('span',{style: tagifyStyle},
+              character == ' ' ? String.fromCharCode(160) : character), 
+              child);
+        });
+        Element.remove(child);
+      }
+    });
+  },
+  multiple: function(element, effect) {
+    var elements;
+    if(((typeof element == 'object') || 
+        (typeof element == 'function')) && 
+       (element.length))
+      elements = element;
+    else
+      elements = $(element).childNodes;
+      
+    var options = Object.extend({
+      speed: 0.1,
+      delay: 0.0
+    }, arguments[2] || {});
+    var masterDelay = options.delay;
+
+    $A(elements).each( function(element, index) {
+      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+    });
+  },
+  PAIRS: {
+    'slide':  ['SlideDown','SlideUp'],
+    'blind':  ['BlindDown','BlindUp'],
+    'appear': ['Appear','Fade']
+  },
+  toggle: function(element, effect) {
+    element = $(element);
+    effect = (effect || 'appear').toLowerCase();
+    var options = Object.extend({
+      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+    }, arguments[2] || {});
+    Effect[element.visible() ? 
+      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+  }
+};
+
+var Effect2 = Effect; // deprecated
+
+/* ------------- transitions ------------- */
+
+Effect.Transitions = {
+  linear: Prototype.K,
+  sinoidal: function(pos) {
+    return (-Math.cos(pos*Math.PI)/2) + 0.5;
+  },
+  reverse: function(pos) {
+    return 1-pos;
+  },
+  flicker: function(pos) {
+    return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+  },
+  wobble: function(pos) {
+    return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+  },
+  pulse: function(pos, pulses) { 
+    pulses = pulses || 5; 
+    return (
+      Math.round((pos % (1/pulses)) * pulses) == 0 ? 
+            ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : 
+        1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
+      );
+  },
+  none: function(pos) {
+    return 0;
+  },
+  full: function(pos) {
+    return 1;
+  }
+};
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+  initialize: function() {
+    this.effects  = [];
+    this.interval = null;
+  },
+  _each: function(iterator) {
+    this.effects._each(iterator);
+  },
+  add: function(effect) {
+    var timestamp = new Date().getTime();
+    
+    var position = (typeof effect.options.queue == 'string') ? 
+      effect.options.queue : effect.options.queue.position;
+    
+    switch(position) {
+      case 'front':
+        // move unstarted effects after this effect  
+        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+            e.startOn  += effect.finishOn;
+            e.finishOn += effect.finishOn;
+          });
+        break;
+      case 'with-last':
+        timestamp = this.effects.pluck('startOn').max() || timestamp;
+        break;
+      case 'end':
+        // start effect after last queued effect has finished
+        timestamp = this.effects.pluck('finishOn').max() || timestamp;
+        break;
+    }
+    
+    effect.startOn  += timestamp;
+    effect.finishOn += timestamp;
+
+    if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+      this.effects.push(effect);
+    
+    if(!this.interval) 
+      this.interval = setInterval(this.loop.bind(this), 15);
+  },
+  remove: function(effect) {
+    this.effects = this.effects.reject(function(e) { return e==effect });
+    if(this.effects.length == 0) {
+      clearInterval(this.interval);
+      this.interval = null;
+    }
+  },
+  loop: function() {
+    var timePos = new Date().getTime();
+    for(var i=0, len=this.effects.length;i<len;i++) 
+      if(this.effects[i]) this.effects[i].loop(timePos);
+  }
+});
+
+Effect.Queues = {
+  instances: $H(),
+  get: function(queueName) {
+    if(typeof queueName != 'string') return queueName;
+    
+    if(!this.instances[queueName])
+      this.instances[queueName] = new Effect.ScopedQueue();
+      
+    return this.instances[queueName];
+  }
+}
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.DefaultOptions = {
+  transition: Effect.Transitions.sinoidal,
+  duration:   1.0,   // seconds
+  fps:        60.0,  // max. 60fps due to Effect.Queue implementation
+  sync:       false, // true for combining
+  from:       0.0,
+  to:         1.0,
+  delay:      0.0,
+  queue:      'parallel'
+}
+
+Effect.Base = function() {};
+Effect.Base.prototype = {
+  position: null,
+  start: function(options) {
+    this.options      = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
+    this.currentFrame = 0;
+    this.state        = 'idle';
+    this.startOn      = this.options.delay*1000;
+    this.finishOn     = this.startOn + (this.options.duration*1000);
+    this.event('beforeStart');
+    if(!this.options.sync)
+      Effect.Queues.get(typeof this.options.queue == 'string' ? 
+        'global' : this.options.queue.scope).add(this);
+  },
+  loop: function(timePos) {
+    if(timePos >= this.startOn) {
+      if(timePos >= this.finishOn) {
+        this.render(1.0);
+        this.cancel();
+        this.event('beforeFinish');
+        if(this.finish) this.finish(); 
+        this.event('afterFinish');
+        return;  
+      }
+      var pos   = (timePos - this.startOn) / (this.finishOn - this.startOn);
+      var frame = Math.round(pos * this.options.fps * this.options.duration);
+      if(frame > this.currentFrame) {
+        this.render(pos);
+        this.currentFrame = frame;
+      }
+    }
+  },
+  render: function(pos) {
+    if(this.state == 'idle') {
+      this.state = 'running';
+      this.event('beforeSetup');
+      if(this.setup) this.setup();
+      this.event('afterSetup');
+    }
+    if(this.state == 'running') {
+      if(this.options.transition) pos = this.options.transition(pos);
+      pos *= (this.options.to-this.options.from);
+      pos += this.options.from;
+      this.position = pos;
+      this.event('beforeUpdate');
+      if(this.update) this.update(pos);
+      this.event('afterUpdate');
+    }
+  },
+  cancel: function() {
+    if(!this.options.sync)
+      Effect.Queues.get(typeof this.options.queue == 'string' ? 
+        'global' : this.options.queue.scope).remove(this);
+    this.state = 'finished';
+  },
+  event: function(eventName) {
+    if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+    if(this.options[eventName]) this.options[eventName](this);
+  },
+  inspect: function() {
+    var data = $H();
+    for(property in this)
+      if(typeof this[property] != 'function') data[property] = this[property];
+    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
+  }
+}
+
+Effect.Parallel = Class.create();
+Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+  initialize: function(effects) {
+    this.effects = effects || [];
+    this.start(arguments[1]);
+  },
+  update: function(position) {
+    this.effects.invoke('render', position);
+  },
+  finish: function(position) {
+    this.effects.each( function(effect) {
+      effect.render(1.0);
+      effect.cancel();
+      effect.event('beforeFinish');
+      if(effect.finish) effect.finish(position);
+      effect.event('afterFinish');
+    });
+  }
+});
+
+Effect.Event = Class.create();
+Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
+  initialize: function() {
+    var options = Object.extend({
+      duration: 0
+    }, arguments[0] || {});
+    this.start(options);
+  },
+  update: Prototype.emptyFunction
+});
+
+Effect.Opacity = Class.create();
+Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    // make this work on IE on elements without 'layout'
+    if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+      this.element.setStyle({zoom: 1});
+    var options = Object.extend({
+      from: this.element.getOpacity() || 0.0,
+      to:   1.0
+    }, arguments[1] || {});
+    this.start(options);
+  },
+  update: function(position) {
+    this.element.setOpacity(position);
+  }
+});
+
+Effect.Move = Class.create();
+Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      x:    0,
+      y:    0,
+      mode: 'relative'
+    }, arguments[1] || {});
+    this.start(options);
+  },
+  setup: function() {
+    // Bug in Opera: Opera returns the "real" position of a static element or
+    // relative element that does not have top/left explicitly set.
+    // ==> Always set top and left for position relative elements in your stylesheets 
+    // (to 0 if you do not need them) 
+    this.element.makePositioned();
+    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
+    if(this.options.mode == 'absolute') {
+      // absolute movement, so we need to calc deltaX and deltaY
+      this.options.x = this.options.x - this.originalLeft;
+      this.options.y = this.options.y - this.originalTop;
+    }
+  },
+  update: function(position) {
+    this.element.setStyle({
+      left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
+      top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
+    });
+  }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+  return new Effect.Move(element, 
+    Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+};
+
+Effect.Scale = Class.create();
+Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+  initialize: function(element, percent) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      scaleX: true,
+      scaleY: true,
+      scaleContent: true,
+      scaleFromCenter: false,
+      scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
+      scaleFrom: 100.0,
+      scaleTo:   percent
+    }, arguments[2] || {});
+    this.start(options);
+  },
+  setup: function() {
+    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+    this.elementPositioning = this.element.getStyle('position');
+    
+    this.originalStyle = {};
+    ['top','left','width','height','fontSize'].each( function(k) {
+      this.originalStyle[k] = this.element.style[k];
+    }.bind(this));
+      
+    this.originalTop  = this.element.offsetTop;
+    this.originalLeft = this.element.offsetLeft;
+    
+    var fontSize = this.element.getStyle('font-size') || '100%';
+    ['em','px','%','pt'].each( function(fontSizeType) {
+      if(fontSize.indexOf(fontSizeType)>0) {
+        this.fontSize     = parseFloat(fontSize);
+        this.fontSizeType = fontSizeType;
+      }
+    }.bind(this));
+    
+    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+    
+    this.dims = null;
+    if(this.options.scaleMode=='box')
+      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+    if(/^content/.test(this.options.scaleMode))
+      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+    if(!this.dims)
+      this.dims = [this.options.scaleMode.originalHeight,
+                   this.options.scaleMode.originalWidth];
+  },
+  update: function(position) {
+    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+    if(this.options.scaleContent && this.fontSize)
+      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+  },
+  finish: function(position) {
+    if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+  },
+  setDimensions: function(height, width) {
+    var d = {};
+    if(this.options.scaleX) d.width = Math.round(width) + 'px';
+    if(this.options.scaleY) d.height = Math.round(height) + 'px';
+    if(this.options.scaleFromCenter) {
+      var topd  = (height - this.dims[0])/2;
+      var leftd = (width  - this.dims[1])/2;
+      if(this.elementPositioning == 'absolute') {
+        if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
+        if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+      } else {
+        if(this.options.scaleY) d.top = -topd + 'px';
+        if(this.options.scaleX) d.left = -leftd + 'px';
+      }
+    }
+    this.element.setStyle(d);
+  }
+});
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+    this.start(options);
+  },
+  setup: function() {
+    // Prevent executing on elements not in the layout flow
+    if(this.element.getStyle('display')=='none') { this.cancel(); return; }
+    // Disable background image during the effect
+    this.oldStyle = {};
+    if (!this.options.keepBackgroundImage) {
+      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
+      this.element.setStyle({backgroundImage: 'none'});
+    }
+    if(!this.options.endcolor)
+      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+    if(!this.options.restorecolor)
+      this.options.restorecolor = this.element.getStyle('background-color');
+    // init color calculations
+    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+  },
+  update: function(position) {
+    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+      return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
+  },
+  finish: function() {
+    this.element.setStyle(Object.extend(this.oldStyle, {
+      backgroundColor: this.options.restorecolor
+    }));
+  }
+});
+
+Effect.ScrollTo = Class.create();
+Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    this.start(arguments[1] || {});
+  },
+  setup: function() {
+    Position.prepare();
+    var offsets = Position.cumulativeOffset(this.element);
+    if(this.options.offset) offsets[1] += this.options.offset;
+    var max = window.innerHeight ? 
+      window.height - window.innerHeight :
+      document.body.scrollHeight - 
+        (document.documentElement.clientHeight ? 
+          document.documentElement.clientHeight : document.body.clientHeight);
+    this.scrollStart = Position.deltaY;
+    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
+  },
+  update: function(position) {
+    Position.prepare();
+    window.scrollTo(Position.deltaX, 
+      this.scrollStart + (position*this.delta));
+  }
+});
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  var options = Object.extend({
+  from: element.getOpacity() || 1.0,
+  to:   0.0,
+  afterFinishInternal: function(effect) { 
+    if(effect.options.to!=0) return;
+    effect.element.hide().setStyle({opacity: oldOpacity}); 
+  }}, arguments[1] || {});
+  return new Effect.Opacity(element,options);
+}
+
+Effect.Appear = function(element) {
+  element = $(element);
+  var options = Object.extend({
+  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+  to:   1.0,
+  // force Safari to render floated elements properly
+  afterFinishInternal: function(effect) {
+    effect.element.forceRerendering();
+  },
+  beforeSetup: function(effect) {
+    effect.element.setOpacity(effect.options.from).show(); 
+  }}, arguments[1] || {});
+  return new Effect.Opacity(element,options);
+}
+
+Effect.Puff = function(element) {
+  element = $(element);
+  var oldStyle = { 
+    opacity: element.getInlineOpacity(), 
+    position: element.getStyle('position'),
+    top:  element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height
+  };
+  return new Effect.Parallel(
+   [ new Effect.Scale(element, 200, 
+      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
+     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
+     Object.extend({ duration: 1.0, 
+      beforeSetupInternal: function(effect) {
+        Position.absolutize(effect.effects[0].element)
+      },
+      afterFinishInternal: function(effect) {
+         effect.effects[0].element.hide().setStyle(oldStyle); }
+     }, arguments[1] || {})
+   );
+}
+
+Effect.BlindUp = function(element) {
+  element = $(element);
+  element.makeClipping();
+  return new Effect.Scale(element, 0,
+    Object.extend({ scaleContent: false, 
+      scaleX: false, 
+      restoreAfterFinish: true,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping();
+      } 
+    }, arguments[1] || {})
+  );
+}
+
+Effect.BlindDown = function(element) {
+  element = $(element);
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false,
+    scaleFrom: 0,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping();
+    }
+  }, arguments[1] || {}));
+}
+
+Effect.SwitchOff = function(element) {
+  element = $(element);
+  var oldOpacity = element.getInlineOpacity();
+  return new Effect.Appear(element, Object.extend({
+    duration: 0.4,
+    from: 0,
+    transition: Effect.Transitions.flicker,
+    afterFinishInternal: function(effect) {
+      new Effect.Scale(effect.element, 1, { 
+        duration: 0.3, scaleFromCenter: true,
+        scaleX: false, scaleContent: false, restoreAfterFinish: true,
+        beforeSetup: function(effect) { 
+          effect.element.makePositioned().makeClipping();
+        },
+        afterFinishInternal: function(effect) {
+          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
+        }
+      })
+    }
+  }, arguments[1] || {}));
+}
+
+Effect.DropOut = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left'),
+    opacity: element.getInlineOpacity() };
+  return new Effect.Parallel(
+    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
+      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+    Object.extend(
+      { duration: 0.5,
+        beforeSetup: function(effect) {
+          effect.effects[0].element.makePositioned(); 
+        },
+        afterFinishInternal: function(effect) {
+          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
+        } 
+      }, arguments[1] || {}));
+}
+
+Effect.Shake = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.getStyle('top'),
+    left: element.getStyle('left') };
+    return new Effect.Move(element, 
+      { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
+    new Effect.Move(effect.element,
+      { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+        effect.element.undoPositioned().setStyle(oldStyle);
+  }}) }}) }}) }}) }}) }});
+}
+
+Effect.SlideDown = function(element) {
+  element = $(element).cleanWhitespace();
+  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+  var oldInnerBottom = element.down().getStyle('bottom');
+  var elementDimensions = element.getDimensions();
+  return new Effect.Scale(element, 100, Object.extend({ 
+    scaleContent: false, 
+    scaleX: false, 
+    scaleFrom: window.opera ? 0 : 1,
+    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+    restoreAfterFinish: true,
+    afterSetup: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if(window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
+    },
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.undoClipping().undoPositioned();
+      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
+    }, arguments[1] || {})
+  );
+}
+
+Effect.SlideUp = function(element) {
+  element = $(element).cleanWhitespace();
+  var oldInnerBottom = element.down().getStyle('bottom');
+  return new Effect.Scale(element, window.opera ? 0 : 1,
+   Object.extend({ scaleContent: false, 
+    scaleX: false, 
+    scaleMode: 'box',
+    scaleFrom: 100,
+    restoreAfterFinish: true,
+    beforeStartInternal: function(effect) {
+      effect.element.makePositioned();
+      effect.element.down().makePositioned();
+      if(window.opera) effect.element.setStyle({top: ''});
+      effect.element.makeClipping().show();
+    },  
+    afterUpdateInternal: function(effect) {
+      effect.element.down().setStyle({bottom:
+        (effect.dims[0] - effect.element.clientHeight) + 'px' });
+    },
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
+      effect.element.down().undoPositioned();
+    }
+   }, arguments[1] || {})
+  );
+}
+
+// Bug in opera makes the TD containing this element expand for a instance after finish 
+Effect.Squish = function(element) {
+  return new Effect.Scale(element, window.opera ? 1 : 0, { 
+    restoreAfterFinish: true,
+    beforeSetup: function(effect) {
+      effect.element.makeClipping(); 
+    },  
+    afterFinishInternal: function(effect) {
+      effect.element.hide().undoClipping(); 
+    }
+  });
+}
+
+Effect.Grow = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.full
+  }, arguments[1] || {});
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();    
+  var initialMoveX, initialMoveY;
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      initialMoveX = initialMoveY = moveX = moveY = 0; 
+      break;
+    case 'top-right':
+      initialMoveX = dims.width;
+      initialMoveY = moveY = 0;
+      moveX = -dims.width;
+      break;
+    case 'bottom-left':
+      initialMoveX = moveX = 0;
+      initialMoveY = dims.height;
+      moveY = -dims.height;
+      break;
+    case 'bottom-right':
+      initialMoveX = dims.width;
+      initialMoveY = dims.height;
+      moveX = -dims.width;
+      moveY = -dims.height;
+      break;
+    case 'center':
+      initialMoveX = dims.width / 2;
+      initialMoveY = dims.height / 2;
+      moveX = -dims.width / 2;
+      moveY = -dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Move(element, {
+    x: initialMoveX,
+    y: initialMoveY,
+    duration: 0.01, 
+    beforeSetup: function(effect) {
+      effect.element.hide().makeClipping().makePositioned();
+    },
+    afterFinishInternal: function(effect) {
+      new Effect.Parallel(
+        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+          new Effect.Scale(effect.element, 100, {
+            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
+            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+        ], Object.extend({
+             beforeSetup: function(effect) {
+               effect.effects[0].element.setStyle({height: '0px'}).show(); 
+             },
+             afterFinishInternal: function(effect) {
+               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
+             }
+           }, options)
+      )
+    }
+  });
+}
+
+Effect.Shrink = function(element) {
+  element = $(element);
+  var options = Object.extend({
+    direction: 'center',
+    moveTransition: Effect.Transitions.sinoidal,
+    scaleTransition: Effect.Transitions.sinoidal,
+    opacityTransition: Effect.Transitions.none
+  }, arguments[1] || {});
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    height: element.style.height,
+    width: element.style.width,
+    opacity: element.getInlineOpacity() };
+
+  var dims = element.getDimensions();
+  var moveX, moveY;
+  
+  switch (options.direction) {
+    case 'top-left':
+      moveX = moveY = 0;
+      break;
+    case 'top-right':
+      moveX = dims.width;
+      moveY = 0;
+      break;
+    case 'bottom-left':
+      moveX = 0;
+      moveY = dims.height;
+      break;
+    case 'bottom-right':
+      moveX = dims.width;
+      moveY = dims.height;
+      break;
+    case 'center':  
+      moveX = dims.width / 2;
+      moveY = dims.height / 2;
+      break;
+  }
+  
+  return new Effect.Parallel(
+    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+    ], Object.extend({            
+         beforeStartInternal: function(effect) {
+           effect.effects[0].element.makePositioned().makeClipping(); 
+         },
+         afterFinishInternal: function(effect) {
+           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
+       }, options)
+  );
+}
+
+Effect.Pulsate = function(element) {
+  element = $(element);
+  var options    = arguments[1] || {};
+  var oldOpacity = element.getInlineOpacity();
+  var transition = options.transition || Effect.Transitions.sinoidal;
+  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
+  reverser.bind(transition);
+  return new Effect.Opacity(element, 
+    Object.extend(Object.extend({  duration: 2.0, from: 0,
+      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+    }, options), {transition: reverser}));
+}
+
+Effect.Fold = function(element) {
+  element = $(element);
+  var oldStyle = {
+    top: element.style.top,
+    left: element.style.left,
+    width: element.style.width,
+    height: element.style.height };
+  element.makeClipping();
+  return new Effect.Scale(element, 5, Object.extend({   
+    scaleContent: false,
+    scaleX: false,
+    afterFinishInternal: function(effect) {
+    new Effect.Scale(element, 1, { 
+      scaleContent: false, 
+      scaleY: false,
+      afterFinishInternal: function(effect) {
+        effect.element.hide().undoClipping().setStyle(oldStyle);
+      } });
+  }}, arguments[1] || {}));
+};
+
+Effect.Morph = Class.create();
+Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
+  initialize: function(element) {
+    this.element = $(element);
+    if(!this.element) throw(Effect._elementDoesNotExistError);
+    var options = Object.extend({
+      style: {}
+    }, arguments[1] || {});
+    if (typeof options.style == 'string') {
+      if(options.style.indexOf(':') == -1) {
+        var cssText = '', selector = '.' + options.style;
+        $A(document.styleSheets).reverse().each(function(styleSheet) {
+          if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
+          else if (styleSheet.rules) cssRules = styleSheet.rules;
+          $A(cssRules).reverse().each(function(rule) {
+            if (selector == rule.selectorText) {
+              cssText = rule.style.cssText;
+              throw $break;
+            }
+          });
+          if (cssText) throw $break;
+        });
+        this.style = cssText.parseStyle();
+        options.afterFinishInternal = function(effect){
+          effect.element.addClassName(effect.options.style);
+          effect.transforms.each(function(transform) {
+            if(transform.style != 'opacity')
+              effect.element.style[transform.style.camelize()] = '';
+          });
+        }
+      } else this.style = options.style.parseStyle();
+    } else this.style = $H(options.style)
+    this.start(options);
+  },
+  setup: function(){
+    function parseColor(color){
+      if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
+      color = color.parseColor();
+      return $R(0,2).map(function(i){
+        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
+      });
+    }
+    this.transforms = this.style.map(function(pair){
+      var property = pair[0].underscore().dasherize(), value = pair[1], unit = null;
+
+      if(value.parseColor('#zzzzzz') != '#zzzzzz') {
+        value = value.parseColor();
+        unit  = 'color';
+      } else if(property == 'opacity') {
+        value = parseFloat(value);
+        if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
+          this.element.setStyle({zoom: 1});
+      } else if(Element.CSS_LENGTH.test(value)) 
+        var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
+          value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;
+
+      var originalValue = this.element.getStyle(property);
+      return $H({ 
+        style: property, 
+        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
+        targetValue: unit=='color' ? parseColor(value) : value,
+        unit: unit
+      });
+    }.bind(this)).reject(function(transform){
+      return (
+        (transform.originalValue == transform.targetValue) ||
+        (
+          transform.unit != 'color' &&
+          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
+        )
+      )
+    });
+  },
+  update: function(position) {
+    var style = $H(), value = null;
+    this.transforms.each(function(transform){
+      value = transform.unit=='color' ?
+        $R(0,2).inject('#',function(m,v,i){
+          return m+(Math.round(transform.originalValue[i]+
+            (transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) : 
+        transform.originalValue + Math.round(
+          ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
+      style[transform.style] = value;
+    });
+    this.element.setStyle(style);
+  }
+});
+
+Effect.Transform = Class.create();
+Object.extend(Effect.Transform.prototype, {
+  initialize: function(tracks){
+    this.tracks  = [];
+    this.options = arguments[1] || {};
+    this.addTracks(tracks);
+  },
+  addTracks: function(tracks){
+    tracks.each(function(track){
+      var data = $H(track).values().first();
+      this.tracks.push($H({
+        ids:     $H(track).keys().first(),
+        effect:  Effect.Morph,
+        options: { style: data }
+      }));
+    }.bind(this));
+    return this;
+  },
+  play: function(){
+    return new Effect.Parallel(
+      this.tracks.map(function(track){
+        var elements = [$(track.ids) || $$(track.ids)].flatten();
+        return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
+      }).flatten(),
+      this.options
+    );
+  }
+});
+
+Element.CSS_PROPERTIES = $w(
+  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
+  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
+  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
+  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
+  'fontSize fontWeight height left letterSpacing lineHeight ' +
+  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
+  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
+  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
+  'right textIndent top width wordSpacing zIndex');
+  
+Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+String.prototype.parseStyle = function(){
+  var element = Element.extend(document.createElement('div'));
+  element.innerHTML = '<div style="' + this + '"></div>';
+  var style = element.down().style, styleRules = $H();
+  
+  Element.CSS_PROPERTIES.each(function(property){
+    if(style[property]) styleRules[property] = style[property]; 
+  });
+  if(/MSIE/.test(navigator.userAgent) && !window.opera && this.indexOf('opacity') > -1) {
+    styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
+  }
+  return styleRules;
+};
+
+Element.morph = function(element, style) {
+  new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
+  return element;
+};
+
+['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( 
+  function(f) { Element.Methods[f] = Element[f]; }
+);
+
+Element.Methods.visualEffect = function(element, effect, options) {
+  s = effect.gsub(/_/, '-').camelize();
+  effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+  new Effect[effect_class](element, options);
+  return $(element);
+};
+
+Element.addMethods();
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/prototype.js 2.2.2/wp-includes/js/scriptaculous/prototype.js
--- 2.0.5/wp-includes/js/scriptaculous/prototype.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/prototype.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,2515 @@
+/*  Prototype JavaScript framework, version 1.5.0
+ *  (c) 2005-2007 Sam Stephenson
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.5.0',
+  BrowserFeatures: {
+    XPath: !!document.evaluate
+  },
+
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+  emptyFunction: function() {},
+  K: function(x) { return x }
+}
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (var property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+}
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (object === undefined) return 'undefined';
+      if (object === null) return 'null';
+      return object.inspect ? object.inspect() : object.toString();
+    } catch (e) {
+      if (e instanceof RangeError) return '...';
+      throw e;
+    }
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({}, object);
+  }
+});
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function(event) {
+    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+  }
+}
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0, length = arguments.length; i < length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  stop: function() {
+    if (!this.timer) return;
+    clearInterval(this.timer);
+    this.timer = null;
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback(this);
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+}
+String.interpret = function(value){
+  return value == null ? '' : String(value);
+}
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(replacement);
+
+    while (source.length > 0) {
+      if (match = source.match(pattern)) {
+        result += source.slice(0, match.index);
+        result += String.interpret(replacement(match));
+        source  = source.slice(match.index + match[0].length);
+      } else {
+        result += source, source = '';
+      }
+    }
+    return result;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.prepareReplacement(replacement);
+    count = count === undefined ? 1 : count;
+
+    return this.gsub(pattern, function(match) {
+      if (--count < 0) return match[0];
+      return replacement(match);
+    });
+  },
+
+  scan: function(pattern, iterator) {
+    this.gsub(pattern, iterator);
+    return this;
+  },
+
+  truncate: function(length, truncation) {
+    length = length || 30;
+    truncation = truncation === undefined ? '...' : truncation;
+    return this.length > length ?
+      this.slice(0, length - truncation.length) + truncation : this;
+  },
+
+  strip: function() {
+    return this.replace(/^\s+/, '').replace(/\s+$/, '');
+  },
+
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? (div.childNodes.length > 1 ?
+      $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
+      div.childNodes[0].nodeValue) : '';
+  },
+
+  toQueryParams: function(separator) {
+    var match = this.strip().match(/([^?#]*)(#.*)?$/);
+    if (!match) return {};
+
+    return match[1].split(separator || '&').inject({}, function(hash, pair) {
+      if ((pair = pair.split('='))[0]) {
+        var name = decodeURIComponent(pair[0]);
+        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;
+
+        if (hash[name] !== undefined) {
+          if (hash[name].constructor != Array)
+            hash[name] = [hash[name]];
+          if (value) hash[name].push(value);
+        }
+        else hash[name] = value;
+      }
+      return hash;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  camelize: function() {
+    var parts = this.split('-'), len = parts.length;
+    if (len == 1) return parts[0];
+
+    var camelized = this.charAt(0) == '-'
+      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+      : parts[0];
+
+    for (var i = 1; i < len; i++)
+      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+    return camelized;
+  },
+
+  capitalize: function(){
+    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+  },
+
+  underscore: function() {
+    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+  },
+
+  dasherize: function() {
+    return this.gsub(/_/,'-');
+  },
+
+  inspect: function(useDoubleQuotes) {
+    var escapedString = this.replace(/\\/g, '\\\\');
+    if (useDoubleQuotes)
+      return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    else
+      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+  if (typeof replacement == 'function') return replacement;
+  var template = new Template(replacement);
+  return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern  = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    return this.template.gsub(this.pattern, function(match) {
+      var before = match[1];
+      if (before == '\\') return match[2];
+      return before + String.interpret(object[match[3]]);
+    });
+  }
+}
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator) {
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.map(iterator);
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push((iterator || Prototype.K)(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    })
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(number, fillWith) {
+    fillWith = fillWith === undefined ? null : fillWith;
+    return this.eachSlice(number, function(slice) {
+      while(slice.length < number) slice.push(fillWith);
+      return slice;
+    });
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (result == undefined || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  size: function() {
+    return this.toArray().length;
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+}
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0, length = iterable.length; i < length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+  Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value && value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0, length = this.length; i < length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function() {
+    return this.inject([], function(array, value) {
+      return array.include(value) ? array : array.concat([value]);
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string){
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if(window.opera){
+  Array.prototype.concat = function(){
+    var array = [];
+    for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      if(arguments[i].constructor == Array) {
+        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+          array.push(arguments[i][j]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  }
+}
+var Hash = function(obj) {
+  Object.extend(this, obj || {});
+};
+
+Object.extend(Hash, {
+  toQueryString: function(obj) {
+    var parts = [];
+
+	  this.prototype._each.call(obj, function(pair) {
+      if (!pair.key) return;
+
+      if (pair.value && pair.value.constructor == Array) {
+        var values = pair.value.compact();
+        if (values.length < 2) pair.value = values.reduce();
+        else {
+        	key = encodeURIComponent(pair.key);
+          values.each(function(value) {
+            value = value != undefined ? encodeURIComponent(value) : '';
+            parts.push(key + '=' + encodeURIComponent(value));
+          });
+          return;
+        }
+      }
+      if (pair.value == undefined) pair[1] = '';
+      parts.push(pair.map(encodeURIComponent).join('='));
+	  });
+
+    return parts.join('&');
+  }
+});
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+  _each: function(iterator) {
+    for (var key in this) {
+      var value = this[key];
+      if (value && value == Hash.prototype[key]) continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject(this, function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  remove: function() {
+    var result;
+    for(var i = 0, length = arguments.length; i < length; i++) {
+      var value = this[arguments[i]];
+      if (value !== undefined){
+        if (result === undefined) result = value;
+        else {
+          if (result.constructor != Array) result = [result];
+          result.push(value)
+        }
+      }
+      delete this[arguments[i]];
+    }
+    return result;
+  },
+
+  toQueryString: function() {
+    return Hash.toQueryString(this);
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+});
+
+function $H(object) {
+  if (object && object.constructor == Hash) return object;
+  return new Hash(object);
+};
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new XMLHttpRequest()},
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+}
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   ''
+    }
+    Object.extend(this.options, options || {});
+
+    this.options.method = this.options.method.toLowerCase();
+    if (typeof this.options.parameters == 'string')
+      this.options.parameters = this.options.parameters.toQueryParams();
+  }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  _complete: false,
+
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    var params = this.options.parameters;
+
+    if (!['get', 'post'].include(this.method)) {
+      // simulate other verbs over post
+      params['_method'] = this.method;
+      this.method = 'post';
+    }
+
+    params = Hash.toQueryString(params);
+    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='
+
+    // when GET, append parameters to URL
+    if (this.method == 'get' && params)
+      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;
+
+    try {
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.method.toUpperCase(), this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous)
+        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+      this.transport.onreadystatechange = this.onStateChange.bind(this);
+      this.setRequestHeaders();
+
+      var body = this.method == 'post' ? (this.options.postBody || params) : null;
+
+      this.transport.send(body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (typeof extras.push == 'function')
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    return !this.transport.status
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.getHeader('Content-type') || 'text/javascript').strip().
+        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+          this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + state, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) { return null }
+  },
+
+  evalJSON: function() {
+    try {
+      var json = this.getHeader('X-JSON');
+      return json ? eval('(' + json + ')') : null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    }
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, param) {
+      this.updateContent();
+      onComplete(transport, param);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.container[this.success() ? 'success' : 'failure'];
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts) response = response.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (this.options.insertion)
+        new this.options.insertion(receiver, response);
+      else
+        receiver.update(response);
+    }
+
+    if (this.success()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.options.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+function $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (typeof element == 'string')
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(query.snapshotItem(i));
+    return results;
+  };
+}
+
+document.getElementsByClassName = function(className, parentElement) {
+  if (Prototype.BrowserFeatures.XPath) {
+    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+    return document._getElementsByXPath(q, parentElement);
+  } else {
+    var children = ($(parentElement) || document.body).getElementsByTagName('*');
+    var elements = [], child;
+    for (var i = 0, length = children.length; i < length; i++) {
+      child = children[i];
+      if (Element.hasClassName(child, className))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+  var Element = new Object();
+
+Element.extend = function(element) {
+  if (!element || _nativeExtensions || element.nodeType == 3) return element;
+
+  if (!element._extended && element.tagName && element != window) {
+    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;
+
+    if (element.tagName == 'FORM')
+      Object.extend(methods, Form.Methods);
+    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
+      Object.extend(methods, Form.Element.Methods);
+
+    Object.extend(methods, Element.Methods.Simulated);
+
+    for (var property in methods) {
+      var value = methods[property];
+      if (typeof value == 'function' && !(property in element))
+        element[property] = cache.findOrStore(value);
+    }
+  }
+
+  element._extended = true;
+  return element;
+};
+
+Element.extend.cache = {
+  findOrStore: function(value) {
+    return this[value] = this[value] || function() {
+      return value.apply(null, [this].concat($A(arguments)));
+    }
+  }
+};
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    return element;
+  },
+
+  update: function(element, html) {
+    html = typeof html == 'undefined' ? '' : html.toString();
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  replace: function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    if (element.outerHTML) {
+      element.outerHTML = html.stripScripts();
+    } else {
+      var range = element.ownerDocument.createRange();
+      range.selectNodeContents(element);
+      element.parentNode.replaceChild(
+        range.createContextualFragment(html.stripScripts()), element);
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $A($(element).getElementsByTagName('*'));
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (typeof selector == 'string')
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    return Selector.findElement($(element).ancestors(), expression, index);
+  },
+
+  down: function(element, expression, index) {
+    return Selector.findElement($(element).descendants(), expression, index);
+  },
+
+  previous: function(element, expression, index) {
+    return Selector.findElement($(element).previousSiblings(), expression, index);
+  },
+
+  next: function(element, expression, index) {
+    return Selector.findElement($(element).nextSiblings(), expression, index);
+  },
+
+  getElementsBySelector: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  getElementsByClassName: function(element, className) {
+    return document.getElementsByClassName(className, element);
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (document.all && !window.opera) {
+      var t = Element._attributeTranslations;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name])  name = t.names[name];
+      var attribute = element.attributes[name];
+      if(attribute) return attribute.nodeValue;
+    }
+    return element.getAttribute(name);
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    if (elementClassName.length == 0) return false;
+    if (elementClassName == className ||
+        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      return true;
+    return false;
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).add(className);
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element).remove(className);
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+    return element;
+  },
+
+  observe: function() {
+    Event.observe.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  stopObserving: function() {
+    Event.stopObserving.apply(Event, arguments);
+    return $A(arguments).first();
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    while (element = element.parentNode)
+      if (element == ancestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = Position.cumulativeOffset(element);
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    if (['float','cssFloat'].include(style))
+      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
+    style = style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css[style] : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style];
+      }
+    }
+
+    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
+      value = element['offset'+style.capitalize()] + 'px';
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+    if(style == 'opacity') {
+      if(value) return parseFloat(value);
+      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if(value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (var name in style) {
+      var value = style[name];
+      if(name == 'opacity') {
+        if (value == 1) {
+          value = (/Gecko/.test(navigator.userAgent) &&
+            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else if(value == '') {
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
+        } else {
+          if(value < 0.00001) value = 0;
+          if(/MSIE/.test(navigator.userAgent) && !window.opera)
+            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
+              'alpha(opacity='+value*100+')';
+        }
+      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
+      element.style[name.camelize()] = value;
+    }
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('display');
+    if (display != 'none' && display != null) // Safari bug
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    var originalDisplay = els.display;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = element.style.overflow || 'auto';
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  }
+};
+
+Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});
+
+Element._attributeTranslations = {};
+
+Element._attributeTranslations.names = {
+  colspan:   "colSpan",
+  rowspan:   "rowSpan",
+  valign:    "vAlign",
+  datetime:  "dateTime",
+  accesskey: "accessKey",
+  tabindex:  "tabIndex",
+  enctype:   "encType",
+  maxlength: "maxLength",
+  readonly:  "readOnly",
+  longdesc:  "longDesc"
+};
+
+Element._attributeTranslations.values = {
+  _getAttr: function(element, attribute) {
+    return element.getAttribute(attribute, 2);
+  },
+
+  _flag: function(element, attribute) {
+    return $(element).hasAttribute(attribute) ? attribute : null;
+  },
+
+  style: function(element) {
+    return element.style.cssText.toLowerCase();
+  },
+
+  title: function(element) {
+    var node = element.getAttributeNode('title');
+    return node.specified ? node.nodeValue : null;
+  }
+};
+
+Object.extend(Element._attributeTranslations.values, {
+  href: Element._attributeTranslations.values._getAttr,
+  src:  Element._attributeTranslations.values._getAttr,
+  disabled: Element._attributeTranslations.values._flag,
+  checked:  Element._attributeTranslations.values._flag,
+  readonly: Element._attributeTranslations.values._flag,
+  multiple: Element._attributeTranslations.values._flag
+});
+
+Element.Methods.Simulated = {
+  hasAttribute: function(element, attribute) {
+    var t = Element._attributeTranslations;
+    attribute = t.names[attribute] || attribute;
+    return $(element).getAttributeNode(attribute).specified;
+  }
+};
+
+// IE is missing .innerHTML support for TABLE-related elements
+if (document.all && !window.opera){
+  Element.Methods.update = function(element, html) {
+    element = $(element);
+    html = typeof html == 'undefined' ? '' : html.toString();
+    var tagName = element.tagName.toUpperCase();
+    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+      var div = document.createElement('div');
+      switch (tagName) {
+        case 'THEAD':
+        case 'TBODY':
+          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
+          depth = 2;
+          break;
+        case 'TR':
+          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
+          depth = 3;
+          break;
+        case 'TD':
+          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
+          depth = 4;
+      }
+      $A(element.childNodes).each(function(node){
+        element.removeChild(node)
+      });
+      depth.times(function(){ div = div.firstChild });
+
+      $A(div.childNodes).each(
+        function(node){ element.appendChild(node) });
+    } else {
+      element.innerHTML = html.stripScripts();
+    }
+    setTimeout(function() {html.evalScripts()}, 10);
+    return element;
+  }
+};
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
+    var className = 'HTML' + tag + 'Element';
+    if(window[className]) return;
+    var klass = window[className] = {};
+    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
+  });
+
+Element.addMethods = function(methods) {
+  Object.extend(Element.Methods, methods || {});
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    var cache = Element.extend.cache;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = cache.findOrStore(value);
+    }
+  }
+
+  if (typeof HTMLElement != 'undefined') {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+    copy(Form.Methods, HTMLFormElement.prototype);
+    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
+      copy(Form.Element.Methods, klass.prototype);
+    });
+    _nativeExtensions = true;
+  }
+}
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        var tagName = this.element.tagName.toUpperCase();
+        if (['TBODY', 'TR'].include(tagName)) {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+  initialize: function(expression) {
+    this.params = {classNames: []};
+    this.expression = expression.toString().strip();
+    this.parseExpression();
+    this.compileMatcher();
+  },
+
+  parseExpression: function() {
+    function abort(message) { throw 'Parse error in selector: ' + message; }
+
+    if (this.expression == '')  abort('empty expression');
+
+    var params = this.params, expr = this.expression, match, modifier, clause, rest;
+    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+      params.attributes = params.attributes || [];
+      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+      expr = match[1];
+    }
+
+    if (expr == '*') return this.params.wildcard = true;
+
+    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+      modifier = match[1], clause = match[2], rest = match[3];
+      switch (modifier) {
+        case '#':       params.id = clause; break;
+        case '.':       params.classNames.push(clause); break;
+        case '':
+        case undefined: params.tagName = clause.toUpperCase(); break;
+        default:        abort(expr.inspect());
+      }
+      expr = rest;
+    }
+
+    if (expr.length > 0) abort(expr.inspect());
+  },
+
+  buildMatchExpression: function() {
+    var params = this.params, conditions = [], clause;
+
+    if (params.wildcard)
+      conditions.push('true');
+    if (clause = params.id)
+      conditions.push('element.readAttribute("id") == ' + clause.inspect());
+    if (clause = params.tagName)
+      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+    if ((clause = params.classNames).length > 0)
+      for (var i = 0, length = clause.length; i < length; i++)
+        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
+    if (clause = params.attributes) {
+      clause.each(function(attribute) {
+        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
+        var splitValueBy = function(delimiter) {
+          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+        }
+
+        switch (attribute.operator) {
+          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
+          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+          case '|=':      conditions.push(
+                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+                          ); break;
+          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
+          case '':
+          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
+          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
+        }
+      });
+    }
+
+    return conditions.join(' && ');
+  },
+
+  compileMatcher: function() {
+    this.match = new Function('element', 'if (!element.tagName) return false; \
+      element = $(element); \
+      return ' + this.buildMatchExpression());
+  },
+
+  findElements: function(scope) {
+    var element;
+
+    if (element = $(this.params.id))
+      if (this.match(element))
+        if (!scope || Element.childOf(element, scope))
+          return [element];
+
+    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+    var results = [];
+    for (var i = 0, length = scope.length; i < length; i++)
+      if (this.match(element = scope[i]))
+        results.push(Element.extend(element));
+
+    return results;
+  },
+
+  toString: function() {
+    return this.expression;
+  }
+}
+
+Object.extend(Selector, {
+  matchElements: function(elements, expression) {
+    var selector = new Selector(expression);
+    return elements.select(selector.match.bind(selector)).map(Element.extend);
+  },
+
+  findElement: function(elements, expression, index) {
+    if (typeof expression == 'number') index = expression, expression = false;
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    return expressions.map(function(expression) {
+      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
+        var selector = new Selector(expr);
+        return results.inject([], function(elements, result) {
+          return elements.concat(selector.findElements(result || element));
+        });
+      });
+    }).flatten();
+  }
+});
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, getHash) {
+    var data = elements.inject({}, function(result, element) {
+      if (!element.disabled && element.name) {
+        var key = element.name, value = $(element).getValue();
+        if (value != undefined) {
+          if (result[key]) {
+            if (result[key].constructor != Array) result[key] = [result[key]];
+            result[key].push(value);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return getHash ? data : Hash.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, getHash) {
+    return Form.serializeElements(Form.getElements(form), getHash);
+  },
+
+  getElements: function(form) {
+    return $A($(form).getElementsByTagName('*')).inject([],
+      function(elements, child) {
+        if (Form.Element.Serializers[child.tagName.toLowerCase()])
+          elements.push(Element.extend(child));
+        return elements;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.blur();
+      element.disabled = 'true';
+    });
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    form.getElements().each(function(element) {
+      element.disabled = '';
+    });
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    return $(form).getElements().find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+}
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = {};
+        pair[element.name] = value;
+        return Hash.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
+      !['button', 'reset', 'submit'].include(element.type) ) )
+      element.select();
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = false;
+    return element;
+  }
+}
+
+Object.extend(Form.Element, Form.Element.Methods);
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+      default:
+        return Form.Element.Serializers.textarea(element);
+    }
+  },
+
+  inputSelector: function(element) {
+    return element.checked ? element.value : null;
+  },
+
+  textarea: function(element) {
+    return element.value;
+  },
+
+  select: function(element) {
+    return this[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  optionValue: function(opt) {
+    // extend element because hasAttribute may not be native
+    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+      ? this.lastValue != value : String(this.lastValue) != String(value));
+    if (changed) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback.bind(this));
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+}
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+  KEY_HOME:     36,
+  KEY_END:      35,
+  KEY_PAGEUP:   33,
+  KEY_PAGEDOWN: 34,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0, length = Event.observers.length; i < length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    Event._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      try {
+        element.detachEvent('on' + name, observer);
+      } catch (e) {}
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+  Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if(element.tagName=='BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!window.opera || element.tagName=='BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {})
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+}
+
+Element.addMethods();
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/scriptaculous.js 2.2.2/wp-includes/js/scriptaculous/scriptaculous.js
--- 2.0.5/wp-includes/js/scriptaculous/scriptaculous.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/scriptaculous.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,51 @@
+// script.aculo.us scriptaculous.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+var Scriptaculous = {
+  Version: '1.7.0',
+  require: function(libraryName) {
+    // inserting via DOM fails in Safari 2.0, so brute force approach
+    document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
+  },
+  load: function() {
+    if((typeof Prototype=='undefined') || 
+       (typeof Element == 'undefined') || 
+       (typeof Element.Methods=='undefined') ||
+       parseFloat(Prototype.Version.split(".")[0] + "." +
+                  Prototype.Version.split(".")[1]) < 1.5)
+       throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
+    
+    $A(document.getElementsByTagName("script")).findAll( function(s) {
+      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+    }).each( function(s) {
+      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+      var includes = s.src.match(/\?.*load=([a-z,]*)/);
+      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
+       function(include) { Scriptaculous.require(path+include+'.js') });
+    });
+  }
+}
+
+Scriptaculous.load();
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/slider.js 2.2.2/wp-includes/js/scriptaculous/slider.js
--- 2.0.5/wp-includes/js/scriptaculous/slider.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/slider.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,278 @@
+// script.aculo.us slider.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Marty Haught, Thomas Fuchs 
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+if(!Control) var Control = {};
+Control.Slider = Class.create();
+
+// options:
+//  axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+//  onChange(value)
+//  onSlide(value)
+Control.Slider.prototype = {
+  initialize: function(handle, track, options) {
+    var slider = this;
+    
+    if(handle instanceof Array) {
+      this.handles = handle.collect( function(e) { return $(e) });
+    } else {
+      this.handles = [$(handle)];
+    }
+    
+    this.track   = $(track);
+    this.options = options || {};
+
+    this.axis      = this.options.axis || 'horizontal';
+    this.increment = this.options.increment || 1;
+    this.step      = parseInt(this.options.step || '1');
+    this.range     = this.options.range || $R(0,1);
+    
+    this.value     = 0; // assure backwards compat
+    this.values    = this.handles.map( function() { return 0 });
+    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
+    this.options.startSpan = $(this.options.startSpan || null);
+    this.options.endSpan   = $(this.options.endSpan || null);
+
+    this.restricted = this.options.restricted || false;
+
+    this.maximum   = this.options.maximum || this.range.end;
+    this.minimum   = this.options.minimum || this.range.start;
+
+    // Will be used to align the handle onto the track, if necessary
+    this.alignX = parseInt(this.options.alignX || '0');
+    this.alignY = parseInt(this.options.alignY || '0');
+    
+    this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+    this.handleLength = this.isVertical() ? 
+      (this.handles[0].offsetHeight != 0 ? 
+        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
+      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
+        this.handles[0].style.width.replace(/px$/,""));
+
+    this.active   = false;
+    this.dragging = false;
+    this.disabled = false;
+
+    if(this.options.disabled) this.setDisabled();
+
+    // Allowed values array
+    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+    if(this.allowedValues) {
+      this.minimum = this.allowedValues.min();
+      this.maximum = this.allowedValues.max();
+    }
+
+    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
+    this.eventMouseMove = this.update.bindAsEventListener(this);
+
+    // Initialize handles in reverse (make sure first handle is active)
+    this.handles.each( function(h,i) {
+      i = slider.handles.length-1-i;
+      slider.setValue(parseFloat(
+        (slider.options.sliderValue instanceof Array ? 
+          slider.options.sliderValue[i] : slider.options.sliderValue) || 
+         slider.range.start), i);
+      Element.makePositioned(h); // fix IE
+      Event.observe(h, "mousedown", slider.eventMouseDown);
+    });
+    
+    Event.observe(this.track, "mousedown", this.eventMouseDown);
+    Event.observe(document, "mouseup", this.eventMouseUp);
+    Event.observe(document, "mousemove", this.eventMouseMove);
+    
+    this.initialized = true;
+  },
+  dispose: function() {
+    var slider = this;    
+    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+    Event.stopObserving(document, "mouseup", this.eventMouseUp);
+    Event.stopObserving(document, "mousemove", this.eventMouseMove);
+    this.handles.each( function(h) {
+      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+    });
+  },
+  setDisabled: function(){
+    this.disabled = true;
+  },
+  setEnabled: function(){
+    this.disabled = false;
+  },  
+  getNearestValue: function(value){
+    if(this.allowedValues){
+      if(value >= this.allowedValues.max()) return(this.allowedValues.max());
+      if(value <= this.allowedValues.min()) return(this.allowedValues.min());
+      
+      var offset = Math.abs(this.allowedValues[0] - value);
+      var newValue = this.allowedValues[0];
+      this.allowedValues.each( function(v) {
+        var currentOffset = Math.abs(v - value);
+        if(currentOffset <= offset){
+          newValue = v;
+          offset = currentOffset;
+        } 
+      });
+      return newValue;
+    }
+    if(value > this.range.end) return this.range.end;
+    if(value < this.range.start) return this.range.start;
+    return value;
+  },
+  setValue: function(sliderValue, handleIdx){
+    if(!this.active) {
+      this.activeHandleIdx = handleIdx || 0;
+      this.activeHandle    = this.handles[this.activeHandleIdx];
+      this.updateStyles();
+    }
+    handleIdx = handleIdx || this.activeHandleIdx || 0;
+    if(this.initialized && this.restricted) {
+      if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
+        sliderValue = this.values[handleIdx-1];
+      if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
+        sliderValue = this.values[handleIdx+1];
+    }
+    sliderValue = this.getNearestValue(sliderValue);
+    this.values[handleIdx] = sliderValue;
+    this.value = this.values[0]; // assure backwards compat
+    
+    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
+      this.translateToPx(sliderValue);
+    
+    this.drawSpans();
+    if(!this.dragging || !this.event) this.updateFinished();
+  },
+  setValueBy: function(delta, handleIdx) {
+    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
+      handleIdx || this.activeHandleIdx || 0);
+  },
+  translateToPx: function(value) {
+    return Math.round(
+      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
+      (value - this.range.start)) + "px";
+  },
+  translateToValue: function(offset) {
+    return ((offset/(this.trackLength-this.handleLength) * 
+      (this.range.end-this.range.start)) + this.range.start);
+  },
+  getRange: function(range) {
+    var v = this.values.sortBy(Prototype.K); 
+    range = range || 0;
+    return $R(v[range],v[range+1]);
+  },
+  minimumOffset: function(){
+    return(this.isVertical() ? this.alignY : this.alignX);
+  },
+  maximumOffset: function(){
+    return(this.isVertical() ? 
+      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
+        this.track.style.height.replace(/px$/,"")) - this.alignY : 
+      (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
+        this.track.style.width.replace(/px$/,"")) - this.alignY);
+  },  
+  isVertical:  function(){
+    return (this.axis == 'vertical');
+  },
+  drawSpans: function() {
+    var slider = this;
+    if(this.spans)
+      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
+    if(this.options.startSpan)
+      this.setSpan(this.options.startSpan,
+        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
+    if(this.options.endSpan)
+      this.setSpan(this.options.endSpan, 
+        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
+  },
+  setSpan: function(span, range) {
+    if(this.isVertical()) {
+      span.style.top = this.translateToPx(range.start);
+      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+    } else {
+      span.style.left = this.translateToPx(range.start);
+      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+    }
+  },
+  updateStyles: function() {
+    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
+    Element.addClassName(this.activeHandle, 'selected');
+  },
+  startDrag: function(event) {
+    if(Event.isLeftClick(event)) {
+      if(!this.disabled){
+        this.active = true;
+        
+        var handle = Event.element(event);
+        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
+        var track = handle;
+        if(track==this.track) {
+          var offsets  = Position.cumulativeOffset(this.track); 
+          this.event = event;
+          this.setValue(this.translateToValue( 
+           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
+          ));
+          var offsets  = Position.cumulativeOffset(this.activeHandle);
+          this.offsetX = (pointer[0] - offsets[0]);
+          this.offsetY = (pointer[1] - offsets[1]);
+        } else {
+          // find the handle (prevents issues with Safari)
+          while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
+            handle = handle.parentNode;
+            
+          if(this.handles.indexOf(handle)!=-1) {
+            this.activeHandle    = handle;
+            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+            this.updateStyles();
+            
+            var offsets  = Position.cumulativeOffset(this.activeHandle);
+            this.offsetX = (pointer[0] - offsets[0]);
+            this.offsetY = (pointer[1] - offsets[1]);
+          }
+        }
+      }
+      Event.stop(event);
+    }
+  },
+  update: function(event) {
+   if(this.active) {
+      if(!this.dragging) this.dragging = true;
+      this.draw(event);
+      // fix AppleWebKit rendering
+      if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+      Event.stop(event);
+   }
+  },
+  draw: function(event) {
+    var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    var offsets = Position.cumulativeOffset(this.track);
+    pointer[0] -= this.offsetX + offsets[0];
+    pointer[1] -= this.offsetY + offsets[1];
+    this.event = event;
+    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
+    if(this.initialized && this.options.onSlide)
+      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
+  },
+  endDrag: function(event) {
+    if(this.active && this.dragging) {
+      this.finishDrag(event, true);
+      Event.stop(event);
+    }
+    this.active = false;
+    this.dragging = false;
+  },  
+  finishDrag: function(event, success) {
+    this.active = false;
+    this.dragging = false;
+    this.updateFinished();
+  },
+  updateFinished: function() {
+    if(this.initialized && this.options.onChange) 
+      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
+    this.event = null;
+  }
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/unittest.js 2.2.2/wp-includes/js/scriptaculous/unittest.js
--- 2.0.5/wp-includes/js/scriptaculous/unittest.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/unittest.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,564 @@
+// script.aculo.us unittest.js v1.7.0, Fri Jan 19 19:16:36 CET 2007
+
+// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//           (c) 2005, 2006 Jon Tirsen (http://www.tirsen.com)
+//           (c) 2005, 2006 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// script.aculo.us is freely distributable under the terms of an MIT-style license.
+// For details, see the script.aculo.us web site: http://script.aculo.us/
+
+// experimental, Firefox-only
+Event.simulateMouse = function(element, eventName) {
+  var options = Object.extend({
+    pointerX: 0,
+    pointerY: 0,
+    buttons:  0,
+    ctrlKey:  false,
+    altKey:   false,
+    shiftKey: false,
+    metaKey:  false
+  }, arguments[2] || {});
+  var oEvent = document.createEvent("MouseEvents");
+  oEvent.initMouseEvent(eventName, true, true, document.defaultView, 
+    options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY, 
+    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
+  
+  if(this.mark) Element.remove(this.mark);
+  this.mark = document.createElement('div');
+  this.mark.appendChild(document.createTextNode(" "));
+  document.body.appendChild(this.mark);
+  this.mark.style.position = 'absolute';
+  this.mark.style.top = options.pointerY + "px";
+  this.mark.style.left = options.pointerX + "px";
+  this.mark.style.width = "5px";
+  this.mark.style.height = "5px;";
+  this.mark.style.borderTop = "1px solid red;"
+  this.mark.style.borderLeft = "1px solid red;"
+  
+  if(this.step)
+    alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
+  
+  $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function(element, eventName) {
+  var options = Object.extend({
+    ctrlKey: false,
+    altKey: false,
+    shiftKey: false,
+    metaKey: false,
+    keyCode: 0,
+    charCode: 0
+  }, arguments[2] || {});
+
+  var oEvent = document.createEvent("KeyEvents");
+  oEvent.initKeyEvent(eventName, true, true, window, 
+    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
+    options.keyCode, options.charCode );
+  $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function(element, command) {
+  for(var i=0; i<command.length; i++) {
+    Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
+  }
+};
+
+var Test = {}
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = Object.inspect;
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+  initialize: function(log) {
+    this.log = $(log);
+    if (this.log) {
+      this._createLogTable();
+    }
+  },
+  start: function(testName) {
+    if (!this.log) return;
+    this.testName = testName;
+    this.lastLogLine = document.createElement('tr');
+    this.statusCell = document.createElement('td');
+    this.nameCell = document.createElement('td');
+    this.nameCell.className = "nameCell";
+    this.nameCell.appendChild(document.createTextNode(testName));
+    this.messageCell = document.createElement('td');
+    this.lastLogLine.appendChild(this.statusCell);
+    this.lastLogLine.appendChild(this.nameCell);
+    this.lastLogLine.appendChild(this.messageCell);
+    this.loglines.appendChild(this.lastLogLine);
+  },
+  finish: function(status, summary) {
+    if (!this.log) return;
+    this.lastLogLine.className = status;
+    this.statusCell.innerHTML = status;
+    this.messageCell.innerHTML = this._toHTML(summary);
+    this.addLinksToResults();
+  },
+  message: function(message) {
+    if (!this.log) return;
+    this.messageCell.innerHTML = this._toHTML(message);
+  },
+  summary: function(summary) {
+    if (!this.log) return;
+    this.logsummary.innerHTML = this._toHTML(summary);
+  },
+  _createLogTable: function() {
+    this.log.innerHTML =
+    '<div id="logsummary"></div>' +
+    '<table id="logtable">' +
+    '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+    '<tbody id="loglines"></tbody>' +
+    '</table>';
+    this.logsummary = $('logsummary')
+    this.loglines = $('loglines');
+  },
+  _toHTML: function(txt) {
+    return txt.escapeHTML().replace(/\n/g,"<br/>");
+  },
+  addLinksToResults: function(){ 
+    $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
+      td.title = "Run only this test"
+      Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
+    });
+    $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
+      td.title = "Run all tests"
+      Event.observe(td, 'click', function(){ window.location.search = "";});
+    });
+  }
+}
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+  initialize: function(testcases) {
+    this.options = Object.extend({
+      testLog: 'testlog'
+    }, arguments[1] || {});
+    this.options.resultsURL = this.parseResultsURLQueryParameter();
+    this.options.tests      = this.parseTestsQueryParameter();
+    if (this.options.testLog) {
+      this.options.testLog = $(this.options.testLog) || null;
+    }
+    if(this.options.tests) {
+      this.tests = [];
+      for(var i = 0; i < this.options.tests.length; i++) {
+        if(/^test/.test(this.options.tests[i])) {
+          this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+        }
+      }
+    } else {
+      if (this.options.test) {
+        this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+      } else {
+        this.tests = [];
+        for(var testcase in testcases) {
+          if(/^test/.test(testcase)) {
+            this.tests.push(
+               new Test.Unit.Testcase(
+                 this.options.context ? ' -> ' + this.options.titles[testcase] : testcase, 
+                 testcases[testcase], testcases["setup"], testcases["teardown"]
+               ));
+          }
+        }
+      }
+    }
+    this.currentTest = 0;
+    this.logger = new Test.Unit.Logger(this.options.testLog);
+    setTimeout(this.runTests.bind(this), 1000);
+  },
+  parseResultsURLQueryParameter: function() {
+    return window.location.search.parseQuery()["resultsURL"];
+  },
+  parseTestsQueryParameter: function(){
+    if (window.location.search.parseQuery()["tests"]){
+        return window.location.search.parseQuery()["tests"].split(',');
+    };
+  },
+  // Returns:
+  //  "ERROR" if there was an error,
+  //  "FAILURE" if there was a failure, or
+  //  "SUCCESS" if there was neither
+  getResult: function() {
+    var hasFailure = false;
+    for(var i=0;i<this.tests.length;i++) {
+      if (this.tests[i].errors > 0) {
+        return "ERROR";
+      }
+      if (this.tests[i].failures > 0) {
+        hasFailure = true;
+      }
+    }
+    if (hasFailure) {
+      return "FAILURE";
+    } else {
+      return "SUCCESS";
+    }
+  },
+  postResults: function() {
+    if (this.options.resultsURL) {
+      new Ajax.Request(this.options.resultsURL, 
+        { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
+    }
+  },
+  runTests: function() {
+    var test = this.tests[this.currentTest];
+    if (!test) {
+      // finished!
+      this.postResults();
+      this.logger.summary(this.summary());
+      return;
+    }
+    if(!test.isWaiting) {
+      this.logger.start(test.name);
+    }
+    test.run();
+    if(test.isWaiting) {
+      this.logger.message("Waiting for " + test.timeToWait + "ms");
+      setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+    } else {
+      this.logger.finish(test.status(), test.summary());
+      this.currentTest++;
+      // tail recursive, hopefully the browser will skip the stackframe
+      this.runTests();
+    }
+  },
+  summary: function() {
+    var assertions = 0;
+    var failures = 0;
+    var errors = 0;
+    var messages = [];
+    for(var i=0;i<this.tests.length;i++) {
+      assertions +=   this.tests[i].assertions;
+      failures   +=   this.tests[i].failures;
+      errors     +=   this.tests[i].errors;
+    }
+    return (
+      (this.options.context ? this.options.context + ': ': '') + 
+      this.tests.length + " tests, " + 
+      assertions + " assertions, " + 
+      failures   + " failures, " +
+      errors     + " errors");
+  }
+}
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+  initialize: function() {
+    this.assertions = 0;
+    this.failures   = 0;
+    this.errors     = 0;
+    this.messages   = [];
+  },
+  summary: function() {
+    return (
+      this.assertions + " assertions, " + 
+      this.failures   + " failures, " +
+      this.errors     + " errors" + "\n" +
+      this.messages.join("\n"));
+  },
+  pass: function() {
+    this.assertions++;
+  },
+  fail: function(message) {
+    this.failures++;
+    this.messages.push("Failure: " + message);
+  },
+  info: function(message) {
+    this.messages.push("Info: " + message);
+  },
+  error: function(error) {
+    this.errors++;
+    this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
+  },
+  status: function() {
+    if (this.failures > 0) return 'failed';
+    if (this.errors > 0) return 'error';
+    return 'passed';
+  },
+  assert: function(expression) {
+    var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+    try { expression ? this.pass() : 
+      this.fail(message); }
+    catch(e) { this.error(e); }
+  },
+  assertEqual: function(expected, actual) {
+    var message = arguments[2] || "assertEqual";
+    try { (expected == actual) ? this.pass() :
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) + 
+        '", actual "' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertInspect: function(expected, actual) {
+    var message = arguments[2] || "assertInspect";
+    try { (expected == actual.inspect()) ? this.pass() :
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) + 
+        '", actual "' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertEnumEqual: function(expected, actual) {
+    var message = arguments[2] || "assertEnumEqual";
+    try { $A(expected).length == $A(actual).length && 
+      expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
+        this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) + 
+          ', actual ' + Test.Unit.inspect(actual)); }
+    catch(e) { this.error(e); }
+  },
+  assertNotEqual: function(expected, actual) {
+    var message = arguments[2] || "assertNotEqual";
+    try { (expected != actual) ? this.pass() : 
+      this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertIdentical: function(expected, actual) { 
+    var message = arguments[2] || "assertIdentical"; 
+    try { (expected === actual) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
+    catch(e) { this.error(e); } 
+  },
+  assertNotIdentical: function(expected, actual) { 
+    var message = arguments[2] || "assertNotIdentical"; 
+    try { !(expected === actual) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + Test.Unit.inspect(actual) + '"'); } 
+    catch(e) { this.error(e); } 
+  },
+  assertNull: function(obj) {
+    var message = arguments[1] || 'assertNull'
+    try { (obj==null) ? this.pass() : 
+      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertMatch: function(expected, actual) {
+    var message = arguments[2] || 'assertMatch';
+    var regex = new RegExp(expected);
+    try { (regex.exec(actual)) ? this.pass() :
+      this.fail(message + ' : regex: "' +  Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertHidden: function(element) {
+    var message = arguments[1] || 'assertHidden';
+    this.assertEqual("none", element.style.display, message);
+  },
+  assertNotNull: function(object) {
+    var message = arguments[1] || 'assertNotNull';
+    this.assert(object != null, message);
+  },
+  assertType: function(expected, actual) {
+    var message = arguments[2] || 'assertType';
+    try { 
+      (actual.constructor == expected) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + (actual.constructor) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertNotOfType: function(expected, actual) {
+    var message = arguments[2] || 'assertNotOfType';
+    try { 
+      (actual.constructor != expected) ? this.pass() : 
+      this.fail(message + ': expected "' + Test.Unit.inspect(expected) +  
+        '", actual "' + (actual.constructor) + '"'); }
+    catch(e) { this.error(e); }
+  },
+  assertInstanceOf: function(expected, actual) {
+    var message = arguments[2] || 'assertInstanceOf';
+    try { 
+      (actual instanceof expected) ? this.pass() : 
+      this.fail(message + ": object was not an instance of the expected type"); }
+    catch(e) { this.error(e); } 
+  },
+  assertNotInstanceOf: function(expected, actual) {
+    var message = arguments[2] || 'assertNotInstanceOf';
+    try { 
+      !(actual instanceof expected) ? this.pass() : 
+      this.fail(message + ": object was an instance of the not expected type"); }
+    catch(e) { this.error(e); } 
+  },
+  assertRespondsTo: function(method, obj) {
+    var message = arguments[2] || 'assertRespondsTo';
+    try {
+      (obj[method] && typeof obj[method] == 'function') ? this.pass() : 
+      this.fail(message + ": object doesn't respond to [" + method + "]"); }
+    catch(e) { this.error(e); }
+  },
+  assertReturnsTrue: function(method, obj) {
+    var message = arguments[2] || 'assertReturnsTrue';
+    try {
+      var m = obj[method];
+      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
+      m() ? this.pass() : 
+      this.fail(message + ": method returned false"); }
+    catch(e) { this.error(e); }
+  },
+  assertReturnsFalse: function(method, obj) {
+    var message = arguments[2] || 'assertReturnsFalse';
+    try {
+      var m = obj[method];
+      if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
+      !m() ? this.pass() : 
+      this.fail(message + ": method returned true"); }
+    catch(e) { this.error(e); }
+  },
+  assertRaise: function(exceptionName, method) {
+    var message = arguments[2] || 'assertRaise';
+    try { 
+      method();
+      this.fail(message + ": exception expected but none was raised"); }
+    catch(e) {
+      ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e); 
+    }
+  },
+  assertElementsMatch: function() {
+    var expressions = $A(arguments), elements = $A(expressions.shift());
+    if (elements.length != expressions.length) {
+      this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
+      return false;
+    }
+    elements.zip(expressions).all(function(pair, index) {
+      var element = $(pair.first()), expression = pair.last();
+      if (element.match(expression)) return true;
+      this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
+    }.bind(this)) && this.pass();
+  },
+  assertElementMatches: function(element, expression) {
+    this.assertElementsMatch([element], expression);
+  },
+  benchmark: function(operation, iterations) {
+    var startAt = new Date();
+    (iterations || 1).times(operation);
+    var timeTaken = ((new Date())-startAt);
+    this.info((arguments[2] || 'Operation') + ' finished ' + 
+       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
+    return timeTaken;
+  },
+  _isVisible: function(element) {
+    element = $(element);
+    if(!element.parentNode) return true;
+    this.assertNotNull(element);
+    if(element.style && Element.getStyle(element, 'display') == 'none')
+      return false;
+    
+    return this._isVisible(element.parentNode);
+  },
+  assertNotVisible: function(element) {
+    this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
+  },
+  assertVisible: function(element) {
+    this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+  },
+  benchmark: function(operation, iterations) {
+    var startAt = new Date();
+    (iterations || 1).times(operation);
+    var timeTaken = ((new Date())-startAt);
+    this.info((arguments[2] || 'Operation') + ' finished ' + 
+       iterations + ' iterations in ' + (timeTaken/1000)+'s' );
+    return timeTaken;
+  }
+}
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+  initialize: function(name, test, setup, teardown) {
+    Test.Unit.Assertions.prototype.initialize.bind(this)();
+    this.name           = name;
+    
+    if(typeof test == 'string') {
+      test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
+      test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
+      this.test = function() {
+        eval('with(this){'+test+'}');
+      }
+    } else {
+      this.test = test || function() {};
+    }
+    
+    this.setup          = setup || function() {};
+    this.teardown       = teardown || function() {};
+    this.isWaiting      = false;
+    this.timeToWait     = 1000;
+  },
+  wait: function(time, nextPart) {
+    this.isWaiting = true;
+    this.test = nextPart;
+    this.timeToWait = time;
+  },
+  run: function() {
+    try {
+      try {
+        if (!this.isWaiting) this.setup.bind(this)();
+        this.isWaiting = false;
+        this.test.bind(this)();
+      } finally {
+        if(!this.isWaiting) {
+          this.teardown.bind(this)();
+        }
+      }
+    }
+    catch(e) { this.error(e); }
+  }
+});
+
+// *EXPERIMENTAL* BDD-style testing to please non-technical folk
+// This draws many ideas from RSpec http://rspec.rubyforge.org/
+
+Test.setupBDDExtensionMethods = function(){
+  var METHODMAP = {
+    shouldEqual:     'assertEqual',
+    shouldNotEqual:  'assertNotEqual',
+    shouldEqualEnum: 'assertEnumEqual',
+    shouldBeA:       'assertType',
+    shouldNotBeA:    'assertNotOfType',
+    shouldBeAn:      'assertType',
+    shouldNotBeAn:   'assertNotOfType',
+    shouldBeNull:    'assertNull',
+    shouldNotBeNull: 'assertNotNull',
+    
+    shouldBe:        'assertReturnsTrue',
+    shouldNotBe:     'assertReturnsFalse',
+    shouldRespondTo: 'assertRespondsTo'
+  };
+  Test.BDDMethods = {};
+  for(m in METHODMAP) {
+    Test.BDDMethods[m] = eval(
+      'function(){'+
+      'var args = $A(arguments);'+
+      'var scope = args.shift();'+
+      'scope.'+METHODMAP[m]+'.apply(scope,(args || []).concat([this])); }');
+  }
+  [Array.prototype, String.prototype, Number.prototype].each(
+    function(p){ Object.extend(p, Test.BDDMethods) }
+  );
+}
+
+Test.context = function(name, spec, log){
+  Test.setupBDDExtensionMethods();
+  
+  var compiledSpec = {};
+  var titles = {};
+  for(specName in spec) {
+    switch(specName){
+      case "setup":
+      case "teardown":
+        compiledSpec[specName] = spec[specName];
+        break;
+      default:
+        var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
+        var body = spec[specName].toString().split('\n').slice(1);
+        if(/^\{/.test(body[0])) body = body.slice(1);
+        body.pop();
+        body = body.map(function(statement){ 
+          return statement.strip()
+        });
+        compiledSpec[testName] = body.join('\n');
+        titles[testName] = specName;
+    }
+  }
+  new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
+};
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/scriptaculous/wp-scriptaculous.js 2.2.2/wp-includes/js/scriptaculous/wp-scriptaculous.js
--- 2.0.5/wp-includes/js/scriptaculous/wp-scriptaculous.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/scriptaculous/wp-scriptaculous.js	2007-01-25 21:41:17.000000000 -0600
@@ -0,0 +1,40 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// 
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+
+var Scriptaculous = {
+  Version: '1.7.0',
+  require: function(libraryName) {
+    // inserting via DOM fails in Safari 2.0, so brute force approach
+    document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
+  },
+  load: function() {
+    if((typeof Prototype=='undefined') || 
+       (typeof Element == 'undefined') || 
+       (typeof Element.Methods=='undefined') ||
+       parseFloat(Prototype.Version.split(".")[0] + "." +
+                  Prototype.Version.split(".")[1]) < 1.5)
+       throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
+    
+    $A(document.getElementsByTagName("script")).findAll( function(s) {
+      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+    }).each( function(s) {
+      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+      var includes = s.src.match(/\?.*load=([a-z,]*)/);
+      if ( includes )
+       includes[1].split(',').each(
+       function(include) { Scriptaculous.require(path+include+'.js') });
+    });
+  }
+}
+
+Scriptaculous.load();
diff -ruN 2.0.5/wp-includes/js/tinymce/langs/en.js 2.2.2/wp-includes/js/tinymce/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/langs/en.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,47 +1,41 @@
-// UK lang variables
-
-if (navigator.userAgent.indexOf('Mac OS') != -1) {
-// Mac OS browsers use Ctrl to hit accesskeys
-	var metaKey = 'Ctrl';
-}
-else {
-	var metaKey = 'Alt';
-}
-
-tinyMCELang['lang_bold_desc'] = 'Bold (' + metaKey + '+b)';
-tinyMCELang['lang_italic_desc'] = 'Italic (' + metaKey + '+i)';
-tinyMCELang['lang_underline_desc'] = 'Underline';
-tinyMCELang['lang_striketrough_desc'] = 'Striketrough (' + metaKey + '-d)';
-tinyMCELang['lang_justifyleft_desc'] = 'Align left (' + metaKey + '-f)';
-tinyMCELang['lang_justifycenter_desc'] = 'Align center (' + metaKey + '-c)';
-tinyMCELang['lang_justifyright_desc'] = 'Align right (' + metaKey + '-r)';
-tinyMCELang['lang_justifyfull_desc'] = 'Align full';
-tinyMCELang['lang_bullist_desc'] = 'Unordered list (' + metaKey + '-l)';
-tinyMCELang['lang_numlist_desc'] = 'Ordered list (' + metaKey + '-o)';
-tinyMCELang['lang_outdent_desc'] = 'Outdent (' + metaKey + '-w)';
-tinyMCELang['lang_indent_desc'] = 'Indent/Blockquote (' + metaKey + '-q)';
-tinyMCELang['lang_undo_desc'] = 'Undo (' + metaKey + '-u)';
-tinyMCELang['lang_redo_desc'] = 'Redo (' + metaKey + '-y)';
-tinyMCELang['lang_link_desc'] = 'Insert/edit link (' + metaKey + '-a)';
-tinyMCELang['lang_unlink_desc'] = 'Unlink (' + metaKey + '-s)';
-tinyMCELang['lang_image_desc'] = 'Insert/edit image (' + metaKey + '-m)';
-tinyMCELang['lang_cleanup_desc'] = 'Cleanup messy code';
-tinyMCELang['lang_focus_alert'] = 'A editor instance must be focused before using this command.';
-tinyMCELang['lang_edit_confirm'] = 'Do you want to use the WYSIWYG mode for this textarea?';
-tinyMCELang['lang_insert_link_title'] = 'Insert/edit link';
-tinyMCELang['lang_insert'] = 'Insert';
-tinyMCELang['lang_update'] = 'Update';
-tinyMCELang['lang_cancel'] = 'Cancel';
-tinyMCELang['lang_insert_link_url'] = 'Link URL';
-tinyMCELang['lang_insert_link_target'] = 'Target';
-tinyMCELang['lang_insert_link_target_same'] = 'Open link in the same window';
-tinyMCELang['lang_insert_link_target_blank'] = 'Open link in a new window';
-tinyMCELang['lang_insert_image_title'] = 'Insert/edit image';
-tinyMCELang['lang_insert_image_src'] = 'Image URL';
-tinyMCELang['lang_insert_image_alt'] = 'Image description';
-tinyMCELang['lang_help_desc'] = 'Help';
-tinyMCELang['lang_bold_img'] = "bold.gif";
-tinyMCELang['lang_italic_img'] = "italic.gif";
-tinyMCELang['lang_underline_img'] = "underline.gif";
-tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?';
-tinyMCELang['lang_popup_blocked'] = 'Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.';
+// UK lang variables
+
+tinyMCE.addToLang('',{
+bold_desc : 'Bold (Ctrl+B)',
+italic_desc : 'Italic (Ctrl+I)',
+underline_desc : 'Underline (Ctrl+U)',
+striketrough_desc : 'Strikethrough',
+justifyleft_desc : 'Align left',
+justifycenter_desc : 'Align center',
+justifyright_desc : 'Align right',
+justifyfull_desc : 'Align full',
+bullist_desc : 'Unordered list',
+numlist_desc : 'Ordered list',
+outdent_desc : 'Outdent',
+indent_desc : 'Indent',
+undo_desc : 'Undo (Ctrl+Z)',
+redo_desc : 'Redo (Ctrl+Y)',
+link_desc : 'Insert/edit link',
+unlink_desc : 'Unlink',
+image_desc : 'Insert/edit image',
+cleanup_desc : 'Cleanup messy code',
+focus_alert : 'A editor instance must be focused before using this command.',
+edit_confirm : 'Do you want to use the WYSIWYG mode for this textarea?',
+insert_link_title : 'Insert/edit link',
+insert : 'Insert',
+update : 'Update',
+cancel : 'Cancel',
+insert_link_url : 'Link URL',
+insert_link_target : 'Target',
+insert_link_target_same : 'Open link in the same window',
+insert_link_target_blank : 'Open link in a new window',
+insert_image_title : 'Insert/edit image',
+insert_image_src : 'Image URL',
+insert_image_alt : 'Image description',
+help_desc : 'Help',
+bold_img : "bold.gif",
+italic_img : "italic.gif",
+underline_img : "underline.gif",
+clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?',
+popup_blocked : 'Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/license.txt 2.2.2/wp-includes/js/tinymce/license.txt
--- 2.0.5/wp-includes/js/tinymce/license.txt	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/license.txt	2006-11-20 18:55:06.000000000 -0600
@@ -1,13 +1,14 @@
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
 
- Copyright (C) 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
 
 			    Preamble
 
@@ -16,97 +17,109 @@
 Licenses are intended to guarantee your freedom to share and change
 free software--to make sure the software is free for all its users.
 
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
 
   To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
 
   For example, if you distribute copies of the library, whether gratis
 or for a fee, you must give the recipients all the rights that we gave
 you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
 it.  And you must show them these terms so they know their rights.
 
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
 permission to copy, distribute and/or modify the library.
 
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-.
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
 
   The precise terms and conditions for copying, distribution and
 modification follow.  Pay close attention to the difference between a
 "work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
 
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-.
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		  GNU LESSER GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
 
   A "library" means a collection of software functions and/or data
 prepared so as to be conveniently linked with application programs
@@ -145,7 +158,7 @@
   You may charge a fee for the physical act of transferring a copy,
 and you may at your option offer warranty protection in exchange for a
 fee.
-.
+
   2. You may modify your copy or copies of the Library or any portion
 of it, thus forming a work based on the Library, and copy and
 distribute such modifications or work under the terms of Section 1
@@ -203,7 +216,7 @@
 ordinary GNU General Public License has appeared, then you can specify
 that version instead if you wish.)  Do not make any other change in
 these notices.
-.
+
   Once this change is made in a given copy, it is irreversible for
 that copy, so the ordinary GNU General Public License applies to all
 subsequent copies and derivative works made from that copy.
@@ -254,8 +267,8 @@
 distribute the object code for the work under the terms of Section 6.
 Any executables containing that work also fall under Section 6,
 whether or not they are linked directly with the Library itself.
-.
-  6. As an exception to the Sections above, you may also compile or
+
+  6. As an exception to the Sections above, you may also combine or
 link a "work that uses the Library" with the Library to produce a
 work containing portions of the Library, and distribute that work
 under terms of your choice, provided that the terms permit
@@ -282,23 +295,31 @@
     Library will not necessarily be able to recompile the application
     to use the modified definitions.)
 
-    b) Accompany the work with a written offer, valid for at
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
     least three years, to give the same user the materials
     specified in Subsection 6a, above, for a charge no more
     than the cost of performing this distribution.
 
-    c) If distribution of the work is made by offering access to copy
+    d) If distribution of the work is made by offering access to copy
     from a designated place, offer equivalent access to copy the above
     specified materials from the same place.
 
-    d) Verify that the user has already received a copy of these
+    e) Verify that the user has already received a copy of these
     materials or that you have already sent this user a copy.
 
   For an executable, the required form of the "work that uses the
 Library" must include any data and utility programs needed for
 reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
 components (compiler, kernel, and so on) of the operating system on
 which the executable runs, unless that component itself accompanies
 the executable.
@@ -308,7 +329,7 @@
 accompany the operating system.  Such a contradiction means you cannot
 use both them and the Library together in an executable that you
 distribute.
-.
+
   7. You may place library facilities that are a work based on the
 Library side-by-side in a single library together with other library
 facilities not covered by this License, and distribute such a combined
@@ -347,9 +368,9 @@
 original licensor to copy, distribute, link with or modify the Library
 subject to these terms and conditions.  You may not impose any further
 restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
+You are not responsible for enforcing compliance by third parties with
 this License.
-.
+
   11. If, as a consequence of a court judgment or allegation of patent
 infringement or for any other reason (not limited to patent issues),
 conditions are imposed on you (whether by court order, agreement or
@@ -390,7 +411,7 @@
 written in the body of this License.
 
   13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
+versions of the Lesser General Public License from time to time.
 Such new versions will be similar in spirit to the present version,
 but may differ in detail to address new problems or concerns.
 
@@ -401,7 +422,7 @@
 the Free Software Foundation.  If the Library does not specify a
 license version number, you may choose any version ever published by
 the Free Software Foundation.
-.
+
   14. If you wish to incorporate parts of the Library into other free
 programs whose distribution conditions are incompatible with these,
 write to the author to ask for permission.  For software which is
@@ -435,3 +456,49 @@
 DAMAGES.
 
 		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/autosave/editor_plugin.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,2 +1,46 @@
-/* Import plugin specific language pack */
- tinyMCE.importPluginLanguagePack('autosave','en,sv,cs,he,no,hu,de,da,ru,ru_KOI8-R,ru_UTF-8,fi,cy,es,is,pl');function TinyMCE_autosave_getInfo(){return{longname:'Auto save',author:'Moxiecode Systems',authorurl:'http://tinymce.moxiecode.com',infourl:'http://tinymce.moxiecode.com/tinymce/docs/plugin_autosave.html',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion};};function TinyMCE_autosave_beforeUnloadHandler(){var msg=tinyMCE.getLang("lang_autosave_unload_msg");var anyDirty=false;for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(!tinyMCE.isInstance(inst))continue;if(inst.isDirty())return msg;}return;}window.onbeforeunload=TinyMCE_autosave_beforeUnloadHandler;
\ No newline at end of file
+/**
+ * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+/* Import plugin specific language pack */
+tinyMCE.importPluginLanguagePack('autosave');
+
+var TinyMCE_AutoSavePlugin = {
+	getInfo : function() {
+		return {
+			longname : 'Auto save',
+			author : 'Moxiecode Systems AB',
+			authorurl : 'http://tinymce.moxiecode.com',
+			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',
+			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
+		};
+	},
+
+	// Private plugin internal methods
+
+	_beforeUnloadHandler : function() {
+		var n, inst, anyDirty = false, msg = tinyMCE.getLang("lang_autosave_unload_msg");
+
+		if (tinyMCE.getParam("fullscreen_is_enabled"))
+			return;
+
+		for (n in tinyMCE.instances) {
+			inst = tinyMCE.instances[n];
+
+			if (!tinyMCE.isInstance(inst))
+				continue;
+
+			if (inst.isDirty())
+				return msg;
+		}
+
+		return;
+	}
+};
+
+window.onbeforeunload = TinyMCE_AutoSavePlugin._beforeUnloadHandler;
+
+tinyMCE.addPlugin("autosave", TinyMCE_AutoSavePlugin);
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js 2.2.2/wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js
--- 2.0.5/wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,30 +1,30 @@
-/* Import plugin specific language pack */
-tinyMCE.importPluginLanguagePack('autosave', 'en,sv,cs,he,no,hu,de,da,ru,ru_KOI8-R,ru_UTF-8,fi,cy,es,is,pl');
-
-function TinyMCE_autosave_getInfo() {
-	return {
-		longname : 'Auto save',
-		author : 'Moxiecode Systems',
-		authorurl : 'http://tinymce.moxiecode.com',
-		infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_autosave.html',
-		version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
-	};
-};
-
-function TinyMCE_autosave_beforeUnloadHandler() {
-	var msg = tinyMCE.getLang("lang_autosave_unload_msg");
-
-	var anyDirty = false;
-	for (var n in tinyMCE.instances) {
-		var inst = tinyMCE.instances[n];
-		if (!tinyMCE.isInstance(inst))
-			continue;
-
-		if (inst.isDirty())
-			return msg;
-	}
-
-	return;
-}
-
-window.onbeforeunload = TinyMCE_autosave_beforeUnloadHandler;
+/* Import plugin specific language pack */
+tinyMCE.importPluginLanguagePack('autosave', 'en,sv,cs,he,no,hu,de,da,ru,ru_KOI8-R,ru_UTF-8,fi,cy,es,is,pl');
+
+function TinyMCE_autosave_getInfo() {
+	return {
+		longname : 'Auto save',
+		author : 'Moxiecode Systems',
+		authorurl : 'http://tinymce.moxiecode.com',
+		infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_autosave.html',
+		version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
+	};
+};
+
+function TinyMCE_autosave_beforeUnloadHandler() {
+	var msg = tinyMCE.getLang("lang_autosave_unload_msg");
+
+	var anyDirty = false;
+	for (var n in tinyMCE.instances) {
+		var inst = tinyMCE.instances[n];
+		if (!tinyMCE.isInstance(inst))
+			continue;
+
+		if (inst.isDirty())
+			return msg;
+	}
+
+	return;
+}
+
+window.onbeforeunload = TinyMCE_autosave_beforeUnloadHandler;
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/autosave/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/autosave/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/autosave/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/autosave/langs/en.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,5 +1,5 @@
-// EN lang variables
-
-tinyMCE.addToLang('',{
-autosave_unload_msg : 'The changes you made will be lost if you navigate away from this page.'
-});
+// EN lang variables
+
+tinyMCE.addToLang('',{
+autosave_unload_msg : 'The changes you made will be lost if you navigate away from this page.'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/directionality/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/directionality/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/directionality/editor_plugin.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/directionality/editor_plugin.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,83 +1,90 @@
-/* Import plugin specific language pack */
-tinyMCE.importPluginLanguagePack('directionality', 'en,sv,fr_ca,zh_cn,cs,da,he,no,de,hu,ru,ru_KOI8-R,ru_UTF-8,es,cy,is,pl');
-
-function TinyMCE_directionality_getInfo() {
-	return {
-		longname : 'Directionality',
-		author : 'Moxiecode Systems',
-		authorurl : 'http://tinymce.moxiecode.com',
-		infourl : 'http://tinymce.moxiecode.com/tinymce/docs/plugin_directionality.html',
-		version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
-	};
-};
-
-function TinyMCE_directionality_getControlHTML(control_name) {
-    switch (control_name) {
-        case "ltr":
-			var cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceDirectionLTR\');return false;';
-            return '<a href="javascript:' + cmd + '" onclick="' + cmd + '" target="_self" onmousedown="return false;"><img id="{$editor_id}_ltr" src="{$pluginurl}/images/ltr.gif" title="{$lang_directionality_ltr_desc}" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>'
-			+ '<div class="zerosize"><input type="button" accesskey="." onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceDirectionLTR\',false);" /></div>';
-
-        case "rtl":
-			var cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceDirectionRTL\');return false;';
-            return '<a href="javascript:' + cmd + '" onclick="' + cmd + '" target="_self" onmousedown="return false;"><img id="{$editor_id}_rtl" src="{$pluginurl}/images/rtl.gif" title="{$lang_directionality_rtl_desc}" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>'
-			+ '<div class="zerosize"><input type="button" accesskey="," onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceDirectionRTL\',false);" /></div>';
-    }
-
-    return "";
-}
-
-function TinyMCE_directionality_execCommand(editor_id, element, command, user_interface, value) {
-	// Handle commands
-	switch (command) {
-		case "mceDirectionLTR":
-			var inst = tinyMCE.getInstanceById(editor_id);
-			var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
-
-			if (elm)
-				elm.setAttribute("dir", "ltr");
-
-			tinyMCE.triggerNodeChange(false);
-			return true;
-
-		case "mceDirectionRTL":
-			var inst = tinyMCE.getInstanceById(editor_id);
-			var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
-
-			if (elm)
-				elm.setAttribute("dir", "rtl");
-
-			tinyMCE.triggerNodeChange(false);
-			return true;
-	}
-
-	// Pass to next handler in chain
-	return false;
-}
-
-function TinyMCE_directionality_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
-	function getAttrib(elm, name) {
-		return elm.getAttribute(name) ? elm.getAttribute(name) : "";
-	}
-
-	tinyMCE.switchClassSticky(editor_id + '_ltr', 'mceButtonNormal', false);
-	tinyMCE.switchClassSticky(editor_id + '_rtl', 'mceButtonNormal', false);
-
-	if (node == null)
-		return;
-
-	var elm = tinyMCE.getParentElement(node, "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
-	if (!elm) {
-		tinyMCE.switchClassSticky(editor_id + '_ltr', 'mceButtonDisabled', true);
-		tinyMCE.switchClassSticky(editor_id + '_rtl', 'mceButtonDisabled', true);
-		return;
-	}
-
-	var dir = getAttrib(elm, "dir");
-	if (dir == "ltr" || dir == "")
-		tinyMCE.switchClassSticky(editor_id + '_ltr', 'mceButtonSelected', false);
-	else
-		tinyMCE.switchClassSticky(editor_id + '_rtl', 'mceButtonSelected', false);
-
-	return true;
-}
+/**
+ * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+/* Import plugin specific language pack */
+tinyMCE.importPluginLanguagePack('directionality');
+
+var TinyMCE_DirectionalityPlugin = {
+	getInfo : function() {
+		return {
+			longname : 'Directionality',
+			author : 'Moxiecode Systems AB',
+			authorurl : 'http://tinymce.moxiecode.com',
+			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality',
+			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
+		};
+	},
+
+	getControlHTML : function(cn) {
+		switch (cn) {
+			case "ltr":
+				return tinyMCE.getButtonHTML(cn, 'lang_directionality_ltr_desc', '{$pluginurl}/images/ltr.gif', 'mceDirectionLTR');
+
+			case "rtl":
+				return tinyMCE.getButtonHTML(cn, 'lang_directionality_rtl_desc', '{$pluginurl}/images/rtl.gif', 'mceDirectionRTL');
+		}
+
+		return "";
+	},
+
+	execCommand : function(editor_id, element, command, user_interface, value) {
+		// Handle commands
+		switch (command) {
+			case "mceDirectionLTR":
+				var inst = tinyMCE.getInstanceById(editor_id);
+				var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
+
+				if (elm)
+					elm.setAttribute("dir", "ltr");
+
+				tinyMCE.triggerNodeChange(false);
+				return true;
+
+			case "mceDirectionRTL":
+				var inst = tinyMCE.getInstanceById(editor_id);
+				var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
+
+				if (elm)
+					elm.setAttribute("dir", "rtl");
+
+				tinyMCE.triggerNodeChange(false);
+				return true;
+		}
+
+		// Pass to next handler in chain
+		return false;
+	},
+
+	handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
+		function getAttrib(elm, name) {
+			return elm.getAttribute(name) ? elm.getAttribute(name) : "";
+		}
+
+		if (node == null)
+			return;
+
+		var elm = tinyMCE.getParentElement(node, "p,div,td,h1,h2,h3,h4,h5,h6,pre,address");
+		if (!elm) {
+			tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonDisabled');
+			tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonDisabled');
+			return true;
+		}
+
+		tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonNormal');
+
+		var dir = getAttrib(elm, "dir");
+		if (dir == "ltr" || dir == "")
+			tinyMCE.switchClass(editor_id + '_ltr', 'mceButtonSelected');
+		else
+			tinyMCE.switchClass(editor_id + '_rtl', 'mceButtonSelected');
+
+		return true;
+	}
+};
+
+tinyMCE.addPlugin("directionality", TinyMCE_DirectionalityPlugin);
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/directionality/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/directionality/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/directionality/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/directionality/langs/en.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,6 +1,6 @@
-// UK lang variables
-
-tinyMCE.addToLang('',{
-directionality_ltr_desc : 'Direction left to right (Alt-.)',
-directionality_rtl_desc : 'Direction right to left (Alt-,)'
-});
+// UK lang variables
+
+tinyMCE.addToLang('',{
+directionality_ltr_desc : 'Direction left to right (Alt-.)',
+directionality_rtl_desc : 'Direction right to left (Alt-,)'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css
--- 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/css/inlinepopup.css	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,69 @@
+/* Window classes */
+
+.mceWindow {
+	position: absolute;
+	left: 0;
+	top: 0;
+	border: 1px solid black;
+	background-color: #D4D0C8;
+}
+
+.mceWindowHead {
+	background-color: #334F8D;
+	width: 100%;
+	height: 18px;
+	cursor: move;
+	overflow: hidden;
+}
+
+.mceWindowBody {
+	clear: both;
+	background-color: white;
+}
+
+.mceWindowStatusbar {
+	background-color: #D4D0C8;
+	height: 12px;
+	border-top: 1px solid black;
+}
+
+.mceWindowTitle {
+	float: left;
+	font-family: "MS Sans Serif";
+	font-size: 9pt;
+	font-weight: bold;
+	line-height: 18px;
+	color: white;
+	margin-left: 2px;
+	overflow: hidden;
+}
+
+.mceWindowHeadTools {
+	margin-right: 2px;
+}
+
+.mceWindowClose, .mceWindowMinimize, .mceWindowMaximize {
+	display: block;
+	float: right;
+	overflow: hidden;
+	margin-top: 2px;
+}
+
+.mceWindowClose {
+	margin-left: 2px;
+}
+
+.mceWindowMinimize {
+}
+
+.mceWindowMaximize {
+}
+
+.mceWindowResize {
+	display: block;
+	float: right;
+	overflow: hidden;
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js	2007-04-12 12:04:03.000000000 -0500
@@ -0,0 +1,817 @@
+/**
+ * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
+ *
+ * Moxiecode DHTML Windows script.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+// Patch openWindow, closeWindow TinyMCE functions
+
+var TinyMCE_InlinePopupsPlugin = {
+	getInfo : function() {
+		return {
+			longname : 'Inline Popups',
+			author : 'Moxiecode Systems AB',
+			authorurl : 'http://tinymce.moxiecode.com',
+			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups',
+			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
+		};
+	}
+};
+
+tinyMCE.addPlugin("inlinepopups", TinyMCE_InlinePopupsPlugin);
+
+// Patch openWindow, closeWindow TinyMCE functions
+
+TinyMCE_Engine.prototype.orgOpenWindow = TinyMCE_Engine.prototype.openWindow;
+TinyMCE_Engine.prototype.orgCloseWindow = TinyMCE_Engine.prototype.closeWindow;
+
+TinyMCE_Engine.prototype.openWindow = function(template, args) {
+	// Does the caller support inline
+	if (args['inline'] != "yes" || tinyMCE.isOpera || tinyMCE.getParam("plugins").indexOf('inlinepopups') == -1) {
+		mcWindows.selectedWindow = null;
+		args['mce_inside_iframe'] = false;
+		this.orgOpenWindow(template, args);
+		return;
+	}
+
+	var url, resizable, scrollbars;
+
+	args['mce_inside_iframe'] = true;
+	tinyMCE.windowArgs = args;
+
+	if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
+		url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
+	else
+		url = template['file'];
+
+	if (!(width = parseInt(template['width'])))
+		width = 320;
+
+	if (!(height = parseInt(template['height'])))
+		height = 200;
+
+	if (!(minWidth = parseInt(template['minWidth'])))
+		minWidth = 100;
+
+	if (!(minHeight = parseInt(template['minHeight'])))
+		minHeight = 100;
+
+	resizable = (args && args['resizable']) ? args['resizable'] : "no";
+	scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
+
+	height += 18;
+
+	// Replace all args as variables in URL
+	for (var name in args) {
+		if (typeof(args[name]) == 'function')
+			continue;
+
+		url = tinyMCE.replaceVar(url, name, escape(args[name]));
+	}
+
+	var elm = document.getElementById(this.selectedInstance.editorId + '_parent');
+
+	if (tinyMCE.hasPlugin('fullscreen') && this.selectedInstance.getData('fullscreen').enabled)
+		pos = { absLeft: 0, absTop: 0 };
+	else
+		pos = tinyMCE.getAbsPosition(elm);
+
+	// Center div in editor area
+	pos.absLeft += Math.round((elm.firstChild.clientWidth / 2) - (width / 2));
+	pos.absTop += Math.round((elm.firstChild.clientHeight / 2) - (height / 2));
+
+	url += tinyMCE.settings['imp_version'] ? (url.indexOf('?')==-1?'?':'&') + 'ver=' + tinyMCE.settings['imp_version'] : ''; // WordPress cache buster
+
+	mcWindows.open(url, mcWindows.idCounter++, "modal=yes,width=" + width+ ",height=" + height + ",resizable=" + resizable + ",scrollbars=" + scrollbars + ",statusbar=" + resizable + ",left=" + pos.absLeft + ",top=" + pos.absTop + ",minWidth=" + minWidth + ",minHeight=" + minHeight );
+};
+
+TinyMCE_Engine.prototype.closeWindow = function(win) {
+	var gotit = false, n, w;
+	for (n in mcWindows.windows) {
+		w = mcWindows.windows[n];
+		if (typeof(w) == 'function') continue;
+		if (win.name == w.id + '_iframe') {
+			w.close();
+			gotit = true;
+		}
+	}
+	if (!gotit)
+		this.orgCloseWindow(win);
+
+	tinyMCE.selectedInstance.getWin().focus(); 
+};
+
+TinyMCE_Engine.prototype.setWindowTitle = function(win_ref, title) {
+	for (var n in mcWindows.windows) {
+		var win = mcWindows.windows[n];
+		if (typeof(win) == 'function')
+			continue;
+
+		if (win_ref.name == win.id + "_iframe")
+			window.frames[win.id + "_iframe"].document.getElementById(win.id + '_title').innerHTML = title;
+	}
+};
+
+// * * * * * TinyMCE_Windows classes below
+
+// Windows handler
+function TinyMCE_Windows() {
+	this.settings = new Array();
+	this.windows = new Array();
+	this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
+	this.isGecko = navigator.userAgent.indexOf('Gecko') != -1;
+	this.isSafari = navigator.userAgent.indexOf('Safari') != -1;
+	this.isMac = navigator.userAgent.indexOf('Mac') != -1;
+	this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1);
+	this.action = "none";
+	this.selectedWindow = null;
+	this.lastSelectedWindow = null;
+	this.zindex = 1001;
+	this.mouseDownScreenX = 0;
+	this.mouseDownScreenY = 0;
+	this.mouseDownLayerX = 0;
+	this.mouseDownLayerY = 0;
+	this.mouseDownWidth = 0;
+	this.mouseDownHeight = 0;
+	this.idCounter = 0;
+};
+
+TinyMCE_Windows.prototype.init = function(settings) {
+	this.settings = settings;
+
+	if (this.isMSIE)
+		this.addEvent(document, "mousemove", mcWindows.eventDispatcher);
+	else
+		this.addEvent(window, "mousemove", mcWindows.eventDispatcher);
+
+	this.addEvent(document, "mouseup", mcWindows.eventDispatcher);
+
+	this.addEvent(window, "resize", mcWindows.eventDispatcher);
+	this.addEvent(document, "scroll", mcWindows.eventDispatcher);
+
+	this.doc = document;
+};
+
+TinyMCE_Windows.prototype.getBounds = function() {
+	if (!this.bounds) {
+		var vp = tinyMCE.getViewPort(window);
+		var top, left, bottom, right, docEl = this.doc.documentElement;
+
+		top    = vp.top;
+		left   = vp.left;
+		bottom = vp.height + top - 2;
+		right  = vp.width  + left - 22; // TODO this number is platform dependant
+		// x1, y1, x2, y2
+		this.bounds = [left, top, right, bottom];
+	}
+	return this.bounds;
+};
+
+TinyMCE_Windows.prototype.clampBoxPosition = function(x, y, w, h, minW, minH) {
+	var bounds = this.getBounds();
+
+	x = Math.max(bounds[0], Math.min(bounds[2], x + w) - w);
+	y = Math.max(bounds[1], Math.min(bounds[3], y + h) - h);
+
+	return this.clampBoxSize(x, y, w, h, minW, minH);
+};
+
+TinyMCE_Windows.prototype.clampBoxSize = function(x, y, w, h, minW, minH) {
+	var bounds = this.getBounds();
+
+	return [
+		x, y,
+		Math.max(minW, Math.min(bounds[2], x + w) - x),
+		Math.max(minH, Math.min(bounds[3], y + h) - y)
+	];
+};
+
+TinyMCE_Windows.prototype.getParam = function(name, default_value) {
+	var value = null;
+
+	value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
+
+	// Fix bool values
+	if (value == "true" || value == "false")
+		return (value == "true");
+
+	return value;
+};
+
+TinyMCE_Windows.prototype.eventDispatcher = function(e) {
+	e = typeof(e) == "undefined" ? window.event : e;
+
+	if (mcWindows.selectedWindow == null)
+		return;
+
+	// Switch focus
+	if (mcWindows.isGecko && e.type == "mousedown") {
+		var elm = e.currentTarget;
+
+		for (var n in mcWindows.windows) {
+			var win = mcWindows.windows[n];
+
+			if (win.headElement == elm || win.resizeElement == elm) {
+				win.focus();
+				break;
+			}
+		}
+	}
+
+	switch (e.type) {
+		case "mousemove":
+			mcWindows.selectedWindow.onMouseMove(e);
+			break;
+
+		case "mouseup":
+			mcWindows.selectedWindow.onMouseUp(e);
+			break;
+
+		case "mousedown":
+			mcWindows.selectedWindow.onMouseDown(e);
+			break;
+
+		case "focus":
+			mcWindows.selectedWindow.onFocus(e);
+			break;
+		case "scroll":
+		case "resize":
+			if (mcWindows.clampUpdateTimeout)
+				clearTimeout(mcWindows.clampUpdateTimeout);
+			mcWindows.clampEventType = e.type;
+			mcWindows.clampUpdateTimeout =
+				setTimeout(function () {mcWindows.updateClamping()}, 100);
+			break;
+	}
+};
+
+TinyMCE_Windows.prototype.updateClamping = function () {
+	var clamp, oversize, etype = mcWindows.clampEventType;
+
+	this.bounds = null; // Recalc window bounds on resize/scroll
+	this.clampUpdateTimeout = null;
+
+	for (var n in this.windows) {
+		win = this.windows[n];
+		if (typeof(win) == 'function' || ! win.winElement) continue;
+
+		clamp = mcWindows.clampBoxPosition(
+			win.left, win.top,
+			win.winElement.scrollWidth,
+			win.winElement.scrollHeight,
+			win.features.minWidth,
+			win.features.minHeight
+		);
+		oversize = (
+			clamp[2] != win.winElement.scrollWidth ||
+			clamp[3] != win.winElement.scrollHeight
+		) ? true : false;
+
+		if (!oversize || win.features.resizable == "yes" || etype != "scroll")
+			win.moveTo(clamp[0], clamp[1]);
+		if (oversize && win.features.resizable == "yes")
+			win.resizeTo(clamp[2], clamp[3]);
+	}
+};
+
+TinyMCE_Windows.prototype.addEvent = function(obj, name, handler) {
+	if (this.isMSIE)
+		obj.attachEvent("on" + name, handler);
+	else
+		obj.addEventListener(name, handler, false);
+};
+
+TinyMCE_Windows.prototype.cancelEvent = function(e) {
+	if (this.isMSIE) {
+		e.returnValue = false;
+		e.cancelBubble = true;
+	} else
+		e.preventDefault();
+};
+
+TinyMCE_Windows.prototype.parseFeatures = function(opts) {
+	// Cleanup the options
+	opts = opts.toLowerCase();
+	opts = opts.replace(/;/g, ",");
+	opts = opts.replace(/[^0-9a-z=,]/g, "");
+
+	var optionChunks = opts.split(',');
+	var options = new Array();
+
+	options['left'] = "10";
+	options['top'] = "10";
+	options['width'] = "300";
+	options['height'] = "300";
+	options['minwidth'] = "100";
+	options['minheight'] = "100";
+	options['resizable'] = "yes";
+	options['minimizable'] = "yes";
+	options['maximizable'] = "yes";
+	options['close'] = "yes";
+	options['movable'] = "yes";
+	options['statusbar'] = "yes";
+	options['scrollbars'] = "auto";
+	options['modal'] = "no";
+
+	if (opts == "")
+		return options;
+
+	for (var i=0; i<optionChunks.length; i++) {
+		var parts = optionChunks[i].split('=');
+
+		if (parts.length == 2)
+			options[parts[0]] = parts[1];
+	}
+
+	options['left'] = parseInt(options['left']);
+	options['top'] = parseInt(options['top']);
+	options['width'] = parseInt(options['width']);
+	options['height'] = parseInt(options['height']);
+	options['minWidth'] = parseInt(options['minwidth']);
+	options['minHeight'] = parseInt(options['minheight']);
+
+	return options;
+};
+
+TinyMCE_Windows.prototype.open = function(url, name, features) {
+	this.lastSelectedWindow = this.selectedWindow;
+
+	var win = new TinyMCE_Window();
+	var winDiv, html = "", id;
+	var imgPath = this.getParam("images_path");
+
+	features = this.parseFeatures(features);
+
+	// Clamp specified dimensions
+	var clamp = mcWindows.clampBoxPosition(
+		features['left'], features['top'],
+		features['width'], features['height'],
+		features['minWidth'], features['minHeight']
+	);
+
+	features['left'] = clamp[0];
+	features['top'] = clamp[1];
+
+	if (features['resizable'] == "yes") {
+		features['width'] = clamp[2];
+		features['height'] = clamp[3];
+	}
+
+	// Create div
+	id = "mcWindow_" + name;
+	win.deltaHeight = 18;
+
+	if (features['statusbar'] == "yes") {
+		win.deltaHeight += 13;
+
+		if (this.isMSIE)
+			win.deltaHeight += 1;
+	}
+
+	width = parseInt(features['width']);
+	height = parseInt(features['height'])-win.deltaHeight;
+
+	if (this.isMSIE)
+		width -= 2;
+
+	// Setup first part of window
+	win.id = id;
+	win.url = url;
+	win.name = name;
+	win.features = features;
+	this.windows[name] = win;
+
+	iframeWidth = width;
+	iframeHeight = height;
+
+	// Create inner content
+	html += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
+	html += '<html>';
+	html += '<head>';
+	html += '<title>Wrapper iframe</title>';
+	if (this.isMac) html += '<style type="text/css">.mceWindowTitle{float:none;margin:0;width:100%;text-align:center;}.mceWindowClose{float:none;position:absolute;left:0px;top:0px;}</style>';
+	html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
+	html += '<link href="' + this.getParam("css_file") + '" rel="stylesheet" type="text/css" />';
+	html += '</head>';
+	html += '<body onload="parent.mcWindows.onLoad(\'' + name + '\');">';
+
+	html += '<div id="' + id + '_container" class="mceWindow">';
+	html += '<div id="' + id + '_head" class="mceWindowHead" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
+	html += '  <div id="' + id + '_title" class="mceWindowTitle"';
+	html += '  onselectstart="return false;" unselectable="on" style="-moz-user-select: none !important;"></div>';
+	html += '    <div class="mceWindowHeadTools">';
+	html += '      <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].close();" target="_self" onmousedown="return false;" class="mceWindowClose"><img border="0" src="' + imgPath + '/window_close.gif" /></a>';
+	if (features['resizable'] == "yes" && features['maximizable'] == "yes")
+		html += '      <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].maximize();" target="_self" onmousedown="return false;" class="mceWindowMaximize"><img border="0" src="' + imgPath + '/window_maximize.gif" /></a>';
+	// html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].minimize();" target="_self" onmousedown="return false;" class="mceWindowMinimize"></a>';
+	html += '    </div>';
+	html += '</div><div id="' + id + '_body" class="mceWindowBody" style="width: ' + width + 'px; height: ' + height + 'px;">';
+	html += '<iframe id="' + id + '_iframe" name="' + id + '_iframe" frameborder="0" width="' + iframeWidth + '" height="' + iframeHeight + '" src="' + url + '" class="mceWindowBodyIframe" scrolling="' + features['scrollbars'] + '"></iframe></div>';
+
+	if (features['statusbar'] == "yes") {
+		html += '<div id="' + id + '_statusbar" class="mceWindowStatusbar" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
+
+		if (features['resizable'] == "yes") {
+			if (this.isGecko)
+				html += '<div id="' + id + '_resize" class="mceWindowResize"><div style="background-image: url(\'' + imgPath + '/window_resize.gif\'); width: 12px; height: 12px;"></div></div>';
+			else
+				html += '<div id="' + id + '_resize" class="mceWindowResize"><img onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();" border="0" src="' + imgPath + '/window_resize.gif" /></div>';
+		}
+
+		html += '</div>';
+	}
+
+	html += '</div>';
+
+	html += '</body>';
+	html += '</html>';
+
+	// Create iframe
+	this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html);
+};
+
+// Blocks the document events by placing a image over the whole document
+TinyMCE_Windows.prototype.setDocumentLock = function(state) {
+	var elm = document.getElementById('mcWindowEventBlocker');
+
+	if (state) {
+		if (elm == null) {
+			elm = document.createElement("div");
+
+			elm.id = "mcWindowEventBlocker";
+			elm.style.position = "absolute";
+			elm.style.left = "0";
+			elm.style.top = "0";
+
+			document.body.appendChild(elm);
+		}
+
+		elm.style.display = "none";
+
+		var imgPath = this.getParam("images_path");
+		var width = document.body.clientWidth;
+		var height = document.body.clientHeight;
+
+		elm.style.width = width;
+		elm.style.height = height;
+		elm.innerHTML = '<img src="' + imgPath + '/spacer.gif" width="' + width + '" height="' + height + '" />';
+
+		elm.style.zIndex = mcWindows.zindex-1;
+		elm.style.display = "block";
+	} else if (elm != null) {
+		if (mcWindows.windows.length == 0)
+			elm.parentNode.removeChild(elm);
+		else
+			elm.style.zIndex = mcWindows.zindex-1;
+	}
+};
+
+// Gets called when wrapper iframe is initialized
+TinyMCE_Windows.prototype.onLoad = function(name) {
+	var win = mcWindows.windows[name];
+	var id = "mcWindow_" + name;
+	var wrapperIframe = window.frames[id + "_iframe"].frames[0];
+	var wrapperDoc = window.frames[id + "_iframe"].document;
+	var doc = window.frames[id + "_iframe"].document;
+	var winDiv = document.getElementById("mcWindow_" + name + "_div");
+	var realIframe = window.frames[id + "_iframe"].frames[0];
+
+	// Set window data
+	win.id = "mcWindow_" + name;
+	win.winElement = winDiv;
+	win.bodyElement = doc.getElementById(id + '_body');
+	win.iframeElement = doc.getElementById(id + '_iframe');
+	win.headElement = doc.getElementById(id + '_head');
+	win.titleElement = doc.getElementById(id + '_title');
+	win.resizeElement = doc.getElementById(id + '_resize');
+	win.containerElement = doc.getElementById(id + '_container');
+	win.left = win.features['left'];
+	win.top = win.features['top'];
+	win.frame = window.frames[id + '_iframe'].frames[0];
+	win.wrapperFrame = window.frames[id + '_iframe'];
+	win.wrapperIFrameElement = document.getElementById(id + "_iframe");
+
+	// Add event handlers
+	mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher);
+
+	if (win.resizeElement != null)
+		mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher);
+
+	if (mcWindows.isMSIE) {
+		mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher);
+	} else {
+		mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher);
+	}
+
+	for (var i=0; i<window.frames.length; i++) {
+		if (!window.frames[i]._hasMouseHandlers) {
+			if (mcWindows.isMSIE) {
+				mcWindows.addEvent(window.frames[i].document, "mousemove", mcWindows.eventDispatcher);
+				mcWindows.addEvent(window.frames[i].document, "mouseup", mcWindows.eventDispatcher);
+			} else {
+				mcWindows.addEvent(window.frames[i], "mousemove", mcWindows.eventDispatcher);
+				mcWindows.addEvent(window.frames[i], "mouseup", mcWindows.eventDispatcher);
+			}
+
+			window.frames[i]._hasMouseHandlers = true;
+		}
+	}
+
+	if (mcWindows.isMSIE) {
+		mcWindows.addEvent(win.frame.document, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame.document, "mouseup", mcWindows.eventDispatcher);
+	} else {
+		mcWindows.addEvent(win.frame, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame, "mouseup", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame, "focus", mcWindows.eventDispatcher);
+	}
+
+	// Dispatch open window event
+	var func = this.getParam("on_open_window", "");
+	if (func != "")
+		eval(func + "(win);");
+
+	win.focus();
+
+	if (win.features['modal'] == "yes")
+		mcWindows.setDocumentLock(true);
+};
+
+TinyMCE_Windows.prototype.createFloatingIFrame = function(id_prefix, left, top, width, height, html) {
+	var iframe = document.createElement("iframe");
+	var div = document.createElement("div"), doc;
+
+	width = parseInt(width);
+	height = parseInt(height)+1;
+
+	// Create wrapper div
+	div.setAttribute("id", id_prefix + "_div");
+	div.setAttribute("width", width);
+	div.setAttribute("height", (height));
+	div.style.position = "absolute";
+
+	div.style.left = left + "px";
+	div.style.top = top + "px";
+	div.style.width = width + "px";
+	div.style.height = (height) + "px";
+	div.style.backgroundColor = "white";
+	div.style.display = "none";
+
+	if (this.isGecko) {
+		iframeWidth = width + 2;
+		iframeHeight = height + 2;
+	} else {
+		iframeWidth = width;
+		iframeHeight = height + 1;
+	}
+
+	// Create iframe
+	iframe.setAttribute("id", id_prefix + "_iframe");
+	iframe.setAttribute("name", id_prefix + "_iframe");
+	iframe.setAttribute("border", "0");
+	iframe.setAttribute("frameBorder", "0");
+	iframe.setAttribute("marginWidth", "0");
+	iframe.setAttribute("marginHeight", "0");
+	iframe.setAttribute("leftMargin", "0");
+	iframe.setAttribute("topMargin", "0");
+	iframe.setAttribute("width", iframeWidth);
+	iframe.setAttribute("height", iframeHeight);
+	// iframe.setAttribute("src", "../jscripts/tiny_mce/blank.htm");
+	// iframe.setAttribute("allowtransparency", "false");
+	iframe.setAttribute("scrolling", "no");
+	iframe.style.width = iframeWidth + "px";
+	iframe.style.height = iframeHeight + "px";
+	iframe.style.backgroundColor = "white";
+	div.appendChild(iframe);
+
+	document.body.appendChild(div);
+
+	// Fixed MSIE 5.0 issue
+	div.innerHTML = div.innerHTML;
+
+	if (this.isSafari) {
+		// Give Safari some time to setup
+		window.setTimeout(function() {
+			var doc = window.frames[id_prefix + '_iframe'].document;
+			doc.open();
+			doc.write(html);
+			doc.close();
+		}, 10);
+	} else {
+		doc = window.frames[id_prefix + '_iframe'].window.document;
+		doc.open();
+		doc.write(html);
+		doc.close();
+	}
+
+	div.style.display = "block";
+
+	return div;
+};
+
+// Window instance
+function TinyMCE_Window() {
+};
+
+TinyMCE_Window.prototype.focus = function() {
+	if (this != mcWindows.selectedWindow) {
+		this.winElement.style.zIndex = ++mcWindows.zindex;
+		mcWindows.lastSelectedWindow = mcWindows.selectedWindow;
+		mcWindows.selectedWindow = this;
+	}
+};
+
+TinyMCE_Window.prototype.minimize = function() {
+};
+
+TinyMCE_Window.prototype.maximize = function() {
+	if (this.restoreSize) {
+		this.moveTo(this.restoreSize[0], this.restoreSize[1]);
+		this.resizeTo(this.restoreSize[2], this.restoreSize[3]);
+		this.updateClamping();
+		this.restoreSize = null;
+	} else {
+		var bounds = mcWindows.getBounds();
+		this.restoreSize = [
+			this.left, this.top,
+			this.winElement.scrollWidth,
+			this.winElement.scrollHeight
+		];
+		this.moveTo(bounds[0], bounds[1]);
+		this.resizeTo(
+			bounds[2] - bounds[0],
+			bounds[3] - bounds[1]
+		);
+	}
+};
+
+TinyMCE_Window.prototype.startResize = function() {
+	mcWindows.action = "resize";
+};
+
+TinyMCE_Window.prototype.startMove = function(e) {
+	mcWindows.action = "move";
+};
+
+TinyMCE_Window.prototype.close = function() {
+	if (this.frame && this.frame['tinyMCEPopup'])
+		this.frame['tinyMCEPopup'].restoreSelection();
+
+	if (mcWindows.lastSelectedWindow != null)
+		mcWindows.lastSelectedWindow.focus();
+
+	var mcWindowsNew = new Array();
+	for (var n in mcWindows.windows) {
+		var win = mcWindows.windows[n];
+		if (typeof(win) == 'function')
+			continue;
+
+		if (win.name != this.name)
+			mcWindowsNew[n] = win;
+	}
+
+	mcWindows.windows = mcWindowsNew;
+
+	// alert(mcWindows.doc.getElementById(this.id + "_iframe"));
+
+	var e = mcWindows.doc.getElementById(this.id + "_iframe");
+	e.parentNode.removeChild(e);
+
+	var e = mcWindows.doc.getElementById(this.id + "_div");
+	e.parentNode.removeChild(e);
+
+	mcWindows.setDocumentLock(false);
+};
+
+TinyMCE_Window.prototype.onMouseMove = function(e) {
+	var clamp;
+	// Calculate real X, Y
+	var dx = e.screenX - mcWindows.mouseDownScreenX;
+	var dy = e.screenY - mcWindows.mouseDownScreenY;
+
+	switch (mcWindows.action) {
+		case "resize":
+			clamp = mcWindows.clampBoxSize(
+				this.left, this.top,
+				mcWindows.mouseDownWidth + (e.screenX - mcWindows.mouseDownScreenX),
+				mcWindows.mouseDownHeight + (e.screenY - mcWindows.mouseDownScreenY),
+				this.features.minWidth, this.features.minHeight
+			);
+
+			this.resizeTo(clamp[2], clamp[3]);
+
+			mcWindows.cancelEvent(e);
+			break;
+
+		case "move":
+			this.left = mcWindows.mouseDownLayerX + (e.screenX - mcWindows.mouseDownScreenX);
+			this.top = mcWindows.mouseDownLayerY + (e.screenY - mcWindows.mouseDownScreenY);
+			this.updateClamping();
+
+			mcWindows.cancelEvent(e);
+			break;
+	}
+};
+
+TinyMCE_Window.prototype.moveTo = function (x, y) {
+	this.left = x;
+	this.top = y;
+
+	this.winElement.style.left = this.left + "px";
+	this.winElement.style.top = this.top + "px";
+};
+
+TinyMCE_Window.prototype.resizeTo = function (width, height) {
+	this.wrapperIFrameElement.style.width = (width+2) + 'px';
+	this.wrapperIFrameElement.style.height = (height+2) + 'px';
+	this.wrapperIFrameElement.width = width+2;
+	this.wrapperIFrameElement.height = height+2;
+	this.winElement.style.width = width + 'px';
+	this.winElement.style.height = height + 'px';
+
+	height = height - this.deltaHeight;
+
+	this.containerElement.style.width = width + 'px';
+	this.iframeElement.style.width = width + 'px';
+	this.iframeElement.style.height = height + 'px';
+	this.bodyElement.style.width = width + 'px';
+	this.bodyElement.style.height = height + 'px';
+	this.headElement.style.width = width + 'px';
+	//this.statusElement.style.width = width + 'px';
+};
+
+TinyMCE_Window.prototype.updateClamping = function () {
+	var clamp, oversize;
+
+	clamp = mcWindows.clampBoxPosition(
+		this.left, this.top,
+		this.winElement.scrollWidth,
+		this.winElement.scrollHeight,
+		this.features.minWidth, this.features.minHeight
+	);
+	oversize = (
+		clamp[2] != this.winElement.scrollWidth ||
+		clamp[3] != this.winElement.scrollHeight
+	) ? true : false;
+
+	this.moveTo(clamp[0], clamp[1]);
+	if (this.features.resizable == "yes" && oversize)
+		this.resizeTo(clamp[2], clamp[3]);
+};
+
+function debug(msg) {
+	document.getElementById('debug').value += msg + "\n";
+}
+
+TinyMCE_Window.prototype.onMouseUp = function(e) {
+	mcWindows.action = "none";
+};
+
+TinyMCE_Window.prototype.onFocus = function(e) {
+	// Gecko only handler
+	var winRef = e.currentTarget;
+
+	for (var n in mcWindows.windows) {
+		var win = mcWindows.windows[n];
+		if (typeof(win) == 'function')
+			continue;
+
+		if (winRef.name == win.id + "_iframe") {
+			win.focus();
+			return;
+		}
+	}
+};
+
+TinyMCE_Window.prototype.onMouseDown = function(e) {
+	var elm = mcWindows.isMSIE ? this.wrapperFrame.event.srcElement : e.target;
+
+	mcWindows.mouseDownScreenX = e.screenX;
+	mcWindows.mouseDownScreenY = e.screenY;
+	mcWindows.mouseDownLayerX = this.left;
+	mcWindows.mouseDownLayerY = this.top;
+	mcWindows.mouseDownWidth = parseInt(this.winElement.style.width);
+	mcWindows.mouseDownHeight = parseInt(this.winElement.style.height);
+
+	if (this.resizeElement != null && elm == this.resizeElement.firstChild)
+		this.startResize(e);
+	else
+		this.startMove(e);
+
+	mcWindows.cancelEvent(e);
+};
+
+// Global instance
+var mcWindows = new TinyMCE_Windows();
+
+// Initialize windows
+mcWindows.init({
+	images_path : tinyMCE.baseURL + "/plugins/inlinepopups/images",
+	css_file : tinyMCE.baseURL + "/plugins/inlinepopups/css/inlinepopup.css"
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/jscripts/mcwindows.js 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/jscripts/mcwindows.js
--- 2.0.5/wp-includes/js/tinymce/plugins/inlinepopups/jscripts/mcwindows.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/inlinepopups/jscripts/mcwindows.js	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,453 @@
+/**
+ * $Id: mcwindows.js 18 2006-06-29 14:11:23Z spocke $
+ *
+ * Moxiecode DHTML Windows script.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004, Moxiecode Systems AB, All rights reserved.
+ */
+
+// Windows handler
+function MCWindows() {
+	this.settings = new Array();
+	this.windows = new Array();
+	this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
+	this.isGecko = navigator.userAgent.indexOf('Gecko') != -1;
+	this.isSafari = navigator.userAgent.indexOf('Safari') != -1;
+	this.isMac = navigator.userAgent.indexOf('Mac') != -1;
+	this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1);
+	this.action = "none";
+	this.selectedWindow = null;
+	this.zindex = 100;
+	this.mouseDownScreenX = 0;
+	this.mouseDownScreenY = 0;
+	this.mouseDownLayerX = 0;
+	this.mouseDownLayerY = 0;
+	this.mouseDownWidth = 0;
+	this.mouseDownHeight = 0;
+};
+
+MCWindows.prototype.init = function(settings) {
+	this.settings = settings;
+
+	if (this.isMSIE)
+		this.addEvent(document, "mousemove", mcWindows.eventDispatcher);
+	else
+		this.addEvent(window, "mousemove", mcWindows.eventDispatcher);
+
+	this.addEvent(document, "mouseup", mcWindows.eventDispatcher);
+};
+
+MCWindows.prototype.getParam = function(name, default_value) {
+	var value = null;
+
+	value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
+
+	// Fix bool values
+	if (value == "true" || value == "false")
+		return (value == "true");
+
+	return value;
+};
+
+MCWindows.prototype.eventDispatcher = function(e) {
+	e = typeof(e) == "undefined" ? window.event : e;
+
+	if (mcWindows.selectedWindow == null)
+		return;
+
+	// Switch focus
+	if (mcWindows.isGecko && e.type == "mousedown") {
+		var elm = e.currentTarget;
+
+		for (var n in mcWindows.windows) {
+			var win = mcWindows.windows[n];
+			if (typeof(win) == 'function')
+				continue;
+
+			if (win.headElement == elm || win.resizeElement == elm) {
+				win.focus();
+				break;
+			}
+		}
+	}
+
+	switch (e.type) {
+		case "mousemove":
+			mcWindows.selectedWindow.onMouseMove(e);
+			break;
+
+		case "mouseup":
+			mcWindows.selectedWindow.onMouseUp(e);
+			break;
+
+		case "mousedown":
+			mcWindows.selectedWindow.onMouseDown(e);
+			break;
+
+		case "focus":
+			mcWindows.selectedWindow.onFocus(e);
+			break;
+	}
+}
+
+MCWindows.prototype.addEvent = function(obj, name, handler) {
+	if (this.isMSIE)
+		obj.attachEvent("on" + name, handler);
+	else
+		obj.addEventListener(name, handler, true);
+};
+
+MCWindows.prototype.cancelEvent = function(e) {
+	if (this.isMSIE) {
+		e.returnValue = false;
+		e.cancelBubble = true;
+	} else
+		e.preventDefault();
+};
+
+MCWindows.prototype.parseFeatures = function(opts) {
+	// Cleanup the options
+	opts = opts.toLowerCase();
+	opts = opts.replace(/;/g, ",");
+	opts = opts.replace(/[^0-9a-z=,]/g, "");
+
+	var optionChunks = opts.split(',');
+	var options = new Array();
+
+	options['left'] = 10;
+	options['top'] = 10;
+	options['width'] = 300;
+	options['height'] = 300;
+	options['resizable'] = true;
+	options['minimizable'] = true;
+	options['maximizable'] = true;
+	options['close'] = true;
+	options['movable'] = true;
+
+	if (opts == "")
+		return options;
+
+	for (var i=0; i<optionChunks.length; i++) {
+		var parts = optionChunks[i].split('=');
+
+		if (parts.length == 2)
+			options[parts[0]] = parts[1];
+	}
+
+	return options;
+};
+
+MCWindows.prototype.open = function(url, name, features) {
+	var win = new MCWindow();
+	var winDiv, html = "", id;
+
+	features = this.parseFeatures(features);
+
+	// Create div
+	id = "mcWindow_" + name;
+
+	width = parseInt(features['width']);
+	height = parseInt(features['height'])-12-19;
+
+	if (this.isMSIE)
+		width -= 2;
+
+	// Setup first part of window
+	win.id = id;
+	win.url = url;
+	win.name = name;
+	win.features = features;
+	this.windows[name] = win;
+
+	iframeWidth = width;
+	iframeHeight = height;
+
+	// Create inner content
+	html += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
+	html += '<html>';
+	html += '<head>';
+	html += '<title>Wrapper iframe</title>';
+	html += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
+	html += '<link href="../jscripts/tiny_mce/themes/advanced/css/editor_ui.css" rel="stylesheet" type="text/css" />';
+	html += '</head>';
+	html += '<body onload="parent.mcWindows.onLoad(\'' + name + '\');">';
+
+	html += '<div id="' + id + '_container" class="mceWindow">';
+	html += '<div id="' + id + '_head" class="mceWindowHead" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
+	html += '  <div id="' + id + '_title" class="mceWindowTitle"';
+	html += '  onselectstart="return false;" unselectable="on" style="-moz-user-select: none !important;">No name window</div>';
+	html += '    <div class="mceWindowHeadTools">';
+	html += '      <a href="javascript:parent.mcWindows.windows[\'' + name + '\'].close();" onmousedown="return false;" class="mceWindowClose"><img border="0" src="../jscripts/tiny_mce/themes/advanced/images/window_close.gif" /></a>';
+//	html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].maximize();" onmousedown="return false;" class="mceWindowMaximize"></a>';
+//	html += '      <a href="javascript:mcWindows.windows[\'' + name + '\'].minimize();" onmousedown="return false;" class="mceWindowMinimize"></a>';
+	html += '    </div>';
+	html += '</div><div id="' + id + '_body" class="mceWindowBody" style="width: ' + width + 'px; height: ' + height + 'px;">';
+	html += '<iframe id="' + id + '_iframe" name="' + id + '_iframe" onfocus="parent.mcWindows.windows[\'' + name + '\'].focus();" frameborder="0" width="' + iframeWidth + '" height="' + iframeHeight + '" src="' + url + '" class="mceWindowBodyIframe"></iframe></div>';
+	html += '<div id="' + id + '_statusbar" class="mceWindowStatusbar" onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();">';
+	html += '<div id="' + id + '_resize" class="mceWindowResize"><img onmousedown="parent.mcWindows.windows[\'' + name + '\'].focus();" border="0" src="../jscripts/tiny_mce/themes/advanced/images/window_resize.gif" /></div>';
+	html += '</div>';
+	html += '</div>';
+
+	html += '</body>';
+	html += '</html>';
+
+	// Create iframe
+	this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html);
+};
+
+// Gets called when wrapper iframe is initialized
+MCWindows.prototype.onLoad = function(name) {
+	var win = mcWindows.windows[name];
+	var id = "mcWindow_" + name;
+	var wrapperIframe = window.frames[id + "_iframe"].frames[0];
+	var wrapperDoc = window.frames[id + "_iframe"].document;
+	var doc = window.frames[id + "_iframe"].document;
+	var winDiv = document.getElementById("mcWindow_" + name + "_div");
+	var realIframe = window.frames[id + "_iframe"].frames[0];
+
+	// Set window data
+	win.id = "mcWindow_" + name + "_iframe";
+	win.winElement = winDiv;
+	win.bodyElement = doc.getElementById(id + '_body');
+	win.iframeElement = doc.getElementById(id + '_iframe');
+	win.headElement = doc.getElementById(id + '_head');
+	win.titleElement = doc.getElementById(id + '_title');
+	win.resizeElement = doc.getElementById(id + '_resize');
+	win.containerElement = doc.getElementById(id + '_container');
+	win.left = win.features['left'];
+	win.top = win.features['top'];
+	win.frame = window.frames[id + '_iframe'].frames[0];
+	win.wrapperFrame = window.frames[id + '_iframe'];
+	win.wrapperIFrameElement = document.getElementById(id + "_iframe");
+
+	// Add event handlers
+	mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher);
+	mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher);
+
+	if (mcWindows.isMSIE) {
+		mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher);
+	} else {
+		mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher);
+		mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher);
+	}
+
+	for (var i=0; i<window.frames.length; i++) {
+		if (!window.frames[i]._hasMouseHandlers) {
+			if (mcWindows.isMSIE) {
+				mcWindows.addEvent(window.frames[i].document, "mousemove", mcWindows.eventDispatcher);
+				mcWindows.addEvent(window.frames[i].document, "mouseup", mcWindows.eventDispatcher);
+			} else {
+				mcWindows.addEvent(window.frames[i], "mousemove", mcWindows.eventDispatcher);
+				mcWindows.addEvent(window.frames[i], "mouseup", mcWindows.eventDispatcher);
+			}
+
+			window.frames[i]._hasMouseHandlers = true;
+		}
+	}
+
+	if (mcWindows.isMSIE) {
+		mcWindows.addEvent(win.frame.document, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame.document, "mouseup", mcWindows.eventDispatcher);
+	} else {
+		mcWindows.addEvent(win.frame, "mousemove", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame, "mouseup", mcWindows.eventDispatcher);
+		mcWindows.addEvent(win.frame, "focus", mcWindows.eventDispatcher);
+	}
+
+	this.selectedWindow = win;
+};
+
+MCWindows.prototype.createFloatingIFrame = function(id_prefix, left, top, width, height, html) {
+	var iframe = document.createElement("iframe");
+	var div = document.createElement("div");
+
+	width = parseInt(width);
+	height = parseInt(height)+1;
+
+	// Create wrapper div
+	div.setAttribute("id", id_prefix + "_div");
+	div.setAttribute("width", width);
+	div.setAttribute("height", (height));
+	div.style.position = "absolute";
+	div.style.left = left + "px";
+	div.style.top = top + "px";
+	div.style.width = width + "px";
+	div.style.height = (height) + "px";
+	div.style.backgroundColor = "white";
+	div.style.display = "none";
+
+	if (this.isGecko) {
+		iframeWidth = width + 2;
+		iframeHeight = height + 2;
+	} else {
+		iframeWidth = width;
+		iframeHeight = height + 1;
+	}
+
+	// Create iframe
+	iframe.setAttribute("id", id_prefix + "_iframe");
+	iframe.setAttribute("name", id_prefix + "_iframe");
+	iframe.setAttribute("border", "0");
+	iframe.setAttribute("frameBorder", "0");
+	iframe.setAttribute("marginWidth", "0");
+	iframe.setAttribute("marginHeight", "0");
+	iframe.setAttribute("leftMargin", "0");
+	iframe.setAttribute("topMargin", "0");
+	iframe.setAttribute("width", iframeWidth);
+	iframe.setAttribute("height", iframeHeight);
+//	iframe.setAttribute("src", "../jscripts/tiny_mce/blank.htm");
+	// iframe.setAttribute("allowtransparency", "false");
+	iframe.setAttribute("scrolling", "no");
+	iframe.style.width = iframeWidth + "px";
+	iframe.style.height = iframeHeight + "px";
+	iframe.style.backgroundColor = "white";
+	div.appendChild(iframe);
+
+	document.body.appendChild(div);
+
+	// Fixed MSIE 5.0 issue
+	div.innerHTML = div.innerHTML;
+
+	if (this.isSafari) {
+		// Give Safari some time to setup
+		window.setTimeout(function() {
+			doc = window.frames[id_prefix + '_iframe'].document;
+			doc.open();
+			doc.write(html);
+			doc.close();
+		}, 10);
+	} else {
+		doc = window.frames[id_prefix + '_iframe'].window.document
+		doc.open();
+		doc.write(html);
+		doc.close();
+	}
+
+	div.style.display = "block";
+
+	return div;
+};
+
+// Window instance
+function MCWindow() {
+};
+
+MCWindow.prototype.focus = function() {
+	this.winElement.style.zIndex = mcWindows.zindex++;
+	mcWindows.selectedWindow = this;
+};
+
+MCWindow.prototype.minimize = function() {
+};
+
+MCWindow.prototype.maximize = function() {
+	
+};
+
+MCWindow.prototype.startResize = function() {
+	mcWindows.action = "resize";
+};
+
+MCWindow.prototype.startMove = function(e) {
+	mcWindows.action = "move";
+};
+
+MCWindow.prototype.close = function() {
+	document.body.removeChild(this.winElement);
+	mcWindows.windows[this.name] = null;
+};
+
+MCWindow.prototype.onMouseMove = function(e) {
+	var scrollX = 0;//this.doc.body.scrollLeft;
+	var scrollY = 0;//this.doc.body.scrollTop;
+
+	// Calculate real X, Y
+	var dx = e.screenX - mcWindows.mouseDownScreenX;
+	var dy = e.screenY - mcWindows.mouseDownScreenY;
+
+	switch (mcWindows.action) {
+		case "resize":
+			width = mcWindows.mouseDownWidth + (e.screenX - mcWindows.mouseDownScreenX);
+			height = mcWindows.mouseDownHeight + (e.screenY - mcWindows.mouseDownScreenY);
+
+			width = width < 100 ? 100 : width;
+			height = height < 100 ? 100 : height;
+
+			this.wrapperIFrameElement.style.width = width+2;
+			this.wrapperIFrameElement.style.height = height+2;
+			this.wrapperIFrameElement.width = width+2;
+			this.wrapperIFrameElement.height = height+2;
+			this.winElement.style.width = width;
+			this.winElement.style.height = height;
+
+			height = height-12-19;
+
+			this.containerElement.style.width = width;
+
+			this.iframeElement.style.width = width;
+			this.iframeElement.style.height = height;
+			this.bodyElement.style.width = width;
+			this.bodyElement.style.height = height;
+			this.headElement.style.width = width;
+			//this.statusElement.style.width = width;
+
+			mcWindows.cancelEvent(e);
+			break;
+
+		case "move":
+			this.left = mcWindows.mouseDownLayerX + (e.screenX - mcWindows.mouseDownScreenX);
+			this.top = mcWindows.mouseDownLayerY + (e.screenY - mcWindows.mouseDownScreenY);
+			this.winElement.style.left = this.left + "px";
+			this.winElement.style.top = this.top + "px";
+
+			mcWindows.cancelEvent(e);
+			break;
+	}
+};
+
+MCWindow.prototype.onMouseUp = function(e) {
+	mcWindows.action = "none";
+};
+
+MCWindow.prototype.onFocus = function(e) {
+	// Gecko only handler
+	var winRef = e.currentTarget;
+
+	for (var n in mcWindows.windows) {
+		var win = mcWindows.windows[n];
+		if (typeof(win) == 'function')
+			continue;
+
+		if (winRef.name == win.id) {
+			win.focus();
+			return;
+		}
+	}
+};
+
+MCWindow.prototype.onMouseDown = function(e) {
+	var elm = mcWindows.isMSIE ? this.wrapperFrame.event.srcElement : e.target;
+
+	var scrollX = 0;//this.doc.body.scrollLeft;
+	var scrollY = 0;//this.doc.body.scrollTop;
+
+	mcWindows.mouseDownScreenX = e.screenX;
+	mcWindows.mouseDownScreenY = e.screenY;
+	mcWindows.mouseDownLayerX = this.left;
+	mcWindows.mouseDownLayerY = this.top;
+	mcWindows.mouseDownWidth = parseInt(this.winElement.style.width);
+	mcWindows.mouseDownHeight = parseInt(this.winElement.style.height);
+
+	if (elm == this.resizeElement.firstChild)
+		this.startResize(e);
+	else
+		this.startMove(e);
+
+	mcWindows.cancelEvent(e);
+};
+
+// Global instance
+var mcWindows = new MCWindows();
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/blank.htm 2.2.2/wp-includes/js/tinymce/plugins/paste/blank.htm
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/blank.htm	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/blank.htm	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,19 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>blank_page</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+	<script language="javascript">
+		function init() {
+			document.body.contentEditable = true;
+			document.designMode = 'on';
+			parent.initIframe(document);
+			window.focus();
+		}
+	</script>
+	<link href="css/blank.css" rel="stylesheet" type="text/css" />
+	<base target="_self" />
+</head>
+<body onload="init();">
+
+</body>
+</html>
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/css/blank.css 2.2.2/wp-includes/js/tinymce/plugins/paste/css/blank.css
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/css/blank.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/css/blank.css	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,13 @@
+body {
+	background-color: #FFFFFF;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 10px;
+	scrollbar-3dlight-color: #F0F0EE;
+	scrollbar-arrow-color: #676662;
+	scrollbar-base-color: #F0F0EE;
+	scrollbar-darkshadow-color: #DDDDDD;
+	scrollbar-face-color: #E0E0DD;
+	scrollbar-highlight-color: #F0F0EE;
+	scrollbar-shadow-color: #F0F0EE;
+	scrollbar-track-color: #F5F5F5;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/css/pasteword.css 2.2.2/wp-includes/js/tinymce/plugins/paste/css/pasteword.css
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/css/pasteword.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/css/pasteword.css	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,3 @@
+.sourceIframe {
+	border: 1px solid #808080;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/paste/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/editor_plugin.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/editor_plugin.js	2007-04-12 12:04:03.000000000 -0500
@@ -0,0 +1,395 @@
+/**
+ * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+/* Import plugin specific language pack */ 
+tinyMCE.importPluginLanguagePack('paste');
+
+var TinyMCE_PastePlugin = {
+	getInfo : function() {
+		return {
+			longname : 'Paste text/word',
+			author : 'Moxiecode Systems AB',
+			authorurl : 'http://tinymce.moxiecode.com',
+			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',
+			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
+		};
+	},
+
+	initInstance : function(inst) {
+		if (tinyMCE.isMSIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false))
+			tinyMCE.addEvent(inst.getBody(), "paste", TinyMCE_PastePlugin._handlePasteEvent);
+	},
+
+	handleEvent : function(e) {
+		// Force paste dialog if non IE browser
+		if (!tinyMCE.isRealIE && tinyMCE.getParam("paste_auto_cleanup_on_paste", false) && e.ctrlKey && e.keyCode == 86 && e.type == "keydown") {
+			window.setTimeout('tinyMCE.selectedInstance.execCommand("mcePasteText",true)', 1);
+			return tinyMCE.cancelEvent(e);
+		}
+
+		return true;
+	},
+
+	getControlHTML : function(cn) { 
+		switch (cn) { 
+			case "pastetext":
+				return tinyMCE.getButtonHTML(cn, 'lang_paste_text_desc', '{$pluginurl}/images/pastetext.gif', 'mcePasteText', true);
+
+			case "pasteword":
+				return tinyMCE.getButtonHTML(cn, 'lang_paste_word_desc', '{$pluginurl}/images/pasteword.gif', 'mcePasteWord', true);
+
+			case "selectall":
+				return tinyMCE.getButtonHTML(cn, 'lang_selectall_desc', '{$pluginurl}/images/selectall.gif', 'mceSelectAll', true);
+		} 
+
+		return ''; 
+	},
+
+	execCommand : function(editor_id, element, command, user_interface, value) { 
+		switch (command) { 
+			case "mcePasteText": 
+				if (user_interface) {
+					if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false))
+						TinyMCE_PastePlugin._insertText(clipboardData.getData("Text"), true); 
+					else { 
+						var template = new Array(); 
+						template['file']	= '../../plugins/paste/pastetext.htm'; // Relative to theme 
+						template['width']  = 450; 
+						template['height'] = 400; 
+						var plain_text = ""; 
+						tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'}); 
+					}
+				} else
+					TinyMCE_PastePlugin._insertText(value['html'], value['linebreaks']);
+
+				return true;
+
+			case "mcePasteWord": 
+				if (user_interface) {
+					if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && !tinyMCE.getParam('paste_use_dialog', false)) {
+						TinyMCE_PastePlugin._insertWordContent(TinyMCE_PastePlugin._clipboardHTML());
+					} else { 
+						var template = new Array(); 
+						template['file']	= '../../plugins/paste/pasteword.htm'; // Relative to theme 
+						template['width']  = 450; 
+						template['height'] = 400; 
+						var plain_text = ""; 
+						tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", inline : "yes", mceDo : 'insert'});
+					}
+				} else
+					TinyMCE_PastePlugin._insertWordContent(value);
+
+				return true;
+
+			case "mceSelectAll":
+				tinyMCE.execInstanceCommand(editor_id, 'selectall'); 
+				return true; 
+
+		} 
+
+		// Pass to next handler in chain 
+		return false; 
+	},
+
+	// Private plugin internal methods
+
+	_handlePasteEvent : function(e) {
+		switch (e.type) {
+			case "paste":
+				var html = TinyMCE_PastePlugin._clipboardHTML();
+				var r, inst = tinyMCE.selectedInstance;
+
+				// Removes italic, strong etc, the if was needed due to bug #1437114
+				if (inst && (r = inst.getRng()) && r.text.length > 0)
+					tinyMCE.execCommand('delete');
+
+				if (html && html.length > 0)
+					tinyMCE.execCommand('mcePasteWord', false, html);
+
+				tinyMCE.cancelEvent(e);
+				return false;
+		}
+
+		return true;
+	},
+
+	_insertText : function(content, bLinebreaks) { 
+		if (content && content.length > 0) {
+			if (bLinebreaks) { 
+				// Special paragraph treatment 
+				if (tinyMCE.getParam("paste_create_paragraphs", true)) {
+					var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');
+					for (var i=0; i<rl.length; i+=2)
+						content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);
+
+					content = tinyMCE.regexpReplace(content, "\r\n\r\n", "</p><p>", "gi"); 
+					content = tinyMCE.regexpReplace(content, "\r\r", "</p><p>", "gi"); 
+					content = tinyMCE.regexpReplace(content, "\n\n", "</p><p>", "gi"); 
+
+					// Has paragraphs 
+					if ((pos = content.indexOf('</p><p>')) != -1) { 
+						tinyMCE.execCommand("Delete"); 
+
+						var node = tinyMCE.selectedInstance.getFocusElement(); 
+
+						// Get list of elements to break 
+						var breakElms = new Array(); 
+
+						do { 
+							if (node.nodeType == 1) { 
+								// Don't break tables and break at body 
+								if (node.nodeName == "TD" || node.nodeName == "BODY") 
+									break; 
+		
+								breakElms[breakElms.length] = node; 
+							} 
+						} while(node = node.parentNode); 
+
+						var before = "", after = "</p>"; 
+						before += content.substring(0, pos); 
+
+						for (var i=0; i<breakElms.length; i++) { 
+							before += "</" + breakElms[i].nodeName + ">"; 
+							after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; 
+						} 
+
+						before += "<p>"; 
+						content = before + content.substring(pos+7) + after; 
+					} 
+				} 
+
+				if (tinyMCE.getParam("paste_create_linebreaks", true)) {
+					content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi"); 
+					content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi"); 
+					content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi"); 
+				}
+			} 
+		
+			tinyMCE.execCommand("mceInsertRawHTML", false, content); 
+		}
+	},
+
+	_insertWordContent : function(content) { 
+		if (content && content.length > 0) {
+			// Cleanup Word content
+			var bull = String.fromCharCode(8226);
+			var middot = String.fromCharCode(183);
+			var cb;
+
+			if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "")
+				content = eval(cb + "('before', content)");
+
+			var rl = tinyMCE.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');
+			for (var i=0; i<rl.length; i+=2)
+				content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);
+
+			if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) {
+				content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>');
+			}
+
+			content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--");
+			content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>");
+			content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list
+			content = content.replace(/<o:p><\/o:p>/gi, "");
+			content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks
+			content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), "");  // Word comments
+
+			if (tinyMCE.getParam("paste_remove_spans", true))
+				content = content.replace(/<\/?span[^>]*>/gi, "");
+
+			if (tinyMCE.getParam("paste_remove_styles", true))
+				content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3");
+
+			content = content.replace(/<\/?font[^>]*>/gi, "");
+
+			// Strips class attributes.
+			switch (tinyMCE.getParam("paste_strip_class_attributes", "all")) {
+				case "all":
+					content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");
+					break;
+
+				case "mso":
+					content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3");
+					break;
+			}
+
+			content = content.replace(new RegExp('href="?' + TinyMCE_PastePlugin._reEscape("" + document.location) + '', 'gi'), 'href="' + tinyMCE.settings['document_base_url']);
+			content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");
+			content = content.replace(/<\\?\?xml[^>]*>/gi, "");
+			content = content.replace(/<\/?\w+:[^>]*>/gi, "");
+			content = content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi, ""); // Remove pagebreaks
+			content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks
+
+	//		content = content.replace(/\/?&nbsp;*/gi, ""); &nbsp;
+	//		content = content.replace(/<p>&nbsp;<\/p>/gi, '');
+
+			if (!tinyMCE.settings['force_p_newlines']) {
+				content = content.replace('', '' ,'gi');
+				content = content.replace('</p>', '<br /><br />' ,'gi');
+			}
+
+			if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) {
+				content = content.replace(/<\/?p[^>]*>/gi, "");
+			}
+
+			content = content.replace(/<\/?div[^>]*>/gi, "");
+
+			// Convert all middlot lists to UL lists
+			if (tinyMCE.getParam("paste_convert_middot_lists", true)) {
+				var div = document.createElement("div");
+				div.innerHTML = content;
+
+				// Convert all middot paragraphs to li elements
+				var className = tinyMCE.getParam("paste_unindented_list_class", "unIndentedList");
+
+				while (TinyMCE_PastePlugin._convertMiddots(div, "--list--")) ; // bull
+				while (TinyMCE_PastePlugin._convertMiddots(div, middot, className)) ; // Middot
+				while (TinyMCE_PastePlugin._convertMiddots(div, bull)) ; // bull
+
+				content = div.innerHTML;
+			}
+
+			// Replace all headers with strong and fix some other issues
+			if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) {
+				content = content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</p>');
+				content = content.replace(/<h[1-6]>/gi, '<p><b>');
+				content = content.replace(/<\/h[1-6]>/gi, '</b></p>');
+				content = content.replace(/<b>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');
+				content = content.replace(/^(&nbsp;)*/gi, '');
+			}
+
+			content = content.replace(/--list--/gi, ""); // Remove --list--
+
+			if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "")
+				content = eval(cb + "('after', content)");
+
+			// Insert cleaned content
+			tinyMCE.execCommand("mceInsertContent", false, content);
+
+			if (tinyMCE.getParam('paste_force_cleanup_wordpaste', true))
+				window.setTimeout('tinyMCE.execCommand("mceCleanup");', 1); // Do normal cleanup detached from this thread
+		}
+	},
+
+	_reEscape : function(s) {
+		var l = "?.\\*[](){}+^$:";
+		var o = "";
+
+		for (var i=0; i<s.length; i++) {
+			var c = s.charAt(i);
+
+			if (l.indexOf(c) != -1)
+				o += '\\' + c;
+			else
+				o += c;
+		}
+
+		return o;
+	},
+
+	_convertMiddots : function(div, search, class_name) {
+		var mdot = String.fromCharCode(183);
+		var bull = String.fromCharCode(8226);
+
+		var nodes = div.getElementsByTagName("p");
+		var prevul;
+		for (var i=0; i<nodes.length; i++) {
+			var p = nodes[i];
+
+			// Is middot
+			if (p.innerHTML.indexOf(search) == 0) {
+				var ul = document.createElement("ul");
+
+				if (class_name)
+					ul.className = class_name;
+
+				// Add the first one
+				var li = document.createElement("li");
+				li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), '');
+				ul.appendChild(li);
+
+				// Add the rest
+				var np = p.nextSibling;
+				while (np) {
+			        // If the node is whitespace, then
+			        // ignore it and continue on.
+			        if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) {
+			                np = np.nextSibling;
+			                continue;
+			        }
+
+					if (search == mdot) {
+					        if (np.nodeType == 1 && new RegExp('^o(\\s+|&nbsp;)').test(np.innerHTML)) {
+					                // Second level of nesting
+					                if (!prevul) {
+					                        prevul = ul;
+					                        ul = document.createElement("ul");
+					                        prevul.appendChild(ul);
+					                }
+					                np.innerHTML = np.innerHTML.replace(/^o/, '');
+					        } else {
+					                // Pop the stack if we're going back up to the first level
+					                if (prevul) {
+					                        ul = prevul;
+					                        prevul = null;
+					                }
+					                // Not element or middot paragraph
+					                if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
+					                        break;
+					        }
+					} else {
+					        // Not element or middot paragraph
+					        if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)
+					                break;
+				        }
+
+					var cp = np.nextSibling;
+					var li = document.createElement("li");
+					li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), '');
+					np.parentNode.removeChild(np);
+					ul.appendChild(li);
+					np = cp;
+				}
+
+				p.parentNode.replaceChild(ul, p);
+
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	_clipboardHTML : function() {
+		var div = document.getElementById('_TinyMCE_clipboardHTML');
+
+		if (!div) {
+			var div = document.createElement('DIV');
+			div.id = '_TinyMCE_clipboardHTML';
+
+			with (div.style) {
+				visibility = 'hidden';
+				overflow = 'hidden';
+				position = 'absolute';
+				width = 1;
+				height = 1;
+			}
+
+			document.body.appendChild(div);
+		}
+
+		div.innerHTML = '';
+		var rng = document.body.createTextRange();
+		rng.moveToElementText(div);
+		rng.execCommand('Paste');
+		var html = div.innerHTML;
+		div.innerHTML = '';
+		return html;
+	}
+};
+
+tinyMCE.addPlugin("paste", TinyMCE_PastePlugin);
Binary files 2.0.5/wp-includes/js/tinymce/plugins/paste/images/pastetext.gif and 2.2.2/wp-includes/js/tinymce/plugins/paste/images/pastetext.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/plugins/paste/images/pasteword.gif and 2.2.2/wp-includes/js/tinymce/plugins/paste/images/pasteword.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/plugins/paste/images/selectall.gif and 2.2.2/wp-includes/js/tinymce/plugins/paste/images/selectall.gif differ
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/jscripts/pastetext.js 2.2.2/wp-includes/js/tinymce/plugins/paste/jscripts/pastetext.js
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/jscripts/pastetext.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/jscripts/pastetext.js	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,38 @@
+function saveContent() {
+	if (document.forms[0].htmlSource.value == '') {
+		tinyMCEPopup.close();
+		return false;
+	}
+
+	tinyMCEPopup.execCommand('mcePasteText', false, {
+		html : document.forms[0].htmlSource.value,
+		linebreaks : document.forms[0].linebreaks.checked
+	});
+
+	tinyMCEPopup.close();
+}
+
+function onLoadInit() {
+	tinyMCEPopup.resizeToInnerSize();
+
+	// Remove Gecko spellchecking
+	if (tinyMCE.isGecko)
+		document.body.spellcheck = tinyMCE.getParam("gecko_spellcheck");
+
+	resizeInputs();
+}
+
+var wHeight=0, wWidth=0, owHeight=0, owWidth=0;
+
+function resizeInputs() {
+	if (!tinyMCE.isMSIE) {
+		wHeight = self.innerHeight-80;
+		wWidth = self.innerWidth-17;
+	} else {
+		wHeight = document.body.clientHeight-80;
+		wWidth = document.body.clientWidth-17;
+	}
+
+	document.forms[0].htmlSource.style.height = Math.abs(wHeight) + 'px';
+	document.forms[0].htmlSource.style.width  = Math.abs(wWidth) + 'px';
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/jscripts/pasteword.js 2.2.2/wp-includes/js/tinymce/plugins/paste/jscripts/pasteword.js
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/jscripts/pasteword.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/jscripts/pasteword.js	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,52 @@
+function saveContent() {
+	var html = document.getElementById("frmData").contentWindow.document.body.innerHTML;
+
+	if (html == ''){
+		tinyMCEPopup.close();
+		return false;
+	}
+
+	tinyMCEPopup.execCommand('mcePasteWord', false, html);
+	tinyMCEPopup.close();
+}
+
+function onLoadInit() {
+	tinyMCEPopup.resizeToInnerSize();
+
+	// Fix for endless reloading in FF
+	window.setTimeout('createIFrame();', 10);
+}
+
+function createIFrame() {
+	document.getElementById('iframecontainer').innerHTML = '<iframe id="frmData" name="frmData" class="sourceIframe" src="blank.htm" height="280" width="400" frameborder="0" style="background-color:#FFFFFF; width:100%;" dir="ltr" wrap="soft"></iframe>';
+}
+
+var wHeight=0, wWidth=0, owHeight=0, owWidth=0;
+
+function initIframe(doc) {
+	var dir = tinyMCE.selectedInstance.settings['directionality'];
+
+	doc.body.dir = dir;
+
+	// Remove Gecko spellchecking
+	if (tinyMCE.isGecko)
+		doc.body.spellcheck = tinyMCE.getParam("gecko_spellcheck");
+
+	resizeInputs();
+}
+
+function resizeInputs() {
+	if (!tinyMCE.isMSIE) {
+		wHeight = self.innerHeight - 80;
+		wWidth = self.innerWidth - 18;
+	} else {
+		wHeight = document.body.clientHeight - 80;
+		wWidth = document.body.clientWidth - 18;
+	}
+
+	var elm = document.getElementById('frmData');
+	if (elm) {
+		elm.style.height = Math.abs(wHeight) + 'px';
+		elm.style.width  = Math.abs(wWidth) + 'px';
+	}
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/paste/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/langs/en.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/langs/en.js	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,10 @@
+// UK lang variables
+
+tinyMCE.addToLang('',{
+paste_text_desc : 'Paste as Plain Text',
+paste_text_title : 'Use CTRL+V on your keyboard to paste the text into the window.',
+paste_text_linebreaks : 'Keep linebreaks',
+paste_word_desc : 'Paste from Word',
+paste_word_title : 'Use CTRL+V on your keyboard to paste the text into the window.',
+selectall_desc : 'Select All'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/pastetext.htm 2.2.2/wp-includes/js/tinymce/plugins/paste/pastetext.htm
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/pastetext.htm	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/pastetext.htm	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,34 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>{$lang_paste_text_desc}</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
+	<script language="javascript" type="text/javascript" src="jscripts/pastetext.js"></script>
+	<base target="_self" />
+</head>
+<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">
+<form name="source" onsubmit="saveContent();">
+	<div style="float: left" class="title">{$lang_paste_text_desc}</div>
+
+	<div style="float: right">
+		<input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{$lang_paste_text_linebreaks}</label>
+	</div>
+
+	<br style="clear: both" />
+
+	<div>{$lang_paste_text_title}</div>
+
+	<textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft"></textarea>
+
+	<div class="mceActionPanel">
+		<div style="float: left">
+			<input type="button" name="insert" value="{$lang_insert}" onclick="saveContent();" id="insert" />
+		</div>
+
+		<div style="float: right">
+			<input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
+		</div>
+	</div>
+</form>
+</body> 
+</html>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/paste/pasteword.htm 2.2.2/wp-includes/js/tinymce/plugins/paste/pasteword.htm
--- 2.0.5/wp-includes/js/tinymce/plugins/paste/pasteword.htm	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/paste/pasteword.htm	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,29 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<title>{$lang_paste_word_desc}</title>
+	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
+	<script language="javascript" type="text/javascript" src="jscripts/pasteword.js"></script>
+	<link href="css/pasteword.css" rel="stylesheet" type="text/css" />
+	<base target="_self" />
+</head>
+<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');" onresize="resizeInputs();" style="display: none">
+	<form name="source" onsubmit="saveContent();" action="#">
+		<div class="title">{$lang_paste_word_desc}</div>
+
+		<div>{$lang_paste_word_title}</div>
+
+		<div id="iframecontainer"></div>
+
+		<div class="mceActionPanel">
+			<div style="float: left">
+				<input type="button" id="insert" name="insert" value="{$lang_insert}" onclick="saveContent();" />
+			</div>
+
+			<div style="float: right">
+				<input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
+			</div>
+		</div>
+	</form>
+</body>
+</html>
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,339 @@
+<?php
+
+/* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
+   Manual: http://scripts.incutio.com/httpclient/
+*/
+
+class HttpClient {
+    // Request vars
+    var $host;
+    var $port;
+    var $path;
+    var $method;
+    var $postdata = '';
+    var $cookies = array();
+    var $referer;
+    var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
+    var $accept_encoding = 'gzip';
+    var $accept_language = 'en-us';
+    var $user_agent = 'Incutio HttpClient v0.9';
+    // Options
+    var $timeout = 20;
+    var $use_gzip = true;
+    var $persist_cookies = true;  // If true, received cookies are placed in the $this->cookies array ready for the next request
+                                  // Note: This currently ignores the cookie path (and time) completely. Time is not important, 
+                                  //       but path could possibly lead to security problems.
+    var $persist_referers = true; // For each request, sends path of last request as referer
+    var $debug = false;
+    var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
+    var $max_redirects = 5;
+    var $headers_only = false;    // If true, stops receiving once headers have been read.
+    // Basic authorization variables
+    var $username;
+    var $password;
+    // Response vars
+    var $status;
+    var $headers = array();
+    var $content = '';
+    var $errormsg;
+    // Tracker variables
+    var $redirect_count = 0;
+    var $cookie_host = '';
+    function HttpClient($host, $port=80) {
+        $this->host = $host;
+        $this->port = $port;
+    }
+    function get($path, $data = false) {
+        $this->path = $path;
+        $this->method = 'GET';
+        if ($data) {
+            $this->path .= '?'.$this->buildQueryString($data);
+        }
+        return $this->doRequest();
+    }
+    function post($path, $data) {
+        $this->path = $path;
+        $this->method = 'POST';
+        $this->postdata = $this->buildQueryString($data);
+    	return $this->doRequest();
+    }
+    function buildQueryString($data) {
+        $querystring = '';
+        if (is_array($data)) {
+            // Change data in to postable data
+    		foreach ($data as $key => $val) {
+    			if (is_array($val)) {
+    				foreach ($val as $val2) {
+    					$querystring .= urlencode($key).'='.urlencode($val2).'&';
+    				}
+    			} else {
+    				$querystring .= urlencode($key).'='.urlencode($val).'&';
+    			}
+    		}
+    		$querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
+    	} else {
+    	    $querystring = $data;
+    	}
+    	return $querystring;
+    }
+    function doRequest() {
+        // Performs the actual HTTP request, returning true or false depending on outcome
+		if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) {
+		    // Set error message
+            switch($errno) {
+				case -3:
+					$this->errormsg = 'Socket creation failed (-3)';
+				case -4:
+					$this->errormsg = 'DNS lookup failure (-4)';
+				case -5:
+					$this->errormsg = 'Connection refused or timed out (-5)';
+				default:
+					$this->errormsg = 'Connection failed ('.$errno.')';
+			    $this->errormsg .= ' '.$errstr;
+			    $this->debug($this->errormsg);
+			}
+			return false;
+        }
+        socket_set_timeout($fp, $this->timeout);
+        $request = $this->buildRequest();
+        $this->debug('Request', $request);
+        fwrite($fp, $request);
+    	// Reset all the variables that should not persist between requests
+    	$this->headers = array();
+    	$this->content = '';
+    	$this->errormsg = '';
+    	// Set a couple of flags
+    	$inHeaders = true;
+    	$atStart = true;
+    	// Now start reading back the response
+    	while (!feof($fp)) {
+    	    $line = fgets($fp, 4096);
+    	    if ($atStart) {
+    	        // Deal with first line of returned data
+    	        $atStart = false;
+    	        if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
+    	            $this->errormsg = "Status code line invalid: ".htmlentities($line);
+    	            $this->debug($this->errormsg);
+    	            return false;
+    	        }
+    	        $http_version = $m[1]; // not used
+    	        $this->status = $m[2];
+    	        $status_string = $m[3]; // not used
+    	        $this->debug(trim($line));
+    	        continue;
+    	    }
+    	    if ($inHeaders) {
+    	        if (trim($line) == '') {
+    	            $inHeaders = false;
+    	            $this->debug('Received Headers', $this->headers);
+    	            if ($this->headers_only) {
+    	                break; // Skip the rest of the input
+    	            }
+    	            continue;
+    	        }
+    	        if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
+    	            // Skip to the next header
+    	            continue;
+    	        }
+    	        $key = strtolower(trim($m[1]));
+    	        $val = trim($m[2]);
+    	        // Deal with the possibility of multiple headers of same name
+    	        if (isset($this->headers[$key])) {
+    	            if (is_array($this->headers[$key])) {
+    	                $this->headers[$key][] = $val;
+    	            } else {
+    	                $this->headers[$key] = array($this->headers[$key], $val);
+    	            }
+    	        } else {
+    	            $this->headers[$key] = $val;
+    	        }
+    	        continue;
+    	    }
+    	    // We're not in the headers, so append the line to the contents
+    	    $this->content .= $line;
+        }
+        fclose($fp);
+        // If data is compressed, uncompress it
+        if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
+            $this->debug('Content is gzip encoded, unzipping it');
+            $this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
+            $this->content = gzinflate($this->content);
+        }
+        // If $persist_cookies, deal with any cookies
+        if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
+            $cookies = $this->headers['set-cookie'];
+            if (!is_array($cookies)) {
+                $cookies = array($cookies);
+            }
+            foreach ($cookies as $cookie) {
+                if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
+                    $this->cookies[$m[1]] = $m[2];
+                }
+            }
+            // Record domain of cookies for security reasons
+            $this->cookie_host = $this->host;
+        }
+        // If $persist_referers, set the referer ready for the next request
+        if ($this->persist_referers) {
+            $this->debug('Persisting referer: '.$this->getRequestURL());
+            $this->referer = $this->getRequestURL();
+        }
+        // Finally, if handle_redirects and a redirect is sent, do that
+        if ($this->handle_redirects) {
+            if (++$this->redirect_count >= $this->max_redirects) {
+                $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
+                $this->debug($this->errormsg);
+                $this->redirect_count = 0;
+                return false;
+            }
+            $location = isset($this->headers['location']) ? $this->headers['location'] : '';
+            $uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
+            if ($location || $uri) {
+                $url = parse_url($location.$uri);
+                // This will FAIL if redirect is to a different site
+                return $this->get($url['path']);
+            }
+        }
+        return true;
+    }
+    function buildRequest() {
+        $headers = array();
+        $headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
+        $headers[] = "Host: {$this->host}";
+        $headers[] = "User-Agent: {$this->user_agent}";
+        $headers[] = "Accept: {$this->accept}";
+        if ($this->use_gzip) {
+            $headers[] = "Accept-encoding: {$this->accept_encoding}";
+        }
+        $headers[] = "Accept-language: {$this->accept_language}";
+        if ($this->referer) {
+            $headers[] = "Referer: {$this->referer}";
+        }
+    	// Cookies
+    	if ($this->cookies) {
+    	    $cookie = 'Cookie: ';
+    	    foreach ($this->cookies as $key => $value) {
+    	        $cookie .= "$key=$value; ";
+    	    }
+    	    $headers[] = $cookie;
+    	}
+    	// Basic authentication
+    	if ($this->username && $this->password) {
+    	    $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
+    	}
+    	// If this is a POST, set the content type and length
+    	if ($this->postdata) {
+    	    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
+    	    $headers[] = 'Content-Length: '.strlen($this->postdata);
+    	}
+    	$request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
+    	return $request;
+    }
+    function getStatus() {
+        return $this->status;
+    }
+    function getContent() {
+        return $this->content;
+    }
+    function getHeaders() {
+        return $this->headers;
+    }
+    function getHeader($header) {
+        $header = strtolower($header);
+        if (isset($this->headers[$header])) {
+            return $this->headers[$header];
+        } else {
+            return false;
+        }
+    }
+    function getError() {
+        return $this->errormsg;
+    }
+    function getCookies() {
+        return $this->cookies;
+    }
+    function getRequestURL() {
+        $url = 'http://'.$this->host;
+        if ($this->port != 80) {
+            $url .= ':'.$this->port;
+        }            
+        $url .= $this->path;
+        return $url;
+    }
+    // Setter methods
+    function setUserAgent($string) {
+        $this->user_agent = $string;
+    }
+    function setAuthorization($username, $password) {
+        $this->username = $username;
+        $this->password = $password;
+    }
+    function setCookies($array) {
+        $this->cookies = $array;
+    }
+    // Option setting methods
+    function useGzip($boolean) {
+        $this->use_gzip = $boolean;
+    }
+    function setPersistCookies($boolean) {
+        $this->persist_cookies = $boolean;
+    }
+    function setPersistReferers($boolean) {
+        $this->persist_referers = $boolean;
+    }
+    function setHandleRedirects($boolean) {
+        $this->handle_redirects = $boolean;
+    }
+    function setMaxRedirects($num) {
+        $this->max_redirects = $num;
+    }
+    function setHeadersOnly($boolean) {
+        $this->headers_only = $boolean;
+    }
+    function setDebug($boolean) {
+        $this->debug = $boolean;
+    }
+    // "Quick" static methods
+    function quickGet($url) {
+        $bits = parse_url($url);
+        $host = $bits['host'];
+        $port = isset($bits['port']) ? $bits['port'] : 80;
+        $path = isset($bits['path']) ? $bits['path'] : '/';
+        if (isset($bits['query'])) {
+            $path .= '?'.$bits['query'];
+        }
+        $client = new HttpClient($host, $port);
+        if (!$client->get($path)) {
+            return false;
+        } else {
+            return $client->getContent();
+        }
+    }
+    function quickPost($url, $data) {
+        $bits = parse_url($url);
+        $host = $bits['host'];
+        $port = isset($bits['port']) ? $bits['port'] : 80;
+        $path = isset($bits['path']) ? $bits['path'] : '/';
+        $client = new HttpClient($host, $port);
+        if (!$client->post($path, $data)) {
+            return false;
+        } else {
+            return $client->getContent();
+        }
+    }
+    function debug($msg, $object = false) {
+        if ($this->debug) {
+            print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> '.$msg;
+            if ($object) {
+                ob_start();
+        	    print_r($object);
+        	    $content = htmlentities(ob_get_contents());
+        	    ob_end_clean();
+        	    print '<pre>'.$content.'</pre>';
+        	}
+        	print '</div>';
+        }
+    }   
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php	2007-04-08 19:09:42.000000000 -0500
@@ -0,0 +1,126 @@
+<?php
+/* *
+ * Tiny Spelling Interface for TinyMCE Spell Checking.
+ *
+ * Copyright  2006 Moxiecode Systems AB
+ */
+
+class TinyGoogleSpell {
+	var $lang;
+
+	function TinyGoogleSpell(&$config, $lang, $mode, $spelling, $jargon, $encoding) {
+		$this->lang = $lang;
+	}
+
+	// Returns array with bad words or false if failed.
+	function checkWords($word_array) {
+		$words = array();
+		$wordstr = implode(' ', $word_array);
+
+		$matches = $this->_getMatches($wordstr);
+
+		for ($i=0; $i<count($matches); $i++)
+			$words[] = $this->unhtmlentities(mb_substr($wordstr, $matches[$i][1], $matches[$i][2], "UTF-8"));
+
+		return $words;
+	}
+
+	function unhtmlentities($string) {
+		$string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
+		$string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
+
+		$trans_tbl = get_html_translation_table(HTML_ENTITIES);
+		$trans_tbl = array_flip($trans_tbl);
+
+		return strtr($string, $trans_tbl);
+	}
+
+	// Returns array with suggestions or false if failed.
+	function getSuggestion($word) {
+		$sug = array();
+
+		$matches = $this->_getMatches($word);
+
+		if (count($matches) > 0)
+			$sug = explode("\t", utf8_encode($this->unhtmlentities($matches[0][4])));
+
+		return $sug;
+	}
+
+	function _xmlChars($string) {
+	   $trans = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES);
+	
+	   foreach ($trans as $k => $v)
+			$trans[$k] = "&#".ord($k).";";
+
+	   return strtr($string, $trans);
+	}
+
+	function _getMatches($word_list) {
+        $server = "www.google.com";
+        $port = 443;
+        $path = "/tbproxy/spell?lang=" . $this->lang . "&hl=en";
+        $host = "www.google.com";
+        $url = "https://" . $server;
+
+		// Setup XML request
+		$xml = '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' . $word_list . '</text></spellrequest>';
+
+        $header  = "POST ".$path." HTTP/1.0 \r\n";
+        $header .= "MIME-Version: 1.0 \r\n";
+        $header .= "Content-type: application/PTI26 \r\n";
+        $header .= "Content-length: ".strlen($xml)." \r\n";
+        $header .= "Content-transfer-encoding: text \r\n";
+        $header .= "Request-number: 1 \r\n";
+        $header .= "Document-type: Request \r\n";
+        $header .= "Interface-Version: Test 1.4 \r\n";
+        $header .= "Connection: close \r\n\r\n";
+        $header .= $xml;
+		//$this->_debugData($xml);
+
+		// Use curl if it exists
+		if (function_exists('curl_init')) {
+			// Use curl
+			$ch = curl_init();
+			curl_setopt($ch, CURLOPT_URL,$url);
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+			curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $header);
+			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+			$xml = curl_exec($ch);
+			curl_close($ch);
+		} else {
+			// Use raw sockets
+			$fp = fsockopen("ssl://" . $server, $port, $errno, $errstr, 30);
+			if ($fp) {
+				// Send request
+				fwrite($fp, $header);
+
+				// Read response
+				$xml = "";
+				while (!feof($fp))
+					$xml .= fgets($fp, 128);
+
+				fclose($fp);
+			} else 
+				echo "Could not open SSL connection to google.";
+		}
+
+		//$this->_debugData($xml);
+
+		// Grab and parse content
+		preg_match_all('/<c o="([^"]*)" l="([^"]*)" s="([^"]*)">([^<]*)<\/c>/', $xml, $matches, PREG_SET_ORDER);
+
+		return $matches;
+	}
+
+	function _debugData($data) {
+		$fh = @fopen("debug.log", 'a+');
+		@fwrite($fh, $data);
+		@fclose($fh);
+	}
+}
+
+// Setup classname, should be the same as the name of the spellchecker class
+$spellCheckerConfig['class'] = "TinyGoogleSpell";
+
+?>
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php	2007-01-16 11:52:13.000000000 -0600
@@ -0,0 +1,64 @@
+<?php
+/* * 
+ * Tiny Spelling Interface for TinyMCE Spell Checking.
+ *
+ * Copyright  2006 Moxiecode Systems AB
+ *
+ */
+
+class TinyPSpell {
+	var $lang;
+	var $mode;
+	var $string;
+	var $plink;
+	var $errorMsg;
+
+	var $jargon;
+	var $spelling;
+	var $encoding;
+
+	function TinyPSpell(&$config, $lang, $mode, $spelling, $jargon, $encoding) {
+		$this->lang = $lang;
+		$this->mode = $mode;
+		$this->plink = false;
+		$this->errorMsg = array();
+
+		if (!function_exists("pspell_new")) {
+			$this->errorMsg[] = "PSpell not found.";
+			return;
+		}
+
+		$this->plink = pspell_new($this->lang, $this->spelling, $this->jargon, $this->encoding, $this->mode);
+	}
+
+	// Returns array with bad words or false if failed.
+	function checkWords($wordArray) {
+		if (!$this->plink) {
+			$this->errorMsg[] = "No PSpell link found for checkWords.";
+			return array();
+		}
+
+		$wordError = array();
+		foreach($wordArray as $word) {
+			if(!pspell_check($this->plink, trim($word)))
+				$wordError[] = $word;
+		}
+
+		return $wordError;
+	}
+
+	// Returns array with suggestions or false if failed.
+	function getSuggestion($word) {
+		if (!$this->plink) {
+			$this->errorMsg[] = "No PSpell link found for getSuggestion.";
+			return array();
+		}
+
+		return pspell_suggest($this->plink, $word);
+	}
+}
+
+// Setup classname, should be the same as the name of the spellchecker class
+$spellCheckerConfig['class'] = "TinyPspell";
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,121 @@
+<?php
+/* * 
+ * Tiny Spelling Interface for TinyMCE Spell Checking.
+ *
+ * Copyright  2006 Moxiecode Systems AB
+ *
+ */
+
+
+class TinyPspellShell {
+	var $lang;
+	var $mode;
+	var $string;
+	var $error;
+	var $errorMsg;
+
+	var $cmd;
+	var $tmpfile;
+
+	var $jargon;
+	var $spelling;
+	var $encoding;
+
+	function TinyPspellShell(&$config, $lang, $mode, $spelling, $jargon, $encoding) {
+		$this->lang = $lang;
+		$this->mode = $mode;
+		$this->error = false;
+		$this->errorMsg = array();
+
+		$this->tmpfile = tempnam($config['tinypspellshell.tmp'], "tinyspell");
+
+		if(preg_match("#win#i",php_uname()))
+            $this->cmd = $config['tinypspellshell.aspell'] . " -a --lang=". $this->lang." --encoding=utf-8 -H < $this->tmpfile 2>&1";
+        else
+            $this->cmd = "cat ". $this->tmpfile ." | " . $config['tinypspellshell.aspell'] . " -a --encoding=utf-8 -H --lang=". $this->lang;
+	}
+
+	// Returns array with bad words or false if failed.
+	function checkWords($wordArray) {
+		if ($fh = fopen($this->tmpfile, "w")) {
+			fwrite($fh, "!\n");
+			foreach($wordArray as $key => $value)
+				fwrite($fh, "^" . $value . "\n");
+			fclose($fh);
+		} else {
+			$this->errorMsg[] = "PSpell not found.";
+			return array();
+		}
+
+		$data = shell_exec($this->cmd);
+        @unlink($this->tmpfile);
+		
+		$returnData = array();
+		$dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY);
+
+		foreach($dataArr as $dstr) {
+			$matches = array();
+
+			// Skip this line.
+			if (strpos($dstr, "@") === 0)
+				continue;
+
+			preg_match("/\& (.*) .* .*: .*/i", $dstr, $matches);
+
+			if (!empty($matches[1]))
+				$returnData[] = $matches[1];
+		}
+
+		return $returnData;
+	}
+
+	// Returns array with suggestions or false if failed.
+	function getSuggestion($word) {
+        if (function_exists("mb_convert_encoding"))
+            $word = mb_convert_encoding($word, "ISO-8859-1", mb_detect_encoding($word, "UTF-8"));
+        else
+            $word = utf8_encode($word);
+
+		if ($fh = fopen($this->tmpfile, "w")) {
+			fwrite($fh, "!\n");
+			fwrite($fh, "^$word\n");
+			fclose($fh);
+		} else
+			die("Error opening tmp file.");
+
+		$data = shell_exec($this->cmd);
+
+        @unlink($this->tmpfile);
+
+		$returnData = array();
+		$dataArr = preg_split("/\n/", $data, -1, PREG_SPLIT_NO_EMPTY);
+
+		foreach($dataArr as $dstr) {
+			$matches = array();
+
+			// Skip this line.
+			if (strpos($dstr, "@") === 0)
+				continue;
+
+			preg_match("/\& .* .* .*: (.*)/i", $dstr, $matches);
+
+			if (!empty($matches[1])) {
+				// For some reason, the exec version seems to add commas?
+				$returnData[] = str_replace(",", "", $matches[1]);
+			}
+		}
+		return $returnData;
+	}
+
+	function _debugData($data) {
+		$fh = @fopen("debug.log", 'a+');
+		@fwrite($fh, $data);
+		@fclose($fh);
+	}
+
+}
+
+// Setup classname, should be the same as the name of the spellchecker class
+$spellCheckerConfig['class'] = "TinyPspellShell";
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/config.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/config.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/config.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/config.php	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,24 @@
+<?php
+	$spellCheckerConfig = array();
+
+	// Spellchecker class use
+	// require_once("classes/TinyPspellShell.class.php"); // Command line pspell
+	require_once("classes/TinyGoogleSpell.class.php"); // Google web service
+	// require_once("classes/TinyPspell.class.php"); // Internal PHP version
+
+	// General settings
+	$spellCheckerConfig['enabled'] = true;
+
+	// Default settings
+	$spellCheckerConfig['default.language'] = 'en';
+	$spellCheckerConfig['default.mode'] = PSPELL_FAST;
+
+	// Normaly not required to configure
+	$spellCheckerConfig['default.spelling'] = "";
+	$spellCheckerConfig['default.jargon'] = "";
+	$spellCheckerConfig['default.encoding'] = "";
+
+	// Pspell shell specific settings
+	$spellCheckerConfig['tinypspellshell.aspell'] = '/usr/bin/aspell';
+	$spellCheckerConfig['tinypspellshell.tmp'] = '/tmp';
+?>
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/css/content.css 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/css/content.css
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/css/content.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/css/content.css	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,4 @@
+.mceItemHiddenSpellWord {
+	background: url('../images/wline.gif') repeat-x bottom left;
+	cursor: default;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,35 @@
+.mceMsgBox {
+	border: 1px solid gray;
+	padding: 8px;
+}
+
+.mceMsgBox span {
+	vertical-align: top;
+	color: #555555;
+}
+
+/* Misc */
+
+.mceBlockBox {
+	display: none;
+	position: absolute;
+	left: 0;
+	top: 0;
+	z-index: 100;
+	filter:progid:DXImageTransform.Microsoft.Alpha(style=0, opacity=60);
+	-moz-opacity:0.6;
+	opacity: 0.6;
+	background-color: white;
+}
+
+.mceMsgBox {
+	display: none;
+	z-index: 101;
+	position: absolute;
+	left: 0;
+	top: 0;
+	font-family: Arial, Verdana, Tahoma, Helvetica;
+	font-weight: bold;
+	font-size: 11px;
+	background-color: #FFF;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/editor_plugin.js	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1 @@
+tinyMCE.importPluginLanguagePack('spellchecker','en,fr,sv,nn,nb');var TinyMCE_SpellCheckerPlugin={_contextMenu:new TinyMCE_Menu(),_menu:new TinyMCE_Menu(),_counter:0,_ajaxPage:'/tinyspell.php',getInfo:function(){return{longname:'Spellchecker PHP',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://tinymce.moxiecode.com/tinymce/docs/plugin_spellchecker.html',version:"1.0.3"};},handleEvent:function(e){var elm=tinyMCE.isMSIE?e.srcElement:e.target;var inst=tinyMCE.selectedInstance,args='';var self=TinyMCE_SpellCheckerPlugin;var cm=self._contextMenu;var p,p2,x,y,sx,sy,h,elm;if((e.type=="click"||e.type=="contextmenu")&&elm){do{if(tinyMCE.getAttrib(elm,'class')=="mceItemHiddenSpellWord"){inst.spellCheckerElm=elm;args+='id='+inst.editorId+"|"+(++self._counter);args+='&cmd=suggest&check='+encodeURIComponent(elm.innerHTML);args+='&lang='+escape(inst.spellCheckerLang);elm=inst.spellCheckerElm;p=tinyMCE.getAbsPosition(inst.iframeElement);p2=tinyMCE.getAbsPosition(elm);h=parseInt(elm.offsetHeight);sx=inst.getBody().scrollLeft;sy=inst.getBody().scrollTop;x=p.absLeft+p2.absLeft-sx;y=p.absTop+p2.absTop-sy+h;cm.clear();cm.addTitle(tinyMCE.getLang('lang_spellchecker_wait','',true));cm.show();cm.moveTo(x,y);inst.selection.selectNode(elm,false,false);self._sendAjax(self.baseURL+self._ajaxPage,self._ajaxResponse,'post',args);tinyMCE.cancelEvent(e);return false;}}while((elm=elm.parentNode));}return true;},initInstance:function(inst){var self=TinyMCE_SpellCheckerPlugin,m=self._menu,cm=self._contextMenu,e;tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/spellchecker/css/content.css");if(!tinyMCE.hasMenu('spellcheckercontextmenu')){tinyMCE.importCSS(document,tinyMCE.baseURL+"/plugins/spellchecker/css/spellchecker.css");cm.init({drop_menu:false});tinyMCE.addMenu('spellcheckercontextmenu',cm);}if(!tinyMCE.hasMenu('spellcheckermenu')){m.init({});tinyMCE.addMenu('spellcheckermenu',m);}inst.spellCheckerLang='en';self._buildSettingsMenu(inst,null);e=self._getBlockBoxLayer(inst).create('div','mceBlockBox',document.getElementById(inst.editorId+'_parent'));self._getMsgBoxLayer(inst).create('div','mceMsgBox',document.getElementById(inst.editorId+'_parent'));},_getMsgBoxLayer:function(inst){if(!inst.spellCheckerMsgBoxL)inst.spellCheckerMsgBoxL=new TinyMCE_Layer(inst.editorId+'_spellcheckerMsgBox',false);return inst.spellCheckerMsgBoxL;},_getBlockBoxLayer:function(inst){if(!inst.spellCheckerBoxL)inst.spellCheckerBoxL=new TinyMCE_Layer(inst.editorId+'_spellcheckerBlockBox',false);return inst.spellCheckerBoxL;},_buildSettingsMenu:function(inst,lang){var i,ar=tinyMCE.getParam('spellchecker_languages','+English=en').split(','),p;var self=TinyMCE_SpellCheckerPlugin,m=self._menu,c;m.clear();m.addTitle(tinyMCE.getLang('lang_spellchecker_langs','',true));for(i=0;i<ar.length;i++){if(ar[i]!=''){p=ar[i].split('=');c='mceMenuCheckItem';if(p[0].charAt(0)=='+'){p[0]=p[0].substring(1);if(lang==null){c='mceMenuSelectedItem';inst.spellCheckerLang=p[1];}}if(lang==p[1])c='mceMenuSelectedItem';m.add({text:p[0],js:"tinyMCE.execInstanceCommand('"+inst.editorId+"','mceSpellCheckerSetLang',false,'"+p[1]+"');",class_name:c});}}},setupContent:function(editor_id,body,doc){TinyMCE_SpellCheckerPlugin._removeWords(doc,null,true);},getControlHTML:function(cn){switch(cn){case"spellchecker":return TinyMCE_SpellCheckerPlugin._getMenuButtonHTML(cn,'lang_spellchecker_desc','{$pluginurl}/images/spellchecker.gif','lang_spellchecker_desc','mceSpellCheckerMenu','mceSpellCheck');}return"";},_getMenuButtonHTML:function(id,lang,img,mlang,mid,cmd,ui,val){var h='',m,x;cmd='tinyMCE.hideMenus();tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+cmd+'\'';if(typeof(ui)!="undefined"&&ui!=null)cmd+=','+ui;if(typeof(val)!="undefined"&&val!=null)cmd+=",'"+val+"'";cmd+=');';if(tinyMCE.getParam('button_tile_map')&&(!tinyMCE.isMSIE||tinyMCE.isOpera)&&(m=tinyMCE.buttonMap[id])!=null&&(tinyMCE.getParam("language")=="en"||img.indexOf('$lang')==-1)){x=0-(m*20)==0?'0':0-(m*20);h+='<a id="{$editor_id}_'+id+'" href="javascript:'+cmd+'" onclick="'+cmd+'return false;" onmousedown="return false;" class="mceTiledButton mceButtonNormal" target="_self">';h+='<img src="{$themeurl}/images/spacer.gif" style="background-position: '+x+'px 0" title="{$'+lang+'}" />';h+='<img src="{$themeurl}/images/button_menu.gif" title="{$'+lang+'}" class="mceMenuButton" onclick="'+mcmd+'return false;" />';h+='</a>';}else{if(tinyMCE.isMSIE&&!tinyMCE.isOpera)h+='<span id="{$editor_id}_'+id+'" class="mceMenuButton" onmouseover="tinyMCE.plugins.spellchecker._menuButtonEvent(\'over\',this);" onmouseout="tinyMCE.plugins.spellchecker._menuButtonEvent(\'out\',this);">';else h+='<span id="{$editor_id}_'+id+'" class="mceMenuButton">';h+='<a href="javascript:'+cmd+'" onclick="'+cmd+'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">';h+='<img src="'+img+'" title="{$'+lang+'}" /></a>';h+='<a href="#" onclick="tinyMCE.plugins.spellchecker._toggleMenu(\'{$editor_id}\',\''+mid+'\');return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$'+lang+'}" class="mceMenuButton" />';h+='</a></span>';}return h;},_menuButtonEvent:function(e,o){var t=this;window.setTimeout(function(){t._menuButtonEvent2(e,o);},1);},_menuButtonEvent2:function(e,o){if(o.className=='mceMenuButtonFocus')return;if(e=='over')o.className=o.className+' mceMenuHover';else o.className=o.className.replace(/\s.*$/,'');},_toggleMenu:function(editor_id,id){var self=TinyMCE_SpellCheckerPlugin;var e=document.getElementById(editor_id+'_spellchecker');var inst=tinyMCE.getInstanceById(editor_id);if(self._menu.isVisible()){tinyMCE.hideMenus();return;}tinyMCE.lastMenuBtnClass=e.className.replace(/\s.*$/,'');tinyMCE.switchClass(editor_id+'_spellchecker','mceMenuButtonFocus');self._menu.moveRelativeTo(e,'bl');self._menu.moveBy(tinyMCE.isMSIE&&!tinyMCE.isOpera?0:1,-1);if(tinyMCE.isOpera)self._menu.moveBy(0,-2);self._onMenuEvent(inst,self._menu,'show');self._menu.show();tinyMCE.lastSelectedMenuBtn=editor_id+'_spellchecker';},_onMenuEvent:function(inst,m,n){TinyMCE_SpellCheckerPlugin._buildSettingsMenu(inst,inst.spellCheckerLang);},execCommand:function(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id),self=TinyMCE_SpellCheckerPlugin,args='',co,bb,mb,nl,i,e,mbs;switch(command){case"mceSpellCheck":if(!inst.spellcheckerOn){inst.spellCheckerBookmark=inst.selection.getBookmark();if(tinyMCE.isRealIE)tinyMCE.setInnerHTML(inst.getBody(),inst.getBody().innerHTML);args+='id='+inst.editorId+"|"+(++self._counter);args+='&cmd=spell&check='+encodeURIComponent(self._getWordList(inst.getBody())).replace(/\'/g,'%27');args+='&lang='+escape(inst.spellCheckerLang);co=document.getElementById(inst.editorId+'_parent').firstChild;bb=self._getBlockBoxLayer(inst);bb.moveRelativeTo(co,'tl');bb.resizeTo(co.offsetWidth,co.offsetHeight);bb.show();mb=self._getMsgBoxLayer(inst);e=mb.getElement();if(e.childNodes[0])e.removeChild(e.childNodes[0]);mbs=document.createElement("span");mbs.innerHTML='<span>'+tinyMCE.getLang('lang_spellchecker_swait','',true)+'</span>';e.appendChild(mbs);mb.show();mb.moveRelativeTo(co,'cc');if(tinyMCE.isMSIE&&!tinyMCE.isOpera){nl=co.getElementsByTagName('select');for(i=0;i<nl.length;i++)nl[i].disabled=true;}inst.spellcheckerOn=true;tinyMCE.switchClass(editor_id+'_spellchecker','mceMenuButtonSelected');self._sendAjax(self.baseURL+self._ajaxPage,self._ajaxResponse,'post',args);}else{self._removeWords(inst.getDoc());inst.spellcheckerOn=false;tinyMCE.switchClass(editor_id+'_spellchecker','mceMenuButton');}return true;case"mceSpellCheckReplace":if(inst.spellCheckerElm)tinyMCE.setOuterHTML(inst.spellCheckerElm,value);self._checkDone(inst);self._contextMenu.hide();self._menu.hide();return true;case"mceSpellCheckIgnore":if(inst.spellCheckerElm)self._removeWord(inst.spellCheckerElm);self._checkDone(inst);self._contextMenu.hide();self._menu.hide();return true;case"mceSpellCheckIgnoreAll":if(inst.spellCheckerElm)self._removeWords(inst.getDoc(),inst.spellCheckerElm.innerHTML);self._checkDone(inst);self._contextMenu.hide();self._menu.hide();return true;case"mceSpellCheckerSetLang":tinyMCE.hideMenus();inst.spellCheckerLang=value;self._removeWords(inst.getDoc());inst.spellcheckerOn=false;tinyMCE.switchClass(editor_id+'_spellchecker','mceMenuButton');return true;}return false;},cleanup:function(type,content,inst){switch(type){case"get_from_editor_dom":TinyMCE_SpellCheckerPlugin._removeWords(content,null,true);inst.spellcheckerOn=false;break;}return content;},_displayUI:function(inst){var self=TinyMCE_SpellCheckerPlugin;var bb=self._getBlockBoxLayer(inst);var mb=self._getMsgBoxLayer(inst);var nl,i;var co=document.getElementById(inst.editorId+'_parent').firstChild;if(tinyMCE.isMSIE&&!tinyMCE.isOpera){nl=co.getElementsByTagName('select');for(i=0;i<nl.length;i++)nl[i].disabled=false;}bb.hide();mb.hide();},_ajaxResponse:function(xml){var el=xml?xml.documentElement:null;var inst=tinyMCE.selectedInstance,self=TinyMCE_SpellCheckerPlugin;var cmd=el?el.getAttribute("cmd"):null,err,id=el?el.getAttribute("id"):null;if(id)inst=tinyMCE.getInstanceById(id.substring(0,id.indexOf('|')));self._displayUI(inst);if(cmd=="suggest"&&id!=inst.editorId+"|"+self._counter)return;if(!el){inst.spellcheckerOn=false;tinyMCE.switchClass(inst.editorId+'_spellchecker','mceMenuButton');alert("Could not execute AJAX call, server didn't return valid a XML.");return;}err=el.getAttribute("error");if(err=="true"){inst.spellcheckerOn=false;tinyMCE.switchClass(inst.editorId+'_spellchecker','mceMenuButton');alert(el.getAttribute("msg"));return;}switch(cmd){case"spell":if(xml.documentElement.firstChild){self._markWords(inst.getDoc(),inst.getBody(),decodeURIComponent(el.firstChild.nodeValue).split('+'));inst.selection.moveToBookmark(inst.spellCheckerBookmark);if(tinyMCE.getParam('spellchecker_report_misspellings',false))alert(tinyMCE.getLang('lang_spellchecker_mpell_found','',true,{words:self._countWords(inst)}));}else alert(tinyMCE.getLang('lang_spellchecker_no_mpell','',true));self._checkDone(inst);inst.useCSS=false;break;case"suggest":self._buildMenu(el.firstChild?decodeURIComponent(el.firstChild.nodeValue).split('+'):null,10);self._contextMenu.show();break;}},_getWordSeparators:function(){var i,re='',ch=tinyMCE.getParam('spellchecker_word_separator_chars','\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}\u201d\u201c');for(i=0;i<ch.length;i++)re+='\\'+ch.charAt(i);return re;},_getWordList:function(n){var i,x,s,nv='',nl=tinyMCE.getNodeTree(n,new Array(),3),wl=new Array();var re=TinyMCE_SpellCheckerPlugin._getWordSeparators();for(i=0;i<nl.length;i++){if(!new RegExp('/SCRIPT|STYLE/').test(nl[i].parentNode.nodeName))nv+=nl[i].nodeValue+" ";}nv=nv.replace(new RegExp('([0-9]|['+re+'])','g'),' ');nv=tinyMCE.trim(nv.replace(/(\s+)/g,' '));nl=nv.split(/\s+/);for(i=0;i<nl.length;i++){s=false;for(x=0;x<wl.length;x++){if(wl[x]==nl[i]){s=true;break;}}if(!s&&nl[i].length>0)wl[wl.length]=nl[i];}return wl.join(' ');},_removeWords:function(doc,word,cleanup){var i,c,nl=doc.getElementsByTagName("span");var self=TinyMCE_SpellCheckerPlugin;var inst=tinyMCE.selectedInstance,b=inst?inst.selection.getBookmark():null;word=typeof(word)=='undefined'?null:word;for(i=nl.length-1;i>=0;i--){c=tinyMCE.getAttrib(nl[i],'class');if((c=='mceItemHiddenSpellWord'||c=='mceItemHidden')&&(word==null||nl[i].innerHTML==word))self._removeWord(nl[i]);}if(b&&!cleanup)inst.selection.moveToBookmark(b);},_checkDone:function(inst){var self=TinyMCE_SpellCheckerPlugin;var w=self._countWords(inst);if(w==0){self._removeWords(inst.getDoc());inst.spellcheckerOn=false;tinyMCE.switchClass(inst.editorId+'_spellchecker','mceMenuButton');}},_countWords:function(inst){var i,w=0,nl=inst.getDoc().getElementsByTagName("span"),c;var self=TinyMCE_SpellCheckerPlugin;for(i=nl.length-1;i>=0;i--){c=tinyMCE.getAttrib(nl[i],'class');if(c=='mceItemHiddenSpellWord')w++;}return w;},_removeWord:function(e){if(e!=null)tinyMCE.setOuterHTML(e,e.innerHTML);},_markWords:function(doc,n,wl){var i,nv,nn,nl=tinyMCE.getNodeTree(n,new Array(),3);var r1,r2,r3,r4,r5,w='';var re=TinyMCE_SpellCheckerPlugin._getWordSeparators();for(i=0;i<wl.length;i++){if(wl[i].length>0)w+=wl[i]+((i==wl.length-1)?'':'|');}for(i=0;i<nl.length;i++){nv=nl[i].nodeValue;r1=new RegExp('(['+re+'])('+w+')(['+re+'])','g');r2=new RegExp('^('+w+')','g');r3=new RegExp('('+w+')(['+re+']?)$','g');r4=new RegExp('^('+w+')(['+re+']?)$','g');r5=new RegExp('('+w+')(['+re+'])','g');if(r1.test(nv)||r2.test(nv)||r3.test(nv)||r4.test(nv)){nv=tinyMCE.xmlEncode(nv);nv=nv.replace(r5,'<span class="mceItemHiddenSpellWord">$1</span>$2');nv=nv.replace(r3,'<span class="mceItemHiddenSpellWord">$1</span>$2');nn=doc.createElement('span');nn.className="mceItemHidden";nn.innerHTML=nv;nl[i].parentNode.replaceChild(nn,nl[i]);}}},_buildMenu:function(sg,max){var i,self=TinyMCE_SpellCheckerPlugin,cm=self._contextMenu;cm.clear();if(sg!=null){cm.addTitle(tinyMCE.getLang('lang_spellchecker_sug','',true));for(i=0;i<sg.length&&i<max;i++)cm.addItem(sg[i],'tinyMCE.execCommand("mceSpellCheckReplace",false,"'+sg[i]+'");');cm.addSeparator();}else cm.addTitle(tinyMCE.getLang('lang_spellchecker_no_sug','',true));cm.addItem(tinyMCE.getLang('lang_spellchecker_ignore_word','',true),'tinyMCE.execCommand(\'mceSpellCheckIgnore\');');cm.addItem(tinyMCE.getLang('lang_spellchecker_ignore_words','',true),'tinyMCE.execCommand(\'mceSpellCheckIgnoreAll\');');cm.update();},_getAjaxHTTP:function(){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(e){return new XMLHttpRequest();}}},_sendAjax:function(u,f,m,a){var x=TinyMCE_SpellCheckerPlugin._getAjaxHTTP();x.open(m,u,true);x.onreadystatechange=function(){if(x.readyState==4)f(x.responseXML);};if(m=='post')x.setRequestHeader('Content-type','application/x-www-form-urlencoded');x.send(a);}};tinyMCE.addPlugin('spellchecker',TinyMCE_SpellCheckerPlugin);
\ No newline at end of file
Binary files 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/images/spellchecker.gif and 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/images/spellchecker.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/images/wline.gif and 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/images/wline.gif differ
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/langs/en.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/langs/en.js	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,15 @@
+// UK lang variables
+
+tinyMCE.addToLang('spellchecker',{
+	desc : 'Toggle spellchecker',
+	menu : 'Spellchecker settings',
+	ignore_word : 'Ignore word',
+	ignore_words : 'Ignore all',
+	langs : 'Languages',
+	wait : 'Please wait...',
+	swait : 'Spellchecking, please wait...',
+	sug : 'Suggestions',
+	no_sug : 'No suggestions',
+	no_mpell : 'No misspellings found.',
+	mpell_found : 'Found {$words} misspellings.'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php
--- 2.0.5/wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php	2007-03-06 22:26:26.000000000 -0600
@@ -0,0 +1,142 @@
+<?php
+/**
+ * $RCSfile: tinyspell.php,v $
+ * $Revision: 1.1 $
+ * $Date: 2006/03/14 17:33:47 $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2006, Moxiecode Systems AB, All rights reserved.
+ */
+
+	// Ignore the Notice errors for now.
+	error_reporting(E_ALL ^ E_NOTICE);
+
+	require_once("config.php");
+
+	$id = sanitize($_POST['id'], "loose");
+
+	if (!$spellCheckerConfig['enabled']) {
+		header('Content-type: text/xml; charset=utf-8');
+		echo '<?xml version="1.0" encoding="utf-8" ?><res id="' . $id . '" error="true" msg="You must enable the spellchecker by modifying the config.php file." />';
+		die;
+	}
+
+	// Basic config
+	$defaultLanguage = $spellCheckerConfig['default.language'];
+	$defaultMode = $spellCheckerConfig['default.mode'];
+
+	// Normaly not required to configure
+	$defaultSpelling = $spellCheckerConfig['default.spelling'];
+	$defaultJargon = $spellCheckerConfig['default.jargon'];
+	$defaultEncoding = $spellCheckerConfig['default.encoding'];
+	$outputType = "xml"; // Do not change
+
+	// Get input parameters.
+
+	$check = urldecode($_REQUEST['check']);
+	$cmd = sanitize($_REQUEST['cmd']);
+	$lang = sanitize($_REQUEST['lang'], "strict");
+	$mode = sanitize($_REQUEST['mode'], "strict");
+	$spelling = sanitize($_REQUEST['spelling'], "strict");
+	$jargon = sanitize($_REQUEST['jargon'], "strict");
+	$encoding = sanitize($_REQUEST['encoding'], "strict");
+	$sg = sanitize($_REQUEST['sg'], "bool");
+	$words = array();
+
+	$validRequest = true;
+
+	if (empty($check))
+		$validRequest = false;
+
+	if (empty($lang))
+		$lang = $defaultLanguage;
+
+	if (empty($mode))
+		$mode = $defaultMode;
+
+	if (empty($spelling))
+		$spelling = $defaultSpelling;
+
+	if (empty($jargon))
+		$jargon = $defaultJargon;
+
+	if (empty($encoding))
+		$encoding = $defaultEncoding;
+
+	function sanitize($str, $type="strict") {
+		switch ($type) {
+			case "strict":
+				$str = preg_replace("/[^a-zA-Z0-9_\-]/i", "", $str);
+			break;
+			case "loose":
+				$str = preg_replace("/</i", "&gt;", $str);
+				$str = preg_replace("/>/i", "&lt;", $str);
+			break;
+			case "bool":
+				if ($str == "true" || $str == true)
+					$str = true;
+				else
+					$str = false;
+			break;
+		}
+
+		return $str;
+	}
+
+	$result = array();
+	$tinyspell = new $spellCheckerConfig['class']($spellCheckerConfig, $lang, $mode, $spelling, $jargon, $encoding);
+
+	if (count($tinyspell->errorMsg) == 0) {
+		switch($cmd) {
+			case "spell":
+				// Space for non-exec version and \n for the exec version.
+				$words = preg_split("/ |\n/", $check, -1, PREG_SPLIT_NO_EMPTY);
+				$result = $tinyspell->checkWords($words);
+			break;
+	
+			case "suggest":
+				$result = $tinyspell->getSuggestion($check);
+			break;
+
+			default:
+				// Just use this for now.
+				$tinyspell->errorMsg[] = "No command.";
+				$outputType = $outputType . "error";
+			break;
+		}
+	} else
+		$outputType = $outputType . "error";
+
+	if (!$result)
+		$result = array();
+
+	// Output data
+	switch($outputType) {
+		case "xml":
+			header('Content-type: text/xml; charset=utf-8');
+			$body  = '<?xml version="1.0" encoding="utf-8" ?>';
+			$body .= "\n";
+			
+			if (count($result) == 0)
+				$body .= '<res id="' . $id . '" cmd="'. $cmd .'" />';
+			else
+				$body .= '<res id="' . $id . '" cmd="'. $cmd .'">'. urlencode(implode(" ", $result)) .'</res>';
+
+			echo $body;
+		break;
+		case "xmlerror";
+			header('Content-type: text/xml; charset=utf-8');
+			$body  = '<?xml version="1.0" encoding="utf-8" ?>';
+			$body .= "\n";
+			$body .= '<res id="' . $id . '" cmd="'. $cmd .'" error="true" msg="'. implode(" ", $tinyspell->errorMsg) .'" />';
+			echo $body;
+		break;
+		case "html":
+			var_dump($result);
+		break;
+		case "htmlerror":
+			echo "Error";
+		break;
+	}
+
+?>
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,285 +1,592 @@
-/* Import plugin specific language pack */
-tinyMCE.importPluginLanguagePack('wordpress', '');
-
-function TinyMCE_wordpress_initInstance(inst) {
-	if (!tinyMCE.settings['wordpress_skip_plugin_css'])
-		tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/wordpress/wordpress.css");
-}
-
-function TinyMCE_wordpress_getControlHTML(control_name) {
-	switch (control_name) {
-		case "wordpress":
-			var titleMore = tinyMCE.getLang('lang_wordpress_more_button');
-			var titlePage = tinyMCE.getLang('lang_wordpress_page_button');
-			var titleHelp = tinyMCE.getLang('lang_wordpress_help_button');
-			var buttons = '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\')" target="_self" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\');return false;"><img id="{$editor_id}_wordpress_more" src="{$pluginurl}/images/more.gif" title="'+titleMore+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
-			// Add this to the buttons var to put the Page button into the toolbar.
-			// '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpresspage\')" target="_self" onclick="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpresspage\');return false;"><img id="{$editor_id}_wordpress_page" src="{$pluginurl}/images/page.gif" title="'+titlePage+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
-			return buttons;
-	}
-
-	return '';
-}
-
-function TinyMCE_wordpress_parseAttributes(attribute_string) {
-	var attributeName = "";
-	var attributeValue = "";
-	var withInName;
-	var withInValue;
-	var attributes = new Array();
-	var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g');
-	var titleText = tinyMCE.getLang('lang_wordpress_more');
-	var titleTextPage = tinyMCE.getLang('lang_wordpress_page');
-
-	if (attribute_string == null || attribute_string.length < 2)
-		return null;
-
-	withInName = withInValue = false;
-
-	for (var i=0; i<attribute_string.length; i++) {
-		var chr = attribute_string.charAt(i);
-
-		if ((chr == '"' || chr == "'") && !withInValue)
-			withInValue = true;
-		else if ((chr == '"' || chr == "'") && withInValue) {
-			withInValue = false;
-
-			var pos = attributeName.lastIndexOf(' ');
-			if (pos != -1)
-				attributeName = attributeName.substring(pos+1);
-
-			attributes[attributeName.toLowerCase()] = attributeValue.substring(1).toLowerCase();
-
-			attributeName = "";
-			attributeValue = "";
-		} else if (!whiteSpaceRegExp.test(chr) && !withInName && !withInValue)
-			withInName = true;
-
-		if (chr == '=' && withInName)
-			withInName = false;
-
-		if (withInName)
-			attributeName += chr;
-
-		if (withInValue)
-			attributeValue += chr;
-	}
-
-	return attributes;
-}
-
-function TinyMCE_wordpress_execCommand(editor_id, element, command, user_interface, value) {
-	var inst = tinyMCE.getInstanceById(editor_id);
-	var focusElm = inst.getFocusElement();
-	var doc = inst.getDoc();
-
-	function getAttrib(elm, name) {
-		return elm.getAttribute(name) ? elm.getAttribute(name) : "";
-	}
-
-	// Handle commands
-	switch (command) {
-			case "mcewordpressmore":
-				var flag = "";
-				var template = new Array();
-				var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
-
-				// Is selection a image
-				if (focusElm != null && focusElm.nodeName.toLowerCase() == "img") {
-					flag = getAttrib(focusElm, 'class');
-	
-					if (flag != 'mce_plugin_wordpress_more') // Not a wordpress
-						return true;
-	
-					action = "update";
-				}
-	
-				html = ''
-					+ '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" '
-					+ ' width="100%" height="10px" '
-					+ 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" name="mce_plugin_wordpress_more" />';
-				tinyMCE.execCommand("mceInsertContent",true,html);
-				tinyMCE.selectedInstance.repaint();
-				return true;
-			case "mcewordpresspage":
-				var flag = "";
-				var template = new Array();
-				var altPage = tinyMCE.getLang('lang_wordpress_more_alt');
-	
-				// Is selection a image
-				if (focusElm != null && focusElm.nodeName.toLowerCase() == "img") {
-					flag = getAttrib(focusElm, 'name');
-	
-					if (flag != 'mce_plugin_wordpress_page') // Not a wordpress
-						return true;
-	
-					action = "update";
-				}
-	
-				html = ''
-					+ '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" '
-					+ ' width="100%" height="10px" '
-					+ 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" name="mce_plugin_wordpress_page" />';
-				tinyMCE.execCommand("mceInsertContent",true,html);
-				tinyMCE.selectedInstance.repaint();
-				return true;
-	}
-
-	// Pass to next handler in chain
-	return false;
-}
-
-function TinyMCE_wordpress_cleanup(type, content) {
-	switch (type) {
-	
-		case "insert_to_editor":
-			var startPos = 0;
-			var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
-			var altPage = tinyMCE.getLang('lang_wordpress_page_alt');
-
-			// Parse all <!--more--> tags and replace them with images
-			while ((startPos = content.indexOf('<!--more-->', startPos)) != -1) {
-				// Insert image
-				var contentAfter = content.substring(startPos + 11);
-				content = content.substring(0, startPos);
-				content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
-				content += ' width="100%" height="10px" ';
-				content += 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" />';
-				content += contentAfter;
-
-				startPos++;
-			}
-			var startPos = 0;
-
-			// Parse all <!--page--> tags and replace them with images
-			while ((startPos = content.indexOf('<!--nextpage-->', startPos)) != -1) {
-				// Insert image
-				var contentAfter = content.substring(startPos + 15);
-				content = content.substring(0, startPos);
-				content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
-				content += ' width="100%" height="10px" ';
-				content += 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" />';
-				content += contentAfter;
-
-				startPos++;
-			}
-
-			// It's supposed to be WYSIWYG, right?
-			content = content.replace(new RegExp('&', 'g'), '&amp;');
-
-			break;
-
-		case "get_from_editor":
-			// Parse all img tags and replace them with <!--more-->
-			var startPos = -1;
-			while ((startPos = content.indexOf('<img', startPos+1)) != -1) {
-				var endPos = content.indexOf('/>', startPos);
-				var attribs = TinyMCE_wordpress_parseAttributes(content.substring(startPos + 4, endPos));
-
-				if (attribs['class'] == "mce_plugin_wordpress_more") {
-					endPos += 2;
-	
-					var embedHTML = '<!--more-->';
-	
-					// Insert embed/object chunk
-					chunkBefore = content.substring(0, startPos);
-					chunkAfter = content.substring(endPos);
-					content = chunkBefore + embedHTML + chunkAfter;
-				}
-				if (attribs['class'] == "mce_plugin_wordpress_page") {
-					endPos += 2;
-	
-					var embedHTML = '<!--nextpage-->';
-	
-					// Insert embed/object chunk
-					chunkBefore = content.substring(0, startPos);
-					chunkAfter = content.substring(endPos);
-					content = chunkBefore + embedHTML + chunkAfter;
-				}
-			}
-
-			// If it says & in the WYSIWYG editor, it should say &amp; in the html.
-			content = content.replace(new RegExp('&', 'g'), '&amp;');
-			content = content.replace(new RegExp('&amp;nbsp;', 'g'), '&nbsp;');
-
-			// Remove anonymous, empty paragraphs.
-			content = content.replace(new RegExp('<p>(\\s|&nbsp;)*</p>', 'mg'), '');
-
-			// Handle table badness.
-			content = content.replace(new RegExp('<(table( [^>]*)?)>.*?<((tr|thead)( [^>]*)?)>', 'mg'), '<$1><$3>');
-			content = content.replace(new RegExp('<(tr|thead|tfoot)>.*?<((td|th)( [^>]*)?)>', 'mg'), '<$1><$2>');
-			content = content.replace(new RegExp('</(td|th)>.*?<(td( [^>]*)?|th( [^>]*)?|/tr|/thead|/tfoot)>', 'mg'), '</$1><$2>');
-			content = content.replace(new RegExp('</tr>.*?<(tr|/table)>', 'mg'), '</tr><$1>');
-			content = content.replace(new RegExp('<(/?(table|tbody|tr|th|td)[^>]*)>(\\s*|(<br ?/?>)*)*', 'g'), '<$1>');
-
-			// Pretty it up for the source editor.
-			var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre|p';
-			content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
-			content = content.replace(new RegExp('\\s*<(('+blocklist+')[^>]*)>\\s*', 'mg'), '\n<$1>');
-			content = content.replace(new RegExp('<((li|/?tr|/?thead|/?tfoot)( [^>]*)?)>', 'g'), '\t<$1>');
-			content = content.replace(new RegExp('<((td|th)( [^>]*)?)>', 'g'), '\t\t<$1>');
-			content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'mg'), '<br />\n');
-			content = content.replace(new RegExp('^\\s*', ''), '');
-			content = content.replace(new RegExp('\\s*$', ''), '');
-			
-			break;
-	}
-
-	// Pass through to next handler in chain
-	return content;
-}
-
-function TinyMCE_wordpress_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
-	function getAttrib(elm, name) {
-		return elm.getAttribute(name) ? elm.getAttribute(name) : "";
-	}
-
-	tinyMCE.switchClassSticky(editor_id + '_wordpress_more', 'mceButtonNormal');
-	tinyMCE.switchClassSticky(editor_id + '_wordpress_page', 'mceButtonNormal');
-
-	if (node == null)
-		return;
-
-	do {
-		if (node.nodeName.toLowerCase() == "img" && getAttrib(node, 'class').indexOf('mce_plugin_wordpress_more') == 0)
-			tinyMCE.switchClassSticky(editor_id + '_wordpress_more', 'mceButtonSelected');
-		if (node.nodeName.toLowerCase() == "img" && getAttrib(node, 'class').indexOf('mce_plugin_wordpress_page') == 0)
-			tinyMCE.switchClassSticky(editor_id + '_wordpress_page', 'mceButtonSelected');
-	} while ((node = node.parentNode));
-
-	return true;
-}
-
-function wp_save_callback(el, content, body) {
-	// We have a TON of cleanup to do.
-
-	// Mark </p> if it has any attributes.
-	content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>');
-
-	// Decode the ampersands of time.
-	content = content.replace(new RegExp('&amp;', 'g'), '&');
-
-	// Get it ready for wpautop.
-	content = content.replace(new RegExp('[\\s]*<p>[\\s]*', 'mgi'), '');
-	content = content.replace(new RegExp('[\\s]*</p>[\\s]*', 'mgi'), '\n\n');
-	content = content.replace(new RegExp('\\n\\s*\\n\\s*\\n*', 'mgi'), '\n\n');
-	content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'gi'), '\n');
-
-	// Fix some block element newline issues
-	var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre';
-	content = content.replace(new RegExp('\\s*<(('+blocklist+') ?[^>]*)\\s*>', 'mg'), '\n<$1>');
-	content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
-	content = content.replace(new RegExp('<li>', 'g'), '\t<li>');
-
-	// Unmark special paragraph closing tags
-	content = content.replace(new RegExp('</p#>', 'g'), '</p>\n');
-	content = content.replace(new RegExp('\\s*(<p[^>]+>.*</p>)', 'mg'), '\n$1');
-
-	// Trim any whitespace
-	content = content.replace(new RegExp('^\\s*', ''), '');
-	content = content.replace(new RegExp('\\s*$', ''), '');
-
-	// Hope.
-	return content;
-
-}
+/* Import plugin specific language pack */
+tinyMCE.importPluginLanguagePack('wordpress', 'en');
+
+var TinyMCE_wordpressPlugin = {
+	getInfo : function() {
+		return {
+			longname : 'WordPress Plugin',
+			author : 'WordPress',
+			authorurl : 'http://wordpress.org',
+			infourl : 'http://wordpress.org',
+			version : '1'
+		};
+	},
+
+	getControlHTML : function(control_name) {
+		switch (control_name) {
+			case "wp_more":
+				return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_more_button', '{$pluginurl}/images/more.gif', 'wpMore');
+			case "wp_page":
+				return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_page_button', '{$pluginurl}/images/page.gif', 'wpPage');
+			case "wp_help":
+				var buttons = tinyMCE.getButtonHTML(control_name, 'lang_help_button_title', '{$pluginurl}/images/help.gif', 'wpHelp');
+				var hiddenControls = '<div class="zerosize">'
+				+ '<input type="button" accesskey="n" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceSpellCheck\',false);" />'
+				+ '<input type="button" accesskey="k" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Strikethrough\',false);" />'
+				+ '<input type="button" accesskey="l" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertUnorderedList\',false);" />'
+				+ '<input type="button" accesskey="o" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertOrderedList\',false);" />'
+				+ '<input type="button" accesskey="w" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Outdent\',false);" />'
+				+ '<input type="button" accesskey="q" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Indent\',false);" />'
+				+ '<input type="button" accesskey="f" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyLeft\',false);" />'
+				+ '<input type="button" accesskey="c" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyCenter\',false);" />'
+				+ '<input type="button" accesskey="r" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyRight\',false);" />'
+				+ '<input type="button" accesskey="j" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyFull\',false);" />'
+				+ '<input type="button" accesskey="a" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceLink\',true);" />'
+				+ '<input type="button" accesskey="s" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'unlink\',false);" />'
+				+ '<input type="button" accesskey="m" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceImage\',true);" />'
+				+ '<input type="button" accesskey="t" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpMore\');" />'
+				+ '<input type="button" accesskey="g" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpPage\');" />'
+				+ '<input type="button" accesskey="u" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Undo\',false);" />'
+				+ '<input type="button" accesskey="y" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Redo\',false);" />'
+				+ '<input type="button" accesskey="h" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpHelp\',false);" />'
+				+ '<input type="button" accesskey="b" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Bold\',false);" />'
+				+ '<input type="button" accesskey="v" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'wpAdv\',false);" />'
+				+ '</div>';
+				return buttons+hiddenControls;
+			case "wp_adv":
+				return tinyMCE.getButtonHTML(control_name, 'lang_wordpress_adv_button', '{$pluginurl}/images/toolbars.gif', 'wpAdv');
+			case "wp_adv_start":
+				return '<div id="wpadvbar" style="display:none;"><br />';
+			case "wp_adv_end":
+				return '</div>';
+		}
+		return '';
+	},
+
+	execCommand : function(editor_id, element, command, user_interface, value) {
+		var inst = tinyMCE.getInstanceById(editor_id);
+		var focusElm = inst.getFocusElement();
+		var doc = inst.getDoc();
+
+		function getAttrib(elm, name) {
+			return elm.getAttribute(name) ? elm.getAttribute(name) : "";
+		}
+
+		// Handle commands
+		switch (command) {
+			case "wpMore":
+				var flag = "";
+				var template = new Array();
+				var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
+
+				// Is selection a image
+				if (focusElm != null && focusElm.nodeName.toLowerCase() == "img") {
+					flag = getAttrib(focusElm, 'class');
+
+					if (flag != 'mce_plugin_wordpress_more') // Not a wordpress
+						return true;
+
+					action = "update";
+				}
+
+				html = ''
+					+ '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" '
+					+ ' width="100%" height="10px" '
+					+ 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" name="mce_plugin_wordpress_more" />';
+				tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, html);
+				tinyMCE.selectedInstance.repaint();
+				return true;
+
+			case "wpPage":
+				var flag = "";
+				var template = new Array();
+				var altPage = tinyMCE.getLang('lang_wordpress_more_alt');
+
+				// Is selection a image
+				if (focusElm != null && focusElm.nodeName.toLowerCase() == "img") {
+					flag = getAttrib(focusElm, 'name');
+
+					if (flag != 'mce_plugin_wordpress_page') // Not a wordpress
+						return true;
+
+					action = "update";
+				}
+
+				html = ''
+					+ '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" '
+					+ ' width="100%" height="10px" '
+					+ 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" name="mce_plugin_wordpress_page" />';
+				tinyMCE.execCommand("mceInsertContent",true,html);
+				tinyMCE.selectedInstance.repaint();
+				return true;
+
+			case "wpHelp":
+				var template = new Array();
+
+				template['file']   = tinyMCE.baseURL + '/wp-mce-help.php';
+				template['width']  = 480;
+				template['height'] = 380;
+
+				args = {
+					resizable : 'yes',
+					scrollbars : 'yes'
+				};
+
+				tinyMCE.openWindow(template, args);
+				return true;
+			case "wpAdv":
+				var adv = document.getElementById('wpadvbar');
+				if ( adv.style.display == 'none' ) {
+					adv.style.display = 'block';
+					tinyMCE.switchClass(editor_id + '_wp_adv', 'mceButtonSelected');
+				} else {
+					adv.style.display = 'none';
+					tinyMCE.switchClass(editor_id + '_wp_adv', 'mceButtonNormal');
+				}
+				return true;
+		}
+
+		// Pass to next handler in chain
+		return false;
+	},
+
+	cleanup : function(type, content) {
+		switch (type) {
+
+			case "insert_to_editor":
+				var startPos = 0;
+				var altMore = tinyMCE.getLang('lang_wordpress_more_alt');
+				var altPage = tinyMCE.getLang('lang_wordpress_page_alt');
+
+				// Parse all <!--more--> tags and replace them with images
+				while ((startPos = content.indexOf('<!--more', startPos)) != -1) {
+					var endPos = content.indexOf('-->', startPos) + 3;
+					// Insert image
+					var moreText = content.substring(startPos + 8, endPos - 3);
+					var contentAfter = content.substring(endPos);
+					content = content.substring(0, startPos);
+					content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
+					content += ' width="100%" height="10px" moretext="'+moreText+'" ';
+					content += 'alt="'+altMore+'" title="'+altMore+'" class="mce_plugin_wordpress_more" name="mce_plugin_wordpress_more" />';
+					content += contentAfter;
+
+					startPos++;
+				}
+				var startPos = 0;
+
+				// Parse all <!--page--> tags and replace them with images
+				while ((startPos = content.indexOf('<!--nextpage-->', startPos)) != -1) {
+					// Insert image
+					var contentAfter = content.substring(startPos + 15);
+					content = content.substring(0, startPos);
+					content += '<img src="' + (tinyMCE.getParam("theme_href") + "/images/spacer.gif") + '" ';
+					content += ' width="100%" height="10px" ';
+					content += 'alt="'+altPage+'" title="'+altPage+'" class="mce_plugin_wordpress_page" name="mce_plugin_wordpress_page" />';
+					content += contentAfter;
+
+					startPos++;
+				}
+
+				// Look for \n in <pre>, replace with <br>
+				var startPos = -1;
+				while ((startPos = content.indexOf('<pre', startPos+1)) != -1) {
+					var endPos = content.indexOf('</pre>', startPos+1);
+					var innerPos = content.indexOf('>', startPos+1);
+					var chunkBefore = content.substring(0, innerPos);
+					var chunkAfter = content.substring(endPos);
+					
+					var innards = content.substring(innerPos, endPos);
+					innards = innards.replace(/\n/g, '<br />');
+					content = chunkBefore + innards + chunkAfter;
+				}
+
+				break;
+
+			case "get_from_editor":
+				// Parse all img tags and replace them with <!--more-->
+				var startPos = -1;
+				while ((startPos = content.indexOf('<img', startPos+1)) != -1) {
+					var endPos = content.indexOf('/>', startPos);
+					var attribs = this._parseAttributes(content.substring(startPos + 4, endPos));
+
+					if (attribs['class'] == "mce_plugin_wordpress_more" || attribs['name'] == "mce_plugin_wordpress_more") {
+						endPos += 2;
+
+						var moreText = attribs['moretext'] ? attribs['moretext'] : '';
+						var embedHTML = '<!--more'+moreText+'-->';
+
+						// Insert embed/object chunk
+						chunkBefore = content.substring(0, startPos);
+						chunkAfter = content.substring(endPos);
+						content = chunkBefore + embedHTML + chunkAfter;
+					}
+					if (attribs['class'] == "mce_plugin_wordpress_page" || attribs['name'] == "mce_plugin_wordpress_page") {
+						endPos += 2;
+
+						var embedHTML = '<!--nextpage-->';
+
+						// Insert embed/object chunk
+						chunkBefore = content.substring(0, startPos);
+						chunkAfter = content.substring(endPos);
+						content = chunkBefore + embedHTML + chunkAfter;
+					}
+				}
+
+				// Remove normal line breaks
+				content = content.replace(/\n|\r/g, ' ');
+
+				// Look for <br> in <pre>, replace with \n
+				var startPos = -1;
+				while ((startPos = content.indexOf('<pre', startPos+1)) != -1) {
+					var endPos = content.indexOf('</pre>', startPos+1);
+					var innerPos = content.indexOf('>', startPos+1);
+					var chunkBefore = content.substring(0, innerPos);
+					var chunkAfter = content.substring(endPos);
+					
+					var innards = content.substring(innerPos, endPos);
+					innards = innards.replace(new RegExp('<br\\s?/?>', 'g'), '\n');
+					innards = innards.replace(new RegExp('\\s$', ''), '');
+					content = chunkBefore + innards + chunkAfter;
+				}
+
+				// Remove anonymous, empty paragraphs.
+				content = content.replace(new RegExp('<p>(\\s|&nbsp;)*</p>', 'mg'), '');
+
+				// Handle table badness.
+				content = content.replace(new RegExp('<(table( [^>]*)?)>.*?<((tr|thead)( [^>]*)?)>', 'mg'), '<$1><$3>');
+				content = content.replace(new RegExp('<(tr|thead|tfoot)>.*?<((td|th)( [^>]*)?)>', 'mg'), '<$1><$2>');
+				content = content.replace(new RegExp('</(td|th)>.*?<(td( [^>]*)?|th( [^>]*)?|/tr|/thead|/tfoot)>', 'mg'), '</$1><$2>');
+				content = content.replace(new RegExp('</tr>.*?<(tr|/table)>', 'mg'), '</tr><$1>');
+				content = content.replace(new RegExp('<(/?(table|tbody|tr|th|td)[^>]*)>(\\s*|(<br ?/?>)*)*', 'g'), '<$1>');
+
+				// Pretty it up for the source editor.
+				var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre|p';
+				content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
+				content = content.replace(new RegExp('\\s*<(('+blocklist+')[^>]*)>', 'mg'), '\n<$1>');
+				content = content.replace(new RegExp('<((li|/?tr|/?thead|/?tfoot)( [^>]*)?)>', 'g'), '\t<$1>');
+				content = content.replace(new RegExp('<((td|th)( [^>]*)?)>', 'g'), '\t\t<$1>');
+				content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'mg'), '<br />\n');
+				content = content.replace(new RegExp('^\\s*', ''), '');
+				content = content.replace(new RegExp('\\s*$', ''), '');
+
+				break;
+		}
+
+		// Pass through to next handler in chain
+		return content;
+	},
+
+	handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
+
+		tinyMCE.switchClass(editor_id + '_wp_more', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_wp_page', 'mceButtonNormal');
+
+		if (node == null)
+			return;
+
+		do {
+			if (node.nodeName.toLowerCase() == "img" && tinyMCE.getAttrib(node, 'class').indexOf('mce_plugin_wordpress_more') == 0)
+				tinyMCE.switchClass(editor_id + '_wp_more', 'mceButtonSelected');
+			if (node.nodeName.toLowerCase() == "img" && tinyMCE.getAttrib(node, 'class').indexOf('mce_plugin_wordpress_page') == 0)
+				tinyMCE.switchClass(editor_id + '_wp_page', 'mceButtonSelected');
+		} while ((node = node.parentNode));
+
+		return true;
+	},
+
+	saveCallback : function(el, content, body) {
+		// We have a TON of cleanup to do.
+
+		// Mark </p> if it has any attributes.
+		content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>');
+
+		// Decode the ampersands of time.
+		// content = content.replace(new RegExp('&amp;', 'g'), '&');
+
+		// Get it ready for wpautop.
+		content = content.replace(new RegExp('\\s*<p>', 'mgi'), '');
+		content = content.replace(new RegExp('\\s*</p>\\s*', 'mgi'), '\n\n');
+		content = content.replace(new RegExp('\\n\\s*\\n', 'mgi'), '\n\n');
+		content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'gi'), '\n');
+
+		// Fix some block element newline issues
+		var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre';
+		content = content.replace(new RegExp('\\s*<(('+blocklist+') ?[^>]*)\\s*>', 'mg'), '\n<$1>');
+		content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n');
+		content = content.replace(new RegExp('<li>', 'g'), '\t<li>');
+
+		// Unmark special paragraph closing tags
+		content = content.replace(new RegExp('</p#>', 'g'), '</p>\n');
+		content = content.replace(new RegExp('\\s*(<p[^>]+>.*</p>)', 'mg'), '\n$1');
+
+		// Trim trailing whitespace
+		content = content.replace(new RegExp('\\s*$', ''), '');
+
+		// Hope.
+		return content;
+
+	},
+
+	_parseAttributes : function(attribute_string) {
+		var attributeName = "";
+		var attributeValue = "";
+		var withInName;
+		var withInValue;
+		var attributes = new Array();
+		var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g');
+		var titleText = tinyMCE.getLang('lang_wordpress_more');
+		var titleTextPage = tinyMCE.getLang('lang_wordpress_page');
+
+		if (attribute_string == null || attribute_string.length < 2)
+			return null;
+
+		withInName = withInValue = false;
+
+		for (var i=0; i<attribute_string.length; i++) {
+			var chr = attribute_string.charAt(i);
+
+			if ((chr == '"' || chr == "'") && !withInValue)
+				withInValue = true;
+			else if ((chr == '"' || chr == "'") && withInValue) {
+				withInValue = false;
+
+				var pos = attributeName.lastIndexOf(' ');
+				if (pos != -1)
+					attributeName = attributeName.substring(pos+1);
+
+				attributes[attributeName.toLowerCase()] = attributeValue.substring(1);
+
+				attributeName = "";
+				attributeValue = "";
+			} else if (!whiteSpaceRegExp.test(chr) && !withInName && !withInValue)
+				withInName = true;
+
+			if (chr == '=' && withInName)
+				withInName = false;
+
+			if (withInName)
+				attributeName += chr;
+
+			if (withInValue)
+				attributeValue += chr;
+		}
+
+		return attributes;
+	}
+};
+
+tinyMCE.addPlugin("wordpress", TinyMCE_wordpressPlugin);
+
+/* This little hack protects our More and Page placeholders from the removeformat command */
+tinyMCE.orgExecCommand = tinyMCE.execCommand;
+tinyMCE.execCommand = function (command, user_interface, value) {
+	re = this.orgExecCommand(command, user_interface, value);
+
+	if ( command == 'removeformat' ) {
+		var inst = tinyMCE.getInstanceById('mce_editor_0');
+		doc = inst.getDoc();
+		var imgs = doc.getElementsByTagName('img');
+		for (i=0;img=imgs[i];i++)
+			img.className = img.name;
+	}
+	return re;
+};
+wpInstTriggerSave = function (skip_cleanup, skip_callback) {
+	var e, nl = new Array(), i, s;
+
+	this.switchSettings();
+	s = tinyMCE.settings;
+
+	// Force hidden tabs visible while serializing
+	if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
+		e = this.iframeElement;
+
+		do {
+			if (e.style && e.style.display == 'none') {
+				e.style.display = 'block';
+				nl[nl.length] = {elm : e, type : 'style'};
+			}
+
+			if (e.style && s.hidden_tab_class.length > 0 && e.className.indexOf(s.hidden_tab_class) != -1) {
+				e.className = s.display_tab_class;
+				nl[nl.length] = {elm : e, type : 'class'};
+			}
+		} while ((e = e.parentNode) != null)
+	}
+
+	tinyMCE.settings['preformatted'] = false;
+
+	// Default to false
+	if (typeof(skip_cleanup) == "undefined")
+		skip_cleanup = false;
+
+	// Default to false
+	if (typeof(skip_callback) == "undefined")
+		skip_callback = false;
+
+//	tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML);
+
+	// Remove visual aids when cleanup is disabled
+	if (this.settings['cleanup'] == false) {
+		tinyMCE.handleVisualAid(this.getBody(), true, false, this);
+		tinyMCE._setEventsEnabled(this.getBody(), true);
+	}
+
+	tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body);
+	tinyMCE.selectedInstance.getWin().oldfocus=tinyMCE.selectedInstance.getWin().focus;
+	tinyMCE.selectedInstance.getWin().focus=function() {};
+	var htm = tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
+	tinyMCE.selectedInstance.getWin().focus=tinyMCE.selectedInstance.getWin().oldfocus;
+	htm = tinyMCE._customCleanup(this, "submit_content", htm);
+
+	if (!skip_callback && tinyMCE.settings['save_callback'] != "")
+		var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());");
+
+	// Use callback content if available
+	if ((typeof(content) != "undefined") && content != null)
+		htm = content;
+
+	// Replace some weird entities (Bug: #1056343)
+	htm = tinyMCE.regexpReplace(htm, "&#40;", "(", "gi");
+	htm = tinyMCE.regexpReplace(htm, "&#41;", ")", "gi");
+	htm = tinyMCE.regexpReplace(htm, "&#59;", ";", "gi");
+	htm = tinyMCE.regexpReplace(htm, "&#34;", "&quot;", "gi");
+	htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "gi");
+
+	if (this.formElement)
+		this.formElement.value = htm;
+
+	if (tinyMCE.isSafari && this.formElement)
+		this.formElement.innerText = htm;
+
+	// Hide them again (tabs in MSIE)
+	for (i=0; i<nl.length; i++) {
+		if (nl[i].type == 'style')
+			nl[i].elm.style.display = 'none';
+		else
+			nl[i].elm.className = s.hidden_tab_class;
+	}
+}
+tinyMCE.wpTriggerSave = function () {
+	var inst, n;
+	for (n in tinyMCE.instances) {
+		inst = tinyMCE.instances[n];
+		if (!tinyMCE.isInstance(inst))
+			continue;
+		inst.wpTriggerSave = wpInstTriggerSave;
+		inst.wpTriggerSave(false, false);
+	}
+}
+
+function switchEditors(id) {
+	var inst = tinyMCE.getInstanceById(id);
+	var qt = document.getElementById('quicktags');
+	var H = document.getElementById('edButtonHTML');
+	var P = document.getElementById('edButtonPreview');
+	var ta = document.getElementById(id);
+	var pdr = ta.parentNode;
+
+	if ( inst ) {
+		edToggle(H, P);
+
+		if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) {
+			// IE rejects the later overflow assignment so we skip this step.
+			// Alternate code might be nice. Until then, IE reflows.
+		} else {
+			// Lock the fieldset's height to prevent reflow/flicker
+			pdr.style.height = pdr.clientHeight + 'px';
+			pdr.style.overflow = 'hidden';
+		}
+
+		// Save the coords of the bottom right corner of the rich editor
+		var table = document.getElementById(inst.editorId + '_parent').getElementsByTagName('table')[0];
+		var y1 = table.offsetTop + table.offsetHeight;
+
+		if ( TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height") == null ) {
+			var expires = new Date();
+			expires.setTime(expires.getTime() + 3600000 * 24 * 30);
+			var offset = tinyMCE.isMSIE ? 1 : 2;
+			TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + inst.editorId + "_height", "" + (table.offsetHeight - offset), expires);
+		}
+
+		// Unload the rich editor
+		inst.triggerSave(false, false);
+		htm = inst.formElement.value;
+		tinyMCE.removeMCEControl(id);
+		document.getElementById(id).value = htm;
+		--tinyMCE.idCounter;
+
+		// Reveal Quicktags and textarea
+		qt.style.display = 'block';
+		ta.style.display = 'inline';
+
+		// Set the textarea height to match the rich editor
+		y2 = ta.offsetTop + ta.offsetHeight;
+		ta.style.height = (ta.clientHeight + y1 - y2) + 'px';
+
+		// Tweak the widths
+		ta.parentNode.style.paddingRight = '12px';
+
+		if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) {
+		} else {
+			// Unlock the fieldset's height
+			pdr.style.height = 'auto';
+			pdr.style.overflow = 'display';
+		}
+	} else {
+		edToggle(P, H);
+		edCloseAllTags(); // :-(
+
+		if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) {
+		} else {
+			// Lock the fieldset's height
+			pdr.style.height = pdr.clientHeight + 'px';
+			pdr.style.overflow = 'hidden';
+		}
+
+		// Hide Quicktags and textarea
+		qt.style.display = 'none';
+		ta.style.display = 'none';
+
+		// Tweak the widths
+		ta.parentNode.style.paddingRight = '0px';
+
+		// Load the rich editor with formatted html
+		if ( tinyMCE.isMSIE ) {
+			ta.value = wpautop(ta.value);
+			tinyMCE.addMCEControl(ta, id);
+		} else {
+			htm = wpautop(ta.value);
+			tinyMCE.addMCEControl(ta, id);
+			tinyMCE.getInstanceById(id).execCommand('mceSetContent', null, htm);
+		}
+
+		if ( tinyMCE.isMSIE && !tinyMCE.isOpera ) {
+		} else {
+			// Unlock the fieldset's height
+			pdr.style.height = 'auto';
+			pdr.style.overflow = 'display';
+		}
+	}
+}
+
+function edToggle(A, B) {
+	A.className = 'edButtonFore';
+	B.className = 'edButtonBack';
+
+	B.onclick = A.onclick;
+	A.onclick = null;
+}
+
+function wpautop(pee) {
+	pee = pee + "\n\n";
+	pee = pee.replace(new RegExp('<br />\\s*<br />', 'gi'), "\n\n");
+	pee = pee.replace(new RegExp('(<(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)', 'gi'), "\n$1"); 
+	pee = pee.replace(new RegExp('(</(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])>)', 'gi'), "$1\n\n");
+	pee = pee.replace(new RegExp("\\r\\n|\\r", 'g'), "\n");
+	pee = pee.replace(new RegExp("\\n\\s*\\n+", 'g'), "\n\n");
+	pee = pee.replace(new RegExp('([\\s\\S]+?)\\n\\n', 'mg'), "<p>$1</p>\n");
+	pee = pee.replace(new RegExp('<p>\\s*?</p>', 'gi'), '');
+	pee = pee.replace(new RegExp('<p>\\s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\\s*</p>', 'gi'), "$1");
+	pee = pee.replace(new RegExp("<p>(<li.+?)</p>", 'gi'), "$1");
+	pee = pee.replace(new RegExp('<p><blockquote([^>]*)>', 'gi'), "<blockquote$1><p>");
+	pee = pee.replace(new RegExp('</blockquote></p>', 'gi'), '</p></blockquote>');
+	pee = pee.replace(new RegExp('<p>\\s*(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|hr|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)', 'gi'), "$1");
+	pee = pee.replace(new RegExp('(</?(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\\s*</p>', 'gi'), "$1"); 
+	pee = pee.replace(new RegExp('\\s*\\n', 'gi'), "<br />\n");
+	pee = pee.replace(new RegExp('(</?(?:table|thead|tfoot|caption|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)\\s*<br />', 'gi'), "$1");
+	pee = pee.replace(new RegExp('<br />(\\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)', 'gi'), '$1');
+	pee = pee.replace(new RegExp('^((?:&nbsp;)*)\\s', 'mg'), '$1&nbsp;');
+	//pee = pee.replace(new RegExp('(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') .  stripslashes(clean_pre('$2'))  . '</pre>' "); // Hmm...
+	return pee;
+}
Binary files 2.0.5/wp-includes/js/tinymce/plugins/wordpress/images/help.gif and 2.2.2/wp-includes/js/tinymce/plugins/wordpress/images/help.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/plugins/wordpress/images/toolbars.gif and 2.2.2/wp-includes/js/tinymce/plugins/wordpress/images/toolbars.gif differ
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wordpress/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/wordpress/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/wordpress/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wordpress/langs/en.js	2007-02-25 08:04:49.000000000 -0600
@@ -1,16 +1,33 @@
-// EN lang variables
-
-if (navigator.userAgent.indexOf('Mac OS') != -1) {
-// Mac OS browsers use Ctrl to hit accesskeys
-	var metaKey = 'Ctrl';
-}
-else {
-	var metaKey = 'Alt';
-}
-
-tinyMCE.addToLang('',{
-wordpress_more_button : 'Split post with More tag (' + metaKey + '-t)',
-wordpress_page_button : 'Split post with Page tag',
-wordpress_more_alt : 'More...',
-wordpress_page_alt : '...page...'
-});
+// EN lang variables
+
+if (navigator.userAgent.indexOf('Mac OS') != -1) {
+// Mac OS browsers use Ctrl to hit accesskeys
+	var metaKey = 'Ctrl';
+}
+else {
+	var metaKey = 'Alt';
+}
+
+tinyMCE.addToLang('',{
+wordpress_more_button : 'Split post with More tag (' + metaKey + '+t)',
+wordpress_page_button : 'Split post with Page tag',
+wordpress_adv_button : 'Show/Hide Advanced Toolbar (' + metaKey + '+b)',
+wordpress_more_alt : 'More...',
+wordpress_page_alt : '...page...',
+help_button_title : 'Help (' + metaKey + '+h)',
+bold_desc : 'Bold (Ctrl+B)',
+italic_desc : 'Italic (Ctrl+I)',
+underline_desc : 'Underline (Ctrl+U)',
+link_desc : 'Insert/edit link (' + metaKey + '+a)',
+unlink_desc : 'Unlink (' + metaKey + '+s)',
+image_desc : 'Insert/edit image (' + metaKey + '+m)',
+striketrough_desc : 'Strikethrough (' + metaKey + '+k)',
+justifyleft_desc : 'Align left (' + metaKey + '+f)',
+justifycenter_desc : 'Align center (' + metaKey + '+c)',
+justifyright_desc : 'Align right (' + metaKey + '+r)',
+justifyfull_desc : 'Align full (' + metaKey + '+j)',
+bullist_desc : 'Unordered list (' + metaKey + '+l)',
+numlist_desc : 'Ordered list (' + metaKey + '+o)',
+outdent_desc : 'Outdent (' + metaKey + '+w)',
+indent_desc : 'Indent list/blockquote (' + metaKey + '+q)'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wordpress/popups.css 2.2.2/wp-includes/js/tinymce/plugins/wordpress/popups.css
--- 2.0.5/wp-includes/js/tinymce/plugins/wordpress/popups.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wordpress/popups.css	2006-03-30 01:50:33.000000000 -0600
@@ -0,0 +1,354 @@
+/* This file contains the CSS data for all popups in TinyMCE */
+
+body {
+	background-color: #F0F0EE;
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 11px;
+	scrollbar-3dlight-color: #F0F0EE;
+	scrollbar-arrow-color: #676662;
+	scrollbar-base-color: #F0F0EE;
+	scrollbar-darkshadow-color: #DDDDDD;
+	scrollbar-face-color: #E0E0DD;
+	scrollbar-highlight-color: #F0F0EE;
+	scrollbar-shadow-color: #F0F0EE;
+	scrollbar-track-color: #F5F5F5;
+	margin: 8px;
+}
+
+td {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 11px;
+}
+
+input {
+	background: #FFFFFF;
+	border: 1px solid #cccccc;
+}
+
+td, input, select, textarea {
+	font-family: Verdana, Arial, Helvetica, sans-serif;
+	font-size: 10px;
+}
+
+input, select, textarea {
+	border: 1px solid #808080;
+}
+
+.input_noborder {
+	border: 0;
+}
+
+#insert, .updateButton {
+   font-weight: bold;
+   width: 90px;
+   height: 21px;
+   border: 0;
+   background-image: url('../images/insert_button_bg.gif');
+   cursor: pointer;
+}
+
+#cancel {
+   font-weight: bold;
+   width: 90px;
+   height: 21px;
+   border: 0;
+   background-image: url('../images/cancel_button_bg.gif');
+   cursor: pointer;
+}
+
+/* Mozilla only style */
+html>body #insert, html>body #cancel {
+	padding-bottom: 2px;
+}
+
+.title {
+	display: block;
+	padding-top: 5px;
+	padding-bottom: 5px;
+	padding-left: 15px;
+	font-size: 15px;
+}
+
+
+table.charmap {
+	border-style: solid;
+	border-width: 1px;
+	border-color: #AAAAAA;
+}
+
+td.charmap, td.charmapOver {
+	color: #000000;
+	border-color: #AAAAAA;
+	border-style: solid;
+	border-width: 1px;
+	text-align: center;
+	font-size: 12px;
+}
+
+td.charmapOver {
+	background-color: #CCCCCC;
+	cursor: default;
+}
+
+a.charmap {
+	color: #000000;
+	text-decoration: none
+}
+
+.wordWrapCode {
+	vertical-align: middle;
+	border: 1px none #000000;
+	background-color: transparent;
+}
+
+input.radio {
+	border: 1px none #000000;
+	background-color: transparent;
+	vertical-align: middle;
+}
+
+input.checkbox {
+	border: 1px none #000000;
+	background-color: transparent;
+	vertical-align: middle;
+}
+
+.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected {
+	margin-left: 1px;
+}
+
+.mceButtonNormal {
+	border-top: 1px solid;
+	border-left: 1px solid;
+	border-bottom: 1px solid;
+	border-right: 1px solid;
+	border-color: #F0F0EE;
+	cursor: default;
+}
+
+.mceButtonOver {
+	border: 1px solid #0A246A;
+	cursor: default;
+	background-color: #B6BDD2;
+}
+
+.mceButtonDown {
+	cursor: default;
+	border: 1px solid #0A246A;
+	background-color: #8592B5;
+}
+
+.mceButtonDisabled {
+	filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);
+	-moz-opacity:0.3;
+	opacity: 0.3;
+	border-top: 1px solid;
+	border-left: 1px solid;
+	border-bottom: 1px solid;
+	border-right: 1px solid;
+	border-color: #F0F0EE;
+	cursor: default;
+}
+
+.mceActionPanel {
+	margin-top: 5px;
+}
+
+/* Tabs classes */
+
+.tabs {
+	float: left;
+	width: 100%;
+	line-height: normal;
+	background-image: url("../images/xp/tabs_bg.gif");
+}
+
+.tabs ul {
+	margin: 0;
+	padding: 0 0 0;
+	list-style: none;
+}
+
+.tabs li {
+	float: left;
+	background: url("../images/xp/tab_bg.gif") no-repeat left top;
+	margin: 0;
+	margin-left: 0;
+	margin-right: 2px;
+	padding: 0 0 0 10px;
+	line-height: 18px;
+}
+
+.tabs li.current {
+	background: url("../images/xp/tab_sel_bg.gif") no-repeat left top;
+	margin-right: 2px;
+}
+
+.tabs span {
+	float: left;
+	display: block;
+	background: url("../images/xp/tab_end.gif") no-repeat right top;
+	padding: 0px 10px 0 0;
+}
+
+.tabs .current span {
+	background: url("../images/xp/tab_sel_end.gif") no-repeat right top;
+}
+
+.tabs a {
+	text-decoration: none;
+	font-family: Verdana, Arial;
+	font-size: 10px;
+}
+
+.tabs a:link, .tabs a:visited, .tabs a:hover {
+	color: black;
+}
+
+.tabs a:hover {
+}
+
+.tabs .current {
+}
+
+.tabs .current a, .tabs .current a:link, .tabs .current a:visited {
+}
+
+.panel_wrapper div.panel {
+	display: none;
+}
+
+.panel_wrapper div.current {
+	display: block;
+	width: 100%;
+	height: 300px;
+	overflow: visible; /* Should be auto but that breaks Safari */
+}
+
+.panel_wrapper {
+	border: 1px solid #919B9C;
+	border-top: 0px;
+	padding: 10px;
+	padding-top: 5px;
+	clear: both;
+	background-color: white;
+}
+
+fieldset {
+	border: 1px solid #919B9C;
+	font-family: Verdana, Arial;
+	font-size: 10px;
+	padding: 0;
+	margin: 0;
+	padding: 4px;
+}
+
+legend {
+	color: #2B6FB6;
+	font-weight: bold;
+}
+
+.properties {
+	width: 100%;
+}
+
+.properties .column1 {
+}
+
+.properties .column2 {
+	text-align: left;
+}
+
+a:link, a:visited {
+	color: black;
+}
+
+a:hover {
+	color: #2B6FB6;
+}
+
+#plugintable thead {
+	font-weight: bold;
+	background-color: #DDDDDD;
+}
+
+#plugintable, #about #plugintable td {
+	border: 1px solid #919B9C;
+}
+
+#plugintable {
+	width: 99%;
+	margin-top: 10px;
+}
+
+#pluginscontainer {
+	height: 290px;
+	overflow: auto;
+}
+
+/* MSIE Specific styles */
+
+* html .panel_wrapper {
+	width: 100%;
+}
+
+.column {
+	float: left;
+}
+
+h1, h2, h3, h4 {
+	color: #2B6FB6;
+	margin: 0;
+	padding: 0;
+	padding-top: 5px;
+}
+
+h3 {
+	font-size: 14px;
+}
+
+#link .panel_wrapper, #link div.current {
+	height: 125px;
+}
+
+#image .panel_wrapper, #image div.current {
+	height: 190px;
+}
+
+/* Disables the advanced tab in the table plugin. */
+/*
+#table #advanced_tab {
+	display: none;
+}
+*/
+
+/* Disables the border input field and label in the table plugin. */
+/*
+#table #border, #table #borderlabel {
+	display: none;
+}
+*/
+
+#insert, #cancel, .submitbutton {
+	font: 13px Verdana, Arial, Helvetica, sans-serif;
+	height: auto;
+	width: auto;
+	background-color: transparent;
+	background-image: url(../../../../../wp-admin/images/fade-butt.png);
+	background-repeat: repeat;
+	border: 3px double;
+	border-right-color: rgb(153, 153, 153);
+	border-bottom-color: rgb(153, 153, 153);
+	border-left-color: rgb(204, 204, 204);
+	border-top-color: rgb(204, 204, 204);
+	color: rgb(51, 51, 51);
+	padding: 0.25em 0.75em;
+}
+
+#insert:active, #cancel:active, .submitbutton:active {
+	background: #f4f4f4;
+	border-left-color: #999;
+	border-top-color: #999;
+}
+
+
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wordpress/wordpress.css 2.2.2/wp-includes/js/tinymce/plugins/wordpress/wordpress.css
--- 2.0.5/wp-includes/js/tinymce/plugins/wordpress/wordpress.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wordpress/wordpress.css	2007-03-05 13:27:40.000000000 -0600
@@ -19,3 +19,63 @@
 	background-repeat: no-repeat;
 	background-position: right top;
 }
+
+/* This file contains the CSS data for the editable area(iframe) of TinyMCE */
+/* You can extend this CSS by adding your own CSS file with the the content_css option */
+
+body {
+	background: #fff;
+	font: 1em/1.3em Georgia, "Times New Roman", Times, serif;
+	padding: .5em;
+}
+
+td {
+	font-size: 10px;
+}
+
+pre {
+	font-family: "Courier New", fixed;
+	font-size: 11px;
+	line-height: 13px;
+}
+
+.mceVisualAid {
+	border: 1px dashed #BBBBBB !important;
+}
+
+.mceItemAnchor {
+	width: 12px;
+	line-height: 6px;
+	overflow: hidden;
+	padding-left: 12px;
+	background-position: bottom;
+	background-repeat: no-repeat;
+}
+
+/* Important is needed in Gecko browsers inorder to style links */
+/*
+a {
+	color: green !important;
+}
+*/
+
+/* Style selection range colors in Gecko browsers */
+/*
+::-moz-selection {
+	background-color: red;
+	color: green;
+}
+*/
+
+/* MSIE specific */
+
+* html body {
+	scrollbar-3dlight-color: #F0F0EE;
+	scrollbar-arrow-color: #676662;
+	scrollbar-base-color: #F0F0EE;
+	scrollbar-darkshadow-color: #DDDDDD;
+	scrollbar-face-color: #E0E0DD;
+	scrollbar-highlight-color: #F0F0EE;
+	scrollbar-shadow-color: #F0F0EE;
+	scrollbar-track-color: #F5F5F5;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wphelp/editor_plugin.js 2.2.2/wp-includes/js/tinymce/plugins/wphelp/editor_plugin.js
--- 2.0.5/wp-includes/js/tinymce/plugins/wphelp/editor_plugin.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wphelp/editor_plugin.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,57 +1,57 @@
-/* Import plugin specific language pack */
-tinyMCE.importPluginLanguagePack('wphelp', '');
-
-function TinyMCE_wphelp_getControlHTML(control_name) {
-	switch (control_name) {
-		case "wphelp":
-			var titleHelp = tinyMCE.getLang('lang_help_button_title');
-			var buttons = '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\')" target="_self" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\');return false;"><img id="{$editor_id}_help" src="{$pluginurl}/images/help.gif" title="'+titleHelp+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
-			var hiddenControls = '<div class="zerosize">'
-			+ '<input type="button" accesskey="b" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Bold\',false);" />'
-			+ '<input type="button" accesskey="i" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Italic\',false);" />'
-			+ '<input type="button" accesskey="d" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Strikethrough\',false);" />'
-			+ '<input type="button" accesskey="l" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertUnorderedList\',false);" />'
-			+ '<input type="button" accesskey="o" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertOrderedList\',false);" />'
-			+ '<input type="button" accesskey="w" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Outdent\',false);" />'
-			+ '<input type="button" accesskey="q" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Indent\',false);" />'
-			+ '<input type="button" accesskey="f" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyLeft\',false);" />'
-			+ '<input type="button" accesskey="c" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyCenter\',false);" />'
-			+ '<input type="button" accesskey="r" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyRight\',false);" />'
-			+ '<input type="button" accesskey="a" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceLink\',true);" />'
-			+ '<input type="button" accesskey="s" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'unlink\',false);" />'
-			+ '<input type="button" accesskey="m" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceImage\',true);" />'
-			+ '<input type="button" accesskey="t" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\');" />'
-			+ '<input type="button" accesskey="u" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Undo\',false);" />'
-			+ '<input type="button" accesskey="y" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Redo\',false);" />'
-			+ '<input type="button" accesskey="e" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceCodeEditor\',false);" />'
-			+ '<input type="button" accesskey="h" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\',false);" />'
-			+ '</div>';
-			return buttons+hiddenControls;
-    }
-
-    return "";
-}
-
-function TinyMCE_wphelp_execCommand(editor_id, element, command, user_interface, value) {
-
-	// Handle commands
-	switch (command) {
-		case "mceWordPressHelp":
-			var template = new Array();
-
-			template['file']   = tinyMCE.baseURL + '/wp-mce-help.php';
-			template['width']  = 480;
-			template['height'] = 380;
-
-			args = {
-				resizable : 'yes',
-				scrollbars : 'yes'
-			};
-
-			tinyMCE.openWindow(template, args);
-			return true;
-	}
-
-	// Pass to next handler in chain
-	return false;
-}
+/* Import plugin specific language pack */
+tinyMCE.importPluginLanguagePack('wphelp', '');
+
+function TinyMCE_wphelp_getControlHTML(control_name) {
+	switch (control_name) {
+		case "wphelp":
+			var titleHelp = tinyMCE.getLang('lang_help_button_title');
+			var buttons = '<a href="javascript:tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\')" target="_self" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\');return false;"><img id="{$editor_id}_help" src="{$pluginurl}/images/help.gif" title="'+titleHelp+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';
+			var hiddenControls = '<div class="zerosize">'
+			+ '<input type="button" accesskey="b" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Bold\',false);" />'
+			+ '<input type="button" accesskey="i" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Italic\',false);" />'
+			+ '<input type="button" accesskey="d" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Strikethrough\',false);" />'
+			+ '<input type="button" accesskey="l" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertUnorderedList\',false);" />'
+			+ '<input type="button" accesskey="o" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'InsertOrderedList\',false);" />'
+			+ '<input type="button" accesskey="w" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Outdent\',false);" />'
+			+ '<input type="button" accesskey="q" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Indent\',false);" />'
+			+ '<input type="button" accesskey="f" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyLeft\',false);" />'
+			+ '<input type="button" accesskey="c" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyCenter\',false);" />'
+			+ '<input type="button" accesskey="r" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'JustifyRight\',false);" />'
+			+ '<input type="button" accesskey="a" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceLink\',true);" />'
+			+ '<input type="button" accesskey="s" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'unlink\',false);" />'
+			+ '<input type="button" accesskey="m" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceImage\',true);" />'
+			+ '<input type="button" accesskey="t" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mcewordpressmore\');" />'
+			+ '<input type="button" accesskey="u" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Undo\',false);" />'
+			+ '<input type="button" accesskey="y" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'Redo\',false);" />'
+			+ '<input type="button" accesskey="e" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceCodeEditor\',false);" />'
+			+ '<input type="button" accesskey="h" onclick="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceWordPressHelp\',false);" />'
+			+ '</div>';
+			return buttons+hiddenControls;
+    }
+
+    return "";
+}
+
+function TinyMCE_wphelp_execCommand(editor_id, element, command, user_interface, value) {
+
+	// Handle commands
+	switch (command) {
+		case "mceWordPressHelp":
+			var template = new Array();
+
+			template['file']   = tinyMCE.baseURL + '/wp-mce-help.php';
+			template['width']  = 480;
+			template['height'] = 380;
+
+			args = {
+				resizable : 'yes',
+				scrollbars : 'yes'
+			};
+
+			tinyMCE.openWindow(template, args);
+			return true;
+	}
+
+	// Pass to next handler in chain
+	return false;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/plugins/wphelp/langs/en.js 2.2.2/wp-includes/js/tinymce/plugins/wphelp/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/plugins/wphelp/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/plugins/wphelp/langs/en.js	2007-01-16 11:52:13.000000000 -0600
@@ -1,5 +1,5 @@
-// EN lang variables
-
-tinyMCE.addToLang('',{
-help_button_title : 'Help (Alt+h)'
-});
+// EN lang variables
+
+tinyMCE.addToLang('',{
+help_button_title : 'Help (Alt+h)'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/about.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/about.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/about.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/about.htm	2007-01-24 19:20:47.000000000 -0600
@@ -4,7 +4,7 @@
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
 	<script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/about.js"></script>
-	<link href="css/dialog_about.css" rel="stylesheet" type="text/css" />
+	<base target="_self" />
 </head>
 <body id="about" onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
 		<div class="tabs">
@@ -21,7 +21,7 @@
 				<p>Version: {$tinymce_version} ({$tinymce_releasedate})</p>
 				<p>TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under <a href="../../license.txt" target="_blank">LGPL</a>
 				by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.</p>
-				<p>Copyright &copy; 2005, <a href="http://www.moxiecode.com" target="_blank">Moxiecode Systems AB</a>, All rights reserved.</p>
+				<p>Copyright &copy; 2003-2007, <a href="http://www.moxiecode.com" target="_blank">Moxiecode Systems AB</a>, All rights reserved.</p>
 				<p>For more information about this software visit the <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE website</a>.</p>
 
 				<div id="buttoncontainer"></div>
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/anchor.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/anchor.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/anchor.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/anchor.htm	2006-03-30 01:50:33.000000000 -0600
@@ -3,6 +3,7 @@
 	<title>{$lang_insert_anchor_title}</title>
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/anchor.js"></script>
+	<base target="_self" />
 </head>
 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
 <form onsubmit="insertAnchor();return false;" action="#">
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/charmap.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/charmap.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/charmap.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/charmap.htm	2006-11-20 18:55:06.000000000 -0600
@@ -4,6 +4,7 @@
 	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/charmap.js"></script>
+	<base target="_self" />
 </head>
 <body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
 <table align="center" border="0" cellspacing="0" cellpadding="2">
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/color_picker.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/color_picker.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/color_picker.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/color_picker.htm	2007-05-18 19:10:57.000000000 -0500
@@ -2,11 +2,73 @@
 <head>
 	<title>{$lang_theme_colorpicker_title}</title>
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
+	<script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/color_picker.js"></script>
+	<link href="css/colorpicker.css" rel="stylesheet" type="text/css" />
+	<base target="_self" />
 </head>
-<body onload="tinyMCEPopup.executeOnLoad('init();');" marginheight="3" topmargin="3" leftmargin="3" marginwidth="3" style="display: none">
-	<div align="center">
-	   <script language="javascript" type="text/javascript">renderColorMap();</script>
+<body onload="tinyMCEPopup.executeOnLoad('init();');" style="display: none">
+	<div class="tabs">
+		<ul>
+			<li id="picker_tab" class="current"><span><a href="javascript:mcTabs.displayTab('picker_tab','picker_panel');" onmousedown="return false;">{$lang_color_picker_tab}</a></span></li>
+			<li id="rgb_tab"><span><a href="#" onclick="generateWebColors();mcTabs.displayTab('rgb_tab','rgb_panel');" onmousedown="return false;">{$lang_web_colors_tab}</a></span></li>
+			<li id="named_tab"><span><a  href="#" onclick="generateNamedColors();javascript:mcTabs.displayTab('named_tab','named_panel');" onmousedown="return false;">{$lang_named_colors_tab}</a></span></li>
+		</ul>
+	</div>
+
+	<div class="panel_wrapper">
+		<div id="picker_panel" class="panel current">
+			<fieldset>
+				<legend>{$lang_color_picker}</legend>
+				<div id="picker">
+					<img id="colorpicker" src="images/colors.jpg" onclick="computeColor(event)" onmousedown="isMouseDown = true;return false;" onmouseup="isMouseDown = false;" onmousemove="if (isMouseDown && isMouseOver) computeColor(event); return false;" onmouseover="isMouseOver=true;" onmouseout="isMouseOver=false;" />
+
+					<div id="light">
+						<!-- Will be filled with divs -->
+					</div>
+
+					<br style="clear: both" />
+				</div>
+			</fieldset>
+		</div>
+
+		<div id="rgb_panel" class="panel">
+			<fieldset>
+				<legend>{$lang_web_colors}</legend>
+				<div id="webcolors">
+					<!-- Gets filled with web safe colors-->
+				</div>
+
+				<br style="clear: both" />
+			</fieldset>
+		</div>
+
+		<div id="named_panel" class="panel">
+			<fieldset>
+				<legend>{$lang_named_colors}</legend>
+				<div id="namedcolors">
+					<!-- Gets filled with named colors-->
+				</div>
+
+				<br style="clear: both" />
+
+				<div id="colornamecontainer">
+					{$lang_color_name} <span id="colorname"></span>
+				</div>
+			</fieldset>
+		</div>
+	</div>
+
+	<div class="mceActionPanel">
+		<div style="float: left">
+			<input type="button" id="insert" name="insert" value="{$lang_theme_colorpicker_apply}" onclick="insertAction();" />
+		</div>
+
+		<div id="preview"></div>
+
+		<div id="previewblock">
+			<label for="color">{$lang_color}</label> <input id="color" type="text" size="8" maxlength="8" class="text" />
+		</div>
 	</div>
 </body>
 </html>
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css 2.2.2/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/css/colorpicker.css	2007-05-18 19:10:57.000000000 -0500
@@ -0,0 +1,53 @@
+/* Colorpicker dialog specific CSS */
+
+#preview {
+	float: right;
+	width: 50px;
+	height: 14px;
+	line-height: 1px;
+	border: 1px solid black;
+	margin-left: 5px;
+}
+
+#colorpicker {
+	float: left;
+	cursor: crosshair;
+}
+
+#light {
+	border: 1px solid gray;
+	margin-left: 5px;
+	float: left;
+	width: 15px;
+	cursor: crosshair;
+}
+
+#light div {
+	overflow: hidden;
+}
+
+#previewblock {
+	float: right;
+	padding-left: 10px;
+	height: 20px;
+}
+
+.panel_wrapper div.current {
+	height: 175px;
+}
+
+#namedcolors {
+	width: 150px;
+}
+
+#namedcolors a {
+	display: block;
+	float: left;
+	width: 10px; height: 10px;
+	margin: 1px 1px 0 0;
+	overflow: hidden;
+}
+
+#colornamecontainer {
+	margin-top: 5px;
+}
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_content.css 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_content.css
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_content.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_content.css	2006-11-20 18:55:06.000000000 -0600
@@ -1,28 +1,24 @@
 /* This file contains the CSS data for the editable area(iframe) of TinyMCE */
 /* You can extend this CSS by adding your own CSS file with the the content_css option */
 
-body {
-	background-color: #FFFFFF;
-	font-family: Verdana, Arial, Helvetica, sans-serif;
-	font-size: 0.9em;
-	line-height: 1.2em;
-	padding: .3em;
-}
-
-td {
+body, td, pre {
 	font-family: Verdana, Arial, Helvetica, sans-serif;
 	font-size: 10px;
 }
 
-pre {
-	font-family: Verdana, Arial, Helvetica, sans-serif;
-	font-size: 10px;
+body {
+	background-color: #FFFFFF;
 }
 
 .mceVisualAid {
 	border: 1px dashed #BBBBBB !important;
 }
 
+div.mceVisualAid {
+	background-image:url('../images/spacer.gif');
+	visibility: visible !important;
+}
+
 .mceItemAnchor {
 	width: 12px;
 	line-height: 6px;
@@ -47,3 +43,16 @@
 	color: green;
 }
 */
+
+/* MSIE specific */
+
+* html body {
+	scrollbar-3dlight-color: #F0F0EE;
+	scrollbar-arrow-color: #676662;
+	scrollbar-base-color: #F0F0EE;
+	scrollbar-darkshadow-color: #DDDDDD;
+	scrollbar-face-color: #E0E0DD;
+	scrollbar-highlight-color: #F0F0EE;
+	scrollbar-shadow-color: #F0F0EE;
+	scrollbar-track-color: #F5F5F5;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_popup.css	2006-11-20 18:55:06.000000000 -0600
@@ -35,14 +35,14 @@
 }
 
 .input_noborder {
-	border: 0px solid #808080;
+	border: 0;
 }
 
-#insert {
+#insert, .updateButton {
    font-weight: bold;
    width: 90px;
    height: 21px;
-   border: 0px;
+   border: 0;
    background-image: url('../images/insert_button_bg.gif');
    cursor: pointer;
 }
@@ -51,7 +51,7 @@
    font-weight: bold;
    width: 90px;
    height: 21px;
-   border: 0px;
+   border: 0;
    background-image: url('../images/cancel_button_bg.gif');
    cursor: pointer;
 }
@@ -84,7 +84,7 @@
 
 td.charmapOver {
 	background-color: #CCCCCC;
-	cursor: arrow;
+	cursor: default;
 }
 
 a.charmap {
@@ -120,17 +120,17 @@
 	border-bottom: 1px solid;
 	border-right: 1px solid;
 	border-color: #F0F0EE;
-	cursor: arrow;
+	cursor: default;
 }
 
 .mceButtonOver {
 	border: 1px solid #0A246A;
-	cursor: arrow;
+	cursor: default;
 	background-color: #B6BDD2;
 }
 
 .mceButtonDown {
-	cursor: arrow;
+	cursor: default;
 	border: 1px solid #0A246A;
 	background-color: #8592B5;
 }
@@ -144,7 +144,7 @@
 	border-bottom: 1px solid;
 	border-right: 1px solid;
 	border-color: #F0F0EE;
-	cursor: arrow;
+	cursor: default;
 }
 
 .mceActionPanel {
@@ -162,7 +162,7 @@
 
 .tabs ul {
 	margin: 0;
-	padding: 0px 0px 0;
+	padding: 0 0 0;
 	list-style: none;
 }
 
@@ -170,7 +170,7 @@
 	float: left;
 	background: url("../images/xp/tab_bg.gif") no-repeat left top;
 	margin: 0;
-	margin-left: 0px;
+	margin-left: 0;
 	margin-right: 2px;
 	padding: 0 0 0 10px;
 	line-height: 18px;
@@ -185,7 +185,7 @@
 	float: left;
 	display: block;
 	background: url("../images/xp/tab_end.gif") no-repeat right top;
-	padding: 0px 10px 0px 0px;
+	padding: 0px 10px 0 0;
 }
 
 .tabs .current span {
@@ -235,8 +235,8 @@
 	border: 1px solid #919B9C;
 	font-family: Verdana, Arial;
 	font-size: 10px;
-	padding: 0px;
-	margin: 0px;
+	padding: 0;
+	margin: 0;
 	padding: 4px;
 }
 
@@ -295,8 +295,8 @@
 
 h1, h2, h3, h4 {
 	color: #2B6FB6;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	padding-top: 5px;
 }
 
@@ -304,6 +304,18 @@
 	font-size: 14px;
 }
 
+#link .panel_wrapper, #link div.current {
+	height: 125px;
+}
+
+#image .panel_wrapper, #image div.current {
+	height: 190px;
+}
+
+label.msg { display: none; }
+label.invalid { color: #EE0000; display: inline; }
+input.invalid { border: 1px solid #EE0000; }
+
 /* Disables the advanced tab in the table plugin. */
 /*
 #table #advanced_tab {
@@ -317,3 +329,30 @@
 	display: none;
 }
 */
+
+/* Below this line is WordPress customizations */
+#insert, #cancel, .submitbutton {
+	font: 11px Verdana, Arial, Helvetica, sans-serif;
+	height: auto;
+	width: auto;
+	background-color: transparent;
+	background-image: url(../../../../../../wp-admin/images/fade-butt.png);
+	background-repeat: repeat;
+	border: 3px double;
+	border-right-color: rgb(153, 153, 153);
+	border-bottom-color: rgb(153, 153, 153);
+	border-left-color: rgb(204, 204, 204);
+	border-top-color: rgb(204, 204, 204);
+	color: rgb(51, 51, 51);
+	padding: 0.1em 0.5em;
+}
+
+#insert:active, #cancel:active, .submitbutton:active {
+	background: #f4f4f4;
+	border-left-color: #999;
+	border-top-color: #999;
+}
+
+#styleSelectRow {
+	display: none;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/css/editor_ui.css	2007-04-12 12:04:03.000000000 -0500
@@ -1,181 +1,97 @@
 /* This file contains the CSS data for the editor UI of TinyMCE instances */
 
-.mceToolbarTop a, .mceToolbarTop a:visited, .mceToolbarTop a:hover, .mceToolbarBottom a, .mceToolbarBottom a:visited, .mceToolbarBottom a:hover {
-	border: 0px; margin: 0px; padding: 0px; background: transparent;
-}
-
-.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceSeparatorLine, .mceButtonDisabled, .mceButtonSelected {
-	border: 0px; margin: 0px; padding: 0px; background: transparent;
-	margin-top: 1px;
-	margin-left: 1px;
-}
-
-.mceButtonNormal {
-	border-top: 1px solid;
-	border-left: 1px solid;
-	border-bottom: 1px solid;
-	border-right: 1px solid;
-	border-color: #F0F0EE;
-	cursor: arrow;
-}
-
-.mceButtonOver {
-	border: 1px solid #0A246A;
-	cursor: arrow;
-	background-color: #B6BDD2;
-}
-
-.mceButtonDown {
-	cursor: arrow;
-	border: 1px solid #0A246A;
-	background-color: #8592B5;
-}
-
-.mceButtonSelected {
-	border: 1px solid;
-	border-color: #C0C0BB;
-	cursor: arrow;
-}
-
-.mceButtonDisabled {
-	filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);
-	-moz-opacity:0.3;
-	opacity: 0.3;
-	border-top: 1px solid;
-	border-left: 1px solid;
-	border-bottom: 1px solid;
-	border-right: 1px solid;
-	border-color: #F0F0EE;
-	cursor: arrow;
-}
-
-.mceSeparator {
-	border-top: 1px solid buttonhighlight;
-	border-left: 1px solid buttonhighlight;
-	border-bottom: 1px solid buttonshadow;
-	border-right: 1px solid buttonshadow;
-	margin-right: 2px;
-	margin-left: 2px;
-}
-
-.mceSeparatorLine {
-	margin:2px;
-	margin-left: 4px;
-	background-color: #F0F0EE;
-	border-top: 1px solid buttonshadow;
-	border-left: 1px solid buttonshadow;
-	border-bottom: 1px solid buttonhighlight;
-	border-right: 1px solid buttonhighlight;
-	width: 0px;
-	height: 15px;
-}
-
-.mceSelectList {
-	font-family: "MS Sans Serif";
-	font-size: 7pt;
-	font-weight: normal;
-	margin-top: 3px;
-	padding: 0px;
-	display: inline;
-	vertical-align: top;
-	background-color: #F0F0EE
-}
-
-.mceLabel, .mceLabelDisabled {
-	font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
-	font-size: 9pt;
-}
-
-.mceLabel {
-	color: #000000;
-}
-
-.mceLabelDisabled {
-	cursor: text;
-	color: #999999;
-}
-
-.mceEditor {
-	background: #F0F0EE;
-	border: 1px solid #cccccc;
-	padding: 0px;
-	margin: 0px;
-}
-
-.mceEditorArea {
-	font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
-	background: #FFFFFF;
-	padding: 0px;
-	margin: 0px;
-}
-
-.mceToolbarTop, .mceToolbarBottom {
-	background: #F0F0EE;
-	line-height: 1px;
-	font-size: 1px;
-}
-
-.mceToolbarTop {
-	border-bottom: 1px solid #cccccc;
-}
-
-.mceToolbarBottom {
-	border-top: 1px solid #cccccc;
-}
-
-.mceStatusbarTop, .mceStatusbarBottom, .mceStatusbar {
-	height: 20px;
-}
-
-.mceStatusbarTop .mceStatusbarPathText, .mceStatusbarBottom .mceStatusbarPathText, .mceStatusbar .mceStatusbarPathText {
-	font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
-	font-size: 9pt;
-	padding: 2px;
-	line-height: 16px;
-	overflow: visible;
-}
-
-.mceStatusbarTop {
-	border-bottom: 1px solid #cccccc;
-}
-
-.mceStatusbarBottom {
-	border-top: 1px solid #cccccc;
-}
-
-.mceStatusbar {
-	border-bottom: 1px solid #cccccc;
-}
-
-.mcePathItem, .mcePathItem:link, .mcePathItem:visited, .mcePathItem:hover {
-	text-decoration: none;
-	font-family: 'MS Sans Serif', sans-serif, Verdana, Arial;
-	font-size: 9pt;
-	color: #000000;
-}
-
-.mcePathItem:hover {
-	text-decoration: underline;
-}
-
-.mceStatusbarPathText {
-	float: left;
-}
-
-.mceStatusbarResize {
-	float: right;
-	background-image: url('../images/statusbar_resize.gif');
-	background-repeat: no-repeat;
-	width: 11px;
-	height: 20px;
-	cursor: se-resize;
-}
-
-.mceResizeBox {
-	width: 10px;
-	height: 10px;
-	display: none;
-	border: 1px dotted gray;
-	margin: 0px;
-	padding: 0px;
-}
+.mceToolbarTop a, .mceToolbarTop a:visited, .mceToolbarTop a:hover, .mceToolbarBottom a, .mceToolbarBottom a:visited, .mceToolbarBottom a:hover {border: 0; margin: 0; padding: 0; background: transparent;}
+.mceSeparatorLine {border: 0; padding: 0; margin-left: 4px; margin-right: 2px;}
+.mceSelectList {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 7pt !important; font-weight: normal; margin-top: 3px; padding: 0; display: inline; vertical-align: top; background-color: #F0F0EE;}
+.mceLabel, .mceLabelDisabled {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt;}
+.mceLabel {color: #000000;}
+.mceLabelDisabled {cursor: text; color: #999999;}
+.mceEditor {background: #F0F0EE; border: 1px solid #cccccc; padding: 0; margin: 0;}
+.mceEditorArea { font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; background: #FFFFFF; padding: 0; margin: 0; }
+.mceToolbarTop, .mceToolbarBottom {background: #F0F0EE; line-height: 1px; font-size: 1px;}
+.mceToolbarTop {border-bottom: 1px solid #cccccc; padding-bottom: 1px;}
+.mceToolbarBottom {border-top: 1px solid #cccccc;}
+.mceToolbarContainer {display: block; position: relative; left: 0; top: 0; width: 100%;}
+.mceStatusbarTop, .mceStatusbarBottom, .mceStatusbar {height: 20px;}
+.mceStatusbarTop .mceStatusbarPathText, .mceStatusbarBottom .mceStatusbarPathText, .mceStatusbar .mceStatusbarPathText {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt; padding: 2px; line-height: 16px; overflow: visible;}
+.mceStatusbarTop {border-bottom: 1px solid #cccccc;}
+.mceStatusbarBottom {border-top: 1px solid #cccccc;}
+.mceStatusbar {border-bottom: 1px solid #cccccc;}
+.mcePathItem, .mcePathItem:link, .mcePathItem:visited, .mcePathItem:hover {text-decoration: none; font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt; color: #000000;}
+.mcePathItem:hover {text-decoration: underline;}
+.mceStatusbarPathText {float: left;}
+.mceStatusbarResize {float: right; background-image: url('../images/statusbar_resize.gif'); background-repeat: no-repeat; width: 11px; height: 20px; cursor: se-resize;}
+.mceResizeBox {width: 10px; height: 10px; display: none; border: 1px dotted gray; margin: 0; padding: 0;}
+.mceEditorIframe {border: 0;}
+
+/* Button CSS rules */
+
+a.mceButtonDisabled img, a.mceButtonNormal img, a.mceButtonSelected img {width: 20px; height: 20px; cursor: default; margin-top: 1px; margin-left: 1px;}
+a.mceButtonDisabled img {border: 0 !important;}
+a.mceButtonNormal img, a.mceButtonSelected img {border: 1px solid #F0F0EE !important;}
+a.mceButtonSelected img {border: 1px solid #6779AA !important; background-color: #D4D5D8;}
+a.mceButtonNormal img:hover, a.mceButtonSelected img:hover {border: 1px solid #0A246A !important; cursor: default; background-color: #B6BDD2;}
+a.mceButtonDisabled img {-moz-opacity:0.3; opacity: 0.3; border: 1px solid #F0F0EE !important; cursor: default;}
+a.mceTiledButton img {background-image: url('../images/buttons.gif'); background-repeat: no-repeat;}
+
+/* Menu button CSS rules */
+
+span.mceMenuButton img, span.mceMenuButtonSelected img {border: 1px solid #F0F0EE; margin-left: 1px;}
+span.mceMenuButtonSelected img {border: 1px solid #6779AA; background-color: #B6BDD2;}
+span.mceMenuButtonSelected img.mceMenuButton {border: 1px solid #F0F0EE; background-color: transparent;}
+span.mceMenuButton img.mceMenuButton, span.mceMenuButtonSelected img.mceMenuButton {border-left: 0; margin-left: 0;}
+span.mceMenuButton:hover img, span.mceMenuButtonSelected:hover img {border: 1px solid #0A246A; background-color: #B6BDD2;}
+span.mceMenuButton:hover img.mceMenuButton, span.mceMenuButtonSelected:hover img.mceMenuButton {border-left: 0;}
+span.mceMenuButtonFocus img {border: 1px solid gray; border-right: 0; margin-left: 1px; background-color: #F5F4F2;}
+span.mceMenuButtonFocus img.mceMenuButton {border: 1px solid gray; border-left: 1px solid #F5F4F2; margin-left: 0;}
+span.mceMenuHover img {border: 1px solid #0A246A; background-color: #B6BDD2;}
+span.mceMenuButtonSelected.mceMenuHover img.mceMenuButton {border: 1px solid #0A246A; background-color: #B6BDD2; border-left: 0;}
+
+/* Menu */
+
+.mceMenu {position: absolute; left: 0; top: 0; display: none; z-index: 1000; background-color: white; border: 1px solid gray; font-weight: normal;}
+.mceMenu a, .mceMenuTitle, .mceMenuDisabled {display: block; width: 100%; text-decoration: none; background-color: white; font-family: Tahoma, Verdana, Arial, Helvetica; font-size: 11px; line-height: 20px; color: black;}
+.mceMenu a:hover {background-color: #B6BDD2; color: black; text-decoration: none !important;}
+.mceMenu span {padding-left: 10px; padding-right: 10px; display: block; line-height: 20px;}
+.mceMenuSeparator {border-bottom: 1px solid gray; background-color: gray; height: 1px;}
+.mceMenuTitle span {padding-left: 5px;}
+.mceMenuTitle {background-color: #DDDDDD; font-weight: bold;}
+.mceMenuDisabled {color: gray;}
+span.mceMenuSelectedItem {background-image: url('../images/menu_check.gif'); background-repeat: no-repeat; background-position: 5px 8px; padding-left: 20px;}
+span.mceMenuCheckItem {padding-left: 20px;}
+span.mceMenuLine {display: block; position: absolute; left: 0; top: -1px; background-color: #F5F4F2; width: 30px; height: 1px; overflow: hidden; padding-left: 0; padding-right: 0;}
+.mceColors table, .mceColors td {margin: 0; padding: 2px;}
+a.mceMoreColors {width: auto; padding: 0; margin: 0 3px 3px 3px; text-align: center; border: 1px solid white; text-decoration: none !important;}
+.mceColorPreview {position: absolute; overflow:hidden; left: 0; top: 0; margin-left: 3px; margin-top: 15px; width: 16px; height: 4px; background-color: red;}
+a.mceMoreColors:hover {border: 1px solid #0A246A;}
+.mceColors td a {width: 9px; height: 9px; overflow: hidden; border: 1px solid #808080;}
+
+/* MSIE 6 specific rules */
+
+* html a.mceButtonNormal img, * html a.mceButtonSelected img, * html a.mceButtonDisabled img {border: 0 !important; margin-top: 2px; margin-bottom: 1px;}
+* html a.mceButtonDisabled img {filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); border: 0 !important;}
+* html a.mceButtonDisabled {border: 1px solid #F0F0EE !important;}
+* html a.mceButtonNormal, * html a.mceButtonSelected {border: 1px solid #F0F0EE !important; cursor: default;}
+* html a.mceButtonSelected {border: 1px solid #6779AA !important; background-color: #D4D5D8;}
+* html a.mceButtonNormal:hover, * html a.mceButtonSelected:hover {border: 1px solid #0A246A !important; background-color: #B6BDD2; cursor: default;}
+* html .mceSelectList {margin-top: 2px;}
+* html span.mceMenuButton, * html span.mceMenuButtonFocus {position: relative; left: 0; top: 0;}
+* html span.mceMenuButton img, * html span.mceMenuButtonSelected img, * html span.mceMenuButtonFocus img {position: relative; top: 1px;}
+* html a.mceMoreColors {width: auto;}
+* html .mceColors td a {width: 10px; height: 10px;}
+* html .mceColorPreview {margin-left: 2px; margin-top: 14px;}
+
+/* MSIE 7 specific rules */
+
+*:first-child+html a.mceButtonNormal img, *:first-child+html a.mceButtonSelected img, *:first-child+html a.mceButtonDisabled img {border: 0 !important; margin-top: 2px; margin-bottom: 1px;}
+*:first-child+html a.mceButtonDisabled img {filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); border: 0 !important;}
+*:first-child+html a.mceButtonDisabled {border: 1px solid #F0F0EE !important;}
+*:first-child+html a.mceButtonNormal, *:first-child+html a.mceButtonSelected {border: 1px solid #F0F0EE !important; cursor: default;}
+*:first-child+html a.mceButtonSelected {border: 1px solid #6779AA !important; background-color: #D4D5D8;}
+*:first-child+html a.mceButtonNormal:hover, *:first-child+html a.mceButtonSelected:hover {border: 1px solid #0A246A !important; background-color: #B6BDD2; cursor: default;}
+*:first-child+html .mceSelectList {margin-top: 2px;}
+*:first-child+html span.mceMenuButton, *:first-child+html span.mceMenuButtonFocus {position: relative; left: 0; top: 0;}
+*:first-child+html span.mceMenuButton img, *:first-child+html span.mceMenuButtonSelected img, *:first-child+html span.mceMenuButtonFocus img {position: relative; top: 1px;}
+*:first-child+html a.mceMoreColors {width: 137px;}
+*:first-child+html .mceColors td a {width: 10px; height: 10px;}
+*:first-child+html .mceColorPreview {margin: 0; padding-left: 4px; margin-top: 14px; width: 14px;}
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/editor_template.js 2.2.2/wp-includes/js/tinymce/themes/advanced/editor_template.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/editor_template.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/editor_template.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,13 +1,1579 @@
+/**
+ * $Id: editor_template_src.js 218 2007-02-13 11:08:01Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
 /* Import theme specific language pack */
- tinyMCE.importThemeLanguagePack('advanced');var TinyMCE_advanced_autoImportCSSClasses=true;var TinyMCE_advanced_resizer=new Object();var TinyMCE_advanced_buttons=[['bold','{$lang_bold_img}','{$lang_bold_desc}','Bold'],['italic','{$lang_italic_img}','{$lang_italic_desc}','Italic'],['underline','{$lang_underline_img}','{$lang_underline_desc}','Underline'],['strikethrough','strikethrough.gif','{$lang_striketrough_desc}','Strikethrough'],['justifyleft','left.gif','{$lang_justifyleft_desc}','JustifyLeft'],['justifycenter','center.gif','{$lang_justifycenter_desc}','JustifyCenter'],['justifyright','right.gif','{$lang_justifyright_desc}','JustifyRight'],['justifyfull','full.gif','{$lang_justifyfull_desc}','JustifyFull'],['bullist','bullist.gif','{$lang_bullist_desc}','InsertUnorderedList'],['numlist','numlist.gif','{$lang_numlist_desc}','InsertOrderedList'],['outdent','outdent.gif','{$lang_outdent_desc}','Outdent'],['indent','indent.gif','{$lang_indent_desc}','Indent'],['cut','cut.gif','{$lang_cut_desc}','Cut'],['copy','copy.gif','{$lang_copy_desc}','Copy'],['paste','paste.gif','{$lang_paste_desc}','Paste'],['undo','undo.gif','{$lang_undo_desc}','Undo'],['redo','redo.gif','{$lang_redo_desc}','Redo'],['link','link.gif','{$lang_link_desc}','mceLink',true],['unlink','unlink.gif','{$lang_unlink_desc}','unlink'],['image','image.gif','{$lang_image_desc}','mceImage',true],['cleanup','cleanup.gif','{$lang_cleanup_desc}','mceCleanup'],['help','help.gif','{$lang_help_desc}','mceHelp'],['code','code.gif','{$lang_theme_code_desc}','mceCodeEditor'],['hr','hr.gif','{$lang_theme_hr_desc}','inserthorizontalrule'],['removeformat','removeformat.gif','{$lang_theme_removeformat_desc}','removeformat'],['sub','sub.gif','{$lang_theme_sub_desc}','subscript'],['sup','sup.gif','{$lang_theme_sup_desc}','superscript'],['forecolor','forecolor.gif','{$lang_theme_forecolor_desc}','mceForeColor',true],['backcolor','backcolor.gif','{$lang_theme_backcolor_desc}','mceBackColor',true],['charmap','charmap.gif','{$lang_theme_charmap_desc}','mceCharMap'],['visualaid','visualaid.gif','{$lang_theme_visualaid_desc}','mceToggleVisualAid'],['anchor','anchor.gif','{$lang_theme_anchor_desc}','mceInsertAnchor'],['newdocument','newdocument.gif','{$lang_newdocument_desc}','mceNewDocument']];function TinyMCE_advanced_getControlHTML(button_name){var buttonTileMap=new Array('anchor.gif','backcolor.gif','bullist.gif','center.gif','charmap.gif','cleanup.gif','code.gif','copy.gif','custom_1.gif','cut.gif','forecolor.gif','full.gif','help.gif','hr.gif','image.gif','indent.gif','left.gif','link.gif','numlist.gif','outdent.gif','paste.gif','redo.gif','removeformat.gif','right.gif','strikethrough.gif','sub.gif','sup.gif','undo.gif','unlink.gif','visualaid.gif');for(var i=0;i<TinyMCE_advanced_buttons.length;i++){var but=TinyMCE_advanced_buttons[i];if(but[0]==button_name){if(tinyMCE.settings['button_tile_map']){for(var x=0;!tinyMCE.isMSIE&&x<buttonTileMap.length;x++){if(buttonTileMap[x]==but[1]){var cmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+but[3]+'\','+(but.length>4?but[4]:false)+(but.length>5?',\''+but[5]+'\'':'')+')';return '<a href="javascript:'+cmd+'" onclick="'+cmd+';return false;" onmousedown="return false;" target="_self"><img id="{$editor_id}_'+but[0]+'" src="{$themeurl}/images/spacer.gif" style="background-image:url({$themeurl}/images/buttons.gif); background-position: '+(0-(x*20))+'px 0px" title="'+but[2]+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';}}}var cmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+but[3]+'\','+(but.length>4?but[4]:false)+(but.length>5?',\''+but[5]+'\'':'')+')';return '<a href="javascript:'+cmd+'" onclick="'+cmd+';return false;" onmousedown="return false;" target="_self"><img id="{$editor_id}_'+but[0]+'" src="{$themeurl}/images/'+but[1]+'" title="'+but[2]+'" width="20" height="20" class="mceButtonNormal" onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');" onmouseout="tinyMCE.restoreClass(this);" onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');" /></a>';}}switch(button_name){case "formatselect":var html='<select id="{$editor_id}_formatSelect" name="{$editor_id}_formatSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FormatBlock\',false,this.options[this.selectedIndex].value);" class="mceSelectList">';var formats=tinyMCE.getParam("theme_advanced_blockformats","p,address,pre,h1,h2,h3,h4,h5,h6",true).split(',');var lookup=[['p','{$lang_theme_paragraph}'],['address','{$lang_theme_address}'],['pre','{$lang_theme_pre}'],['h1','{$lang_theme_h1}'],['h2','{$lang_theme_h2}'],['h3','{$lang_theme_h3}'],['h4','{$lang_theme_h4}'],['h5','{$lang_theme_h5}'],['h6','{$lang_theme_h6}']];html+='<option value="">{$lang_theme_block}</option>';for(var i=0;i<formats.length;i++){for(var x=0;x<lookup.length;x++){if(formats[i]==lookup[x][0]){html+='<option value="<'+lookup[x][0]+'>">'+lookup[x][1]+'</option>';}}}html+='</select>';return html;case "styleselect":return '<select id="{$editor_id}_styleSelect" onmousedown="TinyMCE_advanced_setupCSSClasses(\'{$editor_id}\');" name="{$editor_id}_styleSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceSetCSSClass\',false,this.options[this.selectedIndex].value);" class="mceSelectList">{$style_select_options}</select>';case "fontselect":var fontHTML='<select id="{$editor_id}_fontNameSelect" name="{$editor_id}_fontNameSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontName\',false,this.options[this.selectedIndex].value);" class="mceSelectList"><option value="">{$lang_theme_fontdefault}</option>';var iFonts='Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings';var nFonts='Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sand;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats';var fonts=tinyMCE.getParam("theme_advanced_fonts",nFonts).split(';');for(var i=0;i<fonts.length;i++){if(fonts[i]!=''){var parts=fonts[i].split('=');fontHTML+='<option value="'+parts[1]+'">'+parts[0]+'</option>';}}fontHTML+='</select>';return fontHTML;case "fontsizeselect":return '<select id="{$editor_id}_fontSizeSelect" name="{$editor_id}_fontSizeSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontSize\',false,this.options[this.selectedIndex].value);" class="mceSelectList">\
-		<option value="0">{$lang_theme_font_size}</option>\
-		<option value="1">1 (8 pt)</option>\
-		<option value="2">2 (10 pt)</option>\
-		<option value="3">3 (12 pt)</option>\
-		<option value="4">4 (14 pt)</option>\
-		<option value="5">5 (18 pt)</option>\
-		<option value="6">6 (24 pt)</option>\
-		<option value="7">7 (36 pt)</option>\
-		</select>';case "|":case "separator":return '<img src="{$themeurl}/images/spacer.gif" width="1" height="15" class="mceSeparatorLine">';case "spacer":return '<img src="{$themeurl}/images/spacer.gif" width="1" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" />';case "rowseparator":return '<br />';}return "";}function TinyMCE_advanced_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceForeColor":var template=new Array();var elm=tinyMCE.selectedInstance.getFocusElement();var inputColor=tinyMCE.getAttrib(elm,"color");if(inputColor=='')inputColor=elm.style.color;if(!inputColor)inputColor="#000000";template['file']='color_picker.htm';template['width']=220;template['height']=190;tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes",command:"forecolor",input_color:inputColor});return true;case "mceBackColor":var template=new Array();var elm=tinyMCE.selectedInstance.getFocusElement();var inputColor=elm.style.backgroundColor;if(!inputColor)inputColor="#000000";template['file']='color_picker.htm';template['width']=220;template['height']=190;template['width']+=tinyMCE.getLang('lang_theme_advanced_backcolor_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_backcolor_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes",command:"HiliteColor",input_color:inputColor});return true;case "mceColorPicker":if(user_interface){var template=new Array();var inputColor=value['document'].getElementById(value['element_id']).value;template['file']='color_picker.htm';template['width']=220;template['height']=190;template['close_previous']="no";template['width']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height',0);if(typeof(value['store_selection'])=="undefined")value['store_selection']=true;tinyMCE.lastColorPickerValue=value;tinyMCE.openWindow(template,{editor_id:editor_id,mce_store_selection:value['store_selection'],inline:"yes",command:"mceColorPicker",input_color:inputColor});}else{var savedVal=tinyMCE.lastColorPickerValue;var elm=savedVal['document'].getElementById(savedVal['element_id']);elm.value=value;eval('elm.onchange();');}return true;case "mceCodeEditor":var template=new Array();template['file']='source_editor.htm';template['width']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_width",500));template['height']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_height",400));tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"no",inline:"yes"});return true;case "mceCharMap":var template=new Array();template['file']='charmap.htm';template['width']=550+(tinyMCE.isOpera?40:0);template['height']=250;template['width']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case "mceInsertAnchor":var template=new Array();template['file']='anchor.htm';template['width']=320;template['height']=90+(tinyMCE.isNS7?30:0);template['width']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case "mceNewDocument":if(confirm(tinyMCE.getLang('lang_newdocument')))tinyMCE.execInstanceCommand(editor_id,'mceSetContent',false,'');return true;}return false;}function TinyMCE_advanced_getEditorTemplate(settings,editorId){function removeFromArray(in_array,remove_array){var outArray=new Array();for(var i=0;i<in_array.length;i++){skip=false;for(var j=0;j<remove_array.length;j++){if(in_array[i]==remove_array[j]){skip=true;}}if(!skip){outArray[outArray.length]=in_array[i];}}return outArray;}function addToArray(in_array,add_array){for(var i=0;i<add_array.length;i++){in_array[in_array.length]=add_array[i];}return in_array;}var template=new Array();var deltaHeight=0;var resizing=tinyMCE.getParam("theme_advanced_resizing",false);var path=tinyMCE.getParam("theme_advanced_path",true);var statusbarHTML='<div id="{$editor_id}_path" class="mceStatusbarPathText" style="display: '+(path?"block":"none")+'">&nbsp;</div><div id="{$editor_id}_resize" class="mceStatusbarResize" style="display: '+(resizing?"block":"none")+'" onmousedown="TinyMCE_advanced_setResizing(event,\'{$editor_id}\',true);"></div><br style="clear: both" />';var layoutManager=tinyMCE.getParam("theme_advanced_layout_manager","SimpleLayout");var styleSelectHTML='<option value="">{$lang_theme_style_select}</option>';if(settings['theme_advanced_styles']){var stylesAr=settings['theme_advanced_styles'].split(';');for(var i=0;i<stylesAr.length;i++){var key,value;key=stylesAr[i].split('=')[0];value=stylesAr[i].split('=')[1];styleSelectHTML+='<option value="'+value+'">'+key+'</option>';}TinyMCE_advanced_autoImportCSSClasses=false;}switch(layoutManager){case "SimpleLayout":var toolbarHTML="";var toolbarLocation=tinyMCE.getParam("theme_advanced_toolbar_location","bottom");var toolbarAlign=tinyMCE.getParam("theme_advanced_toolbar_align","center");var pathLocation=tinyMCE.getParam("theme_advanced_path_location","none");var statusbarLocation=tinyMCE.getParam("theme_advanced_statusbar_location",pathLocation);var defVals={theme_advanced_buttons1:"bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,separator,sub,sup,separator,charmap"};/*toolbarHTML+='<a href="#" accesskey="q" title="'+tinyMCE.getLang("lang_toolbar_focus")+'"></a>';*/for(var i=1;i<100;i++){var def=defVals["theme_advanced_buttons"+i];var buttons=tinyMCE.getParam("theme_advanced_buttons"+i,def==null?'':def,true,',');if(buttons.length==0)break;buttons=removeFromArray(buttons,tinyMCE.getParam("theme_advanced_disable","",true,','));buttons=addToArray(buttons,tinyMCE.getParam("theme_advanced_buttons"+i+"_add","",true,','));buttons=addToArray(tinyMCE.getParam("theme_advanced_buttons"+i+"_add_before","",true,','),buttons);for(var b=0;b<buttons.length;b++)toolbarHTML+=tinyMCE.getControlHTML(buttons[b]);if(buttons.length>0){toolbarHTML+="<br />";deltaHeight-=23;}}toolbarHTML+='<a href="#" accesskey="z" onfocus="tinyMCE.getInstanceById(\''+editorId+'\').getWin().focus();"></a>';template['html']='<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';if(toolbarLocation=="top"){template['html']+='<tr><td class="mceToolbarTop" align="'+toolbarAlign+'" height="1" nowrap="nowrap">'+toolbarHTML+'</td></tr>';}if(statusbarLocation=="top"){template['html']+='<tr><td class="mceStatusbarTop" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=23;}template['html']+='<tr><td align="center"><span id="{$editor_id}"></span></td></tr>';if(toolbarLocation=="bottom"){template['html']+='<tr><td class="mceToolbarBottom" align="'+toolbarAlign+'" height="1">'+toolbarHTML+'</td></tr>';}if(toolbarLocation=="external"){var bod=document.body;var elm=document.createElement("div");toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCE.settings);toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCELang);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,'style_select_options',styleSelectHTML);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,"editor_id",editorId);toolbarHTML=tinyMCE.applyTemplate(toolbarHTML);elm.className="mceToolbarExternal";elm.id=editorId+"_toolbar";elm.innerHTML='<table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table>';bod.appendChild(elm);deltaHeight=0;tinyMCE.getInstanceById(editorId).toolbarElement=elm;}else{tinyMCE.getInstanceById(editorId).toolbarElement=null;}if(statusbarLocation=="bottom"){template['html']+='<tr><td class="mceStatusbarBottom" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=23;}template['html']+='</tbody></table>';break;case "RowLayout":template['html']='<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';var containers=tinyMCE.getParam("theme_advanced_containers","",true,",");var defaultContainerCSS=tinyMCE.getParam("theme_advanced_containers_default_class","container");var defaultContainerAlign=tinyMCE.getParam("theme_advanced_containers_default_align","center");for(var i=0;i<containers.length;i++){if(containers[i]=="mceEditor"){template['html']+='<tr><td align="center" class="mceEditor_border">\
-												<span id="{$editor_id}"></span>\
-												</td></tr>';}else if(containers[i]=="mceElementpath"||containers[i]=="mceStatusbar"){var pathClass="mceStatusbar";if(i==containers.length-1){pathClass="mceStatusbarBottom";}else if(i==0){pathClass="mceStatusbar";}else{deltaHeight-=2;}template['html']+='<tr><td class="'+pathClass+'" height="1">'+statusbarHTML+'</td></tr>';deltaHeight-=22;}else{var curContainer=tinyMCE.getParam("theme_advanced_container_"+containers[i],"",true,',');var curContainerHTML="";var curAlign=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align",defaultContainerAlign);var curCSS=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class",defaultContainerCSS);for(var j=0;j<curContainer.length;j++){curContainerHTML+=tinyMCE.getControlHTML(curContainer[j]);}if(curContainer.length>0){curContainerHTML+="<br />";deltaHeight-=23;}template['html']+='<tr><td class="'+curCSS+'" align="'+curAlign+'" height="1">'+curContainerHTML+'</td></tr>';}}template['html']+='</tbody></table>';break;case "BorderLayout":break;case "CustomLayout":var customLayout=tinyMCE.getParam("theme_advanced_custom_layout","");if(customLayout!=""&&eval("typeof("+customLayout+")")!="undefined"){template=eval(customLayout+"(template);");}break;default:alert('UNDEFINED LAYOUT MANAGER! PLEASE CHECK YOUR TINYMCE CONFIG!');break;}template['html']+='<div id="{$editor_id}_resize_box" class="mceResizeBox"></div>';template['html']=tinyMCE.replaceVar(template['html'],'style_select_options',styleSelectHTML);template['delta_width']=0;template['delta_height']=deltaHeight;return template;}function TinyMCE_advanced_setResizing(e,editor_id,state){e=typeof(e)=="undefined"?window.event:e;var resizer=TinyMCE_advanced_resizer;var editorContainer=document.getElementById(editor_id+'_parent');var editorArea=document.getElementById(editor_id+'_parent').firstChild;var resizeBox=document.getElementById(editor_id+'_resize_box');var inst=tinyMCE.getInstanceById(editor_id);if(state){var width=editorArea.clientWidth;var height=editorArea.clientHeight;resizeBox.style.width=width+"px";resizeBox.style.height=height+"px";resizer.iframeWidth=inst.iframeElement.clientWidth;resizer.iframeHeight=inst.iframeElement.clientHeight;editorArea.style.display="none";resizeBox.style.display="block";if(!resizer.eventHandlers){if(tinyMCE.isMSIE)tinyMCE.addEvent(document,"mousemove",TinyMCE_advanced_resizeEventHandler);else tinyMCE.addEvent(window,"mousemove",TinyMCE_advanced_resizeEventHandler);tinyMCE.addEvent(document,"mouseup",TinyMCE_advanced_resizeEventHandler);resizer.eventHandlers=true;}resizer.resizing=true;resizer.downX=e.screenX;resizer.downY=e.screenY;resizer.width=parseInt(resizeBox.style.width);resizer.height=parseInt(resizeBox.style.height);resizer.editorId=editor_id;resizer.resizeBox=resizeBox;resizer.horizontal=tinyMCE.getParam("theme_advanced_resize_horizontal",true);}else{resizer.resizing=false;resizeBox.style.display="none";editorArea.style.display=tinyMCE.isMSIE?"block":"table";tinyMCE.execCommand('mceResetDesignMode');}}function TinyMCE_advanced_initInstance(inst){if(tinyMCE.getParam("theme_advanced_resizing",false)){if(tinyMCE.getParam("theme_advanced_resizing_use_cookie",true)){var w=TinyMCE_advanced_getCookie("TinyMCE_"+inst.editorId+"_width");var h=TinyMCE_advanced_getCookie("TinyMCE_"+inst.editorId+"_height");TinyMCE_advanced_resizeTo(inst,w,h,tinyMCE.getParam("theme_advanced_resize_horizontal",true));}}}function TinyMCE_advanced_setCookie(name,value,expires,path,domain,secure){var curCookie=name+"="+escape(value)+((expires)?"; expires="+expires.toGMTString():"")+((path)?"; path="+escape(path):"")+((domain)?"; domain="+domain:"")+((secure)?"; secure":"");document.cookie=curCookie;}function TinyMCE_advanced_getCookie(name){var dc=document.cookie;var prefix=name+"=";var begin=dc.indexOf("; "+prefix);if(begin==-1){begin=dc.indexOf(prefix);if(begin!=0)return null;}else begin+=2;var end=document.cookie.indexOf(";",begin);if(end==-1)end=dc.length;return unescape(dc.substring(begin+prefix.length,end));}function TinyMCE_advanced_resizeTo(inst,w,h,set_w){var editorContainer=document.getElementById(inst.editorId+'_parent');var tableElm=editorContainer.firstChild;var iframe=inst.iframeElement;if(w==null||w=="null"){set_w=false;w=0;}if(h==null||h=="null")return;w=parseInt(w);h=parseInt(h);if(tinyMCE.isGecko){w+=2;h+=2;}var dx=w-tableElm.clientWidth;var dy=h-tableElm.clientHeight;if(set_w)tableElm.style.width=w+"px";tableElm.style.height=h+"px";iw=iframe.clientWidth+dx;ih=iframe.clientHeight+dy;if(tinyMCE.isGecko){iw-=2;ih-=2;}if(set_w)iframe.style.width=iw+"px";iframe.style.height=ih+"px";if(set_w){var tableBodyElm=tableElm.firstChild;var minIframeWidth=tableBodyElm.scrollWidth;if(inst.iframeElement.clientWidth<minIframeWidth){dx=minIframeWidth-inst.iframeElement.clientWidth;inst.iframeElement.style.width=(iw+dx)+"px";}}}function TinyMCE_advanced_resizeEventHandler(e){var resizer=TinyMCE_advanced_resizer;if(!resizer.resizing)return;e=typeof(e)=="undefined"?window.event:e;var dx=e.screenX-resizer.downX;var dy=e.screenY-resizer.downY;var resizeBox=resizer.resizeBox;var editorId=resizer.editorId;switch(e.type){case "mousemove":if(resizer.horizontal)resizeBox.style.width=(resizer.width+dx)+"px";resizeBox.style.height=(resizer.height+dy)+"px";break;case "mouseup":TinyMCE_advanced_setResizing(e,editorId,false);TinyMCE_advanced_resizeTo(tinyMCE.getInstanceById(editorId),resizer.width+dx,resizer.height+dy,resizer.horizontal);if(tinyMCE.getParam("theme_advanced_resizing_use_cookie",true)){var expires=new Date();expires.setTime(expires.getTime()+3600000*24*30);TinyMCE_advanced_setCookie("TinyMCE_"+editorId+"_width",""+(resizer.horizontal?resizer.width+dx:""),expires);TinyMCE_advanced_setCookie("TinyMCE_"+editorId+"_height",""+(resizer.height+dy),expires);}break;}}function TinyMCE_advanced_getInsertLinkTemplate(){var template=new Array();template['file']='link.htm';template['width']=330;template['height']=160;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);return template;};function TinyMCE_advanced_getInsertImageTemplate(){var template=new Array();template['file']='image.htm?src={$src}';template['width']=340;template['height']=165;template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);return template;};function TinyMCE_advanced_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection,setup_content){function selectByValue(select_elm,value,first_index){first_index=typeof(first_index)=="undefined"?false:true;if(select_elm){for(var i=0;i<select_elm.options.length;i++){var ov=""+select_elm.options[i].value;if(first_index&&ov.toLowerCase().indexOf(value.toLowerCase())==0){select_elm.selectedIndex=i;return true;}if(ov==value){select_elm.selectedIndex=i;return true;}}}return false;};function getAttrib(elm,name){return elm.getAttribute(name)?elm.getAttribute(name):"";};if(node==null){return;}var pathElm=document.getElementById(editor_id+"_path");var inst=tinyMCE.getInstanceById(editor_id);var doc=inst.getDoc();if(pathElm){var parentNode=node;var path=new Array();while(parentNode!=null){if(parentNode.nodeName.toUpperCase()=="BODY"){break;}if(parentNode.nodeType==1){path[path.length]=parentNode;}parentNode=parentNode.parentNode;}var html="";for(var i=path.length-1;i>=0;i--){var nodeName=path[i].nodeName.toLowerCase();var nodeData="";if(nodeName=="b"){nodeName="strong";}if(nodeName=="i"){nodeName="em";}if(nodeName=="span"){var cn=tinyMCE.getAttrib(path[i],"class");if(cn!=""&&cn.indexOf('mceItem')==-1)nodeData+="class: "+cn+" ";var st=tinyMCE.getAttrib(path[i],"style");if(st!=""){st=tinyMCE.serializeStyle(tinyMCE.parseStyle(st));nodeData+="style: "+st+" ";}}if(nodeName=="font"){if(tinyMCE.getParam("convert_fonts_to_spans"))nodeName="span";var face=tinyMCE.getAttrib(path[i],"face");if(face!="")nodeData+="font: "+face+" ";var size=tinyMCE.getAttrib(path[i],"size");if(size!="")nodeData+="size: "+size+" ";var color=tinyMCE.getAttrib(path[i],"color");if(color!="")nodeData+="color: "+color+" ";}if(getAttrib(path[i],'id')!=""){nodeData+="id: "+path[i].getAttribute('id')+" ";}var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1)nodeData+="class: "+className+" ";if(getAttrib(path[i],'src')!=""){nodeData+="src: "+path[i].getAttribute('src')+" ";}if(getAttrib(path[i],'href')!=""){nodeData+="href: "+path[i].getAttribute('href')+" ";}if(nodeName=="img"&&tinyMCE.getAttrib(path[i],"class").indexOf('mceItemFlash')!=-1){nodeName="flash";nodeData="src: "+path[i].getAttribute('title');}if(nodeName=="a"&&(anchor=tinyMCE.getAttrib(path[i],"name"))!=""){nodeName="a";nodeName+="#"+anchor;nodeData="";}if(getAttrib(path[i],'name').indexOf("mce_")!=0){var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1){nodeName+="."+className;}}var cmd='tinyMCE.execInstanceCommand(\''+editor_id+'\',\'mceSelectNodeDepth\',false,\''+i+'\');';html+='<a title="'+nodeData+'" href="javascript:'+cmd+'" onclick="'+cmd+'return false;" onmousedown="return false;" target="_self" class="mcePathItem">'+nodeName+'</a>';if(i>0){html+=" &raquo; ";}}pathElm.innerHTML='<a href="#" accesskey="x"></a>'+tinyMCE.getLang('lang_theme_path')+": "+html+'&nbsp;';}tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sub','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sup','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_link','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_unlink','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_image','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonNormal');if(node.nodeName=="A"&&tinyMCE.getAttrib(node,"class").indexOf('mceItemAnchor')!=-1)tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonSelected');var anchorLink=tinyMCE.getParentElement(node,"a","href");if(anchorLink||any_selection){tinyMCE.switchClassSticky(editor_id+'_link',anchorLink?'mceButtonSelected':'mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_unlink',anchorLink?'mceButtonSelected':'mceButtonNormal',false);}tinyMCE.switchClassSticky(editor_id+'_visualaid',visual_aid?'mceButtonSelected':'mceButtonNormal',false);if(undo_levels!=-1){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonDisabled',true);}if(tinyMCE.getParentElement(node,"li,blockquote")){tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index<undo_levels-1&&undo_levels>0)){tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index>0&&undo_levels>0)){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonNormal',false);}var selectElm=document.getElementById(editor_id+"_styleSelect");if(selectElm){TinyMCE_advanced_setupCSSClasses(editor_id);classNode=node;breakOut=false;var index=0;do{if(classNode&&classNode.className){for(var i=0;i<selectElm.options.length;i++){if(selectElm.options[i].value==classNode.className){index=i;breakOut=true;break;}}}}while(!breakOut&&classNode!=null&&(classNode=classNode.parentNode)!=null);selectElm.selectedIndex=index;}var selectElm=document.getElementById(editor_id+"_formatSelect");if(selectElm){var elm=tinyMCE.getParentElement(node,"p,div,h1,h2,h3,h4,h5,h6,pre,address");if(elm){selectByValue(selectElm,"<"+elm.nodeName.toLowerCase()+">");}else{selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontNameSelect");if(selectElm){if(!tinyMCE.isSafari&&!(tinyMCE.isMSIE&&!tinyMCE.isOpera)){var face=doc.queryCommandValue('FontName');face=face==null||face==""?"":face;selectByValue(selectElm,face,face!="");}else{var elm=tinyMCE.getParentElement(node,"font","face");if(elm){var family=tinyMCE.getAttrib(elm,"face");if(family=='')family=''+elm.style.fontFamily;if(!selectByValue(selectElm,family,family!=""))selectByValue(selectElm,"");}else selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontSizeSelect");if(selectElm){if(!tinyMCE.isSafari&&!tinyMCE.isOpera){var size=doc.queryCommandValue('FontSize');selectByValue(selectElm,size==null||size==""?"0":size);}else{var elm=tinyMCE.getParentElement(node,"font","size");if(elm){var size=tinyMCE.getAttrib(elm,"size");if(size==''){var sizes=new Array('','8px','10px','12px','14px','18px','24px','36px');size=''+elm.style.fontSize;for(var i=0;i<sizes.length;i++){if((''+sizes[i])==size){size=i;break;}}}if(!selectByValue(selectElm,size))selectByValue(selectElm,"");}else selectByValue(selectElm,"0");}}alignNode=node;breakOut=false;do{if(!alignNode.getAttribute||!alignNode.getAttribute('align')){continue;}switch(alignNode.getAttribute('align').toLowerCase()){case "left":tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonSelected');breakOut=true;break;case "right":tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonSelected');breakOut=true;break;case "middle":case "center":tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonSelected');breakOut=true;break;case "justify":tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonSelected');breakOut=true;break;}}while(!breakOut&&(alignNode=alignNode.parentNode)!=null);var div=tinyMCE.getParentElement(node,"div");if(div&&div.style.textAlign=="center")tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonSelected');if(!setup_content){var ar=new Array("Bold","_bold","Italic","_italic","Strikethrough","_strikethrough","superscript","_sup","subscript","_sub");for(var i=0;i<ar.length;i+=2){if(doc.queryCommandState(ar[i]))tinyMCE.switchClassSticky(editor_id+ar[i+1],'mceButtonSelected');}if(doc.queryCommandState("Underline")&&(node.parentNode==null||node.parentNode.nodeName!="A")){tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');}}do{switch(node.nodeName){case "UL":tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonSelected');break;case "OL":tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonSelected');break;case "HR":tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonSelected');break;case "IMG":if(getAttrib(node,'name').indexOf('mce_')!=0){tinyMCE.switchClassSticky(editor_id+'_image','mceButtonSelected');}break;}}while((node=node.parentNode)!=null);};function TinyMCE_advanced_setupCSSClasses(editor_id){if(!TinyMCE_advanced_autoImportCSSClasses){return;}var selectElm=document.getElementById(editor_id+'_styleSelect');if(selectElm&&selectElm.getAttribute('cssImported')!='true'){var csses=tinyMCE.getCSSClasses(editor_id);if(csses&&selectElm){for(var i=0;i<csses.length;i++){selectElm.options[selectElm.length]=new Option(csses[i],csses[i]);}}if(csses!=null&&csses.length>0){selectElm.setAttribute('cssImported','true');}}};
+tinyMCE.importThemeLanguagePack('advanced');
+
+var TinyMCE_AdvancedTheme = {
+	// Private theme fields
+	_defColors : "000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF",
+	_autoImportCSSClasses : true,
+	_resizer : {},
+	_buttons : [
+		// Control id, button img, button title, command, user_interface, value
+		['bold', '{$lang_bold_img}', 'lang_bold_desc', 'Bold'],
+		['italic', '{$lang_italic_img}', 'lang_italic_desc', 'Italic'],
+		['underline', '{$lang_underline_img}', 'lang_underline_desc', 'Underline'],
+		['strikethrough', 'strikethrough.gif', 'lang_striketrough_desc', 'Strikethrough'],
+		['justifyleft', 'justifyleft.gif', 'lang_justifyleft_desc', 'JustifyLeft'],
+		['justifycenter', 'justifycenter.gif', 'lang_justifycenter_desc', 'JustifyCenter'],
+		['justifyright', 'justifyright.gif', 'lang_justifyright_desc', 'JustifyRight'],
+		['justifyfull', 'justifyfull.gif', 'lang_justifyfull_desc', 'JustifyFull'],
+		['bullist', 'bullist.gif', 'lang_bullist_desc', 'InsertUnorderedList'],
+		['numlist', 'numlist.gif', 'lang_numlist_desc', 'InsertOrderedList'],
+		['outdent', 'outdent.gif', 'lang_outdent_desc', 'Outdent'],
+		['indent', 'indent.gif', 'lang_indent_desc', 'Indent'],
+		['cut', 'cut.gif', 'lang_cut_desc', 'Cut'],
+		['copy', 'copy.gif', 'lang_copy_desc', 'Copy'],
+		['paste', 'paste.gif', 'lang_paste_desc', 'Paste'],
+		['undo', 'undo.gif', 'lang_undo_desc', 'Undo'],
+		['redo', 'redo.gif', 'lang_redo_desc', 'Redo'],
+		['link', 'link.gif', 'lang_link_desc', 'mceLink', true],
+		['unlink', 'unlink.gif', 'lang_unlink_desc', 'unlink'],
+		['image', 'image.gif', 'lang_image_desc', 'mceImage', true],
+		['cleanup', 'cleanup.gif', 'lang_cleanup_desc', 'mceCleanup'],
+		['help', 'help.gif', 'lang_help_desc', 'mceHelp'],
+		['code', 'code.gif', 'lang_theme_code_desc', 'mceCodeEditor'],
+		['hr', 'hr.gif', 'lang_theme_hr_desc', 'inserthorizontalrule'],
+		['removeformat', 'removeformat.gif', 'lang_theme_removeformat_desc', 'removeformat'],
+		['sub', 'sub.gif', 'lang_theme_sub_desc', 'subscript'],
+		['sup', 'sup.gif', 'lang_theme_sup_desc', 'superscript'],
+		['forecolor', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolor', true],
+		['forecolorpicker', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolorpicker', true],
+		['backcolor', 'backcolor.gif', 'lang_theme_backcolor_desc', 'HiliteColor', true],
+		['backcolorpicker', 'backcolor.gif', 'lang_theme_backcolor_desc', 'backcolorpicker', true],
+		['charmap', 'charmap.gif', 'lang_theme_charmap_desc', 'mceCharMap'],
+		['visualaid', 'visualaid.gif', 'lang_theme_visualaid_desc', 'mceToggleVisualAid'],
+		['anchor', 'anchor.gif', 'lang_theme_anchor_desc', 'mceInsertAnchor'],
+		['newdocument', 'newdocument.gif', 'lang_newdocument_desc', 'mceNewDocument']
+	],
+
+	_buttonMap : 'anchor,backcolor,bold,bullist,charmap,cleanup,code,copy,cut,forecolor,help,hr,image,indent,italic,justifycenter,justifyfull,justifyleft,justifyright,link,newdocument,numlist,outdent,paste,redo,removeformat,strikethrough,sub,sup,underline,undo,unlink,visualaid,advhr,ltr,rtl,emotions,flash,fullpage,fullscreen,iespell,insertdate,inserttime,pastetext,pasteword,selectall,preview,print,save,replace,search,table,cell_props,delete_col,delete_row,col_after,col_before,row_after,row_before,merge_cells,row_props,split_cells,delete_table',
+
+	/**
+	 * Returns HTML code for the specificed control.
+	 */
+	getControlHTML : function(button_name) {
+		var i, x, but;
+
+		// Lookup button in button list
+		for (i=0; i<TinyMCE_AdvancedTheme._buttons.length; i++) {
+			but = TinyMCE_AdvancedTheme._buttons[i];
+
+			if (but[0] == button_name && (button_name == "forecolor" || button_name == "backcolor"))
+				return tinyMCE.getMenuButtonHTML(but[0], but[2], '{$themeurl}/images/' + but[1], but[3] + "Menu", but[3], (but.length > 4 ? but[4] : false), (but.length > 5 ? but[5] : null));
+
+			if (but[0] == button_name)
+				return tinyMCE.getButtonHTML(but[0], but[2], '{$themeurl}/images/' + but[1], but[3], (but.length > 4 ? but[4] : false), (but.length > 5 ? but[5] : null));
+		}
+
+		// Custom controlls other than buttons
+		switch (button_name) {
+			case "formatselect":
+				var html = '<select id="{$editor_id}_formatSelect" name="{$editor_id}_formatSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FormatBlock\',false,this.options[this.selectedIndex].value);" class="mceSelectList">';
+				var formats = tinyMCE.getParam("theme_advanced_blockformats", "p,address,pre,h1,h2,h3,h4,h5,h6", true).split(',');
+				var lookup = [
+					['p', '{$lang_theme_paragraph}'],
+					['address', '{$lang_theme_address}'],
+					['pre', '{$lang_theme_pre}'],
+					['h1', '{$lang_theme_h1}'],
+					['h2', '{$lang_theme_h2}'],
+					['h3', '{$lang_theme_h3}'],
+					['h4', '{$lang_theme_h4}'],
+					['h5', '{$lang_theme_h5}'],
+					['h6', '{$lang_theme_h6}'],
+					['div', '{$lang_theme_div}'],
+					['blockquote', '{$lang_theme_blockquote}'],
+					['code', '{$lang_theme_code}'],
+					['dt', '{$lang_theme_dt}'],
+					['dd', '{$lang_theme_dd}'],
+					['samp', '{$lang_theme_samp}']
+				];
+
+				html += '<option value="">{$lang_theme_block}</option>';
+
+				// Build format select
+				for (var i=0; i<formats.length; i++) {
+					for (var x=0; x<lookup.length; x++) {
+						if (formats[i] == lookup[x][0])
+							html += '<option value="&lt;' + lookup[x][0] + '&gt;">' + lookup[x][1] + '</option>';
+					}
+				}
+
+				html += '</select>';
+
+				return html;
+
+			case "styleselect":
+				return '<select id="{$editor_id}_styleSelect" onmousedown="tinyMCE.themes.advanced._setupCSSClasses(\'{$editor_id}\');" name="{$editor_id}_styleSelect" onfocus="tinyMCE.addSelectAccessibility(event,this,window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'mceSetCSSClass\',false,this.options[this.selectedIndex].value);" class="mceSelectList">{$style_select_options}</select>';
+
+			case "fontselect":
+				var fontHTML = '<select id="{$editor_id}_fontNameSelect" name="{$editor_id}_fontNameSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontName\',false,this.options[this.selectedIndex].value);" class="mceSelectList"><option value="">{$lang_theme_fontdefault}</option>';
+				var iFonts = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings';
+				var nFonts = 'Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sand;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats';
+				var fonts = tinyMCE.getParam("theme_advanced_fonts", nFonts).split(';');
+				for (i=0; i<fonts.length; i++) {
+					if (fonts[i] != '') {
+						var parts = fonts[i].split('=');
+						fontHTML += '<option value="' + parts[1] + '">' + parts[0] + '</option>';
+					}
+				}
+
+				fontHTML += '</select>';
+				return fontHTML;
+
+			case "fontsizeselect":
+				return '<select id="{$editor_id}_fontSizeSelect" name="{$editor_id}_fontSizeSelect" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="tinyMCE.execInstanceCommand(\'{$editor_id}\',\'FontSize\',false,this.options[this.selectedIndex].value);" class="mceSelectList">'+
+						'<option value="0">{$lang_theme_font_size}</option>'+
+						'<option value="1">1 (8 pt)</option>'+
+						'<option value="2">2 (10 pt)</option>'+
+						'<option value="3">3 (12 pt)</option>'+
+						'<option value="4">4 (14 pt)</option>'+
+						'<option value="5">5 (18 pt)</option>'+
+						'<option value="6">6 (24 pt)</option>'+
+						'<option value="7">7 (36 pt)</option>'+
+						'</select>';
+
+			case "|":
+			case "separator":
+				return '<img src="{$themeurl}/images/separator.gif" width="2" height="20" class="mceSeparatorLine" />';
+
+			case "spacer":
+				return '<img src="{$themeurl}/images/separator.gif" width="2" height="15" border="0" class="mceSeparatorLine" style="vertical-align: middle" />';
+
+			case "rowseparator":
+				return '<br />';
+		}
+
+		return "";
+	},
+
+	/**
+	 * Theme specific execcommand handling.
+	 */
+	execCommand : function(editor_id, element, command, user_interface, value) {
+		switch (command) {
+			case 'mceHelp':
+				tinyMCE.openWindow({
+					file : 'about.htm',
+					width : 480,
+					height : 380
+				}, {
+					tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion,
+					tinymce_releasedate : tinyMCE.releaseDate,
+					inline : "yes"
+				});
+			return true;
+
+			case "mceLink":
+				var inst = tinyMCE.getInstanceById(editor_id);
+				var doc = inst.getDoc();
+				var selectedText = "";
+
+				if (tinyMCE.isMSIE) {
+					var rng = doc.selection.createRange();
+					selectedText = rng.text;
+				} else
+					selectedText = inst.getSel().toString();
+
+				if (!tinyMCE.linkElement) {
+					if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0))
+						return true;
+				}
+
+				var href = "", target = "", title = "", onclick = "", action = "insert", style_class = "";
+
+				if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a")
+					tinyMCE.linkElement = tinyMCE.selectedElement;
+
+				// Is anchor not a link
+				if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "")
+					tinyMCE.linkElement = null;
+
+				if (tinyMCE.linkElement) {
+					href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href');
+					target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target');
+					title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title');
+					onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
+					style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class');
+
+					// Try old onclick to if copy/pasted content
+					if (onclick == "")
+						onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
+
+					onclick = tinyMCE.cleanupEventStr(onclick);
+
+					href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
+
+					// Use mce_href if defined
+					mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href');
+					if (mceRealHref != "") {
+						href = mceRealHref;
+
+						if (tinyMCE.getParam('convert_urls'))
+							href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
+					}
+
+					action = "update";
+				}
+
+				var template = new Array();
+
+				template['file'] = 'link.htm';
+				template['width'] = 310;
+				template['height'] = 200;
+
+				// Language specific width and height addons
+				template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0);
+				template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0);
+
+				if (inst.settings['insertlink_callback']) {
+					var returnVal = eval(inst.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);");
+					if (returnVal && returnVal['href'])
+						TinyMCE_AdvancedTheme._insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']);
+				} else {
+					tinyMCE.openWindow(template, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"});
+				}
+
+				return true;
+
+			case "mceImage":
+				var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = "";
+				var title = "", onmouseover = "", onmouseout = "", action = "insert";
+				var img = tinyMCE.imgElement;
+				var inst = tinyMCE.getInstanceById(editor_id);
+
+				if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
+					img = tinyMCE.selectedElement;
+					tinyMCE.imgElement = img;
+				}
+
+				if (img) {
+					// Is it a internal MCE visual aid image, then skip this one.
+					if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0)
+						return true;
+
+					src = tinyMCE.getAttrib(img, 'src');
+					alt = tinyMCE.getAttrib(img, 'alt');
+
+					// Try polling out the title
+					if (alt == "")
+						alt = tinyMCE.getAttrib(img, 'title');
+
+					// Fix width/height attributes if the styles is specified
+					if (tinyMCE.isGecko) {
+						var w = img.style.width;
+						if (w != null && w != "")
+							img.setAttribute("width", w);
+
+						var h = img.style.height;
+						if (h != null && h != "")
+							img.setAttribute("height", h);
+					}
+
+					border = tinyMCE.getAttrib(img, 'border');
+					hspace = tinyMCE.getAttrib(img, 'hspace');
+					vspace = tinyMCE.getAttrib(img, 'vspace');
+					width = tinyMCE.getAttrib(img, 'width');
+					height = tinyMCE.getAttrib(img, 'height');
+					align = tinyMCE.getAttrib(img, 'align');
+					onmouseover = tinyMCE.getAttrib(img, 'onmouseover');
+					onmouseout = tinyMCE.getAttrib(img, 'onmouseout');
+					title = tinyMCE.getAttrib(img, 'title');
+
+					// Is realy specified?
+					if (tinyMCE.isMSIE) {
+						width = img.attributes['width'].specified ? width : "";
+						height = img.attributes['height'].specified ? height : "";
+					}
+
+					//onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));
+					//onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));
+
+					src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
+
+					// Use mce_src if defined
+					mceRealSrc = tinyMCE.getAttrib(img, 'mce_src');
+					if (mceRealSrc != "") {
+						src = mceRealSrc;
+
+						if (tinyMCE.getParam('convert_urls'))
+							src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
+					}
+
+					//if (onmouseover != "")
+					//	onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);");
+
+					//if (onmouseout != "")
+					//	onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);");
+
+					action = "update";
+				}
+
+				var template = new Array();
+
+				template['file'] = 'image.htm?src={$src}';
+				template['width'] = 355;
+				template['height'] = 265 + (tinyMCE.isMSIE ? 25 : 0);
+
+				// Language specific width and height addons
+				template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0);
+				template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0);
+
+				if (inst.settings['insertimage_callback']) {
+					var returnVal = eval(inst.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");
+					if (returnVal && returnVal['src'])
+						TinyMCE_AdvancedTheme._insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']);
+				} else
+					tinyMCE.openWindow(template, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"});
+
+				return true;
+
+			case "forecolor":
+				var fcp = new TinyMCE_Layer(editor_id + '_fcPreview', false), p, img, elm;
+
+				TinyMCE_AdvancedTheme._hideMenus(editor_id);
+
+				if (!fcp.exists()) {
+					fcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar'));
+					elm = fcp.getElement();
+					elm._editor_id = editor_id;
+					elm._command = "forecolor";
+					elm._switchId = editor_id + "_forecolor";
+					tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent);
+					tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent);
+					tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent);
+				}
+
+				img = tinyMCE.selectNodes(document.getElementById(editor_id + "_forecolor"), function(n) {return n.nodeName == "IMG";})[0];
+				p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar'));
+
+				fcp.moveTo(p.absLeft, p.absTop);
+				fcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).foreColor;
+				fcp.show();
+
+				return false;
+
+			case "forecolorpicker":
+				this._pickColor(editor_id, 'forecolor');
+				return true;
+
+			case "forecolorMenu":
+				TinyMCE_AdvancedTheme._hideMenus(editor_id);
+
+				// Create color layer
+				var ml = new TinyMCE_Layer(editor_id + '_fcMenu');
+
+				if (!ml.exists())
+					ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_text_colors', 'forecolor'));
+
+				tinyMCE.switchClass(editor_id + '_forecolor', 'mceMenuButtonFocus');
+				ml.moveRelativeTo(document.getElementById(editor_id + "_forecolor"), 'bl');
+
+				ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1);
+
+				if (tinyMCE.isOpera)
+					ml.moveBy(0, -2);
+
+				ml.show();
+			return true;
+
+			case "HiliteColor":
+				var bcp = new TinyMCE_Layer(editor_id + '_bcPreview', false), p, img;
+
+				TinyMCE_AdvancedTheme._hideMenus(editor_id);
+
+				if (!bcp.exists()) {
+					bcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar'));
+					elm = bcp.getElement();
+					elm._editor_id = editor_id;
+					elm._command = "HiliteColor";
+					elm._switchId = editor_id + "_backcolor";
+					tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent);
+					tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent);
+					tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent);
+				}
+
+				img = tinyMCE.selectNodes(document.getElementById(editor_id + "_backcolor"), function(n) {return n.nodeName == "IMG";})[0];
+				p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar'));
+
+				bcp.moveTo(p.absLeft, p.absTop);
+				bcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).backColor;
+				bcp.show();
+
+				return false;
+
+			case "HiliteColorMenu":
+				TinyMCE_AdvancedTheme._hideMenus(editor_id);
+
+				// Create color layer
+				var ml = new TinyMCE_Layer(editor_id + '_bcMenu');
+
+				if (!ml.exists())
+					ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_background_colors', 'HiliteColor'));
+
+				tinyMCE.switchClass(editor_id + '_backcolor', 'mceMenuButtonFocus');
+				ml.moveRelativeTo(document.getElementById(editor_id + "_backcolor"), 'bl');
+
+				ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1);
+
+				if (tinyMCE.isOpera)
+					ml.moveBy(0, -2);
+
+				ml.show();
+			return true;
+	
+			case "backcolorpicker":
+				this._pickColor(editor_id, 'HiliteColor');
+				return true;
+
+			case "mceColorPicker":
+				if (user_interface) {
+					var template = [];
+	
+					if (!value['callback'] && !value['color'])
+						value['color'] = value['document'].getElementById(value['element_id']).value;
+
+					template['file'] = 'color_picker.htm';
+					template['width'] = 380;
+					template['height'] = 250;
+					template['close_previous'] = "no";
+
+					template['width'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width', 0);
+					template['height'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height', 0);
+
+					if (typeof(value['store_selection']) == "undefined")
+						value['store_selection'] = true;
+
+					tinyMCE.lastColorPickerValue = value;
+					tinyMCE.openWindow(template, {editor_id : editor_id, mce_store_selection : value['store_selection'], inline : "yes", command : "mceColorPicker", input_color : value['color']});
+				} else {
+					var savedVal = tinyMCE.lastColorPickerValue, elm;
+
+					if (savedVal['callback']) {
+						savedVal['callback'](value);
+						return true;
+					}
+
+					elm = savedVal['document'].getElementById(savedVal['element_id']);
+					elm.value = value;
+
+					if (elm.onchange != null && elm.onchange != '')
+						eval('elm.onchange();');
+				}
+			return true;
+
+			case "mceCodeEditor":
+				var template = new Array();
+
+				template['file'] = 'source_editor.htm';
+				template['width'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_width", 720));
+				template['height'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_height", 580));
+
+				tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "no", inline : "yes"});
+				return true;
+
+			case "mceCharMap":
+				var template = new Array();
+
+				template['file'] = 'charmap.htm';
+				template['width'] = 550 + (tinyMCE.isOpera ? 40 : 0);
+				template['height'] = 250;
+
+				template['width'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_width', 0);
+				template['height'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_height', 0);
+
+				tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"});
+				return true;
+
+			case "mceInsertAnchor":
+				var template = new Array();
+
+				template['file'] = 'anchor.htm';
+				template['width'] = 320;
+				template['height'] = 90 + (tinyMCE.isNS7 ? 30 : 0);
+
+				template['width'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_width', 0);
+				template['height'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_height', 0);
+
+				tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"});
+				return true;
+
+			case "mceNewDocument":
+				if (confirm(tinyMCE.getLang('lang_newdocument')))
+					tinyMCE.execInstanceCommand(editor_id, 'mceSetContent', false, ' ');
+
+				return true;
+		}
+
+		return false;
+	},
+
+	/**
+	 * Editor instance template function.
+	 */
+	getEditorTemplate : function(settings, editorId) {
+		function removeFromArray(in_array, remove_array) {
+			var outArray = new Array(), skip;
+			
+			for (var i=0; i<in_array.length; i++) {
+				skip = false;
+
+				for (var j=0; j<remove_array.length; j++) {
+					if (in_array[i] == remove_array[j]) {
+						skip = true;
+					}
+				}
+
+				if (!skip) {
+					outArray[outArray.length] = in_array[i];
+				}
+			}
+
+			return outArray;
+		}
+
+		function addToArray(in_array, add_array) {
+			for (var i=0; i<add_array.length; i++) {
+				in_array[in_array.length] = add_array[i];
+			}
+
+			return in_array;
+		}
+
+		var template = new Array();
+		var deltaHeight = 0;
+		var resizing = tinyMCE.getParam("theme_advanced_resizing", false);
+		var path = tinyMCE.getParam("theme_advanced_path", true);
+		var statusbarHTML = '<div id="{$editor_id}_path" class="mceStatusbarPathText" style="display: ' + (path ? "block" : "none") + '">&#160;</div><div id="{$editor_id}_resize" class="mceStatusbarResize" style="display: ' + (resizing ? "block" : "none") + '" onmousedown="tinyMCE.themes.advanced._setResizing(event,\'{$editor_id}\',true);"></div><br style="clear: both" />';
+		var layoutManager = tinyMCE.getParam("theme_advanced_layout_manager", "SimpleLayout");
+
+		// Setup style select options -- MOVED UP FOR EXTERNAL TOOLBAR COMPATABILITY!
+		var styleSelectHTML = '<option value="">{$lang_theme_style_select}</option>';
+		if (settings['theme_advanced_styles']) {
+			var stylesAr = settings['theme_advanced_styles'].split(';');
+			
+			for (var i=0; i<stylesAr.length; i++) {
+				var key, value;
+
+				key = stylesAr[i].split('=')[0];
+				value = stylesAr[i].split('=')[1];
+
+				styleSelectHTML += '<option value="' + value + '">' + key + '</option>';
+			}
+
+			TinyMCE_AdvancedTheme._autoImportCSSClasses = false;
+		}
+
+		switch(layoutManager) {
+			case "SimpleLayout" : //the default TinyMCE Layout (for backwards compatibility)...
+				var toolbarHTML = "";
+				var toolbarLocation = tinyMCE.getParam("theme_advanced_toolbar_location", "bottom");
+				var toolbarAlign = tinyMCE.getParam("theme_advanced_toolbar_align", "center");
+				var pathLocation = tinyMCE.getParam("theme_advanced_path_location", "none"); // Compatiblity
+				var statusbarLocation = tinyMCE.getParam("theme_advanced_statusbar_location", pathLocation);
+				var defVals = {
+					theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",
+					theme_advanced_buttons2 : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code",
+					theme_advanced_buttons3 : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap"
+				};
+
+				// Add accessibility control
+				toolbarHTML += '<a href="#" accesskey="q" title="' + tinyMCE.getLang("lang_toolbar_focus") + '"';
+
+				if (!tinyMCE.getParam("accessibility_focus"))
+					toolbarHTML += ' onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"';
+
+				toolbarHTML += '></a>';
+
+				// Render rows
+				for (var i=1; i<100; i++) {
+					var def = defVals["theme_advanced_buttons" + i];
+
+					var buttons = tinyMCE.getParam("theme_advanced_buttons" + i, def == null ? '' : def, true, ',');
+					if (buttons.length == 0)
+						break;
+
+					buttons = removeFromArray(buttons, tinyMCE.getParam("theme_advanced_disable", "", true, ','));
+					buttons = addToArray(buttons, tinyMCE.getParam("theme_advanced_buttons" + i + "_add", "", true, ','));
+					buttons = addToArray(tinyMCE.getParam("theme_advanced_buttons" + i + "_add_before", "", true, ','), buttons);
+
+					for (var b=0; b<buttons.length; b++)
+						toolbarHTML += tinyMCE.getControlHTML(buttons[b]);
+
+					if (buttons.length > 0) {
+						toolbarHTML += "<br />";
+						deltaHeight -= 23;
+					}
+				}
+
+				// Add accessibility control
+				toolbarHTML += '<a href="#" accesskey="z" onfocus="tinyMCE.getInstanceById(\'' + editorId + '\').getWin().focus();"></a>';
+
+				// Setup template html
+				template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width_style};height:{$height_style}"><tbody>';
+
+				if (toolbarLocation == "top")
+					template['html'] += '<tr><td dir="ltr" class="mceToolbarTop" align="' + toolbarAlign + '" height="1" nowrap="nowrap"><span id="' + editorId + '_toolbar" class="mceToolbarContainer">' + toolbarHTML + '</span></td></tr>';
+
+				if (statusbarLocation == "top") {
+					template['html'] += '<tr><td class="mceStatusbarTop" height="1">' + statusbarHTML + '</td></tr>';
+					deltaHeight -= 23;
+				}
+
+				template['html'] += '<tr><td align="center"><span id="{$editor_id}"></span></td></tr>';
+
+				if (toolbarLocation == "bottom")
+					template['html'] += '<tr><td dir="ltr" class="mceToolbarBottom" align="' + toolbarAlign + '" height="1"><span id="' + editorId + '_toolbar" class="mceToolbarContainer">' + toolbarHTML + '</span></td></tr>';
+
+				// External toolbar changes
+				if (toolbarLocation == "external") {
+					var bod = document.body;
+					var elm = document.createElement ("div");
+
+					toolbarHTML = tinyMCE.replaceVar(toolbarHTML, 'style_select_options', styleSelectHTML);
+					toolbarHTML = tinyMCE.applyTemplate(toolbarHTML, {editor_id : editorId});
+
+					elm.className = "mceToolbarExternal";
+					elm.id = editorId+"_toolbar";
+					elm.innerHTML = '<table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table>';
+					bod.appendChild (elm);
+					// bod.style.marginTop = elm.offsetHeight + "px";
+
+					deltaHeight = 0;
+					tinyMCE.getInstanceById(editorId).toolbarElement = elm;
+
+					//template['html'] = '<div id="mceExternalToolbar" align="center" class="mceToolbarExternal"><table width="100%" border="0" align="center"><tr><td align="center">'+toolbarHTML+'</td></tr></table></div>' + template["html"];
+				} else {
+					tinyMCE.getInstanceById(editorId).toolbarElement = null;
+				}
+
+				if (statusbarLocation == "bottom") {
+					template['html'] += '<tr><td class="mceStatusbarBottom" height="1">' + statusbarHTML + '</td></tr>';
+					deltaHeight -= 23;
+				}
+
+				template['html'] += '</tbody></table>';
+				//"SimpleLayout"
+			break;
+
+			case "RowLayout" : //Container Layout - containers defined in "theme_advanced_containers" are rendered from top to bottom.
+				template['html'] = '<table class="mceEditor" border="0" cellpadding="0" cellspacing="0" width="{$width}" height="{$height}" style="width:{$width}px;height:{$height}px"><tbody>';
+
+				var containers = tinyMCE.getParam("theme_advanced_containers", "", true, ",");
+				var defaultContainerCSS = tinyMCE.getParam("theme_advanced_containers_default_class", "container");
+				var defaultContainerAlign = tinyMCE.getParam("theme_advanced_containers_default_align", "center");
+
+				//Render Containers:
+				for (var i = 0; i < containers.length; i++)
+				{
+					if (containers[i] == "mceEditor") //Exceptions for mceEditor and ...
+						template['html'] += '<tr><td align="center" class="mceEditor_border"><span id="{$editor_id}"></span></td></tr>';
+					else if (containers[i] == "mceElementpath" || containers[i] == "mceStatusbar") // ... mceElementpath:
+					{
+						var pathClass = "mceStatusbar";
+
+						if (i == containers.length-1)
+						{
+							pathClass = "mceStatusbarBottom";
+						}
+						else if (i == 0)
+						{
+							pathClass = "mceStatusbar";
+						}
+						else
+						{
+							deltaHeight-=2;
+						}
+
+						template['html'] += '<tr><td class="' + pathClass + '" height="1">' + statusbarHTML + '</td></tr>';
+						deltaHeight -= 22;
+					} else { // Render normal Container
+						var curContainer = tinyMCE.getParam("theme_advanced_container_"+containers[i], "", true, ',');
+						var curContainerHTML = "";
+						var curAlign = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align", defaultContainerAlign);
+						var curCSS = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class", defaultContainerCSS);
+
+						curContainer = removeFromArray(curContainer, tinyMCE.getParam("theme_advanced_disable", "", true, ','));
+
+						for (var j=0; j<curContainer.length; j++)
+							curContainerHTML += tinyMCE.getControlHTML(curContainer[j]);
+
+						if (curContainer.length > 0) {
+							curContainerHTML += "<br />";
+							deltaHeight -= 23;
+						}
+
+						template['html'] += '<tr><td class="' + curCSS + '" align="' + curAlign + '" height="1">' + curContainerHTML + '</td></tr>';
+					}
+				}
+
+				template['html'] += '</tbody></table>';
+				//RowLayout
+			break;
+
+			case "CustomLayout" : //User defined layout callback...
+				var customLayout = tinyMCE.getParam("theme_advanced_custom_layout","");
+
+				if (customLayout != "" && eval("typeof(" + customLayout + ")") != "undefined") {
+					template = eval(customLayout + "(template);");
+				}
+			break;
+		}
+
+		if (resizing)
+			template['html'] += '<span id="{$editor_id}_resize_box" class="mceResizeBox"></span>';
+
+		template['html'] = tinyMCE.replaceVar(template['html'], 'style_select_options', styleSelectHTML);
+
+		// Set to default values
+		if (!template['delta_width'])
+			template['delta_width'] = 0;
+
+		if (!template['delta_height'])
+			template['delta_height'] = deltaHeight;
+
+		return template;
+	},
+
+	initInstance : function(inst) {
+		if (tinyMCE.getParam("theme_advanced_resizing", false)) {
+			if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) {
+				var w = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_width");
+				var h = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height");
+
+				TinyMCE_AdvancedTheme._resizeTo(inst, w, h, tinyMCE.getParam("theme_advanced_resize_horizontal", true));
+			}
+		}
+
+		inst.addShortcut('ctrl', 'k', 'lang_link_desc', 'mceLink');
+	},
+
+	removeInstance : function(inst) {
+		new TinyMCE_Layer(inst.editorId + '_fcMenu').remove();
+		new TinyMCE_Layer(inst.editorId + '_bcMenu').remove();
+	},
+
+	hideInstance : function(inst) {
+		TinyMCE_AdvancedTheme._hideMenus(inst.editorId);
+	},
+
+	_handleMenuEvent : function(e) {
+		var te = tinyMCE.isMSIE ? window.event.srcElement : e.target;
+		tinyMCE._menuButtonEvent(e.type == "mouseover" ? "over" : "out", document.getElementById(te._switchId));
+
+		if (e.type == "click")
+			tinyMCE.execInstanceCommand(te._editor_id, te._command);
+	},
+
+	_hideMenus : function(id) {
+		var fcml = new TinyMCE_Layer(id + '_fcMenu'), bcml = new TinyMCE_Layer(id + '_bcMenu');
+
+		if (fcml.exists() && fcml.isVisible()) {
+			tinyMCE.switchClass(id + '_forecolor', 'mceMenuButton');
+			fcml.hide();
+		}
+
+		if (bcml.exists() && bcml.isVisible()) {
+			tinyMCE.switchClass(id + '_backcolor', 'mceMenuButton');
+			bcml.hide();
+		}
+	},
+
+	/**
+	 * Node change handler.
+	 */
+	handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection, setup_content) {
+		var alignNode, breakOut, classNode;
+
+		function selectByValue(select_elm, value, first_index) {
+			first_index = typeof(first_index) == "undefined" ? false : true;
+
+			if (select_elm) {
+				for (var i=0; i<select_elm.options.length; i++) {
+					var ov = "" + select_elm.options[i].value;
+
+					if (first_index && ov.toLowerCase().indexOf(value.toLowerCase()) == 0) {
+						select_elm.selectedIndex = i;
+						return true;
+					}
+
+					if (ov == value) {
+						select_elm.selectedIndex = i;
+						return true;
+					}
+				}
+			}
+
+			return false;
+		};
+
+		// No node provided
+		if (node == null)
+			return;
+
+		// Update path
+		var pathElm = document.getElementById(editor_id + "_path");
+		var inst = tinyMCE.getInstanceById(editor_id);
+		var doc = inst.getDoc();
+		TinyMCE_AdvancedTheme._hideMenus(editor_id);
+
+		if (pathElm) {
+			// Get node path
+			var parentNode = node;
+			var path = new Array();
+			
+			while (parentNode != null) {
+				if (parentNode.nodeName.toUpperCase() == "BODY") {
+					break;
+				}
+
+				// Only append element nodes to path
+				if (parentNode.nodeType == 1 && tinyMCE.getAttrib(parentNode, "class").indexOf('mceItemHidden') == -1) {
+					path[path.length] = parentNode;
+				}
+
+				parentNode = parentNode.parentNode;
+			}
+
+			// Setup HTML
+			var html = "";
+			for (var i=path.length-1; i>=0; i--) {
+				var nodeName = path[i].nodeName.toLowerCase();
+				var nodeData = "";
+
+				if (nodeName.indexOf("html:") == 0)
+					nodeName = nodeName.substring(5);
+
+				if (nodeName == "b") {
+					nodeName = "strong";
+				}
+
+				if (nodeName == "i") {
+					nodeName = "em";
+				}
+
+				if (nodeName == "span") {
+					var cn = tinyMCE.getAttrib(path[i], "class");
+					if (cn != "" && cn.indexOf('mceItem') == -1)
+						nodeData += "class: " + cn + " ";
+
+					var st = tinyMCE.getAttrib(path[i], "style");
+					if (st != "") {
+						st = tinyMCE.serializeStyle(tinyMCE.parseStyle(st));
+						nodeData += "style: " + tinyMCE.xmlEncode(st) + " ";
+					}
+				}
+
+				if (nodeName == "font") {
+					if (tinyMCE.getParam("convert_fonts_to_spans"))
+						nodeName = "span";
+
+					var face = tinyMCE.getAttrib(path[i], "face");
+					if (face != "")
+						nodeData += "font: " + tinyMCE.xmlEncode(face) + " ";
+
+					var size = tinyMCE.getAttrib(path[i], "size");
+					if (size != "")
+						nodeData += "size: " + tinyMCE.xmlEncode(size) + " ";
+
+					var color = tinyMCE.getAttrib(path[i], "color");
+					if (color != "")
+						nodeData += "color: " + tinyMCE.xmlEncode(color) + " ";
+				}
+
+				if (tinyMCE.getAttrib(path[i], 'id') != "") {
+					nodeData += "id: " + path[i].getAttribute('id') + " ";
+				}
+
+				var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false);
+				if (className != "" && className.indexOf('mceItem') == -1)
+					nodeData += "class: " + className + " ";
+
+				if (tinyMCE.getAttrib(path[i], 'src') != "") {
+					var src = tinyMCE.getAttrib(path[i], "mce_src");
+
+					if (src == "")
+						 src = tinyMCE.getAttrib(path[i], "src");
+
+					nodeData += "src: " + tinyMCE.xmlEncode(src) + " ";
+				}
+
+				if (path[i].nodeName == 'A' && tinyMCE.getAttrib(path[i], 'href') != "") {
+					var href = tinyMCE.getAttrib(path[i], "mce_href");
+
+					if (href == "")
+						 href = tinyMCE.getAttrib(path[i], "href");
+
+					nodeData += "href: " + tinyMCE.xmlEncode(href) + " ";
+				}
+
+				className = tinyMCE.getAttrib(path[i], "class");
+				if ((nodeName == "img" || nodeName == "span") && className.indexOf('mceItem') != -1) {
+					nodeName = className.replace(/mceItem([a-z]+)/gi, '$1').toLowerCase();
+					nodeData = path[i].getAttribute('title');
+				}
+
+				if (nodeName == "a" && (anchor = tinyMCE.getAttrib(path[i], "name")) != "") {
+					nodeName = "a";
+					nodeName += "#" + tinyMCE.xmlEncode(anchor);
+					nodeData = "";
+				}
+
+				if (tinyMCE.getAttrib(path[i], 'name').indexOf("mce_") != 0) {
+					var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false);
+					if (className != "" && className.indexOf('mceItem') == -1) {
+						nodeName += "." + className;
+					}
+				}
+
+				var cmd = 'tinyMCE.execInstanceCommand(\'' + editor_id + '\',\'mceSelectNodeDepth\',false,\'' + i + '\');';
+				html += '<a title="' + nodeData + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" target="_self" class="mcePathItem">' + nodeName + '</a>';
+
+				if (i > 0) {
+					html += " &raquo; ";
+				}
+			}
+
+			pathElm.innerHTML = '<a href="#" accesskey="x"></a>' + tinyMCE.getLang('lang_theme_path') + ": " + html + '&#160;';
+		}
+
+		// Reset old states
+		tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_bold', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_italic', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_underline', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_sub', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_sup', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_link', 'mceButtonDisabled');
+		tinyMCE.switchClass(editor_id + '_unlink', 'mceButtonDisabled');
+		tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonDisabled');
+		tinyMCE.switchClass(editor_id + '_image', 'mceButtonNormal');
+		tinyMCE.switchClass(editor_id + '_hr', 'mceButtonNormal');
+
+		if (node.nodeName == "A" && tinyMCE.getAttrib(node, "class").indexOf('mceItemAnchor') != -1)
+			tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonSelected');
+
+		// Get link
+		var anchorLink = tinyMCE.getParentElement(node, "a", "href");
+
+		if (anchorLink || any_selection) {
+			tinyMCE.switchClass(editor_id + '_link', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal');
+			tinyMCE.switchClass(editor_id + '_unlink', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal');
+		}
+
+		// Handle visual aid
+		tinyMCE.switchClass(editor_id + '_visualaid', visual_aid ? 'mceButtonSelected' : 'mceButtonNormal');
+
+		if (undo_levels != -1) {
+			tinyMCE.switchClass(editor_id + '_undo', 'mceButtonDisabled');
+			tinyMCE.switchClass(editor_id + '_redo', 'mceButtonDisabled');
+		}
+
+		// Within li, blockquote
+		if (tinyMCE.getParentElement(node, "li,blockquote"))
+			tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonNormal');
+
+		// Has redo levels
+		if (undo_index != -1 && (undo_index < undo_levels-1 && undo_levels > 0))
+			tinyMCE.switchClass(editor_id + '_redo', 'mceButtonNormal');
+
+		// Has undo levels
+		if (undo_index != -1 && (undo_index > 0 && undo_levels > 0))
+			tinyMCE.switchClass(editor_id + '_undo', 'mceButtonNormal');
+
+		// Select class in select box
+		var selectElm = document.getElementById(editor_id + "_styleSelect");
+		
+		if (selectElm) {
+			TinyMCE_AdvancedTheme._setupCSSClasses(editor_id);
+
+			classNode = node;
+			breakOut = false;
+			var index = 0;
+
+			do {
+				if (classNode && classNode.className) {
+					for (var i=0; i<selectElm.options.length; i++) {
+						if (selectElm.options[i].value == classNode.className) {
+							index = i;
+							breakOut = true;
+							break;
+						}
+					}
+				}
+			} while (!breakOut && classNode != null && (classNode = classNode.parentNode) != null);
+
+			selectElm.selectedIndex = index;
+		}
+
+		// Select formatblock
+		var selectElm = document.getElementById(editor_id + "_formatSelect");
+		if (selectElm) {
+			var elm = tinyMCE.getParentElement(node, "p,div,h1,h2,h3,h4,h5,h6,pre,address");
+
+			if (elm)
+				selectByValue(selectElm, "<" + elm.nodeName.toLowerCase() + ">");
+			else
+				selectByValue(selectElm, "");
+		}
+
+		// Select fontselect
+		var selectElm = document.getElementById(editor_id + "_fontNameSelect");
+		if (selectElm) {
+			if (!tinyMCE.isSafari && !(tinyMCE.isMSIE && !tinyMCE.isOpera)) {
+				var face = inst.queryCommandValue('FontName');
+
+				face = face == null || face == "" ? "" : face;
+
+				selectByValue(selectElm, face, face != "");
+			} else {
+				var elm = tinyMCE.getParentElement(node, "font", "face");
+
+				if (elm) {
+					var family = tinyMCE.getAttrib(elm, "face");
+
+					if (family == '')
+						family = '' + elm.style.fontFamily;
+
+					if (!selectByValue(selectElm, family, family != ""))
+						selectByValue(selectElm, "");
+				} else
+					selectByValue(selectElm, "");
+			}
+		}
+
+		// Select fontsize
+		var selectElm = document.getElementById(editor_id + "_fontSizeSelect");
+		if (selectElm) {
+			if (!tinyMCE.isSafari && !tinyMCE.isOpera) {
+				var size = inst.queryCommandValue('FontSize');
+				selectByValue(selectElm, size == null || size == "" ? "0" : size);
+			} else {
+				var elm = tinyMCE.getParentElement(node, "font", "size");
+				if (elm) {
+					var size = tinyMCE.getAttrib(elm, "size");
+
+					if (size == '') {
+						var sizes = new Array('', '8px', '10px', '12px', '14px', '18px', '24px', '36px');
+
+						size = '' + elm.style.fontSize;
+
+						for (var i=0; i<sizes.length; i++) {
+							if (('' + sizes[i]) == size) {
+								size = i;
+								break;
+							}
+						}
+					}
+
+					if (!selectByValue(selectElm, size))
+						selectByValue(selectElm, "");
+				} else
+					selectByValue(selectElm, "0");
+			}
+		}
+
+		// Handle align attributes
+		alignNode = node;
+		breakOut = false;
+		do {
+			if (!alignNode.getAttribute || !alignNode.getAttribute('align'))
+				continue;
+
+			switch (alignNode.getAttribute('align').toLowerCase()) {
+				case "left":
+					tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonSelected');
+					breakOut = true;
+				break;
+
+				case "right":
+					tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonSelected');
+					breakOut = true;
+				break;
+
+				case "middle":
+				case "center":
+					tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected');
+					breakOut = true;
+				break;
+
+				case "justify":
+					tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonSelected');
+					breakOut = true;
+				break;
+			}
+		} while (!breakOut && (alignNode = alignNode.parentNode) != null);
+
+		// Div justification
+		var div = tinyMCE.getParentElement(node, "div");
+		if (div && div.style.textAlign == "center")
+			tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonSelected');
+
+		// Do special text
+		if (!setup_content) {
+			// , "JustifyLeft", "_justifyleft", "JustifyCenter", "justifycenter", "JustifyRight", "justifyright", "JustifyFull", "justifyfull", "InsertUnorderedList", "bullist", "InsertOrderedList", "numlist", "InsertUnorderedList", "bullist", "Outdent", "outdent", "Indent", "indent", "subscript", "sub"
+			var ar = new Array("Bold", "_bold", "Italic", "_italic", "Strikethrough", "_strikethrough", "superscript", "_sup", "subscript", "_sub");
+			for (var i=0; i<ar.length; i+=2) {
+				if (inst.queryCommandState(ar[i]))
+					tinyMCE.switchClass(editor_id + ar[i+1], 'mceButtonSelected');
+			}
+
+			if (inst.queryCommandState("Underline") && (node.parentNode == null || node.parentNode.nodeName != "A"))
+				tinyMCE.switchClass(editor_id + '_underline', 'mceButtonSelected');
+		}
+
+		// Handle elements
+		do {
+			switch (node.nodeName) {
+				case "UL":
+					tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonSelected');
+				break;
+
+				case "OL":
+					tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonSelected');
+				break;
+
+				case "HR":
+					 tinyMCE.switchClass(editor_id + '_hr', 'mceButtonSelected');
+				break;
+
+				case "IMG":
+				if (tinyMCE.getAttrib(node, 'name').indexOf('mce_') != 0 && tinyMCE.getAttrib(node, 'class').indexOf('mceItem') == -1) {
+					tinyMCE.switchClass(editor_id + '_image', 'mceButtonSelected');
+				}
+				break;
+			}
+		} while ((node = node.parentNode) != null);
+	},
+
+	// Private theme internal functions
+
+	// This function auto imports CSS classes into the class selection droplist
+	_setupCSSClasses : function(editor_id) {
+		var i, selectElm;
+
+		if (!TinyMCE_AdvancedTheme._autoImportCSSClasses)
+			return;
+
+		selectElm = document.getElementById(editor_id + '_styleSelect');
+
+		if (selectElm && selectElm.getAttribute('cssImported') != 'true') {
+			var csses = tinyMCE.getCSSClasses(editor_id);
+			if (csses && selectElm)	{
+				for (i=0; i<csses.length; i++)
+					selectElm.options[selectElm.options.length] = new Option(csses[i], csses[i]);
+			}
+
+			// Only do this once
+			if (csses != null && csses.length > 0)
+				selectElm.setAttribute('cssImported', 'true');
+		}
+	},
+
+	_setCookie : function(name, value, expires, path, domain, secure) {
+		var curCookie = name + "=" + escape(value) +
+			((expires) ? "; expires=" + expires.toGMTString() : "") +
+			((path) ? "; path=" + escape(path) : "") +
+			((domain) ? "; domain=" + domain : "") +
+			((secure) ? "; secure" : "");
+
+		document.cookie = curCookie;
+	},
+
+	_getCookie : function(name) {
+		var dc = document.cookie;
+		var prefix = name + "=";
+		var begin = dc.indexOf("; " + prefix);
+
+		if (begin == -1) {
+			begin = dc.indexOf(prefix);
+
+			if (begin != 0)
+				return null;
+		} else
+			begin += 2;
+
+		var end = document.cookie.indexOf(";", begin);
+
+		if (end == -1)
+			end = dc.length;
+
+		return unescape(dc.substring(begin + prefix.length, end));
+	},
+
+	_resizeTo : function(inst, w, h, set_w) {
+		var editorContainer = document.getElementById(inst.editorId + '_parent');
+		var tableElm = editorContainer.firstChild;
+		var iframe = inst.iframeElement;
+
+		if (w == null || w == "null") {
+			set_w = false;
+			w = 0;
+		}
+
+		if (h == null || h == "null")
+			return;
+
+		w = parseInt(w);
+		h = parseInt(h);
+
+		if (tinyMCE.isGecko) {
+			w += 2;
+			h += 2;
+		}
+
+		var dx = w - tableElm.clientWidth;
+		var dy = h - tableElm.clientHeight;
+
+		w = w < 1 ? 30 : w;
+		h = h < 1 ? 30 : h;
+
+		if (set_w)
+			tableElm.style.width = w + "px";
+
+		if ( !tinyMCE.isMSIE || tinyMCE.isMSIE7 || tinyMCE.isOpera ) // WordPress: do this later to avoid creeping toolbar bug in MSIE6
+		tableElm.style.height = h + "px";
+
+		iw = iframe.clientWidth + dx;
+		ih = iframe.clientHeight + dy;
+
+		iw = iw < 1 ? 30 : iw;
+		ih = ih < 1 ? 30 : ih;
+
+/* WordPress found that this led to a shrinking editor with every resize. (Gray background creeps in 1px at a time.)
+		if (tinyMCE.isGecko) {
+			iw -= 2;
+			ih -= 2;
+		}
+*/
+
+		if (set_w)
+			iframe.style.width = iw + "px";
+
+		iframe.style.height = ih + "px";
+
+		// Is it to small, make it bigger again
+		if (set_w) {
+			var tableBodyElm = tableElm.firstChild;
+			var minIframeWidth = tableBodyElm.scrollWidth;
+			if (inst.iframeElement.clientWidth < minIframeWidth) {
+				dx = minIframeWidth - inst.iframeElement.clientWidth;
+
+				inst.iframeElement.style.width = (iw + dx) + "px";
+			}
+		}
+
+		tableElm.style.height = h + "px"; // WordPress: see above
+
+		// Remove pesky table controls
+		inst.useCSS = false;
+	},
+
+	/**
+	 * Handles resizing events.
+	 */
+	_resizeEventHandler : function(e) {
+		var resizer = TinyMCE_AdvancedTheme._resizer;
+
+		// Do nothing
+		if (!resizer.resizing)
+			return;
+
+		e = typeof(e) == "undefined" ? window.event : e;
+
+		var dx = e.screenX - resizer.downX;
+		var dy = e.screenY - resizer.downY;
+		var resizeBox = resizer.resizeBox;
+		var editorId = resizer.editorId;
+
+		switch (e.type) {
+			case "mousemove":
+				var w, h;
+
+				w = resizer.width + dx;
+				h = resizer.height + dy;
+
+				w = w < 1 ? 1 : w;
+				h = h < 1 ? 1 : h;
+
+				if (resizer.horizontal)
+					resizeBox.style.width = w + "px";
+
+				resizeBox.style.height = h + "px";
+				break;
+
+			case "mouseup":
+				TinyMCE_AdvancedTheme._setResizing(e, editorId, false);
+				TinyMCE_AdvancedTheme._resizeTo(tinyMCE.getInstanceById(editorId), resizer.width + dx, resizer.height + dy, resizer.horizontal);
+
+				// Expire in a month
+				if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) {
+					var expires = new Date();
+					expires.setTime(expires.getTime() + 3600000 * 24 * 30);
+
+					// Set the cookies
+					TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_width", "" + (resizer.horizontal ? resizer.width + dx : ""), expires);
+					TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_height", "" + (resizer.height + dy), expires);
+				}
+				break;
+		}
+	},
+
+	/**
+	 * Starts/stops the editor resizing.
+	 */
+	_setResizing : function(e, editor_id, state) {
+		e = typeof(e) == "undefined" ? window.event : e;
+
+		var resizer = TinyMCE_AdvancedTheme._resizer;
+		var editorContainer = document.getElementById(editor_id + '_parent');
+		var editorArea = document.getElementById(editor_id + '_parent').firstChild;
+		var resizeBox = document.getElementById(editor_id + '_resize_box');
+		var inst = tinyMCE.getInstanceById(editor_id);
+
+		if (state) {
+			// Place box over editor area
+			var width = editorArea.clientWidth;
+			var height = editorArea.clientHeight;
+
+			resizeBox.style.width = width + "px";
+			resizeBox.style.height = height + "px";
+
+			resizer.iframeWidth = inst.iframeElement.clientWidth;
+			resizer.iframeHeight = inst.iframeElement.clientHeight;
+
+			// Hide editor and show resize box
+			editorArea.style.display = "none";
+			resizeBox.style.display = "block";
+
+			// Add event handlers, only once
+			if (!resizer.eventHandlers) {
+				if (tinyMCE.isMSIE)
+					tinyMCE.addEvent(document, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler);
+				else
+					tinyMCE.addEvent(window, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler);
+
+				tinyMCE.addEvent(document, "mouseup", TinyMCE_AdvancedTheme._resizeEventHandler);
+
+				resizer.eventHandlers = true;
+			}
+
+			resizer.resizing = true;
+			resizer.downX = e.screenX;
+			resizer.downY = e.screenY;
+			resizer.width = parseInt(resizeBox.style.width);
+			resizer.height = parseInt(resizeBox.style.height);
+			resizer.editorId = editor_id;
+			resizer.resizeBox = resizeBox;
+			resizer.horizontal = tinyMCE.getParam("theme_advanced_resize_horizontal", true);
+		} else {
+			resizer.resizing = false;
+			resizeBox.style.display = "none";
+			editorArea.style.display = tinyMCE.isMSIE && !tinyMCE.isOpera ? "block" : "table";
+			tinyMCE.execCommand('mceResetDesignMode');
+		}
+	},
+
+	_getColorHTML : function(id, n, cm) {
+		var i, h, cl;
+
+		h = '<span class="mceMenuLine"></span>';
+		cl = tinyMCE.getParam(n, TinyMCE_AdvancedTheme._defColors).split(',');
+
+		h += '<table class="mceColors"><tr>';
+		for (i=0; i<cl.length; i++) {
+			c = 'tinyMCE.execInstanceCommand(\'' + id + '\', \'' + cm + '\', false, \'#' + cl[i] + '\');';
+			h += '<td><a href="javascript:' + c + '" style="background-color: #' + cl[i] + '" onclick="' + c + ';return false;"></a></td>';
+
+			if ((i+1) % 8 == 0)
+				h += '</tr><tr>';
+		}
+
+		h += '</tr></table>';
+
+		if (tinyMCE.getParam("theme_advanced_more_colors", true))
+			h += '<a href="#" onclick="TinyMCE_AdvancedTheme._pickColor(\'' + id + '\',\'' + cm + '\');" class="mceMoreColors">' + tinyMCE.getLang('lang_more_colors') + '</a>';
+
+		return h;
+	},
+
+	_pickColor : function(id, cm) {
+		var inputColor, inst = tinyMCE.selectedInstance;
+
+		if (cm == 'forecolor' && inst)
+			inputColor = inst.foreColor;
+
+		if ((cm == 'backcolor' || cm == 'HiliteColor') && inst)
+			inputColor = inst.backColor;
+
+		tinyMCE.execCommand('mceColorPicker', true, {color : inputColor, callback : function(c) {
+			tinyMCE.execInstanceCommand(id, cm, false, c);
+		}});
+	},
+
+	_insertImage : function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) {
+		tinyMCE.execCommand('mceBeginUndoLevel');
+
+		if (src == "")
+			return;
+
+		if (!tinyMCE.imgElement && tinyMCE.isSafari) {
+			var html = "";
+
+			html += '<img src="' + src + '" alt="' + alt + '"';
+			html += ' border="' + border + '" hspace="' + hspace + '"';
+			html += ' vspace="' + vspace + '" width="' + width + '"';
+			html += ' height="' + height + '" align="' + align + '" title="' + title + '" onmouseover="' + onmouseover + '" onmouseout="' + onmouseout + '" />';
+
+			tinyMCE.execCommand("mceInsertContent", false, html);
+		} else {
+			if (!tinyMCE.imgElement && tinyMCE.selectedInstance) {
+				if (tinyMCE.isSafari)
+					tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');
+				else
+					tinyMCE.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);
+
+				tinyMCE.imgElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);
+			}
+		}
+
+		if (tinyMCE.imgElement) {
+			var needsRepaint = false;
+			var msrc = src;
+
+			src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");
+
+			if (tinyMCE.getParam('convert_urls'))
+				msrc = src;
+
+			if (onmouseover && onmouseover != "")
+				onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";
+
+			if (onmouseout && onmouseout != "")
+				onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';";
+
+			// Use alt as title if it's undefined
+			if (typeof(title) == "undefined")
+				title = alt;
+
+			if (width != tinyMCE.imgElement.getAttribute("width") || height != tinyMCE.imgElement.getAttribute("height") || align != tinyMCE.imgElement.getAttribute("align"))
+				needsRepaint = true;
+
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'src', src);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'mce_src', msrc);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'alt', alt);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'title', title);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'align', align);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'border', border, true);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'hspace', hspace, true);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'vspace', vspace, true);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'width', width, true);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'height', height, true);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseover', onmouseover);
+			tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseout', onmouseout);
+
+			// Fix for bug #989846 - Image resize bug
+			if (width && width != "")
+				tinyMCE.imgElement.style.pixelWidth = width;
+
+			if (height && height != "")
+				tinyMCE.imgElement.style.pixelHeight = height;
+
+			if (needsRepaint)
+				tinyMCE.selectedInstance.repaint();
+		}
+
+		tinyMCE.execCommand('mceEndUndoLevel');
+	},
+
+	_insertLink : function(href, target, title, onclick, style_class) {
+		tinyMCE.execCommand('mceBeginUndoLevel');
+
+		if (tinyMCE.selectedInstance && tinyMCE.selectedElement && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
+			var doc = tinyMCE.selectedInstance.getDoc();
+			var linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
+			var newLink = false;
+
+			if (!linkElement) {
+				linkElement = doc.createElement("a");
+				newLink = true;
+			}
+
+			var mhref = href;
+			var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");
+			mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+
+			tinyMCE.setAttrib(linkElement, 'href', thref);
+			tinyMCE.setAttrib(linkElement, 'mce_href', mhref);
+			tinyMCE.setAttrib(linkElement, 'target', target);
+			tinyMCE.setAttrib(linkElement, 'title', title);
+			tinyMCE.setAttrib(linkElement, 'onclick', onclick);
+			tinyMCE.setAttrib(linkElement, 'class', style_class);
+
+			if (newLink) {
+				linkElement.appendChild(tinyMCE.selectedElement.cloneNode(true));
+				tinyMCE.selectedElement.parentNode.replaceChild(linkElement, tinyMCE.selectedElement);
+			}
+
+			return;
+		}
+
+		if (!tinyMCE.linkElement && tinyMCE.selectedInstance) {
+			if (tinyMCE.isSafari) {
+				tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + tinyMCE.selectedInstance.selection.getSelectedHTML() + '</a>');
+			} else
+				tinyMCE.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL);
+
+			tinyMCE.linkElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
+
+			var elementArray = tinyMCE.getElementsByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
+
+			for (var i=0; i<elementArray.length; i++) {
+				var mhref = href;
+				var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");
+				mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+
+				tinyMCE.setAttrib(elementArray[i], 'href', thref);
+				tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref);
+				tinyMCE.setAttrib(elementArray[i], 'target', target);
+				tinyMCE.setAttrib(elementArray[i], 'title', title);
+				tinyMCE.setAttrib(elementArray[i], 'onclick', onclick);
+				tinyMCE.setAttrib(elementArray[i], 'class', style_class);
+			}
+
+			tinyMCE.linkElement = elementArray[0];
+		}
+
+		if (tinyMCE.linkElement) {
+			var mhref = href;
+			href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement);");
+			mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'href', href);
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'mce_href', mhref);
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'target', target);
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'title', title);
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'onclick', onclick);
+			tinyMCE.setAttrib(tinyMCE.linkElement, 'class', style_class);
+		}
+
+		tinyMCE.execCommand('mceEndUndoLevel');
+	}
+};
+
+tinyMCE.addTheme("advanced", TinyMCE_AdvancedTheme);
+
+// Add default buttons maps for advanced theme and all internal plugins
+tinyMCE.addButtonMap(TinyMCE_AdvancedTheme._buttonMap);
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/image.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/image.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/image.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/image.htm	2006-04-17 18:27:18.000000000 -0500
@@ -2,44 +2,27 @@
 <head>
 	<title>{$lang_insert_image_title}</title>
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
+	<script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
 	<script language="javascript" type="text/javascript" src="../../utils/form_utils.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/image.js"></script>
-	<style type="text/css">
-		#insert, #cancel {
-			font: 13px Verdana, Arial, Helvetica, sans-serif;
-			height:auto;
-			width: auto;
-			background-color: transparent;
-			background-image: url(../../../../../wp-admin/images/fade-butt.png);
-			background-repeat: repeat;
-			border: 3px double;
-			border-right-color: rgb(153, 153, 153);
-			border-bottom-color: rgb(153, 153, 153);
-			border-left-color: rgb(204, 204, 204);
-			border-top-color: rgb(204, 204, 204);
-			color: rgb(51, 51, 51);
-			padding: 0.25em 1em;
-		}
-		#insert:active, #cancel:active {
-			background: #f4f4f4;
-			border-left-color: #999;
-			border-top-color: #999;
-		}
-	</style>
+	<base target="_self" />
 </head>
-<body onload="tinyMCEPopup.executeOnLoad('init();');document.getElementById('src').focus();" style="display: none">
-<form onsubmit="insertImage();return false;">
-  <table border="0" cellpadding="0" cellspacing="0" width="200">
-    <tr>
-      <td align="center" valign="middle"><table border="0" cellpadding="4" cellspacing="0">
-          <tr>
-            <td colspan="2" class="title" nowrap="nowrap">{$lang_insert_image_title}</td>
-          </tr>
+<body id="image" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('src').focus();" style="display: none">
+<form onsubmit="insertImage();return false;" action="#">
+	<div class="tabs">
+		<ul>
+			<li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{$lang_insert_image_title}</a></span></li>
+		</ul>
+	</div>
+
+	<div class="panel_wrapper">
+		<div id="general_panel" class="panel current">
+     <table border="0" cellpadding="4" cellspacing="0">
           <tr>
-            <td nowrap="nowrap">{$lang_insert_image_src}:</td>
+            <td nowrap="nowrap"><label for="src">{$lang_insert_image_src}</label></td>
             <td><table border="0" cellspacing="0" cellpadding="0">
                 <tr>
-                  <td><input name="src" type="text" id="src" value="" style="width: 200px" onchange="getImageData();"></td>
+                  <td><input id="src" name="src" type="text" value="" style="width: 200px" onchange="getImageData();"></td>
                   <td id="srcbrowsercontainer">&nbsp;</td>
                 </tr>
               </table></td>
@@ -49,8 +32,8 @@
 			if (typeof(tinyMCEImageList) != "undefined" && tinyMCEImageList.length > 0) {
 				var html = "";
 
-				html += '<tr><td>{$lang_image_list}:</td>';
-				html += '<td><select name="image_list" style="width: 200px" onchange="this.form.src.value=this.options[this.selectedIndex].value;resetImageData();getImageData();">';
+				html += '<tr><td><label for="image_list">{$lang_image_list}</label></td>';
+				html += '<td><select id="image_list" name="image_list" style="width: 200px" onchange="this.form.src.value=this.options[this.selectedIndex].value;resetImageData();getImageData();">';
 				html += '<option value="">---</option>';
 
 				for (var i=0; i<tinyMCEImageList.length; i++)
@@ -63,12 +46,12 @@
 		  </script>
 		  <!-- /Image list -->
           <tr>
-            <td nowrap="nowrap">{$lang_insert_image_alt}:</td>
-            <td><input name="alt" type="text" id="alt" value="" style="width: 200px"></td>
+            <td nowrap="nowrap"><label for="alt">{$lang_insert_image_alt}</label></td>
+            <td><input id="alt" name="alt" type="text" value="" style="width: 200px"></td>
           </tr>
           <tr>
-            <td nowrap="nowrap">{$lang_insert_image_align}:</td>
-            <td><select name="align">
+            <td nowrap="nowrap"><label for="align">{$lang_insert_image_align}</label></td>
+            <td><select id="align" name="align">
                 <option value="">{$lang_insert_image_align_default}</option>
                 <option value="baseline">{$lang_insert_image_align_baseline}</option>
                 <option value="top">{$lang_insert_image_align_top}</option>
@@ -82,31 +65,36 @@
               </select></td>
           </tr>
           <tr>
-            <td nowrap="nowrap"><!--{$lang_insert_image_dimensions}:</td>
-            <td><input name="width" type="text" id="width" value="" size="3" maxlength="3">
+            <td nowrap="nowrap"><label for="width">{$lang_insert_image_dimensions}</label></td>
+            <td><input id="width" name="width" type="text" value="" size="4" maxlength="4">
               x
-              <input name="height" type="text" id="height" value="" size="3" maxlength="3">--></td>
-          </tr>
-<!--          <tr>
-            <td nowrap="nowrap">{$lang_insert_image_border}:</td>
-            <td><input name="border" type="text" id="border" value="" size="3" maxlength="3"></td>
+              <input id="height" name="height" type="text" value="" size="4" maxlength="4"></td>
           </tr>
           <tr>
-            <td nowrap="nowrap">{$lang_insert_image_vspace}:</td>
-            <td><input name="vspace" type="text" id="vspace" value="" size="3" maxlength="3"></td>
+            <td nowrap="nowrap"><label for="border">{$lang_insert_image_border}</label></td>
+            <td><input id="border" name="border" type="text" value="" size="4" maxlength="4"></td>
           </tr>
           <tr>
-            <td nowrap="nowrap">{$lang_insert_image_hspace}:</td>
-            <td><input name="hspace" type="text" id="hspace" value="" size="3" maxlength="3"></td>
+            <td nowrap="nowrap"><label for="vspace">{$lang_insert_image_vspace}</label></td>
+            <td><input id="vspace" name="vspace" type="text" value="" size="4" maxlength="4"></td>
           </tr>
--->          <tr>
-            <td nowrap="nowrap"><input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertImage();">
-            </td>
-            <td align="right"><input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();"></td>
+          <tr>
+            <td nowrap="nowrap"><label for="hspace">{$lang_insert_image_hspace}</label></td>
+            <td><input id="hspace" name="hspace" type="text" value="" size="4" maxlength="4"></td>
           </tr>
-        </table></td>
-    </tr>
-  </table>
+        </table>
+		</div>
+	</div>
+
+	<div class="mceActionPanel">
+		<div style="float: left">
+			<input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
+		</div>
+
+		<div style="float: right">
+			<input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertImage();" />
+		</div>
+	</div>
 </form>
 </body>
 </html>
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/backcolor.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/backcolor.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/bold_es.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/bold_es.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/bold_tw.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/bold_tw.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/button_menu.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/button_menu.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/buttons.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/buttons.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/colors.jpg and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/colors.jpg differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/forecolor.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/forecolor.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/help.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/help.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/italic_es.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/italic_es.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/italic_tw.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/italic_tw.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/justifycenter.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/justifycenter.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/justifyfull.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/justifyfull.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/justifyleft.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/justifyleft.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/justifyright.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/justifyright.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/menu_check.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/menu_check.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/opacity.png and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/opacity.png differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/separator.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/separator.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/underline_es.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/underline_es.gif differ
Binary files 2.0.5/wp-includes/js/tinymce/themes/advanced/images/underline_tw.gif and 2.2.2/wp-includes/js/tinymce/themes/advanced/images/underline_tw.gif differ
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/about.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/about.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/about.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/about.js	2006-03-30 01:50:33.000000000 -0600
@@ -1,5 +1,8 @@
 function init() {
+	var inst;
+
 	tinyMCEPopup.resizeToInnerSize();
+	inst = tinyMCE.selectedInstance;
 
 	// Give FF some time
 	window.setTimeout('insertHelpIFrame();', 10);
@@ -20,8 +23,8 @@
 	html += '</thead>';
 	html += '<tbody>';
 
-	for (var i=0; i<plugins.length; i++) {
-		var info = getPluginInfo(plugins[i]);
+	for (var i=0; i<inst.plugins.length; i++) {
+		var info = getPluginInfo(inst.plugins[i]);
 
 		html += '<tr>';
 
@@ -46,10 +49,8 @@
 }
 
 function getPluginInfo(name) {
-	var fn = eval('tinyMCEPopup.windowOpener.TinyMCE_' + name + '_getInfo');
-
-	if (typeof(fn) != 'undefined')
-		return fn();
+	if (tinyMCE.plugins[name].getInfo)
+		return tinyMCE.plugins[name].getInfo();
 
 	return {
 		longname : name,
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/anchor.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/anchor.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/anchor.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/anchor.js	2006-03-30 01:50:33.000000000 -0600
@@ -26,7 +26,7 @@
 
 function insertAnchor() {
 	var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id'));
-	var name = document.forms[0].anchorName.value;
+	var name = document.forms[0].anchorName.value, e;
 
 	tinyMCEPopup.execCommand("mceBeginUndoLevel");
 
@@ -44,11 +44,26 @@
 		name = name.replace(/&/g, '&amp;');
 		name = name.replace(/\"/g, '&quot;');
 		name = name.replace(/</g, '&lt;');
-		name = name.replace(/>/g, '&gr;');
+		name = name.replace(/>/g, '&gt;');
 
-		html = '<a name="' + name + '"></a>';
+		// Fix for bug #1447335
+		if (tinyMCE.isGecko)
+			html = '<a id="mceNewAnchor" name="' + name + '"></a>';
+		else
+			html = '<a name="' + name + '"></a>';
 
 		tinyMCEPopup.execCommand("mceInsertContent", false, html);
+
+		// Fix for bug #1447335 force cursor after the anchor element
+		if (tinyMCE.isGecko) {
+			e = inst.getDoc().getElementById('mceNewAnchor');
+
+			if (e) {
+				inst.selection.selectNode(e, true, false, false);
+				e.removeAttribute('id');
+			}
+		}
+
 		tinyMCE.handleVisualAid(inst.getBody(), true, inst.visualAid, inst);
 	}
 
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/charmap.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/charmap.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/charmap.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/charmap.js	2006-03-30 01:50:33.000000000 -0600
@@ -170,7 +170,7 @@
 	['&yacute;',  '&#253;',  true, 'y - acute'],
 	['&thorn;',   '&#254;',  true, 'thorn'],
 	['&yuml;',    '&#255;',  true, 'y - diaeresis'],
-// ['&Alpha;',   '&#913;',  true, 'Alpha'],
+    ['&Alpha;',   '&#913;',  true, 'Alpha'],
 	['&Beta;',    '&#914;',  true, 'Beta'],
 	['&Gamma;',   '&#915;',  true, 'Gamma'],
 	['&Delta;',   '&#916;',  true, 'Delta'],
@@ -279,9 +279,9 @@
 			cols++;
 			html += ''
 				+ '<td width="' + tdWidth + '" height="' + tdHeight + '" class="charmap"'
-				+ ' onmouseover="tinyMCE.switchClass(this,\'charmapOver\');'
+				+ ' onmouseover="this.className=\'charmapOver\';'
 				+ 'previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');"'
-				+ ' onmouseout="tinyMCE.restoreClass(this,\'charmapOver\');"'
+				+ ' onmouseout="this.className=\'charmap\';"'
 				+ ' nowrap="nowrap" onclick="insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');"><a style="text-decoration: none;" onfocus="previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');" href="javascript:insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');" onclick="return false;" onmousedown="return false;" title="' + charmap[i][3] + '">'
 				+ charmap[i][1]
 				+ '</a></td>';
@@ -299,11 +299,13 @@
 }
 
 function insertChar(chr) {
-	tinyMCEPopup.execCommand('mceInsertContent', false, '\&#' + chr + ';');
+	tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';');
 
 	// Refocus in window
 	if (tinyMCEPopup.isWindow)
 		window.focus();
+
+	tinyMCEPopup.close();
 }
 
 function previewChar(codeA, codeB, codeN) {
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/color_picker.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,19 +1,4 @@
-function init() {
-	if (tinyMCE.isMSIE)
-		tinyMCEPopup.resizeToInnerSize();
-}
-
-function selectColor() {
-	var color = document.getElementById("selectedColorBox").value;
-
-	tinyMCEPopup.execCommand(tinyMCE.getWindowArg('command'), false, color);
-	tinyMCEPopup.close();
-}
-
-function showColor(color) {
-	document.getElementById("selectedColor").style.backgroundColor = color;
-	document.getElementById("selectedColorBox").value = color;
-}
+var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false;
 
 var colors = new Array(
 	"#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033",
@@ -45,9 +30,71 @@
 	"#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff"
 );
 
+var named = {
+	'#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige',
+	'#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown',
+	'#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue',
+	'#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod',
+	'#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen',
+	'#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue',
+	'#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue',
+	'#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen',
+	'#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey',
+	'#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory',
+	'#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue',
+	'#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen',
+	'#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey',
+	'#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon',
+	'#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue',
+	'#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin',
+	'#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid',
+	'#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff',
+	'#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue',
+	'#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver',
+	'#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen',
+	'#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet',
+	'#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen'
+};
+
+function init() {
+	var inputColor = convertRGBToHex(tinyMCE.getWindowArg('input_color'));
+
+	if (tinyMCE.isMSIE)
+		tinyMCEPopup.resizeToInnerSize();
+
+	generatePicker();
+
+	if (inputColor) {
+		changeFinalColor(inputColor);
+
+		col = convertHexToRGB(inputColor);
+
+		if (col)
+			updateLight(col.r, col.g, col.b);
+	}
+}
+
+function insertAction() {
+	var color = document.getElementById("color").value;
+
+	tinyMCEPopup.execCommand(tinyMCE.getWindowArg('command'), false, color);
+	tinyMCEPopup.close();
+}
+
+function showColor(color, name) {
+	if (name)
+		document.getElementById("colorname").innerHTML = name;
+
+	document.getElementById("preview").style.backgroundColor = color;
+	document.getElementById("color").value = color;
+}
+
 function convertRGBToHex(col) {
 	var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi");
 
+	if (!col)
+		return col;
+
 	var rgb = col.replace(re, "$1,$2,$3").split(',');
 	if (rgb.length == 3) {
 		r = parseInt(rgb[0]).toString(16);
@@ -72,36 +119,131 @@
 		g = parseInt(col.substring(2, 4), 16);
 		b = parseInt(col.substring(4, 6), 16);
 
-		return "rgb(" + r + "," + g + "," + b + ")";
+		return {r : r, g : g, b : b};
 	}
 
-	return col;
+	return null;
 }
 
-function renderColorMap() {
-	var html = "";
-	var inputColor = convertRGBToHex(tinyMCE.getWindowArg('input_color'));
+function generatePicker() {
+	var el = document.getElementById('light'), h = '', i;
 
-	html += '<table border="0" cellspacing="1" cellpadding="0">'
+	for (i = 0; i < detail; i++){
+		h += '<div id="gs'+i+'" style="background-color:#000000; width:15px; height:3px; border-style:none; border-width:0px;"'
+		+ ' onclick="changeFinalColor(this.style.backgroundColor)"'
+		+ ' onmousedown="isMouseDown = true; return false;"'
+		+ ' onmouseup="isMouseDown = false;"'
+		+ ' onmousemove="if (isMouseDown && isMouseOver) changeFinalColor(this.style.backgroundColor); return false;"'
+		+ ' onmouseover="isMouseOver = true;"'
+		+ ' onmouseout="isMouseOver = false;"'
+		+ '></div>';
+	}
+
+	el.innerHTML = h;
+}
+
+function generateWebColors() {
+	var el = document.getElementById('webcolors'), h = '', i;
+
+	if (el.className == 'generated')
+		return;
+
+	h += '<table border="0" cellspacing="1" cellpadding="0">'
 		+ '<tr>';
-	for (var i=0; i<colors.length; i++) {
-		html += '<td bgcolor="' + colors[i] + '">'
+
+	for (i=0; i<colors.length; i++) {
+		h += '<td bgcolor="' + colors[i] + '">'
 			+ '<a href="javascript:selectColor();" onfocus="showColor(\'' + colors[i] +  '\');" onmouseover="showColor(\'' + colors[i] +  '\');">'
 			+ '<img border="0" src="images/spacer.gif" width="10" height="10" title="' + colors[i] +  '" alt="' + colors[i] +  '" /></a></td>';
 		if ((i+1) % 18 == 0)
-			html += '</tr><tr>';
+			h += '</tr><tr>';
+	}
+
+	h += '</table>';
+
+	el.innerHTML = h;
+	el.className = 'generated';
+}
+
+function generateNamedColors() {
+	var el = document.getElementById('namedcolors'), h = '', n, v, i = 0;
+
+	if (el.className == 'generated')
+		return;
+
+	for (n in named) {
+		v = named[n];
+		h += '<a href="javascript:selectColor();" onmouseover="showColor(\'' + n +  '\',\'' + v + '\');" style="background-color: ' + n + '"><!-- IE --></a>'
+	}
+
+	el.innerHTML = h;
+	el.className = 'generated';
+}
+
+function selectColor() {
+	var color = document.getElementById("color").value;
+
+	if(window.opener)
+		window.opener.tinyMCE.execInstanceCommand(tinyMCE.getWindowArg('editor_id'),tinyMCE.getWindowArg('command'),false,color);
+
+	window.close();
+}
+
+function dechex(n) {
+	return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16);
+}
+
+function computeColor(e) {
+	var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB;
+
+	x = e.offsetX ? e.offsetX : (e.target ? e.clientX - e.target.x : 0);
+	y = e.offsetY ? e.offsetY : (e.target ? e.clientY - e.target.y : 0);
+
+	partWidth = document.getElementById('colorpicker').width / 6;
+	partDetail = detail / 2;
+	imHeight = document.getElementById('colorpicker').height;
+
+	r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255;
+	g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255	+ (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth);
+	b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth);
+
+	coef = (imHeight - y) / imHeight;
+	r = 128 + (r - 128) * coef;
+	g = 128 + (g - 128) * coef;
+	b = 128 + (b - 128) * coef;
+
+	changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b));
+	updateLight(r, g, b);
+}
+
+function updateLight(r, g, b) {
+	var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color;
+
+	for (i=0; i<detail; i++) {
+		if ((i>=0) && (i<partDetail)) {
+			finalCoef = i / partDetail;
+			finalR = dechex(255 - (255 - r) * finalCoef);
+			finalG = dechex(255 - (255 - g) * finalCoef);
+			finalB = dechex(255 - (255 - b) * finalCoef);
+		} else {
+			finalCoef = 2 - i / partDetail;
+			finalR = dechex(r * finalCoef);
+			finalG = dechex(g * finalCoef);
+			finalB = dechex(b * finalCoef);
+		}
+
+		color = finalR + finalG + finalB;
+
+		document.getElementById('gs' + i).style.backgroundColor = '#'+color;
 	}
-	html += '<tr><td colspan="18">'
-		+ '<table width="100%" border="0" cellspacing="0" cellpadding="0">'
-		+ '<tr><td>'
-		+ '<img id="selectedColor" style="background-color:' + tinyMCE.getWindowArg('input_color') + '" border="0" src="images/spacer.gif" width="80" height="16" />'
-		+ '</td><td align="right">'
-		+ '<input id="selectedColorBox" name="selectedColorBox" type="text" size="7" maxlength="7" style="width:65px" value="' + inputColor + '" />'
-		+ '</td></tr>'
-		+ '</table>'
-		+ '<input type="button" id="insert" name="insert" value="{$lang_theme_colorpicker_apply}" style="margin-top:3px" onclick="selectColor();">'
-		+ '</td></tr>'
-		+ '</table>';
+}
+
+function changeFinalColor(color) {
+	if (color.indexOf('#') == -1)
+		color = convertRGBToHex(color);
+
+	document.getElementById('preview').style.backgroundColor = color;
+	document.getElementById('color').value = color;
+}
 
-	document.write(html);
-}
\ No newline at end of file
+window.focus();
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/image.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/image.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/image.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/image.js	2006-03-30 01:50:33.000000000 -0600
@@ -8,19 +8,18 @@
 }
 
 function insertImage() {
-	if (window.opener) {
-		var src = document.forms[0].src.value;
-		var alt = document.forms[0].alt.value;
-		var border = '';//document.forms[0].border.value;
-		var vspace = '';//document.forms[0].vspace.value;
-		var hspace = '';//document.forms[0].hspace.value;
-		var width = '';//document.forms[0].width.value;
-		var height = '';//document.forms[0].height.value;
-		var align = document.forms[0].align.options[document.forms[0].align.selectedIndex].value;
-
-		window.opener.tinyMCE.insertImage(src, alt, border, hspace, vspace, width, height, align);
-		top.close();
-	}
+	var src = document.forms[0].src.value;
+	var alt = document.forms[0].alt.value;
+	var border = document.forms[0].border.value;
+	var vspace = document.forms[0].vspace.value;
+	var hspace = document.forms[0].hspace.value;
+	var width = document.forms[0].width.value;
+	var height = document.forms[0].height.value;
+	var align = document.forms[0].align.options[document.forms[0].align.selectedIndex].value;
+
+	tinyMCEPopup.restoreSelection();
+	tinyMCE.themes['advanced']._insertImage(src, alt, border, hspace, vspace, width, height, align);
+	tinyMCEPopup.close();
 }
 
 function init() {
@@ -37,11 +36,11 @@
 
 	formObj.src.value = tinyMCE.getWindowArg('src');
 	formObj.alt.value = tinyMCE.getWindowArg('alt');
-//	formObj.border.value = tinyMCE.getWindowArg('border');
-//	formObj.vspace.value = tinyMCE.getWindowArg('vspace');
-//	formObj.hspace.value = tinyMCE.getWindowArg('hspace');
-//	formObj.width.value = tinyMCE.getWindowArg('width');
-//	formObj.height.value = tinyMCE.getWindowArg('height');
+	formObj.border.value = tinyMCE.getWindowArg('border');
+	formObj.vspace.value = tinyMCE.getWindowArg('vspace');
+	formObj.hspace.value = tinyMCE.getWindowArg('hspace');
+	formObj.width.value = tinyMCE.getWindowArg('width');
+	formObj.height.value = tinyMCE.getWindowArg('height');
 	formObj.insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true); 
 
 	// Handle file browser
@@ -67,11 +66,11 @@
 function updateImageData() {
 	var formObj = document.forms[0];
 
-//	if (formObj.width.value == "")
-//		formObj.width.value = preloadImg.width;
+	if (formObj.width.value == "")
+		formObj.width.value = preloadImg.width;
 
-//	if (formObj.height.value == "")
-//		formObj.height.value = preloadImg.height;
+	if (formObj.height.value == "")
+		formObj.height.value = preloadImg.height;
 }
 
 function getImageData() {
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/link.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/link.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/link.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/link.js	2007-04-12 12:04:03.000000000 -0500
@@ -10,7 +10,11 @@
 function init() {
 	tinyMCEPopup.resizeToInnerSize();
 
-//	document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','theme_advanced_link');
+	document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','theme_advanced_link');
+
+	// Handle file browser
+	if (isVisible('hrefbrowser'))
+		document.getElementById('href').style.width = '180px';
 
 	var formObj = document.forms[0];
 
@@ -21,16 +25,21 @@
 			option.selected = true;
 	}
 
-	document.forms[0].href.value = tinyMCE.getWindowArg('href');
+	document.forms[0].href.value = tinyMCE.getWindowArg('href') || 'http://';
+	document.forms[0].href.select();
+	document.forms[0].href.focus();
 	document.forms[0].linktitle.value = tinyMCE.getWindowArg('title');
 	document.forms[0].insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true); 
 
-//	addClassesToList('styleSelect', 'theme_advanced_link_styles');
-//	selectByValue(formObj, 'styleSelect', tinyMCE.getWindowArg('className'), true);
+	addClassesToList('styleSelect', 'theme_advanced_link_styles');
+	selectByValue(formObj, 'styleSelect', tinyMCE.getWindowArg('className'), true);
 
-	// Handle file browser
-	if (isVisible('hrefbrowser'))
-		document.getElementById('href').style.width = '180px';
+	// Hide css select row if no CSS classes
+	if (formObj.styleSelect && formObj.styleSelect.options.length <= 1) {
+		var sr = document.getElementById('styleSelectRow');
+		sr.style.display = 'none';
+		sr.parentNode.removeChild(sr);
+	}
 
 	// Auto select link in list
 	if (typeof(tinyMCELinkList) != "undefined" && tinyMCELinkList.length > 0) {
@@ -44,21 +53,20 @@
 }
 
 function insertLink() {
-	if (window.opener) {
-		var href = document.forms[0].href.value;
-		var target = document.forms[0].target.options[document.forms[0].target.selectedIndex].value;
-		var title = document.forms[0].linktitle.value;
-		var style_class = '';//document.forms[0].styleSelect.value;
-		var dummy;
-
-		// Make anchors absolute
-		if (href.charAt(0) == '#')
-			href = tinyMCE.settings['document_base_url'] + href;
-
-		if (target == '_self')
-			target = '';
-
-		window.opener.tinyMCE.insertLink(href, target, title, dummy, style_class);
-		tinyMCEPopup.close();
-	}
+	var href = document.forms[0].href.value;
+	var target = document.forms[0].target.options[document.forms[0].target.selectedIndex].value;
+	var title = document.forms[0].linktitle.value;
+	var style_class = document.forms[0].styleSelect ? document.forms[0].styleSelect.value : "";
+	var dummy;
+	
+	// WordPress: Make anchors absolute;
+	if (href.charAt(0) == '#')
+		href = tinyMCE.settings['document_base_url'] + href;
+
+	if (target == '_self')
+		target = '';
+
+	tinyMCEPopup.restoreSelection();
+	tinyMCE.themes['advanced']._insertLink(href, target, title, dummy, style_class);
+	tinyMCEPopup.close();
 }
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/source_editor.js 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/source_editor.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/jscripts/source_editor.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/jscripts/source_editor.js	2007-01-24 19:20:47.000000000 -0600
@@ -3,29 +3,35 @@
 	tinyMCE.closeWindow(window);
 }
 
-// Fixes some charcode issues
-function fixContent(html) {
-	// WP
-	return html;
-
-	html = html.replace(new RegExp('<(p|hr|table|tr|td|ol|ul|object|embed|li|blockquote)', 'gi'),'\n<$1');
-	html = html.replace(new RegExp('<\/(p|ol|ul|li|table|tr|td|blockquote|object)>', 'gi'),'</$1>\n');
-	html = tinyMCE.regexpReplace(html, '<br />','<br />\n','gi');
-	html = tinyMCE.regexpReplace(html, '\n\n','\n','gi');
-	return html;
-}
-
 function onLoadInit() {
 	tinyMCEPopup.resizeToInnerSize();
 
-	document.forms[0].htmlSource.value = fixContent(tinyMCE.getContent(tinyMCE.getWindowArg('editor_id')));
+	// Remove Gecko spellchecking
+	if (tinyMCE.isGecko)
+		document.body.spellcheck = tinyMCE.getParam("gecko_spellcheck");
+
+	document.getElementById('htmlSource').value = tinyMCE.getContent(tinyMCE.getWindowArg('editor_id'));
+
 	resizeInputs();
-	setWrap('off');
+
+	if (tinyMCE.getParam("theme_advanced_source_editor_wrap", true)) {
+		setWrap('soft');
+		document.getElementById('wraped').checked = true;
+	}
 }
 
 function setWrap(val) {
-	// hard soft off
-	document.forms[0].htmlSource.wrap = val;
+	var s = document.getElementById('htmlSource');
+
+	s.wrap = val;
+
+	if (tinyMCE.isGecko || tinyMCE.isOpera) {
+		var v = s.value;
+		var n = s.cloneNode(false);
+		n.setAttribute("wrap", val);
+		s.parentNode.replaceChild(n, s);
+		n.value = v;
+	}
 }
 
 function toggleWordWrap(elm) {
@@ -38,19 +44,16 @@
 var wHeight=0, wWidth=0, owHeight=0, owWidth=0;
 
 function resizeInputs() {
+	var el = document.getElementById('htmlSource');
+
 	if (!tinyMCE.isMSIE) {
-		 wHeight = self.innerHeight-80;
-		 wWidth = self.innerWidth-16;
+		 wHeight = self.innerHeight - 60;
+		 wWidth = self.innerWidth - 16;
 	} else {
-		 wHeight = document.body.clientHeight - 80;
+		 wHeight = document.body.clientHeight - 60;
 		 wWidth = document.body.clientWidth - 16;
 	}
 
-	document.forms[0].htmlSource.style.height = Math.abs(wHeight) + 'px';
-	document.forms[0].htmlSource.style.width  = Math.abs(wWidth) + 'px';
-}
-
-function renderWordWrap() {
-	if (tinyMCE.isMSIE)
-		document.write('<input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{$lang_theme_code_wordwrap}</label>');
+	el.style.height = Math.abs(wHeight) + 'px';
+	el.style.width  = Math.abs(wWidth) + 'px';
 }
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/langs/en.js 2.2.2/wp-includes/js/tinymce/themes/advanced/langs/en.js
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/langs/en.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/langs/en.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,76 +1,91 @@
-// UK lang variables
-
-tinyMCE.addToLang('',{
-theme_style_select : '-- Styles --',
-theme_code_desc : 'Edit HTML Source (Alt+e)',
-theme_code_title : 'HTML Source Editor',
-theme_code_wordwrap : 'Word wrap',
-theme_sub_desc : 'Subscript',
-theme_sup_desc : 'Superscript',
-theme_hr_desc : 'Insert horizontal ruler',
-theme_removeformat_desc : 'Remove formatting',
-theme_custom1_desc : 'Your custom description here',
-insert_image_border : 'Border',
-insert_image_dimensions : 'Dimensions',
-insert_image_vspace : 'Vertical space',
-insert_image_hspace : 'Horizontal space',
-insert_image_align : 'Alignment',
-insert_image_align_default : '-- Not set --',
-insert_image_align_baseline : 'Baseline',
-insert_image_align_top : 'Top',
-insert_image_align_middle : 'Middle',
-insert_image_align_bottom : 'Bottom',
-insert_image_align_texttop : 'TextTop',
-insert_image_align_absmiddle : 'Absolute Middle',
-insert_image_align_absbottom : 'Absolute Bottom',
-insert_image_align_left : 'Left',
-insert_image_align_right : 'Right',
-theme_font_size : '-- Font size --',
-theme_fontdefault : '-- Font family --',
-theme_block : '-- Format --',
-theme_paragraph : 'Paragraph',
-theme_div : 'Div',
-theme_address : 'Address',
-theme_pre : 'Preformatted',
-theme_h1 : 'Heading 1',
-theme_h2 : 'Heading 2',
-theme_h3 : 'Heading 3',
-theme_h4 : 'Heading 4',
-theme_h5 : 'Heading 5',
-theme_h6 : 'Heading 6',
-theme_colorpicker_title : 'Select a color',
-theme_colorpicker_apply : 'Apply',
-theme_forecolor_desc : 'Select text color',
-theme_backcolor_desc : 'Select background color',
-theme_charmap_title : 'Select custom character',
-theme_charmap_desc : 'Insert custom character',
-theme_visualaid_desc : 'Toggle guidelines/invisible elements',
-insert_anchor_title : 'Insert/edit anchor',
-insert_anchor_name : 'Anchor name',
-theme_anchor_desc : 'Insert/edit anchor',
-theme_insert_link_titlefield : 'Title',
-theme_clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?',
-theme_path : 'Path',
-cut_desc : 'Cut',
-copy_desc : 'Copy',
-paste_desc : 'Paste',
-link_list : 'Link list',
-image_list : 'Image list',
-browse : 'Browse',
-image_props_desc : 'Image properties',
-newdocument_desc : 'New document',
-class_name : 'Class',
-newdocument : 'Are you sure you want clear all contents?',
-about_title : 'About TinyMCE',
-about : 'About',
-license : 'License',
-plugins : 'Plugins',
-plugin : 'Plugin',
-author : 'Author',
-version : 'Version',
-loaded_plugins : 'Loaded plugins',
-help : 'Help',
-not_set : '-- Not set --',
-close : 'Close',
-toolbar_focus : 'Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X'
-});
+// UK lang variables
+
+tinyMCE.addToLang('',{
+theme_style_select : '-- Styles --',
+theme_code_desc : 'Edit HTML Source',
+theme_code_title : 'HTML Source Editor',
+theme_code_wordwrap : 'Word wrap',
+theme_sub_desc : 'Subscript',
+theme_sup_desc : 'Superscript',
+theme_hr_desc : 'Insert horizontal ruler',
+theme_removeformat_desc : 'Remove formatting',
+theme_custom1_desc : 'Your custom description here',
+insert_image_border : 'Border',
+insert_image_dimensions : 'Dimensions',
+insert_image_vspace : 'Vertical space',
+insert_image_hspace : 'Horizontal space',
+insert_image_align : 'Alignment',
+insert_image_align_default : '-- Not set --',
+insert_image_align_baseline : 'Baseline',
+insert_image_align_top : 'Top',
+insert_image_align_middle : 'Middle',
+insert_image_align_bottom : 'Bottom',
+insert_image_align_texttop : 'TextTop',
+insert_image_align_absmiddle : 'Absolute Middle',
+insert_image_align_absbottom : 'Absolute Bottom',
+insert_image_align_left : 'Left',
+insert_image_align_right : 'Right',
+theme_font_size : '-- Font size --',
+theme_fontdefault : '-- Font family --',
+theme_block : '-- Format --',
+theme_paragraph : 'Paragraph',
+theme_div : 'Div',
+theme_address : 'Address',
+theme_pre : 'Preformatted',
+theme_h1 : 'Heading 1',
+theme_h2 : 'Heading 2',
+theme_h3 : 'Heading 3',
+theme_h4 : 'Heading 4',
+theme_h5 : 'Heading 5',
+theme_h6 : 'Heading 6',
+theme_blockquote : 'Blockquote',
+theme_code : 'Code',
+theme_samp : 'Code sample',
+theme_dt : 'Definition term ',
+theme_dd : 'Definition description',
+theme_colorpicker_title : 'Select a color',
+theme_colorpicker_apply : 'Apply',
+theme_forecolor_desc : 'Select text color',
+theme_backcolor_desc : 'Select background color',
+theme_charmap_title : 'Select custom character',
+theme_charmap_desc : 'Insert custom character',
+theme_visualaid_desc : 'Toggle guidelines/invisible elements',
+insert_anchor_title : 'Insert/edit anchor',
+insert_anchor_name : 'Anchor name',
+theme_anchor_desc : 'Insert/edit anchor',
+theme_insert_link_titlefield : 'Title',
+theme_clipboard_msg : 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?',
+theme_path : 'Path',
+cut_desc : 'Cut',
+copy_desc : 'Copy',
+paste_desc : 'Paste',
+link_list : 'Link list',
+image_list : 'Image list',
+browse : 'Browse',
+image_props_desc : 'Image properties',
+newdocument_desc : 'New document',
+class_name : 'Class',
+newdocument : 'Are you sure you want clear all contents?',
+about_title : 'About TinyMCE',
+about : 'About',
+license : 'License',
+plugins : 'Plugins',
+plugin : 'Plugin',
+author : 'Author',
+version : 'Version',
+loaded_plugins : 'Loaded plugins',
+help : 'Help',
+not_set : '-- Not set --',
+close : 'Close',
+toolbar_focus : 'Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X',
+invalid_data : 'Error: Invalid values entered, these are marked in red.',
+more_colors : 'More colors',
+color_picker_tab : 'Picker',
+color_picker : 'Color picker',
+web_colors_tab : 'Web safe',
+web_colors : 'Web safe colors',
+named_colors_tab : 'Named',
+named_colors : 'Named colors',
+color : 'Color:',
+color_name : 'Name:'
+});
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/link.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/link.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/link.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/link.htm	2006-03-30 01:50:33.000000000 -0600
@@ -2,55 +2,39 @@
 <head>
 	<title>{$lang_insert_link_title}</title>
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
+	<script language="javascript" type="text/javascript" src="../../utils/mctabs.js"></script>
 	<script language="javascript" type="text/javascript" src="../../utils/form_utils.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/link.js"></script>
-	<style type="text/css">
-		#insert, #cancel {
-			font: 13px Verdana, Arial, Helvetica, sans-serif;
-			height: auto;
-			width: auto;
-			background-color: transparent;
-			background-image: url(../../../../../wp-admin/images/fade-butt.png);
-			background-repeat: repeat;
-			border: 3px double;
-			border-right-color: rgb(153, 153, 153);
-			border-bottom-color: rgb(153, 153, 153);
-			border-left-color: rgb(204, 204, 204);
-			border-top-color: rgb(204, 204, 204);
-			color: rgb(51, 51, 51);
-			padding: 0.25em 0.75em;
-		}
-		#insert:active, #cancel:active {
-			background: #f4f4f4;
-			border-left-color: #999;
-			border-top-color: #999;
-		}
-	</style>
+	<base target="_self" />
 </head>
-<body onload="tinyMCEPopup.executeOnLoad('init();');document.getElementById('href').focus();" style="display: none">
-<form onsubmit="insertLink();return false;">
-  <table border="0" cellpadding="0" cellspacing="0" width="100">
-    <tr>
-      <td align="center" valign="middle"><table border="0" cellpadding="4" cellspacing="0">
-          <tr>
-            <td colspan="2" class="title" nowrap="nowrap">{$lang_insert_link_title}</td>
-          </tr>
+<body id="link" onload="tinyMCEPopup.executeOnLoad('init();');document.body.style.display='';document.getElementById('href').focus();" style="display: none">
+<form onsubmit="insertLink();return false;" action="#">
+	<div class="tabs">
+		<ul>
+			<li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{$lang_insert_link_title}</a></span></li>
+		</ul>
+	</div>
+
+	<div class="panel_wrapper">
+		<div id="general_panel" class="panel current">
+
+		<table border="0" cellpadding="4" cellspacing="0">
           <tr>
-            <td nowrap="nowrap">{$lang_insert_link_url}:</td>
-            <td>              <table border="0" cellspacing="0" cellpadding="0">
-                <tr>
-                  <td><input name="href" type="text" id="href" value="" style="width: 200px"></td>
-                  <td id="hrefbrowsercontainer">&nbsp;</td>
-                </tr>
-              </table></td>
+            <td nowrap="nowrap"><label for="href">{$lang_insert_link_url}</label></td>
+            <td><table border="0" cellspacing="0" cellpadding="0"> 
+				  <tr> 
+					<td><input id="href" name="href" type="text" value="" style="width: 200px" /></td> 
+					<td id="hrefbrowsercontainer">&nbsp;</td>
+				  </tr> 
+				</table></td>
           </tr>
 		  <!-- Link list -->
 		  <script language="javascript">
 			if (typeof(tinyMCELinkList) != "undefined" && tinyMCELinkList.length > 0) {
 				var html = "";
 
-				html += '<tr><td>{$lang_link_list}:</td>';
-				html += '<td><select name="link_list" style="width: 200px" onchange="this.form.href.value=this.options[this.selectedIndex].value;">';
+				html += '<tr><td><label for="link_list">{$lang_link_list}</label></td>';
+				html += '<td><select id="link_list" name="link_list" style="width: 200px" onchange="this.form.href.value=this.options[this.selectedIndex].value;">';
 				html += '<option value="">---</option>';
 
 				for (var i=0; i<tinyMCELinkList.length; i++)
@@ -63,8 +47,8 @@
 		  </script>
 		  <!-- /Link list -->
           <tr>
-            <td nowrap="nowrap">{$lang_insert_link_target}:</td>
-            <td><select name="target" style="width: 200px">
+            <td nowrap="nowrap"><label for="target">{$lang_insert_link_target}</label></td>
+            <td><select id="target" name="target" style="width: 200px">
                 <option value="_self">{$lang_insert_link_target_same}</option>
                 <option value="_blank">{$lang_insert_link_target_blank}</option>
 				<script language="javascript">
@@ -88,26 +72,29 @@
             </select></td>
           </tr>
           <tr>
-            <td nowrap="nowrap">{$lang_theme_insert_link_titlefield}:</td>
-            <td><input name="linktitle" type="text" id="linktitle" value="" style="width: 200px"></td>
+            <td nowrap="nowrap"><label for="linktitle">{$lang_theme_insert_link_titlefield}</label></td>
+            <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px"></td>
           </tr>
           <tr id="styleSelectRow">
-            <td><!--{$lang_class_name}:</td>
+            <td><label for="styleSelect">{$lang_class_name}</label></td>
             <td>
 			 <select id="styleSelect" name="styleSelect">
                 <option value="" selected>{$lang_theme_style_select}</option>
              </select></td>
-            <td align="right">&nbsp;</td>
-            <td align="right">&nbsp;--></td>
-          </tr>
-          <tr>
-            <td><input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertLink();">
-            </td>
-            <td align="right"><input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();"></td>
           </tr>
-        </table></td>
-    </tr>
-  </table>
+        </table>
+		</div>
+	</div>
+
+	<div class="mceActionPanel">
+		<div style="float: left">
+			<input type="button" id="cancel" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" />
+		</div>
+
+		<div style="float: right">
+			<input type="submit" id="insert" name="insert" value="{$lang_insert}" onclick="insertLink();" />
+		</div>
+	</div>
 </form>
 </body>
 </html>
diff -ruN 2.0.5/wp-includes/js/tinymce/themes/advanced/source_editor.htm 2.2.2/wp-includes/js/tinymce/themes/advanced/source_editor.htm
--- 2.0.5/wp-includes/js/tinymce/themes/advanced/source_editor.htm	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/themes/advanced/source_editor.htm	2007-01-08 19:16:40.000000000 -0600
@@ -4,46 +4,27 @@
 	<title>{$lang_theme_code_title}</title>
 	<script language="javascript" type="text/javascript" src="../../tiny_mce_popup.js"></script>
 	<script language="javascript" type="text/javascript" src="jscripts/source_editor.js"></script>
-	<style type="text/css">
-		#insert, #cancel {
-			font: 13px Verdana, Arial, Helvetica, sans-serif;
-			height: auto;
-			width: auto;
-			background-color: transparent;
-			background-image: url(../../../../../wp-admin/images/fade-butt.png);
-			background-repeat: repeat;
-			border: 3px double;
-			border-right-color: rgb(153, 153, 153);
-			border-bottom-color: rgb(153, 153, 153);
-			border-left-color: rgb(204, 204, 204);
-			border-top-color: rgb(204, 204, 204);
-			color: rgb(51, 51, 51);
-			padding: 0.25em 0.75em;
-		}
-		#insert:active, #cancel:active {
-			background: #f4f4f4;
-			border-left-color: #999;
-			border-top-color: #999;
-		}
-	</style>
+	<base target="_self" />
 </head>
-<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none">
+<body onload="tinyMCEPopup.executeOnLoad('onLoadInit();');document.body.style.display='';document.getElementById('htmlSource').focus();" onresize="resizeInputs();" style="display: none">
 	<form name="source" onsubmit="saveContent();" action="#">
 		<div style="float: left" class="title">{$lang_theme_code_title}</div>
 
-		<div style="float: right">
-			<script language="javascript" type="text/javascript">renderWordWrap();</script>
+		<div id="wrapline" style="float: right">
+			<input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{$lang_theme_code_wordwrap}</label>
 		</div>
 
-		<textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft"></textarea>
+		<br style="clear: both" />
+
+		<textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px" dir="ltr" wrap="off"></textarea>
 
 		<div class="mceActionPanel">
 			<div style="float: left">
-				<input type="button" name="insert" value="{$lang_update}" onclick="saveContent();" id="insert" />
+				<input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
 			</div>
 
 			<div style="float: right">
-				<input type="button" name="cancel" value="{$lang_cancel}" onclick="tinyMCEPopup.close();" id="cancel" />
+				<input type="submit" name="insert" value="{$lang_update}" onclick="saveContent();" id="insert" />
 			</div>
 		</div>
 	</form>
diff -ruN 2.0.5/wp-includes/js/tinymce/tiny_mce.js 2.2.2/wp-includes/js/tinymce/tiny_mce.js
--- 2.0.5/wp-includes/js/tinymce/tiny_mce.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/tiny_mce.js	2007-04-12 12:04:03.000000000 -0500
@@ -1,30 +1,33 @@
-/**
- * $RCSfile: tiny_mce_src.js,v $
- * $Revision: 1.281 $
- * $Date: 2005/12/02 08:12:07 $
- *
- * @author Moxiecode
- * @copyright Copyright  2004, Moxiecode Systems AB, All rights reserved.
- */
 
-function TinyMCE() {
+/* file:jscripts/tiny_mce/classes/TinyMCE_Engine.class.js */
+
+function TinyMCE_Engine() {
+	var ua;
+
 	this.majorVersion = "2";
-	this.minorVersion = "0";
-	this.releaseDate = "2005-12-01";
+	this.minorVersion = "1.0";
+	this.releaseDate = "2007-02-13";
 
 	this.instances = new Array();
-	this.stickyClassesLookup = new Array();
+	this.switchClassCache = new Array();
 	this.windowArgs = new Array();
 	this.loadedFiles = new Array();
+	this.pendingFiles = new Array();
+	this.loadingIndex = 0;
 	this.configs = new Array();
 	this.currentConfig = 0;
 	this.eventHandlers = new Array();
+	this.log = new Array();
+	this.undoLevels = [];
+	this.undoIndex = 0;
+	this.typingUndoIndex = -1;
 
 	// Browser check
-	var ua = navigator.userAgent;
+	ua = navigator.userAgent;
 	this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
 	this.isMSIE5 = this.isMSIE && (ua.indexOf('MSIE 5') != -1);
 	this.isMSIE5_0 = this.isMSIE && (ua.indexOf('MSIE 5.0') != -1);
+	this.isMSIE7 = this.isMSIE && (ua.indexOf('MSIE 7') != -1);
 	this.isGecko = ua.indexOf('Gecko') != -1;
 	this.isSafari = ua.indexOf('Safari') != -1;
 	this.isOpera = ua.indexOf('Opera') != -1;
@@ -32,6 +35,12 @@
 	this.isNS7 = ua.indexOf('Netscape/7') != -1;
 	this.isNS71 = ua.indexOf('Netscape/7.1') != -1;
 	this.dialogCounter = 0;
+	this.plugins = new Array();
+	this.themes = new Array();
+	this.menus = new Array();
+	this.loadedPlugins = new Array();
+	this.buttonMap = new Array();
+	this.isLoaded = false;
 
 	// Fake MSIE on Opera and if Opera fakes IE, Gecko or Safari cancel those
 	if (this.isOpera) {
@@ -40,3374 +49,5313 @@
 		this.isSafari =  false;
 	}
 
+	this.isIE = this.isMSIE;
+	this.isRealIE = this.isMSIE && !this.isOpera;
+
 	// TinyMCE editor id instance counter
 	this.idCounter = 0;
 };
 
-TinyMCE.prototype.defParam = function(key, def_val) {
-	this.settings[key] = tinyMCE.getParam(key, def_val);
-};
+TinyMCE_Engine.prototype = {
+	init : function(settings) {
+		var theme, nl, baseHREF = "", i;
+
+		// IE 5.0x is no longer supported since 5.5, 6.0 and 7.0 now exists. We can't support old browsers forever, sorry.
+		if (this.isMSIE5_0)
+			return;
 
-TinyMCE.prototype.init = function(settings) {
-	var theme;
+		this.settings = settings;
 
-	this.settings = settings;
+		// Check if valid browser has execcommand support
+		if (typeof(document.execCommand) == 'undefined')
+			return;
 
-	// Check if valid browser has execcommand support
-	if (typeof(document.execCommand) == 'undefined')
-		return;
+		// Get script base path
+		if (!tinyMCE.baseURL) {
+			var elements = document.getElementsByTagName('script');
+
+			// If base element found, add that infront of baseURL
+			nl = document.getElementsByTagName('base');
+			for (i=0; i<nl.length; i++) {
+				if (nl[i].href)
+					baseHREF = nl[i].href;
+			}
+
+			for (var i=0; i<elements.length; i++) {
+				if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_dev.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {
+					var src = elements[i].src;
+
+					tinyMCE.srcMode = (src.indexOf('_src') != -1 || src.indexOf('_dev') != -1) ? '_src' : '';
+					tinyMCE.gzipMode = src.indexOf('_gzip') != -1;
+					src = src.substring(0, src.lastIndexOf('/'));
+
+					if (settings.exec_mode == "src" || settings.exec_mode == "normal")
+						tinyMCE.srcMode = settings.exec_mode == "src" ? '_src' : '';
+
+					// Force it absolute if page has a base href
+					if (baseHREF != "" && src.indexOf('://') == -1)
+						tinyMCE.baseURL = baseHREF + src;
+					else
+						tinyMCE.baseURL = src;
 
-	// Get script base path
-	if (!tinyMCE.baseURL) {
-		var elements = document.getElementsByTagName('script');
+					break;
+				}
+			}
+		}
 
-		for (var i=0; i<elements.length; i++) {
-			if (elements[i].src && (elements[i].src.indexOf("tiny_mce.js") != -1 || elements[i].src.indexOf("tiny_mce_src.js") != -1 || elements[i].src.indexOf("tiny_mce_gzip") != -1)) {
-				var src = elements[i].src;
+		// Get document base path
+		this.documentBasePath = document.location.href;
+		if (this.documentBasePath.indexOf('?') != -1)
+			this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?'));
+		this.documentURL = this.documentBasePath;
+		this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/'));
+
+		// If not HTTP absolute
+		if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') {
+			// If site absolute
+			tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL;
+		}
+
+		// Set default values on settings
+		this._def("mode", "none");
+		this._def("theme", "advanced");
+		this._def("plugins", "", true);
+		this._def("language", "en");
+		this._def("docs_language", this.settings['language']);
+		this._def("elements", "");
+		this._def("textarea_trigger", "mce_editable");
+		this._def("editor_selector", "");
+		this._def("editor_deselector", "mceNoEditor");
+		this._def("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[id|style|dir|class|align],-h2[id|style|dir|class|align],-h3[id|style|dir|class|align],-h4[id|style|dir|class|align],-h5[id|style|dir|class|align],-h6[id|style|dir|class|align],hr[class|style],-font[face|size|style|id|class|dir|color],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],cite[title|id|class|style|dir|lang],abbr[title|id|class|style|dir|lang],acronym[title|id|class|style|dir|lang],del[title|id|class|style|dir|lang|datetime|cite],ins[title|id|class|style|dir|lang|datetime|cite]");
+		this._def("extended_valid_elements", "");
+		this._def("invalid_elements", "");
+		this._def("encoding", "");
+		this._def("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE_Engine.prototype.convertURL"));
+		this._def("save_callback", "");
+		this._def("debug", false);
+		this._def("force_br_newlines", false);
+		this._def("force_p_newlines", true);
+		this._def("add_form_submit_trigger", true);
+		this._def("relative_urls", true);
+		this._def("remove_script_host", true);
+		this._def("focus_alert", true);
+		this._def("document_base_url", this.documentURL);
+		this._def("visual", true);
+		this._def("visual_table_class", "mceVisualAid");
+		this._def("setupcontent_callback", "");
+		this._def("fix_content_duplication", true);
+		this._def("custom_undo_redo", true);
+		this._def("custom_undo_redo_levels", -1);
+		this._def("custom_undo_redo_keyboard_shortcuts", true);
+		this._def("custom_undo_redo_restore_selection", true);
+		this._def("custom_undo_redo_global", false);
+		this._def("verify_html", true);
+		this._def("apply_source_formatting", false);
+		this._def("directionality", "ltr");
+		this._def("cleanup_on_startup", false);
+		this._def("inline_styles", false);
+		this._def("convert_newlines_to_brs", false);
+		this._def("auto_reset_designmode", true);
+		this._def("entities", "39,#39,160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,34,quot,38,amp,60,lt,62,gt,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro", true);
+		this._def("entity_encoding", "named");
+		this._def("cleanup_callback", "");
+		this._def("add_unload_trigger", true);
+		this._def("ask", false);
+		this._def("nowrap", false);
+		this._def("auto_resize", false);
+		this._def("auto_focus", false);
+		this._def("cleanup", true);
+		this._def("remove_linebreaks", true);
+		this._def("button_tile_map", false);
+		this._def("submit_patch", true);
+		this._def("browsers", "msie,safari,gecko,opera", true);
+		this._def("dialog_type", "window");
+		this._def("accessibility_warnings", true);
+		this._def("accessibility_focus", true);
+		this._def("merge_styles_invalid_parents", "");
+		this._def("force_hex_style_colors", true);
+		this._def("trim_span_elements", true);
+		this._def("convert_fonts_to_spans", false);
+		this._def("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');
+		this._def("font_size_classes", '');
+		this._def("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large', true);
+		this._def("event_elements", 'a,img', true);
+		this._def("convert_urls", true);
+		this._def("table_inline_editing", false);
+		this._def("object_resizing", true);
+		this._def("custom_shortcuts", true);
+		this._def("convert_on_click", false);
+		this._def("content_css", '');
+		this._def("fix_list_elements", true);
+		this._def("fix_table_elements", false);
+		this._def("strict_loading_mode", document.contentType == 'application/xhtml+xml');
+		this._def("hidden_tab_class", '');
+		this._def("display_tab_class", '');
+		this._def("gecko_spellcheck", false);
+		this._def("hide_selects_on_submit", true);
+
+		// Force strict loading mode to false on non Gecko browsers
+		if (this.isMSIE && !this.isOpera)
+			this.settings.strict_loading_mode = false;
 
-				tinyMCE.srcMode = (src.indexOf('_src') != -1) ? '_src' : '';
-				src = src.substring(0, src.lastIndexOf('/'));
+		// Browser check IE
+		if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
+			return;
 
-				tinyMCE.baseURL = src;
-				break;
+		// Browser check Gecko
+		if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
+			return;
+
+		// Browser check Safari
+		if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
+			return;
+
+		// Browser check Opera
+		if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
+			return;
+
+		// If not super absolute make it so
+		baseHREF = tinyMCE.settings['document_base_url'];
+		var h = document.location.href;
+		var p = h.indexOf('://');
+		if (p > 0 && document.location.protocol != "file:") {
+			p = h.indexOf('/', p + 3);
+			h = h.substring(0, p);
+
+			if (baseHREF.indexOf('://') == -1)
+				baseHREF = h + baseHREF;
+
+			tinyMCE.settings['document_base_url'] = baseHREF;
+			tinyMCE.settings['document_base_prefix'] = h;
+		}
+
+		// Trim away query part
+		if (baseHREF.indexOf('?') != -1)
+			baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
+
+		this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
+
+		theme = this.settings['theme'];
+		this.inlineStrict = 'A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';
+		this.inlineTransitional = 'A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';
+		this.blockElms = 'H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';
+		this.blockRegExp = new RegExp("^(" + this.blockElms + ")$", "i");
+		this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
+		this.uniqueURL = 'javascript:void(091039730);'; // Make unique URL non real URL
+		this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
+		this.callbacks = new Array('onInit', 'getInfo', 'getEditorTemplate', 'setupContent', 'onChange', 'onPageLoad', 'handleNodeChange', 'initInstance', 'execCommand', 'getControlHTML', 'handleEvent', 'cleanup', 'removeInstance');
+
+		// Theme url
+		this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
+
+		if (!tinyMCE.isIE || tinyMCE.isOpera)
+			this.settings['force_br_newlines'] = false;
+
+		if (tinyMCE.getParam("popups_css", false)) {
+			var cssPath = tinyMCE.getParam("popups_css", "");
+
+			// Is relative
+			if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
+				this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
+			else
+				this.settings['popups_css'] = cssPath;
+		} else
+			this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
+
+		if (tinyMCE.getParam("editor_css", false)) {
+			var cssPath = tinyMCE.getParam("editor_css", "");
+
+			// Is relative
+			if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
+				this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
+			else
+				this.settings['editor_css'] = cssPath;
+		} else {
+			if (this.settings.editor_css != '')
+				this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
+		}
+
+		if (tinyMCE.settings['debug']) {
+			var msg = "Debug: \n";
+
+			msg += "baseURL: " + this.baseURL + "\n";
+			msg += "documentBasePath: " + this.documentBasePath + "\n";
+			msg += "content_css: " + this.settings['content_css'] + "\n";
+			msg += "popups_css: " + this.settings['popups_css'] + "\n";
+			msg += "editor_css: " + this.settings['editor_css'] + "\n";
+
+			alert(msg);
+		}
+
+		// Only do this once
+		if (this.configs.length == 0) {
+			if (typeof(TinyMCECompressed) == "undefined") {
+				tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCE_Engine.prototype.onLoad);
+
+				if (tinyMCE.isRealIE) {
+					if (document.body)
+						tinyMCE.addEvent(document.body, "readystatechange", TinyMCE_Engine.prototype.onLoad);
+					else
+						tinyMCE.addEvent(document, "readystatechange", TinyMCE_Engine.prototype.onLoad);
+				}
+
+				tinyMCE.addEvent(window, "load", TinyMCE_Engine.prototype.onLoad);
+				tinyMCE._addUnloadEvents();
 			}
 		}
-	}
 
-	// Get document base path
-	this.documentBasePath = document.location.href;
-	if (this.documentBasePath.indexOf('?') != -1)
-		this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.indexOf('?'));
-	this.documentURL = this.documentBasePath;
-	this.documentBasePath = this.documentBasePath.substring(0, this.documentBasePath.lastIndexOf('/'));
-
-	// If not HTTP absolute
-	if (tinyMCE.baseURL.indexOf('://') == -1 && tinyMCE.baseURL.charAt(0) != '/') {
-		// If site absolute
-		tinyMCE.baseURL = this.documentBasePath + "/" + tinyMCE.baseURL;
-	}
-
-	// Set default values on settings
-	this.defParam("mode", "none");
-	this.defParam("theme", "advanced");
-	this.defParam("plugins", "", true);
-	this.defParam("language", "en");
-	this.defParam("docs_language", this.settings['language']);
-	this.defParam("elements", "");
-	this.defParam("textarea_trigger", "mce_editable");
-	this.defParam("editor_selector", "");
-	this.defParam("editor_deselector", "mceNoEditor");
-	this.defParam("valid_elements", "+a[id|style|rel|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/b[class|style],-em/i[class|style],-strike[class|style],-u[class|style],+p[style|dir|class|align],-ol[class|style],-ul[class|style],-li[class|style],br,img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border=0|alt|title|hspace|vspace|width|height|align],-sub[style|class],-sup[style|class],-blockquote[dir|style],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],-td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[style|class|align],-pre[class|align|style],address[class|align|style],-h1[style|dir|class|align],-h2[style|dir|class|align],-h3[style|dir|class|align],-h4[style|dir|class|align],-h5[style|dir|class|align],-h6[style|dir|class|align],hr[class|style],font[face|size|style|id|class|dir|color]");
-	this.defParam("extended_valid_elements", "");
-	this.defParam("invalid_elements", "");
-	this.defParam("encoding", "");
-	this.defParam("urlconverter_callback", tinyMCE.getParam("urlconvertor_callback", "TinyMCE.prototype.convertURL"));
-	this.defParam("save_callback", "");
-	this.defParam("debug", false);
-	this.defParam("force_br_newlines", false);
-	this.defParam("force_p_newlines", true);
-	this.defParam("add_form_submit_trigger", true);
-	this.defParam("relative_urls", true);
-	this.defParam("remove_script_host", true);
-	this.defParam("focus_alert", true);
-	this.defParam("document_base_url", this.documentURL);
-	this.defParam("visual", true);
-	this.defParam("visual_table_class", "mceVisualAid");
-	this.defParam("setupcontent_callback", "");
-	this.defParam("fix_content_duplication", true);
-	this.defParam("custom_undo_redo", true);
-	this.defParam("custom_undo_redo_levels", -1);
-	this.defParam("custom_undo_redo_keyboard_shortcuts", true);
-	this.defParam("verify_css_classes", false);
-	this.defParam("verify_html", true);
-	this.defParam("apply_source_formatting", false);
-	this.defParam("directionality", "ltr");
-	this.defParam("cleanup_on_startup", false);
-	this.defParam("inline_styles", false);
-	this.defParam("convert_newlines_to_brs", false);
-	this.defParam("auto_reset_designmode", true);
-	this.defParam("entities", "160,nbsp,38,amp,34,quot,162,cent,8364,euro,163,pound,165,yen,169,copy,174,reg,8482,trade,8240,permil,181,micro,183,middot,8226,bull,8230,hellip,8242,prime,8243,Prime,167,sect,182,para,223,szlig,8249,lsaquo,8250,rsaquo,171,laquo,187,raquo,8216,lsquo,8217,rsquo,8220,ldquo,8221,rdquo,8218,sbquo,8222,bdquo,60,lt,62,gt,8804,le,8805,ge,8211,ndash,8212,mdash,175,macr,8254,oline,164,curren,166,brvbar,168,uml,161,iexcl,191,iquest,710,circ,732,tilde,176,deg,8722,minus,177,plusmn,247,divide,8260,frasl,215,times,185,sup1,178,sup2,179,sup3,188,frac14,189,frac12,190,frac34,402,fnof,8747,int,8721,sum,8734,infin,8730,radic,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8712,isin,8713,notin,8715,ni,8719,prod,8743,and,8744,or,172,not,8745,cap,8746,cup,8706,part,8704,forall,8707,exist,8709,empty,8711,nabla,8727,lowast,8733,prop,8736,ang,180,acute,184,cedil,170,ordf,186,ordm,8224,dagger,8225,Dagger,192,Agrave,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,202,Ecirc,203,Euml,204,Igrave,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,212,Ocirc,213,Otilde,214,Ouml,216,Oslash,338,OElig,217,Ugrave,219,Ucirc,220,Uuml,376,Yuml,222,THORN,224,agrave,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,234,ecirc,235,euml,236,igrave,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,244,ocirc,245,otilde,246,ouml,248,oslash,339,oelig,249,ugrave,251,ucirc,252,uuml,254,thorn,255,yuml,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,8501,alefsym,982,piv,8476,real,977,thetasym,978,upsih,8472,weierp,8465,image,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8756,there4,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,173,shy,233,eacute,237,iacute,243,oacute,250,uacute,193,Aacute,225,aacute,201,Eacute,205,Iacute,211,Oacute,218,Uacute,221,Yacute,253,yacute");
-	this.defParam("entity_encoding", "named");
-	this.defParam("cleanup_callback", "");
-	this.defParam("add_unload_trigger", true);
-	this.defParam("ask", false);
-	this.defParam("nowrap", false);
-	this.defParam("auto_resize", false);
-	this.defParam("auto_focus", false);
-	this.defParam("cleanup", true);
-	this.defParam("remove_linebreaks", true);
-	this.defParam("button_tile_map", false);
-	this.defParam("submit_patch", true);
-	this.defParam("browsers", "msie,safari,gecko,opera");
-	this.defParam("dialog_type", "window");
-	this.defParam("accessibility_warnings", true);
-	this.defParam("merge_styles_invalid_parents", "");
-	this.defParam("force_hex_style_colors", true);
-	this.defParam("trim_span_elements", true);
-	this.defParam("convert_fonts_to_spans", false);
-	this.defParam("doctype", '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">');
-	this.defParam("font_size_classes", '');
-	this.defParam("font_size_style_values", 'xx-small,x-small,small,medium,large,x-large,xx-large');
-	this.defParam("event_elements", 'a,img');
-	this.defParam("convert_urls", true);
-	this.defParam("table_inline_editing", false);
-	this.defParam("object_resizing", true);
-
-	// Browser check IE
-	if (this.isMSIE && this.settings['browsers'].indexOf('msie') == -1)
-		return;
-
-	// Browser check Gecko
-	if (this.isGecko && this.settings['browsers'].indexOf('gecko') == -1)
-		return;
-
-	// Browser check Safari
-	if (this.isSafari && this.settings['browsers'].indexOf('safari') == -1)
-		return;
-
-	// Browser check Opera
-	if (this.isOpera && this.settings['browsers'].indexOf('opera') == -1)
-		return;
-
-	// If not super absolute make it so
-	var baseHREF = tinyMCE.settings['document_base_url'];
-	var h = document.location.href;
-	var p = h.indexOf('://');
-	if (p > 0 && document.location.protocol != "file:") {
-		p = h.indexOf('/', p + 3);
-		h = h.substring(0, p);
-
-		if (baseHREF.indexOf('://') == -1)
-			baseHREF = h + baseHREF;
-
-		tinyMCE.settings['document_base_url'] = baseHREF;
-		tinyMCE.settings['document_base_prefix'] = h;
-	}
-
-	// Trim away query part
-	if (baseHREF.indexOf('?') != -1)
-		baseHREF = baseHREF.substring(0, baseHREF.indexOf('?'));
-
-	this.settings['base_href'] = baseHREF.substring(0, baseHREF.lastIndexOf('/')) + "/";
-
-	theme = this.settings['theme'];
-	this.blockRegExp = new RegExp("^(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|blockquote|center|dl|dir|fieldset|form|noscript|noframes|menu|isindex)$", "i");
-	this.posKeyCodes = new Array(13,45,36,35,33,34,37,38,39,40);
-	this.uniqueURL = 'http://tinymce.moxiecode.cp/mce_temp_url'; // Make unique URL non real URL
-	this.uniqueTag = '<div id="mceTMPElement" style="display: none">TMP</div>';
-
-	// Theme url
-	this.settings['theme_href'] = tinyMCE.baseURL + "/themes/" + theme;
-
-	if (!tinyMCE.isMSIE)
-		this.settings['force_br_newlines'] = false;
-
-	if (tinyMCE.getParam("content_css", false)) {
-		var cssPath = tinyMCE.getParam("content_css", "");
-
-		// Is relative
-		if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
-			this.settings['content_css'] = this.documentBasePath + "/" + cssPath;
-		else
-			this.settings['content_css'] = cssPath;
-	} else
-		this.settings['content_css'] = '';
-
-	if (tinyMCE.getParam("popups_css", false)) {
-		var cssPath = tinyMCE.getParam("popups_css", "");
-
-		// Is relative
-		if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
-			this.settings['popups_css'] = this.documentBasePath + "/" + cssPath;
-		else
-			this.settings['popups_css'] = cssPath;
-	} else
-		this.settings['popups_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_popup.css";
-
-	if (tinyMCE.getParam("editor_css", false)) {
-		var cssPath = tinyMCE.getParam("editor_css", "");
-
-		// Is relative
-		if (cssPath.indexOf('://') == -1 && cssPath.charAt(0) != '/')
-			this.settings['editor_css'] = this.documentBasePath + "/" + cssPath;
-		else
-			this.settings['editor_css'] = cssPath;
-	} else
-		this.settings['editor_css'] = tinyMCE.baseURL + "/themes/" + theme + "/css/editor_ui.css";
+		this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
+		this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
+		this.loadCSS(this.settings['editor_css']);
 
-	if (tinyMCE.settings['debug']) {
-		var msg = "Debug: \n";
+		// Add plugins
+		var p = tinyMCE.getParam('plugins', '', true, ',');
+		if (p.length > 0) {
+			for (var i=0; i<p.length; i++) {
+				if (p[i].charAt(0) != '-')
+					this.loadScript(tinyMCE.baseURL + '/plugins/' + p[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
+			}
+		}
 
-		msg += "baseURL: " + this.baseURL + "\n";
-		msg += "documentBasePath: " + this.documentBasePath + "\n";
-		msg += "content_css: " + this.settings['content_css'] + "\n";
-		msg += "popups_css: " + this.settings['popups_css'] + "\n";
-		msg += "editor_css: " + this.settings['editor_css'] + "\n";
+		// Setup entities
+		if (tinyMCE.getParam('entity_encoding') == 'named') {
+			settings['cleanup_entities'] = new Array();
+			var entities = tinyMCE.getParam('entities', '', true, ',');
+			for (var i=0; i<entities.length; i+=2)
+				settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
+		}
 
-		alert(msg);
-	}
+		// Save away this config
+		settings['index'] = this.configs.length;
+		this.configs[this.configs.length] = settings;
 
-	// Init HTML cleanup
-	this._initCleanup();
+		// Start loading first one in chain
+		this.loadNextScript();
 
-	// Only do this once
-	if (this.configs.length == 0) {
-		// Is Safari enabled
-		if (this.isSafari && this.getParam('safari_warning', true))
-			alert("Safari support is very limited and should be considered experimental.\nSo there is no need to even submit bugreports on this early version.\nYou can disable this message by setting: safari_warning option to false");
+		// Force flicker free CSS backgrounds in IE
+		if (this.isIE && !this.isOpera) {
+			try {
+				document.execCommand('BackgroundImageCache', false, true);
+			} catch (e) {
+			}
+		}
 
-		tinyMCE.addEvent(window, "load", TinyMCE.prototype.onLoad);
+		// Setup XML encoding regexps
+		this.xmlEncodeAposRe = new RegExp('[<>&"\']', 'g');
+		this.xmlEncodeRe = new RegExp('[<>&"]', 'g');
+//		this.xmlEncodeEnts = {'&':'&amp;','"':'&quot;',"'":'&#39;','<':'&lt;','>':'&gt;'};
+	},
 
-		if (tinyMCE.isMSIE) {
+	_addUnloadEvents : function() {
+		if (tinyMCE.isIE) {
 			if (tinyMCE.settings['add_unload_trigger']) {
-				tinyMCE.addEvent(window, "unload", TinyMCE.prototype.unloadHandler);
-				tinyMCE.addEvent(window.document, "beforeunload", TinyMCE.prototype.unloadHandler);
+				tinyMCE.addEvent(window, "unload", TinyMCE_Engine.prototype.unloadHandler);
+				tinyMCE.addEvent(window.document, "beforeunload", TinyMCE_Engine.prototype.unloadHandler);
 			}
 		} else {
 			if (tinyMCE.settings['add_unload_trigger'])
 				tinyMCE.addEvent(window, "unload", function () {tinyMCE.triggerSave(true, true);});
 		}
-	}
+	},
 
-	this.loadScript(tinyMCE.baseURL + '/themes/' + this.settings['theme'] + '/editor_template' + tinyMCE.srcMode + '.js');
-	this.loadScript(tinyMCE.baseURL + '/langs/' + this.settings['language'] +  '.js');
-	this.loadCSS(this.settings['editor_css']);
-
-	// Add plugins
-	var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
-	if (this.settings['plugins'] != '') {
-		for (var i=0; i<themePlugins.length; i++)
-			this.loadScript(tinyMCE.baseURL + '/plugins/' + themePlugins[i] + '/editor_plugin' + tinyMCE.srcMode + '.js');
-	}
-
-	// Setup entities
-	settings['cleanup_entities'] = new Array();
-	var entities = tinyMCE.getParam('entities', '', true, ',');
-	for (var i=0; i<entities.length; i+=2)
-		settings['cleanup_entities']['c' + entities[i]] = entities[i+1];
-
-	// Save away this config
-	settings['index'] = this.configs.length;
-	this.configs[this.configs.length] = settings;
-};
-
-TinyMCE.prototype.loadScript = function(url) {
-	for (var i=0; i<this.loadedFiles.length; i++) {
-		if (this.loadedFiles[i] == url)
-			return;
-	}
+	_def : function(key, def_val, t) {
+		var v = tinyMCE.getParam(key, def_val);
 
-	document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>');
+		v = t ? v.replace(/\s+/g, "") : v;
 
-	this.loadedFiles[this.loadedFiles.length] = url;
-};
+		this.settings[key] = v;
+	},
 
-TinyMCE.prototype.loadCSS = function(url) {
-	for (var i=0; i<this.loadedFiles.length; i++) {
-		if (this.loadedFiles[i] == url)
-			return;
-	}
+	hasPlugin : function(n) {
+		return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
+	},
 
-	document.write('<link href="' + url + '" rel="stylesheet" type="text/css" />');
+	addPlugin : function(n, p) {
+		var op = this.plugins[n];
 
-	this.loadedFiles[this.loadedFiles.length] = url;
-};
+		// Use the previous plugin object base URL used when loading external plugins
+		p.baseURL = op ? op.baseURL : tinyMCE.baseURL + "/plugins/" + n;
+		this.plugins[n] = p;
 
-TinyMCE.prototype.importCSS = function(doc, css_file) {
-	if (css_file == '')
-		return;
+		this.loadNextScript();
+	},
 
-	if (typeof(doc.createStyleSheet) == "undefined") {
-		var elm = doc.createElement("link");
+	setPluginBaseURL : function(n, u) {
+		var op = this.plugins[n];
 
-		elm.rel = "stylesheet";
-		elm.href = css_file;
+		if (op)
+			op.baseURL = u;
+		else
+			this.plugins[n] = {baseURL : u};
+	},
 
-		if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)
-			headArr[0].appendChild(elm);
-	} else
-		var styleSheet = doc.createStyleSheet(css_file);
-};
+	loadPlugin : function(n, u) {
+		u = u.indexOf('.js') != -1 ? u.substring(0, u.lastIndexOf('/')) : u;
+		u = u.charAt(u.length-1) == '/' ? u.substring(0, u.length-1) : u;
+		this.plugins[n] = {baseURL : u};
+		this.loadScript(u + "/editor_plugin" + (tinyMCE.srcMode ? '_src' : '') + ".js");
+	},
+
+	hasTheme : function(n) {
+		return typeof(this.themes[n]) != "undefined" && this.themes[n] != null;
+	},
+
+	addTheme : function(n, t) {
+		this.themes[n] = t;
+
+		this.loadNextScript();
+	},
+
+	addMenu : function(n, m) {
+		this.menus[n] = m;
+	},
+
+	hasMenu : function(n) {
+		return typeof(this.plugins[n]) != "undefined" && this.plugins[n] != null;
+	},
 
-TinyMCE.prototype.confirmAdd = function(e, settings) {
-	var elm = tinyMCE.isMSIE ? event.srcElement : e.target;
-	var elementId = elm.name ? elm.name : elm.id;
+	loadScript : function(url) {
+		var i;
 
-	tinyMCE.settings = settings;
+		for (i=0; i<this.loadedFiles.length; i++) {
+			if (this.loadedFiles[i] == url)
+				return;
+		}
 
-	if (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm']))
-		tinyMCE.addMCEControl(elm, elementId);
+		if (tinyMCE.settings.strict_loading_mode)
+			this.pendingFiles[this.pendingFiles.length] = url;
+		else
+			document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '"></script>');
 
-	elm.setAttribute('mce_noask', 'true');
-};
+		this.loadedFiles[this.loadedFiles.length] = url;
+	},
 
-TinyMCE.prototype.updateContent = function(form_element_name) {
-	// Find MCE instance linked to given form element and copy it's value
-	var formElement = document.getElementById(form_element_name);
-	for (var n in tinyMCE.instances) {
-		var inst = tinyMCE.instances[n];
-		if (!tinyMCE.isInstance(inst))
-			continue;
+	loadNextScript : function() {
+		var d = document, se;
 
-		inst.switchSettings();
+		if (!tinyMCE.settings.strict_loading_mode)
+			return;
 
-		if (inst.formElement == formElement) {
-			var doc = inst.getDoc();
-	
-			tinyMCE._setHTML(doc, inst.formElement.value);
+		if (this.loadingIndex < this.pendingFiles.length) {
+			se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script');
+			se.setAttribute('language', 'javascript');
+			se.setAttribute('type', 'text/javascript');
+			se.setAttribute('src', this.pendingFiles[this.loadingIndex++]);
 
-			if (!tinyMCE.isMSIE)
-				doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid);
-		}
-	}
-};
+			d.getElementsByTagName("head")[0].appendChild(se);
+		} else
+			this.loadingIndex = -1; // Done with loading
+	},
 
-TinyMCE.prototype.addMCEControl = function(replace_element, form_element_name, target_document) {
-	var id = "mce_editor_" + tinyMCE.idCounter++;
-	var inst = new TinyMCEControl(tinyMCE.settings);
+	loadCSS : function(url) {
+		var ar = url.replace(/\s+/, '').split(',');
+		var lflen = 0, csslen = 0;
+		var skip = false;
+		var x = 0, i = 0, nl, le;
+
+		for (x = 0,csslen = ar.length; x<csslen; x++) {
+			if (ar[x] != null && ar[x] != 'null' && ar[x].length > 0) {
+				/* Make sure it doesn't exist. */
+				for (i=0, lflen=this.loadedFiles.length; i<lflen; i++) {
+					if (this.loadedFiles[i] == ar[x]) {
+						skip = true;
+						break;
+					}
+				}
 
-	inst.editorId = id;
-	this.instances[id] = inst;
+				if (!skip) {
+					if (tinyMCE.settings.strict_loading_mode) {
+						nl = document.getElementsByTagName("head");
+
+						le = document.createElement('link');
+						le.setAttribute('href', ar[x]);
+						le.setAttribute('rel', 'stylesheet');
+						le.setAttribute('type', 'text/css');
 
-	inst.onAdd(replace_element, form_element_name, target_document);
-};
+						nl[0].appendChild(le);			
+					} else
+						document.write('<link href="' + ar[x] + '" rel="stylesheet" type="text/css" />');
 
-TinyMCE.prototype.triggerSave = function(skip_cleanup, skip_callback) {
-	// Cleanup and set all form fields
-	for (var n in tinyMCE.instances) {
-		var inst = tinyMCE.instances[n];
-		if (!tinyMCE.isInstance(inst))
-			continue;
+					this.loadedFiles[this.loadedFiles.length] = ar[x];
+				}
+			}
+		}
+	},
 
-		inst.switchSettings();
+	importCSS : function(doc, css) {
+		var css_ary = css.replace(/\s+/, '').split(',');
+		var csslen, elm, headArr, x, css_file;
 
-		tinyMCE.settings['preformatted'] = false;
+		for (x = 0, csslen = css_ary.length; x<csslen; x++) {
+			css_file = css_ary[x];
 
-		// Default to false
-		if (typeof(skip_cleanup) == "undefined")
-			skip_cleanup = false;
+			if (css_file != null && css_file != 'null' && css_file.length > 0) {
+				// Is relative, make absolute
+				if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/')
+					css_file = this.documentBasePath + "/" + css_file;
 
-		// Default to false
-		if (typeof(skip_callback) == "undefined")
-			skip_callback = false;
+				if (typeof(doc.createStyleSheet) == "undefined") {
+					elm = doc.createElement("link");
 
-		tinyMCE._setHTML(inst.getDoc(), inst.getBody().innerHTML);
+					elm.rel = "stylesheet";
+					elm.href = css_file;
 
-		// Remove visual aids when cleanup is disabled
-		if (inst.settings['cleanup'] == false) {
-			tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);
-			tinyMCE._setEventsEnabled(inst.getBody(), true);
+					if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0)
+						headArr[0].appendChild(elm);
+				} else
+					doc.createStyleSheet(css_file);
+			}
 		}
+	},
 
-		tinyMCE._customCleanup(inst, "submit_content_dom", inst.contentWindow.document.body);
-		var htm = skip_cleanup ? inst.getBody().innerHTML : tinyMCE._cleanupHTML(inst, inst.getDoc(), this.settings, inst.getBody(), this.visualAid, true);
-		htm = tinyMCE._customCleanup(inst, "submit_content", htm);
+	confirmAdd : function(e, settings) {
+		var elm = tinyMCE.isIE ? event.srcElement : e.target;
+		var elementId = elm.name ? elm.name : elm.id;
 
-		if (tinyMCE.settings["encoding"] == "xml" || tinyMCE.settings["encoding"] == "html")
-			htm = tinyMCE.convertStringToXML(htm);
+		tinyMCE.settings = settings;
 
-		if (!skip_callback && tinyMCE.settings['save_callback'] != "")
-			var content = eval(tinyMCE.settings['save_callback'] + "(inst.formTargetElementId,htm,inst.getBody());");
+		if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm'])))
+			tinyMCE.addMCEControl(elm, elementId);
 
-		// Use callback content if available
-		if ((typeof(content) != "undefined") && content != null)
-			htm = content;
+		elm.setAttribute('mce_noask', 'true');
+	},
 
-		// Replace some weird entities (Bug: #1056343)
-		htm = tinyMCE.regexpReplace(htm, "&#40;", "(", "gi");
-		htm = tinyMCE.regexpReplace(htm, "&#41;", ")", "gi");
-		htm = tinyMCE.regexpReplace(htm, "&#59;", ";", "gi");
-		htm = tinyMCE.regexpReplace(htm, "&#34;", "&quot;", "gi");
-		htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "gi");
+	updateContent : function(form_element_name) {
+		// Find MCE instance linked to given form element and copy it's value
+		var formElement = document.getElementById(form_element_name);
+		for (var n in tinyMCE.instances) {
+			var inst = tinyMCE.instances[n];
+			if (!tinyMCE.isInstance(inst))
+				continue;
 
-		if (inst.formElement)
-			inst.formElement.value = htm;
-	}
-};
+			inst.switchSettings();
 
-TinyMCE.prototype._setEventsEnabled = function(node, state) {
-	var events = new Array('onfocus','onblur','onclick','ondblclick',
-				'onmousedown','onmouseup','onmouseover','onmousemove',
-				'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup');
+			if (inst.formElement == formElement) {
+				var doc = inst.getDoc();
+		
+				tinyMCE._setHTML(doc, inst.formElement.value);
 
-	var evs = tinyMCE.settings['event_elements'].split(',');
-    for (var y=0; y<evs.length; y++){
-		var elms = node.getElementsByTagName(evs[y]);
-		for (var i=0; i<elms.length; i++) {
-			var event = "";
+				if (!tinyMCE.isIE)
+					doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid);
+			}
+		}
+	},
 
-			for (var x=0; x<events.length; x++) {
-				if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
-					event = tinyMCE.cleanupEventStr("" + event);
+	addMCEControl : function(replace_element, form_element_name, target_document) {
+		var id = "mce_editor_" + tinyMCE.idCounter++;
+		var inst = new TinyMCE_Control(tinyMCE.settings);
 
-					if (!state)
-						event = "return true;" + event;
-					else
-						event = event.replace(/^return true;/gi, '');
+		inst.editorId = id;
+		this.instances[id] = inst;
 
-					elms[i].removeAttribute(events[x]);
-					elms[i].setAttribute(events[x], event);
-				}
-			}
-		}
-	}
-};
+		inst._onAdd(replace_element, form_element_name, target_document);
+	},
 
-TinyMCE.prototype.resetForm = function(form_index) {
-	var formObj = document.forms[form_index];
+	removeInstance : function(ti) {
+		var t = [], n, i;
 
-	for (var n in tinyMCE.instances) {
-		var inst = tinyMCE.instances[n];
-		if (!tinyMCE.isInstance(inst))
-			continue;
+		// Remove from instances
+		for (n in tinyMCE.instances) {
+			i = tinyMCE.instances[n];
 
-		inst.switchSettings();
+			if (tinyMCE.isInstance(i) && ti != i)
+					t[n] = i;
+		}
+
+		tinyMCE.instances = t;
 
-		for (var i=0; i<formObj.elements.length; i++) {
-			if (inst.formTargetElementId == formObj.elements[i].name)
-				inst.getBody().innerHTML = inst.startContent;
+		// Remove from global undo/redo
+		n = [];
+		t = tinyMCE.undoLevels;
+
+		for (i=0; i<t.length; i++) {
+			if (t[i] != ti)
+				n.push(t[i]);
 		}
-	}
-};
 
-TinyMCE.prototype.execInstanceCommand = function(editor_id, command, user_interface, value, focus) {
-	var inst = tinyMCE.getInstanceById(editor_id);
-	if (inst) {
-		if (typeof(focus) == "undefined")
-			focus = true;
+		tinyMCE.undoLevels = n;
+		tinyMCE.undoIndex = n.length;
 
-		if (focus)
-			inst.contentWindow.focus();
+		// Dispatch remove instance call
+		tinyMCE.dispatchCallback(ti, 'remove_instance_callback', 'removeInstance', ti);
 
-		// Reset design mode if lost
-		inst.autoResetDesignMode();
+		return ti;
+	},
 
-		this.selectedElement = inst.getFocusElement();
-		this.selectedInstance = inst;
-		tinyMCE.execCommand(command, user_interface, value);
+	removeMCEControl : function(editor_id) {
+		var inst = tinyMCE.getInstanceById(editor_id), h, re, ot, tn;
 
-		// Cancel event so it doesn't call onbeforeonunlaod
-		if (tinyMCE.isMSIE && window.event != null)
-			tinyMCE.cancelEvent(window.event);
-	}
-};
+		if (inst) {
+			inst.switchSettings();
 
-TinyMCE.prototype.execCommand = function(command, user_interface, value) {
-	// Default input
-	user_interface = user_interface ? user_interface : false;
-	value = value ? value : null;
+			editor_id = inst.editorId;
+			h = tinyMCE.getContent(editor_id);
 
-	if (tinyMCE.selectedInstance)
-		tinyMCE.selectedInstance.switchSettings();
+			this.removeInstance(inst);
 
-	switch (command) {
-		case 'mceHelp':
-			var template = new Array();
-
-			template['file']   = 'about.htm';
-			template['width']  = 480;
-			template['height'] = 380;
-
-			tinyMCE.openWindow(template, {
-				tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion,
-				tinymce_releasedate : tinyMCE.releaseDate,
-				inline : "yes"
-			});
-		return;
+			tinyMCE.selectedElement = null;
+			tinyMCE.selectedInstance = null;
 
-		case 'mceFocus':
-			var inst = tinyMCE.getInstanceById(value);
-			if (inst)
-				inst.contentWindow.focus();
-		return;
+			// Remove element
+			re = document.getElementById(editor_id + "_parent");
+			ot = inst.oldTargetElement;
+			tn = ot.nodeName.toLowerCase();
+
+			if (tn == "textarea" || tn == "input") {
+				re.parentNode.removeChild(re);
+				ot.style.display = "inline";
+				ot.value = h;
+			} else {
+				ot.innerHTML = h;
+				ot.style.display = 'block';
+				re.parentNode.insertBefore(ot, re);
+				re.parentNode.removeChild(re);
+			}
+		}
+	},
 
-		case "mceAddControl":
-		case "mceAddEditor":
-			tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
-			return;
+	triggerSave : function(skip_cleanup, skip_callback) {
+		var inst, n;
 
-		case "mceAddFrameControl":
-			tinyMCE.addMCEControl(tinyMCE._getElementById(value), value['element'], value['document']);
-			return;
+		// Default to false
+		if (typeof(skip_cleanup) == "undefined")
+			skip_cleanup = false;
 
-		case "mceRemoveControl":
-		case "mceRemoveEditor":
-			tinyMCE.removeMCEControl(value);
-			return;
+		// Default to false
+		if (typeof(skip_callback) == "undefined")
+			skip_callback = false;
 
-		case "mceResetDesignMode":
-			// Resets the designmode state of the editors in Gecko
-			if (!tinyMCE.isMSIE) {
-				for (var n in tinyMCE.instances) {
-					if (!tinyMCE.isInstance(tinyMCE.instances[n]))
-						continue;
+		// Cleanup and set all form fields
+		for (n in tinyMCE.instances) {
+			inst = tinyMCE.instances[n];
 
-					try {
-						tinyMCE.instances[n].getDoc().designMode = "on";
-					} catch (e) {
-						// Ignore any errors
-					}
-				}
-			}
+			if (!tinyMCE.isInstance(inst))
+				continue;
 
-			return;
-	}
+			inst.triggerSave(skip_cleanup, skip_callback);
+		}
+	},
 
-	if (this.selectedInstance) {
-		this.selectedInstance.execCommand(command, user_interface, value);
-	} else if (tinyMCE.settings['focus_alert'])
-		alert(tinyMCELang['lang_focus_alert']);
-};
+	resetForm : function(form_index) {
+		var i, inst, n, formObj = document.forms[form_index];
 
-TinyMCE.prototype.eventPatch = function(editor_id) {
-	// Remove odd, error
-	if (typeof(tinyMCE) == "undefined")
-		return true;
+		for (n in tinyMCE.instances) {
+			inst = tinyMCE.instances[n];
 
-	for (var i=0; i<document.frames.length; i++) {
-		try {
-			if (document.frames[i].event) {
-				var event = document.frames[i].event;
+			if (!tinyMCE.isInstance(inst))
+				continue;
 
-				if (!event.target)
-					event.target = event.srcElement;
+			inst.switchSettings();
 
-				TinyMCE.prototype.handleEvent(event);
-				return;
+			for (i=0; i<formObj.elements.length; i++) {
+				if (inst.formTargetElementId == formObj.elements[i].name)
+					inst.getBody().innerHTML = inst.startContent;
 			}
-		} catch (ex) {
-			// Ignore error if iframe is pointing to external URL
 		}
-	}
-};
+	},
 
-TinyMCE.prototype.unloadHandler = function() {
-	tinyMCE.triggerSave(true, true);
-};
+	execInstanceCommand : function(editor_id, command, user_interface, value, focus) {
+		var inst = tinyMCE.getInstanceById(editor_id), r;
 
-TinyMCE.prototype.addEventHandlers = function(editor_id) {
-	if (tinyMCE.isMSIE) {
-		var doc = document.frames[editor_id].document;
-
-		// Event patch
-		tinyMCE.addEvent(doc, "keypress", TinyMCE.prototype.eventPatch);
-		tinyMCE.addEvent(doc, "keyup", TinyMCE.prototype.eventPatch);
-		tinyMCE.addEvent(doc, "keydown", TinyMCE.prototype.eventPatch);
-		tinyMCE.addEvent(doc, "mouseup", TinyMCE.prototype.eventPatch);
-		tinyMCE.addEvent(doc, "click", TinyMCE.prototype.eventPatch);
-	} else {
-		var inst = tinyMCE.instances[editor_id];
-		var doc = inst.getDoc();
+		if (inst) {
+			r = inst.selection.getRng();
 
-		inst.switchSettings();
+			if (typeof(focus) == "undefined")
+				focus = true;
 
-		tinyMCE.addEvent(doc, "keypress", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "keydown", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "keyup", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "click", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "mouseup", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "mousedown", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "focus", tinyMCE.handleEvent);
-		tinyMCE.addEvent(doc, "blur", tinyMCE.handleEvent);
-
-		eval('try { doc.designMode = "On"; } catch(e) {}');
-	}
-};
+			// IE bug lost focus on images in absolute divs Bug #1534575
+			if (focus && (!r || !r.item))
+				inst.contentWindow.focus();
 
-TinyMCE.prototype._createIFrame = function(replace_element) {
-	var iframe = document.createElement("iframe");
-	var id = replace_element.getAttribute("id");
-	var aw, ah;
-
-	aw = "" + tinyMCE.settings['area_width'];
-	ah = "" + tinyMCE.settings['area_height'];
-
-	if (aw.indexOf('%') == -1) {
-		aw = parseInt(aw);
-		aw = aw < 0 ? 300 : aw;
-		aw = aw + "px";
-	}
-
-	if (ah.indexOf('%') == -1) {
-		ah = parseInt(ah);
-		ah = ah < 0 ? 240 : ah;
-		ah = ah + "px";
-	}
-
-	iframe.setAttribute("id", id);
-	//iframe.setAttribute("className", "mceEditorArea");
-	iframe.setAttribute("border", "0");
-	iframe.setAttribute("frameBorder", "0");
-	iframe.setAttribute("marginWidth", "0");
-	iframe.setAttribute("marginHeight", "0");
-	iframe.setAttribute("leftMargin", "0");
-	iframe.setAttribute("topMargin", "0");
-	iframe.setAttribute("width", aw);
-	iframe.setAttribute("height", ah);
-	iframe.setAttribute("allowtransparency", "true");
-
-	if (tinyMCE.settings["auto_resize"])
-		iframe.setAttribute("scrolling", "no");
-
-	// Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera)
-		iframe.setAttribute("src", this.settings['default_document']);
-
-	iframe.style.width = aw;
-	iframe.style.height = ah;
-
-	// MSIE 5.0 issue
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera)
-		replace_element.outerHTML = iframe.outerHTML;
-	else
-		replace_element.parentNode.replaceChild(iframe, replace_element);
+			// Reset design mode if lost
+			inst.autoResetDesignMode();
 
-	if (tinyMCE.isMSIE)
-		return window.frames[id];
-	else
-		return iframe;
-};
+			this.selectedElement = inst.getFocusElement();
+			inst.select();
+			tinyMCE.execCommand(command, user_interface, value);
 
-TinyMCE.prototype.setupContent = function(editor_id) {
-	var inst = tinyMCE.instances[editor_id];
-	var doc = inst.getDoc();
-	var head = doc.getElementsByTagName('head').item(0);
-	var content = inst.startContent;
+			// Cancel event so it doesn't call onbeforeonunlaod
+			if (tinyMCE.isIE && window.event != null)
+				tinyMCE.cancelEvent(window.event);
+		}
+	},
 
-	tinyMCE.operaOpacityCounter = 100 * tinyMCE.idCounter;
+	execCommand : function(command, user_interface, value) {
+		var inst = tinyMCE.selectedInstance;
 
-	inst.switchSettings();
+		// Default input
+		user_interface = user_interface ? user_interface : false;
+		value = value ? value : null;
 
-	// Not loaded correctly hit it again, Mozilla bug #997860
-	if (!tinyMCE.isMSIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {
-		// This part will remove the designMode status
-		// Failes first time in Firefox 1.5b2 on Mac
-		try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}
-		window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);
-		return;
-	}
-
-	if (!head) {
-		window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
-		return;
-	}
-
-	// Import theme specific content CSS the user specific
-	tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
-	tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
-	tinyMCE.executeCallback('init_instance_callback', '_initInstance', 0, inst);
+		if (inst)
+			inst.switchSettings();
 
-	// Setup span styles
-	if (tinyMCE.getParam("convert_fonts_to_spans"))
-		inst.getDoc().body.setAttribute('id', 'mceSpanFonts');
+		switch (command) {
+			case "Undo":
+				if (this.getParam('custom_undo_redo_global')) {
+					if (this.undoIndex > 0) {
+						tinyMCE.nextUndoRedoAction = 'Undo';
+						inst = this.undoLevels[--this.undoIndex];
+						inst.select();
 
-	if (tinyMCE.settings['nowrap'])
-		doc.body.style.whiteSpace = "nowrap";
+						if (!tinyMCE.nextUndoRedoInstanceId)
+							inst.execCommand('Undo');
+					}
+				} else
+					inst.execCommand('Undo');
+				return true;
 
-	doc.body.dir = this.settings['directionality'];
-	doc.editorId = editor_id;
+			case "Redo":
+				if (this.getParam('custom_undo_redo_global')) {
+					if (this.undoIndex <= this.undoLevels.length - 1) {
+						tinyMCE.nextUndoRedoAction = 'Redo';
+						inst = this.undoLevels[this.undoIndex++];
+						inst.select();
 
-	// Add on document element in Mozilla
-	if (!tinyMCE.isMSIE)
-		doc.documentElement.editorId = editor_id;
+						if (!tinyMCE.nextUndoRedoInstanceId)
+							inst.execCommand('Redo');
+					}
+				} else
+					inst.execCommand('Redo');
 
-	// Setup base element
-	var base = doc.createElement("base");
-	base.setAttribute('href', tinyMCE.settings['base_href']);
-	head.appendChild(base);
+				return true;
 
-	// Replace new line characters to BRs
-	if (tinyMCE.settings['convert_newlines_to_brs']) {
-		content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
-		content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
-		content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi");
-	}
+			case 'mceFocus':
+				var inst = tinyMCE.getInstanceById(value);
+				if (inst)
+					inst.getWin().focus();
+			return;
 
-	// Open closed anchors
-//	content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
+			case "mceAddControl":
+			case "mceAddEditor":
+				tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
+				return;
 
-	// Call custom cleanup code
-	content = tinyMCE.storeAwayURLs(content);
-	content = tinyMCE._customCleanup(inst, "insert_to_editor", content);
+			case "mceAddFrameControl":
+				tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']);
+				return;
 
-	if (tinyMCE.isMSIE) {
-		// Ugly!!!
-		window.setInterval('try{tinyMCE.getCSSClasses(document.frames["' + editor_id + '"].document, "' + editor_id + '");}catch(e){}', 500);
+			case "mceRemoveControl":
+			case "mceRemoveEditor":
+				tinyMCE.removeMCEControl(value);
+				return;
+
+			case "mceToggleEditor":
+				var inst = tinyMCE.getInstanceById(value), pe, te;
 
-		if (tinyMCE.settings["force_br_newlines"])
-			document.frames[editor_id].document.styleSheets[0].addRule("p", "margin: 0px;");
+				if (inst) {
+					pe = document.getElementById(inst.editorId + '_parent');
+					te = inst.oldTargetElement;
+
+					if (typeof(inst.enabled) == 'undefined')
+						inst.enabled = true;
+
+					inst.enabled = !inst.enabled;
+
+					if (!inst.enabled) {
+						pe.style.display = 'none';
+						te.value = inst.getHTML();
+						te.style.display = inst.oldTargetDisplay;
+						tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst);
+					} else {
+						pe.style.display = 'block';
+						te.style.display = 'none';
+						inst.setHTML(te.value);
+						inst.useCSS = false;
+						tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst);
+					}
+				} else
+					tinyMCE.addMCEControl(tinyMCE._getElementById(value), value);
 
-		var body = document.frames[editor_id].document.body;
+				return;
 
-		tinyMCE.addEvent(body, "beforepaste", TinyMCE.prototype.eventPatch);
-		tinyMCE.addEvent(body, "beforecut", TinyMCE.prototype.eventPatch);
+			case "mceResetDesignMode":
+				// Resets the designmode state of the editors in Gecko
+				if (!tinyMCE.isIE) {
+					for (var n in tinyMCE.instances) {
+						if (!tinyMCE.isInstance(tinyMCE.instances[n]))
+							continue;
+
+						try {
+							tinyMCE.instances[n].getDoc().designMode = "on";
+						} catch (e) {
+							// Ignore any errors
+						}
+					}
+				}
 
-		body.editorId = editor_id;
-	}
+				return;
+		}
 
-	content = tinyMCE.cleanupHTMLCode(content);
+		if (inst) {
+			inst.execCommand(command, user_interface, value);
+		} else if (tinyMCE.settings['focus_alert'])
+			alert(tinyMCELang['lang_focus_alert']);
+	},
+
+	_createIFrame : function(replace_element, doc, win) {
+		var iframe, id = replace_element.getAttribute("id");
+		var aw, ah;
+
+		if (typeof(doc) == "undefined")
+			doc = document;
+
+		if (typeof(win) == "undefined")
+			win = window;
+
+		iframe = doc.createElement("iframe");
+
+		aw = "" + tinyMCE.settings['area_width'];
+		ah = "" + tinyMCE.settings['area_height'];
+
+		if (aw.indexOf('%') == -1) {
+			aw = parseInt(aw);
+			aw = (isNaN(aw) || aw < 0) ? 300 : aw;
+			aw = aw + "px";
+		}
+
+		if (ah.indexOf('%') == -1) {
+			ah = parseInt(ah);
+			ah = (isNaN(ah) || ah < 0) ? 240 : ah;
+			ah = ah + "px";
+		}
+
+		iframe.setAttribute("id", id);
+		iframe.setAttribute("name", id);
+		iframe.setAttribute("class", "mceEditorIframe");
+		iframe.setAttribute("border", "0");
+		iframe.setAttribute("frameBorder", "0");
+		iframe.setAttribute("marginWidth", "0");
+		iframe.setAttribute("marginHeight", "0");
+		iframe.setAttribute("leftMargin", "0");
+		iframe.setAttribute("topMargin", "0");
+		iframe.setAttribute("width", aw);
+		iframe.setAttribute("height", ah);
+		iframe.setAttribute("allowtransparency", "true");
+		iframe.className = 'mceEditorIframe';
+
+		if (tinyMCE.settings["auto_resize"])
+			iframe.setAttribute("scrolling", "no");
+
+		// Must have a src element in MSIE HTTPs breaks aswell as absoute URLs
+		if (tinyMCE.isRealIE)
+			iframe.setAttribute("src", this.settings['default_document']);
+
+		iframe.style.width = aw;
+		iframe.style.height = ah;
+
+		// Ugly hack for Gecko problem in strict mode
+		if (tinyMCE.settings.strict_loading_mode)
+			iframe.style.marginBottom = '-5px';
+
+		// MSIE 5.0 issue
+		if (tinyMCE.isRealIE)
+			replace_element.outerHTML = iframe.outerHTML;
+		else
+			replace_element.parentNode.replaceChild(iframe, replace_element);
+
+		if (tinyMCE.isRealIE)
+			return win.frames[id];
+		else
+			return iframe;
+	},
 
-	// Fix for bug #958637
-	if (!tinyMCE.isMSIE) {
-		var contentElement = inst.getDoc().createElement("body");
+	setupContent : function(editor_id) {
+		var inst = tinyMCE.instances[editor_id], i;
 		var doc = inst.getDoc();
+		var head = doc.getElementsByTagName('head').item(0);
+		var content = inst.startContent;
+
+		// HTML values get XML encoded in strict mode
+		if (tinyMCE.settings.strict_loading_mode) {
+			content = content.replace(/&lt;/g, '<');
+			content = content.replace(/&gt;/g, '>');
+			content = content.replace(/&quot;/g, '"');
+			content = content.replace(/&amp;/g, '&');
+		}
 
-		contentElement.innerHTML = content;
+		tinyMCE.selectedInstance = inst;
+		inst.switchSettings();
 
-		// Remove weridness!
-		if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
-			content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
-
-		if (tinyMCE.settings['cleanup_on_startup'])
-			tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
-		else {
-			// Convert all strong/em to b/i
-			content = tinyMCE.regexpReplace(content, "<strong", "<b", "gi");
-			content = tinyMCE.regexpReplace(content, "<em(/?)>", "<i$1>", "gi");
-			content = tinyMCE.regexpReplace(content, "<em ", "<i ", "gi");
-			content = tinyMCE.regexpReplace(content, "</strong>", "</b>", "gi");
-			content = tinyMCE.regexpReplace(content, "</em>", "</i>", "gi");
-			tinyMCE.setInnerHTML(inst.getBody(), content);
+		// Not loaded correctly hit it again, Mozilla bug #997860
+		if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") {
+			// This part will remove the designMode status
+			// Failes first time in Firefox 1.5b2 on Mac
+			try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {}
+			window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000);
+			return;
 		}
 
-		inst.convertAllRelativeURLs();
-	} else {
-		if (tinyMCE.settings['cleanup_on_startup']) {
-			tinyMCE._setHTML(inst.getDoc(), content);
+		if (!head) {
+			window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10);
+			return;
+		}
 
-			// Produces permission denied error in MSIE 5.5
-			eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
-		} else
-			tinyMCE._setHTML(inst.getDoc(), content);
-	}
+		// Import theme specific content CSS the user specific
+		tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css");
+		tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']);
+		tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst);
 
-	// Fix for bug #957681
-	//inst.getDoc().designMode = inst.getDoc().designMode;
+		// Setup keyboard shortcuts
+		if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) {
+			inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo');
+			inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo');
+		}
 
-	// Setup element references
-	var parentElm = document.getElementById(inst.editorId + '_parent');
-	if (parentElm.lastChild.nodeName == "INPUT")
-		inst.formElement = tinyMCE.isGecko ? parentElm.firstChild : parentElm.lastChild;
-	else
-		inst.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
+		// BlockFormat shortcuts keys
+		for (i=1; i<=6; i++)
+			inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, '<h' + i + '>');
 
-	tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
-	tinyMCE.executeCallback('setupcontent_callback', '_setupContent', 0, editor_id, inst.getBody(), inst.getDoc());
+		inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '<p>');
+		inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '<div>');
+		inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '<address>');
 
-	// Re-add design mode on mozilla
-	if (!tinyMCE.isMSIE)
-		TinyMCE.prototype.addEventHandlers(editor_id);
+		// Add default shortcuts for gecko
+		if (tinyMCE.isGecko) {
+			inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold');
+			inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic');
+			inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline');
+		}
 
-	// Add blur handler
-	if (tinyMCE.isMSIE)
-		tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE.prototype.eventPatch);
+		// Setup span styles
+		if (tinyMCE.getParam("convert_fonts_to_spans"))
+			inst.getBody().setAttribute('id', 'mceSpanFonts');
 
-	// Trigger node change, this call locks buttons for tables and so forth
-	tinyMCE.selectedInstance = inst;
-	tinyMCE.selectedElement = inst.contentWindow.document.body;
+		if (tinyMCE.settings['nowrap'])
+			doc.body.style.whiteSpace = "nowrap";
 
-	if (!inst.isHidden())
-		tinyMCE.triggerNodeChange(false, true);
+		doc.body.dir = this.settings['directionality'];
+		doc.editorId = editor_id;
 
-	// Call custom DOM cleanup
-	tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());
-	tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());
-	tinyMCE._setEventsEnabled(inst.getBody(), false);
-	tinyMCE.cleanupAnchors(inst.getDoc());
+		// Add on document element in Mozilla
+		if (!tinyMCE.isIE)
+			doc.documentElement.editorId = editor_id;
 
-	if (tinyMCE.getParam("convert_fonts_to_spans"))
-		tinyMCE.convertSpansToFonts(inst.getDoc());
+		inst.setBaseHREF(tinyMCE.settings['base_href']);
 
-	inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);
-	inst.undoLevels[inst.undoLevels.length] = inst.startContent;
+		// Replace new line characters to BRs
+		if (tinyMCE.settings['convert_newlines_to_brs']) {
+			content = tinyMCE.regexpReplace(content, "\r\n", "<br />", "gi");
+			content = tinyMCE.regexpReplace(content, "\r", "<br />", "gi");
+			content = tinyMCE.regexpReplace(content, "\n", "<br />", "gi");
+		}
 
-	tinyMCE.operaOpacityCounter = -1;
-};
+		// Open closed anchors
+	//	content = content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
 
-TinyMCE.prototype.cleanupHTMLCode = function(s) {
-	s = s.replace(/<p \/>/gi, '<p>&nbsp;</p>');
-	s = s.replace(/<p>\s*<\/p>/gi, '<p>&nbsp;</p>');
+		// Call custom cleanup code
+		content = tinyMCE.storeAwayURLs(content);
+		content = tinyMCE._customCleanup(inst, "insert_to_editor", content);
 
-	// Open closed tags like <b/> to <b></b>
-//	tinyMCE.debug("f:" + s);
-	s = s.replace(/<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\|>]*?)\/>/gi, '<$1$2$3></$1$2>');
-//	tinyMCE.debug("e:" + s);
+		if (tinyMCE.isIE) {
+			// Ugly!!!
+			window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500);
 
-	// Remove trailing space <b > to <b>
-	s = s.replace(new RegExp('\\s+></', 'gi'), '></');
+			if (tinyMCE.settings["force_br_newlines"])
+				doc.styleSheets[0].addRule("p", "margin: 0;");
 
-	// Close tags <img></img> to <img/>
-	s = s.replace(/<(img|br|hr)(.*?)><\/(img|br|hr)>/gi, '<$1$2 />');
+			var body = inst.getBody();
+			body.editorId = editor_id;
+		}
 
-	// Weird MSIE bug, <p><hr /></p> breaks runtime?
-	if (tinyMCE.isMSIE)
-		s = s.replace(/<p><hr \/><\/p>/gi, "<hr>");
+		content = tinyMCE.cleanupHTMLCode(content);
 
-	// Convert relative anchors to absolute URLs ex: #something to file.htm#something
-	s = s.replace(new RegExp('(href=\"?)(\\s*?#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
+		// Fix for bug #958637
+		if (!tinyMCE.isIE) {
+			var contentElement = inst.getDoc().createElement("body");
+			var doc = inst.getDoc();
 
-	return s;
-};
+			contentElement.innerHTML = content;
 
-TinyMCE.prototype.storeAwayURLs = function(s) {
-	// Remove all mce_src, mce_href and replace them with new ones
-	s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
-	s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
-	s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');
-	s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');
+			// Remove weridness!
+			if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt'])
+				content = content.replace(new RegExp('&lt;&gt;', 'g'), "");
 
-	return s;
-};
+			if (tinyMCE.settings['cleanup_on_startup'])
+				tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement));
+			else
+				tinyMCE.setInnerHTML(inst.getBody(), content);
 
-TinyMCE.prototype.cancelEvent = function(e) {
-	if (tinyMCE.isMSIE) {
-		e.returnValue = false;
-		e.cancelBubble = true;
-	} else
-		e.preventDefault();
-};
+			tinyMCE.convertAllRelativeURLs(inst.getBody());
+		} else {
+			if (tinyMCE.settings['cleanup_on_startup']) {
+				tinyMCE._setHTML(inst.getDoc(), content);
 
-TinyMCE.prototype.removeTinyMCEFormElements = function(form_obj) {
-	// Check if form is valid
-	if (typeof(form_obj) == "undefined" || form_obj == null)
-		return;
-
-	// If not a form, find the form
-	if (form_obj.nodeName != "FORM") {
-		if (form_obj.form)
-			form_obj = form_obj.form;
-		else
-			form_obj = tinyMCE.getParentElement(form_obj, "form");
-	}
+				// Produces permission denied error in MSIE 5.5
+				eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}');
+			} else
+				tinyMCE._setHTML(inst.getDoc(), content);
+		}
 
-	// Still nothing
-	if (form_obj == null)
-		return;
+		// Fix for bug #957681
+		//inst.getDoc().designMode = inst.getDoc().designMode;
 
-	// Disable all UI form elements that TinyMCE created
-	for (var i=0; i<form_obj.elements.length; i++) {
-		var elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;
+		tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst);
+		tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc());
 
-		if (elementId.indexOf('mce_editor_') == 0)
-			form_obj.elements[i].disabled = true;
-	}
-};
+		// Re-add design mode on mozilla
+		if (!tinyMCE.isIE)
+			tinyMCE.addEventHandlers(inst);
 
-TinyMCE.prototype.accessibleEventHandler = function(e) {
-	var win = this._win;
-	e = tinyMCE.isMSIE ? win.event : e;
-	var elm = tinyMCE.isMSIE ? e.srcElement : e.target;
+		// Add blur handler
+		if (tinyMCE.isIE) {
+			tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch);
+			tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953
 
-	// Piggyback onchange
-	if (elm.nodeName == "SELECT" && !elm.oldonchange) {
-		elm.oldonchange = elm.onchange;
-		elm.onchange = null;
-	}
+			// Workaround for drag drop/copy paste base href bug
+			if (!tinyMCE.isOpera) {
+				tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove);
+				tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch);
+				tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch);
+			}
+		}
 
-	// Execute onchange and remove piggyback
-	if (e.keyCode == 13 || e.keyCode == 32) {
-		elm.onchange = elm.oldonchange;
-		elm.onchange();
-		elm.oldonchange = null;
-		tinyMCE.cancelEvent(e);
-	}
-};
+		// Trigger node change, this call locks buttons for tables and so forth
+		inst.select();
+		tinyMCE.selectedElement = inst.contentWindow.document.body;
 
-TinyMCE.prototype.addSelectAccessibility = function(e, select, win) {
-	// Add event handlers 
-	if (!select._isAccessible) {
-		select.onkeydown = tinyMCE.accessibleEventHandler;
-		select._isAccessible = true;
-		select._win = win;
-	}
-};
+		// Call custom DOM cleanup
+		tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody());
+		tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody());
+		tinyMCE._setEventsEnabled(inst.getBody(), false);
+		tinyMCE.cleanupAnchors(inst.getDoc());
 
-TinyMCE.prototype.handleEvent = function(e) {
-	// Remove odd, error
-	if (typeof(tinyMCE) == "undefined")
-		return true;
+		if (tinyMCE.getParam("convert_fonts_to_spans"))
+			tinyMCE.convertSpansToFonts(inst.getDoc());
 
-	//tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : ""));
+		inst.startContent = tinyMCE.trim(inst.getBody().innerHTML);
+		inst.undoRedo.add({ content : inst.startContent });
 
-	switch (e.type) {
-		case "blur":
-			if (tinyMCE.selectedInstance)
-				tinyMCE.selectedInstance.execCommand('mceEndTyping');
+		// Cleanup any mess left from storyAwayURLs
+		if (tinyMCE.isGecko) {
+			// Remove mce_src from textnodes and comments
+			tinyMCE.selectNodes(inst.getBody(), function(n) {
+				if (n.nodeType == 3 || n.nodeType == 8)
+					n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), "");
 
-			return;
+				return false;
+			});
+		}
+
+		// Remove Gecko spellchecking
+		if (tinyMCE.isGecko)
+			inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck");
+
+		// Cleanup any mess left from storyAwayURLs
+		tinyMCE._removeInternal(inst.getBody());
+
+		inst.select();
+		tinyMCE.triggerNodeChange(false, true);
+	},
+
+	storeAwayURLs : function(s) {
+		// Remove all mce_src, mce_href and replace them with new ones
+		// s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
+		// s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), '');
+
+		if (!s.match(/(mce_src|mce_href)/gi, s)) {
+			s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"');
+			s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"');
+		}
+
+		return s;
+	},
+
+	_removeInternal : function(n) {
+		if (tinyMCE.isGecko) {
+			// Remove mce_src from textnodes and comments
+			tinyMCE.selectNodes(n, function(n) {
+				if (n.nodeType == 3 || n.nodeType == 8)
+					n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), "");
+
+				return false;
+			});
+		}
+	},
 
-		case "submit":
-			tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
-			tinyMCE.triggerSave();
-			tinyMCE.isNotDirty = true;
+	removeTinyMCEFormElements : function(form_obj) {
+		var i, elementId;
+
+		// Skip form element removal
+		if (!tinyMCE.getParam('hide_selects_on_submit'))
 			return;
 
-		case "reset":
-			var formObj = tinyMCE.isMSIE ? window.event.srcElement : e.target;
+		// Check if form is valid
+		if (typeof(form_obj) == "undefined" || form_obj == null)
+			return;
 
-			for (var i=0; i<document.forms.length; i++) {
-				if (document.forms[i] == formObj)
-					window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
-			}
+		// If not a form, find the form
+		if (form_obj.nodeName != "FORM") {
+			if (form_obj.form)
+				form_obj = form_obj.form;
+			else
+				form_obj = tinyMCE.getParentElement(form_obj, "form");
+		}
 
+		// Still nothing
+		if (form_obj == null)
 			return;
 
-		case "keypress":
-			if (e.target.editorId) {
-				tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
-			} else {
-				if (e.target.ownerDocument.editorId)
-					tinyMCE.selectedInstance = tinyMCE.instances[e.target.ownerDocument.editorId];
-			}
+		// Disable all UI form elements that TinyMCE created
+		for (i=0; i<form_obj.elements.length; i++) {
+			elementId = form_obj.elements[i].name ? form_obj.elements[i].name : form_obj.elements[i].id;
 
-			if (tinyMCE.selectedInstance)
-				tinyMCE.selectedInstance.switchSettings();
+			if (elementId.indexOf('mce_editor_') == 0)
+				form_obj.elements[i].disabled = true;
+		}
+	},
 
-			// Insert space instead of &nbsp;
-/*			if (tinyMCE.isGecko && e.charCode == 32) {
-				if (tinyMCE.selectedInstance._insertSpace()) {
-					// Cancel event
-					e.preventDefault();
-					return false;
-				}
-			}*/
+	handleEvent : function(e) {
+		var inst = tinyMCE.selectedInstance;
 
-			// Insert P element
-			if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
-				// Insert P element instead of BR
-				if (tinyMCE.selectedInstance._insertPara(e)) {
-					// Cancel event
-					tinyMCE.execCommand("mceAddUndoLevel");
-					tinyMCE.cancelEvent(e);
-					return false;
-				}
-			}
+		// Remove odd, error
+		if (typeof(tinyMCE) == "undefined")
+			return true;
 
-			// Handle backspace
-			if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
-				// Insert P element instead of BR
-				if (tinyMCE.selectedInstance._handleBackSpace(e.type)) {
-					// Cancel event
-					tinyMCE.execCommand("mceAddUndoLevel");
-					tinyMCE.cancelEvent(e);
-					return false;
-				}
-			}
+		//tinyMCE.debug(e.type + " " + e.target.nodeName + " " + (e.relatedTarget ? e.relatedTarget.nodeName : ""));
 
-			// Mozilla custom key handling
-			if (tinyMCE.isGecko && (e.ctrlKey && !e.altKey) && tinyMCE.settings['custom_undo_redo']) {
-				if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {
-					if (e.charCode == 122) { // Ctrl+Z
-						tinyMCE.selectedInstance.execCommand("Undo");
-						tinyMCE.cancelEvent(e);
-						return false;
-					}
+		if (tinyMCE.executeCallback(tinyMCE.selectedInstance, 'handle_event_callback', 'handleEvent', e))
+			return false;
 
-					if (e.charCode == 121) { // Ctrl+Y
-						tinyMCE.selectedInstance.execCommand("Redo");
-						tinyMCE.cancelEvent(e);
-						return false;
+		switch (e.type) {
+			case "beforedeactivate": // Was added due to bug #1439953
+			case "blur":
+				if (tinyMCE.selectedInstance)
+					tinyMCE.selectedInstance.execCommand('mceEndTyping');
+
+				tinyMCE.hideMenus();
+
+				return;
+
+			// Workaround for drag drop/copy paste base href bug
+			case "drop":
+			case "beforepaste":
+				if (tinyMCE.selectedInstance)
+					tinyMCE.selectedInstance.setBaseHREF(null);
+
+				// Fixes odd MSIE bug where drag/droping elements in a iframe with height 100% breaks
+				// This logic forces the width/height to be in pixels while the user is drag/dropping
+				if (tinyMCE.isRealIE) {
+					var ife = tinyMCE.selectedInstance.iframeElement;
+
+					/*if (ife.style.width.indexOf('%') != -1) {
+						ife._oldWidth = ife.width.height;
+						ife.style.width = ife.clientWidth;
+					}*/
+
+					if (ife.style.height.indexOf('%') != -1) {
+						ife._oldHeight = ife.style.height;
+						ife.style.height = ife.clientHeight;
 					}
 				}
 
-				if (e.charCode == 98) { // Ctrl+B
-					tinyMCE.selectedInstance.execCommand("Bold");
-					tinyMCE.cancelEvent(e);
-					return false;
+				window.setTimeout("tinyMCE.selectedInstance.setBaseHREF(tinyMCE.settings['base_href']);tinyMCE._resetIframeHeight();", 1);
+				return;
+
+			case "submit":
+				tinyMCE.removeTinyMCEFormElements(tinyMCE.isMSIE ? window.event.srcElement : e.target);
+				tinyMCE.triggerSave();
+				tinyMCE.isNotDirty = true;
+				return;
+
+			case "reset":
+				var formObj = tinyMCE.isIE ? window.event.srcElement : e.target;
+
+				for (var i=0; i<document.forms.length; i++) {
+					if (document.forms[i] == formObj)
+						window.setTimeout('tinyMCE.resetForm(' + i + ');', 10);
 				}
 
-				if (e.charCode == 105) { // Ctrl+I
-					tinyMCE.selectedInstance.execCommand("Italic");
-					tinyMCE.cancelEvent(e);
+				return;
+
+			case "keypress":
+				if (inst && inst.handleShortcut(e))
 					return false;
+
+				if (e.target.editorId) {
+					tinyMCE.instances[e.target.editorId].select();
+				} else {
+					if (e.target.ownerDocument.editorId)
+						tinyMCE.instances[e.target.ownerDocument.editorId].select();
 				}
 
-				if (e.charCode == 117) { // Ctrl+U
-					tinyMCE.selectedInstance.execCommand("Underline");
-					tinyMCE.cancelEvent(e);
-					return false;
+				if (tinyMCE.selectedInstance)
+					tinyMCE.selectedInstance.switchSettings();
+
+				// Insert P element
+				if ((tinyMCE.isGecko || tinyMCE.isOpera || tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && e.keyCode == 13 && !e.shiftKey) {
+					// Insert P element instead of BR
+					if (TinyMCE_ForceParagraphs._insertPara(tinyMCE.selectedInstance, e)) {
+						// Cancel event
+						tinyMCE.execCommand("mceAddUndoLevel");
+						return tinyMCE.cancelEvent(e);
+					}
 				}
 
-				if (e.charCode == 118) { // Ctrl+V
-					tinyMCE.selectedInstance.execCommand("mceInsertContent", false, '<geckopastefix/>');
+				// Handle backspace
+				if ((tinyMCE.isGecko && !tinyMCE.isSafari) && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
+					// Insert P element instead of BR
+					if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
+						// Cancel event
+						tinyMCE.execCommand("mceAddUndoLevel");
+						return tinyMCE.cancelEvent(e);
+					}
 				}
-			}
 
-			// Return key pressed
-			if (tinyMCE.isMSIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
-				if (e.target.editorId)
-					tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
+				// Return key pressed
+				if (tinyMCE.isIE && tinyMCE.settings['force_br_newlines'] && e.keyCode == 13) {
+					if (e.target.editorId)
+						tinyMCE.instances[e.target.editorId].select();
+
+					if (tinyMCE.selectedInstance) {
+						var sel = tinyMCE.selectedInstance.getDoc().selection;
+						var rng = sel.createRange();
 
-				if (tinyMCE.selectedInstance) {
-					var sel = tinyMCE.selectedInstance.getDoc().selection;
-					var rng = sel.createRange();
+						if (tinyMCE.getParentElement(rng.parentElement(), "li") != null)
+							return false;
 
-					if (tinyMCE.getParentElement(rng.parentElement(), "li") != null)
-						return false;
+						// Cancel event
+						e.returnValue = false;
+						e.cancelBubble = true;
 
-					// Cancel event
-					e.returnValue = false;
-					e.cancelBubble = true;
-
-					// Insert BR element
-					rng.pasteHTML("<br />");
-					rng.collapse(false);
-					rng.select();
+						// Insert BR element
+						rng.pasteHTML("<br />");
+						rng.collapse(false);
+						rng.select();
 
-					tinyMCE.execCommand("mceAddUndoLevel");
+						tinyMCE.execCommand("mceAddUndoLevel");
+						tinyMCE.triggerNodeChange(false);
+						return false;
+					}
+				}
+
+				// Backspace or delete
+				if (e.keyCode == 8 || e.keyCode == 46) {
+					tinyMCE.selectedElement = e.target;
+					tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a");
+					tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img");
 					tinyMCE.triggerNodeChange(false);
-					return false;
 				}
-			}
 
-			// Backspace or delete
-			if (e.keyCode == 8 || e.keyCode == 46) {
-				tinyMCE.selectedElement = e.target;
-				tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a");
-				tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img");
-				tinyMCE.triggerNodeChange(false);
-			}
+				return false;
+			break;
 
-			return false;
-		break;
+			case "keyup":
+			case "keydown":
+				tinyMCE.hideMenus();
+				tinyMCE.hasMouseMoved = false;
 
-		case "keyup":
-		case "keydown":
-			if (e.target.editorId)
-				tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
-			else
-				return;
+				if (inst && inst.handleShortcut(e))
+					return false;
 
-			if (tinyMCE.selectedInstance)
-				tinyMCE.selectedInstance.switchSettings();
+				if (e.target.editorId)
+					tinyMCE.instances[e.target.editorId].select();
 
-			var inst = tinyMCE.selectedInstance;
+				if (tinyMCE.selectedInstance)
+					tinyMCE.selectedInstance.switchSettings();
 
-			// Handle backspace
-			if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
-				// Insert P element instead of BR
-				if (tinyMCE.selectedInstance._handleBackSpace(e.type)) {
-					// Cancel event
-					tinyMCE.execCommand("mceAddUndoLevel");
-					e.preventDefault();
-					return false;
-				}
-			}
+				var inst = tinyMCE.selectedInstance;
 
-			tinyMCE.selectedElement = null;
-			tinyMCE.selectedNode = null;
-			var elm = tinyMCE.selectedInstance.getFocusElement();
-			tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
-			tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
-			tinyMCE.selectedElement = elm;
-
-			// Update visualaids on tabs
-			if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
-				tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
-
-			// Fix empty elements on return/enter, check where enter occured
-			if (tinyMCE.isMSIE && e.type == "keydown" && e.keyCode == 13)
-				tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();
-
-			// Fix empty elements on return/enter
-			if (tinyMCE.isMSIE && e.type == "keyup" && e.keyCode == 13) {
-				var elm = tinyMCE.enterKeyElement;
-				if (elm) {
-					var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
-					var dre = new RegExp('^H[1-6]$','g'); // Add double on these
-
-					if (!elm.hasChildNodes() && !re.test(elm.nodeName)) {
-						if (dre.test(elm.nodeName))
-							elm.innerHTML = "&nbsp;&nbsp;";
-						else
-							elm.innerHTML = "&nbsp;";
+				// Handle backspace
+				if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) {
+					// Insert P element instead of BR
+					if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) {
+						// Cancel event
+						tinyMCE.execCommand("mceAddUndoLevel");
+						e.preventDefault();
+						return false;
 					}
 				}
-			}
 
-			// Check if it's a position key
-			var keys = tinyMCE.posKeyCodes;
-			var posKey = false;
-			for (var i=0; i<keys.length; i++) {
-				if (keys[i] == e.keyCode) {
-					posKey = true;
-					break;
+				tinyMCE.selectedElement = null;
+				tinyMCE.selectedNode = null;
+				var elm = tinyMCE.selectedInstance.getFocusElement();
+				tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a");
+				tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img");
+				tinyMCE.selectedElement = elm;
+
+				// Update visualaids on tabs
+				if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9)
+					tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance);
+
+				// Fix empty elements on return/enter, check where enter occured
+				if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13)
+					tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement();
+
+				// Fix empty elements on return/enter
+				if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) {
+					var elm = tinyMCE.enterKeyElement;
+					if (elm) {
+						var re = new RegExp('^HR|IMG|BR$','g'); // Skip these
+						var dre = new RegExp('^H[1-6]$','g'); // Add double on these
+
+						if (!elm.hasChildNodes() && !re.test(elm.nodeName)) {
+							if (dre.test(elm.nodeName))
+								elm.innerHTML = "&nbsp;&nbsp;";
+							else
+								elm.innerHTML = "&nbsp;";
+						}
+					}
 				}
-			}
 
-			// MSIE custom key handling
-			if (tinyMCE.isMSIE && tinyMCE.settings['custom_undo_redo']) {
-				var keys = new Array(8,46); // Backspace,Delete
+				// Check if it's a position key
+				var keys = tinyMCE.posKeyCodes;
+				var posKey = false;
 				for (var i=0; i<keys.length; i++) {
 					if (keys[i] == e.keyCode) {
-						if (e.type == "keyup")
-							tinyMCE.triggerNodeChange(false);
+						posKey = true;
+						break;
 					}
 				}
 
-				if (tinyMCE.settings['custom_undo_redo_keyboard_shortcuts']) {
-					if (e.keyCode == 90 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Z
-						tinyMCE.selectedInstance.execCommand("Undo");
-						tinyMCE.triggerNodeChange(false);
+				// MSIE custom key handling
+				if (tinyMCE.isIE && tinyMCE.settings['custom_undo_redo']) {
+					var keys = new Array(8,46); // Backspace,Delete
+
+					for (var i=0; i<keys.length; i++) {
+						if (keys[i] == e.keyCode) {
+							if (e.type == "keyup")
+								tinyMCE.triggerNodeChange(false);
+						}
 					}
+				}
 
-					if (e.keyCode == 89 && (e.ctrlKey && !e.altKey) && e.type == "keydown") { // Ctrl+Y
-						tinyMCE.selectedInstance.execCommand("Redo");
-						tinyMCE.triggerNodeChange(false);
-					}
+				// If Ctrl key
+				if (e.keyCode == 17)
+					return true;
 
-					if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey)) {
-						// Cancel event
-						e.returnValue = false;
-						e.cancelBubble = true;
-						return false;
-					}
-				}
-			}
+				// Handle Undo/Redo when typing content
 
-			// If undo/redo key
-			if ((e.keyCode == 90 || e.keyCode == 89) && (e.ctrlKey && !e.altKey))
-				return true;
+				if (tinyMCE.isGecko) {
+					// Start typing (not a position key or ctrl key, but ctrl+x and ctrl+p is ok)
+					if (!posKey && e.type == "keyup" && !e.ctrlKey || (e.ctrlKey && (e.keyCode == 86 || e.keyCode == 88)))
+						tinyMCE.execCommand("mceStartTyping");
+				} else {
+					// IE seems to be working better with this setting
+					if (!posKey && e.type == "keyup")
+						tinyMCE.execCommand("mceStartTyping");
+				}
 
-			// If Ctrl key
-			if (e.keyCode == 17)
-				return true;
+				// Store undo bookmark
+				if (e.type == "keydown" && (posKey || e.ctrlKey) && inst)
+					inst.undoBookmark = inst.selection.getBookmark();
 
-			// Handle Undo/Redo when typing content
+				// End typing (position key) or some Ctrl event
+				if (e.type == "keyup" && (posKey || e.ctrlKey))
+					tinyMCE.execCommand("mceEndTyping");
 
-			// Start typing (non position key)
-			if (!posKey && e.type == "keyup")
-				tinyMCE.execCommand("mceStartTyping");
+				if (posKey && e.type == "keyup")
+					tinyMCE.triggerNodeChange(false);
 
-			// End typing (position key) or some Ctrl event
-			if (e.type == "keyup" && (posKey || e.ctrlKey))
-				tinyMCE.execCommand("mceEndTyping");
+				if (tinyMCE.isIE && e.ctrlKey)
+					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+			break;
 
-			if (posKey && e.type == "keyup")
-				tinyMCE.triggerNodeChange(false);
+			case "mousedown":
+			case "mouseup":
+			case "click":
+			case "dblclick":
+			case "focus":
+				tinyMCE.hideMenus();
 
-			if (tinyMCE.isMSIE && e.ctrlKey)
-				window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
-		break;
-
-		case "mousedown":
-		case "mouseup":
-		case "click":
-		case "focus":
-			if (tinyMCE.selectedInstance)
-				tinyMCE.selectedInstance.switchSettings();
+				if (tinyMCE.selectedInstance) {
+					tinyMCE.selectedInstance.switchSettings();
+					tinyMCE.selectedInstance.isFocused = true;
+				}
 
-			// Check instance event trigged on
-			var targetBody = tinyMCE.getParentElement(e.target, "body");
-			for (var instanceName in tinyMCE.instances) {
-				if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))
-					continue;
+				// Check instance event trigged on
+				var targetBody = tinyMCE.getParentElement(e.target, "html");
+				for (var instanceName in tinyMCE.instances) {
+					if (!tinyMCE.isInstance(tinyMCE.instances[instanceName]))
+						continue;
 
-				var inst = tinyMCE.instances[instanceName];
+					var inst = tinyMCE.instances[instanceName];
 
-				// Reset design mode if lost (on everything just in case)
-				inst.autoResetDesignMode();
+					// Reset design mode if lost (on everything just in case)
+					inst.autoResetDesignMode();
 
-				if (inst.getBody() == targetBody) {
-					tinyMCE.selectedInstance = inst;
-					tinyMCE.selectedElement = e.target;
-					tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
-					tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img");
-					break;
+					// Use HTML element since users might click outside of body element
+					if (inst.getBody().parentNode == targetBody) {
+						inst.select();
+						tinyMCE.selectedElement = e.target;
+						tinyMCE.linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
+						tinyMCE.imgElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "img");
+						break;
+					}
 				}
-			}
 
-			if (tinyMCE.isSafari) {
-				tinyMCE.selectedInstance.lastSafariSelection = tinyMCE.selectedInstance.getBookmark();
-				tinyMCE.selectedInstance.lastSafariSelectedElement = tinyMCE.selectedElement;
+				// Add first bookmark location
+				if (!tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark && (e.type == "mouseup" || e.type == "dblclick"))
+					tinyMCE.selectedInstance.undoRedo.undoLevels[0].bookmark = tinyMCE.selectedInstance.selection.getBookmark();
+
+				// Reset selected node
+				if (e.type != "focus")
+					tinyMCE.selectedNode = null;
 
-				var lnk = tinyMCE.getParentElement(tinyMCE.selectedElement, "a");
+				tinyMCE.triggerNodeChange(false);
+				tinyMCE.execCommand("mceEndTyping");
 
-				// Patch the darned link
-				if (lnk && e.type == "mousedown") {
-					lnk.setAttribute("mce_real_href", lnk.getAttribute("href"));
-					lnk.setAttribute("href", "javascript:void(0);");
-				}
+				if (e.type == "mouseup")
+					tinyMCE.execCommand("mceAddUndoLevel");
 
-				// Patch back
-				if (lnk && e.type == "click") {
-					window.setTimeout(function() {
-						lnk.setAttribute("href", lnk.getAttribute("mce_real_href"));
-						lnk.removeAttribute("mce_real_href");
-					}, 10);
-				}
-			}
+				// Just in case
+				if (!tinyMCE.selectedInstance && e.target.editorId)
+					tinyMCE.instances[e.target.editorId].select();
 
-			// Reset selected node
-			if (e.type != "focus")
-				tinyMCE.selectedNode = null;
+				return false;
+			break;
+		}
+	},
 
-			tinyMCE.triggerNodeChange(false);
-			tinyMCE.execCommand("mceEndTyping");
+	getButtonHTML : function(id, lang, img, cmd, ui, val) {
+		var h = '', m, x, io = '';
 
-			if (e.type == "mouseup")
-				tinyMCE.execCommand("mceAddUndoLevel");
+		cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\'';
 
-			// Just in case
-			if (!tinyMCE.selectedInstance && e.target.editorId)
-				tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId];
+		if (typeof(ui) != "undefined" && ui != null)
+			cmd += ',' + ui;
 
-			return false;
-		break;
-    } // end switch
-}; // end function
+		if (typeof(val) != "undefined" && val != null)
+			cmd += ",'" + val + "'";
 
-TinyMCE.prototype.switchClass = function(element, class_name, lock_state) {
-	var lockChanged = false;
+		cmd += ');';
 
-	if (typeof(lock_state) != "undefined" && element != null) {
-		element.classLock = lock_state;
-		lockChanged = true;
-	}
+		// Patch for IE7 bug with hover out not restoring correctly
+		if (tinyMCE.isRealIE)
+			io = 'onmouseover="tinyMCE.lastHover = this;"';
 
-	if (element != null && (lockChanged || !element.classLock)) {
-		element.oldClassName = element.className;
-		element.className = class_name;
-	}
-};
+		// Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled
+		if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = this.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) {
+			// Tiled button
+			x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
+			h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceTiledButton mceButtonNormal" target="_self">';
+			h += '<img src="{$themeurl}/images/spacer.gif" style="background-position: ' + x + 'px 0" title="{$' + lang + '}" />';
+			h += '</a>';
+		} else {
+			// Normal button
+			h += '<a id="{$editor_id}_' + id + '" href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" ' + io + ' class="mceButtonNormal" target="_self">';
+			h += '<img src="' + img + '" title="{$' + lang + '}" />';
+			h += '</a>';
+		}
 
-TinyMCE.prototype.restoreAndSwitchClass = function(element, class_name) {
-	if (element != null && !element.classLock) {
-		this.restoreClass(element);
-		this.switchClass(element, class_name);
-	}
-};
+		return h;
+	},
 
-TinyMCE.prototype.switchClassSticky = function(element_name, class_name, lock_state) {
-	var element, lockChanged = false;
+	getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) {
+		var h = '', m, x;
 
-	// Performance issue
-	if (!this.stickyClassesLookup[element_name])
-		this.stickyClassesLookup[element_name] = document.getElementById(element_name);
+		mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');';
+		cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\'';
 
-//	element = document.getElementById(element_name);
-	element = this.stickyClassesLookup[element_name];
+		if (typeof(ui) != "undefined" && ui != null)
+			cmd += ',' + ui;
 
-	if (typeof(lock_state) != "undefined" && element != null) {
-		element.classLock = lock_state;
-		lockChanged = true;
-	}
+		if (typeof(val) != "undefined" && val != null)
+			cmd += ",'" + val + "'";
 
-	if (element != null && (lockChanged || !element.classLock)) {
-		element.className = class_name;
-		element.oldClassName = class_name;
+		cmd += ');';
 
-		// Fix opacity in Opera
-		if (tinyMCE.isOpera) {
-			if (class_name == "mceButtonDisabled") {
-				var suffix = "";
+		// Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled
+		if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) {
+			x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20);
 
-				if (!element.mceOldSrc)
-					element.mceOldSrc = element.src;
+			if (tinyMCE.isRealIE)
+				h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">';
+			else
+				h += '<span id="{$editor_id}_' + id + '" class="mceMenuButton">';
 
-				if (this.operaOpacityCounter > -1)
-					suffix = '?rnd=' + this.operaOpacityCounter++;
+			h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceTiledButton mceMenuButtonNormal" target="_self">';
+			h += '<img src="{$themeurl}/images/spacer.gif" style="width: 20px; height: 20px; background-position: ' + x + 'px 0" title="{$' + lang + '}" /></a>';
+			h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />';
+			h += '</a></span>';
+		} else {
+			if (tinyMCE.isRealIE)
+				h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton" onmouseover="tinyMCE._menuButtonEvent(\'over\',this);tinyMCE.lastHover = this;" onmouseout="tinyMCE._menuButtonEvent(\'out\',this);">';
+			else
+				h += '<span id="{$editor_id}_' + id + '" dir="ltr" class="mceMenuButton">';
 
-				element.src = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/images/opacity.png" + suffix;
-				element.style.backgroundImage = "url('" + element.mceOldSrc + "')";
-			} else {
-				if (element.mceOldSrc) {
-					element.src = element.mceOldSrc;
-					element.parentNode.style.backgroundImage = "";
-					element.mceOldSrc = null;
-				}
-			}
+			h += '<a href="javascript:' + cmd + '" onclick="' + cmd + 'return false;" onmousedown="return false;" class="mceMenuButtonNormal" target="_self">';
+			h += '<img src="' + img + '" title="{$' + lang + '}" /></a>';
+			h += '<a href="javascript:' + mcmd + '" onclick="' + mcmd + 'return false;" onmousedown="return false;"><img src="{$themeurl}/images/button_menu.gif" title="{$' + lang + '}" class="mceMenuButton" />';
+			h += '</a></span>';
 		}
-	}
-};
 
-TinyMCE.prototype.restoreClass = function(element) {
-	if (element != null && element.oldClassName && !element.classLock) {
-		element.className = element.oldClassName;
-		element.oldClassName = null;
-	}
-};
+		return h;
+	},
 
-TinyMCE.prototype.setClassLock = function(element, lock_state) {
-	if (element != null)
-		element.classLock = lock_state;
-};
+	_menuButtonEvent : function(e, o) {
+		if (o.className == 'mceMenuButtonFocus')
+			return;
 
-TinyMCE.prototype.addEvent = function(obj, name, handler) {
-	if (tinyMCE.isMSIE) {
-		obj.attachEvent("on" + name, handler);
-	} else
-		obj.addEventListener(name, handler, false);
-};
+		if (e == 'over')
+			o.className = o.className + ' mceMenuHover';
+		else
+			o.className = o.className.replace(/\s.*$/, '');
+	},
 
-TinyMCE.prototype.submitPatch = function() {
-	tinyMCE.removeTinyMCEFormElements(this);
-	tinyMCE.triggerSave();
-	this.mceOldSubmit();
-	tinyMCE.isNotDirty = true;
-};
+	addButtonMap : function(m) {
+		var i, a = m.replace(/\s+/, '').split(',');
 
-TinyMCE.prototype.onLoad = function() {
-	for (var c=0; c<tinyMCE.configs.length; c++) {
-		tinyMCE.settings = tinyMCE.configs[c];
+		for (i=0; i<a.length; i++)
+			this.buttonMap[a[i]] = i;
+	},
+
+	submitPatch : function() {
+		tinyMCE.removeTinyMCEFormElements(this);
+		tinyMCE.triggerSave();
+		tinyMCE.isNotDirty = true;
+		this.mceOldSubmit();
+	},
+
+	onLoad : function() {
+		var r;
+
+		// Wait for everything to be loaded first
+		if (tinyMCE.settings.strict_loading_mode && this.loadingIndex != -1) {
+			window.setTimeout('tinyMCE.onLoad();', 1);
+			return;
+		}
 
-		var selector = tinyMCE.getParam("editor_selector");
-		var deselector = tinyMCE.getParam("editor_deselector");
-		var elementRefAr = new Array();
+		if (tinyMCE.isRealIE && window.event.type == "readystatechange" && document.readyState != "complete")
+			return true;
 
-		// Add submit triggers
-		if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
-			for (var i=0; i<document.forms.length; i++) {
-				var form = document.forms[i];
+		if (tinyMCE.isLoaded)
+			return true;
 
-				tinyMCE.addEvent(form, "submit", TinyMCE.prototype.handleEvent);
-				tinyMCE.addEvent(form, "reset", TinyMCE.prototype.handleEvent);
-				tinyMCE.submitTriggers = true; // Do it only once
+		tinyMCE.isLoaded = true;
 
-				// Patch the form.submit function
-				if (tinyMCE.settings['submit_patch']) {
-					try {
-						form.mceOldSubmit = form.submit;
-						form.submit = TinyMCE.prototype.submitPatch;
-					} catch (e) {
-						// Do nothing
+		// IE produces JS error if TinyMCE is placed in a frame
+		// It seems to have something to do with the selection not beeing
+		// correctly initialized in IE so this hack solves the problem
+		if (tinyMCE.isRealIE && document.body) {
+			r = document.body.createTextRange();
+			r.collapse(true);
+			r.select();
+		}
+
+		tinyMCE.dispatchCallback(null, 'onpageload', 'onPageLoad');
+
+		for (var c=0; c<tinyMCE.configs.length; c++) {
+			tinyMCE.settings = tinyMCE.configs[c];
+
+			var selector = tinyMCE.getParam("editor_selector");
+			var deselector = tinyMCE.getParam("editor_deselector");
+			var elementRefAr = new Array();
+
+			// Add submit triggers
+			if (document.forms && tinyMCE.settings['add_form_submit_trigger'] && !tinyMCE.submitTriggers) {
+				for (var i=0; i<document.forms.length; i++) {
+					var form = document.forms[i];
+
+					tinyMCE.addEvent(form, "submit", TinyMCE_Engine.prototype.handleEvent);
+					tinyMCE.addEvent(form, "reset", TinyMCE_Engine.prototype.handleEvent);
+					tinyMCE.submitTriggers = true; // Do it only once
+
+					// Patch the form.submit function
+					if (tinyMCE.settings['submit_patch']) {
+						try {
+							form.mceOldSubmit = form.submit;
+							form.submit = TinyMCE_Engine.prototype.submitPatch;
+						} catch (e) {
+							// Do nothing
+						}
 					}
 				}
 			}
-		}
-
-		// Add editor instances based on mode
-		var mode = tinyMCE.settings['mode'];
-		switch (mode) {
-			case "exact":
-				var elements = tinyMCE.getParam('elements', '', true, ',');
-
-				for (var i=0; i<elements.length; i++) {
-					var element = tinyMCE._getElementById(elements[i]);
-					var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
-
-					if (tinyMCE.getAttrib(element, "class").indexOf(deselector) != -1)
-						continue;
 
-					if (trigger == "false")
-						continue;
+			// Add editor instances based on mode
+			var mode = tinyMCE.settings['mode'];
+			switch (mode) {
+				case "exact":
+					var elements = tinyMCE.getParam('elements', '', true, ',');
+
+					for (var i=0; i<elements.length; i++) {
+						var element = tinyMCE._getElementById(elements[i]);
+						var trigger = element ? element.getAttribute(tinyMCE.settings['textarea_trigger']) : "";
+
+						if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(element, "class")))
+							continue;
+
+						if (trigger == "false")
+							continue;
+
+						if ((tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) && element) {
+							elementRefAr[elementRefAr.length] = element;
+							continue;
+						}
 
-					if (tinyMCE.settings['ask'] && element) {
-						elementRefAr[elementRefAr.length] = element;
-						continue;
+						if (element)
+							tinyMCE.addMCEControl(element, elements[i]);
+						else if (tinyMCE.settings['debug'])
+							alert("Error: Could not find element by id or name: " + elements[i]);
 					}
+				break;
 
-					if (element)
-						tinyMCE.addMCEControl(element, elements[i]);
-					else if (tinyMCE.settings['debug'])
-						alert("Error: Could not find element by id or name: " + elements[i]);
-				}
-			break;
+				case "specific_textareas":
+				case "textareas":
+					var nodeList = document.getElementsByTagName("textarea");
 
-			case "specific_textareas":
-			case "textareas":
-				var nodeList = document.getElementsByTagName("textarea");
-
-				for (var i=0; i<nodeList.length; i++) {
-					var elm = nodeList.item(i);
-					var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
+					for (var i=0; i<nodeList.length; i++) {
+						var elm = nodeList.item(i);
+						var trigger = elm.getAttribute(tinyMCE.settings['textarea_trigger']);
 
-					if (selector != '' && tinyMCE.getAttrib(elm, "class").indexOf(selector) == -1)
-						continue;
+						if (selector != '' && !new RegExp('\\b' + selector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
+							continue;
 
-					if (selector != '')
-						trigger = selector != "" ? "true" : "";
+						if (selector != '')
+							trigger = selector != "" ? "true" : "";
 
-					if (tinyMCE.getAttrib(elm, "class").indexOf(deselector) != -1)
-						continue;
+						if (new RegExp('\\b' + deselector + '\\b').test(tinyMCE.getAttrib(elm, "class")))
+							continue;
 
-					if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false"))
-						elementRefAr[elementRefAr.length] = elm;
-				}
-			break;
-		}
+						if ((mode == "specific_textareas" && trigger == "true") || (mode == "textareas" && trigger != "false"))
+							elementRefAr[elementRefAr.length] = elm;
+					}
+				break;
+			}
 
-		for (var i=0; i<elementRefAr.length; i++) {
-			var element = elementRefAr[i];
-			var elementId = element.name ? element.name : element.id;
+			for (var i=0; i<elementRefAr.length; i++) {
+				var element = elementRefAr[i];
+				var elementId = element.name ? element.name : element.id;
+
+				if (tinyMCE.settings['ask'] || tinyMCE.settings['convert_on_click']) {
+					// Focus breaks in Mozilla
+					if (tinyMCE.isGecko) {
+						var settings = tinyMCE.settings;
+
+						tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
+
+						if (element.nodeName != "TEXTAREA" && element.nodeName != "INPUT")
+							tinyMCE.addEvent(element, "click", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
+						// tinyMCE.addEvent(element, "mouseover", function (e) {window.setTimeout(function() {TinyMCE_Engine.prototype.confirmAdd(e, settings);}, 10);});
+					} else {
+						var settings = tinyMCE.settings;
 
-			if (tinyMCE.settings['ask']) {
-				// Focus breaks in Mozilla
-				if (tinyMCE.isGecko) {
-					var settings = tinyMCE.settings;
+						tinyMCE.addEvent(element, "focus", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
+						tinyMCE.addEvent(element, "click", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
+						// tinyMCE.addEvent(element, "mouseenter", function () { TinyMCE_Engine.prototype.confirmAdd(null, settings); });
+					}
+				} else
+					tinyMCE.addMCEControl(element, elementId);
+			}
 
-					tinyMCE.addEvent(element, "focus", function (e) {window.setTimeout(function() {TinyMCE.prototype.confirmAdd(e, settings);}, 10);});
-				} else {
-					var settings = tinyMCE.settings;
+			// Handle auto focus
+			if (tinyMCE.settings['auto_focus']) {
+				window.setTimeout(function () {
+					var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
+					inst.selection.selectNode(inst.getBody(), true, true);
+					inst.contentWindow.focus();
+				}, 100);
+			}
 
-					tinyMCE.addEvent(element, "focus", function () { TinyMCE.prototype.confirmAdd(null, settings); });
-				}
-			} else
-				tinyMCE.addMCEControl(element, elementId);
+			tinyMCE.dispatchCallback(null, 'oninit', 'onInit');
 		}
+	},
 
-		// Handle auto focus
-		if (tinyMCE.settings['auto_focus']) {
-			window.setTimeout(function () {
-				var inst = tinyMCE.getInstanceById(tinyMCE.settings['auto_focus']);
-				inst.selectNode(inst.getBody(), true, true);
-				inst.contentWindow.focus();
-			}, 10);
-		}
+	isInstance : function(o) {
+		return o != null && typeof(o) == "object" && o.isTinyMCE_Control;
+	},
 
-		tinyMCE.executeCallback('oninit', '_oninit', 0);
-	}
-};
+	getParam : function(name, default_value, strip_whitespace, split_chr) {
+		var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
 
-TinyMCE.prototype.removeMCEControl = function(editor_id) {
-	var inst = tinyMCE.getInstanceById(editor_id);
+		// Fix bool values
+		if (value == "true" || value == "false")
+			return (value == "true");
 
-	if (inst) {
-		inst.switchSettings();
+		if (strip_whitespace)
+			value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "");
 
-		editor_id = inst.editorId;
-		var html = tinyMCE.getContent(editor_id);
+		if (typeof(split_chr) != "undefined" && split_chr != null) {
+			value = value.split(split_chr);
+			var outArray = new Array();
 
-		// Remove editor instance from instances array
-		var tmpInstances = new Array();
-		for (var instanceName in tinyMCE.instances) {
-			var instance = tinyMCE.instances[instanceName];
-			if (!tinyMCE.isInstance(instance))
-				continue;
+			for (var i=0; i<value.length; i++) {
+				if (value[i] && value[i] != "")
+					outArray[outArray.length] = value[i];
+			}
 
-			if (instanceName != editor_id)
-					tmpInstances[instanceName] = instance;
+			value = outArray;
 		}
-		tinyMCE.instances = tmpInstances;
 
-		tinyMCE.selectedElement = null;
-		tinyMCE.selectedInstance = null;
+		return value;
+	},
 
-		// Remove element
-		var replaceElement = document.getElementById(editor_id + "_parent");
-		var oldTargetElement = inst.oldTargetElement;
-		var targetName = oldTargetElement.nodeName.toLowerCase();
-
-		if (targetName == "textarea" || targetName == "input") {
-			// Just show the old text area
-			replaceElement.parentNode.removeChild(replaceElement);
-			oldTargetElement.style.display = "inline";
-			oldTargetElement.value = html;
-		} else {
-			oldTargetElement.innerHTML = html;
+	getLang : function(name, default_value, parse_entities, va) {
+		var v = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name], n;
 
-			replaceElement.parentNode.insertBefore(oldTargetElement, replaceElement);
-			replaceElement.parentNode.removeChild(replaceElement);
+		if (parse_entities)
+			v = tinyMCE.entityDecode(v);
+
+		if (va) {
+			for (n in va)
+				v = this.replaceVar(v, n, va[n]);
 		}
-	}
-};
 
-TinyMCE.prototype._cleanupElementName = function(element_name, element) {
-	var name = "";
+		return v;
+	},
 
-	element_name = element_name.toLowerCase();
+	entityDecode : function(s) {
+		var e = document.createElement("div");
 
-	// Never include body
-	if (element_name == "body")
-		return null;
+		e.innerHTML = s;
 
-	// If verification mode
-	if (tinyMCE.cleanup_verify_html) {
-		// Check if invalid element
-		for (var i=0; i<tinyMCE.cleanup_invalidElements.length; i++) {
-			if (tinyMCE.cleanup_invalidElements[i] == element_name)
-				return null;
-		}
+		return e.firstChild.nodeValue;
+	},
 
-		// Check if valid element
-		var validElement = false;
-		var elementAttribs = null;
-		for (var i=0; i<tinyMCE.cleanup_validElements.length && !elementAttribs; i++) {
-			for (var x=0, n=tinyMCE.cleanup_validElements[i][0].length; x<n; x++) {
-				var elmMatch = tinyMCE.cleanup_validElements[i][0][x];
-
-				if (elmMatch.charAt(0) == '+' || elmMatch.charAt(0) == '-')
-					elmMatch = elmMatch.substring(1);
-
-				// Handle wildcard/regexp
-				if (elmMatch.match(new RegExp('\\*|\\?|\\+', 'g')) != null) {
-					elmMatch = elmMatch.replace(new RegExp('\\?', 'g'), '(\\S?)');
-					elmMatch = elmMatch.replace(new RegExp('\\+', 'g'), '(\\S+)');
-					elmMatch = elmMatch.replace(new RegExp('\\*', 'g'), '(\\S*)');
-					elmMatch = "^" + elmMatch + "$";
-					if (element_name.match(new RegExp(elmMatch, 'g'))) {
-						elementAttribs = tinyMCE.cleanup_validElements[i];
-						validElement = true;
-						break;
-					}
-				}
+	addToLang : function(prefix, ar) {
+		for (var key in ar) {
+			if (typeof(ar[key]) == 'function')
+				continue;
 
-				// Handle non regexp
-				if (element_name == elmMatch) {
-					elementAttribs = tinyMCE.cleanup_validElements[i];
-					validElement = true;
-					element_name = elementAttribs[0][0];
-					break;
-				}
-			}
+			tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
 		}
 
-		if (!validElement)
-			return null;
-	}
+		this.loadNextScript();
 
-	if (element_name.charAt(0) == '+' || element_name.charAt(0) == '-')
-		name = element_name.substring(1);
+	//	for (var key in ar)
+	//		tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
+	},
 
-	// Special Mozilla stuff
-	if (!tinyMCE.isMSIE) {
-		// Fix for bug #958498
-		if (name == "strong" && !tinyMCE.cleanup_on_save)
-			element_name = "b";
-		else if (name == "em" && !tinyMCE.cleanup_on_save)
-			element_name = "i";
-	}
+	triggerNodeChange : function(focus, setup_content) {
+		var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st;
 
-	var elmData = new Object();
+		if (tinyMCE.selectedInstance) {
+			inst = tinyMCE.selectedInstance;
+			elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();
 
-	elmData.element_name = element_name;
-	elmData.valid_attribs = elementAttribs;
+/*			if (elm == inst.lastTriggerEl)
+				return;
 
-	return elmData;
-};
+			inst.lastTriggerEl = elm;*/
 
-/**
- * This function moves CSS styles to/from attributes.
- */
-TinyMCE.prototype._moveStyle = function(elm, style, attrib) {
-	if (tinyMCE.cleanup_inline_styles) {
-		var val = tinyMCE.getAttrib(elm, attrib);
+			editorId = inst.editorId;
+			st = inst.selection.getSelectedText();
 
-		if (val != '') {
-			val = '' + val;
+			if (tinyMCE.settings.auto_resize)
+				inst.resizeToContent();
 
-			switch (attrib) {
-				case "background":
-					val = "url('" + val + "')";
-					break;
+			if (setup_content && tinyMCE.isGecko && inst.isHidden())
+				elm = inst.getBody();
 
-				case "bordercolor":
-					if (elm.style.borderStyle == '' || elm.style.borderStyle == 'none')
-						elm.style.borderStyle = 'solid';
-					break;
+			inst.switchSettings();
 
-				case "border":
-				case "width":
-				case "height":
-					if (attrib == "border" && elm.style.borderWidth > 0)
-						return;
+			if (tinyMCE.selectedElement)
+				anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0);
 
-					if (val.indexOf('%') == -1)
-						val += 'px';
-					break;
+			if (tinyMCE.settings['custom_undo_redo']) {
+				undoIndex = inst.undoRedo.undoIndex;
+				undoLevels = inst.undoRedo.undoLevels.length;
+			}
 
-				case "vspace":
-				case "hspace":
-					elm.style.marginTop = val + "px";
-					elm.style.marginBottom = val + "px";
-					elm.removeAttribute(attrib);
-					return;
-
-				case "align":
-					if (elm.nodeName == "IMG") {
-						if (tinyMCE.isMSIE)
-							elm.style.styleFloat = val;
-						else
-							elm.style.cssFloat = val;
-					} else
-						elm.style.textAlign = val;
+			tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
+		}
 
-					elm.removeAttribute(attrib);
-					return;
-			}
+		if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
+			this.selectedInstance.contentWindow.focus();
+	},
 
-			if (val != '') {
-				eval('elm.style.' + style + ' = val;');
-				elm.removeAttribute(attrib);
-			}
-		}
-	} else {
-		if (style == '')
-			return;
+	_customCleanup : function(inst, type, content) {
+		var pl, po, i;
 
-		var val = eval('elm.style.' + style) == '' ? tinyMCE.getAttrib(elm, attrib) : eval('elm.style.' + style);
-		val = val == null ? '' : '' + val;
+		// Call custom cleanup
+		var customCleanup = tinyMCE.settings['cleanup_callback'];
+		if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
+			content = eval(customCleanup + "(type, content, inst);");
 
-		switch (attrib) {
-			// Always move background to style
-			case "background":
-				if (val.indexOf('url') == -1 && val != '')
-					val = "url('" + val + "');";
-
-				if (val != '') {
-					elm.style.backgroundImage = val;
-					elm.removeAttribute(attrib);
-				}
-				return;
+		// Trigger theme cleanup
+		po = tinyMCE.themes[tinyMCE.settings['theme']];
+		if (po && po.cleanup)
+			content = po.cleanup(type, content, inst);
 
-			case "border":
-			case "width":
-			case "height":
-				val = val.replace('px', '');
-				break;
+		// Trigger plugin cleanups
+		pl = inst.plugins;
+		for (i=0; i<pl.length; i++) {
+			po = tinyMCE.plugins[pl[i]];
 
-			case "align":
-				if (tinyMCE.getAttrib(elm, 'align') == '') {
-					if (elm.nodeName == "IMG") {
-						if (tinyMCE.isMSIE && elm.style.styleFloat != '') {
-							val = elm.style.styleFloat;
-							style = 'styleFloat';
-						} else if (tinyMCE.isGecko && elm.style.cssFloat != '') {
-							val = elm.style.cssFloat;
-							style = 'cssFloat';
-						}
-					}
-				}
-				break;
+			if (po && po.cleanup)
+				content = po.cleanup(type, content, inst);
 		}
 
-		if (val != '') {
-			elm.removeAttribute(attrib);
-			elm.setAttribute(attrib, val);
-			eval('elm.style.' + style + ' = "";');
-		}
-	}
-};
+		return content;
+	},
 
-TinyMCE.prototype._cleanupAttribute = function(valid_attributes, element_name, attribute_node, element_node) {
-	var attribName = attribute_node.nodeName.toLowerCase();
-	var attribValue = attribute_node.nodeValue;
-	var attribMustBeValue = null;
-	var verified = false;
+	setContent : function(h) {
+		if (tinyMCE.selectedInstance) {
+			tinyMCE.selectedInstance.execCommand('mceSetContent', false, h);
+			tinyMCE.selectedInstance.repaint();
+		}
+	},
 
-	// Mozilla attibute, remove them
-	if (attribName.indexOf('moz_') != -1)
-		return null;
+	importThemeLanguagePack : function(name) {
+		if (typeof(name) == "undefined")
+			name = tinyMCE.settings['theme'];
 
-	if (!tinyMCE.cleanup_on_save && (attribName == "mce_href" || attribName == "mce_src"))
-		return {name : attribName, value : attribValue};
+		tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
+	},
 
-	// Verify attrib
-	if (tinyMCE.cleanup_verify_html && !verified) {
-		for (var i=1; i<valid_attributes.length; i++) {
-			var attribMatch = valid_attributes[i][0];
-			var re = null;
-
-			// Build regexp from wildcard
-			if (attribMatch.match(new RegExp('\\*|\\?|\\+', 'g')) != null) {
-				attribMatch = attribMatch.replace(new RegExp('\\?', 'g'), '(\\S?)');
-				attribMatch = attribMatch.replace(new RegExp('\\+', 'g'), '(\\S+)');
-				attribMatch = attribMatch.replace(new RegExp('\\*', 'g'), '(\\S*)');
-				attribMatch = "^" + attribMatch + "$";
-				re = new RegExp(attribMatch, 'g');
-			}
-
-			if ((re && attribName.match(re) != null) || attribName == attribMatch) {
-				verified = true;
-				attribMustBeValue = valid_attributes[i][3];
-				break;
-			}
-		}
+	importPluginLanguagePack : function(name) {
+		var b = tinyMCE.baseURL + '/plugins/' + name;
 
-		if (!verified)
-			return false;
-	} else
-		verified = true;
+		if (this.plugins[name])
+			b = this.plugins[name].baseURL;
 
-	// Treat some attribs diffrent
-	switch (attribName) {
-		case "size":
-			if (tinyMCE.isMSIE5 && element_name == "font")
-				attribValue = element_node.size;
-			break;
+		tinyMCE.loadScript(b + '/langs/' + tinyMCE.settings['language'] +  '.js');
+	},
 
-		case "width":
-		case "height":
-		case "border":
-			// Old MSIE needs this
-			if (tinyMCE.isMSIE5)
-				attribValue = eval("element_node." + attribName);
-			break;
+	applyTemplate : function(h, as) {
+		return h.replace(new RegExp('\\{\\$([a-z0-9_]+)\\}', 'gi'), function(m, s) {
+			if (s.indexOf('lang_') == 0 && tinyMCELang[s])
+				return tinyMCELang[s];
 
-		case "shape":
-			attribValue = attribValue.toLowerCase();
-			break;
+			if (as && as[s])
+				return as[s];
 
-		case "cellspacing":
-			if (tinyMCE.isMSIE5)
-				attribValue = element_node.cellSpacing;
-			break;
+			if (tinyMCE.settings[s])
+				return tinyMCE.settings[s];
 
-		case "cellpadding":
-			if (tinyMCE.isMSIE5)
-				attribValue = element_node.cellPadding;
-			break;
+			if (m == 'themeurl')
+				return tinyMCE.themeURL;
 
-		case "color":
-			if (tinyMCE.isMSIE5 && element_name == "font")
-				attribValue = element_node.color;
-			break;
+			return m;
+		});
+	},
 
-		case "class":
-			// Remove mceItem classes from anchors
-			if (tinyMCE.cleanup_on_save && attribValue.indexOf('mceItemAnchor') != -1)
-				attribValue = attribValue.replace(/mceItem[a-z0-9]+/gi, '');
-
-			if (element_name == "table" || element_name == "td" || element_name == "th") {
-				// Handle visual aid
-				if (tinyMCE.cleanup_visual_table_class != "")
-					attribValue = tinyMCE.getVisualAidClass(attribValue, !tinyMCE.cleanup_on_save);
-			}
+	replaceVar : function(h, r, v) {
+		return h.replace(new RegExp('{\\\$' + r + '}', 'g'), v);
+	},
 
-			if (!tinyMCE._verifyClass(element_node) || attribValue == "")
-				return null;
+	openWindow : function(template, args) {
+		var html, width, height, x, y, resizable, scrollbars, url;
 
-			break;
+		args = !args ? {} : args;
 
-		case "onfocus":
-		case "onblur":
-		case "onclick":
-		case "ondblclick":
-		case "onmousedown":
-		case "onmouseup":
-		case "onmouseover":
-		case "onmousemove":
-		case "onmouseout":
-		case "onkeypress":
-		case "onkeydown":
-		case "onkeydown":
-		case "onkeyup":
-			attribValue = tinyMCE.cleanupEventStr("" + attribValue);
+		args['mce_template_file'] = template['file'];
+		args['mce_width'] = template['width'];
+		args['mce_height'] = template['height'];
+		tinyMCE.windowArgs = args;
 
-			if (attribValue.indexOf('return false;') == 0)
-				attribValue = attribValue.substring(14);
+		html = template['html'];
+		if (!(width = parseInt(template['width'])))
+			width = 320;
 
-			break;
+		if (!(height = parseInt(template['height'])))
+			height = 200;
 
-		case "style":
-			attribValue = tinyMCE.serializeStyle(tinyMCE.parseStyle(tinyMCE.getAttrib(element_node, "style")));
-			break;
+		// Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
+		if (tinyMCE.isIE)
+			height += 40;
+		else
+			height += 20;
 
-		// Convert the URLs of these
-		case "href":
-		case "src":
-		case "longdesc":
-			attribValue = tinyMCE.getAttrib(element_node, attribName);
-
-			// Use mce_href instead
-			var href = tinyMCE.getAttrib(element_node, "mce_href");
-			if (attribName == "href" && href != "")
-				attribValue = href;
-
-			// Use mce_src instead
-			var src = tinyMCE.getAttrib(element_node, "mce_src");
-			if (attribName == "src" && src != "")
-				attribValue = src;
-
-			// Always use absolute URLs within TinyMCE
-			if (!tinyMCE.cleanup_on_save)
-				attribValue = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], attribValue);
-			else if (tinyMCE.getParam('convert_urls'))
-				attribValue = eval(tinyMCE.cleanup_urlconverter_callback + "(attribValue, element_node, tinyMCE.cleanup_on_save);");
+		x = parseInt(screen.width / 2.0) - (width / 2.0);
+		y = parseInt(screen.height / 2.0) - (height / 2.0);
 
-			break;
+		resizable = (args && args['resizable']) ? args['resizable'] : "no";
+		scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
 
-		case "colspan":
-		case "rowspan":
-			// Not needed
-			if (attribValue == "1")
-				return null;
-			break;
+		if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
+			url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
+		else
+			url = template['file'];
 
-		// Skip these
-		case "_moz-userdefined":
-		case "editorid":
-		case "mce_href":
-		case "mce_src":
-			return null;
-	}
+		// Replace all args as variables in URL
+		for (var name in args) {
+			if (typeof(args[name]) == 'function')
+				continue;
 
-	// Not the must be value
-	if (attribMustBeValue != null) {
-		var isCorrect = false;
-		for (var i=0; i<attribMustBeValue.length; i++) {
-			if (attribValue == attribMustBeValue[i]) {
-				isCorrect = true;
-				break;
-			}
+			url = tinyMCE.replaceVar(url, name, escape(args[name]));
 		}
 
-		if (!isCorrect)
-			return null;
-	}
+		if (html) {
+			html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
+			html = tinyMCE.applyTemplate(html, args);
 
-	var attrib = new Object();
+			var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
+			if (win == null) {
+				alert(tinyMCELang['lang_popup_blocked']);
+				return;
+			}
 
-	attrib.name = attribName;
-	attrib.value = attribValue;
+			win.document.write(html);
+			win.document.close();
+			win.resizeTo(width, height);
+			win.focus();
+		} else {
+			if ((tinyMCE.isRealIE) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
+				height += 10;
 
-	return attrib;
-};
+				var features = "resizable:" + resizable 
+					+ ";scroll:"
+					+ scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
+					+ width + "px;dialogHeight:" + height + "px;";
 
-TinyMCE.prototype.clearArray = function(ar) {
-	// Since stupid people tend to extend core objects like
-	// Array with their own crap I needed to make functions that clean away
-	// this junk so the arrays get clean and nice as they should be
-	for (var key in ar)
-		ar[key] = null;
-};
+				window.showModalDialog(url, window, features);
+			} else {
+				var modal = (resizable == "yes") ? "no" : "yes";
 
-TinyMCE.prototype.isInstance = function(inst) {
-	return inst != null && typeof(inst) == "object" && inst.isTinyMCEControl;
-};
+				if (tinyMCE.isGecko && tinyMCE.isMac)
+					modal = "no";
 
-TinyMCE.prototype.parseStyle = function(str) {
-	var ar = new Array();
+				if (template['close_previous'] != "no")
+					try {tinyMCE.lastWindow.close();} catch (ex) {}
 
-	if (str == null)
-		return ar;
+				var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
+				if (win == null) {
+					alert(tinyMCELang['lang_popup_blocked']);
+					return;
+				}
 
-	var st = str.split(';');
+				if (template['close_previous'] != "no")
+					tinyMCE.lastWindow = win;
 
-	tinyMCE.clearArray(ar);
+				eval('try { win.resizeTo(width, height); } catch(e) { }');
 
-	for (var i=0; i<st.length; i++) {
-		if (st[i] == '')
-			continue;
+				// Make it bigger if statusbar is forced
+				if (tinyMCE.isGecko) {
+					if (win.document.defaultView.statusbar.visible)
+						win.resizeBy(0, tinyMCE.isMac ? 10 : 24);
+				}
 
-		var re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$');
-		var pa = st[i].replace(re, '$1||$2').split('||');
-//tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2'));
-		if (pa.length == 2)
-			ar[pa[0].toLowerCase()] = pa[1];
-	}
+				win.focus();
+			}
+		}
+	},
 
-	return ar;
-};
+	closeWindow : function(win) {
+		win.close();
+	},
 
-TinyMCE.prototype.compressStyle = function(ar, pr, sf, res) {
-	var box = new Array();
+	getVisualAidClass : function(class_name, state) {
+		var aidClass = tinyMCE.settings['visual_table_class'];
 
-	box[0] = ar[pr + '-top' + sf];
-	box[1] = ar[pr + '-left' + sf];
-	box[2] = ar[pr + '-right' + sf];
-	box[3] = ar[pr + '-bottom' + sf];
+		if (typeof(state) == "undefined")
+			state = tinyMCE.settings['visual'];
 
-	for (var i=0; i<box.length; i++) {
-		if (box[i] == null)
-			return;
+		// Split
+		var classNames = new Array();
+		var ar = class_name.split(' ');
+		for (var i=0; i<ar.length; i++) {
+			if (ar[i] == aidClass)
+				ar[i] = "";
 
-		for (var a=0; a<box.length; a++) {
-			if (box[a] != box[i])
-				return;
+			if (ar[i] != "")
+				classNames[classNames.length] = ar[i];
 		}
-	}
 
-	// They are all the same
-	ar[res] = box[0];
-	ar[pr + '-top' + sf] = null;
-	ar[pr + '-left' + sf] = null;
-	ar[pr + '-right' + sf] = null;
-	ar[pr + '-bottom' + sf] = null;
-};
+		if (state)
+			classNames[classNames.length] = aidClass;
 
-TinyMCE.prototype.serializeStyle = function(ar) {
-	var str = "";
+		// Glue
+		var className = "";
+		for (var i=0; i<classNames.length; i++) {
+			if (i > 0)
+				className += " ";
 
-	// Compress box
-	tinyMCE.compressStyle(ar, "border", "", "border");
-	tinyMCE.compressStyle(ar, "border", "-width", "border-width");
-	tinyMCE.compressStyle(ar, "border", "-color", "border-color");
+			className += classNames[i];
+		}
 
-	for (var key in ar) {
-		var val = ar[key];
-		if (typeof(val) == 'function')
-			continue;
+		return className;
+	},
 
-		if (val != null && val != '') {
-			val = '' + val; // Force string
+	handleVisualAid : function(el, deep, state, inst, skip_dispatch) {
+		if (!el)
+			return;
 
-			// Fix style URL
-			val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");
+		if (!skip_dispatch)
+			tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst);
 
-			// Convert URL
-			if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {
-				var m = new RegExp("url\\('(.*?)'\\)").exec(val);
+		var tableElement = null;
 
-				if (m.length > 1)
-					val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";
-			}
+		switch (el.nodeName) {
+			case "TABLE":
+				var oldW = el.style.width;
+				var oldH = el.style.height;
+				var bo = tinyMCE.getAttrib(el, "border");
 
-			// Force HEX colors
-			if (tinyMCE.getParam("force_hex_style_colors"))
-				val = tinyMCE.convertRGBToHex(val, true);
+				bo = bo == "" || bo == "0" ? true : false;
 
-			if (val != "url('')")
-				str += key.toLowerCase() + ": " + val + "; ";
-		}
-	}
+				tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
 
-	if (new RegExp('; $').test(str))
-		str = str.substring(0, str.length - 2);
+				el.style.width = oldW;
+				el.style.height = oldH;
 
-	return str;
-};
+				for (var y=0; y<el.rows.length; y++) {
+					for (var x=0; x<el.rows[y].cells.length; x++) {
+						var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
+						tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
+					}
+				}
 
-TinyMCE.prototype.convertRGBToHex = function(s, k) {
-	if (s.toLowerCase().indexOf('rgb') != -1) {
-		var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
-		var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');
-		if (rgb.length == 5) {
-			r = parseInt(rgb[1]).toString(16);
-			g = parseInt(rgb[2]).toString(16);
-			b = parseInt(rgb[3]).toString(16);
+				break;
 
-			r = r.length == 1 ? '0' + r : r;
-			g = g.length == 1 ? '0' + g : g;
-			b = b.length == 1 ? '0' + b : b;
+			case "A":
+				var anchorName = tinyMCE.getAttrib(el, "name");
 
-			s = "#" + r + g + b;
+				if (anchorName != '' && state) {
+					el.title = anchorName;
+					tinyMCE.addCSSClass(el, 'mceItemAnchor');
+				} else if (anchorName != '' && !state)
+					el.className = '';
 
-			if (k)
-				s = rgb[0] + s + rgb[4];
+				break;
 		}
-	}
 
-	return s;
-};
+		if (deep && el.hasChildNodes()) {
+			for (var i=0; i<el.childNodes.length; i++)
+				tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst, true);
+		}
+	},
 
-TinyMCE.prototype.convertHexToRGB = function(s) {
-	if (s.indexOf('#') != -1) {
-		s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
-		return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";
-	}
+	/*
+	applyClassesToFonts : function(doc, size) {
+		var f = doc.getElementsByTagName("font");
+		for (var i=0; i<f.length; i++) {
+			var s = tinyMCE.getAttrib(f[i], "size");
 
-	return s;
-};
+			if (s != "")
+				tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
+		}
 
-TinyMCE.prototype._verifyClass = function(node) {
-	// Sometimes the class gets set to null, weird Gecko bug?
-	if (tinyMCE.isGecko) {
-		var className = node.getAttribute('class');
-		if (!className)
-			return false;
-	}
+		if (typeof(size) != "undefined") {
+			var css = "";
 
-	// Trim CSS class
-	if (tinyMCE.isMSIE)
-		var className = node.getAttribute('className');
-
-	if (tinyMCE.cleanup_verify_css_classes && tinyMCE.cleanup_on_save) {
-		var csses = tinyMCE.getCSSClasses();
-		nonDefinedCSS = true;
-		for (var c=0; c<csses.length; c++) {
-			if (csses[c] == className) {
-				nonDefinedCSS = false;
-				break;
-			}
-		}
+			for (var x=0; x<doc.styleSheets.length; x++) {
+				for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
+					if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
+						css = doc.styleSheets[x].rules[i].style.cssText;
+						break;
+					}
+				}
 
-		if (nonDefinedCSS && className.indexOf('mce_') != 0) {
-			node.removeAttribute('className');
-			node.removeAttribute('class');
-			return false;
-		}
-	}
+				if (css != "")
+					break;
+			}
 
-	return true;
-};
+			if (doc.styleSheets[0].rules[0].selectorText == "FONT")
+				doc.styleSheets[0].removeRule(0);
 
-TinyMCE.prototype.cleanupNode = function(node) {
-	var output = "";
+			doc.styleSheets[0].addRule("FONT", css, 0);
+		}
+	},
+	*/
 
-	switch (node.nodeType) {
-		case 1: // Element
-			var elementData = tinyMCE._cleanupElementName(node.nodeName, node);
-			var elementName = elementData ? elementData.element_name : null;
-			var elementValidAttribs = elementData ? elementData.valid_attribs : null;
-			var elementAttribs = "";
-			var openTag = false, nonEmptyTag = false;
+	fixGeckoBaseHREFBug : function(m, e, h) {
+		var xsrc, xhref;
 
-			if (elementName != null && elementName.charAt(0) == '+') {
-				elementName = elementName.substring(1);
-				openTag = true;
-			}
+		if (tinyMCE.isGecko) {
+			if (m == 1) {
+				h = h.replace(/\ssrc=/gi, " mce_tsrc=");
+				h = h.replace(/\shref=/gi, " mce_thref=");
 
-			if (elementName != null && elementName.charAt(0) == '-') {
-				elementName = elementName.substring(1);
-				nonEmptyTag = true;
-			}
+				return h;
+			} else {
+				// Why bother if there is no src or href broken
+				if (!new RegExp('(src|href)=', 'g').test(h))
+					return h;
+
+				// Restore src and href that gets messed up by Gecko
+				tinyMCE.selectElements(e, 'A,IMG,SELECT,AREA,IFRAME,BASE,INPUT,SCRIPT,EMBED,OBJECT,LINK', function (n) {
+					xsrc = tinyMCE.getAttrib(n, "mce_tsrc");
+					xhref = tinyMCE.getAttrib(n, "mce_thref");
 
-			// Checking DOM tree for MSIE weirdness!!
-			if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) {
-				var lookup = tinyMCE.cleanup_elementLookupTable;
+					if (xsrc != "") {
+						try {
+							n.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
+						} catch (e) {
+							// Ignore, Firefox cast exception if local file wasn't found
+						}
 
-				for (var i=0; i<lookup.length; i++) {
-					// Found element reference else were, hmm?
-					if (lookup[i] == node)
-						return output;
-				}
+						n.removeAttribute("mce_tsrc");
+					}
 
-				// Add element to lookup table
-				lookup[lookup.length] = node;
-			}
+					if (xhref != "") {
+						try {
+							n.href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
+						} catch (e) {
+							// Ignore, Firefox cast exception if local file wasn't found
+						}
 
-			// Element not valid (only render children)
-			if (!elementName) {
-				if (node.hasChildNodes()) {
-					for (var i=0; i<node.childNodes.length; i++)
-						output += this.cleanupNode(node.childNodes[i]);
-				}
+						n.removeAttribute("mce_thref");
+					}
 
-				return output;
-			}
+					return false;
+				});
 
-			if (tinyMCE.cleanup_on_save) {
-				if (node.nodeName == "A" && node.className == "mceItemAnchor") {
-					if (node.hasChildNodes()) {
-						for (var i=0; i<node.childNodes.length; i++)
-							output += this.cleanupNode(node.childNodes[i]);
+				// Restore text/comment nodes
+				tinyMCE.selectNodes(e, function(n) {
+					if (n.nodeType == 3 || n.nodeType == 8) {
+						n.nodeValue = n.nodeValue.replace(/\smce_tsrc=/gi, " src=");
+						n.nodeValue = n.nodeValue.replace(/\smce_thref=/gi, " href=");
 					}
 
-					return '<a name="' + this.convertStringToXML(node.getAttribute("name")) + '"></a>' + output;
-				}
+					return false;
+				});
 			}
+		}
 
-			// Remove deprecated attributes
-			var re = new RegExp("^(TABLE|TD|TR)$");
-			if (re.test(node.nodeName)) {
-				// Move attrib to style
-				if ((node.nodeName != "TABLE" || tinyMCE.cleanup_inline_styles) && (width = tinyMCE.getAttrib(node, "width")) != '') {
-					node.style.width = width.indexOf('%') != -1 ? width : width.replace(/[^0-9]/gi, '') + "px";
-					node.removeAttribute("width");
-				}
-
-				// Is table and not inline
-				if ((node.nodeName == "TABLE" && !tinyMCE.cleanup_inline_styles) && node.style.width != '') {
-					tinyMCE.setAttrib(node, "width", node.style.width.replace('px',''));
-					node.style.width = '';
-				}
+		return h;
+	},
 
-				// Move attrib to style
-				if ((height = tinyMCE.getAttrib(node, "height")) != '') {
-					height = "" + height; // Force string
-					node.style.height = height.indexOf('%') != -1 ? height : height.replace(/[^0-9]/gi, '') + "px";
-					node.removeAttribute("height");
-				}
-			}
+	_setHTML : function(doc, html_content) {
+		// Force closed anchors open
+		//html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
 
-			// Handle inline/outline styles
-			if (tinyMCE.cleanup_inline_styles) {
-				var re = new RegExp("^(TABLE|TD|TR|IMG|HR)$");
-				if (re.test(node.nodeName) && tinyMCE.getAttrib(node, "class").indexOf('mceItem') == -1) {
-					tinyMCE._moveStyle(node, 'width', 'width');
-					tinyMCE._moveStyle(node, 'height', 'height');
-					tinyMCE._moveStyle(node, 'borderWidth', 'border');
-					tinyMCE._moveStyle(node, '', 'vspace');
-					tinyMCE._moveStyle(node, '', 'hspace');
-					tinyMCE._moveStyle(node, 'textAlign', 'align');
-					tinyMCE._moveStyle(node, 'backgroundColor', 'bgColor');
-					tinyMCE._moveStyle(node, 'borderColor', 'borderColor');
-					tinyMCE._moveStyle(node, 'backgroundImage', 'background');
+		html_content = tinyMCE.cleanupHTMLCode(html_content);
 
-					// Refresh element in old MSIE
-					if (tinyMCE.isMSIE5)
-						node.outerHTML = node.outerHTML;
-				} else if (tinyMCE.isBlockElement(node))
-					tinyMCE._moveStyle(node, 'textAlign', 'align');
+		// Try innerHTML if it fails use pasteHTML in MSIE
+		try {
+			tinyMCE.setInnerHTML(doc.body, html_content);
+		} catch (e) {
+			if (this.isMSIE)
+				doc.body.createTextRange().pasteHTML(html_content);
+		}
 
-				if (node.nodeName == "FONT")
-					tinyMCE._moveStyle(node, 'color', 'color');
+		// Content duplication bug fix
+		if (tinyMCE.isIE && tinyMCE.settings['fix_content_duplication']) {
+			// Remove P elements in P elements
+			var paras = doc.getElementsByTagName("P");
+			for (var i=0; i<paras.length; i++) {
+				var node = paras[i];
+				while ((node = node.parentNode) != null) {
+					if (node.nodeName == "P")
+						node.outerHTML = node.innerHTML;
+				}
 			}
 
-			// Set attrib data
-			if (elementValidAttribs) {
-				for (var a=1; a<elementValidAttribs.length; a++) {
-					var attribName, attribDefaultValue, attribForceValue, attribValue;
+			// Content duplication bug fix (Seems to be word crap)
+			var html = doc.body.innerHTML;
+/*
+			if (html.indexOf('="mso') != -1) {
+				for (var i=0; i<doc.body.all.length; i++) {
+					var el = doc.body.all[i];
+					el.removeAttribute("className","",0);
+					el.removeAttribute("style","",0);
+				}
+
+				html = doc.body.innerHTML;
+				html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
+				html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
+				html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
+				html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
+				html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
+				html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
+				html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
+				html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
+			}*/
 
-					attribName = elementValidAttribs[a][0];
-					attribDefaultValue = elementValidAttribs[a][1];
-					attribForceValue = elementValidAttribs[a][2];
+			// Always set the htmlText output
+			tinyMCE.setInnerHTML(doc.body, html);
+		}
 
-					if (attribDefaultValue != null || attribForceValue != null) {
-						var attribValue = node.getAttribute(attribName);
+		tinyMCE.cleanupAnchors(doc);
 
-						if (node.getAttribute(attribName) == null || node.getAttribute(attribName) == "")
-							attribValue = attribDefaultValue;
+		if (tinyMCE.getParam("convert_fonts_to_spans"))
+			tinyMCE.convertSpansToFonts(doc);
+	},
 
-						attribValue = attribForceValue ? attribForceValue : attribValue;
+	getEditorId : function(form_element) {
+		var inst = this.getInstanceById(form_element);
+		if (!inst)
+			return null;
 
-						// Is to generate id
-						if (attribValue == "{$uid}")
-							attribValue = "uid_" + (tinyMCE.cleanup_idCount++);
+		return inst.editorId;
+	},
 
-						// Add visual aid class
-						if (attribName == "class")
-							attribValue = tinyMCE.getVisualAidClass(attribValue, tinyMCE.cleanup_on_save);
+	getInstanceById : function(editor_id) {
+		var inst = this.instances[editor_id];
+		if (!inst) {
+			for (var n in tinyMCE.instances) {
+				var instance = tinyMCE.instances[n];
+				if (!tinyMCE.isInstance(instance))
+					continue;
 
-						node.setAttribute(attribName, attribValue);
-						//alert(attribName + "=" + attribValue);
-					}
+				if (instance.formTargetElementId == editor_id) {
+					inst = instance;
+					break;
 				}
 			}
+		}
 
-			if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && elementName == "style")
-				return "<style>" + node.innerHTML + "</style>";
+		return inst;
+	},
 
-			// Remove empty tables
-			if (elementName == "table" && !node.hasChildNodes())
-				return "";
+	queryInstanceCommandValue : function(editor_id, command) {
+		var inst = tinyMCE.getInstanceById(editor_id);
+		if (inst)
+			return inst.queryCommandValue(command);
 
-			// Handle element attributes
-			if (node.attributes.length > 0) {
-				var lastAttrib = "";
+		return false;
+	},
 
-				for (var i=0; i<node.attributes.length; i++) {
-					if (node.attributes[i].specified) {
-						// Is the attrib already processed (removed duplicate attributes in opera TD[align=left])
-						if (tinyMCE.isOpera) {
-							if (node.attributes[i].nodeName == lastAttrib)
-								continue;
+	queryInstanceCommandState : function(editor_id, command) {
+		var inst = tinyMCE.getInstanceById(editor_id);
+		if (inst)
+			return inst.queryCommandState(command);
 
-							lastAttrib = node.attributes[i].nodeName;
-						}
+		return null;
+	},
 
-						// tinyMCE.debug(node.nodeName, node.attributes[i].nodeName, node.attributes[i].nodeValue, node.innerHTML);
-						var attrib = tinyMCE._cleanupAttribute(elementValidAttribs, elementName, node.attributes[i], node);
-						if (attrib && attrib.value != "")
-							elementAttribs += " " + attrib.name + "=" + '"' + this.convertStringToXML("" + attrib.value) + '"';
-					}
-				}
-			}
+	setWindowArg : function(n, v) {
+		this.windowArgs[n] = v;
+	},
 
-			// MSIE table summary fix (MSIE 5.5)
-			if (tinyMCE.isMSIE && elementName == "table" && node.getAttribute("summary") != null && elementAttribs.indexOf('summary') == -1) {
-				var summary = tinyMCE.getAttrib(node, 'summary');
-				if (summary != '')
-					elementAttribs += " summary=" + '"' + this.convertStringToXML(summary) + '"';
-			}
+	getWindowArg : function(n, d) {
+		return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n];
+	},
 
-			// Handle missing attributes in MSIE 5.5
-			if (tinyMCE.isMSIE5 && /^(td|img|a)$/.test(elementName)) {
-				var ma = new Array("scope", "longdesc", "hreflang", "charset", "type");
+	getCSSClasses : function(editor_id, doc) {
+		var inst = tinyMCE.getInstanceById(editor_id);
 
-				for (var u=0; u<ma.length; u++) {
-					if (node.getAttribute(ma[u]) != null) {
-						var s = tinyMCE.getAttrib(node, ma[u]);
+		// Is cached, use that
+		if (inst && inst.cssClasses.length > 0)
+			return inst.cssClasses;
 
-						if (s != '')
-							elementAttribs += " " + ma[u] + "=" + '"' + this.convertStringToXML(s) + '"';
-					}
-				}
-			}
+		if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
+			var instance;
 
-			// MSIE form element issue
-			if (tinyMCE.isMSIE && elementName == "input") {
-				if (node.type) {
-					if (!elementAttribs.match(/ type=/g))
-						elementAttribs += " type=" + '"' + node.type + '"';
-				}
+			for (var instanceName in tinyMCE.instances) {
+				instance = tinyMCE.instances[instanceName];
+				if (!tinyMCE.isInstance(instance))
+					continue;
 
-				if (node.value) {
-					if (!elementAttribs.match(/ value=/g))
-						elementAttribs += " value=" + '"' + node.value + '"';
-				}
+				break;
 			}
 
-			// Add nbsp to some elements
-			if ((elementName == "p" || elementName == "td") && (node.innerHTML == "" || node.innerHTML == "&nbsp;"))
-				return "<" + elementName + elementAttribs + ">" + this.convertStringToXML(String.fromCharCode(160)) + "</" + elementName + ">";
-
-			// Is MSIE script element
-			if (tinyMCE.isMSIE && elementName == "script")
-				return "<" + elementName + elementAttribs + ">" + node.text + "</" + elementName + ">";
+			doc = instance.getDoc();
+		}
 
-			// Clean up children
-			if (node.hasChildNodes()) {
-				// If not empty span
-				if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {
-					// Force BR
-					if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)
-						output += "<div" + elementAttribs + ">";
-					else
-						output += "<" + elementName + elementAttribs + ">";
-				}
+		if (typeof(doc) == "undefined") {
+			var instance = tinyMCE.getInstanceById(editor_id);
+			doc = instance.getDoc();
+		}
 
-				for (var i=0; i<node.childNodes.length; i++)
-					output += this.cleanupNode(node.childNodes[i]);
+		if (doc) {
+			var styles = doc.styleSheets;
 
-				// If not empty span
-				if (!(elementName == "span" && elementAttribs == "" && tinyMCE.getParam("trim_span_elements"))) {
-					// Force BR
-					if (elementName == "p" && tinyMCE.cleanup_force_br_newlines)
-						output += "</div><br />";
-					else
-						output += "</" + elementName + ">";
-				}
-			} else {
-				if (!nonEmptyTag) {
-					if (openTag)
-						output += "<" + elementName + elementAttribs + "></" + elementName + ">";
-					else
-						output += "<" + elementName + elementAttribs + " />";
-				}
-			}
+			if (styles && styles.length > 0) {
+				for (var x=0; x<styles.length; x++) {
+					var csses = null;
 
-			return output;
+					// Just ignore any errors
+					eval("try {var csses = tinyMCE.isIE ? doc.styleSheets(" + x + ").rules : styles[" + x + "].cssRules;} catch(e) {}");
+					if (!csses)
+						return new Array();
 
-		case 3: // Text
-			// Do not convert script elements
-			if (node.parentNode.nodeName == "SCRIPT" || node.parentNode.nodeName == "NOSCRIPT" || node.parentNode.nodeName == "STYLE")
-				return node.nodeValue;
+					for (var i=0; i<csses.length; i++) {
+						var selectorText = csses[i].selectorText;
 
-			return this.convertStringToXML(node.nodeValue);
+						// Can be multiple rules per selector
+						if (selectorText) {
+							var rules = selectorText.split(',');
+							for (var c=0; c<rules.length; c++) {
+								var rule = rules[c];
 
-		case 8: // Comment
-			return "<!--" + node.nodeValue + "-->";
+								// Strip spaces between selectors
+								while (rule.indexOf(' ') == 0)
+									rule = rule.substring(1);
 
-		default: // Unknown
-			return "[UNKNOWN NODETYPE " + node.nodeType + "]";
-	}
-};
+								// Invalid rule
+								if (rule.indexOf(' ') != -1 || rule.indexOf(':') != -1 || rule.indexOf('mceItem') != -1)
+									continue;
 
-TinyMCE.prototype.convertStringToXML = function(html_data) {
-    var output = "";
+								if (rule.indexOf(tinyMCE.settings['visual_table_class']) != -1 || rule.indexOf('mceEditable') != -1 || rule.indexOf('mceNonEditable') != -1)
+									continue;
 
-	for (var i=0; i<html_data.length; i++) {
-		var chr = html_data.charCodeAt(i);
+								// Is class rule
+								if (rule.indexOf('.') != -1) {
+									var cssClass = rule.substring(rule.indexOf('.') + 1);
+									var addClass = true;
 
-		// Numeric entities
-		if (tinyMCE.settings['entity_encoding'] == "numeric") {
-			if (chr > 127)
-				output += '&#' + chr + ";";
-			else
-				output += String.fromCharCode(chr);
+									for (var p=0; p<inst.cssClasses.length && addClass; p++) {
+										if (inst.cssClasses[p] == cssClass)
+											addClass = false;
+									}
 
-			continue;
+									if (addClass)
+										inst.cssClasses[inst.cssClasses.length] = cssClass;
+								}
+							}
+						}
+					}
+				}
+			}
 		}
 
-		// Raw entities
-		if (tinyMCE.settings['entity_encoding'] == "raw") {
-			output += String.fromCharCode(chr);
-			continue;
-		}
+		return inst.cssClasses;
+	},
 
-		// Named entities
-		if (typeof(tinyMCE.settings['cleanup_entities']["c" + chr]) != 'undefined' && tinyMCE.settings['cleanup_entities']["c" + chr] != '')
-			output += '&' + tinyMCE.settings['cleanup_entities']["c" + chr] + ';';
-		else
-			output += '' + String.fromCharCode(chr);
-    }
+	regexpReplace : function(in_str, reg_exp, replace_str, opts) {
+		if (in_str == null)
+			return in_str;
 
-    return output;
-};
+		if (typeof(opts) == "undefined")
+			opts = 'g';
 
-TinyMCE.prototype._getCleanupElementName = function(chunk) {
-	var pos;
+		var re = new RegExp(reg_exp, opts);
+		return in_str.replace(re, replace_str);
+	},
 
-	if (chunk.charAt(0) == '+')
-		chunk = chunk.substring(1);
+	trim : function(s) {
+		return s.replace(/^\s*|\s*$/g, "");
+	},
 
-	if (chunk.charAt(0) == '-')
-		chunk = chunk.substring(1);
+	cleanupEventStr : function(s) {
+		s = "" + s;
+		s = s.replace('function anonymous()\n{\n', '');
+		s = s.replace('\n}', '');
+		s = s.replace(/^return true;/gi, ''); // Remove event blocker
 
-	if ((pos = chunk.indexOf('/')) != -1)
-		chunk = chunk.substring(0, pos);
+		return s;
+	},
 
-	if ((pos = chunk.indexOf('[')) != -1)
-		chunk = chunk.substring(0, pos);
-
-	return chunk;
-};
-
-TinyMCE.prototype._initCleanup = function() {
-	// Parse valid elements and attributes
-	var validElements = tinyMCE.settings["valid_elements"];
-	validElements = validElements.split(',');
-
-	// Handle extended valid elements
-	var extendedValidElements = tinyMCE.settings["extended_valid_elements"];
-	extendedValidElements = extendedValidElements.split(',');
-	for (var i=0; i<extendedValidElements.length; i++) {
-		var elementName = this._getCleanupElementName(extendedValidElements[i]);
-		var skipAdd = false;
-
-		// Check if it's defined before, if so override that one
-		for (var x=0; x<validElements.length; x++) {
-			if (this._getCleanupElementName(validElements[x]) == elementName) {
-				validElements[x] = extendedValidElements[i];
-				skipAdd = true;
-				break;
-			}
-		}
+	getControlHTML : function(c) {
+		var i, l, n, o, v, rtl = tinyMCE.getLang('lang_dir') == 'rtl';
 
-		if (!skipAdd)
-			validElements[validElements.length] = extendedValidElements[i];
-	}
+		l = tinyMCE.plugins;
+		for (n in l) {
+			o = l[n];
 
-	for (var i=0; i<validElements.length; i++) {
-		var item = validElements[i];
+			if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
+				if (rtl)
+					return '<span dir="rtl">' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '</span>';
 
-		item = item.replace('[','|');
-		item = item.replace(']','');
+				return tinyMCE.replaceVar(v, "pluginurl", o.baseURL);
+			}
+		}
 
-		// Split and convert
-		var attribs = item.split('|');
-		for (var x=0; x<attribs.length; x++)
-			attribs[x] = attribs[x].toLowerCase();
+		o = tinyMCE.themes[tinyMCE.settings['theme']];
+		if (o.getControlHTML && (v = o.getControlHTML(c)) != '') {
+			if (rtl)
+				return '<span dir="rtl">' + v + '</span>';
 
-		// Handle change elements
-		attribs[0] = attribs[0].split('/');
+			return v;
+		}
 
-		// Handle default attribute values
-		for (var x=1; x<attribs.length; x++) {
-			var attribName = attribs[x];
-			var attribDefault = null;
-			var attribForce = null;
-			var attribMustBe = null;
+		return '';
+	},
 
-			// Default value
-			if ((pos = attribName.indexOf('=')) != -1) {
-				attribDefault = attribName.substring(pos+1);
-				attribName = attribName.substring(0, pos);
-			}
+	evalFunc : function(f, idx, a, o) {
+		o = !o ? window : o;
+		f = typeof(f) == 'function' ? f : o[f];
 
-			// Force check
-			if ((pos = attribName.indexOf(':')) != -1) {
-				attribForce = attribName.substring(pos+1);
-				attribName = attribName.substring(0, pos);
-			}
+		return f.apply(o, Array.prototype.slice.call(a, idx));
+	},
 
-			// Force check
-			if ((pos = attribName.indexOf('<')) != -1) {
-				attribMustBe = attribName.substring(pos+1).split('?');
-				attribName = attribName.substring(0, pos);
-			}
+	dispatchCallback : function(i, p, n) {
+		return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments);
+	},
 
-			attribs[x] = new Array(attribName, attribDefault, attribForce, attribMustBe);
-		}
+	executeCallback : function(i, p, n) {
+		return this.callFunc(i, p, n, 1, this.executeCallback.arguments);
+	},
 
-		validElements[i] = attribs;
-	}
+	execCommandCallback : function(i, p, n) {
+		return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments);
+	},
 
-	var invalidElements = tinyMCE.settings['invalid_elements'].split(',');
-	for (var i=0; i<invalidElements.length; i++)
-		invalidElements[i] = invalidElements[i].toLowerCase();
+	callFunc : function(ins, p, n, m, a) {
+		var l, i, on, o, s, v;
 
-	// Set these for performance
-	tinyMCE.settings['cleanup_validElements'] = validElements;
-	tinyMCE.settings['cleanup_invalidElements'] = invalidElements;
-};
+		s = m == 2;
 
-TinyMCE.prototype._cleanupHTML = function(inst, doc, config, element, visual, on_save) {
-	if (!tinyMCE.settings['cleanup']) {
-		tinyMCE.handleVisualAid(inst.getBody(), true, false, inst);
+		l = tinyMCE.getParam(p, '');
 
-		var html = element.innerHTML;
+		if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0)
+			return true;
 
-		// Remove mce_href/mce_src
-		html = html.replace(new RegExp('(mce_href|mce_src)=".*?"', 'gi'), '');
-		html = html.replace(/\s+>/gi, '>');
+		if (ins != null) {
+			for (i=0, l = ins.plugins; i<l.length; i++) {
+				o = tinyMCE.plugins[l[i]];
 
-		return html;
-	}
+				if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0)
+					return true;
+			}
+		}
 
-	if (on_save && tinyMCE.getParam("convert_fonts_to_spans"))
-		tinyMCE.convertFontsToSpans(doc);
+		l = tinyMCE.themes;
+		for (on in l) {
+			o = l[on];
 
-	// Call custom cleanup code
-	tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
+			if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0)
+				return true;
+		}
 
-	// Move bgcolor to style
-	var n = doc.getElementsByTagName("font");
-	for (var i=0; i<n.length; i++) {
-		var c = "";
-		if ((c = tinyMCE.getAttrib(n[i], "bgcolor")) != "") {
-			n[i].style.backgroundColor = c;
-			tinyMCE.setAttrib(n[i], "bgcolor", "");
-		}
-	}
-
-	// Set these for performance
-	tinyMCE.cleanup_validElements = tinyMCE.settings['cleanup_validElements'];
-	tinyMCE.cleanup_invalidElements = tinyMCE.settings['cleanup_invalidElements'];
-	tinyMCE.cleanup_verify_html = tinyMCE.settings['verify_html'];
-	tinyMCE.cleanup_force_br_newlines = tinyMCE.settings['force_br_newlines'];
-	tinyMCE.cleanup_urlconverter_callback = tinyMCE.settings['urlconverter_callback'];
-	tinyMCE.cleanup_verify_css_classes = tinyMCE.settings['verify_css_classes'];
-	tinyMCE.cleanup_visual_table_class = tinyMCE.settings['visual_table_class'];
-	tinyMCE.cleanup_apply_source_formatting = tinyMCE.settings['apply_source_formatting'];
-	tinyMCE.cleanup_inline_styles = tinyMCE.settings['inline_styles'];
-	tinyMCE.cleanup_visual_aid = visual;
-	tinyMCE.cleanup_on_save = on_save;
-	tinyMCE.cleanup_idCount = 0;
-	tinyMCE.cleanup_elementLookupTable = new Array();
-
-	var startTime = new Date().getTime();
-
-	// Cleanup madness that breaks the editor in MSIE
-	if (tinyMCE.isMSIE) {
-		// Remove null ids from HR elements, results in runtime error
-		var nodes = element.getElementsByTagName("hr");
-		for (var i=0; i<nodes.length; i++) {
-			if (nodes[i].id == "null")
-				nodes[i].removeAttribute("id");
-		}
-
-		tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<p>[ \n\r]*<hr.*>[ \n\r]*</p>', '<hr />', 'gi'));
-		tinyMCE.setInnerHTML(element, tinyMCE.regexpReplace(element.innerHTML, '<!([^-(DOCTYPE)]* )|<!/[^-]*>', '', 'gi'));
-	}
-
-	var html = this.cleanupNode(element);
-
-	if (tinyMCE.settings['debug'])
-		tinyMCE.debug("Cleanup process executed in: " + (new Date().getTime()-startTime) + " ms.");
-
-	// Remove pesky HR paragraphs and other crap
-	html = tinyMCE.regexpReplace(html, '<p><hr /></p>', '<hr />');
-	html = tinyMCE.regexpReplace(html, '<p>&nbsp;</p><hr /><p>&nbsp;</p>', '<hr />');
-	html = tinyMCE.regexpReplace(html, '<td>\\s*<br />\\s*</td>', '<td>&nbsp;</td>');
-	html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s*</p>', '<p>&nbsp;</p>');
-	html = tinyMCE.regexpReplace(html, '<p>\\s*&nbsp;\\s*<br />\\s*&nbsp;\\s*</p>', '<p>&nbsp;</p>');
-	html = tinyMCE.regexpReplace(html, '<p>\\s*&nbsp;\\s*<br />\\s*</p>', '<p>&nbsp;</p>');
-	html = tinyMCE.regexpReplace(html, '<p>\\s*<br />\\s*&nbsp;\\s*</p>', '<p>&nbsp;</p>');
-
-	// Remove empty anchors
-	html = html.replace(new RegExp('<a>(.*?)</a>', 'gi'), '$1');
-
-	// Remove some mozilla crap
-	if (!tinyMCE.isMSIE)
-		html = html.replace(new RegExp('<o:p _moz-userdefined="" />', 'g'), "");
-
-	if (tinyMCE.settings['remove_linebreaks'])
-		html = html.replace(new RegExp('\r|\n', 'g'), ' ');
-
-	if (tinyMCE.getParam('apply_source_formatting')) {
-		html = html.replace(new RegExp('<(p|div)([^>]*)>', 'g'), "\n<$1$2>\n");
-		html = html.replace(new RegExp('<\/(p|div)([^>]*)>', 'g'), "\n</$1$2>\n");
-		html = html.replace(new RegExp('<br />', 'g'), "<br />\n");
-	}
-
-	if (tinyMCE.settings['force_br_newlines']) {
-		var re = new RegExp('<p>&nbsp;</p>', 'g');
-		html = html.replace(re, "<br />");
-	}
-
-	if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) {
-		// Remove weridness!
-		var re = new RegExp('&lt;&gt;', 'g');
-		html = html.replace(re, "");
-	}
+		return false;
+	},
 
-	// Call custom cleanup code
-	html = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", html);
+	xmlEncode : function(s, skip_apos) {
+		return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) {
+			switch (c) {
+				case '&':
+					return '&amp;';
 
-	// Emtpy node, return empty
-	var chk = tinyMCE.regexpReplace(html, "[ \t\r\n]", "").toLowerCase();
-	if (chk == "<br/>" || chk == "<br>" || chk == "<p>&nbsp;</p>" || chk == "<p>&#160;</p>" || chk == "<p></p>")
-		html = "";
+				case '"':
+					return '&quot;';
 
-	if (tinyMCE.settings["preformatted"])
-		return "<pre>" + html + "</pre>";
+				case '\'':
+					return '&#39;'; // &apos; is not working in MSIE
 
-	return html;
-};
+				case '<':
+					return '&lt;';
+
+				case '>':
+					return '&gt;';
+			}
 
-TinyMCE.prototype.insertLink = function(href, target, title, onclick, style_class) {
-	tinyMCE.execCommand('mceBeginUndoLevel');
+			return c;
+		}) : s;
+	},
 
-	if (this.selectedInstance && this.selectedElement && this.selectedElement.nodeName.toLowerCase() == "img") {
-		var doc = this.selectedInstance.getDoc();
-		var linkElement = tinyMCE.getParentElement(this.selectedElement, "a");
-		var newLink = false;
+	extend : function(p, np) {
+		var o = {};
 
-		if (!linkElement) {
-			linkElement = doc.createElement("a");
-			newLink = true;
-		}
+		o.parent = p;
+
+		for (n in p)
+			o[n] = p[n];
+
+		for (n in np)
+			o[n] = np[n];
 
-		var mhref = href;
-		var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);");
-		mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+		return o;
+	},
 
-		tinyMCE.setAttrib(linkElement, 'href', thref);
-		tinyMCE.setAttrib(linkElement, 'mce_href', mhref);
-		tinyMCE.setAttrib(linkElement, 'target', target);
-		tinyMCE.setAttrib(linkElement, 'title', title);
-        tinyMCE.setAttrib(linkElement, 'onclick', onclick);
-		tinyMCE.setAttrib(linkElement, 'class', style_class);
+	hideMenus : function() {
+		var e = tinyMCE.lastSelectedMenuBtn;
 
-		if (newLink) {
-			linkElement.appendChild(this.selectedElement.cloneNode(true));
-			this.selectedElement.parentNode.replaceChild(linkElement, this.selectedElement);
+		if (tinyMCE.lastMenu) {
+			tinyMCE.lastMenu.hide();
+			tinyMCE.lastMenu = null;
 		}
 
-		return;
+		if (e) {
+			tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass);
+			tinyMCE.lastSelectedMenuBtn = null;
+		}
 	}
 
-	if (!this.linkElement && this.selectedInstance) {
-		if (tinyMCE.isSafari) {
-			tinyMCE.execCommand("mceInsertContent", false, '<a href="' + tinyMCE.uniqueURL + '">' + this.selectedInstance.getSelectedHTML() + '</a>');
-		} else
-			this.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL);
+	};
+
+// Global instances
+var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors
+var tinyMCE = new TinyMCE_Engine();
+var tinyMCELang = {};
 
-		tinyMCE.linkElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
+/* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */
 
-		var elementArray = this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL);
+function TinyMCE_Control(settings) {
+	var t, i, to, fu, p, x, fn, fu, pn, s = settings;
 
-		for (var i=0; i<elementArray.length; i++) {
-			var mhref = href;
-			var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, elementArray[i]);");
-			mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+	this.undoRedoLevel = true;
+	this.isTinyMCE_Control = true;
 
-			tinyMCE.setAttrib(elementArray[i], 'href', thref);
-			tinyMCE.setAttrib(elementArray[i], 'mce_href', mhref);
-			tinyMCE.setAttrib(elementArray[i], 'target', target);
-			tinyMCE.setAttrib(elementArray[i], 'title', title);
-            tinyMCE.setAttrib(elementArray[i], 'onclick', onclick);
-			tinyMCE.setAttrib(elementArray[i], 'class', style_class);
-		}
+	// Default settings
+	this.settings = s;
+	this.settings['theme'] = tinyMCE.getParam("theme", "default");
+	this.settings['width'] = tinyMCE.getParam("width", -1);
+	this.settings['height'] = tinyMCE.getParam("height", -1);
+	this.selection = new TinyMCE_Selection(this);
+	this.undoRedo = new TinyMCE_UndoRedo(this);
+	this.cleanup = new TinyMCE_Cleanup();
+	this.shortcuts = new Array();
+	this.hasMouseMoved = false;
+	this.foreColor = this.backColor = "#999999";
+	this.data = {};
+	this.cssClasses = [];
 
-		tinyMCE.linkElement = elementArray[0];
-	}
+	this.cleanup.init({
+		valid_elements : s.valid_elements,
+		extended_valid_elements : s.extended_valid_elements,
+		valid_child_elements : s.valid_child_elements,
+		entities : s.entities,
+		entity_encoding : s.entity_encoding,
+		debug : s.cleanup_debug,
+		indent : s.apply_source_formatting,
+		invalid_elements : s.invalid_elements,
+		verify_html : s.verify_html,
+		fix_content_duplication : s.fix_content_duplication,
+		convert_fonts_to_spans : s.convert_fonts_to_spans
+	});
 
-	if (this.linkElement) {
-		var mhref = href;
-		href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, this.linkElement);");
-		mhref = tinyMCE.getParam('convert_urls') ? href : mhref;
+	// Wrap old theme
+	t = this.settings['theme'];
+	if (!tinyMCE.hasTheme(t)) {
+		fn = tinyMCE.callbacks;
+		to = {};
 
-		tinyMCE.setAttrib(this.linkElement, 'href', href);
-		tinyMCE.setAttrib(this.linkElement, 'mce_href', mhref);
-		tinyMCE.setAttrib(this.linkElement, 'target', target);
-		tinyMCE.setAttrib(this.linkElement, 'title', title);
-        tinyMCE.setAttrib(this.linkElement, 'onclick', onclick);
-		tinyMCE.setAttrib(this.linkElement, 'class', style_class);
-	}
+		for (i=0; i<fn.length; i++) {
+			if ((fu = window['TinyMCE_' + t + "_" + fn[i]]))
+				to[fn[i]] = fu;
+		}
 
-	tinyMCE.execCommand('mceEndUndoLevel');
-};
+		tinyMCE.addTheme(t, to);
+	}
 
-TinyMCE.prototype.insertImage = function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) {
-	tinyMCE.execCommand('mceBeginUndoLevel');
+	// Wrap old plugins
+	this.plugins = new Array();
+	p = tinyMCE.getParam('plugins', '', true, ',');
+	if (p.length > 0) {
+		for (i=0; i<p.length; i++) {
+			pn = p[i];
 
-	if (src == "")
-		return;
+			if (pn.charAt(0) == '-')
+				pn = pn.substring(1);
 
-	if (!this.imgElement && tinyMCE.isSafari) {
-		var html = "";
+			if (!tinyMCE.hasPlugin(pn)) {
+				fn = tinyMCE.callbacks;
+				to = {};
 
-		html += '<img src="' + src + '" alt="' + alt + '"';
-		html += ' border="' + border + '" hspace="' + hspace + '"';
-		html += ' vspace="' + vspace + '" width="' + width + '"';
-		html += ' height="' + height + '" align="' + align + '" title="' + title + '" onmouseover="' + onmouseover + '" onmouseout="' + onmouseout + '" />';
+				for (x=0; x<fn.length; x++) {
+					if ((fu = window['TinyMCE_' + pn + "_" + fn[x]]))
+						to[fn[x]] = fu;
+				}
 
-		tinyMCE.execCommand("mceInsertContent", false, html);
-	} else {
-		if (!this.imgElement && this.selectedInstance) {
-			if (tinyMCE.isSafari)
-				tinyMCE.execCommand("mceInsertContent", false, '<img src="' + tinyMCE.uniqueURL + '" />');
-			else
-				this.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL);
+				tinyMCE.addPlugin(pn, to);
+			}
 
-			tinyMCE.imgElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL);
+			this.plugins[this.plugins.length] = pn; 
 		}
 	}
+};
 
-	if (this.imgElement) {
-		var needsRepaint = false;
-		var msrc = src;
+TinyMCE_Control.prototype = {
+	selection : null,
 
-		src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);");
+	settings : null,
 
-		if (tinyMCE.getParam('convert_urls'))
-			msrc = src;
+	cleanup : null,
 
-		if (onmouseover && onmouseover != "")
-			onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';";
+	getData : function(na) {
+		var o = this.data[na];
 
-		if (onmouseout && onmouseout != "")
-			onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';";
+		if (!o)
+			o = this.data[na] = {};
 
-		// Use alt as title if it's undefined
-		if (typeof(title) == "undefined")
-			title = alt;
+		return o;
+	},
 
-		if (width != this.imgElement.getAttribute("width") || height != this.imgElement.getAttribute("height") || align != this.imgElement.getAttribute("align"))
-			needsRepaint = true;
+	hasPlugin : function(n) {
+		var i;
 
-		tinyMCE.setAttrib(this.imgElement, 'src', src);
-		tinyMCE.setAttrib(this.imgElement, 'mce_src', msrc);
-		tinyMCE.setAttrib(this.imgElement, 'alt', alt);
-		tinyMCE.setAttrib(this.imgElement, 'title', title);
-		tinyMCE.setAttrib(this.imgElement, 'align', align);
-		tinyMCE.setAttrib(this.imgElement, 'border', border, true);
-		tinyMCE.setAttrib(this.imgElement, 'hspace', hspace, true);
-		tinyMCE.setAttrib(this.imgElement, 'vspace', vspace, true);
-		tinyMCE.setAttrib(this.imgElement, 'width', width, true);
-		tinyMCE.setAttrib(this.imgElement, 'height', height, true);
-		tinyMCE.setAttrib(this.imgElement, 'onmouseover', onmouseover);
-		tinyMCE.setAttrib(this.imgElement, 'onmouseout', onmouseout);
+		for (i=0; i<this.plugins.length; i++) {
+			if (this.plugins[i] == n)
+				return true;
+		}
 
-		// Fix for bug #989846 - Image resize bug
-		if (width && width != "")
-			this.imgElement.style.pixelWidth = width;
+		return false;
+	},
 
-		if (height && height != "")
-			this.imgElement.style.pixelHeight = height;
+	addPlugin : function(n, p) {
+		if (!this.hasPlugin(n)) {
+			tinyMCE.addPlugin(n, p);
+			this.plugins[this.plugins.length] = n;
+		}
+	},
 
-		if (needsRepaint)
-			tinyMCE.selectedInstance.repaint();
-	}
+	repaint : function() {
+		var s, b, ex;
 
-	tinyMCE.execCommand('mceEndUndoLevel');
-};
+		if (tinyMCE.isRealIE)
+			return;
 
-TinyMCE.prototype.getElementByAttributeValue = function(node, element_name, attrib, value) {
-	var elements = this.getElementsByAttributeValue(node, element_name, attrib, value);
-	if (elements.length == 0)
-		return null;
+		try {
+			s = this.selection;
+			b = s.getBookmark(true);
+			this.getBody().style.display = 'none';
+			this.getDoc().execCommand('selectall', false, null);
+			this.getSel().collapseToStart();
+			this.getBody().style.display = 'block';
+			s.moveToBookmark(b);
+		} catch (ex) {
+			// Ignore
+		}
+	},
 
-	return elements[0];
-};
+	switchSettings : function() {
+		if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
+			tinyMCE.settings = this.settings;
+			tinyMCE.currentConfig = this.settings['index'];
+		}
+	},
 
-TinyMCE.prototype.getElementsByAttributeValue = function(node, element_name, attrib, value) {
-	var elements = new Array();
+	select : function() {
+		var oldInst = tinyMCE.selectedInstance;
 
-	if (node && node.nodeName.toLowerCase() == element_name) {
-		if (node.getAttribute(attrib) && node.getAttribute(attrib).indexOf(value) != -1)
-			elements[elements.length] = node;
-	}
+		if (oldInst != this) {
+			if (oldInst)
+				oldInst.execCommand('mceEndTyping');
 
-	if (node && node.hasChildNodes()) {
-		for (var x=0, n=node.childNodes.length; x<n; x++) {
-			var childElements = this.getElementsByAttributeValue(node.childNodes[x], element_name, attrib, value);
-			for (var i=0, m=childElements.length; i<m; i++)
-				elements[elements.length] = childElements[i];
+			tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst);
+			tinyMCE.selectedInstance = this;
 		}
-	}
+	},
 
-	return elements;
-};
-
-TinyMCE.prototype.isBlockElement = function(node) {
-	return node != null && node.nodeType == 1 && this.blockRegExp.test(node.nodeName);
-};
+	getBody : function() {
+		return this.contentBody ? this.contentBody : this.getDoc().body;
+	},
 
-TinyMCE.prototype.getParentBlockElement = function(node) {
-	// Search up the tree for block element
-	while (node) {
-		if (this.blockRegExp.test(node.nodeName))
-			return node;
+	getDoc : function() {
+//		return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ?
+		return this.contentWindow.document;
+	},
 
-		node = node.parentNode;
-	}
+	getWin : function() {
+		return this.contentWindow;
+	},
 
-	return null;
-};
+	getContainerWin : function() {
+		return this.containerWindow ? this.containerWindow : window;
+	},
 
-TinyMCE.prototype.getNodeTree = function(node, node_array, type, node_name) {
-	if (typeof(type) == "undefined" || node.nodeType == type && (typeof(node_name) == "undefined" || node.nodeName == node_name))
-		node_array[node_array.length] = node;
+	getViewPort : function() {
+		return tinyMCE.getViewPort(this.getWin());
+	},
 
-	if (node.hasChildNodes()) {
-		for (var i=0; i<node.childNodes.length; i++)
-			tinyMCE.getNodeTree(node.childNodes[i], node_array, type, node_name);
-	}
+	getParentNode : function(n, f) {
+		return tinyMCE.getParentNode(n, f, this.getBody());
+	},
 
-	return node_array;
-};
+	getParentElement : function(n, na, f) {
+		return tinyMCE.getParentElement(n, na, f, this.getBody());
+	},
 
-TinyMCE.prototype.getParentElement = function(node, names, attrib_name, attrib_value) {
-	if (typeof(names) == "undefined") {
-		if (node.nodeType == 1)
-			return node;
+	getParentBlockElement : function(n) {
+		return tinyMCE.getParentBlockElement(n, this.getBody());
+	},
 
-		// Find parent node that is a element
-		while ((node = node.parentNode) != null && node.nodeType != 1) ;
+	resizeToContent : function() {
+		var d = this.getDoc(), b = d.body, de = d.documentElement;
 
-		return node;
-	}
+		this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px';
+	},
 
-	var namesAr = names.split(',');
+	addShortcut : function(m, k, d, cmd, ui, va) {
+		var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts;
 
-	if (node == null)
-		return null;
+		if (!tinyMCE.getParam('custom_shortcuts'))
+			return false;
 
-	do {
-		for (var i=0; i<namesAr.length; i++) {
-			if (node.nodeName.toLowerCase() == namesAr[i].toLowerCase() || names == "*") {
-				if (typeof(attrib_name) == "undefined")
-					return node;
-				else if (node.getAttribute(attrib_name)) {
-					if (typeof(attrib_value) == "undefined") {
-						if (node.getAttribute(attrib_name) != "")
-							return node;
-					} else if (node.getAttribute(attrib_name) == attrib_value)
-						return node;
-				}
+		m = m.toLowerCase();
+		k = ie && !n ? k.toUpperCase() : k;
+		c = n ? null : k.charCodeAt(0);
+		d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d;
+
+		sc = {
+			alt : m.indexOf('alt') != -1,
+			ctrl : m.indexOf('ctrl') != -1,
+			shift : m.indexOf('shift') != -1,
+			charCode : c,
+			keyCode : n ? k : (ie ? c : null),
+			desc : d,
+			cmd : cmd,
+			ui : ui,
+			val : va
+		};
+
+		for (i=0; i<scl.length; i++) {
+			if (sc.alt == scl[i].alt && sc.ctrl == scl[i].ctrl && sc.shift == scl[i].shift
+				&& sc.charCode == scl[i].charCode && sc.keyCode == scl[i].keyCode) {
+				return false;
 			}
 		}
-	} while ((node = node.parentNode) != null);
 
-	return null;
-};
+		scl[scl.length] = sc;
 
-TinyMCE.prototype.convertURL = function(url, node, on_save) {
-	var prot = document.location.protocol;
-	var host = document.location.hostname;
-	var port = document.location.port;
+		return true;
+	},
 
-	// Pass through file protocol
-	if (prot == "file:")
-		return url;
+	handleShortcut : function(e) {
+		var i, s, o;
 
-	// Something is wrong, remove weirdness
-	url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
+		// Normal key press, then ignore it
+		if (!e.altKey && !e.ctrlKey)
+			return false;
 
-	// Mailto link or anchor (Pass through)
-	if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
-		return url;
+		s = this.shortcuts;
 
-	// Fix relative/Mozilla
-	if (!tinyMCE.isMSIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
-		return tinyMCE.settings['base_href'] + url;
+		for (i=0; i<s.length; i++) {
+			o = s[i];
 
-	// Handle relative URLs
-	if (on_save && tinyMCE.getParam('relative_urls')) {
-		var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
-		if (curl.charAt(0) == '/')
-			curl = tinyMCE.settings['document_base_prefix'] + curl;
+			if (o.alt == e.altKey && o.ctrl == e.ctrlKey && (o.keyCode == e.keyCode || o.charCode == e.charCode)) {
+				if (o.cmd && (e.type == "keydown" || (e.type == "keypress" && !tinyMCE.isOpera)))
+					tinyMCE.execCommand(o.cmd, o.ui, o.val);
 
-		var urlParts = tinyMCE.parseURL(curl);
-		var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
+				tinyMCE.cancelEvent(e);
+				return true;
+			}
+		}
 
-		// Force relative
-		if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
-			return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
-	}
+		return false;
+	},
 
-	// Handle absolute URLs
-	if (!tinyMCE.getParam('relative_urls')) {
-		var urlParts = tinyMCE.parseURL(url);
-		var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
+	autoResetDesignMode : function() {
+		// Add fix for tab/style.display none/block problems in Gecko
+		if (!tinyMCE.isIE && this.isHidden() && tinyMCE.getParam('auto_reset_designmode'))
+			eval('try { this.getDoc().designMode = "On"; this.useCSS = false; } catch(e) {}');
+	},
 
-		// Force absolute URLs from relative URLs
-		url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
+	isHidden : function() {
+		var s;
 
-		// If anchor and path is the same page
-		if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
-			return "#" + urlParts['anchor'];
-	}
+		if (tinyMCE.isIE)
+			return false;
 
-	// Remove current domain
-	if (tinyMCE.getParam('remove_script_host')) {
-		var start = "", portPart = "";
+		s = this.getSel();
 
-		if (port != "")
-			portPart = ":" + port;
+		// Weird, wheres that cursor selection?
+		return (!s || !s.rangeCount || s.rangeCount == 0);
+	},
+
+	isDirty : function() {
+		// Is content modified and not in a submit procedure
+		return tinyMCE.trim(this.startContent) != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
+	},
+
+	_mergeElements : function(scmd, pa, ch, override) {
+		if (scmd == "removeformat") {
+			pa.className = "";
+			pa.style.cssText = "";
+			ch.className = "";
+			ch.style.cssText = "";
+			return;
+		}
 
-		start = prot + "//" + host + portPart + "/";
+		var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
+		var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
+		var className = tinyMCE.getAttrib(pa, "class");
+
+		// Removed class adding due to bug #1478272
+		className = tinyMCE.getAttrib(ch, "class");
+
+		if (override) {
+			for (var n in st) {
+				if (typeof(st[n]) == 'function')
+					continue;
 
-		if (url.indexOf(start) == 0)
-			url = url.substring(start.length-1);
-	}
+				stc[n] = st[n];
+			}
+		} else {
+			for (var n in stc) {
+				if (typeof(stc[n]) == 'function')
+					continue;
 
-	return url;
-};
+				st[n] = stc[n];
+			}
+		}
 
-/**
- * Parses a URL in to its diffrent components.
- */
-TinyMCE.prototype.parseURL = function(url_str) {
-	var urlParts = new Array();
+		tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st));
+		tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className));
+		ch.className = "";
+		ch.style.cssText = "";
+		ch.removeAttribute("class");
+		ch.removeAttribute("style");
+	},
 
-	if (url_str) {
-		var pos, lastPos;
+	_setUseCSS : function(b) {
+		var d = this.getDoc();
 
-		// Parse protocol part
-		pos = url_str.indexOf('://');
-		if (pos != -1) {
-			urlParts['protocol'] = url_str.substring(0, pos);
-			lastPos = pos + 3;
-		}
+		try {d.execCommand("useCSS", false, !b);} catch (ex) {}
+		try {d.execCommand("styleWithCSS", false, b);} catch (ex) {}
 
-		// Find port or path start
-		for (var i=lastPos; i<url_str.length; i++) {
-			var chr = url_str.charAt(i);
+		if (!tinyMCE.getParam("table_inline_editing"))
+			try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}
 
-			if (chr == ':')
-				break;
+		if (!tinyMCE.getParam("object_resizing"))
+			try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {}
+	},
 
-			if (chr == '/')
-				break;
-		}
-		pos = i;
+	execCommand : function(command, user_interface, value) {
+		var doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement();
 
-		// Get host
-		urlParts['host'] = url_str.substring(lastPos, pos);
+		// Is not a undo specific command
+		if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command))
+			this.undoBookmark = null;
 
-		// Get port
-		urlParts['port'] = "";
-		lastPos = pos;
-		if (url_str.charAt(pos) == ':') {
-			pos = url_str.indexOf('/', lastPos);
-			urlParts['port'] = url_str.substring(lastPos+1, pos);
+		// Mozilla issue
+		if (!tinyMCE.isIE && !this.useCSS) {
+			this._setUseCSS(false);
+			this.useCSS = true;
 		}
 
-		// Get path
-		lastPos = pos;
-		pos = url_str.indexOf('?', lastPos);
+		//debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value);
+		this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks
 
-		if (pos == -1)
-			pos = url_str.indexOf('#', lastPos);
+		// Don't dispatch key commands
+		if (!/mceStartTyping|mceEndTyping/.test(command)) {
+			if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value))
+				return;
+		}
 
-		if (pos == -1)
-			pos = url_str.length;
+		// Fix align on images
+		if (focusElm && focusElm.nodeName == "IMG") {
+			var align = focusElm.getAttribute('align');
+			var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
 
-		urlParts['path'] = url_str.substring(lastPos, pos);
+			switch (command) {
+				case "JustifyLeft":
+					if (align == 'left')
+						img.removeAttribute('align');
+					else
+						img.setAttribute('align', 'left');
 
-		// Get query
-		lastPos = pos;
-		if (url_str.charAt(pos) == '?') {
-			pos = url_str.indexOf('#');
-			pos = (pos == -1) ? url_str.length : pos;
-			urlParts['query'] = url_str.substring(lastPos+1, pos);
-		}
+					// Remove the div
+					var div = focusElm.parentNode;
+					if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
+						div.parentNode.replaceChild(img, div);
 
-		// Get anchor
-		lastPos = pos;
-		if (url_str.charAt(pos) == '#') {
-			pos = url_str.length;
-			urlParts['anchor'] = url_str.substring(lastPos+1, pos);
-		}
-	}
+					this.selection.selectNode(img);
+					this.repaint();
+					tinyMCE.triggerNodeChange();
+					return;
 
-	return urlParts;
-};
+				case "JustifyCenter":
+					img.removeAttribute('align');
 
-TinyMCE.prototype.serializeURL = function(up) {
-	var url = "";
+					// Is centered
+					var div = tinyMCE.getParentElement(focusElm, "div");
+					if (div && div.style.textAlign == "center") {
+						// Remove div
+						if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
+							div.parentNode.replaceChild(img, div);
+					} else {
+						// Add div
+						var div = this.getDoc().createElement("div");
+						div.style.textAlign = 'center';
+						div.appendChild(img);
+						focusElm.parentNode.replaceChild(div, focusElm);
+					}
 
-	if (up['protocol'])
-		url += up['protocol'] + "://";
+					this.selection.selectNode(img);
+					this.repaint();
+					tinyMCE.triggerNodeChange();
+					return;
 
-	if (up['host'])
-		url += up['host'];
+				case "JustifyRight":
+					if (align == 'right')
+						img.removeAttribute('align');
+					else
+						img.setAttribute('align', 'right');
 
-	if (up['port'])
-		url += ":" + up['port'];
+					// Remove the div
+					var div = focusElm.parentNode;
+					if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
+						div.parentNode.replaceChild(img, div);
 
-	if (up['path'])
-		url += up['path'];
+					this.selection.selectNode(img);
+					this.repaint();
+					tinyMCE.triggerNodeChange();
+					return;
+			}
+		}
 
-	if (up['query'])
-		url += "?" + up['query'];
+		if (tinyMCE.settings['force_br_newlines']) {
+			var alignValue = "";
 
-	if (up['anchor'])
-		url += "#" + up['anchor'];
+			if (doc.selection.type != "Control") {
+				switch (command) {
+						case "JustifyLeft":
+							alignValue = "left";
+							break;
 
-	return url;
-};
+						case "JustifyCenter":
+							alignValue = "center";
+							break;
 
-/**
- * Converts an absolute path to relative path.
- */
-TinyMCE.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
-	var baseURL = this.parseURL(base_url);
-	var targetURL = this.parseURL(url_to_relative);
-	var strTok1;
-	var strTok2;
-	var breakPoint = 0;
-	var outPath = "";
-	var forceSlash = false;
+						case "JustifyFull":
+							alignValue = "justify";
+							break;
 
-	if (targetURL.path == "")
-		targetURL.path = "/";
-	else
-		forceSlash = true;
+						case "JustifyRight":
+							alignValue = "right";
+							break;
+				}
 
-	// Crop away last path part
-	base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
-	strTok1 = base_url.split('/');
-	strTok2 = targetURL.path.split('/');
+				if (alignValue != "") {
+					var rng = doc.selection.createRange();
 
-	if (strTok1.length >= strTok2.length) {
-		for (var i=0; i<strTok1.length; i++) {
-			if (i >= strTok2.length || strTok1[i] != strTok2[i]) {
-				breakPoint = i + 1;
-				break;
-			}
-		}
-	}
+					if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null)
+						divElm.setAttribute("align", alignValue);
+					else if (rng.pasteHTML && rng.htmlText.length > 0)
+						rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>");
 
-	if (strTok1.length < strTok2.length) {
-		for (var i=0; i<strTok2.length; i++) {
-			if (i >= strTok1.length || strTok1[i] != strTok2[i]) {
-				breakPoint = i + 1;
-				break;
+					tinyMCE.triggerNodeChange();
+					return;
+				}
 			}
 		}
-	}
 
-	if (breakPoint == 1)
-		return targetURL.path;
+		switch (command) {
+			case "mceRepaint":
+				this.repaint();
+				return true;
+
+			case "unlink":
+				// Unlink if caret is inside link
+				if (tinyMCE.isGecko && this.getSel().isCollapsed) {
+					focusElm = tinyMCE.getParentElement(focusElm, 'A');
+
+					if (focusElm)
+						this.selection.selectNode(focusElm, false);
+				}
+
+				this.getDoc().execCommand(command, user_interface, value);
+
+				tinyMCE.isGecko && this.getSel().collapseToEnd();
+
+				tinyMCE.triggerNodeChange();
+
+				return true;
+
+			case "InsertUnorderedList":
+			case "InsertOrderedList":
+				this.getDoc().execCommand(command, user_interface, value);
+				tinyMCE.triggerNodeChange();
+				break;
+
+			case "Strikethrough":
+				this.getDoc().execCommand(command, user_interface, value);
+				tinyMCE.triggerNodeChange();
+				break;
+
+			case "mceSelectNode":
+				this.selection.selectNode(value);
+				tinyMCE.triggerNodeChange();
+				tinyMCE.selectedNode = value;
+				break;
+
+			case "FormatBlock":
+				if (value == null || value == "") {
+					var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp");
+
+					if (elm)
+						this.execCommand("mceRemoveNode", false, elm);
+				} else {
+					if (!this.cleanup.isValid(value))
+						return true;
+
+					if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value))
+						value = value.replace(/[^a-z]/gi, '');
+
+					if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) {
+						var b = this.selection.getBookmark();
+						this.getDoc().execCommand("FormatBlock", false, '<p>');
+						tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value);
+						this.selection.moveToBookmark(b);
+					} else
+						this.getDoc().execCommand("FormatBlock", false, value);
+				}
+
+				tinyMCE.triggerNodeChange();
+
+				break;
+
+			case "mceRemoveNode":
+				if (!value)
+					value = tinyMCE.getParentElement(this.getFocusElement());
+
+				if (tinyMCE.isIE) {
+					value.outerHTML = value.innerHTML;
+				} else {
+					var rng = value.ownerDocument.createRange();
+					rng.setStartBefore(value);
+					rng.setEndAfter(value);
+					rng.deleteContents();
+					rng.insertNode(rng.createContextualFragment(value.innerHTML));
+				}
+
+				tinyMCE.triggerNodeChange();
+
+				break;
+
+			case "mceSelectNodeDepth":
+				var parentNode = this.getFocusElement();
+				for (var i=0; parentNode; i++) {
+					if (parentNode.nodeName.toLowerCase() == "body")
+						break;
+
+					if (parentNode.nodeName.toLowerCase() == "#text") {
+						i--;
+						parentNode = parentNode.parentNode;
+						continue;
+					}
+
+					if (i == value) {
+						this.selection.selectNode(parentNode, false);
+						tinyMCE.triggerNodeChange();
+						tinyMCE.selectedNode = parentNode;
+						return;
+					}
+
+					parentNode = parentNode.parentNode;
+				}
+
+				break;
+
+			case "mceSetStyleInfo":
+			case "SetStyleInfo":
+				var rng = this.getRng();
+				var sel = this.getSel();
+				var scmd = value['command'];
+				var sname = value['name'];
+				var svalue = value['value'] == null ? '' : value['value'];
+				//var svalue = value['value'] == null ? '' : value['value'];
+				var wrapper = value['wrapper'] ? value['wrapper'] : "span";
+				var parentElm = null;
+				var invalidRe = new RegExp("^BODY|HTML$", "g");
+				var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
+
+				// Whole element selected check
+				if (tinyMCE.isIE) {
+					// Control range
+					if (rng.item)
+						parentElm = rng.item(0);
+					else {
+						var pelm = rng.parentElement();
+						var prng = doc.selection.createRange();
+						prng.moveToElementText(pelm);
+
+						if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {
+							if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))
+								parentElm = pelm;
+						}
+					}
+				} else {
+					var felm = this.getFocusElement();
+					if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode))
+						parentElm = felm;
+				}
+
+				// Whole element selected
+				if (parentElm && !invalidRe.test(parentElm.nodeName)) {
+					if (scmd == "setstyle")
+						tinyMCE.setStyleAttrib(parentElm, sname, svalue);
+
+					if (scmd == "setattrib")
+						tinyMCE.setAttrib(parentElm, sname, svalue);
+
+					if (scmd == "removeformat") {
+						parentElm.style.cssText = '';
+						tinyMCE.setAttrib(parentElm, 'class', '');
+					}
+
+					// Remove style/attribs from all children
+					var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
+					for (var z=0; z<ch.length; z++) {
+						if (ch[z] == parentElm)
+							continue;
+
+						if (scmd == "setstyle")
+							tinyMCE.setStyleAttrib(ch[z], sname, '');
+
+						if (scmd == "setattrib")
+							tinyMCE.setAttrib(ch[z], sname, '');
+
+						if (scmd == "removeformat") {
+							ch[z].style.cssText = '';
+							tinyMCE.setAttrib(ch[z], 'class', '');
+						}
+					}
+				} else {
+					this._setUseCSS(false); // Bug in FF when running in fullscreen
+					doc.execCommand("FontName", false, "#mce_temp_font#");
+					var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#");
+
+					// Change them all
+					for (var x=0; x<elementArray.length; x++) {
+						elm = elementArray[x];
+						if (elm) {
+							var spanElm = doc.createElement(wrapper);
+
+							if (scmd == "setstyle")
+								tinyMCE.setStyleAttrib(spanElm, sname, svalue);
+
+							if (scmd == "setattrib")
+								tinyMCE.setAttrib(spanElm, sname, svalue);
+
+							if (scmd == "removeformat") {
+								spanElm.style.cssText = '';
+								tinyMCE.setAttrib(spanElm, 'class', '');
+							}
+
+							if (elm.hasChildNodes()) {
+								for (var i=0; i<elm.childNodes.length; i++)
+									spanElm.appendChild(elm.childNodes[i].cloneNode(true));
+							}
+
+							spanElm.setAttribute("mce_new", "true");
+							elm.parentNode.replaceChild(spanElm, elm);
+
+							// Remove style/attribs from all children
+							var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
+							for (var z=0; z<ch.length; z++) {
+								if (ch[z] == spanElm)
+									continue;
+
+								if (scmd == "setstyle")
+									tinyMCE.setStyleAttrib(ch[z], sname, '');
+
+								if (scmd == "setattrib")
+									tinyMCE.setAttrib(ch[z], sname, '');
+
+								if (scmd == "removeformat") {
+									ch[z].style.cssText = '';
+									tinyMCE.setAttrib(ch[z], 'class', '');
+								}
+							}
+						}
+					}
+				}
+
+				// Cleaup wrappers
+				var nodes = doc.getElementsByTagName(wrapper);
+				for (var i=nodes.length-1; i>=0; i--) {
+					var elm = nodes[i];
+					var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
+
+					elm.removeAttribute("mce_new");
+
+					// Is only child a element
+					if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) {
+						//tinyMCE.debug("merge1" + isNew);
+						this._mergeElements(scmd, elm, elm.childNodes[0], isNew);
+						continue;
+					}
+
+					// Is I the only child
+					if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {
+						//tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);
+						if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))
+							this._mergeElements(scmd, elm.parentNode, elm, false);
+					}
+				}
+
+				// Remove empty wrappers
+				var nodes = doc.getElementsByTagName(wrapper);
+				for (var i=nodes.length-1; i>=0; i--) {
+					var elm = nodes[i];
+					var isEmpty = true;
+
+					// Check if it has any attribs
+					var tmp = doc.createElement("body");
+					tmp.appendChild(elm.cloneNode(false));
+
+					// Is empty span, remove it
+					tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');
+					//tinyMCE.debug(tmp.innerHTML);
+					if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
+						for (var x=0; x<elm.childNodes.length; x++) {
+							if (elm.parentNode != null)
+								elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
+						}
+
+						elm.parentNode.removeChild(elm);
+					}
+				}
+
+				// Re add the visual aids
+				if (scmd == "removeformat")
+					tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
+
+				tinyMCE.triggerNodeChange();
+
+				break;
+
+			case "FontName":
+				if (value == null) {
+					var s = this.getSel();
+
+					// Find font and select it
+					if (tinyMCE.isGecko && s.isCollapsed) {
+						var f = tinyMCE.getParentElement(this.getFocusElement(), "font");
+
+						if (f != null)
+							this.selection.selectNode(f, false);
+					}
+
+					// Remove format
+					this.getDoc().execCommand("RemoveFormat", false, null);
+
+					// Collapse range if font was found
+					if (f != null && tinyMCE.isGecko) {
+						var r = this.getRng().cloneRange();
+						r.collapse(true);
+						s.removeAllRanges();
+						s.addRange(r);
+					}
+				} else
+					this.getDoc().execCommand('FontName', false, value);
+
+				if (tinyMCE.isGecko)
+					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+
+				return;
+
+			case "FontSize":
+				this.getDoc().execCommand('FontSize', false, value);
+
+				if (tinyMCE.isGecko)
+					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+
+				return;
+
+			case "forecolor":
+				value = value == null ? this.foreColor : value;
+				value = tinyMCE.trim(value);
+				value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value;
+
+				this.foreColor = value;
+				this.getDoc().execCommand('forecolor', false, value);
+				break;
+
+			case "HiliteColor":
+				value = value == null ? this.backColor : value;
+				value = tinyMCE.trim(value);
+				value = value.charAt(0) != '#' ? (isNaN('0x' + value) ? value : '#' + value) : value;
+				this.backColor = value;
+
+				if (tinyMCE.isGecko) {
+					this._setUseCSS(true);
+					this.getDoc().execCommand('hilitecolor', false, value);
+					this._setUseCSS(false);
+				} else
+					this.getDoc().execCommand('BackColor', false, value);
+				break;
+
+			case "Cut":
+			case "Copy":
+			case "Paste":
+				var cmdFailed = false;
+
+				// Try executing command
+				eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');
+
+				if (tinyMCE.isOpera && cmdFailed)
+					alert('Currently not supported by your browser, use keyboard shortcuts instead.');
+
+				// Alert error in gecko if command failed
+				if (tinyMCE.isGecko && cmdFailed) {
+					// Confirm more info
+					if (confirm(tinyMCE.entityDecode(tinyMCE.getLang('lang_clipboard_msg'))))
+						window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
+
+					return;
+				} else
+					tinyMCE.triggerNodeChange();
+			break;
+
+			case "mceSetContent":
+				if (!value)
+					value = "";
+
+				// Call custom cleanup code
+				value = tinyMCE.storeAwayURLs(value);
+				value = tinyMCE._customCleanup(this, "insert_to_editor", value);
+
+				if (this.getBody().nodeName == 'BODY')
+					tinyMCE._setHTML(doc, value);
+				else
+					this.getBody().innerHTML = value;
+
+				tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, doc, this.settings, this.getBody(), false, false, false, true));
+				tinyMCE.convertAllRelativeURLs(this.getBody());
+
+				// Cleanup any mess left from storyAwayURLs
+				tinyMCE._removeInternal(this.getBody());
+
+				// When editing always use fonts internaly
+				if (tinyMCE.getParam("convert_fonts_to_spans"))
+					tinyMCE.convertSpansToFonts(doc);
+
+				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
+				tinyMCE._setEventsEnabled(this.getBody(), false);
+				return true;
+
+			case "mceCleanup":
+				var b = this.selection.getBookmark();
+				tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);
+				tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));
+				tinyMCE.convertAllRelativeURLs(doc.body);
+
+				// When editing always use fonts internaly
+				if (tinyMCE.getParam("convert_fonts_to_spans"))
+					tinyMCE.convertSpansToFonts(doc);
+
+				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
+				tinyMCE._setEventsEnabled(this.getBody(), false);
+				this.repaint();
+				this.selection.moveToBookmark(b);
+				tinyMCE.triggerNodeChange();
+			break;
+
+			case "mceReplaceContent":
+				// Force empty string
+				if (!value)
+					value = '';
+
+				this.getWin().focus();
+
+				var selectedText = "";
+
+				if (tinyMCE.isIE) {
+					var rng = doc.selection.createRange();
+					selectedText = rng.text;
+				} else
+					selectedText = this.getSel().toString();
+
+				if (selectedText.length > 0) {
+					value = tinyMCE.replaceVar(value, "selection", selectedText);
+					tinyMCE.execCommand('mceInsertContent', false, value);
+				}
+
+				tinyMCE.triggerNodeChange();
+			break;
+
+			case "mceSetAttribute":
+				if (typeof(value) == 'object') {
+					var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
+					var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
+
+					if (targetNode) {
+						targetNode.setAttribute(value['name'], value['value']);
+						tinyMCE.triggerNodeChange();
+					}
+				}
+			break;
+
+			case "mceSetCSSClass":
+				this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value});
+			break;
+
+			case "mceInsertRawHTML":
+				var key = 'tiny_mce_marker';
+
+				this.execCommand('mceBeginUndoLevel');
+
+				// Insert marker key
+				this.execCommand('mceInsertContent', false, key);
+
+				// Store away scroll pos
+				var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft;
+				var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop;
+
+				// Find marker and replace with RAW HTML
+				var html = this.getBody().innerHTML;
+				if ((pos = html.indexOf(key)) != -1)
+					tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));
+
+				// Restore scoll pos
+				this.contentWindow.scrollTo(scrollX, scrollY);
+
+				this.execCommand('mceEndUndoLevel');
+
+				break;
+
+			case "mceInsertContent":
+				// Force empty string
+				if (!value)
+					value = '';
+
+				var insertHTMLFailed = false;
+
+				// Removed since it produced problems in IE
+				// this.getWin().focus();
+
+				if (tinyMCE.isGecko || tinyMCE.isOpera) {
+					try {
+						// Is plain text or HTML, &amp;, &nbsp; etc will be encoded wrong in FF
+						if (value.indexOf('<') == -1 && !value.match(/(&#38;|&#160;|&#60;|&#62;)/g)) {
+							var r = this.getRng();
+							var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));
+							var s = this.getSel();
+							var r2 = r.cloneRange();
+
+							// Insert text at cursor position
+							s.removeAllRanges();
+							r.deleteContents();
+							r.insertNode(n);
+
+							// Move the cursor to the end of text
+							r2.selectNode(n);
+							r2.collapse(false);
+							s.removeAllRanges();
+							s.addRange(r2);
+						} else {
+							value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);
+							this.getDoc().execCommand('inserthtml', false, value);
+							tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
+						}
+					} catch (ex) {
+						insertHTMLFailed = true;
+					}
+
+					if (!insertHTMLFailed) {
+						tinyMCE.triggerNodeChange();
+						return;
+					}
+				}
+
+				if (!tinyMCE.isIE) {
+					var isHTML = value.indexOf('<') != -1;
+					var sel = this.getSel();
+					var rng = this.getRng();
+
+					if (isHTML) {
+						if (tinyMCE.isSafari) {
+							var tmpRng = this.getDoc().createRange();
+
+							tmpRng.setStart(this.getBody(), 0);
+							tmpRng.setEnd(this.getBody(), 0);
+
+							value = tmpRng.createContextualFragment(value);
+						} else
+							value = rng.createContextualFragment(value);
+					} else {
+						// Setup text node
+						var el = document.createElement("div");
+						el.innerHTML = value;
+						value = el.firstChild.nodeValue;
+						value = doc.createTextNode(value);
+					}
+
+					// Insert plain text in Safari
+					if (tinyMCE.isSafari && !isHTML) {
+						this.execCommand('InsertText', false, value.nodeValue);
+						tinyMCE.triggerNodeChange();
+						return true;
+					} else if (tinyMCE.isSafari && isHTML) {
+						rng.deleteContents();
+						rng.insertNode(value);
+						tinyMCE.triggerNodeChange();
+						return true;
+					}
+
+					rng.deleteContents();
+
+					// If target node is text do special treatment, (Mozilla 1.3 fix)
+					if (rng.startContainer.nodeType == 3) {
+						var node = rng.startContainer.splitText(rng.startOffset);
+						node.parentNode.insertBefore(value, node); 
+					} else
+						rng.insertNode(value);
+
+					if (!isHTML) {
+						// Removes weird selection trails
+						sel.selectAllChildren(doc.body);
+						sel.removeAllRanges();
+
+						// Move cursor to end of content
+						var rng = doc.createRange();
+
+						rng.selectNode(value);
+						rng.collapse(false);
+
+						sel.addRange(rng);
+					} else
+						rng.collapse(false);
+
+					tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
+				} else {
+					var rng = doc.selection.createRange(), tmpRng = null;
+					var c = value.indexOf('<!--') != -1;
+
+					// Fix comment bug, add tag before comments
+					if (c)
+						value = tinyMCE.uniqueTag + value;
+
+					//	tmpRng = rng.duplicate(); // Store away range (Fixes Undo bookmark bug in IE)
+
+					if (rng.item)
+						rng.item(0).outerHTML = value;
+					else
+						rng.pasteHTML(value);
+
+					//if (tmpRng)
+					//	tmpRng.select(); // Restore range  (Fixes Undo bookmark bug in IE)
+
+					// Remove unique tag
+					if (c) {
+						var e = this.getDoc().getElementById('mceTMPElement');
+						e.parentNode.removeChild(e);
+					}
+				}
+
+				tinyMCE.execCommand("mceAddUndoLevel");
+				tinyMCE.triggerNodeChange();
+			break;
+
+			case "mceStartTyping":
+				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex == -1) {
+					this.undoRedo.typingUndoIndex = this.undoRedo.undoIndex;
+					tinyMCE.typingUndoIndex = tinyMCE.undoIndex;
+					this.execCommand('mceAddUndoLevel');
+				}
+				break;
+
+			case "mceEndTyping":
+				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo.typingUndoIndex != -1) {
+					this.execCommand('mceAddUndoLevel');
+					this.undoRedo.typingUndoIndex = -1;
+				}
+
+				tinyMCE.typingUndoIndex = -1;
+				break;
+
+			case "mceBeginUndoLevel":
+				this.undoRedoLevel = false;
+				break;
+
+			case "mceEndUndoLevel":
+				this.undoRedoLevel = true;
+				this.execCommand('mceAddUndoLevel');
+				break;
+
+			case "mceAddUndoLevel":
+				if (tinyMCE.settings['custom_undo_redo'] && this.undoRedoLevel) {
+					if (this.undoRedo.add())
+						tinyMCE.triggerNodeChange(false);
+				}
+				break;
+
+			case "Undo":
+				if (tinyMCE.settings['custom_undo_redo']) {
+					tinyMCE.execCommand("mceEndTyping");
+					this.undoRedo.undo();
+					tinyMCE.triggerNodeChange();
+				} else
+					this.getDoc().execCommand(command, user_interface, value);
+				break;
+
+			case "Redo":
+				if (tinyMCE.settings['custom_undo_redo']) {
+					tinyMCE.execCommand("mceEndTyping");
+					this.undoRedo.redo();
+					tinyMCE.triggerNodeChange();
+				} else
+					this.getDoc().execCommand(command, user_interface, value);
+				break;
+
+			case "mceToggleVisualAid":
+				this.visualAid = !this.visualAid;
+				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
+				tinyMCE.triggerNodeChange();
+				break;
+
+			case "Indent":
+				this.getDoc().execCommand(command, user_interface, value);
+				tinyMCE.triggerNodeChange();
+
+				if (tinyMCE.isIE) {
+					var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote");
+					do {
+						if (n && n.nodeName == "BLOCKQUOTE") {
+							n.removeAttribute("dir");
+							n.removeAttribute("style");
+						}
+					} while (n != null && (n = n.parentNode) != null);
+				}
+				break;
+
+			case "RemoveFormat":
+			case "removeformat":
+				var text = this.selection.getSelectedText();
+
+				if (tinyMCE.isOpera) {
+					this.getDoc().execCommand("RemoveFormat", false, null);
+					return;
+				}
+
+				if (tinyMCE.isIE) {
+					try {
+						var rng = doc.selection.createRange();
+						rng.execCommand("RemoveFormat", false, null);
+					} catch (e) {
+						// Do nothing
+					}
+
+					this.execCommand("mceSetStyleInfo", false, {command : "removeformat"});
+				} else {
+					this.getDoc().execCommand(command, user_interface, value);
+
+					this.execCommand("mceSetStyleInfo", false, {command : "removeformat"});
+				}
+
+				// Remove class
+				if (text.length == 0)
+					this.execCommand("mceSetCSSClass", false, "");
+
+				tinyMCE.triggerNodeChange();
+				break;
+
+			default:
+				this.getDoc().execCommand(command, user_interface, value);
+
+				if (tinyMCE.isGecko)
+					window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+				else
+					tinyMCE.triggerNodeChange();
+		}
+
+		// Add undo level after modification
+		if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping")
+			tinyMCE.execCommand("mceAddUndoLevel");
+	},
+
+	queryCommandValue : function(c) {
+		try {
+			return this.getDoc().queryCommandValue(c);
+		} catch (e) {
+			return null;
+		}
+	},
+
+	queryCommandState : function(c) {
+		return this.getDoc().queryCommandState(c);
+	},
+
+	_onAdd : function(replace_element, form_element_name, target_document) {
+		var hc, th, to, editorTemplate;
+
+		th = this.settings['theme'];
+		to = tinyMCE.themes[th];
+
+		var targetDoc = target_document ? target_document : document;
+
+		this.targetDoc = targetDoc;
+
+		tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
+		this.settings['themeurl'] = tinyMCE.themeURL;
+
+		if (!replace_element) {
+			alert("Error: Could not find the target element.");
+			return false;
+		}
+
+		if (to.getEditorTemplate)
+			editorTemplate = to.getEditorTemplate(this.settings, this.editorId);
+
+		var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
+		var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
+		var html = '<span id="' + this.editorId + '_parent" class="mceEditorContainer">' + editorTemplate['html'];
+
+		html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
+		this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
+
+		this.settings['old_width'] = this.settings['width'];
+		this.settings['old_height'] = this.settings['height'];
+
+		// Set default width, height
+		if (this.settings['width'] == -1)
+			this.settings['width'] = replace_element.offsetWidth;
+
+		if (this.settings['height'] == -1)
+			this.settings['height'] = replace_element.offsetHeight;
+
+		// Try the style width
+		if (this.settings['width'] == 0)
+			this.settings['width'] = replace_element.style.width;
+
+		// Try the style height
+		if (this.settings['height'] == 0)
+			this.settings['height'] = replace_element.style.height; 
+
+		// If no width/height then default to 320x240, better than nothing
+		if (this.settings['width'] == 0)
+			this.settings['width'] = 320;
+
+		if (this.settings['height'] == 0)
+			this.settings['height'] = 240;
+
+		this.settings['area_width'] = parseInt(this.settings['width']);
+		this.settings['area_height'] = parseInt(this.settings['height']);
+		this.settings['area_width'] += deltaWidth;
+		this.settings['area_height'] += deltaHeight;
+
+		this.settings['width_style'] = "" + this.settings['width'];
+		this.settings['height_style'] = "" + this.settings['height'];
+
+		// Special % handling
+		if (("" + this.settings['width']).indexOf('%') != -1)
+			this.settings['area_width'] = "100%";
+		else
+			this.settings['width_style'] += 'px';
+
+		if (("" + this.settings['height']).indexOf('%') != -1)
+			this.settings['area_height'] = "100%";
+		else
+			this.settings['height_style'] += 'px';
+
+		if (("" + replace_element.style.width).indexOf('%') != -1) {
+			this.settings['width'] = replace_element.style.width;
+			this.settings['area_width'] = "100%";
+			this.settings['width_style'] = "100%";
+		}
+
+		if (("" + replace_element.style.height).indexOf('%') != -1) {
+			this.settings['height'] = replace_element.style.height;
+			this.settings['area_height'] = "100%";
+			this.settings['height_style'] = "100%";
+		}
+
+		html = tinyMCE.applyTemplate(html);
+
+		this.settings['width'] = this.settings['old_width'];
+		this.settings['height'] = this.settings['old_height'];
+
+		this.visualAid = this.settings['visual'];
+		this.formTargetElementId = form_element_name;
+
+		// Get replace_element contents
+		if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT")
+			this.startContent = replace_element.value;
+		else
+			this.startContent = replace_element.innerHTML;
+
+		// If not text area or input
+		if (replace_element.nodeName != "TEXTAREA" && replace_element.nodeName != "INPUT") {
+			this.oldTargetElement = replace_element;
+
+			// Debug mode
+			if (tinyMCE.settings['debug']) {
+				hc = '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
+			} else {
+				hc = '<input type="hidden" id="' + form_element_name + '" name="' + form_element_name + '" />';
+				this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
+				this.oldTargetElement.style.display = "none";
+			}
+
+			html += '</span>';
+
+			if (tinyMCE.isGecko)
+				html = hc + html;
+			else
+				html += hc;
+
+			// Output HTML and set editable
+			if (tinyMCE.isGecko) {
+				var rng = replace_element.ownerDocument.createRange();
+				rng.setStartBefore(replace_element);
+
+				var fragment = rng.createContextualFragment(html);
+				tinyMCE.insertAfter(fragment, replace_element);
+			} else
+				replace_element.insertAdjacentHTML("beforeBegin", html);
+		} else {
+			html += '</span>';
+
+			// Just hide the textarea element
+			this.oldTargetElement = replace_element;
+
+			if (!tinyMCE.settings['debug']) {
+				this.oldTargetDisplay = tinyMCE.getStyle(this.oldTargetElement, 'display', 'inline');
+				this.oldTargetElement.style.display = "none";
+			}
+
+			// Output HTML and set editable
+			if (tinyMCE.isGecko) {
+				var rng = replace_element.ownerDocument.createRange();
+				rng.setStartBefore(replace_element);
+
+				var fragment = rng.createContextualFragment(html);
+				tinyMCE.insertAfter(fragment, replace_element);
+			} else
+				replace_element.insertAdjacentHTML("beforeBegin", html);
+		}
+
+		// Setup iframe
+		var dynamicIFrame = false;
+		var tElm = targetDoc.getElementById(this.editorId);
+
+		if (!tinyMCE.isIE) {
+			// Node case is preserved in XML strict mode
+			if (tElm && (tElm.nodeName == "SPAN" || tElm.nodeName == "span")) {
+				tElm = tinyMCE._createIFrame(tElm, targetDoc);
+				dynamicIFrame = true;
+			}
+
+			this.targetElement = tElm;
+			this.iframeElement = tElm;
+			this.contentDocument = tElm.contentDocument;
+			this.contentWindow = tElm.contentWindow;
+
+			//this.getDoc().designMode = "on";
+		} else {
+			if (tElm && tElm.nodeName == "SPAN")
+				tElm = tinyMCE._createIFrame(tElm, targetDoc, targetDoc.parentWindow);
+			else
+				tElm = targetDoc.frames[this.editorId];
+
+			this.targetElement = tElm;
+			this.iframeElement = targetDoc.getElementById(this.editorId);
+
+			if (tinyMCE.isOpera) {
+				this.contentDocument = this.iframeElement.contentDocument;
+				this.contentWindow = this.iframeElement.contentWindow;
+				dynamicIFrame = true;
+			} else {
+				this.contentDocument = tElm.window.document;
+				this.contentWindow = tElm.window;
+			}
+
+			this.getDoc().designMode = "on";
+		}
+
+		// Setup base HTML
+		var doc = this.contentDocument;
+		if (dynamicIFrame) {
+			var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';
+
+			try {
+				if (!this.isHidden())
+					this.getDoc().designMode = "on";
+
+				doc.open();
+				doc.write(html);
+				doc.close();
+			} catch (e) {
+				// Failed Mozilla 1.3
+				this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm";
+			}
+		}
+
+		// This timeout is needed in MSIE 5.5 for some odd reason
+		// it seems that the document.frames isn't initialized yet?
+		if (tinyMCE.isIE)
+			window.setTimeout("tinyMCE.addEventHandlers(tinyMCE.instances[\"" + this.editorId + "\"]);", 1);
+
+		// Setup element references
+		var parentElm = this.targetDoc.getElementById(this.editorId + '_parent');
+		this.formElement = tinyMCE.isGecko ? parentElm.previousSibling : parentElm.nextSibling;
+
+		tinyMCE.setupContent(this.editorId, true);
+
+		return true;
+	},
+
+	setBaseHREF : function(u) {
+		var h, b, d, nl;
+
+		d = this.getDoc();
+		nl = d.getElementsByTagName("base");
+		b = nl.length > 0 ? nl[0] : null;
+
+		if (!b) {
+			nl = d.getElementsByTagName("head");
+			h = nl.length > 0 ? nl[0] : null;
+
+			b = d.createElement("base");
+			b.setAttribute('href', u);
+			h.appendChild(b);
+		} else {
+			if (u == "" || u == null)
+				b.parentNode.removeChild(b);
+			else
+				b.setAttribute('href', u);
+		}
+	},
+
+	getHTML : function(r) {
+		var h, d = this.getDoc(), b = this.getBody();
+
+		if (r)
+			return b.innerHTML;
+
+		h = tinyMCE._cleanupHTML(this, d, this.settings, b, false, true, false, true);
+
+		if (tinyMCE.getParam("convert_fonts_to_spans"))
+			tinyMCE.convertSpansToFonts(d);
+
+		return h;
+	},
+
+	setHTML : function(h) {
+		this.execCommand('mceSetContent', false, h);
+		this.repaint();
+	},
+
+	getFocusElement : function() {
+		return this.selection.getFocusElement();
+	},
+
+	getSel : function() {
+		return this.selection.getSel();
+	},
+
+	getRng : function() {
+		return this.selection.getRng();
+	},
+
+	triggerSave : function(skip_cleanup, skip_callback) {
+		var e, nl = [], i, s;
+
+		this.switchSettings();
+		s = tinyMCE.settings;
+
+		// Force hidden tabs visible while serializing
+		if (tinyMCE.isRealIE) {
+			e = this.iframeElement;
+
+			do {
+				if (e.style && e.style.display == 'none') {
+					e.style.display = 'block';
+					nl[nl.length] = {elm : e, type : 'style'};
+				}
+
+				if (e.style && s.hidden_tab_class.length > 0 && e.className.indexOf(s.hidden_tab_class) != -1) {
+					e.className = s.display_tab_class;
+					nl[nl.length] = {elm : e, type : 'class'};
+				}
+			} while ((e = e.parentNode) != null)
+		}
+
+		tinyMCE.settings['preformatted'] = false;
+
+		// Default to false
+		if (typeof(skip_cleanup) == "undefined")
+			skip_cleanup = false;
+
+		// Default to false
+		if (typeof(skip_callback) == "undefined")
+			skip_callback = false;
+
+		tinyMCE._setHTML(this.getDoc(), this.getBody().innerHTML);
+
+		// Remove visual aids when cleanup is disabled
+		if (this.settings['cleanup'] == false) {
+			tinyMCE.handleVisualAid(this.getBody(), true, false, this);
+			tinyMCE._setEventsEnabled(this.getBody(), true);
+		}
+
+		tinyMCE._customCleanup(this, "submit_content_dom", this.contentWindow.document.body);
+		var htm = skip_cleanup ? this.getBody().innerHTML : tinyMCE._cleanupHTML(this, this.getDoc(), this.settings, this.getBody(), tinyMCE.visualAid, true, true);
+		htm = tinyMCE._customCleanup(this, "submit_content", htm);
+
+		if (!skip_callback && tinyMCE.settings['save_callback'] != "")
+			var content = eval(tinyMCE.settings['save_callback'] + "(this.formTargetElementId,htm,this.getBody());");
+
+		// Use callback content if available
+		if ((typeof(content) != "undefined") && content != null)
+			htm = content;
+
+		// Replace some weird entities (Bug: #1056343)
+		htm = tinyMCE.regexpReplace(htm, "&#40;", "(", "gi");
+		htm = tinyMCE.regexpReplace(htm, "&#41;", ")", "gi");
+		htm = tinyMCE.regexpReplace(htm, "&#59;", ";", "gi");
+		htm = tinyMCE.regexpReplace(htm, "&#34;", "&quot;", "gi");
+		htm = tinyMCE.regexpReplace(htm, "&#94;", "^", "gi");
+
+		if (this.formElement)
+			this.formElement.value = htm;
+
+		if (tinyMCE.isSafari && this.formElement)
+			this.formElement.innerText = htm;
+
+		// Hide them again (tabs in MSIE)
+		for (i=0; i<nl.length; i++) {
+			if (nl[i].type == 'style')
+				nl[i].elm.style.display = 'none';
+			else
+				nl[i].elm.className = s.hidden_tab_class;
+		}
+	}
+
+	};
+
+/* file:jscripts/tiny_mce/classes/TinyMCE_Cleanup.class.js */
+
+TinyMCE_Engine.prototype.cleanupHTMLCode = function(s) {
+	s = s.replace(new RegExp('<p \\/>', 'gi'), '<p>&nbsp;</p>');
+	s = s.replace(new RegExp('<p>\\s*<\\/p>', 'gi'), '<p>&nbsp;</p>');
+
+	// Fix close BR elements
+	s = s.replace(new RegExp('<br>\\s*<\\/br>', 'gi'), '<br />');
+
+	// Open closed tags like <b/> to <b></b>
+	s = s.replace(new RegExp('<(h[1-6]|p|div|address|pre|form|table|li|ol|ul|td|b|font|em|strong|i|strike|u|span|a|ul|ol|li|blockquote)([a-z]*)([^\\\\|>]*)\\/>', 'gi'), '<$1$2$3></$1$2>');
+
+	// Remove trailing space <b > to <b>
+	s = s.replace(new RegExp('\\s+></', 'gi'), '></');
+
+	// Close tags <img></img> to <img/>
+	s = s.replace(new RegExp('<(img|br|hr)([^>]*)><\\/(img|br|hr)>', 'gi'), '<$1$2 />');
+
+	// Weird MSIE bug, <p><hr /></p> breaks runtime?
+	if (tinyMCE.isIE)
+		s = s.replace(new RegExp('<p><hr \\/><\\/p>', 'gi'), "<hr>");
+
+	// Weird tags will make IE error #bug: 1538495
+	if (tinyMCE.isIE)
+		s = s.replace(/<!(\s*)\/>/g, '');
+
+	// Convert relative anchors to absolute URLs ex: #something to file.htm#something
+	// Removed: Since local document anchors should never be forced absolute example edit.php?id=something
+	//if (tinyMCE.getParam('convert_urls'))
+	//	s = s.replace(new RegExp('(href=\"{0,1})(\\s*#)', 'gi'), '$1' + tinyMCE.settings['document_base_url'] + "#");
+
+	return s;
+};
+
+TinyMCE_Engine.prototype.parseStyle = function(str) {
+	var ar = new Array();
+
+	if (str == null)
+		return ar;
+
+	var st = str.split(';');
+
+	tinyMCE.clearArray(ar);
+
+	for (var i=0; i<st.length; i++) {
+		if (st[i] == '')
+			continue;
+
+		var re = new RegExp('^\\s*([^:]*):\\s*(.*)\\s*$');
+		var pa = st[i].replace(re, '$1||$2').split('||');
+//tinyMCE.debug(str, pa[0] + "=" + pa[1], st[i].replace(re, '$1||$2'));
+		if (pa.length == 2)
+			ar[pa[0].toLowerCase()] = pa[1];
+	}
+
+	return ar;
+};
+
+TinyMCE_Engine.prototype.compressStyle = function(ar, pr, sf, res) {
+	var box = new Array();
+
+	box[0] = ar[pr + '-top' + sf];
+	box[1] = ar[pr + '-left' + sf];
+	box[2] = ar[pr + '-right' + sf];
+	box[3] = ar[pr + '-bottom' + sf];
+
+	for (var i=0; i<box.length; i++) {
+		if (box[i] == null)
+			return;
+
+		for (var a=0; a<box.length; a++) {
+			if (box[a] != box[i])
+				return;
+		}
+	}
+
+	// They are all the same
+	ar[res] = box[0];
+	ar[pr + '-top' + sf] = null;
+	ar[pr + '-left' + sf] = null;
+	ar[pr + '-right' + sf] = null;
+	ar[pr + '-bottom' + sf] = null;
+};
+
+TinyMCE_Engine.prototype.serializeStyle = function(ar) {
+	var str = "";
+
+	// Compress box
+	tinyMCE.compressStyle(ar, "border", "", "border");
+	tinyMCE.compressStyle(ar, "border", "-width", "border-width");
+	tinyMCE.compressStyle(ar, "border", "-color", "border-color");
+	tinyMCE.compressStyle(ar, "border", "-style", "border-style");
+	tinyMCE.compressStyle(ar, "padding", "", "padding");
+	tinyMCE.compressStyle(ar, "margin", "", "margin");
+
+	for (var key in ar) {
+		var val = ar[key];
+
+		if (typeof(val) == 'function')
+			continue;
+
+		if (key.indexOf('mso-') == 0)
+			continue;
+
+		if (val != null && val != '') {
+			val = '' + val; // Force string
+
+			// Fix style URL
+			val = val.replace(new RegExp("url\\(\\'?([^\\']*)\\'?\\)", 'gi'), "url('$1')");
+
+			// Convert URL
+			if (val.indexOf('url(') != -1 && tinyMCE.getParam('convert_urls')) {
+				var m = new RegExp("url\\('(.*?)'\\)").exec(val);
+
+				if (m.length > 1)
+					val = "url('" + eval(tinyMCE.getParam('urlconverter_callback') + "(m[1], null, true);") + "')";
+			}
+
+			// Force HEX colors
+			if (tinyMCE.getParam("force_hex_style_colors"))
+				val = tinyMCE.convertRGBToHex(val, true);
+
+			val = val.replace(/\"/g, '\'');
+
+			if (val != "url('')")
+				str += key.toLowerCase() + ": " + val + "; ";
+		}
+	}
+
+	if (new RegExp('; $').test(str))
+		str = str.substring(0, str.length - 2);
+
+	return str;
+};
+
+TinyMCE_Engine.prototype.convertRGBToHex = function(s, k) {
+	if (s.toLowerCase().indexOf('rgb') != -1) {
+		var re = new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)", "gi");
+		var rgb = s.replace(re, "$1,$2,$3,$4,$5").split(',');
+		if (rgb.length == 5) {
+			r = parseInt(rgb[1]).toString(16);
+			g = parseInt(rgb[2]).toString(16);
+			b = parseInt(rgb[3]).toString(16);
+
+			r = r.length == 1 ? '0' + r : r;
+			g = g.length == 1 ? '0' + g : g;
+			b = b.length == 1 ? '0' + b : b;
+
+			s = "#" + r + g + b;
+
+			if (k)
+				s = rgb[0] + s + rgb[4];
+		}
+	}
+
+	return s;
+};
+
+TinyMCE_Engine.prototype.convertHexToRGB = function(s) {
+	if (s.indexOf('#') != -1) {
+		s = s.replace(new RegExp('[^0-9A-F]', 'gi'), '');
+		return "rgb(" + parseInt(s.substring(0, 2), 16) + "," + parseInt(s.substring(2, 4), 16) + "," + parseInt(s.substring(4, 6), 16) + ")";
+	}
+
+	return s;
+};
+
+TinyMCE_Engine.prototype.convertSpansToFonts = function(doc) {
+	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
+
+	/*var h = doc.body.innerHTML;
+	h = h.replace(/<span/gi, '<font');
+	h = h.replace(/<\/span/gi, '</font');
+	tinyMCE.setInnerHTML(doc.body, h);*/
+
+	var s = tinyMCE.selectElements(doc, 'span,font');
+	for (var i=0; i<s.length; i++) {
+		var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
+		var fSize = 0;
+
+		for (var x=0; x<sizes.length; x++) {
+			if (sizes[x] == size) {
+				fSize = x + 1;
+				break;
+			}
+		}
+
+		if (fSize > 0) {
+			tinyMCE.setAttrib(s[i], 'size', fSize);
+			s[i].style.fontSize = '';
+		}
+
+		var fFace = s[i].style.fontFamily;
+		if (fFace != null && fFace != "") {
+			tinyMCE.setAttrib(s[i], 'face', fFace);
+			s[i].style.fontFamily = '';
+		}
+
+		var fColor = s[i].style.color;
+		if (fColor != null && fColor != "") {
+			tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
+			s[i].style.color = '';
+		}
+	}
+};
+
+TinyMCE_Engine.prototype.convertFontsToSpans = function(doc) {
+	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
+
+/*	var h = doc.body.innerHTML;
+	h = h.replace(/<font/gi, '<span');
+	h = h.replace(/<\/font/gi, '</span');
+	tinyMCE.setInnerHTML(doc.body, h);*/
+
+	var fsClasses = tinyMCE.getParam('font_size_classes');
+	if (fsClasses != '')
+		fsClasses = fsClasses.replace(/\s+/, '').split(',');
+	else
+		fsClasses = null;
+
+	var s = tinyMCE.selectElements(doc, 'span,font');
+	for (var i=0; i<s.length; i++) {
+		var fSize, fFace, fColor;
+
+		fSize = tinyMCE.getAttrib(s[i], 'size');
+		fFace = tinyMCE.getAttrib(s[i], 'face');
+		fColor = tinyMCE.getAttrib(s[i], 'color');
+
+		if (fSize != "") {
+			fSize = parseInt(fSize);
+
+			if (fSize > 0 && fSize < 8) {
+				if (fsClasses != null)
+					tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
+				else
+					s[i].style.fontSize = sizes[fSize-1];
+			}
+
+			s[i].removeAttribute('size');
+		}
+
+		if (fFace != "") {
+			s[i].style.fontFamily = fFace;
+			s[i].removeAttribute('face');
+		}
+
+		if (fColor != "") {
+			s[i].style.color = fColor;
+			s[i].removeAttribute('color');
+		}
+	}
+};
+
+TinyMCE_Engine.prototype.cleanupAnchors = function(doc) {
+	var i, cn, x, an = doc.getElementsByTagName("a");
+
+	// Loops backwards due to bug #1467987
+	for (i=an.length-1; i>=0; i--) {
+		if (tinyMCE.getAttrib(an[i], "name") != "" && tinyMCE.getAttrib(an[i], "href") == "") {
+			cn = an[i].childNodes;
+
+			for (x=cn.length-1; x>=0; x--)
+				tinyMCE.insertAfter(cn[x], an[i]);
+		}
+	}
+};
+
+TinyMCE_Engine.prototype.getContent = function(editor_id) {
+	if (typeof(editor_id) != "undefined")
+		 tinyMCE.getInstanceById(editor_id).select();
+
+	if (tinyMCE.selectedInstance)
+		return tinyMCE.selectedInstance.getHTML();
+
+	return null;
+};
+
+TinyMCE_Engine.prototype._fixListElements = function(d) {
+	var nl, x, a = ['ol', 'ul'], i, n, p, r = new RegExp('^(OL|UL)$'), np;
+
+	for (x=0; x<a.length; x++) {
+		nl = d.getElementsByTagName(a[x]);
+
+		for (i=0; i<nl.length; i++) {
+			n = nl[i];
+			p = n.parentNode;
+
+			if (r.test(p.nodeName)) {
+				np = tinyMCE.prevNode(n, 'LI');
+
+				if (!np) {
+					np = d.createElement('li');
+					np.innerHTML = '&nbsp;';
+					np.appendChild(n);
+					p.insertBefore(np, p.firstChild);
+				} else
+					np.appendChild(n);
+			}
+		}
+	}
+};
+
+TinyMCE_Engine.prototype._fixTables = function(d) {
+	var nl, i, n, p, np, x, t;
+
+	nl = d.getElementsByTagName('table');
+	for (i=0; i<nl.length; i++) {
+		n = nl[i];
+
+		if ((p = tinyMCE.getParentElement(n, 'p,h1,h2,h3,h4,h5,h6')) != null) {
+			np = p.cloneNode(false);
+			np.removeAttribute('id');
+
+			t = n;
+
+			while ((n = n.nextSibling))
+				np.appendChild(n);
+
+			tinyMCE.insertAfter(np, p);
+			tinyMCE.insertAfter(t, p);
+		}
+	}
+};
+
+TinyMCE_Engine.prototype._cleanupHTML = function(inst, doc, config, elm, visual, on_save, on_submit, inn) {
+	var h, d, t1, t2, t3, t4, t5, c, s, nb;
+
+	if (!tinyMCE.getParam('cleanup'))
+		return elm.innerHTML;
+
+	on_save = typeof(on_save) == 'undefined' ? false : on_save;
+
+	c = inst.cleanup;
+	s = inst.settings;
+	d = c.settings.debug;
+
+	if (d)
+		t1 = new Date().getTime();
+
+	if (tinyMCE.getParam("convert_fonts_to_spans"))
+		tinyMCE.convertFontsToSpans(doc);
+
+	if (tinyMCE.getParam("fix_list_elements"))
+		tinyMCE._fixListElements(doc);
+
+	if (tinyMCE.getParam("fix_table_elements"))
+		tinyMCE._fixTables(doc);
+
+	// Call custom cleanup code
+	tinyMCE._customCleanup(inst, on_save ? "get_from_editor_dom" : "insert_to_editor_dom", doc.body);
+
+	if (d)
+		t2 = new Date().getTime();
+
+	c.settings.on_save = on_save;
+	//for (var i=0; i<100; i++)
+
+	c.idCount = 0;
+	c.serializationId++;
+	c.serializedNodes = new Array();
+	c.sourceIndex = -1;
+
+	if (s.cleanup_serializer == "xml")
+		h = c.serializeNodeAsXML(elm, inn);
+	else
+		h = c.serializeNodeAsHTML(elm, inn);
+
+	if (d)
+		t3 = new Date().getTime();
+
+	// Post processing
+	nb = tinyMCE.getParam('entity_encoding') == 'numeric' ? '&#160;' : '&nbsp;';
+	h = h.replace(/<\/?(body|head|html)[^>]*>/gi, '');
+	h = h.replace(new RegExp(' (rowspan="1"|colspan="1")', 'g'), '');
+	h = h.replace(/<p><hr \/><\/p>/g, '<hr />');
+	h = h.replace(/<p>(&nbsp;|&#160;)<\/p><hr \/><p>(&nbsp;|&#160;)<\/p>/g, '<hr />');
+	h = h.replace(/<td>\s*<br \/>\s*<\/td>/g, '<td>' + nb + '</td>');
+	h = h.replace(/<p>\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
+	h = h.replace(/<br \/>$/, ''); // Remove last BR for Gecko
+	h = h.replace(/<br \/><\/p>/g, '</p>'); // Remove last BR in P tags for Gecko
+	h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*(&nbsp;|&#160;)\s*<\/p>/g, '<p>' + nb + '</p>');
+	h = h.replace(/<p>\s*(&nbsp;|&#160;)\s*<br \/>\s*<\/p>/g, '<p>' + nb + '</p>');
+	h = h.replace(/<p>\s*<br \/>\s*&nbsp;\s*<\/p>/g, '<p>' + nb + '</p>');
+	h = h.replace(new RegExp('<a>(.*?)<\\/a>', 'g'), '$1');
+	h = h.replace(/<p([^>]*)>\s*<\/p>/g, '<p$1>' + nb + '</p>');
+
+	// Clean body
+	if (/^\s*(<br \/>|<p>&nbsp;<\/p>|<p>&#160;<\/p>|<p><\/p>)\s*$/.test(h))
+		h = '';
+
+	// If preformatted
+	if (s.preformatted) {
+		h = h.replace(/^<pre>/, '');
+		h = h.replace(/<\/pre>$/, '');
+		h = '<pre>' + h + '</pre>';
+	}
+
+	// Gecko specific processing
+	if (tinyMCE.isGecko) {
+		h = h.replace(/<o:p _moz-userdefined="" \/>/g, '');
+		h = h.replace(/<td([^>]*)>\s*<br \/>\s*<\/td>/g, '<td$1>' + nb + '</td>');
+	}
+
+	if (s.force_br_newlines)
+		h = h.replace(/<p>(&nbsp;|&#160;)<\/p>/g, '<br />');
+
+	// Call custom cleanup code
+	h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
+
+	// Remove internal classes
+	if (on_save) {
+		h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
+		h = h.replace(new RegExp(' ?class=""', 'g'), '');
+	}
+
+	if (s.remove_linebreaks && !c.settings.indent)
+		h = h.replace(/\n|\r/g, ' ');
+
+	if (d)
+		t4 = new Date().getTime();
+
+	if (on_save && c.settings.indent)
+		h = c.formatHTML(h);
+
+	// If encoding (not recommended option)
+	if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
+		h = c.xmlEncode(h);
+
+	if (d)
+		t5 = new Date().getTime();
+
+	if (c.settings.debug)
+		tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
+
+	return h;
+};
+
+function TinyMCE_Cleanup() {
+	this.isIE = (navigator.appName == "Microsoft Internet Explorer");
+	this.rules = tinyMCE.clearArray(new Array());
+
+	// Default config
+	this.settings = {
+		indent_elements : 'head,table,tbody,thead,tfoot,form,tr,ul,ol,blockquote,object',
+		newline_before_elements : 'h1,h2,h3,h4,h5,h6,pre,address,div,ul,ol,li,meta,option,area,title,link,base,script,td',
+		newline_after_elements : 'br,hr,p,pre,address,div,ul,ol,meta,option,area,link,base,script',
+		newline_before_after_elements : 'html,head,body,table,thead,tbody,tfoot,tr,form,ul,ol,blockquote,p,object,param,hr,div',
+		indent_char : '\t',
+		indent_levels : 1,
+		entity_encoding : 'raw',
+		valid_elements : '*[*]',
+		entities : '',
+		url_converter : '',
+		invalid_elements : '',
+		verify_html : false
+	};
+
+	this.vElements = tinyMCE.clearArray(new Array());
+	this.vElementsRe = '';
+	this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/;
+	this.codeElementsRe = /^(SCRIPT|STYLE)$/;
+	this.serializationId = 0;
+	this.mceAttribs = {
+		href : 'mce_href',
+		src : 'mce_src',
+		type : 'mce_type'
+	};
+}
+
+TinyMCE_Cleanup.prototype = {
+	init : function(s) {
+		var n, a, i, ir, or, st;
+
+		for (n in s)
+			this.settings[n] = s[n];
+
+		// Setup code formating
+		s = this.settings;
+
+		// Setup regexps
+		this.inRe = this._arrayToRe(s.indent_elements.split(','), '', '^<(', ')[^>]*');
+		this.ouRe = this._arrayToRe(s.indent_elements.split(','), '', '^<\\/(', ')[^>]*');
+		this.nlBeforeRe = this._arrayToRe(s.newline_before_elements.split(','), 'gi', '<(',  ')([^>]*)>');
+		this.nlAfterRe = this._arrayToRe(s.newline_after_elements.split(','), 'gi', '<(',  ')([^>]*)>');
+		this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>');
+		this.serializedNodes = [];
+
+		if (s.invalid_elements != '')
+			this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$');
+		else
+			this.iveRe = null;
+
+		// Setup separator
+		st = '';
+		for (i=0; i<s.indent_levels; i++)
+			st += s.indent_char;
+
+		this.inStr = st;
+
+		// If verify_html if false force *[*]
+		if (!s.verify_html) {
+			s.valid_elements = '*[*]';
+			s.extended_valid_elements = '';
+		}
+
+		this.fillStr = s.entity_encoding == "named" ? "&nbsp;" : "&#160;";
+		this.idCount = 0;
+		this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g');
+		this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g');
+	},
+
+	addRuleStr : function(s) {
+		var r = this.parseRuleStr(s);
+		var n;
+
+		for (n in r) {
+			if (r[n])
+				this.rules[n] = r[n];
+		}
+
+		this.vElements = tinyMCE.clearArray(new Array());
+
+		for (n in this.rules) {
+			if (this.rules[n])
+				this.vElements[this.vElements.length] = this.rules[n].tag;
+		}
+
+		this.vElementsRe = this._arrayToRe(this.vElements, '');
+	},
+
+	isValid : function(n) {
+		this._setupRules(); // Will initialize cleanup rules
+
+		// Empty is true since it removes formatting
+		if (!n)
+			return true;
+
+		// Clean the name up a bit
+		n = n.replace(/[^a-z0-9]+/gi, '').toUpperCase();
+
+		return !tinyMCE.getParam('cleanup') || this.vElementsRe.test(n);
+	},
+
+	addChildRemoveRuleStr : function(s) {
+		var x, y, p, i, t, tn, ta, cl, r;
+
+		if (!s)
+			return;
+
+		ta = s.split(',');
+		for (x=0; x<ta.length; x++) {
+			s = ta[x];
+
+			// Split tag/children
+			p = this.split(/\[|\]/, s);
+			if (p == null || p.length < 1)
+				t = s.toUpperCase();
+			else
+				t = p[0].toUpperCase();
+
+			// Handle all tag names
+			tn = this.split('/', t);
+			for (y=0; y<tn.length; y++) {
+				r = "^(";
+
+				// Build regex
+				cl = this.split(/\|/, p[1]);
+				for (i=0; i<cl.length; i++) {
+					if (cl[i] == '%istrict')
+						r += tinyMCE.inlineStrict;
+					else if (cl[i] == '%itrans')
+						r += tinyMCE.inlineTransitional;
+					else if (cl[i] == '%istrict_na')
+						r += tinyMCE.inlineStrict.substring(2);
+					else if (cl[i] == '%itrans_na')
+						r += tinyMCE.inlineTransitional.substring(2);
+					else if (cl[i] == '%btrans')
+						r += tinyMCE.blockElms;
+					else if (cl[i] == '%strict')
+						r += tinyMCE.blockStrict;
+					else
+						r += (cl[i].charAt(0) != '#' ? cl[i].toUpperCase() : cl[i]);
+
+					r += (i != cl.length - 1 ? '|' : '');
+				}
 
-	for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)
-		outPath += "../";
+				r += ')$';
+//tinyMCE.debug(t + "=" + r);
+				if (this.childRules == null)
+					this.childRules = tinyMCE.clearArray(new Array());
 
-	for (var i=breakPoint-1; i<strTok2.length; i++) {
-		if (i != (breakPoint-1))
-			outPath += "/" + strTok2[i];
+				this.childRules[tn[y]] = new RegExp(r);
+
+				if (p.length > 1)
+					this.childRules[tn[y]].wrapTag = p[2];
+			}
+		}
+	},
+
+	parseRuleStr : function(s) {
+		var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv;
+
+		if (s == null || s.length == 0)
+			return or;
+
+		ta = s.split(',');
+		for (x=0; x<ta.length; x++) {
+			s = ta[x];
+			if (s.length == 0)
+				continue;
+
+			// Split tag/attrs
+			p = this.split(/\[|\]/, s);
+			if (p == null || p.length < 1)
+				t = s.toUpperCase();
+			else
+				t = p[0].toUpperCase();
+
+			// Handle all tag names
+			tn = this.split('/', t);
+			for (y=0; y<tn.length; y++) {
+				r = {};
+
+				r.tag = tn[y];
+				r.forceAttribs = null;
+				r.defaultAttribs = null;
+				r.validAttribValues = null;
+
+				// Handle prefixes
+				px = r.tag.charAt(0);
+				r.forceOpen = px == '+';
+				r.removeEmpty = px == '-';
+				r.fill = px == '#';
+				r.tag = r.tag.replace(/\+|-|#/g, '');
+				r.oTagName = tn[0].replace(/\+|-|#/g, '').toLowerCase();
+				r.isWild = new RegExp('\\*|\\?|\\+', 'g').test(r.tag);
+				r.validRe = new RegExp(this._wildcardToRe('^' + r.tag + '$'));
+
+				// Setup valid attributes
+				if (p.length > 1) {
+					r.vAttribsRe = '^(';
+					a = this.split(/\|/, p[1]);
+
+					for (i=0; i<a.length; i++) {
+						t = a[i];
+
+						if (t.charAt(0) == '!') {
+							a[i] = t = t.substring(1);
+
+							if (!r.reqAttribsRe)
+								r.reqAttribsRe = '\\s+(' + t;
+							else
+								r.reqAttribsRe += '|' + t;
+						}
+
+						av = new RegExp('(=|:|<)(.*?)$').exec(t);
+						t = t.replace(new RegExp('(=|:|<).*?$'), '');
+						if (av && av.length > 0) {
+							if (av[0].charAt(0) == ':') {
+								if (!r.forceAttribs)
+									r.forceAttribs = tinyMCE.clearArray(new Array());
+
+								r.forceAttribs[t.toLowerCase()] = av[0].substring(1);
+							} else if (av[0].charAt(0) == '=') {
+								if (!r.defaultAttribs)
+									r.defaultAttribs = tinyMCE.clearArray(new Array());
+
+								dv = av[0].substring(1);
+
+								r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv;
+							} else if (av[0].charAt(0) == '<') {
+								if (!r.validAttribValues)
+									r.validAttribValues = tinyMCE.clearArray(new Array());
+
+								r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i');
+							}
+						}
+
+						r.vAttribsRe += '' + t.toLowerCase() + (i != a.length - 1 ? '|' : '');
+
+						a[i] = t.toLowerCase();
+					}
+
+					if (r.reqAttribsRe)
+						r.reqAttribsRe = new RegExp(r.reqAttribsRe + ')=\"', 'g');
+
+					r.vAttribsRe += ')$';
+					r.vAttribsRe = this._wildcardToRe(r.vAttribsRe);
+					r.vAttribsReIsWild = new RegExp('\\*|\\?|\\+', 'g').test(r.vAttribsRe);
+					r.vAttribsRe = new RegExp(r.vAttribsRe);
+					r.vAttribs = a.reverse();
+
+					//tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC);
+				} else {
+					r.vAttribsRe = '';
+					r.vAttribs = tinyMCE.clearArray(new Array());
+					r.vAttribsReIsWild = false;
+				}
+
+				or[r.tag] = r;
+			}
+		}
+
+		return or;
+	},
+
+	serializeNodeAsXML : function(n) {
+		var s, b;
+
+		if (!this.xmlDoc) {
+			if (this.isIE) {
+				try {this.xmlDoc = new ActiveXObject('MSXML2.DOMDocument');} catch (e) {}
+
+				if (!this.xmlDoc)
+					try {this.xmlDoc = new ActiveXObject('Microsoft.XmlDom');} catch (e) {}
+			} else
+				this.xmlDoc = document.implementation.createDocument('', '', null);
+
+			if (!this.xmlDoc)
+				alert("Error XML Parser could not be found.");
+		}
+
+		if (this.xmlDoc.firstChild)
+			this.xmlDoc.removeChild(this.xmlDoc.firstChild);
+
+		b = this.xmlDoc.createElement("html");
+		b = this.xmlDoc.appendChild(b);
+
+		this._convertToXML(n, b);
+
+		if (this.isIE)
+			return this.xmlDoc.xml;
 		else
-			outPath += strTok2[i];
-	}
+			return new XMLSerializer().serializeToString(this.xmlDoc);
+	},
 
-	targetURL.protocol = null;
-	targetURL.host = null;
-	targetURL.port = null;
-	targetURL.path = outPath == "" && forceSlash ? "/" : outPath;
+	_convertToXML : function(n, xn) {
+		var xd, el, i, l, cn, at, no, hc = false;
 
-	// Remove document prefix from local anchors
-	var fileName = baseURL.path;
-	var pos;
+		if (tinyMCE.isRealIE && this._isDuplicate(n))
+			return;
 
-	if ((pos = fileName.lastIndexOf('/')) != -1)
-		fileName = fileName.substring(pos + 1);
+		xd = this.xmlDoc;
 
-	// Is local anchor
-	if (fileName == targetURL.path && targetURL.anchor != "")
-		targetURL.path = "";
+		switch (n.nodeType) {
+			case 1: // Element
+				hc = n.hasChildNodes();
 
-	return this.serializeURL(targetURL);
-};
+				el = xd.createElement(n.nodeName.toLowerCase());
 
-TinyMCE.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
-	var baseURL = TinyMCE.prototype.parseURL(base_url);
-	var relURL = TinyMCE.prototype.parseURL(relative_url);
+				at = n.attributes;
+				for (i=at.length-1; i>-1; i--) {
+					no = at[i];
 
-	if (relative_url == "" || relative_url.charAt(0) == '/' || relative_url.indexOf('://') != -1 || relative_url.indexOf('mailto:') != -1 || relative_url.indexOf('javascript:') != -1)
-		return relative_url;
+					if (no.specified && no.nodeValue)
+						el.setAttribute(no.nodeName.toLowerCase(), no.nodeValue);
+				}
 
-	// Split parts
-	baseURLParts = baseURL['path'].split('/');
-	relURLParts = relURL['path'].split('/');
+				if (!hc && !this.closeElementsRe.test(n.nodeName))
+					el.appendChild(xd.createTextNode(""));
 
-	// Remove empty chunks
-	var newBaseURLParts = new Array();
-	for (var i=baseURLParts.length-1; i>=0; i--) {
-		if (baseURLParts[i].length == 0)
-			continue;
+				xn = xn.appendChild(el);
+				break;
 
-		newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
-	}
-	baseURLParts = newBaseURLParts.reverse();
+			case 3: // Text
+				xn.appendChild(xd.createTextNode(n.nodeValue));
+				return;
 
-	// Merge relURLParts chunks
-	var newRelURLParts = new Array();
-	var numBack = 0;
-	for (var i=relURLParts.length-1; i>=0; i--) {
-		if (relURLParts[i].length == 0 || relURLParts[i] == ".")
-			continue;
+			case 8: // Comment
+				xn.appendChild(xd.createComment(n.nodeValue));
+				return;
+		}
 
-		if (relURLParts[i] == '..') {
-			numBack++;
-			continue;
+		if (hc) {
+			cn = n.childNodes;
+
+			for (i=0, l=cn.length; i<l; i++)
+				this._convertToXML(cn[i], xn);
 		}
+	},
 
-		if (numBack > 0) {
-			numBack--;
-			continue;
+	serializeNodeAsHTML : function(n, inn) {
+		var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn;
+
+		this._setupRules(); // Will initialize cleanup rules
+
+		if (tinyMCE.isRealIE && this._isDuplicate(n))
+			return '';
+
+		// Skip non valid child elements
+		if (n.parentNode && this.childRules != null) {
+			cr = this.childRules[n.parentNode.nodeName];
+
+			if (typeof(cr) != "undefined" && !cr.test(n.nodeName)) {
+				st = true;
+				t = null;
+			}
 		}
 
-		newRelURLParts[newRelURLParts.length] = relURLParts[i];
-	}
+		switch (n.nodeType) {
+			case 1: // Element
+				hc = n.hasChildNodes();
 
-	relURLParts = newRelURLParts.reverse();
+				if (st)
+					break;
 
-	// Remove end from absolute path
-	var len = baseURLParts.length-numBack;
-	var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
-	var start = "", end = "";
+				// MSIE sometimes produces <//tag>
+				if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1)
+					break;
 
-	// Build output URL
-	relURL.protocol = baseURL.protocol;
-	relURL.host = baseURL.host;
-	relURL.port = baseURL.port;
+				nn = n.nodeName;
 
-	// Re-add trailing slash if it's removed
-	if (relURL.path.charAt(relURL.path.length-1) == "/")
-		absPath += "/";
+				// Convert fonts to spans
+				if (this.settings.convert_fonts_to_spans) {
+					// On get content FONT -> SPAN
+					if (this.settings.on_save && nn == 'FONT')
+						nn = 'SPAN';
+
+					// On insert content SPAN -> FONT
+					if (!this.settings.on_save && nn == 'SPAN')
+						nn = 'FONT';
+				}
+
+				if (this.vElementsRe.test(nn) && (!this.iveRe || !this.iveRe.test(nn)) && !inn) {
+					va = true;
+
+					r = this.rules[nn];
+					if (!r) {
+						at = this.rules;
+						for (no in at) {
+							if (at[no] && at[no].validRe.test(nn)) {
+								r = at[no];
+								break;
+							}
+						}
+					}
 
-	relURL.path = absPath;
+					en = r.isWild ? nn.toLowerCase() : r.oTagName;
+					f = r.fill;
 
-	return TinyMCE.prototype.serializeURL(relURL);
-};
+					if (r.removeEmpty && !hc)
+						return "";
+
+					t = '<' + en;
+
+					if (r.vAttribsReIsWild) {
+						// Serialize wildcard attributes
+						at = n.attributes;
+						for (i=at.length-1; i>-1; i--) {
+							no = at[i];
+							if (no.specified && r.vAttribsRe.test(no.nodeName))
+								t += this._serializeAttribute(n, r, no.nodeName);
+						}
+					} else {
+						// Serialize specific attributes
+						for (i=r.vAttribs.length-1; i>-1; i--)
+							t += this._serializeAttribute(n, r, r.vAttribs[i]);
+					}
+
+					// Serialize mce_ atts
+					if (!this.settings.on_save) {
+						at = this.mceAttribs;
+
+						for (no in at) {
+							if (at[no])
+								t += this._serializeAttribute(n, r, at[no]);
+						}
+					}
+
+					// Check for required attribs
+					if (r.reqAttribsRe && !t.match(r.reqAttribsRe))
+						t = null;
+
+					// Close these
+					if (t != null && this.closeElementsRe.test(nn))
+						return t + ' />';
+
+					if (t != null)
+						h += t + '>';
+
+					if (this.isIE && this.codeElementsRe.test(nn))
+						h += n.innerHTML;
+				}
+			break;
 
-TinyMCE.prototype.getParam = function(name, default_value, strip_whitespace, split_chr) {
-	var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
+			case 3: // Text
+				if (st)
+					break;
 
-	// Fix bool values
-	if (value == "true" || value == "false")
-		return (value == "true");
+				if (n.parentNode && this.codeElementsRe.test(n.parentNode.nodeName))
+					return this.isIE ? '' : n.nodeValue;
 
-	if (strip_whitespace)
-		value = tinyMCE.regexpReplace(value, "[ \t\r\n]", "");
+				return this.xmlEncode(n.nodeValue);
 
-	if (typeof(split_chr) != "undefined" && split_chr != null) {
-		value = value.split(split_chr);
-		var outArray = new Array();
+			case 8: // Comment
+				if (st)
+					break;
 
-		for (var i=0; i<value.length; i++) {
-			if (value[i] && value[i] != "")
-				outArray[outArray.length] = value[i];
+				return "<!--" + this._trimComment(n.nodeValue) + "-->";
 		}
 
-		value = outArray;
-	}
+		if (hc) {
+			cn = n.childNodes;
 
-	return value;
-};
+			for (i=0, l=cn.length; i<l; i++)
+				h += this.serializeNodeAsHTML(cn[i]);
+		}
 
-TinyMCE.prototype.getLang = function(name, default_value, parse_entities) {
-	var value = (typeof(tinyMCELang[name]) == "undefined") ? default_value : tinyMCELang[name];
+		// Fill empty nodes
+		if (f && !hc)
+			h += this.fillStr;
 
-	if (parse_entities)
-		value = tinyMCE.entityDecode(value);
+		// End element
+		if (t != null && va)
+			h += '</' + en + '>';
 
-	return value;
-};
+		return h;
+	},
 
-TinyMCE.prototype.entityDecode = function(s) {
-	var e = document.createElement("div");
-	e.innerHTML = s;
-	return e.innerHTML;
-};
+	_serializeAttribute : function(n, r, an) {
+		var av = '', t, os = this.settings.on_save;
 
-TinyMCE.prototype.addToLang = function(prefix, ar) {
-	for (var key in ar) {
-		if (typeof(ar[key]) == 'function')
-			continue;
+		if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0))
+			return '';
 
-		tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = ar[key];
-	}
+		if (os && this.mceAttribs[an])
+			av = this._getAttrib(n, this.mceAttribs[an]);
 
-//	for (var key in ar)
-//		tinyMCELang[(key.indexOf('lang_') == -1 ? 'lang_' : '') + (prefix != '' ? (prefix + "_") : '') + key] = "|" + ar[key] + "|";
-};
+		if (av.length == 0)
+			av = this._getAttrib(n, an);
 
-TinyMCE.prototype.replaceVar = function(replace_haystack, replace_var, replace_str) {
-	var re = new RegExp('{\\\$' + replace_var + '}', 'g');
-	return replace_haystack.replace(re, replace_str);
-};
+		if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) {
+			av = t;
 
-TinyMCE.prototype.replaceVars = function(replace_haystack, replace_vars) {
-	for (var key in replace_vars) {
-		var value = replace_vars[key];
-		if (typeof(value) == 'function')
-			continue;
+			if (av == "mce_empty")
+				return " " + an + '=""';
+		}
 
-		replace_haystack = tinyMCE.replaceVar(replace_haystack, key, value);
-	}
+		if (r.forceAttribs && (t = r.forceAttribs[an]))
+			av = t;
 
-	return replace_haystack;
-};
+		if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an))
+			av = this._urlConverter(this, n, av);
 
-TinyMCE.prototype.triggerNodeChange = function(focus, setup_content) {
-	if (tinyMCE.settings['handleNodeChangeCallback']) {
-		if (tinyMCE.selectedInstance) {
-			var inst = tinyMCE.selectedInstance;
-			var editorId = inst.editorId;
-			var elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();
-			var undoIndex = -1;
-			var undoLevels = -1;
-			var anySelection = false;
-			var selectedText = inst.getSelectedText();
+		if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av))
+			return "";
 
-			inst.switchSettings();
+		if (av.length != 0 && av == "{$uid}")
+			av = "uid_" + (this.idCount++);
 
-			if (tinyMCE.settings["auto_resize"]) {
-				var doc = inst.getDoc();
+		if (av.length != 0) {
+			if (an.indexOf('on') != 0)
+				av = this.xmlEncode(av, 1);
 
-				inst.iframeElement.style.width = doc.body.offsetWidth + "px";
-				inst.iframeElement.style.height = doc.body.offsetHeight + "px";
-			}
+			return " " + an + "=" + '"' + av + '"';
+		}
 
-			if (tinyMCE.selectedElement)
-				anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (selectedText && selectedText.length > 0);
+		return "";
+	},
 
-			if (tinyMCE.settings['custom_undo_redo']) {
-				undoIndex = inst.undoIndex;
-				undoLevels = inst.undoLevels.length;
+	formatHTML : function(h) {
+		var s = this.settings, p = '', i = 0, li = 0, o = '', l;
+
+		// Replace BR in pre elements to \n
+		h = h.replace(/<pre([^>]*)>(.*?)<\/pre>/gi, function (a, b, c) {
+			c = c.replace(/<br\s*\/>/gi, '\n');
+			return '<pre' + b + '>' + c + '</pre>';
+		});
+
+		h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :)
+		h = '\n' + h;
+		h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting
+		h = h.replace(this.nlBeforeRe, '\n<$1$2>');
+		h = h.replace(this.nlAfterRe, '<$1$2>\n');
+		h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n');
+		h += '\n';
+
+		//tinyMCE.debug(h);
+
+		while ((i = h.indexOf('\n', i + 1)) != -1) {
+			if ((l = h.substring(li + 1, i)).length != 0) {
+				if (this.ouRe.test(l) && p.length >= s.indent_levels)
+					p = p.substring(s.indent_levels);
+
+				o += p + l + '\n';
+	
+				if (this.inRe.test(l))
+					p += this.inStr;
 			}
 
-			tinyMCE.executeCallback('handleNodeChangeCallback', '_handleNodeChange', 0, editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
+			li = i;
 		}
-	}
 
-	if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
-		this.selectedInstance.contentWindow.focus();
-};
+		//tinyMCE.debug(h);
 
-TinyMCE.prototype._customCleanup = function(inst, type, content) {
-	// Call custom cleanup
-	var customCleanup = tinyMCE.settings['cleanup_callback'];
-	if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined")
-		content = eval(customCleanup + "(type, content, inst);");
+		return o;
+	},
 
-	// Trigger plugin cleanups
-	var plugins = tinyMCE.getParam('plugins', '', true, ',');
-	for (var i=0; i<plugins.length; i++) {
-		if (eval("typeof(TinyMCE_" + plugins[i] +  "_cleanup)") != "undefined")
-			content = eval("TinyMCE_" + plugins[i] +  "_cleanup(type, content, inst);");
-	}
+	xmlEncode : function(s, skip_apos) {
+		var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe;
 
-	return content;
-};
+		this._setupEntities(); // Will intialize lookup table
 
-TinyMCE.prototype.getContent = function(editor_id) {
-	if (typeof(editor_id) != "undefined")
-		tinyMCE.selectedInstance = tinyMCE.getInstanceById(editor_id);
+		switch (this.settings.entity_encoding) {
+			case "raw":
+				return tinyMCE.xmlEncode(s, skip_apos);
 
-	if (tinyMCE.selectedInstance) {
-		var old = this.selectedInstance.getBody().innerHTML;
-		var html = tinyMCE._cleanupHTML(this.selectedInstance, this.selectedInstance.getDoc(), tinyMCE.settings, this.selectedInstance.getBody(), false, true);
-		tinyMCE.setInnerHTML(this.selectedInstance.getBody(), old);
-		return html;
-	}
+			case "named":
+				return s.replace(re, function (c, b) {
+					b = cl.entities[c.charCodeAt(0)];
 
-	return null;
-};
+					return b ? '&' + b + ';' : c;
+				});
 
-TinyMCE.prototype.setContent = function(html_content) {
-	if (tinyMCE.selectedInstance) {
-		tinyMCE.selectedInstance.execCommand('mceSetContent', false, html_content);
-		tinyMCE.selectedInstance.repaint();
-	}
-};
+			case "numeric":
+				return s.replace(re, function (c, b) {
+					return b ? '&#' + c.charCodeAt(0) + ';' : c;
+				});
+		}
 
-TinyMCE.prototype.importThemeLanguagePack = function(name) {
-	if (typeof(name) == "undefined")
-		name = tinyMCE.settings['theme'];
+		return s;
+	},
 
-	tinyMCE.loadScript(tinyMCE.baseURL + '/themes/' + name + '/langs/' + tinyMCE.settings['language'] + '.js');
-};
+	split : function(re, s) {
+		var c = s.split(re);
+		var i, l, o = new Array();
+
+		for (i=0, l=c.length; i<l; i++) {
+			if (c[i] != '')
+				o[i] = c[i];
+		}
 
-TinyMCE.prototype.importPluginLanguagePack = function(name, valid_languages) {
-	var lang = "en";
+		return o;
+	},
 
-	valid_languages = valid_languages.split(',');
-	for (var i=0; i<valid_languages.length; i++) {
-		if (tinyMCE.settings['language'] == valid_languages[i])
-			lang = tinyMCE.settings['language'];
-	}
+	_trimComment : function(s) {
+		// Remove mce_src, mce_href
+		s = s.replace(new RegExp('\\smce_src=\"[^\"]*\"', 'gi'), "");
+		s = s.replace(new RegExp('\\smce_href=\"[^\"]*\"', 'gi'), "");
 
-	tinyMCE.loadScript(tinyMCE.baseURL + '/plugins/' + name + '/langs/' + lang +  '.js');
-};
+		return s;
+	},
 
-/**
- * Adds themeurl, settings and lang to HTML code.
- */
-TinyMCE.prototype.applyTemplate = function(html, args) {
-	html = tinyMCE.replaceVar(html, "themeurl", tinyMCE.themeURL);
+	_getAttrib : function(e, n, d) {
+		var v, ex, nn;
 
-	if (typeof(args) != "undefined")
-		html = tinyMCE.replaceVars(html, args);
+		if (typeof(d) == "undefined")
+			d = "";
 
-	html = tinyMCE.replaceVars(html, tinyMCE.settings);
-	html = tinyMCE.replaceVars(html, tinyMCELang);
+		if (!e || e.nodeType != 1)
+			return d;
 
-	return html;
-};
+		try {
+			v = e.getAttribute(n, 0);
+		} catch (ex) {
+			// IE 7 may cast exception on invalid attributes
+			v = e.getAttribute(n, 2);
+		}
 
-TinyMCE.prototype.openWindow = function(template, args) {
-	var html, width, height, x, y, resizable, scrollbars, url;
+		if (n == "class" && !v)
+			v = e.className;
 
-	args['mce_template_file'] = template['file'];
-	args['mce_width'] = template['width'];
-	args['mce_height'] = template['height'];
-	tinyMCE.windowArgs = args;
+		if (this.isIE) {
+			if (n == "http-equiv")
+				v = e.httpEquiv;
 
-	html = template['html'];
-	if (!(width = parseInt(template['width'])))
-		width = 320;
+			nn = e.nodeName;
 
-	if (!(height = parseInt(template['height'])))
-		height = 200;
+			// Skip the default values that IE returns
+			if (nn == "FORM" && n == "enctype" && v == "application/x-www-form-urlencoded")
+				v = "";
 
-	// Add to height in M$ due to SP2 WHY DON'T YOU GUYS IMPLEMENT innerWidth of windows!!
-	if (tinyMCE.isMSIE)
-		height += 40;
-	else
-		height += 20;
+			if (nn == "INPUT" && n == "size" && v == "20")
+				v = "";
 
-	x = parseInt(screen.width / 2.0) - (width / 2.0);
-	y = parseInt(screen.height / 2.0) - (height / 2.0);
+			if (nn == "INPUT" && n == "maxlength" && v == "2147483647")
+				v = "";
+		}
 
-	resizable = (args && args['resizable']) ? args['resizable'] : "no";
-	scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no";
+		if (n == 'style' && v) {
+			if (!tinyMCE.isOpera)
+				v = e.style.cssText;
 
-	if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1)
-		url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file'];
-	else
-		url = template['file'];
+			v = tinyMCE.serializeStyle(tinyMCE.parseStyle(v));
+		}
 
-	// Replace all args as variables in URL
-	for (var name in args) {
-		if (typeof(args[name]) == 'function')
-			continue;
+		if (this.settings.on_save && n.indexOf('on') != -1 && this.settings.on_save && v && v != "")
+			v = tinyMCE.cleanupEventStr(v);
 
-		url = tinyMCE.replaceVar(url, name, escape(args[name]));
-	}
+		return (v && v != "") ? '' + v : d;
+	},
 
-	if (html) {
-		html = tinyMCE.replaceVar(html, "css", this.settings['popups_css']);
-		html = tinyMCE.applyTemplate(html, args);
+	_urlConverter : function(c, n, v) {
+		if (!c.settings.on_save)
+			return tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, v);
+		else if (tinyMCE.getParam('convert_urls')) {
+			if (!this.urlConverter)
+				this.urlConverter = eval(tinyMCE.settings.urlconverter_callback);
 
-		var win = window.open("", "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=yes,minimizable=" + resizable + ",modal=yes,width=" + width + ",height=" + height + ",resizable=" + resizable);
-		if (win == null) {
-			alert(tinyMCELang['lang_popup_blocked']);
-			return;
+			return this.urlConverter(v, n, true);
 		}
 
-		win.document.write(html);
-		win.document.close();
-		win.resizeTo(width, height);
-		win.focus();
-	} else {
-		if ((tinyMCE.isMSIE && !tinyMCE.isOpera) && resizable != 'yes' && tinyMCE.settings["dialog_type"] == "modal") {
-            var features = "resizable:" + resizable 
-                + ";scroll:"
-                + scrollbars + ";status:yes;center:yes;help:no;dialogWidth:"
-                + width + "px;dialogHeight:" + height + "px;";
+		return v;
+	},
 
-			window.showModalDialog(url, window, features);
-		} else {
-			var modal = (resizable == "yes") ? "no" : "yes";
+	_arrayToRe : function(a, op, be, af) {
+		var i, r;
 
-			if (tinyMCE.isGecko && tinyMCE.isMac)
-				modal = "no";
+		op = typeof(op) == "undefined" ? "gi" : op;
+		be = typeof(be) == "undefined" ? "^(" : be;
+		af = typeof(af) == "undefined" ? ")$" : af;
 
-			if (template['close_previous'] != "no")
-				try {tinyMCE.lastWindow.close();} catch (ex) {}
+		r = be;
 
-			var win = window.open(url, "mcePopup" + new Date().getTime(), "top=" + y + ",left=" + x + ",scrollbars=" + scrollbars + ",dialog=" + modal + ",minimizable=" + resizable + ",modal=" + modal + ",width=" + width + ",height=" + height + ",resizable=" + resizable);
-			if (win == null) {
-				alert(tinyMCELang['lang_popup_blocked']);
-				return;
+		for (i=0; i<a.length; i++)
+			r += this._wildcardToRe(a[i]) + (i != a.length-1 ? "|" : "");
+
+		r += af;
+
+		return new RegExp(r, op);
+	},
+
+	_wildcardToRe : function(s) {
+		s = s.replace(/\?/g, '(\\S?)');
+		s = s.replace(/\+/g, '(\\S+)');
+		s = s.replace(/\*/g, '(\\S*)');
+
+		return s;
+	},
+
+	_setupEntities : function() {
+		var n, a, i, s = this.settings;
+
+		// Setup entities
+		if (!this.entitiesDone) {
+			if (s.entity_encoding == "named") {
+				n = tinyMCE.clearArray(new Array());
+				a = this.split(',', s.entities);
+				for (i=0; i<a.length; i+=2)
+					n[a[i]] = a[i+1];
+
+				this.entities = n;
 			}
 
-			if (template['close_previous'] != "no")
-				tinyMCE.lastWindow = win;
+			this.entitiesDone = true;
+		}
+	},
 
-			eval('try { win.resizeTo(width, height); } catch(e) { }');
+	_setupRules : function() {
+		var s = this.settings;
 
-			// Make it bigger if statusbar is forced
-			if (tinyMCE.isGecko) {
-				if (win.document.defaultView.statusbar.visible)
-					win.resizeBy(0, tinyMCE.isMac ? 10 : 24);
+		// Setup default rule
+		if (!this.rulesDone) {
+			this.addRuleStr(s.valid_elements);
+			this.addRuleStr(s.extended_valid_elements);
+			this.addChildRemoveRuleStr(s.valid_child_elements);
+
+			this.rulesDone = true;
+		}
+	},
+
+	_isDuplicate : function(n) {
+		var i;
+
+		if (!this.settings.fix_content_duplication)
+			return false;
+
+		if (tinyMCE.isRealIE && n.nodeType == 1) {
+			// Mark elements
+			if (n.mce_serialized == this.serializationId)
+				return true;
+
+			n.setAttribute('mce_serialized', this.serializationId);
+		} else {
+			// Search lookup table for text nodes  and comments
+			for (i=0; i<this.serializedNodes.length; i++) {
+				if (this.serializedNodes[i] == n)
+					return true;
 			}
 
-			win.focus();
+			this.serializedNodes[this.serializedNodes.length] = n;
+		}
+
+		return false;
+	}
+
+	};
+
+/* file:jscripts/tiny_mce/classes/TinyMCE_DOMUtils.class.js */
+
+TinyMCE_Engine.prototype.createTagHTML = function(tn, a, h) {
+	var o = '', f = tinyMCE.xmlEncode;
+
+	o = '<' + tn;
+
+	if (a) {
+		for (n in a) {
+			if (typeof(a[n]) != 'function' && a[n] != null)
+				o += ' ' + f(n) + '="' + f('' + a[n]) + '"';
+		}
+	}
+
+	o += !h ? ' />' : '>' + h + '</' + tn + '>';
+
+	return o;
+};
+
+TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) {
+	var o = d.createElement(tn);
+
+	if (a) {
+		for (n in a) {
+			if (typeof(a[n]) != 'function' && a[n] != null)
+				tinyMCE.setAttrib(o, n, a[n]);
+		}
+	}
+
+	if (h)
+		o.innerHTML = h;
+
+	return o;
+};
+
+TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
+	return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
+};
+
+TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
+	var i, nl = n.getElementsByTagName(e), o = new Array();
+
+	for (i=0; i<nl.length; i++) {
+		if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
+			o[o.length] = nl[i];
+	}
+
+	return o;
+};
+
+TinyMCE_Engine.prototype.isBlockElement = function(n) {
+	return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
+};
+
+TinyMCE_Engine.prototype.getParentBlockElement = function(n, r) {
+	return this.getParentNode(n, function(n) {
+		return tinyMCE.isBlockElement(n);
+	}, r);
+
+	return null;
+};
+
+TinyMCE_Engine.prototype.insertAfter = function(n, r){
+	if (r.nextSibling)
+		r.parentNode.insertBefore(n, r.nextSibling);
+	else
+		r.parentNode.appendChild(n);
+};
+
+TinyMCE_Engine.prototype.setInnerHTML = function(e, h) {
+	var i, nl, n;
+
+	// Convert all strong/em to b/i in Gecko
+	if (tinyMCE.isGecko) {
+		h = h.replace(/<embed([^>]*)>/gi, '<tmpembed$1>');
+		h = h.replace(/<em([^>]*)>/gi, '<i$1>');
+		h = h.replace(/<tmpembed([^>]*)>/gi, '<embed$1>');
+		h = h.replace(/<strong([^>]*)>/gi, '<b$1>');
+		h = h.replace(/<\/strong>/gi, '</b>');
+		h = h.replace(/<\/em>/gi, '</i>');
+	}
+
+	if (tinyMCE.isRealIE) {
+		// Since MSIE handles invalid HTML better that valid XHTML we
+		// need to make some things invalid. <hr /> gets converted to <hr>.
+		h = h.replace(/\s\/>/g, '>');
+
+		// Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
+		h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
+		h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
+		h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
+
+		// Remove first comment
+		e.innerHTML = tinyMCE.uniqueTag + h;
+		e.firstChild.removeNode(true);
+
+		// Remove weird auto generated empty paragraphs unless it's supposed to be there
+		nl = e.getElementsByTagName("p");
+		for (i=nl.length-1; i>=0; i--) {
+			n = nl[i];
+
+			if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
+				n.parentNode.removeChild(n);
 		}
+	} else {
+		h = this.fixGeckoBaseHREFBug(1, e, h);
+		e.innerHTML = h;
+		this.fixGeckoBaseHREFBug(2, e, h);
 	}
 };
 
-TinyMCE.prototype.closeWindow = function(win) {
-	win.close();
-};
-
-TinyMCE.prototype.getVisualAidClass = function(class_name, state) {
-	var aidClass = tinyMCE.settings['visual_table_class'];
+TinyMCE_Engine.prototype.getOuterHTML = function(e) {
+	if (tinyMCE.isIE)
+		return e.outerHTML;
 
-	if (typeof(state) == "undefined")
-		state = tinyMCE.settings['visual'];
-
-	// Split
-	var classNames = new Array();
-	var ar = class_name.split(' ');
-	for (var i=0; i<ar.length; i++) {
-		if (ar[i] == aidClass)
-			ar[i] = "";
+	var d = e.ownerDocument.createElement("body");
+	d.appendChild(e.cloneNode(true));
+	return d.innerHTML;
+};
 
-		if (ar[i] != "")
-			classNames[classNames.length] = ar[i];
-	}
+TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) {
+	var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
 
-	if (state)
-		classNames[classNames.length] = aidClass;
+	if (tinyMCE.isIE && e.nodeType == 1)
+		e.outerHTML = h;
+	else {
+		t = d.createElement("body");
+		t.innerHTML = h;
 
-	// Glue
-	var className = "";
-	for (var i=0; i<classNames.length; i++) {
-		if (i > 0)
-			className += " ";
+		for (i=0, nl=t.childNodes; i<nl.length; i++)
+			e.parentNode.insertBefore(nl[i].cloneNode(true), e);
 
-		className += classNames[i];
+		e.parentNode.removeChild(e);
 	}
-
-	return className;
 };
 
-TinyMCE.prototype.handleVisualAid = function(el, deep, state, inst) {
-	if (!el)
-		return;
+TinyMCE_Engine.prototype._getElementById = function(id, d) {
+	var e, i, j, f;
 
-	var tableElement = null;
+	if (typeof(d) == "undefined")
+		d = document;
 
-	switch (el.nodeName) {
-		case "TABLE":
-			var oldW = el.style.width;
-			var oldH = el.style.height;
-			var bo = tinyMCE.getAttrib(el, "border");
+	e = d.getElementById(id);
+	if (!e) {
+		f = d.forms;
+
+		for (i=0; i<f.length; i++) {
+			for (j=0; j<f[i].elements.length; j++) {
+				if (f[i].elements[j].name == id) {
+					e = f[i].elements[j];
+					break;
+				}
+			}
+		}
+	}
 
-			bo = bo == "" || bo == "0" ? true : false;
+	return e;
+};
 
-			tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo));
+TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) {
+	return this.selectNodes(n, function(n) {
+		return (!t || n.nodeType == t) && (!nn || n.nodeName == nn);
+	}, na ? na : new Array());
+};
 
-			el.style.width = oldW;
-			el.style.height = oldH;
+TinyMCE_Engine.prototype.getParentElement = function(n, na, f, r) {
+	var re = na ? new RegExp('^(' + na.toUpperCase().replace(/,/g, '|') + ')$') : 0, v;
 
-			for (var y=0; y<el.rows.length; y++) {
-				for (var x=0; x<el.rows[y].cells.length; x++) {
-					var cn = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el.rows[y].cells[x], "class"), state && bo);
-					tinyMCE.setAttrib(el.rows[y].cells[x], "class", cn);
-				}
-			}
+	// Compatiblity with old scripts where f param was a attribute string
+	if (f && typeof(f) == 'string')
+		return this.getParentElement(n, na, function(no) {return tinyMCE.getAttrib(no, f) != '';});
 
-			break;
+	return this.getParentNode(n, function(n) {
+		return ((n.nodeType == 1 && !re) || (re && re.test(n.nodeName))) && (!f || f(n));
+	}, r);
+};
 
-		case "A":
-			var anchorName = tinyMCE.getAttrib(el, "name");
+TinyMCE_Engine.prototype.getParentNode = function(n, f, r) {
+	while (n) {
+		if (n == r)
+			return null;
 
-			if (anchorName != '' && state) {
-				el.title = anchorName;
-				el.className = 'mceItemAnchor';
-			} else if (anchorName != '' && !state)
-				el.className = '';
+		if (f(n))
+			return n;
 
-			break;
+		n = n.parentNode;
 	}
 
-	if (deep && el.hasChildNodes()) {
-		for (var i=0; i<el.childNodes.length; i++)
-			tinyMCE.handleVisualAid(el.childNodes[i], deep, state, inst);
-	}
+	return null;
 };
 
-TinyMCE.prototype.getAttrib = function(elm, name, default_value) {
-	if (typeof(default_value) == "undefined")
-		default_value = "";
+TinyMCE_Engine.prototype.getAttrib = function(elm, name, dv) {
+	var v;
+
+	if (typeof(dv) == "undefined")
+		dv = "";
 
 	// Not a element
 	if (!elm || elm.nodeType != 1)
-		return default_value;
+		return dv;
 
-	var v = elm.getAttribute(name);
+	try {
+		v = elm.getAttribute(name, 0);
+	} catch (ex) {
+		// IE 7 may cast exception on invalid attributes
+		v = elm.getAttribute(name, 2);
+	}
 
 	// Try className for class attrib
 	if (name == "class" && !v)
@@ -3421,742 +5369,504 @@
 	if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
 		v = elm.href;
 
+	if (name == "http-equiv" && tinyMCE.isIE)
+		v = elm.httpEquiv;
+
 	if (name == "style" && !tinyMCE.isOpera)
 		v = elm.style.cssText;
 
-	return (v && v != "") ? v : default_value;
+	return (v && v != "") ? v : dv;
 };
 
-TinyMCE.prototype.setAttrib = function(element, name, value, fix_value) {
-	if (typeof(value) == "number" && value != null)
-		value = "" + value;
+TinyMCE_Engine.prototype.setAttrib = function(el, name, va, fix) {
+	if (typeof(va) == "number" && va != null)
+		va = "" + va;
 
-	if (fix_value) {
-		if (value == null)
-			value = "";
+	if (fix) {
+		if (va == null)
+			va = "";
 
-		var re = new RegExp('[^0-9%]', 'g');
-		value = value.replace(re, '');
+		va = va.replace(/[^0-9%]/g, '');
 	}
 
 	if (name == "style")
-		element.style.cssText = value;
+		el.style.cssText = va;
 
 	if (name == "class")
-		element.className = value;
+		el.className = va;
 
-	if (value != null && value != "" && value != -1)
-		element.setAttribute(name, value);
+	if (va != null && va != "" && va != -1)
+		el.setAttribute(name, va);
 	else
-		element.removeAttribute(name);
+		el.removeAttribute(name);
 };
 
-TinyMCE.prototype.setStyleAttrib = function(elm, name, value) {
-	eval('elm.style.' + name + '=value;');
+TinyMCE_Engine.prototype.setStyleAttrib = function(e, n, v) {
+	e.style[n] = v;
 
-	// Style attrib deleted
-	if (tinyMCE.isMSIE && value == null || value == '') {
-		var str = tinyMCE.serializeStyle(tinyMCE.parseStyle(elm.style.cssText));
-		elm.style.cssText = str;
-		elm.setAttribute("style", str);
+	// Style attrib deleted in IE
+	if (tinyMCE.isIE && v == null || v == '') {
+		v = tinyMCE.serializeStyle(tinyMCE.parseStyle(e.style.cssText));
+		e.style.cssText = v;
+		e.setAttribute("style", v);
 	}
 };
 
-TinyMCE.prototype.convertSpansToFonts = function(doc) {
-	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
-
-	var h = doc.body.innerHTML;
-	h = h.replace(/<span/gi, '<font');
-	h = h.replace(/<\/span/gi, '</font');
-	doc.body.innerHTML = h;
-
-	var s = doc.getElementsByTagName("font");
-	for (var i=0; i<s.length; i++) {
-		var size = tinyMCE.trim(s[i].style.fontSize).toLowerCase();
-		var fSize = 0;
-
-		for (var x=0; x<sizes.length; x++) {
-			if (sizes[x] == size) {
-				fSize = x + 1;
-				break;
-			}
-		}
+TinyMCE_Engine.prototype.switchClass = function(ei, c) {
+	var e;
 
-		if (fSize > 0) {
-			tinyMCE.setAttrib(s[i], 'size', fSize);
-			s[i].style.fontSize = '';
-		}
+	if (tinyMCE.switchClassCache[ei])
+		e = tinyMCE.switchClassCache[ei];
+	else
+		e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);
 
-		var fFace = s[i].style.fontFamily;
-		if (fFace != null && fFace != "") {
-			tinyMCE.setAttrib(s[i], 'face', fFace);
-			s[i].style.fontFamily = '';
-		}
+	if (e) {
+		// Keep tile mode
+		if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
+			c = 'mceTiledButton ' + c;
 
-		var fColor = s[i].style.color;
-		if (fColor != null && fColor != "") {
-			tinyMCE.setAttrib(s[i], 'color', tinyMCE.convertRGBToHex(fColor));
-			s[i].style.color = '';
-		}
+		e.className = c;
 	}
 };
 
-TinyMCE.prototype.convertFontsToSpans = function(doc) {
-	var sizes = tinyMCE.getParam('font_size_style_values').replace(/\s+/, '').split(',');
-
-	var h = doc.body.innerHTML;
-	h = h.replace(/<font/gi, '<span');
-	h = h.replace(/<\/font/gi, '</span');
-	doc.body.innerHTML = h;
-
-	var fsClasses = tinyMCE.getParam('font_size_classes');
-	if (fsClasses != '')
-		fsClasses = fsClasses.replace(/\s+/, '').split(',');
-	else
-		fsClasses = null;
-
-	var s = doc.getElementsByTagName("span");
-	for (var i=0; i<s.length; i++) {
-		var fSize, fFace, fColor;
-
-		fSize = tinyMCE.getAttrib(s[i], 'size');
-		fFace = tinyMCE.getAttrib(s[i], 'face');
-		fColor = tinyMCE.getAttrib(s[i], 'color');
-
-		if (fSize != "") {
-			fSize = parseInt(fSize);
+TinyMCE_Engine.prototype.getAbsPosition = function(n, cn) {
+	var l = 0, t = 0;
 
-			if (fSize > 0 && fSize < 8) {
-				if (fsClasses != null)
-					tinyMCE.setAttrib(s[i], 'class', fsClasses[fSize-1]);
-				else
-					s[i].style.fontSize = sizes[fSize-1];
-			}
+	while (n && n != cn) {
+		l += n.offsetLeft;
+		t += n.offsetTop;
+		n = n.offsetParent;
+	}
 
-			s[i].removeAttribute('size');
-		}
+	return {absLeft : l, absTop : t};
+};
 
-		if (fFace != "") {
-			s[i].style.fontFamily = fFace;
-			s[i].removeAttribute('face');
-		}
+TinyMCE_Engine.prototype.prevNode = function(e, n) {
+	var a = n.split(','), i;
 
-		if (fColor != "") {
-			s[i].style.color = fColor;
-			s[i].removeAttribute('color');
+	while ((e = e.previousSibling) != null) {
+		for (i=0; i<a.length; i++) {
+			if (e.nodeName == a[i])
+				return e;
 		}
 	}
+
+	return null;
 };
 
-/*
-TinyMCE.prototype.applyClassesToFonts = function(doc, size) {
-	var f = doc.getElementsByTagName("font");
-	for (var i=0; i<f.length; i++) {
-		var s = tinyMCE.getAttrib(f[i], "size");
-
-		if (s != "")
-			tinyMCE.setAttrib(f[i], 'class', "mceItemFont" + s);
-	}
-
-	if (typeof(size) != "undefined") {
-		var css = "";
-
-		for (var x=0; x<doc.styleSheets.length; x++) {
-			for (var i=0; i<doc.styleSheets[x].rules.length; i++) {
-				if (doc.styleSheets[x].rules[i].selectorText == '#mceSpanFonts .mceItemFont' + size) {
-					css = doc.styleSheets[x].rules[i].style.cssText;
-					break;
-				}
-			}
+TinyMCE_Engine.prototype.nextNode = function(e, n) {
+	var a = n.split(','), i;
 
-			if (css != "")
-				break;
+	while ((e = e.nextSibling) != null) {
+		for (i=0; i<a.length; i++) {
+			if (e.nodeName == a[i])
+				return e;
 		}
-
-		if (doc.styleSheets[0].rules[0].selectorText == "FONT")
-			doc.styleSheets[0].removeRule(0);
-
-		doc.styleSheets[0].addRule("FONT", css, 0);
 	}
-};
-*/
 
-TinyMCE.prototype.setInnerHTML = function(e, h) {
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
-		e.innerHTML = tinyMCE.uniqueTag + h;
-		e.firstChild.removeNode(true);
-	} else {
-		h = this.fixGeckoBaseHREFBug(1, e, h);
-		e.innerHTML = h;
-		this.fixGeckoBaseHREFBug(2, e, h);
-	}
+	return null;
 };
 
-TinyMCE.prototype.fixGeckoBaseHREFBug = function(m, e, h) {
-	if (tinyMCE.isGecko) {
-		if (m == 1) {
-			h = h.replace(/\ssrc=/gi, " xsrc=");
-			h = h.replace(/\shref=/gi, " xhref=");
-
-			return h;
-		} else {
-			if (h.indexOf(' xsrc') != -1) {
-				var n = e.getElementsByTagName("img");
-				for (var i=0; i<n.length; i++) {
-					var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
-
-					if (xsrc != "") {
-						n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
-						n[i].removeAttribute("xsrc");
-					}
-				}
+TinyMCE_Engine.prototype.selectElements = function(n, na, f) {
+	var i, a = [], nl, x;
 
-				// Select image form fields
-				var n = e.getElementsByTagName("select");
-				for (var i=0; i<n.length; i++) {
-					var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
+	for (x=0, na = na.split(','); x<na.length; x++)
+		for (i=0, nl = n.getElementsByTagName(na[x]); i<nl.length; i++)
+			(!f || f(nl[i])) && a.push(nl[i]);
 
-					if (xsrc != "") {
-						n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
-						n[i].removeAttribute("xsrc");
-					}
-				}
+	return a;
+};
 
-				// iframes
-				var n = e.getElementsByTagName("iframe");
-				for (var i=0; i<n.length; i++) {
-					var xsrc = tinyMCE.getAttrib(n[i], "xsrc");
+TinyMCE_Engine.prototype.selectNodes = function(n, f, a) {
+	var i;
 
-					if (xsrc != "") {
-						n[i].src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xsrc);
-						n[i].removeAttribute("xsrc");
-					}
-				}
-			}
+	if (!a)
+		a = new Array();
 
-			if (h.indexOf(' xhref') != -1) {
-				var n = e.getElementsByTagName("a");
-				for (var i=0; i<n.length; i++) {
-					var xhref = tinyMCE.getAttrib(n[i], "xhref");
+	if (f(n))
+		a[a.length] = n;
 
-					if (xhref != "") {
-						n[i].href = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], xhref);
-						n[i].removeAttribute("xhref");
-					}
-				}
-			}
-		}
+	if (n.hasChildNodes()) {
+		for (i=0; i<n.childNodes.length; i++)
+			tinyMCE.selectNodes(n.childNodes[i], f, a);
 	}
 
-	return h;
-};
-
-TinyMCE.prototype.getOuterHTML = function(e) {
-	if (tinyMCE.isMSIE)
-		return e.outerHTML;
-
-	var d = e.ownerDocument.createElement("body");
-	d.appendChild(e);
-	return d.innerHTML;
+	return a;
 };
 
-TinyMCE.prototype.setOuterHTML = function(doc, e, h) {
-	if (tinyMCE.isMSIE) {
-		e.outerHTML = h;
-		return;
-	}
-
-	var d = e.ownerDocument.createElement("body");
-	d.innerHTML = h;
-	e.parentNode.replaceChild(d.firstChild, e);
+TinyMCE_Engine.prototype.addCSSClass = function(e, c, b) {
+	var o = this.removeCSSClass(e, c);
+	return e.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
 };
 
-TinyMCE.prototype.insertAfter = function(nc, rc){
-	if (rc.nextSibling)
-		rc.parentNode.insertBefore(nc, rc.nextSibling);
-	else
-		rc.parentNode.appendChild(nc);
+TinyMCE_Engine.prototype.removeCSSClass = function(e, c) {
+	c = e.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
+	return e.className = c != ' ' ? c : '';
 };
 
-TinyMCE.prototype.cleanupAnchors = function(doc) {
-	var an = doc.getElementsByTagName("a");
-
-	for (var i=0; i<an.length; i++) {
-		if (tinyMCE.getAttrib(an[i], "name") != "") {
-			var cn = an[i].childNodes;
-			for (var x=cn.length-1; x>=0; x--)
-				tinyMCE.insertAfter(cn[x], an[i]);
-		}
-	}
+TinyMCE_Engine.prototype.hasCSSClass = function(n, c) {
+	return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
 };
 
-TinyMCE.prototype._setHTML = function(doc, html_content) {
-	// Force closed anchors open
-	//html_content = html_content.replace(new RegExp('<a(.*?)/>', 'gi'), '<a$1></a>');
+TinyMCE_Engine.prototype.renameElement = function(e, n, d) {
+	var ne, i, ar;
 
-	html_content = tinyMCE.cleanupHTMLCode(html_content);
+	d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;
 
-	// Try innerHTML if it fails use pasteHTML in MSIE
-	try {
-		tinyMCE.setInnerHTML(doc.body, html_content);
-	} catch (e) {
-		if (this.isMSIE)
-			doc.body.createTextRange().pasteHTML(html_content);
-	}
-
-	// Content duplication bug fix
-	if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) {
-		// Remove P elements in P elements
-		var paras = doc.getElementsByTagName("P");
-		for (var i=0; i<paras.length; i++) {
-			var node = paras[i];
-			while ((node = node.parentNode) != null) {
-				if (node.nodeName == "P")
-					node.outerHTML = node.innerHTML;
-			}
-		}
-
-		// Content duplication bug fix (Seems to be word crap)
-		var html = doc.body.innerHTML;
-
-		if (html.indexOf('="mso') != -1) {
-			for (var i=0; i<doc.body.all.length; i++) {
-				var el = doc.body.all[i];
-				el.removeAttribute("className","",0);
-				el.removeAttribute("style","",0);
-			}
+	if (e) {
+		ne = d.createElement(n);
 
-			html = doc.body.innerHTML;
-			html = tinyMCE.regexpReplace(html, "<o:p><\/o:p>", "<br />");
-			html = tinyMCE.regexpReplace(html, "<o:p>&nbsp;<\/o:p>", "");
-			html = tinyMCE.regexpReplace(html, "<st1:.*?>", "");
-			html = tinyMCE.regexpReplace(html, "<p><\/p>", "");
-			html = tinyMCE.regexpReplace(html, "<p><\/p>\r\n<p><\/p>", "");
-			html = tinyMCE.regexpReplace(html, "<p>&nbsp;<\/p>", "<br />");
-			html = tinyMCE.regexpReplace(html, "<p>\s*(<p>\s*)?", "<p>");
-			html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "</p>");
+		ar = e.attributes;
+		for (i=ar.length-1; i>-1; i--) {
+			if (ar[i].specified && ar[i].nodeValue)
+				ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
 		}
 
-		// Always set the htmlText output
-		tinyMCE.setInnerHTML(doc.body, html);
-	}
-
-	tinyMCE.cleanupAnchors(doc);
-
-	if (tinyMCE.getParam("convert_fonts_to_spans"))
-		tinyMCE.convertSpansToFonts(doc);
-};
-
-TinyMCE.prototype.getImageSrc = function(str) {
-	var pos = -1;
-
-	if (!str)
-		return "";
+		ar = e.childNodes;
+		for (i=0; i<ar.length; i++)
+			ne.appendChild(ar[i].cloneNode(true));
 
-	if ((pos = str.indexOf('this.src=')) != -1) {
-		var src = str.substring(pos + 10);
-
-		src = src.substring(0, src.indexOf('\''));
-
-		return src;
-	}
-
-	return "";
-};
-
-TinyMCE.prototype._getElementById = function(element_id) {
-	var elm = document.getElementById(element_id);
-	if (!elm) {
-		// Check for element in forms
-		for (var j=0; j<document.forms.length; j++) {
-			for (var k=0; k<document.forms[j].elements.length; k++) {
-				if (document.forms[j].elements[k].name == element_id) {
-					elm = document.forms[j].elements[k];
-					break;
-				}
-			}
-		}
+		e.parentNode.replaceChild(ne, e);
 	}
-
-	return elm;
 };
 
-TinyMCE.prototype.getEditorId = function(form_element) {
-	var inst = this.getInstanceById(form_element);
-	if (!inst)
-		return null;
+TinyMCE_Engine.prototype.getViewPort = function(w) {
+	var d = w.document, m = d.compatMode == 'CSS1Compat', b = d.body, de = d.documentElement;
 
-	return inst.editorId;
+	return {
+		left : w.pageXOffset || (m ? de.scrollLeft : b.scrollLeft),
+		top : w.pageYOffset || (m ? de.scrollTop : b.scrollTop),
+		width : w.innerWidth || (m ? de.clientWidth : b.clientWidth),
+		height : w.innerHeight || (m ? de.clientHeight : b.clientHeight)
+	};
 };
 
-TinyMCE.prototype.getInstanceById = function(editor_id) {
-	var inst = this.instances[editor_id];
-	if (!inst) {
-		for (var n in tinyMCE.instances) {
-			var instance = tinyMCE.instances[n];
-			if (!tinyMCE.isInstance(instance))
-				continue;
+TinyMCE_Engine.prototype.getStyle = function(n, na, d) {
+	if (!n)
+		return false;
 
-			if (instance.formTargetElementId == editor_id) {
-				inst = instance;
-				break;
-			}
+	// Gecko
+	if (tinyMCE.isGecko && n.ownerDocument.defaultView) {
+		try {
+			return n.ownerDocument.defaultView.getComputedStyle(n, null).getPropertyValue(na);
+		} catch (n) {
+			// Old safari might fail
+			return null;
 		}
 	}
 
-	return inst;
-};
-
-TinyMCE.prototype.queryInstanceCommandValue = function(editor_id, command) {
-	var inst = tinyMCE.getInstanceById(editor_id);
-	if (inst)
-		return inst.queryCommandValue(command);
+	// Camelcase it, if needed
+	na = na.replace(/-(\D)/g, function(a, b){
+		return b.toUpperCase();
+	});
+
+	// IE & Opera
+	if (n.currentStyle)
+		return n.currentStyle[na];
 
 	return false;
 };
 
-TinyMCE.prototype.queryInstanceCommandState = function(editor_id, command) {
-	var inst = tinyMCE.getInstanceById(editor_id);
-	if (inst)
-		return inst.queryCommandState(command);
-
-	return null;
-};
-
-TinyMCE.prototype.setWindowArg = function(name, value) {
-	this.windowArgs[name] = value;
-};
+/* file:jscripts/tiny_mce/classes/TinyMCE_URL.class.js */
 
-TinyMCE.prototype.getWindowArg = function(name, default_value) {
-	return (typeof(this.windowArgs[name]) == "undefined") ? default_value : this.windowArgs[name];
-};
+TinyMCE_Engine.prototype.parseURL = function(url_str) {
+	var urlParts = new Array();
 
-TinyMCE.prototype.getCSSClasses = function(editor_id, doc) {
-	var output = new Array();
+	if (url_str) {
+		var pos, lastPos;
 
-	// Is cached, use that
-	if (typeof(tinyMCE.cssClasses) != "undefined")
-		return tinyMCE.cssClasses;
+		// Parse protocol part
+		pos = url_str.indexOf('://');
+		if (pos != -1) {
+			urlParts['protocol'] = url_str.substring(0, pos);
+			lastPos = pos + 3;
+		}
 
-	if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") {
-		var instance;
+		// Find port or path start
+		for (var i=lastPos; i<url_str.length; i++) {
+			var chr = url_str.charAt(i);
 
-		for (var instanceName in tinyMCE.instances) {
-			instance = tinyMCE.instances[instanceName];
-			if (!tinyMCE.isInstance(instance))
-				continue;
+			if (chr == ':')
+				break;
 
-			break;
+			if (chr == '/')
+				break;
 		}
+		pos = i;
 
-		doc = instance.getDoc();
-	}
-
-	if (typeof(doc) == "undefined") {
-		var instance = tinyMCE.getInstanceById(editor_id);
-		doc = instance.getDoc();
-	}
+		// Get host
+		urlParts['host'] = url_str.substring(lastPos, pos);
 
-	if (doc) {
-		var styles = tinyMCE.isMSIE ? doc.styleSheets : doc.styleSheets;
+		// Get port
+		urlParts['port'] = "";
+		lastPos = pos;
+		if (url_str.charAt(pos) == ':') {
+			pos = url_str.indexOf('/', lastPos);
+			urlParts['port'] = url_str.substring(lastPos+1, pos);
+		}
 
-		if (styles && styles.length > 0) {
-			for (var x=0; x<styles.length; x++) {
-				var csses = null;
+		// Get path
+		lastPos = pos;
+		pos = url_str.indexOf('?', lastPos);
 
-				// Just ignore any errors
-				eval("try {var csses = tinyMCE.isMSIE ? doc.styleSheets(" + x + ").rules : doc.styleSheets[" + x + "].cssRules;} catch(e) {}");
-				if (!csses)
-					return new Array();
+		if (pos == -1)
+			pos = url_str.indexOf('#', lastPos);
 
-				for (var i=0; i<csses.length; i++) {
-					var selectorText = csses[i].selectorText;
+		if (pos == -1)
+			pos = url_str.length;
 
-					// Can be multiple rules per selector
-					if (selectorText) {
-						var rules = selectorText.split(',');
-						for (var c=0; c<rules.length; c++) {
-							// Invalid rule
-							if (rules[c].indexOf(' ') != -1 || rules[c].indexOf(':') != -1 || rules[c].indexOf('mceItem') != -1)
-								continue;
+		urlParts['path'] = url_str.substring(lastPos, pos);
 
-							if (rules[c] == "." + tinyMCE.settings['visual_table_class'])
-								continue;
+		// Get query
+		lastPos = pos;
+		if (url_str.charAt(pos) == '?') {
+			pos = url_str.indexOf('#');
+			pos = (pos == -1) ? url_str.length : pos;
+			urlParts['query'] = url_str.substring(lastPos+1, pos);
+		}
 
-							// Is class rule
-							if (rules[c].indexOf('.') != -1) {
-								//alert(rules[c].substring(rules[c].indexOf('.')));
-								output[output.length] = rules[c].substring(rules[c].indexOf('.')+1);
-							}
-						}
-					}
-				}
-			}
+		// Get anchor
+		lastPos = pos;
+		if (url_str.charAt(pos) == '#') {
+			pos = url_str.length;
+			urlParts['anchor'] = url_str.substring(lastPos+1, pos);
 		}
 	}
 
-	// Cache em
-	if (output.length > 0)
-		tinyMCE.cssClasses = output;
-
-	return output;
+	return urlParts;
 };
 
-TinyMCE.prototype.regexpReplace = function(in_str, reg_exp, replace_str, opts) {
-	if (in_str == null)
-		return in_str;
+TinyMCE_Engine.prototype.serializeURL = function(up) {
+	var o = "";
+
+	if (up['protocol'])
+		o += up['protocol'] + "://";
+
+	if (up['host'])
+		o += up['host'];
 
-	if (typeof(opts) == "undefined")
-		opts = 'g';
+	if (up['port'])
+		o += ":" + up['port'];
 
-	var re = new RegExp(reg_exp, opts);
-	return in_str.replace(re, replace_str);
-};
+	if (up['path'])
+		o += up['path'];
 
-TinyMCE.prototype.trim = function(str) {
-	return str.replace(/^\s*|\s*$/g, "");
-};
+	if (up['query'])
+		o += "?" + up['query'];
 
-TinyMCE.prototype.cleanupEventStr = function(str) {
-	str = "" + str;
-	str = str.replace('function anonymous()\n{\n', '');
-	str = str.replace('\n}', '');
-	str = str.replace(/^return true;/gi, ''); // Remove event blocker
+	if (up['anchor'])
+		o += "#" + up['anchor'];
 
-	return str;
+	return o;
 };
 
-TinyMCE.prototype.getAbsPosition = function(node) {
-	var pos = new Object();
+TinyMCE_Engine.prototype.convertAbsoluteURLToRelativeURL = function(base_url, url_to_relative) {
+	var baseURL = this.parseURL(base_url);
+	var targetURL = this.parseURL(url_to_relative);
+	var strTok1;
+	var strTok2;
+	var breakPoint = 0;
+	var outPath = "";
+	var forceSlash = false;
 
-	pos.absLeft = pos.absTop = 0;
+	if (targetURL.path == "")
+		targetURL.path = "/";
+	else
+		forceSlash = true;
 
-	var parentNode = node;
-	while (parentNode) {
-		pos.absLeft += parentNode.offsetLeft;
-		pos.absTop += parentNode.offsetTop;
+	// Crop away last path part
+	base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
+	strTok1 = base_url.split('/');
+	strTok2 = targetURL.path.split('/');
 
-		parentNode = parentNode.offsetParent;
+	if (strTok1.length >= strTok2.length) {
+		for (var i=0; i<strTok1.length; i++) {
+			if (i >= strTok2.length || strTok1[i] != strTok2[i]) {
+				breakPoint = i + 1;
+				break;
+			}
+		}
 	}
 
-	return pos;
-};
-
-TinyMCE.prototype.getControlHTML = function(control_name) {
-	var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
-	var templateFunction;
-
-	// Is it defined in any plugins
-	for (var i=themePlugins.length; i>=0; i--) {
-		templateFunction = 'TinyMCE_' + themePlugins[i] + "_getControlHTML";
-		if (eval("typeof(" + templateFunction + ")") != 'undefined') {
-			var html = eval(templateFunction + "('" + control_name + "');");
-			if (html != "")
-				return tinyMCE.replaceVar(html, "pluginurl", tinyMCE.baseURL + "/plugins/" + themePlugins[i]);
+	if (strTok1.length < strTok2.length) {
+		for (var i=0; i<strTok2.length; i++) {
+			if (i >= strTok1.length || strTok1[i] != strTok2[i]) {
+				breakPoint = i + 1;
+				break;
+			}
 		}
 	}
 
-	return eval('TinyMCE_' + tinyMCE.settings['theme'] + "_getControlHTML" + "('" + control_name + "');");
-};
+	if (breakPoint == 1)
+		return targetURL.path;
 
-TinyMCE.prototype._themeExecCommand = function(editor_id, element, command, user_interface, value) {
-	var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
-	var templateFunction;
+	for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)
+		outPath += "../";
 
-	// Is it defined in any plugins
-	for (var i=themePlugins.length; i>=0; i--) {
-		templateFunction = 'TinyMCE_' + themePlugins[i] + "_execCommand";
-		if (eval("typeof(" + templateFunction + ")") != 'undefined') {
-			if (eval(templateFunction + "(editor_id, element, command, user_interface, value);"))
-				return true;
-		}
+	for (var i=breakPoint-1; i<strTok2.length; i++) {
+		if (i != (breakPoint-1))
+			outPath += "/" + strTok2[i];
+		else
+			outPath += strTok2[i];
 	}
 
-	// Theme funtion
-	templateFunction = 'TinyMCE_' + tinyMCE.settings['theme'] + "_execCommand";
-	if (eval("typeof(" + templateFunction + ")") != 'undefined')
-		return eval(templateFunction + "(editor_id, element, command, user_interface, value);");
+	targetURL.protocol = null;
+	targetURL.host = null;
+	targetURL.port = null;
+	targetURL.path = outPath == "" && forceSlash ? "/" : outPath;
 
-	// Pass to normal
-	return false;
-};
+	// Remove document prefix from local anchors
+	var fileName = baseURL.path;
+	var pos;
 
-TinyMCE.prototype._getThemeFunction = function(suffix, skip_plugins) {
-	if (skip_plugins)
-		return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
+	if ((pos = fileName.lastIndexOf('/')) != -1)
+		fileName = fileName.substring(pos + 1);
 
-	var themePlugins = tinyMCE.getParam('plugins', '', true, ',');
-	var templateFunction;
+	// Is local anchor
+	if (fileName == targetURL.path && targetURL.anchor != "")
+		targetURL.path = "";
 
-	// Is it defined in any plugins
-	for (var i=themePlugins.length; i>=0; i--) {
-		templateFunction = 'TinyMCE_' + themePlugins[i] + suffix;
-		if (eval("typeof(" + templateFunction + ")") != 'undefined')
-			return templateFunction;
-	}
+	// If empty and not local anchor force filename or slash
+	if (targetURL.path == "" && !targetURL.anchor)
+		targetURL.path = fileName != "" ? fileName : "/";
 
-	return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
+	return this.serializeURL(targetURL);
 };
 
+TinyMCE_Engine.prototype.convertRelativeToAbsoluteURL = function(base_url, relative_url) {
+	var baseURL = this.parseURL(base_url), baseURLParts, relURLParts;
+	var relURL = this.parseURL(relative_url);
 
-TinyMCE.prototype.isFunc = function(func_name) {
-	if (func_name == null || func_name == "")
-		return false;
+	if (relative_url == "" || relative_url.indexOf('://') != -1 || /^(mailto:|javascript:|#|\/)/.test(relative_url))
+		return relative_url;
 
-	return eval("typeof(" + func_name + ")") != "undefined";
-};
+	// Split parts
+	baseURLParts = baseURL['path'].split('/');
+	relURLParts = relURL['path'].split('/');
+
+	// Remove empty chunks
+	var newBaseURLParts = new Array();
+	for (var i=baseURLParts.length-1; i>=0; i--) {
+		if (baseURLParts[i].length == 0)
+			continue;
+
+		newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
+	}
+	baseURLParts = newBaseURLParts.reverse();
+
+	// Merge relURLParts chunks
+	var newRelURLParts = new Array();
+	var numBack = 0;
+	for (var i=relURLParts.length-1; i>=0; i--) {
+		if (relURLParts[i].length == 0 || relURLParts[i] == ".")
+			continue;
 
-TinyMCE.prototype.exec = function(func_name, args) {
-	var str = func_name + '(';
+		if (relURLParts[i] == '..') {
+			numBack++;
+			continue;
+		}
 
-	// Add all arguments
-	for (var i=3; i<args.length; i++) {
-		str += 'args[' + i + ']';
+		if (numBack > 0) {
+			numBack--;
+			continue;
+		}
 
-		if (i < args.length-1)
-			str += ',';
+		newRelURLParts[newRelURLParts.length] = relURLParts[i];
 	}
 
-	str += ');';
+	relURLParts = newRelURLParts.reverse();
 
-	return eval(str);
-};
+	// Remove end from absolute path
+	var len = baseURLParts.length-numBack;
+	var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
+	var start = "", end = "";
 
-TinyMCE.prototype.executeCallback = function(param, suffix, mode) {
-	switch (mode) {
-		// No chain
-		case 0:
-			var state = false;
+	// Build output URL
+	relURL.protocol = baseURL.protocol;
+	relURL.host = baseURL.host;
+	relURL.port = baseURL.port;
 
-			// Execute each plugin callback
-			var plugins = tinyMCE.getParam('plugins', '', true, ',');
-			for (var i=0; i<plugins.length; i++) {
-				var func = "TinyMCE_" + plugins[i] + suffix;
-				if (tinyMCE.isFunc(func)) {
-					tinyMCE.exec(func, this.executeCallback.arguments);
-					state = true;
-				}
-			}
+	// Re-add trailing slash if it's removed
+	if (relURL.path.charAt(relURL.path.length-1) == "/")
+		absPath += "/";
 
-			// Execute theme callback
-			var func = 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
-			if (tinyMCE.isFunc(func)) {
-				tinyMCE.exec(func, this.executeCallback.arguments);
-				state = true;
-			}
+	relURL.path = absPath;
 
-			// Execute settings callback
-			var func = tinyMCE.getParam(param, '');
-			if (tinyMCE.isFunc(func)) {
-				tinyMCE.exec(func, this.executeCallback.arguments);
-				state = true;
-			}
+	return this.serializeURL(relURL);
+};
 
-			return state;
+TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) {
+	var prot = document.location.protocol;
+	var host = document.location.hostname;
+	var port = document.location.port;
 
-		// Chain mode
-		case 1:
-			// Execute each plugin callback
-			var plugins = tinyMCE.getParam('plugins', '', true, ',');
-			for (var i=0; i<plugins.length; i++) {
-				var func = "TinyMCE_" + plugins[i] + suffix;
-				if (tinyMCE.isFunc(func)) {
-					if (tinyMCE.exec(func, this.executeCallback.arguments))
-						return true;
-				}
-			}
+	// Pass through file protocol
+	if (prot == "file:")
+		return url;
 
-			// Execute theme callback
-			var func = 'TinyMCE_' + tinyMCE.settings['theme'] + suffix;
-			if (tinyMCE.isFunc(func)) {
-				if (tinyMCE.exec(func, this.executeCallback.arguments))
-					return true;
-			}
+	// Something is wrong, remove weirdness
+	url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
 
-			// Execute settings callback
-			var func = tinyMCE.getParam(param, '');
-			if (tinyMCE.isFunc(func)) {
-				if (tinyMCE.exec(func, this.executeCallback.arguments))
-					return true;
-			}
+	// Mailto link or anchor (Pass through)
+	if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
+		return url;
 
-			return false;
-	}
-};
+	// Fix relative/Mozilla
+	if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
+		return tinyMCE.settings['base_href'] + url;
 
-TinyMCE.prototype.debug = function() {
-	var msg = "";
+	// Handle relative URLs
+	if (on_save && tinyMCE.getParam('relative_urls')) {
+		var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
+		if (curl.charAt(0) == '/')
+			curl = tinyMCE.settings['document_base_prefix'] + curl;
 
-	var elm = document.getElementById("tinymce_debug");
-	if (!elm) {
-		var debugDiv = document.createElement("div");
-		debugDiv.setAttribute("className", "debugger");
-		debugDiv.className = "debugger";
-		debugDiv.innerHTML = '\
-			Debug output:\
-			<textarea id="tinymce_debug" style="width: 100%; height: 300px" wrap="nowrap"></textarea>';
+		var urlParts = tinyMCE.parseURL(curl);
+		var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
 
-		document.body.appendChild(debugDiv);
-		elm = document.getElementById("tinymce_debug");
+		// Force relative
+		if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
+			return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
 	}
 
-	var args = this.debug.arguments;
-	for (var i=0; i<args.length; i++) {
-		msg += args[i];
-		if (i<args.length-1)
-			msg += ', ';
-	}
+	// Handle absolute URLs
+	if (!tinyMCE.getParam('relative_urls')) {
+		var urlParts = tinyMCE.parseURL(url);
+		var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
 
-	elm.value += msg + "\n";
-};
+		// Force absolute URLs from relative URLs
+		url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
 
-// TinyMCEControl
-function TinyMCEControl(settings) {
-	// Undo levels
-	this.undoLevels = new Array();
-	this.undoIndex = 0;
-	this.typingUndoIndex = -1;
-	this.undoRedo = true;
-	this.isTinyMCEControl = true;
+		// If anchor and path is the same page
+		if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
+			return "#" + urlParts['anchor'];
+	}
 
-	// Default settings
-	this.settings = settings;
-	this.settings['theme'] = tinyMCE.getParam("theme", "default");
-	this.settings['width'] = tinyMCE.getParam("width", -1);
-	this.settings['height'] = tinyMCE.getParam("height", -1);
-};
+	// Remove current domain
+	if (tinyMCE.getParam('remove_script_host')) {
+		var start = "", portPart = "";
+
+		if (port != "")
+			portPart = ":" + port;
 
-TinyMCEControl.prototype.repaint = function() {
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera)
-		return;
+		start = prot + "//" + host + portPart + "/";
 
-	// Ugly mozilla hack to remove ghost resize handles
-	try {
-		this.getBody().style.display = 'none';
-		this.getDoc().execCommand('selectall', false, null);
-		this.getSel().collapseToStart();
-		this.getBody().style.display = 'block';
-	} catch (ex) {
-		// Could I care less!!
+		if (url.indexOf(start) == 0)
+			url = url.substring(start.length-1);
 	}
-};
 
-TinyMCEControl.prototype.switchSettings = function() {
-	if (tinyMCE.configs.length > 1 && tinyMCE.currentConfig != this.settings['index']) {
-		tinyMCE.settings = this.settings;
-		tinyMCE.currentConfig = this.settings['index'];
-	}
+	return url;
 };
 
-TinyMCEControl.prototype.convertAllRelativeURLs = function() {
-	var body = this.getBody();
+TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) {
+	var i, elms, src, href, mhref, msrc;
 
 	// Convert all image URL:s to absolute URL
-	var elms = body.getElementsByTagName("img");
-	for (var i=0; i<elms.length; i++) {
-		var src = tinyMCE.getAttrib(elms[i], 'src');
+	elms = body.getElementsByTagName("img");
+	for (i=0; i<elms.length; i++) {
+		src = tinyMCE.getAttrib(elms[i], 'src');
 
-		var msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
+		msrc = tinyMCE.getAttrib(elms[i], 'mce_src');
 		if (msrc != "")
 			src = msrc;
 
@@ -4167,11 +5877,11 @@
 	}
 
 	// Convert all link URL:s to absolute URL
-	var elms = body.getElementsByTagName("a");
-	for (var i=0; i<elms.length; i++) {
-		var href = tinyMCE.getAttrib(elms[i], 'href');
+	elms = body.getElementsByTagName("a");
+	for (i=0; i<elms.length; i++) {
+		href = tinyMCE.getAttrib(elms[i], 'href');
 
-		var mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
+		mhref = tinyMCE.getAttrib(elms[i], 'mce_href');
 		if (mhref != "")
 			href = mhref;
 
@@ -4182,1900 +5892,1601 @@
 	}
 };
 
-TinyMCEControl.prototype.getSelectedHTML = function() {
-	if (tinyMCE.isSafari) {
-		// Not realy perfect!!
-
-		return this.getRng().toString();
-	}
-
-	var elm = document.createElement("body");
-
-	if (tinyMCE.isGecko)
-		elm.appendChild(this.getRng().cloneContents());
-	else
-		elm.innerHTML = this.getRng().htmlText;
-
-	return tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, elm, this.visualAid);
-};
-
-TinyMCEControl.prototype.getBookmark = function() {
-	var rng = this.getRng();
+/* file:jscripts/tiny_mce/classes/TinyMCE_Array.class.js */
 
-	if (tinyMCE.isSafari)
-		return rng;
+TinyMCE_Engine.prototype.clearArray = function(a) {
+	var n;
 
-	if (tinyMCE.isMSIE)
-		return rng;
+	for (n in a)
+		a[n] = null;
 
-	if (tinyMCE.isGecko)
-		return rng.cloneRange();
-
-	return null;
+	return a;
 };
 
-TinyMCEControl.prototype.moveToBookmark = function(bookmark) {
-	if (tinyMCE.isSafari) {
-		var sel = this.getSel().realSelection;
+TinyMCE_Engine.prototype.explode = function(d, s) {
+	var ar = s.split(d), oar = new Array(), i;
 
-		sel.setBaseAndExtent(bookmark.startContainer, bookmark.startOffset, bookmark.endContainer, bookmark.endOffset);
-
-		return true;
+	for (i = 0; i<ar.length; i++) {
+		if (ar[i] != "")
+			oar[oar.length] = ar[i];
 	}
 
-	if (tinyMCE.isMSIE)
-		return bookmark.select();
-
-	if (tinyMCE.isGecko) {
-		var rng = this.getDoc().createRange();
-		var sel = this.getSel();
+	return oar;
+};
 
-		rng.setStart(bookmark.startContainer, bookmark.startOffset);
-		rng.setEnd(bookmark.endContainer, bookmark.endOffset);
+/* file:jscripts/tiny_mce/classes/TinyMCE_Event.class.js */
 
-		sel.removeAllRanges();
-		sel.addRange(rng);
+TinyMCE_Engine.prototype._setEventsEnabled = function(node, state) {
+	var evs, x, y, elms, i, event;
+	var events = ['onfocus','onblur','onclick','ondblclick',
+				'onmousedown','onmouseup','onmouseover','onmousemove',
+				'onmouseout','onkeypress','onkeydown','onkeydown','onkeyup'];
 
-		return true;
-	}
+	evs = tinyMCE.settings['event_elements'].split(',');
+	for (y=0; y<evs.length; y++){
+		elms = node.getElementsByTagName(evs[y]);
+		for (i=0; i<elms.length; i++) {
+			event = "";
 
-	return false;
-};
+			for (x=0; x<events.length; x++) {
+				if ((event = tinyMCE.getAttrib(elms[i], events[x])) != '') {
+					event = tinyMCE.cleanupEventStr("" + event);
 
-TinyMCEControl.prototype.getSelectedText = function() {
-	if (tinyMCE.isMSIE) {
-		var doc = this.getDoc();
-
-		if (doc.selection.type == "Text") {
-			var rng = doc.selection.createRange();
-			selectedText = rng.text;
-		} else
-			selectedText = '';
-	} else {
-		var sel = this.getSel();
+					if (!state)
+						event = "return true;" + event;
+					else
+						event = event.replace(/^return true;/gi, '');
 
-		if (sel && sel.toString)
-			selectedText = sel.toString();
-		else
-			selectedText = '';
+					elms[i].removeAttribute(events[x]);
+					elms[i].setAttribute(events[x], event);
+				}
+			}
+		}
 	}
-
-	return selectedText;
 };
 
-TinyMCEControl.prototype.selectNode = function(node, collapse, select_text_node, to_start) {
-	if (!node)
-		return;
+TinyMCE_Engine.prototype._eventPatch = function(editor_id) {
+	var n, inst, win, e;
 
-	if (typeof(collapse) == "undefined")
-		collapse = true;
-
-	if (typeof(select_text_node) == "undefined")
-		select_text_node = false;
-
-	if (typeof(to_start) == "undefined")
-		to_start = true;
+	// Remove odd, error
+	if (typeof(tinyMCE) == "undefined")
+		return true;
 
-	if (tinyMCE.isMSIE) {
-		var rng = this.getBody().createTextRange();
+	try {
+		// Try selected instance first
+		if (tinyMCE.selectedInstance) {
+			win = tinyMCE.selectedInstance.getWin();
 
-		try {
-			rng.moveToElementText(node);
+			if (win && win.event) {
+				e = win.event;
 
-			if (collapse)
-				rng.collapse(to_start);
+				if (!e.target)
+					e.target = e.srcElement;
 
-			rng.select();
-		} catch (e) {
-			// Throws illigal agrument in MSIE some times
+				TinyMCE_Engine.prototype.handleEvent(e);
+				return;
+			}
 		}
-	} else {
-		var sel = this.getSel();
-
-		if (!sel)
-			return;
 
-		if (tinyMCE.isSafari) {
-			sel.realSelection.setBaseAndExtent(node, 0, node, node.innerText.length);
-
-			if (collapse) {
-				if (to_start)
-					sel.realSelection.collapseToStart();
-				else
-					sel.realSelection.collapseToEnd();
-			}
+		// Search for it
+		for (n in tinyMCE.instances) {
+			inst = tinyMCE.instances[n];
 
-			this.scrollToNode(node);
+			if (!tinyMCE.isInstance(inst))
+				continue;
 
-			return;
-		}
+			inst.select();
+			win = inst.getWin();
 
-		var rng = this.getDoc().createRange();
+			if (win && win.event) {
+				e = win.event;
 
-		if (select_text_node) {
-			// Find first textnode in tree
-			var nodes = tinyMCE.getNodeTree(node, new Array(), 3);
-			if (nodes.length > 0)
-				rng.selectNodeContents(nodes[0]);
-			else
-				rng.selectNodeContents(node);
-		} else
-			rng.selectNode(node);
+				if (!e.target)
+					e.target = e.srcElement;
 
-		if (collapse) {
-			// Special treatment of textnode collapse
-			if (!to_start && node.nodeType == 3) {
-				rng.setStart(node, node.nodeValue.length);
-				rng.setEnd(node, node.nodeValue.length);
-			} else
-				rng.collapse(to_start);
+				TinyMCE_Engine.prototype.handleEvent(e);
+				return;
+			}
 		}
+	} catch (ex) {
+		// Ignore error if iframe is pointing to external URL
+	}
+};
 
-		sel.removeAllRanges();
-		sel.addRange(rng);
-	}
+TinyMCE_Engine.prototype.findEvent = function(e) {
+	var n, inst;
 
-	this.scrollToNode(node);
+	if (e)
+		return e;
 
-	// Set selected element
-	tinyMCE.selectedElement = null;
-	if (node.nodeType == 1)
-		tinyMCE.selectedElement = node;
-};
+	for (n in tinyMCE.instances) {
+		inst = tinyMCE.instances[n];
 
-TinyMCEControl.prototype.scrollToNode = function(node) {
-	// Scroll to node position
-	var pos = tinyMCE.getAbsPosition(node);
-	var doc = this.getDoc();
-	var scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft;
-	var scrollY = doc.body.scrollTop + doc.documentElement.scrollTop;
-	var height = tinyMCE.isMSIE ? document.getElementById(this.editorId).style.pixelHeight : this.targetElement.clientHeight;
+		if (tinyMCE.isInstance(inst) && inst.getWin().event)
+			return inst.getWin().event;
+	}
 
-	// Only scroll if out of visible area
-	if (!tinyMCE.settings['auto_resize'] && !(pos.absTop > scrollY && pos.absTop < (scrollY - 25 + height)))
-		this.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25); 
+	return null;
 };
 
-TinyMCEControl.prototype.getBody = function() {
-	return this.getDoc().body;
+TinyMCE_Engine.prototype.unloadHandler = function() {
+	tinyMCE.triggerSave(true, true);
 };
 
-TinyMCEControl.prototype.getDoc = function() {
-	return this.contentWindow.document;
+TinyMCE_Engine.prototype.addEventHandlers = function(inst) {
+	this.setEventHandlers(inst, 1);
 };
 
-TinyMCEControl.prototype.getWin = function() {
-	return this.contentWindow;
-};
+TinyMCE_Engine.prototype.setEventHandlers = function(inst, s) {
+	var doc = inst.getDoc(), ie, ot, i, f = s ? tinyMCE.addEvent : tinyMCE.removeEvent;
 
-TinyMCEControl.prototype.getSel = function() {
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera)
-		return this.getDoc().selection;
+	ie = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'controlselect', 'dblclick'];
+	ot = ['keypress', 'keyup', 'keydown', 'click', 'mouseup', 'mousedown', 'focus', 'blur', 'dragdrop'];
 
-	var sel = this.contentWindow.getSelection();
+	inst.switchSettings();
 
-	// Fake getRangeAt
-	if (tinyMCE.isSafari && !sel.getRangeAt) {
-		var newSel = new Object();
-		var doc = this.getDoc();
+	if (tinyMCE.isIE) {
+		for (i=0; i<ie.length; i++)
+			f(doc, ie[i], TinyMCE_Engine.prototype._eventPatch);
+	} else {
+		for (i=0; i<ot.length; i++)
+			f(doc, ot[i], tinyMCE.handleEvent);
 
-		function getRangeAt(idx) {
-			var rng = new Object();
+		// Force designmode
+		try {
+			doc.designMode = "On";
+		} catch (e) {
+			// Ignore
+		}
+	}
+};
 
-			rng.startContainer = this.focusNode;
-			rng.endContainer = this.anchorNode;
-			rng.commonAncestorContainer = this.focusNode;
-			rng.createContextualFragment = function (html) {
-				// Seems to be a tag
-				if (html.charAt(0) == '<') {
-					var elm = doc.createElement("div");
+TinyMCE_Engine.prototype.onMouseMove = function() {
+	var inst, lh;
 
-					elm.innerHTML = html;
+	// Fix for IE7 bug where it's not restoring hover on anchors correctly
+	if (tinyMCE.lastHover) {
+		lh = tinyMCE.lastHover;
 
-					return elm.firstChild;
-				}
+		// Call out on menus and refresh class on normal buttons
+		if (lh.className.indexOf('mceMenu') != -1)
+			tinyMCE._menuButtonEvent('out', lh);
+		else
+			lh.className = lh.className;
 
-				return doc.createTextNode("UNSUPPORTED, DUE TO LIMITATIONS IN SAFARI!");
-			};
+		tinyMCE.lastHover = null;
+	}
 
-			rng.deleteContents = function () {
-				doc.execCommand("Delete", false, "");
-			};
+	if (!tinyMCE.hasMouseMoved) {
+		inst = tinyMCE.selectedInstance;
 
-			return rng;
+		// Workaround for bug #1437457 (Odd MSIE bug)
+		if (inst.isFocused) {
+			inst.undoBookmark = inst.selection.getBookmark();
+			tinyMCE.hasMouseMoved = true;
 		}
+	}
 
-		// Patch selection
-
-		newSel.focusNode = sel.baseNode;
-		newSel.focusOffset = sel.baseOffset;
-		newSel.anchorNode = sel.extentNode;
-		newSel.anchorOffset = sel.extentOffset;
-		newSel.getRangeAt = getRangeAt;
-		newSel.text = "" + sel;
-		newSel.realSelection = sel;
+//	tinyMCE.cancelEvent(inst.getWin().event);
+//	return false;
+};
 
-		newSel.toString = function () {return this.text;};
+TinyMCE_Engine.prototype.cancelEvent = function(e) {
+	if (!e)
+		return false;
 
-		return newSel;
+	if (tinyMCE.isIE) {
+		e.returnValue = false;
+		e.cancelBubble = true;
+	} else {
+		e.preventDefault();
+		e.stopPropagation && e.stopPropagation();
 	}
 
-	return sel;
+	return false;
 };
 
-TinyMCEControl.prototype.getRng = function() {
-	var sel = this.getSel();
-	if (sel == null)
-		return null;
-
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera)
-		return sel.createRange();
-
-	if (tinyMCE.isSafari) {
-		var rng = this.getDoc().createRange();
-		var sel = this.getSel().realSelection;
+TinyMCE_Engine.prototype.addEvent = function(o, n, h) {
+	// Add cleanup for all non unload events
+	if (n != 'unload') {
+		function clean() {
+			var ex;
 
-		rng.setStart(sel.baseNode, sel.baseOffset);
-		rng.setEnd(sel.extentNode, sel.extentOffset);
+			try {
+				tinyMCE.removeEvent(o, n, h);
+				tinyMCE.removeEvent(window, 'unload', clean);
+				o = n = h = null;
+			} catch (ex) {
+				// IE may produce access denied exception on unload
+			}
+		}
 
-		return rng;
+		// Add memory cleaner
+		tinyMCE.addEvent(window, 'unload', clean);
 	}
 
-	return this.getSel().getRangeAt(0);
+	if (o.attachEvent)
+		o.attachEvent("on" + n, h);
+	else
+		o.addEventListener(n, h, false);
 };
 
-TinyMCEControl.prototype._insertPara = function(e) {
-	function isEmpty(para) {
-		function isEmptyHTML(html) {
-			return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
-		}
+TinyMCE_Engine.prototype.removeEvent = function(o, n, h) {
+	if (o.detachEvent)
+		o.detachEvent("on" + n, h);
+	else
+		o.removeEventListener(n, h, false);
+};
 
-		// Check for images
-		if (para.getElementsByTagName("img").length > 0)
-			return false;
+TinyMCE_Engine.prototype.addSelectAccessibility = function(e, s, w) {
+	// Add event handlers 
+	if (!s._isAccessible) {
+		s.onkeydown = tinyMCE.accessibleEventHandler;
+		s.onblur = tinyMCE.accessibleEventHandler;
+		s._isAccessible = true;
+		s._win = w;
+	}
 
-		// Check for tables
-		if (para.getElementsByTagName("table").length > 0)
-			return false;
+	return false;
+};
 
-		// Check for HRs
-		if (para.getElementsByTagName("hr").length > 0)
-			return false;
+TinyMCE_Engine.prototype.accessibleEventHandler = function(e) {
+	var win = this._win;
+	e = tinyMCE.isIE ? win.event : e;
+	var elm = tinyMCE.isIE ? e.srcElement : e.target;
 
-		// Check all textnodes
-		var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
-		for (var i=0; i<nodes.length; i++) {
-			if (!isEmptyHTML(nodes[i].nodeValue))
-				return false;
+	// Unpiggyback onchange on blur
+	if (e.type == "blur") {
+		if (elm.oldonchange) {
+			elm.onchange = elm.oldonchange;
+			elm.oldonchange = null;
 		}
 
-		// No images, no tables, no hrs, no text content then it's empty
 		return true;
 	}
 
-	var doc = this.getDoc();
-	var sel = this.getSel();
-	var win = this.contentWindow;
-	var rng = sel.getRangeAt(0);
-	var body = doc.body;
-	var rootElm = doc.documentElement;
-	var self = this;
-	var blockName = "P";
-
-//	tinyMCE.debug(body.innerHTML);
-
-//	debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString());
-
-	// Setup before range
-	var rngBefore = doc.createRange();
-	rngBefore.setStart(sel.anchorNode, sel.anchorOffset);
-	rngBefore.collapse(true);
-
-	// Setup after range
-	var rngAfter = doc.createRange();
-	rngAfter.setStart(sel.focusNode, sel.focusOffset);
-	rngAfter.collapse(true);
-
-	// Setup start/end points
-	var direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0;
-	var startNode = direct ? sel.anchorNode : sel.focusNode;
-	var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
-	var endNode = direct ? sel.focusNode : sel.anchorNode;
-	var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
-
-	startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode;
-	endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode;
-
-	// tinyMCE.debug(startNode, endNode);
-
-	// Get block elements
-	var startBlock = tinyMCE.getParentBlockElement(startNode);
-	var endBlock = tinyMCE.getParentBlockElement(endNode);
-
-	// Use current block name
-	if (startBlock != null) {
-		blockName = startBlock.nodeName;
-
-		// Use P instead
-		if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
-			blockName = "P";
+	// Piggyback onchange
+	if (elm.nodeName == "SELECT" && !elm.oldonchange) {
+		elm.oldonchange = elm.onchange;
+		elm.onchange = null;
 	}
 
-	// Within a list use normal behaviour
-	if (tinyMCE.getParentElement(startBlock, "OL,UL") != null)
+	// Execute onchange and remove piggyback
+	if (e.keyCode == 13 || e.keyCode == 32) {
+		elm.onchange = elm.oldonchange;
+		elm.onchange();
+		elm.oldonchange = null;
+
+		tinyMCE.cancelEvent(e);
 		return false;
+	}
 
-	// Within a table create new paragraphs
-	if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE"))
-		startBlock = endBlock = null;
-
-	// Setup new paragraphs
-	var paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);
-	var paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);
-
-	// Is header, then force paragraph under
-	if (/^(H[1-6])$/.test(blockName))
-		paraAfter = doc.createElement("p");
-
-	// Setup chop nodes
-	var startChop = startNode;
-	var endChop = endNode;
-
-	// Get startChop node
-	node = startChop;
-	do {
-		if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
-			break;
+	return true;
+};
 
-		startChop = node;
-	} while ((node = node.previousSibling ? node.previousSibling : node.parentNode));
+TinyMCE_Engine.prototype._resetIframeHeight = function() {
+	var ife;
 
-	// Get endChop node
-	node = endChop;
-	do {
-		if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
-			break;
+	if (tinyMCE.isRealIE) {
+		ife = tinyMCE.selectedInstance.iframeElement;
 
-		endChop = node;
-	} while ((node = node.nextSibling ? node.nextSibling : node.parentNode));
+/*		if (ife._oldWidth) {
+			ife.style.width = ife._oldWidth;
+			ife.width = ife._oldWidth;
+		}*/
 
-	// Fix when only a image is within the TD
-	if (startChop.nodeName == "TD")
-		startChop = startChop.firstChild;
-
-	if (endChop.nodeName == "TD")
-		endChop = endChop.lastChild;
-
-	// If not in a block element
-	if (startBlock == null) {
-		// Delete selection
-		rng.deleteContents();
-		sel.removeAllRanges();
+		if (ife._oldHeight) {
+			ife.style.height = ife._oldHeight;
+			ife.height = ife._oldHeight;
+		}
+	}
+};
 
-		if (startChop != rootElm && endChop != rootElm) {
-			// Insert paragraph before
-			rngBefore = rng.cloneRange();
+/* file:jscripts/tiny_mce/classes/TinyMCE_Selection.class.js */
 
-			if (startChop == body)
-				rngBefore.setStart(startChop, 0);
-			else
-				rngBefore.setStartBefore(startChop);
+function TinyMCE_Selection(inst) {
+	this.instance = inst;
+};
 
-			paraBefore.appendChild(rngBefore.cloneContents());
+TinyMCE_Selection.prototype = {
+	getSelectedHTML : function() {
+		var inst = this.instance;
+		var e, r = this.getRng(), h;
 
-			// Insert paragraph after
-			if (endChop.parentNode.nodeName == blockName)
-				endChop = endChop.parentNode;
+		if (!r)
+			return null;
 
-			// If not after image
-			//if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")
-				rng.setEndAfter(endChop);
+		e = document.createElement("body");
 
-			if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")
-				rngBefore.setEndAfter(endChop);
+		if (r.cloneContents)
+			e.appendChild(r.cloneContents());
+		else if (typeof(r.item) != 'undefined' || typeof(r.htmlText) != 'undefined')
+			e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;
+		else
+			e.innerHTML = r.toString(); // Failed, use text for now
 
-			var contents = rng.cloneContents();
-			if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))
-				paraAfter.innerHTML = contents.firstChild.innerHTML;
-			else
-				paraAfter.appendChild(contents);
+		h = tinyMCE._cleanupHTML(inst, inst.contentDocument, inst.settings, e, e, false, true, false);
 
-			// Check if it's a empty paragraph
-			if (isEmpty(paraBefore))
-				paraBefore.innerHTML = "&nbsp;";
+		// When editing always use fonts internaly
+		//if (tinyMCE.getParam("convert_fonts_to_spans"))
+		//	tinyMCE.convertSpansToFonts(inst.getDoc());
 
-			// Check if it's a empty paragraph
-			if (isEmpty(paraAfter))
-				paraAfter.innerHTML = "&nbsp;";
+		return h;
+	},
 
-			// Delete old contents
-			rng.deleteContents();
-			rngAfter.deleteContents();
-			rngBefore.deleteContents();
+	getSelectedText : function() {
+		var inst = this.instance;
+		var d, r, s, t;
 
-			// Insert new paragraphs
-			paraAfter.normalize();
-			rngBefore.insertNode(paraAfter);
-			paraBefore.normalize();
-			rngBefore.insertNode(paraBefore);
+		if (tinyMCE.isIE) {
+			d = inst.getDoc();
 
-			// tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);
+			if (d.selection.type == "Text") {
+				r = d.selection.createRange();
+				t = r.text;
+			} else
+				t = '';
 		} else {
-			body.innerHTML = "<" + blockName + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + blockName + ">";
-			paraAfter = body.childNodes[1];
-		}
+			s = this.getSel();
 
-		this.selectNode(paraAfter, true, true);
+			if (s && s.toString)
+				t = s.toString();
+			else
+				t = '';
+		}
 
-		return true;
-	}
+		return t;
+	},
 
-	// Place first part within new paragraph
-	if (startChop.nodeName == blockName)
-		rngBefore.setStart(startChop, 0);
-	else
-		rngBefore.setStartBefore(startChop);
+	getBookmark : function(simple) {
+		var inst = this.instance;
+		var rng = this.getRng();
+		var doc = inst.getDoc(), b = inst.getBody();
+		var sp, le, s, e, nl, i, si, ei, w;
+		var trng, sx, sy, xx = -999999999, vp = inst.getViewPort();
+
+		sx = vp.left;
+		sy = vp.top;
+
+		if (tinyMCE.isSafari || tinyMCE.isOpera || simple)
+			return {rng : rng, scrollX : sx, scrollY : sy};
+
+		if (tinyMCE.isIE) {
+			if (rng.item) {
+				e = rng.item(0);
+
+				nl = b.getElementsByTagName(e.nodeName);
+				for (i=0; i<nl.length; i++) {
+					if (e == nl[i]) {
+						sp = i;
+						break;
+					}
+				}
 
-	rngBefore.setEnd(startNode, startOffset);
-	paraBefore.appendChild(rngBefore.cloneContents());
+				return {
+					tag : e.nodeName,
+					index : sp,
+					scrollX : sx,
+					scrollY : sy
+				};
+			} else {
+				trng = doc.body.createTextRange();
+				trng.moveToElementText(inst.getBody());
+				trng.collapse(true);
+				bp = Math.abs(trng.move('character', xx));
 
-	// Place secound part within new paragraph
-	rngAfter.setEndAfter(endChop);
-	rngAfter.setStart(endNode, endOffset);
-	var contents = rngAfter.cloneContents();
-
-	if (contents.firstChild && contents.firstChild.nodeName == blockName) {
-/*		var nodes = contents.firstChild.childNodes;
-		for (var i=0; i<nodes.length; i++) {
-			//tinyMCE.debug(nodes[i].nodeName);
-			if (nodes[i].nodeName != "BODY")
-				paraAfter.appendChild(nodes[i]);
-		}
-*/
-		paraAfter.innerHTML = contents.firstChild.innerHTML;
-	} else
-		paraAfter.appendChild(contents);
-
-	// Check if it's a empty paragraph
-	if (isEmpty(paraBefore))
-		paraBefore.innerHTML = "&nbsp;";
-
-	// Check if it's a empty paragraph
-	if (isEmpty(paraAfter))
-		paraAfter.innerHTML = "&nbsp;";
+				trng = rng.duplicate();
+				trng.collapse(true);
+				sp = Math.abs(trng.move('character', xx));
 
-	// Create a range around everything
-	var rng = doc.createRange();
+				trng = rng.duplicate();
+				trng.collapse(false);
+				le = Math.abs(trng.move('character', xx)) - sp;
 
-	if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) {
-		rng.setStartBefore(startChop.parentNode);
-	} else {
-		if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0)
-			rng.setStartBefore(rngBefore.startContainer);
-		else
-			rng.setStart(rngBefore.startContainer, rngBefore.startOffset);
-	}
+				return {
+					start : sp - bp,
+					length : le,
+					scrollX : sx,
+					scrollY : sy
+				};
+			}
+		}
 
-	if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName)
-		rng.setEndAfter(endChop.parentNode);
-	else
-		rng.setEnd(rngAfter.endContainer, rngAfter.endOffset);
+		if (tinyMCE.isGecko) {
+			s = this.getSel();
+			e = this.getFocusElement();
 
-	// Delete all contents and insert new paragraphs
-	rng.deleteContents();
-	rng.insertNode(paraAfter);
-	rng.insertNode(paraBefore);
-	//tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);
-
-	// Normalize
-	paraAfter.normalize();
-	paraBefore.normalize();
+			if (!s)
+				return null;
 
-	this.selectNode(paraAfter, true, true);
+			if (e && e.nodeName == 'IMG') {
+				/*nl = b.getElementsByTagName('IMG');
+				for (i=0; i<nl.length; i++) {
+					if (e == nl[i]) {
+						sp = i;
+						break;
+					}
+				}*/
 
-	return true;
-};
+				return {
+					start : -1,
+					end : -1,
+					index : sp,
+					scrollX : sx,
+					scrollY : sy
+				};
+			}
+
+			// Caret or selection
+			if (s.anchorNode == s.focusNode && s.anchorOffset == s.focusOffset) {
+				e = this._getPosText(b, s.anchorNode, s.focusNode);
+
+				if (!e)
+					return {scrollX : sx, scrollY : sy};
+
+				return {
+					start : e.start + s.anchorOffset,
+					end : e.end + s.focusOffset,
+					scrollX : sx,
+					scrollY : sy
+				};
+			} else {
+				e = this._getPosText(b, rng.startContainer, rng.endContainer);
 
-TinyMCEControl.prototype._handleBackSpace = function(evt_type) {
-	var doc = this.getDoc();
-	var sel = this.getSel();
-	if (sel == null)
-		return false;
+				if (!e)
+					return {scrollX : sx, scrollY : sy};
 
-	var rng = sel.getRangeAt(0);
-	var node = rng.startContainer;
-	var elm = node.nodeType == 3 ? node.parentNode : node;
+				return {
+					start : e.start + rng.startOffset,
+					end : e.end + rng.endOffset,
+					scrollX : sx,
+					scrollY : sy
+				};
+			}
+		}
 
-	if (node == null)
-		return;
+		return null;
+	},
 
-	// Empty node, wrap contents in paragraph
-	if (elm && elm.nodeName == "") {
-		var para = doc.createElement("p");
+	moveToBookmark : function(bookmark) {
+		var inst = this.instance;
+		var rng, nl, i, ex, b = inst.getBody(), sd;
+		var doc = inst.getDoc();
+		var win = inst.getWin();
+		var sel = this.getSel();
 
-		while (elm.firstChild)
-			para.appendChild(elm.firstChild);
+		if (!bookmark)
+			return false;
 
-		elm.parentNode.insertBefore(para, elm);
-		elm.parentNode.removeChild(elm);
+		if (tinyMCE.isSafari) {
+			sel.setBaseAndExtent(bookmark.rng.startContainer, bookmark.rng.startOffset, bookmark.rng.endContainer, bookmark.rng.endOffset);
+			return true;
+		}
 
-		var rng = rng.cloneRange();
-		rng.setStartBefore(node.nextSibling);
-		rng.setEndAfter(node.nextSibling);
-		rng.extractContents();
+		if (tinyMCE.isRealIE) {
+			if (bookmark.rng) {
+				try {
+					bookmark.rng.select();
+				} catch (ex) {
+					// Ignore
+				}
 
-		this.selectNode(node.nextSibling, true, true);
-	}
+				return true;
+			}
 
-	// Remove empty paragraphs
-	var para = tinyMCE.getParentBlockElement(node);
-	if (para != null && para.nodeName.toLowerCase() == 'p' && evt_type == "keypress") {
-		var htm = para.innerHTML;
-		var block = tinyMCE.getParentBlockElement(node);
+			win.focus();
 
-		// Empty node, we do the killing!!
-		if (htm == "" || htm == "&nbsp;" || block.nodeName.toLowerCase() == "li") {
-			var prevElm = para.previousSibling;
+			if (bookmark.tag) {
+				rng = b.createControlRange();
 
-			while (prevElm != null && prevElm.nodeType != 1)
-				prevElm = prevElm.previousSibling;
+				nl = b.getElementsByTagName(bookmark.tag);
 
-			if (prevElm == null)
-				return false;
+				if (nl.length > bookmark.index) {
+					try {
+						rng.addElement(nl[bookmark.index]);
+					} catch (ex) {
+						// Might be thrown if the node no longer exists
+					}
+				}
+			} else {
+				// Try/catch needed since this operation breaks when TinyMCE is placed in hidden divs/tabs
+				try {
+					// Incorrect bookmark
+					if (bookmark.start < 0)
+						return true;
 
-			// Get previous elements last text node
-			var nodes = tinyMCE.getNodeTree(prevElm, new Array(), 3);
-			var lastTextNode = nodes.length == 0 ? null : nodes[nodes.length-1];
-
-			// Select the last text node and move curstor to end
-			if (lastTextNode != null)
-				this.selectNode(lastTextNode, true, false, false);
+					rng = inst.getSel().createRange();
+					rng.moveToElementText(inst.getBody());
+					rng.collapse(true);
+					rng.moveStart('character', bookmark.start);
+					rng.moveEnd('character', bookmark.length);
+				} catch (ex) {
+					return true;
+				}
+			}
 
-			// Remove the empty paragrapsh
-			para.parentNode.removeChild(para);
+			rng.select();
 
-			//debug("within p element" + para.innerHTML);
-			//showHTML(this.getBody().innerHTML);
+			win.scrollTo(bookmark.scrollX, bookmark.scrollY);
 			return true;
 		}
-	}
 
-	// Remove BR elements
-/*	while (node != null && (node = node.nextSibling) != null) {
-		if (node.nodeName.toLowerCase() == 'br')
-			node.parentNode.removeChild(node);
-		else if (node.nodeType == 1) // Break at other element
-			break;
-	}*/
+		if (tinyMCE.isGecko || tinyMCE.isOpera) {
+			if (!sel)
+				return false;
+
+			if (bookmark.rng) {
+				sel.removeAllRanges();
+				sel.addRange(bookmark.rng);
+			}
 
-	//showHTML(this.getBody().innerHTML);
+			if (bookmark.start != -1 && bookmark.end != -1) {
+				try {
+					sd = this._getTextPos(b, bookmark.start, bookmark.end);
+					rng = doc.createRange();
+					rng.setStart(sd.startNode, sd.startOffset);
+					rng.setEnd(sd.endNode, sd.endOffset);
+					sel.removeAllRanges();
+					sel.addRange(rng);
+					win.focus();
+				} catch (ex) {
+					// Ignore
+				}
+			}
 
-	return false;
-};
+			/*
+			if (typeof(bookmark.index) != 'undefined') {
+				tinyMCE.selectElements(b, 'IMG', function (n) {
+					if (bookmark.index-- == 0) {
+						// Select image in Gecko here
+					}
 
-TinyMCEControl.prototype._insertSpace = function() {
-	return true;
-};
+					return false;
+				});
+			}
+			*/
 
-TinyMCEControl.prototype.autoResetDesignMode = function() {
-	// Add fix for tab/style.display none/block problems in Gecko
-	if (!tinyMCE.isMSIE && tinyMCE.settings['auto_reset_designmode'] && this.isHidden())
-		eval('try { this.getDoc().designMode = "On"; } catch(e) {}');
-};
+			win.scrollTo(bookmark.scrollX, bookmark.scrollY);
+			return true;
+		}
 
-TinyMCEControl.prototype.isHidden = function() {
-	if (tinyMCE.isMSIE)
 		return false;
+	},
 
-	var sel = this.getSel();
+	_getPosText : function(r, sn, en) {
+		var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
 
-	// Weird, wheres that cursor selection?
-	return (!sel || !sel.rangeCount || sel.rangeCount == 0);
-};
+		while ((n = w.nextNode()) != null) {
+			if (n == sn)
+				d.start = p;
 
-TinyMCEControl.prototype.isDirty = function() {
-	// Is content modified and not in a submit procedure
-	return this.startContent != tinyMCE.trim(this.getBody().innerHTML) && !tinyMCE.isNotDirty;
-};
+			if (n == en) {
+				d.end = p;
+				return d;
+			}
 
-TinyMCEControl.prototype._mergeElements = function(scmd, pa, ch, override) {
-	if (scmd == "removeformat") {
-		pa.className = "";
-		pa.style.cssText = "";
-		ch.className = "";
-		ch.style.cssText = "";
-		return;
-	}
+			p += n.nodeValue ? n.nodeValue.length : 0;
+		}
 
-	var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style"));
-	var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style"));
-	var className = tinyMCE.getAttrib(pa, "class");
+		return null;
+	},
 
-	className += " " + tinyMCE.getAttrib(ch, "class");
+	_getTextPos : function(r, sp, ep) {
+		var w = document.createTreeWalker(r, NodeFilter.SHOW_TEXT, null, false), n, p = 0, d = {};
 
-	if (override) {
-		for (var n in st) {
-			if (typeof(st[n]) == 'function')
-				continue;
+		while ((n = w.nextNode()) != null) {
+			p += n.nodeValue ? n.nodeValue.length : 0;
 
-			stc[n] = st[n];
-		}
-	} else {
-		for (var n in stc) {
-			if (typeof(stc[n]) == 'function')
-				continue;
+			if (p >= sp && !d.startNode) {
+				d.startNode = n;
+				d.startOffset = sp - (p - n.nodeValue.length);
+			}
 
-			st[n] = stc[n];
-		}
-	}
+			if (p >= ep) {
+				d.endNode = n;
+				d.endOffset = ep - (p - n.nodeValue.length);
 
-	tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st));
-	tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className));
-	ch.className = "";
-	ch.style.cssText = "";
-	ch.removeAttribute("class");
-	ch.removeAttribute("style");
-};
+				return d;
+			}
+		}
 
-TinyMCEControl.prototype.setUseCSS = function(b) {
-	var doc = this.getDoc();
-	try {doc.execCommand("useCSS", false, !b);} catch (ex) {}
-	try {doc.execCommand("styleWithCSS", false, b);} catch (ex) {}
+		return null;
+	},
 
-	if (!tinyMCE.getParam("table_inline_editing"))
-		try {doc.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {}
+	selectNode : function(node, collapse, select_text_node, to_start) {
+		var inst = this.instance, sel, rng, nodes;
 
-	if (!tinyMCE.getParam("object_resizing"))
-		try {doc.execCommand('enableObjectResizing', false, "false");} catch (ex) {}
-};
+		if (!node)
+			return;
 
-TinyMCEControl.prototype.execCommand = function(command, user_interface, value) {
-	var doc = this.getDoc();
-	var win = this.getWin();
-	var focusElm = this.getFocusElement();
+		if (typeof(collapse) == "undefined")
+			collapse = true;
 
-	if (this.lastSafariSelection && !new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) {
-		this.moveToBookmark(this.lastSafariSelection);
-		tinyMCE.selectedElement = this.lastSafariSelectedElement;
-	}
+		if (typeof(select_text_node) == "undefined")
+			select_text_node = false;
 
-	// Mozilla issue
-	if (!tinyMCE.isMSIE && !this.useCSS) {
-		this.setUseCSS(false);
-		this.useCSS = true;
-	}
+		if (typeof(to_start) == "undefined")
+			to_start = true;
 
-	//debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value);
-	this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks
+		if (inst.settings.auto_resize)
+			inst.resizeToContent();
 
-	// Call theme execcommand
-	if (tinyMCE._themeExecCommand(this.editorId, this.getBody(), command, user_interface, value))
-		return;
+		if (tinyMCE.isRealIE) {
+			rng = inst.getDoc().body.createTextRange();
 
-	// Fix align on images
-	if (focusElm && focusElm.nodeName == "IMG") {
-		var align = focusElm.getAttribute('align');
-		var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm;
+			try {
+				rng.moveToElementText(node);
 
-		switch (command) {
-			case "JustifyLeft":
-				if (align == 'left')
-					img.removeAttribute('align');
-				else
-					img.setAttribute('align', 'left');
+				if (collapse)
+					rng.collapse(to_start);
 
-				// Remove the div
-				var div = focusElm.parentNode;
-				if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
-					div.parentNode.replaceChild(img, div);
+				rng.select();
+			} catch (e) {
+				// Throws illigal agrument in MSIE some times
+			}
+		} else {
+			sel = this.getSel();
 
-				this.selectNode(img);
-				this.repaint();
-				tinyMCE.triggerNodeChange();
+			if (!sel)
 				return;
 
-			case "JustifyCenter":
-				img.removeAttribute('align');
+			if (tinyMCE.isSafari) {
+				sel.setBaseAndExtent(node, 0, node, node.innerText.length);
 
-				// Is centered
-				var div = tinyMCE.getParentElement(focusElm, "div");
-				if (div && div.style.textAlign == "center") {
-					// Remove div
-					if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
-						div.parentNode.replaceChild(img, div);
-				} else {
-					// Add div
-					var div = this.getDoc().createElement("div");
-					div.style.textAlign = 'center';
-					div.appendChild(img);
-					focusElm.parentNode.replaceChild(div, focusElm);
+				if (collapse) {
+					if (to_start)
+						sel.collapseToStart();
+					else
+						sel.collapseToEnd();
 				}
 
-				this.selectNode(img);
-				this.repaint();
-				tinyMCE.triggerNodeChange();
+				this.scrollToNode(node);
+
 				return;
+			}
 
-			case "JustifyRight":
-				if (align == 'right')
-					img.removeAttribute('align');
+			rng = inst.getDoc().createRange();
+
+			if (select_text_node) {
+				// Find first textnode in tree
+				nodes = tinyMCE.getNodeTree(node, new Array(), 3);
+				if (nodes.length > 0)
+					rng.selectNodeContents(nodes[0]);
 				else
-					img.setAttribute('align', 'right');
+					rng.selectNodeContents(node);
+			} else
+				rng.selectNode(node);
 
-				// Remove the div
-				var div = focusElm.parentNode;
-				if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode)
-					div.parentNode.replaceChild(img, div);
+			if (collapse) {
+				// Special treatment of textnode collapse
+				if (!to_start && node.nodeType == 3) {
+					rng.setStart(node, node.nodeValue.length);
+					rng.setEnd(node, node.nodeValue.length);
+				} else
+					rng.collapse(to_start);
+			}
 
-				this.selectNode(img);
-				this.repaint();
-				tinyMCE.triggerNodeChange();
-				return;
+			sel.removeAllRanges();
+			sel.addRange(rng);
 		}
-	}
-
-	if (tinyMCE.settings['force_br_newlines']) {
-		var alignValue = "";
-
-		if (doc.selection.type != "Control") {
-			switch (command) {
-					case "JustifyLeft":
-						alignValue = "left";
-						break;
 
-					case "JustifyCenter":
-						alignValue = "center";
-						break;
+		this.scrollToNode(node);
 
-					case "JustifyFull":
-						alignValue = "justify";
-						break;
+		// Set selected element
+		tinyMCE.selectedElement = null;
+		if (node.nodeType == 1)
+			tinyMCE.selectedElement = node;
+	},
 
-					case "JustifyRight":
-						alignValue = "right";
-						break;
-			}
+	scrollToNode : function(node) {
+		var inst = this.instance, w = inst.getWin(), vp = inst.getViewPort(), pos = tinyMCE.getAbsPosition(node), cvp, p, cwin;
 
-			if (alignValue != "") {
-				var rng = doc.selection.createRange();
+		// Only scroll if out of visible area
+		if (pos.absLeft < vp.left || pos.absLeft > vp.left + vp.width || pos.absTop < vp.top || pos.absTop > vp.top + (vp.height-25))
+			w.scrollTo(pos.absLeft, pos.absTop - vp.height + 25);
 
-				if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null)
-					divElm.setAttribute("align", alignValue);
-				else if (rng.pasteHTML && rng.htmlText.length > 0)
-					rng.pasteHTML('<div align="' + alignValue + '">' + rng.htmlText + "</div>");
+		// Scroll container window
+		if (inst.settings.auto_resize) {
+			cwin = inst.getContainerWin();
+			cvp = tinyMCE.getViewPort(cwin);
+			p = this.getAbsPosition(node);
 
-				tinyMCE.triggerNodeChange();
-				return;
-			}
+			if (p.absLeft < cvp.left || p.absLeft > cvp.left + cvp.width || p.absTop < cvp.top || p.absTop > cvp.top + cvp.height)
+				cwin.scrollTo(p.absLeft, p.absTop - cvp.height + 25);
 		}
-	}
+	},
 
-	switch (command) {
-		case "mceRepaint":
-			this.repaint();
-			return true;
+	getAbsPosition : function(n) {
+		var pos = tinyMCE.getAbsPosition(n), ipos = tinyMCE.getAbsPosition(this.instance.iframeElement);
 
-		case "mceStoreSelection":
-			this.selectionBookmark = this.getBookmark();
-			return true;
+		return {
+			absLeft : ipos.absLeft + pos.absLeft,
+			absTop : ipos.absTop + pos.absTop
+		};
+	},
 
-		case "mceRestoreSelection":
-			this.moveToBookmark(this.selectionBookmark);
-			return true;
+	getSel : function() {
+		var inst = this.instance;
 
-		case "InsertUnorderedList":
-		case "InsertOrderedList":
-			var tag = (command == "InsertUnorderedList") ? "ul" : "ol";
+		if (tinyMCE.isRealIE)
+			return inst.getDoc().selection;
 
-			if (tinyMCE.isSafari)
-				this.execCommand("mceInsertContent", false, "<" + tag + "><li>&nbsp;</li><" + tag + ">");
-			else
-				this.getDoc().execCommand(command, user_interface, value);
+		return inst.contentWindow.getSelection();
+	},
 
-			tinyMCE.triggerNodeChange();
-			break;
+	getRng : function() {
+		var s = this.getSel();
 
-		case "Strikethrough":
-			if (tinyMCE.isSafari)
-				this.execCommand("mceInsertContent", false, "<strike>" + this.getSelectedHTML() + "</strike>");
-			else
-				this.getDoc().execCommand(command, user_interface, value);
+		if (s == null)
+			return null;
 
-			tinyMCE.triggerNodeChange();
-			break;
+		if (tinyMCE.isRealIE)
+			return s.createRange();
 
-		case "mceSelectNode":
-			this.selectNode(value);
-			tinyMCE.triggerNodeChange();
-			tinyMCE.selectedNode = value;
-			break;
+		if (tinyMCE.isSafari && !s.getRangeAt)
+			return '' + window.getSelection();
 
-		case "FormatBlock":
-			if (value == null || value == "") {
-				var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address");
+		if (s.rangeCount > 0)
+			return s.getRangeAt(0);
 
-				if (elm)
-					this.execCommand("mceRemoveNode", false, elm);
-			} else
-				this.getDoc().execCommand("FormatBlock", false, value);
+		return null;
+	},
 
-			tinyMCE.triggerNodeChange();
+	isCollapsed : function() {
+		var r = this.getRng();
 
-			break;
+		if (r.item)
+			return false;
 
-		case "mceRemoveNode":
-			if (!value)
-				value = tinyMCE.getParentElement(this.getFocusElement());
+		return r.boundingWidth == 0 || this.getSel().isCollapsed;
+	},
 
-			if (tinyMCE.isMSIE) {
-				value.outerHTML = value.innerHTML;
-			} else {
-				var rng = value.ownerDocument.createRange();
-				rng.setStartBefore(value);
-				rng.setEndAfter(value);
-				rng.deleteContents();
-				rng.insertNode(rng.createContextualFragment(value.innerHTML));
-			}
+	collapse : function(b) {
+		var r = this.getRng(), s = this.getSel();
 
-			tinyMCE.triggerNodeChange();
+		if (r.select) {
+			r.collapse(b);
+			r.select();
+		} else {
+			if (b)
+				s.collapseToStart();
+			else
+				s.collapseToEnd();
+		}
+	},
 
-			break;
+	getFocusElement : function() {
+		var inst = this.instance, doc, rng, sel, elm;
 
-		case "mceSelectNodeDepth":
-			var parentNode = this.getFocusElement();
-			for (var i=0; parentNode; i++) {
-				if (parentNode.nodeName.toLowerCase() == "body")
-					break;
+		if (tinyMCE.isRealIE) {
+			doc = inst.getDoc();
+			rng = doc.selection.createRange();
 
-				if (parentNode.nodeName.toLowerCase() == "#text") {
-					i--;
-					parentNode = parentNode.parentNode;
-					continue;
-				}
+	//		if (rng.collapse)
+	//			rng.collapse(true);
 
-				if (i == value) {
-					this.selectNode(parentNode, false);
-					tinyMCE.triggerNodeChange();
-					tinyMCE.selectedNode = parentNode;
-					return;
-				}
+			elm = rng.item ? rng.item(0) : rng.parentElement();
+		} else {
+			if (!tinyMCE.isSafari && inst.isHidden())
+				return inst.getBody();
 
-				parentNode = parentNode.parentNode;
-			}
+			sel = this.getSel();
+			rng = this.getRng();
 
-			break;
+			if (!sel || !rng)
+				return null;
 
-		case "SetStyleInfo":
-			var rng = this.getRng();
-			var sel = this.getSel();
-			var scmd = value['command'];
-			var sname = value['name'];
-			var svalue = value['value'] == null ? '' : value['value'];
-			//var svalue = value['value'] == null ? '' : value['value'];
-			var wrapper = value['wrapper'] ? value['wrapper'] : "span";
-			var parentElm = null;
-			var invalidRe = new RegExp("^BODY|HTML$", "g");
-			var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null;
-
-			// Whole element selected check
-			if (tinyMCE.isMSIE) {
-				// Control range
-				if (rng.item)
-					parentElm = rng.item(0);
-				else {
-					var pelm = rng.parentElement();
-					var prng = doc.selection.createRange();
-					prng.moveToElementText(pelm);
-
-					if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) {
-						if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName))
-							parentElm = pelm;
+			elm = rng.commonAncestorContainer;
+			//elm = (sel && sel.anchorNode) ? sel.anchorNode : null;
+
+			// Handle selection a image or other control like element such as anchors
+			if (!rng.collapsed) {
+				// Is selection small
+				if (rng.startContainer == rng.endContainer) {
+					if (rng.startOffset - rng.endOffset < 2) {
+						if (rng.startContainer.hasChildNodes())
+							elm = rng.startContainer.childNodes[rng.startOffset];
 					}
 				}
-			} else {
-				var felm = this.getFocusElement();
-				if (sel.isCollapsed || (/td|tr|tbody|table/ig.test(felm.nodeName) && sel.anchorNode == felm.parentNode))
-					parentElm = felm;
 			}
 
-			// Whole element selected
-			if (parentElm && !invalidRe.test(parentElm.nodeName)) {
-				if (scmd == "setstyle")
-					tinyMCE.setStyleAttrib(parentElm, sname, svalue);
+			// Get the element parent of the node
+			elm = tinyMCE.getParentElement(elm);
+
+			//if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
+			//	elm = tinyMCE.selectedElement;
+		}
+
+		return elm;
+	}
+
+	};
+
+/* file:jscripts/tiny_mce/classes/TinyMCE_UndoRedo.class.js */
+
+function TinyMCE_UndoRedo(inst) {
+	this.instance = inst;
+	this.undoLevels = new Array();
+	this.undoIndex = 0;
+	this.typingUndoIndex = -1;
+	this.undoRedo = true;
+};
+
+TinyMCE_UndoRedo.prototype = {
+	add : function(l) {
+		var b, customUndoLevels, newHTML, inst = this.instance, i, ul, ur;
+
+		if (l) {
+			this.undoLevels[this.undoLevels.length] = l;
+			return true;
+		}
 
-				if (scmd == "setattrib")
-					tinyMCE.setAttrib(parentElm, sname, svalue);
+		if (this.typingUndoIndex != -1) {
+			this.undoIndex = this.typingUndoIndex;
 
-				if (scmd == "removeformat") {
-					parentElm.style.cssText = '';
-					tinyMCE.setAttrib(parentElm, 'class', '');
-				}
+			if (tinyMCE.typingUndoIndex != -1)
+				tinyMCE.undoIndex = tinyMCE.typingUndoIndex;
+		}
 
-				// Remove style/attribs from all children
-				var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1);
-				for (var z=0; z<ch.length; z++) {
-					if (ch[z] == parentElm)
-						continue;
+		newHTML = tinyMCE.trim(inst.getBody().innerHTML);
+		if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) {
+			//tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content);
 
-					if (scmd == "setstyle")
-						tinyMCE.setStyleAttrib(ch[z], sname, '');
+			tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst);
 
-					if (scmd == "setattrib")
-						tinyMCE.setAttrib(ch[z], sname, '');
+			// Time to compress
+			customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
+			if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
+				for (i=0; i<this.undoLevels.length-1; i++)
+					this.undoLevels[i] = this.undoLevels[i+1];
 
-					if (scmd == "removeformat") {
-						ch[z].style.cssText = '';
-						tinyMCE.setAttrib(ch[z], 'class', '');
-					}
-				}
-			} else {
-				doc.execCommand("fontname", false, "#mce_temp_font#");
-				var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#");
+				this.undoLevels.length--;
+				this.undoIndex--;
 
-				// Change them all
-				for (var x=0; x<elementArray.length; x++) {
-					elm = elementArray[x];
-					if (elm) {
-						var spanElm = doc.createElement(wrapper);
+				// Todo: Implement global undo/redo logic here
+			}
 
-						if (scmd == "setstyle")
-							tinyMCE.setStyleAttrib(spanElm, sname, svalue);
+			b = inst.undoBookmark;
 
-						if (scmd == "setattrib")
-							tinyMCE.setAttrib(spanElm, sname, svalue);
+			if (!b)
+				b = inst.selection.getBookmark();
 
-						if (scmd == "removeformat") {
-							spanElm.style.cssText = '';
-							tinyMCE.setAttrib(spanElm, 'class', '');
-						}
+			this.undoIndex++;
+			this.undoLevels[this.undoIndex] = {
+				content : newHTML,
+				bookmark : b
+			};
 
-						if (elm.hasChildNodes()) {
-							for (var i=0; i<elm.childNodes.length; i++)
-								spanElm.appendChild(elm.childNodes[i].cloneNode(true));
-						}
+			// Remove all above from global undo/redo
+			ul = tinyMCE.undoLevels;
+			for (i=tinyMCE.undoIndex + 1; i<ul.length; i++) {
+				ur = ul[i].undoRedo;
 
-						spanElm.setAttribute("mce_new", "true");
-						elm.parentNode.replaceChild(spanElm, elm);
+				if (ur.undoIndex == ur.undoLevels.length -1)
+					ur.undoIndex--;
 
-						// Remove style/attribs from all children
-						var ch = tinyMCE.getNodeTree(spanElm, new Array(), 1);
-						for (var z=0; z<ch.length; z++) {
-							if (ch[z] == spanElm)
-								continue;
+				ur.undoLevels.length--;
+			}
 
-							if (scmd == "setstyle")
-								tinyMCE.setStyleAttrib(ch[z], sname, '');
+			// Add global undo level
+			tinyMCE.undoLevels[tinyMCE.undoIndex++] = inst;
+			tinyMCE.undoLevels.length = tinyMCE.undoIndex;
 
-							if (scmd == "setattrib")
-								tinyMCE.setAttrib(ch[z], sname, '');
+			this.undoLevels.length = this.undoIndex + 1;
 
-							if (scmd == "removeformat") {
-								ch[z].style.cssText = '';
-								tinyMCE.setAttrib(ch[z], 'class', '');
-							}
-						}
-					}
-				}
-			}
+			return true;
+		}
 
-			// Cleaup wrappers
-			var nodes = doc.getElementsByTagName(wrapper);
-			for (var i=nodes.length-1; i>=0; i--) {
-				var elm = nodes[i];
-				var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true";
-
-				elm.removeAttribute("mce_new");
-
-				// Is only child a element
-				if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) {
-					//tinyMCE.debug("merge1" + isNew);
-					this._mergeElements(scmd, elm, elm.childNodes[0], isNew);
-					continue;
-				}
+		return false;
+	},
 
-				// Is I the only child
-				if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) {
-					//tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName);
-					if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName))
-						this._mergeElements(scmd, elm.parentNode, elm, false);
-				}
-			}
+	undo : function() {
+		var inst = this.instance;
 
-			// Remove empty wrappers
-			var nodes = doc.getElementsByTagName(wrapper);
-			for (var i=nodes.length-1; i>=0; i--) {
-				var elm = nodes[i];
-				var isEmpty = true;
+		// Do undo
+		if (this.undoIndex > 0) {
+			this.undoIndex--;
 
-				// Check if it has any attribs
-				var tmp = doc.createElement("body");
-				tmp.appendChild(elm.cloneNode(false));
+			tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
+			inst.repaint();
 
-				// Is empty span, remove it
-				tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), '');
-				//tinyMCE.debug(tmp.innerHTML);
-				if (new RegExp('<span>', 'gi').test(tmp.innerHTML)) {
-					for (var x=0; x<elm.childNodes.length; x++) {
-						if (elm.parentNode != null)
-							elm.parentNode.insertBefore(elm.childNodes[x].cloneNode(true), elm);
-					}
+			if (inst.settings.custom_undo_redo_restore_selection)
+				inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
+		}
+	},
 
-					elm.parentNode.removeChild(elm);
-				}
-			}
+	redo : function() {
+		var inst = this.instance;
 
-			// Re add the visual aids
-			if (scmd == "removeformat")
-				tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
+		tinyMCE.execCommand("mceEndTyping");
 
-			tinyMCE.triggerNodeChange();
+		if (this.undoIndex < (this.undoLevels.length-1)) {
+			this.undoIndex++;
 
-			break;
+			tinyMCE.setInnerHTML(inst.getBody(), this.undoLevels[this.undoIndex].content);
+			inst.repaint();
 
-		case "FontName":
-			if (value == null) {
-				var s = this.getSel();
-
-				// Find font and select it
-				if (tinyMCE.isGecko && s.isCollapsed) {
-					var f = tinyMCE.getParentElement(this.getFocusElement(), "font");
-
-					if (f != null)
-						this.selectNode(f, false);
-				}
-
-				// Remove format
-				this.getDoc().execCommand("RemoveFormat", false, null);
-
-				// Collapse range if font was found
-				if (f != null && tinyMCE.isGecko) {
-					var r = this.getRng().cloneRange();
-					r.collapse(true);
-					s.removeAllRanges();
-					s.addRange(r);
-				}
-			} else
-				this.getDoc().execCommand('FontName', false, value);
+			if (inst.settings.custom_undo_redo_restore_selection)
+				inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark);
+		}
 
-			if (tinyMCE.isGecko)
-				window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+		tinyMCE.triggerNodeChange();
+	}
 
-			return;
+	};
 
-		case "FontSize":
-			this.getDoc().execCommand('FontSize', false, value);
+/* file:jscripts/tiny_mce/classes/TinyMCE_ForceParagraphs.class.js */
 
-			if (tinyMCE.isGecko)
-				window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
+var TinyMCE_ForceParagraphs = {
+	_insertPara : function(inst, e) {
+		var doc = inst.getDoc(), sel = inst.getSel(), body = inst.getBody(), win = inst.contentWindow, rng = sel.getRangeAt(0);
+		var rootElm = doc.documentElement, blockName = "P", startNode, endNode, startBlock, endBlock;
+		var rngBefore, rngAfter, direct, startNode, startOffset, endNode, endOffset, b = tinyMCE.isOpera ? inst.selection.getBookmark() : null;
+		var paraBefore, paraAfter, startChop, endChop, contents;
 
-			return;
+		function isEmpty(para) {
+			function isEmptyHTML(html) {
+				return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == "";
+			}
 
-		case "forecolor":
-			this.getDoc().execCommand('forecolor', false, value);
-			break;
+			// Check for images
+			if (para.getElementsByTagName("img").length > 0)
+				return false;
 
-		case "HiliteColor":
-			if (tinyMCE.isGecko) {
-				this.setUseCSS(true);
-				this.getDoc().execCommand('hilitecolor', false, value);
-				this.setUseCSS(false);
-			} else
-				this.getDoc().execCommand('BackColor', false, value);
-			break;
+			// Check for tables
+			if (para.getElementsByTagName("table").length > 0)
+				return false;
 
-		case "Cut":
-		case "Copy":
-		case "Paste":
-			var cmdFailed = false;
-
-			// Try executing command
-			eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');
-
-			if (tinyMCE.isOpera && cmdFailed)
-				alert('Currently not supported by your browser, use keyboard shortcuts instead.');
-
-			// Alert error in gecko if command failed
-			if (tinyMCE.isGecko && cmdFailed) {
-				// Confirm more info
-				if (confirm(tinyMCE.getLang('lang_clipboard_msg')))
-					window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');
+			// Check for HRs
+			if (para.getElementsByTagName("hr").length > 0)
+				return false;
 
-				return;
-			} else
-				tinyMCE.triggerNodeChange();
-		break;
+			// Check all textnodes
+			var nodes = tinyMCE.getNodeTree(para, new Array(), 3);
+			for (var i=0; i<nodes.length; i++) {
+				if (!isEmptyHTML(nodes[i].nodeValue))
+					return false;
+			}
 
-		case "mceSetContent":
-			if (!value)
-				value = "";
-
-			// Call custom cleanup code
-			value = tinyMCE.storeAwayURLs(value);
-			//value = tinyMCE._customCleanup(this, "insert_to_editor", value);
-			tinyMCE._setHTML(doc, value);
-			tinyMCE.setInnerHTML(doc.body, tinyMCE._cleanupHTML(this, doc, tinyMCE.settings, doc.body));
-			this.convertAllRelativeURLs();
-			tinyMCE.handleVisualAid(doc.body, true, this.visualAid, this);
-			tinyMCE._setEventsEnabled(doc.body, false);
+			// No images, no tables, no hrs, no text content then it's empty
 			return true;
+		}
 
-		case "mceLink":
-			var selectedText = "";
+	//	tinyMCE.debug(body.innerHTML);
 
-			if (tinyMCE.isMSIE) {
-				var rng = doc.selection.createRange();
-				selectedText = rng.text;
-			} else
-				selectedText = this.getSel().toString();
+	//	debug(e.target, sel.anchorNode.nodeName, sel.focusNode.nodeName, rng.startContainer, rng.endContainer, rng.commonAncestorContainer, sel.anchorOffset, sel.focusOffset, rng.toString());
 
-			if (!tinyMCE.linkElement) {
-				if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0))
-					return;
-			}
+		// Setup before range
+		rngBefore = doc.createRange();
+		rngBefore.setStart(sel.anchorNode, sel.anchorOffset);
+		rngBefore.collapse(true);
 
-			var href = "", target = "", title = "", onclick = "", action = "insert", style_class = "";
+		// Setup after range
+		rngAfter = doc.createRange();
+		rngAfter.setStart(sel.focusNode, sel.focusOffset);
+		rngAfter.collapse(true);
 
-			if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a")
-				tinyMCE.linkElement = tinyMCE.selectedElement;
+		// Setup start/end points
+		direct = rngBefore.compareBoundaryPoints(rngBefore.START_TO_END, rngAfter) < 0;
+		startNode = direct ? sel.anchorNode : sel.focusNode;
+		startOffset = direct ? sel.anchorOffset : sel.focusOffset;
+		endNode = direct ? sel.focusNode : sel.anchorNode;
+		endOffset = direct ? sel.focusOffset : sel.anchorOffset;
 
-			// Is anchor not a link
-			if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "")
-				tinyMCE.linkElement = null;
+		startNode = startNode.nodeName == "BODY" ? startNode.firstChild : startNode;
+		endNode = endNode.nodeName == "BODY" ? endNode.firstChild : endNode;
 
-			if (tinyMCE.linkElement) {
-				href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href');
-				target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target');
-				title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title');
-                onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
-				style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class');
+		// Get block elements
+		startBlock = inst.getParentBlockElement(startNode);
+		endBlock = inst.getParentBlockElement(endNode);
 
-				// Try old onclick to if copy/pasted content
-				if (onclick == "")
-					onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick');
+		// If absolute force paragraph generation within
+		if (startBlock && new RegExp('absolute|relative|static', 'gi').test(startBlock.style.position))
+			startBlock = null;
 
-				onclick = tinyMCE.cleanupEventStr(onclick);
+		if (endBlock && new RegExp('absolute|relative|static', 'gi').test(endBlock.style.position))
+			endBlock = null;
 
-				href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
+		// Use current block name
+		if (startBlock != null) {
+			blockName = startBlock.nodeName;
 
-				// Use mce_href if defined
-				mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href');
-				if (mceRealHref != "") {
-					href = mceRealHref;
+			// Use P instead
+			if (blockName == "TD" || blockName == "TABLE" || (blockName == "DIV" && new RegExp('left|right', 'gi').test(startBlock.style.cssFloat)))
+				blockName = "P";
+		}
 
-					if (tinyMCE.getParam('convert_urls'))
-						href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);");
-				}
+		// Within a list use normal behaviour
+		if (tinyMCE.getParentElement(startBlock, "OL,UL", null, body) != null)
+			return false;
 
-				action = "update";
-			}
+		// Within a table create new paragraphs
+		if ((startBlock != null && startBlock.nodeName == "TABLE") || (endBlock != null && endBlock.nodeName == "TABLE"))
+			startBlock = endBlock = null;
+
+		// Setup new paragraphs
+		paraBefore = (startBlock != null && startBlock.nodeName == blockName) ? startBlock.cloneNode(false) : doc.createElement(blockName);
+		paraAfter = (endBlock != null && endBlock.nodeName == blockName) ? endBlock.cloneNode(false) : doc.createElement(blockName);
+
+		// Is header, then force paragraph under
+		if (/^(H[1-6])$/.test(blockName))
+			paraAfter = doc.createElement("p");
+
+		// Setup chop nodes
+		startChop = startNode;
+		endChop = endNode;
+
+		// Get startChop node
+		node = startChop;
+		do {
+			if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
+				break;
 
-			if (this.settings['insertlink_callback']) {
-				var returnVal = eval(this.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);");
-				if (returnVal && returnVal['href'])
-					tinyMCE.insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']);
-			} else {
-				tinyMCE.openWindow(this.insertLinkTemplate, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"});
-			}
-		break;
+			startChop = node;
+		} while ((node = node.previousSibling ? node.previousSibling : node.parentNode));
 
-		case "mceImage":
-			var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = "";
-			var title = "", onmouseover = "", onmouseout = "", action = "insert";
-			var img = tinyMCE.imgElement;
+		// Get endChop node
+		node = endChop;
+		do {
+			if (node == body || node.nodeType == 9 || tinyMCE.isBlockElement(node))
+				break;
 
-			if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") {
-				img = tinyMCE.selectedElement;
-				tinyMCE.imgElement = img;
-			}
+			endChop = node;
+		} while ((node = node.nextSibling ? node.nextSibling : node.parentNode));
 
-			if (img) {
-				// Is it a internal MCE visual aid image, then skip this one.
-				if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0)
-					return;
+		// Fix when only a image is within the TD
+		if (startChop.nodeName == "TD")
+			startChop = startChop.firstChild;
+
+		if (endChop.nodeName == "TD")
+			endChop = endChop.lastChild;
+
+		// If not in a block element
+		if (startBlock == null) {
+			// Delete selection
+			rng.deleteContents();
 
-				src = tinyMCE.getAttrib(img, 'src');
-				alt = tinyMCE.getAttrib(img, 'alt');
+			if (!tinyMCE.isSafari)
+				sel.removeAllRanges();
 
-				// Try polling out the title
-				if (alt == "")
-					alt = tinyMCE.getAttrib(img, 'title');
+			if (startChop != rootElm && endChop != rootElm) {
+				// Insert paragraph before
+				rngBefore = rng.cloneRange();
 
-				// Fix width/height attributes if the styles is specified
-				if (tinyMCE.isGecko) {
-					var w = img.style.width;
-					if (w != null && w != "")
-						img.setAttribute("width", w);
+				if (startChop == body)
+					rngBefore.setStart(startChop, 0);
+				else
+					rngBefore.setStartBefore(startChop);
 
-					var h = img.style.height;
-					if (h != null && h != "")
-						img.setAttribute("height", h);
-				}
+				paraBefore.appendChild(rngBefore.cloneContents());
 
-				border = tinyMCE.getAttrib(img, 'border');
-				hspace = tinyMCE.getAttrib(img, 'hspace');
-				vspace = tinyMCE.getAttrib(img, 'vspace');
-				width = tinyMCE.getAttrib(img, 'width');
-				height = tinyMCE.getAttrib(img, 'height');
-				align = tinyMCE.getAttrib(img, 'align');
-                onmouseover = tinyMCE.getAttrib(img, 'onmouseover');
-                onmouseout = tinyMCE.getAttrib(img, 'onmouseout');
-                title = tinyMCE.getAttrib(img, 'title');
+				// Insert paragraph after
+				if (endChop.parentNode.nodeName == blockName)
+					endChop = endChop.parentNode;
 
-				// Is realy specified?
-				if (tinyMCE.isMSIE) {
-					width = img.attributes['width'].specified ? width : "";
-					height = img.attributes['height'].specified ? height : "";
-				}
+				// If not after image
+				//if (rng.startContainer.nodeName != "BODY" && rng.endContainer.nodeName != "BODY")
+					rng.setEndAfter(endChop);
 
-				onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));
-				onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));
+				if (endChop.nodeName != "#text" && endChop.nodeName != "BODY")
+					rngBefore.setEndAfter(endChop);
 
-				src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
+				contents = rng.cloneContents();
+				if (contents.firstChild && (contents.firstChild.nodeName == blockName || contents.firstChild.nodeName == "BODY"))
+					paraAfter.innerHTML = contents.firstChild.innerHTML;
+				else
+					paraAfter.appendChild(contents);
 
-				// Use mce_src if defined
-				mceRealSrc = tinyMCE.getAttrib(img, 'mce_src');
-				if (mceRealSrc != "") {
-					src = mceRealSrc;
+				// Check if it's a empty paragraph
+				if (isEmpty(paraBefore))
+					paraBefore.innerHTML = "&nbsp;";
 
-					if (tinyMCE.getParam('convert_urls'))
-						src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);");
-				}
+				// Check if it's a empty paragraph
+				if (isEmpty(paraAfter))
+					paraAfter.innerHTML = "&nbsp;";
 
-				if (onmouseover != "")
-					onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);");
+				// Delete old contents
+				rng.deleteContents();
+				rngAfter.deleteContents();
+				rngBefore.deleteContents();
 
-				if (onmouseout != "")
-					onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);");
+				// Insert new paragraphs
+				if (tinyMCE.isOpera) {
+					paraBefore.normalize();
+					rngBefore.insertNode(paraBefore);
+					paraAfter.normalize();
+					rngBefore.insertNode(paraAfter);
+				} else {
+					paraAfter.normalize();
+					rngBefore.insertNode(paraAfter);
+					paraBefore.normalize();
+					rngBefore.insertNode(paraBefore);
+				}
 
-				action = "update";
+				//tinyMCE.debug("1: ", paraBefore.innerHTML, paraAfter.innerHTML);
+			} else {
+				body.innerHTML = "<" + blockName + ">&nbsp;</" + blockName + "><" + blockName + ">&nbsp;</" + blockName + ">";
+				paraAfter = body.childNodes[1];
 			}
 
-			if (this.settings['insertimage_callback']) {
-				var returnVal = eval(this.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");
-				if (returnVal && returnVal['src'])
-					tinyMCE.insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']);
-			} else
-				tinyMCE.openWindow(this.insertImageTemplate, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"});
-		break;
-
-		case "mceCleanup":
-			tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML);
-			tinyMCE.setInnerHTML(this.getBody(), tinyMCE._cleanupHTML(this, this.contentDocument, this.settings, this.getBody(), this.visualAid));
-			this.convertAllRelativeURLs();
-			tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
-			tinyMCE._setEventsEnabled(this.getBody(), false);
-			this.repaint();
-			tinyMCE.triggerNodeChange();
-		break;
-
-		case "mceReplaceContent":
-			this.getWin().focus();
-
-			var selectedText = "";
-
-			if (tinyMCE.isMSIE) {
-				var rng = doc.selection.createRange();
-				selectedText = rng.text;
-			} else
-				selectedText = this.getSel().toString();
+			inst.selection.moveToBookmark(b);
+			inst.selection.selectNode(paraAfter, true, true);
 
-			if (selectedText.length > 0) {
-				value = tinyMCE.replaceVar(value, "selection", selectedText);
-				tinyMCE.execCommand('mceInsertContent', false, value);
-			}
+			return true;
+		}
 
-			tinyMCE.triggerNodeChange();
-		break;
+		// Place first part within new paragraph
+		if (startChop.nodeName == blockName)
+			rngBefore.setStart(startChop, 0);
+		else
+			rngBefore.setStartBefore(startChop);
 
-		case "mceSetAttribute":
-			if (typeof(value) == 'object') {
-				var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets'];
-				var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms);
+		rngBefore.setEnd(startNode, startOffset);
+		paraBefore.appendChild(rngBefore.cloneContents());
 
-				if (targetNode) {
-					targetNode.setAttribute(value['name'], value['value']);
-					tinyMCE.triggerNodeChange();
-				}
+		// Place secound part within new paragraph
+		rngAfter.setEndAfter(endChop);
+		rngAfter.setStart(endNode, endOffset);
+		contents = rngAfter.cloneContents();
+
+		if (contents.firstChild && contents.firstChild.nodeName == blockName) {
+	/*		var nodes = contents.firstChild.childNodes;
+			for (var i=0; i<nodes.length; i++) {
+				//tinyMCE.debug(nodes[i].nodeName);
+				if (nodes[i].nodeName != "BODY")
+					paraAfter.appendChild(nodes[i]);
 			}
-		break;
+	*/
+			paraAfter.innerHTML = contents.firstChild.innerHTML;
+		} else
+			paraAfter.appendChild(contents);
 
-		case "mceSetCSSClass":
-			this.execCommand("SetStyleInfo", false, {command : "setattrib", name : "class", value : value});
-		break;
+		// Check if it's a empty paragraph
+		if (isEmpty(paraBefore))
+			paraBefore.innerHTML = "&nbsp;";
 
-		case "mceInsertRawHTML":
-			var key = 'tiny_mce_marker';
+		// Check if it's a empty paragraph
+		if (isEmpty(paraAfter))
+			paraAfter.innerHTML = "&nbsp;";
 
-			this.execCommand('mceBeginUndoLevel');
+		// Create a range around everything
+		rng = doc.createRange();
 
-			// Insert marker key
-			this.execCommand('mceInsertContent', false, key);
+		if (!startChop.previousSibling && startChop.parentNode.nodeName.toUpperCase() == blockName) {
+			rng.setStartBefore(startChop.parentNode);
+		} else {
+			if (rngBefore.startContainer.nodeName.toUpperCase() == blockName && rngBefore.startOffset == 0)
+				rng.setStartBefore(rngBefore.startContainer);
+			else
+				rng.setStart(rngBefore.startContainer, rngBefore.startOffset);
+		}
 
-			// Store away scroll pos
-			var scrollX = this.getDoc().body.scrollLeft + this.getDoc().documentElement.scrollLeft;
-			var scrollY = this.getDoc().body.scrollTop + this.getDoc().documentElement.scrollTop;
+		if (!endChop.nextSibling && endChop.parentNode.nodeName.toUpperCase() == blockName)
+			rng.setEndAfter(endChop.parentNode);
+		else
+			rng.setEnd(rngAfter.endContainer, rngAfter.endOffset);
 
-			// Find marker and replace with RAW HTML
-			var html = this.getBody().innerHTML;
-			if ((pos = html.indexOf(key)) != -1)
-				tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length));
+		// Delete all contents and insert new paragraphs
+		rng.deleteContents();
 
-			// Restore scoll pos
-			this.contentWindow.scrollTo(scrollX, scrollY);
+		if (tinyMCE.isOpera) {
+			rng.insertNode(paraBefore);
+			rng.insertNode(paraAfter);
+		} else {
+			rng.insertNode(paraAfter);
+			rng.insertNode(paraBefore);
+		}
 
-			this.execCommand('mceEndUndoLevel');
+		//tinyMCE.debug("2", paraBefore.innerHTML, paraAfter.innerHTML);
 
-			break;
+		// Normalize
+		paraAfter.normalize();
+		paraBefore.normalize();
 
-		case "mceInsertContent":
-			var insertHTMLFailed = false;
-			this.getWin().focus();
-/* WP
-			if (tinyMCE.isGecko || tinyMCE.isOpera) {
-				try {
-					// Is plain text or HTML
-					if (value.indexOf('<') == -1) {
-						var r = this.getRng();
-						var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value));
-						var s = this.getSel();
-						var r2 = r.cloneRange();
+		inst.selection.moveToBookmark(b);
+		inst.selection.selectNode(paraAfter, true, true);
 
-						// Insert text at cursor position
-						s.removeAllRanges();
-						r.deleteContents();
-						r.insertNode(n);
+		return true;
+	},
 
-						// Move the cursor to the end of text
-						r2.selectNode(n);
-						r2.collapse(false);
-						s.removeAllRanges();
-						s.addRange(r2);
-					} else {
-						value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value);
-						this.getDoc().execCommand('inserthtml', false, value);
-						tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value);
-					}
-				} catch (ex) {
-					insertHTMLFailed = true;
-				}
+	_handleBackSpace : function(inst) {
+		var r = inst.getRng(), sn = r.startContainer, nv, s = false;
 
-				if (!insertHTMLFailed) {
-					tinyMCE.triggerNodeChange();
-					return;
-				}
-			}
-*/
-			// Ugly hack in Opera due to non working "inserthtml"
-			if (tinyMCE.isOpera && insertHTMLFailed) {
-				this.getDoc().execCommand("insertimage", false, tinyMCE.uniqueURL);
-				var ar = tinyMCE.getElementsByAttributeValue(this.getBody(), "img", "src", tinyMCE.uniqueURL);
-				ar[0].outerHTML = value;
-				return;
-			}
+		// Added body check for bug #1527787
+		if (sn && sn.nextSibling && sn.nextSibling.nodeName == "BR" && sn.parentNode.nodeName != "BODY") {
+			nv = sn.nodeValue;
 
-			if (!tinyMCE.isMSIE) {
-				var isHTML = value.indexOf('<') != -1;
-				var sel = this.getSel();
-				var rng = this.getRng();
+			// Handle if a backspace is pressed after a space character #bug 1466054 removed since fix for #1527787
+			/*if (nv != null && nv.length >= r.startOffset && nv.charAt(r.startOffset - 1) == ' ')
+				s = true;*/
 
-				if (isHTML) {
-					if (tinyMCE.isSafari) {
-						var tmpRng = this.getDoc().createRange();
+			// Only remove BRs if we are at the end of line #bug 1464152
+			if (nv != null && r.startOffset == nv.length)
+				sn.nextSibling.parentNode.removeChild(sn.nextSibling);
+		}
 
-						tmpRng.setStart(this.getBody(), 0);
-						tmpRng.setEnd(this.getBody(), 0);
+		if (inst.settings.auto_resize)
+			inst.resizeToContent();
 
-						value = tmpRng.createContextualFragment(value);
-					} else
-						value = rng.createContextualFragment(value);
-				} else {
-					// Setup text node
-					var el = document.createElement("div");
-					el.innerHTML = value;
-					value = el.firstChild.nodeValue;
-					value = doc.createTextNode(value);
-				}
+		return s;
+	}
 
-				// Insert plain text in Safari
-				if (tinyMCE.isSafari && !isHTML) {
-					this.execCommand('InsertText', false, value.nodeValue);
-					tinyMCE.triggerNodeChange();
-					return true;
-				} else if (tinyMCE.isSafari && isHTML) {
-					rng.deleteContents();
-					rng.insertNode(value);
-					tinyMCE.triggerNodeChange();
-					return true;
-				}
+	};
 
-				rng.deleteContents();
+/* file:jscripts/tiny_mce/classes/TinyMCE_Layer.class.js */
 
-				// If target node is text do special treatment, (Mozilla 1.3 fix)
-				if (rng.startContainer.nodeType == 3) {
-					var node = rng.startContainer.splitText(rng.startOffset);
-					node.parentNode.insertBefore(value, node); 
-				} else
-					rng.insertNode(value);
+function TinyMCE_Layer(id, bm) {
+	this.id = id;
+	this.blockerElement = null;
+	this.events = false;
+	this.element = null;
+	this.blockMode = typeof(bm) != 'undefined' ? bm : true;
+	this.doc = document;
+};
 
-				if (!isHTML) {
-					// Removes weird selection trails
-					sel.selectAllChildren(doc.body);
-					sel.removeAllRanges();
+TinyMCE_Layer.prototype = {
+	moveRelativeTo : function(re, p) {
+		var rep = this.getAbsPosition(re);
+		var w = parseInt(re.offsetWidth);
+		var h = parseInt(re.offsetHeight);
+		var e = this.getElement();
+		var ew = parseInt(e.offsetWidth);
+		var eh = parseInt(e.offsetHeight);
+		var x, y;
 
-					// Move cursor to end of content
-					var rng = doc.createRange();
+		switch (p) {
+			case "tl":
+				x = rep.absLeft;
+				y = rep.absTop;
+				break;
 
-					rng.selectNode(value);
-					rng.collapse(false);
+			case "tr":
+				x = rep.absLeft + w;
+				y = rep.absTop;
+				break;
 
-					sel.addRange(rng);
-				} else
-					rng.collapse(false);
-			} else {
-				var rng = doc.selection.createRange();
-				var c = value.indexOf('<!--') != -1;
+			case "bl":
+				x = rep.absLeft;
+				y = rep.absTop + h;
+				break;
 
-				// Fix comment bug, add tag before comments
-				if (c)
-					value = tinyMCE.uniqueTag + value;
+			case "br":
+				x = rep.absLeft + w;
+				y = rep.absTop + h;
+				break;
 
-				if (rng.item)
-					rng.item(0).outerHTML = value;
-				else
-					rng.pasteHTML(value);
+			case "cc":
+				x = rep.absLeft + (w / 2) - (ew / 2);
+				y = rep.absTop + (h / 2) - (eh / 2);
+				break;
+		}
 
-				// Remove unique tag
-				if (c) {
-					var e = this.getDoc().getElementById('mceTMPElement');
-					e.parentNode.removeChild(e);
-				}
-			}
+		this.moveTo(x, y);
+	},
 
-			tinyMCE.triggerNodeChange();
-		break;
+	moveBy : function(x, y) {
+		var e = this.getElement();
+		this.moveTo(parseInt(e.style.left) + x, parseInt(e.style.top) + y);
+	},
 
-		case "mceStartTyping":
-			if (tinyMCE.settings['custom_undo_redo'] && this.typingUndoIndex == -1) {
-				this.typingUndoIndex = this.undoIndex;
-				this.execCommand('mceAddUndoLevel');
-				//tinyMCE.debug("mceStartTyping");
-			}
-			break;
+	moveTo : function(x, y) {
+		var e = this.getElement();
 
-		case "mceEndTyping":
-			if (tinyMCE.settings['custom_undo_redo'] && this.typingUndoIndex != -1) {
-				this.execCommand('mceAddUndoLevel');
-				this.typingUndoIndex = -1;
-				//tinyMCE.debug("mceEndTyping");
-			}
-			break;
+		e.style.left = x + "px";
+		e.style.top = y + "px";
 
-		case "mceBeginUndoLevel":
-			this.undoRedo = false;
-			break;
+		this.updateBlocker();
+	},
 
-		case "mceEndUndoLevel":
-			this.undoRedo = true;
-			this.execCommand('mceAddUndoLevel');
-			break;
+	resizeBy : function(w, h) {
+		var e = this.getElement();
+		this.resizeTo(parseInt(e.style.width) + w, parseInt(e.style.height) + h);
+	},
 
-		case "mceAddUndoLevel":
-			if (tinyMCE.settings['custom_undo_redo'] && this.undoRedo) {
-				// tinyMCE.debug("add level");
-
-				if (this.typingUndoIndex != -1) {
-					this.undoIndex = this.typingUndoIndex;
-					// tinyMCE.debug("Override: " + this.undoIndex);
-				}
-
-				var newHTML = tinyMCE.trim(this.getBody().innerHTML);
-				if (newHTML != this.undoLevels[this.undoIndex]) {
-					tinyMCE.executeCallback('onchange_callback', '_onchange', 0, this);
-
-					// Time to compress
-					var customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
-					if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
-						for (var i=0; i<this.undoLevels.length-1; i++) {
-							//tinyMCE.debug(this.undoLevels[i] + "=" + this.undoLevels[i+1]);
-							this.undoLevels[i] = this.undoLevels[i+1];
-						}
+	resizeTo : function(w, h) {
+		var e = this.getElement();
 
-						this.undoLevels.length--;
-						this.undoIndex--;
-					}
+		if (w != null)
+			e.style.width = w + "px";
 
-					this.undoIndex++;
-					this.undoLevels[this.undoIndex] = newHTML;
-					this.undoLevels.length = this.undoIndex + 1;
+		if (h != null)
+			e.style.height = h + "px";
 
-					// tinyMCE.debug("level added" + this.undoIndex);
-					tinyMCE.triggerNodeChange(false);
+		this.updateBlocker();
+	},
 
-					// tinyMCE.debug(this.undoIndex + "," + (this.undoLevels.length-1));
-				}
-			}
-			break;
+	show : function() {
+		var el = this.getElement();
 
-		case "Undo":
-			if (tinyMCE.settings['custom_undo_redo']) {
-				tinyMCE.execCommand("mceEndTyping");
+		if (el) {
+			el.style.display = 'block';
+			this.updateBlocker();
+		}
+	},
 
-				// Do undo
-				if (this.undoIndex > 0) {
-					this.undoIndex--;
-					tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);
-					this.repaint();
-				}
+	hide : function() {
+		var el = this.getElement();
 
-				// tinyMCE.debug("Undo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
-				tinyMCE.triggerNodeChange();
-			} else
-				this.getDoc().execCommand(command, user_interface, value);
-			break;
+		if (el) {
+			el.style.display = 'none';
+			this.updateBlocker();
+		}
+	},
 
-		case "Redo":
-			if (tinyMCE.settings['custom_undo_redo']) {
-				tinyMCE.execCommand("mceEndTyping");
+	isVisible : function() {
+		return this.getElement().style.display == 'block';
+	},
 
-				if (this.undoIndex < (this.undoLevels.length-1)) {
-					this.undoIndex++;
-					tinyMCE.setInnerHTML(this.getBody(), this.undoLevels[this.undoIndex]);
-					this.repaint();
-					// tinyMCE.debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex);
-				}
+	getElement : function() {
+		if (!this.element)
+			this.element = this.doc.getElementById(this.id);
 
-				tinyMCE.triggerNodeChange();
-			} else
-				this.getDoc().execCommand(command, user_interface, value);
-			break;
+		return this.element;
+	},
 
-		case "mceToggleVisualAid":
-			this.visualAid = !this.visualAid;
-			tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid, this);
-			tinyMCE.triggerNodeChange();
-			break;
+	setBlockMode : function(s) {
+		this.blockMode = s;
+	},
 
-		case "Indent":
-			this.getDoc().execCommand(command, user_interface, value);
-			tinyMCE.triggerNodeChange();
-			if (tinyMCE.isMSIE) {
-				var n = tinyMCE.getParentElement(this.getFocusElement(), "blockquote");
-				do {
-					if (n && n.nodeName == "BLOCKQUOTE") {
-						n.removeAttribute("dir");
-						n.removeAttribute("style");
-					}
-				} while (n != null && (n = n.parentNode) != null);
-			}
-			break;
+	updateBlocker : function() {
+		var e, b, x, y, w, h;
 
-		case "removeformat":
-			var text = this.getSelectedText();
+		b = this.getBlocker();
+		if (b) {
+			if (this.blockMode) {
+				e = this.getElement();
+				x = this.parseInt(e.style.left);
+				y = this.parseInt(e.style.top);
+				w = this.parseInt(e.offsetWidth);
+				h = this.parseInt(e.offsetHeight);
 
-			if (tinyMCE.isOpera) {
-				this.getDoc().execCommand("RemoveFormat", false, null);
-				return;
-			}
+				b.style.left = x + 'px';
+				b.style.top = y + 'px';
+				b.style.width = w + 'px';
+				b.style.height = h + 'px';
+				b.style.display = e.style.display;
+			} else
+				b.style.display = 'none';
+		}
+	},
 
-			if (tinyMCE.isMSIE) {
-				try {
-					var rng = doc.selection.createRange();
-					rng.execCommand("RemoveFormat", false, null);
-				} catch (e) {
-					// Do nothing
-				}
+	getBlocker : function() {
+		var d, b;
 
-				this.execCommand("SetStyleInfo", false, {command : "removeformat"});
-			} else {
-				this.getDoc().execCommand(command, user_interface, value);
+		if (!this.blockerElement && this.blockMode) {
+			d = this.doc;
+			b = d.getElementById(this.id + "_blocker");
+
+			if (!b) {
+				b = d.createElement("iframe");
 
-				this.execCommand("SetStyleInfo", false, {command : "removeformat"});
+				b.setAttribute('id', this.id + "_blocker");
+				b.style.cssText = 'display: none; position: absolute; left: 0; top: 0';
+				b.src = 'javascript:false;';
+				b.frameBorder = '0';
+				b.scrolling = 'no';
+	
+				d.body.appendChild(b);
 			}
 
-			// Remove class
-			if (text.length == 0)
-				this.execCommand("mceSetCSSClass", false, "");
+			this.blockerElement = b;
+		}
 
-			tinyMCE.triggerNodeChange();
-			break;
+		return this.blockerElement;
+	},
 
-		default:
-			this.getDoc().execCommand(command, user_interface, value);
+	getAbsPosition : function(n) {
+		var p = {absLeft : 0, absTop : 0};
 
-			if (tinyMCE.isGecko)
-				window.setTimeout('tinyMCE.triggerNodeChange(false);', 1);
-			else
-				tinyMCE.triggerNodeChange();
-	}
+		while (n) {
+			p.absLeft += n.offsetLeft;
+			p.absTop += n.offsetTop;
+			n = n.offsetParent;
+		}
 
-	// Add undo level after modification
-	if (command != "mceAddUndoLevel" && command != "Undo" && command != "Redo" && command != "mceStartTyping" && command != "mceEndTyping")
-		tinyMCE.execCommand("mceAddUndoLevel");
-};
+		return p;
+	},
 
-TinyMCEControl.prototype.queryCommandValue = function(command) {
-	try {
-		return this.getDoc().queryCommandValue(command);
-	} catch (ex) {
-		return null;
-	}
-};
+	create : function(n, c, p, h) {
+		var d = this.doc, e = d.createElement(n);
 
-TinyMCEControl.prototype.queryCommandState = function(command) {
-	return this.getDoc().queryCommandState(command);
-};
+		e.setAttribute('id', this.id);
 
-TinyMCEControl.prototype.onAdd = function(replace_element, form_element_name, target_document) {
-	var targetDoc = target_document ? target_document : document;
+		if (c)
+			e.className = c;
 
-	this.targetDoc = targetDoc;
+		if (!p)
+			p = d.body;
 
-	tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme'];
-	this.settings['themeurl'] = tinyMCE.themeURL;
+		if (h)
+			e.innerHTML = h;
 
-	if (!replace_element) {
-		alert("Error: Could not find the target element.");
-		return false;
-	}
+		p.appendChild(e);
 
-	var templateFunction = tinyMCE._getThemeFunction('_getInsertLinkTemplate');
-	if (eval("typeof(" + templateFunction + ")") != 'undefined')
-		this.insertLinkTemplate = eval(templateFunction + '(this.settings);');
-
-	var templateFunction = tinyMCE._getThemeFunction('_getInsertImageTemplate');
-	if (eval("typeof(" + templateFunction + ")") != 'undefined')
-		this.insertImageTemplate = eval(templateFunction + '(this.settings);');
-
-	var templateFunction = tinyMCE._getThemeFunction('_getEditorTemplate');
-	if (eval("typeof(" + templateFunction + ")") == 'undefined') {
-		alert("Error: Could not find the template function: " + templateFunction);
-		return false;
-	}
+		return this.element = e;
+	},
+
+	exists : function() {
+		return this.doc.getElementById(this.id) != null;
+	},
 
-	var editorTemplate = eval(templateFunction + '(this.settings, this.editorId);');
+	parseInt : function(s) {
+		if (s == null || s == '')
+			return 0;
 
-	var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0;
-	var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0;
-	var html = '<span id="' + this.editorId + '_parent">' + editorTemplate['html'];
+		return parseInt(s);
+	},
 
-	var templateFunction = tinyMCE._getThemeFunction('_handleNodeChange', true);
-	if (eval("typeof(" + templateFunction + ")") != 'undefined')
-		this.settings['handleNodeChangeCallback'] = templateFunction;
+	remove : function() {
+		var e = this.getElement(), b = this.getBlocker();
 
-	html = tinyMCE.replaceVar(html, "editor_id", this.editorId);
-	this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm";
+		if (e)
+			e.parentNode.removeChild(e);
 
-	this.settings['old_width'] = this.settings['width'];
-	this.settings['old_height'] = this.settings['height'];
+		if (b)
+			b.parentNode.removeChild(b);
+	}
 
-	// Set default width, height
-	if (this.settings['width'] == -1)
-		this.settings['width'] = replace_element.offsetWidth;
+	};
 
-	if (this.settings['height'] == -1)
-		this.settings['height'] = replace_element.offsetHeight;
+/* file:jscripts/tiny_mce/classes/TinyMCE_Menu.class.js */
 
-	// Try the style width
-	if (this.settings['width'] == 0)
-		this.settings['width'] = replace_element.style.width;
+function TinyMCE_Menu() {
+	var id;
 
-	// Try the style height
-	if (this.settings['height'] == 0)
-		this.settings['height'] = replace_element.style.height; 
+	if (typeof(tinyMCE.menuCounter) == "undefined")
+		tinyMCE.menuCounter = 0;
 
-	// If no width/height then default to 320x240, better than nothing
-	if (this.settings['width'] == 0)
-		this.settings['width'] = 320;
+	id = "mc_menu_" + tinyMCE.menuCounter++;
 
-	if (this.settings['height'] == 0)
-		this.settings['height'] = 240;
+	TinyMCE_Layer.call(this, id, true);
 
-	this.settings['area_width'] = parseInt(this.settings['width']);
-	this.settings['area_height'] = parseInt(this.settings['height']);
-	this.settings['area_width'] += deltaWidth;
-	this.settings['area_height'] += deltaHeight;
+	this.id = id;
+	this.items = new Array();
+	this.needsUpdate = true;
+};
 
-	// Special % handling
-	if (("" + this.settings['width']).indexOf('%') != -1)
-		this.settings['area_width'] = "100%";
+TinyMCE_Menu.prototype = tinyMCE.extend(TinyMCE_Layer.prototype, {
+	init : function(s) {
+		var n;
 
-	if (("" + this.settings['height']).indexOf('%') != -1)
-		this.settings['area_height'] = "100%";
+		// Default params
+		this.settings = {
+			separator_class : 'mceMenuSeparator',
+			title_class : 'mceMenuTitle',
+			disabled_class : 'mceMenuDisabled',
+			menu_class : 'mceMenu',
+			drop_menu : true
+		};
 
-	if (("" + replace_element.style.width).indexOf('%') != -1) {
-		this.settings['width'] = replace_element.style.width;
-		this.settings['area_width'] = "100%";
-	}
+		for (n in s)
+			this.settings[n] = s[n];
 
-	if (("" + replace_element.style.height).indexOf('%') != -1) {
-		this.settings['height'] = replace_element.style.height;
-		this.settings['area_height'] = "100%";
-	}
+		this.create('div', this.settings.menu_class);
+	},
 
-	html = tinyMCE.applyTemplate(html);
+	clear : function() {
+		this.items = new Array();
+	},
 
-	this.settings['width'] = this.settings['old_width'];
-	this.settings['height'] = this.settings['old_height'];
+	addTitle : function(t) {
+		this.add({type : 'title', text : t});
+	},
 
-	this.visualAid = this.settings['visual'];
-	this.formTargetElementId = form_element_name;
+	addDisabled : function(t) {
+		this.add({type : 'disabled', text : t});
+	},
 
-	// Get replace_element contents
-	if (replace_element.nodeName == "TEXTAREA" || replace_element.nodeName == "INPUT")
-		this.startContent = replace_element.value;
-	else
-		this.startContent = replace_element.innerHTML;
+	addSeparator : function() {
+		this.add({type : 'separator'});
+	},
 
-	// If not text area
-	if (replace_element.nodeName.toLowerCase() != "textarea") {
-		this.oldTargetElement = replace_element.cloneNode(true);
-
-		// Debug mode
-		if (tinyMCE.settings['debug'])
-			html += '<textarea wrap="off" id="' + form_element_name + '" name="' + form_element_name + '" cols="100" rows="15"></textarea>';
-		else
-			html += '<input type="hidden" type="text" id="' + form_element_name + '" name="' + form_element_name + '" />';
+	addItem : function(t, js) {
+		this.add({text : t, js : js});
+	},
 
-		html += '</span>';
+	add : function(mi) {
+		this.items[this.items.length] = mi;
+		this.needsUpdate = true;
+	},
 
-		// Output HTML and set editable
-		if (!tinyMCE.isMSIE) {
-			var rng = replace_element.ownerDocument.createRange();
-			rng.setStartBefore(replace_element);
+	update : function() {
+		var e = this.getElement(), h = '', i, t, m = this.items, s = this.settings;
 
-			var fragment = rng.createContextualFragment(html);
-			replace_element.parentNode.replaceChild(fragment, replace_element);
-		} else
-			replace_element.outerHTML = html;
-	} else {
-		html += '</span>';
+		if (this.settings.drop_menu)
+			h += '<span class="mceMenuLine"></span>';
 
-		// Just hide the textarea element
-		this.oldTargetElement = replace_element;
+		h += '<table border="0" cellpadding="0" cellspacing="0">';
 
-		if (!tinyMCE.settings['debug'])
-			this.oldTargetElement.style.display = "none";
+		for (i=0; i<m.length; i++) {
+			t = tinyMCE.xmlEncode(m[i].text);
+			c = m[i].class_name ? ' class="' + m[i].class_name + '"' : '';
 
-		// Output HTML and set editable
-		if (!tinyMCE.isMSIE) {
-			var rng = replace_element.ownerDocument.createRange();
-			rng.setStartBefore(replace_element);
+			switch (m[i].type) {
+				case 'separator':
+					h += '<tr class="' + s.separator_class + '"><td>';
+					break;
 
-			var fragment = rng.createContextualFragment(html);
+				case 'title':
+					h += '<tr class="' + s.title_class + '"><td><span' + c +'>' + t + '</span>';
+					break;
 
-			if (tinyMCE.isGecko)
-				tinyMCE.insertAfter(fragment, replace_element);
-			else
-				replace_element.parentNode.insertBefore(fragment, replace_element);
-		} else
-			replace_element.insertAdjacentHTML("beforeBegin", html);
-	}
+				case 'disabled':
+					h += '<tr class="' + s.disabled_class + '"><td><span' + c +'>' + t + '</span>';
+					break;
 
-	// Setup iframe
-	var dynamicIFrame = false;
-	var tElm = targetDoc.getElementById(this.editorId);
+				default:
+					h += '<tr><td><a href="' + tinyMCE.xmlEncode(m[i].js) + '" onmousedown="' + tinyMCE.xmlEncode(m[i].js) + ';return tinyMCE.cancelEvent(event);" onclick="return tinyMCE.cancelEvent(event);" onmouseup="return tinyMCE.cancelEvent(event);"><span' + c +'>' + t + '</span></a>';
+			}
 
-	if (!tinyMCE.isMSIE) {
-		if (tElm && tElm.nodeName.toLowerCase() == "span") {
-			tElm = tinyMCE._createIFrame(tElm);
-			dynamicIFrame = true;
+			h += '</td></tr>';
 		}
 
-		this.targetElement = tElm;
-		this.iframeElement = tElm;
-		this.contentDocument = tElm.contentDocument;
-		this.contentWindow = tElm.contentWindow;
+		h += '</table>';
 
-		//this.getDoc().designMode = "on";
-	} else {
-		if (tElm && tElm.nodeName.toLowerCase() == "span")
-			tElm = tinyMCE._createIFrame(tElm);
-		else
-			tElm = targetDoc.frames[this.editorId];
+		e.innerHTML = h;
 
-		this.targetElement = tElm;
-		this.iframeElement = targetDoc.getElementById(this.editorId);
+		this.needsUpdate = false;
+		this.updateBlocker();
+	},
 
-		if (tinyMCE.isOpera) {
-			this.contentDocument = this.iframeElement.contentDocument;
-			this.contentWindow = this.iframeElement.contentWindow;
-			dynamicIFrame = true;
-		} else {
-			this.contentDocument = tElm.window.document;
-			this.contentWindow = tElm.window;
-		}
+	show : function() {
+		var nl, i;
 
-		this.getDoc().designMode = "on";
-	}
+		if (tinyMCE.lastMenu == this)
+			return;
 
-	// Setup base HTML
-	var doc = this.contentDocument;
-	if (dynamicIFrame) {
-		var html = tinyMCE.getParam('doctype') + '<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="' + tinyMCE.settings['base_href'] + '" /><title>blank_page</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body class="mceContentBody"></body></html>';
+		if (this.needsUpdate)
+			this.update();
 
-		try {
-			if (!this.isHidden())
-				this.getDoc().designMode = "on";
+		if (tinyMCE.lastMenu && tinyMCE.lastMenu != this)
+			tinyMCE.lastMenu.hide();
 
-			doc.open();
-			doc.write(html);
-			doc.close();
-		} catch (e) {
-			// Failed Mozilla 1.3
-			this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm";
+		TinyMCE_Layer.prototype.show.call(this);
+
+		if (!tinyMCE.isOpera) {
+			// Accessibility stuff
+/*			nl = this.getElement().getElementsByTagName("a");
+			if (nl.length > 0)
+				nl[0].focus();*/
 		}
-	}
 
-	// This timeout is needed in MSIE 5.5 for some odd reason
-	// it seems that the document.frames isn't initialized yet?
-	if (tinyMCE.isMSIE)
-		window.setTimeout("TinyMCE.prototype.addEventHandlers('" + this.editorId + "');", 1);
+		tinyMCE.lastMenu = this;
+	}
 
-	tinyMCE.setupContent(this.editorId, true);
+	});
 
-	return true;
-};
+/* file:jscripts/tiny_mce/classes/TinyMCE_Compatibility.class.js */
 
-TinyMCEControl.prototype.getFocusElement = function() {
-	if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
-		var doc = this.getDoc();
-		var rng = doc.selection.createRange();
+if (!Function.prototype.call) {
+	Function.prototype.call = function() {
+		var a = arguments, s = a[0], i, as = '', r, o;
 
-//		if (rng.collapse)
-//			rng.collapse(true);
+		for (i=1; i<a.length; i++)
+			as += (i > 1 ? ',' : '') + 'a[' + i + ']';
 
-		var elm = rng.item ? rng.item(0) : rng.parentElement();
-	} else {
-		if (this.isHidden())
-			return this.getBody();
+		o = s._fu;
+		s._fu = this;
+		r = eval('s._fu(' + as + ')');
+		s._fu = o;
 
-		var sel = this.getSel();
-		var rng = this.getRng();
+		return r;
+	};
+};
 
-		var elm = rng.commonAncestorContainer;
-		//var elm = (sel && sel.anchorNode) ? sel.anchorNode : null;
+/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */
 
-		// Handle selection a image or other control like element such as anchors
-		if (!rng.collapsed) {
-			// Is selection small
-			if (rng.startContainer == rng.endContainer) {
-				if (rng.startOffset - rng.endOffset < 2) {
-					if (rng.startContainer.hasChildNodes())
-						elm = rng.startContainer.childNodes[rng.startOffset];
-				}
-			}
-		}
+TinyMCE_Engine.prototype.debug = function() {
+	var m = "", a, i, l = tinyMCE.log.length;
 
-		// Get the element parent of the node
-		elm = tinyMCE.getParentElement(elm);
+	for (i=0, a = this.debug.arguments; i<a.length; i++) {
+		m += a[i];
 
-		//if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
-		//	elm = tinyMCE.selectedElement;
+		if (i<a.length-1)
+			m += ', ';
 	}
 
-	return elm;
+	if (l < 1000)
+		tinyMCE.log[l] = "[debug] " + m;
 };
 
-// Global instances
-var tinyMCE = new TinyMCE();
-var tinyMCELang = new Array();
diff -ruN 2.0.5/wp-includes/js/tinymce/tiny_mce_config.php 2.2.2/wp-includes/js/tinymce/tiny_mce_config.php
--- 2.0.5/wp-includes/js/tinymce/tiny_mce_config.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/tiny_mce_config.php	2007-04-09 23:28:40.000000000 -0500
@@ -0,0 +1,96 @@
+<?php
+	@ require('../../../wp-config.php');
+	cache_javascript_headers();
+
+	function wp_translate_tinymce_lang($text) {
+		if ( ! function_exists('__') ) {
+			return $text;
+		} else {
+			$search1 = "/^tinyMCELang\\[(['\"])(.*)\\1\]( ?= ?)(['\"])(.*)\\4/Uem";
+			$replace1 = "'tinyMCELang[\\1\\2\\1]\\3'.stripslashes('\\4').__('\\5').stripslashes('\\4')";
+
+			$search2 = "/ : (['\"])(.*)\\1/Uem";
+			$replace2 = "' : '.stripslashes('\\1').__('\\2').stripslashes('\\1')";
+
+			$search = array($search1, $search2);
+			$replace = array($replace1, $replace2);
+
+			$text = preg_replace($search, $replace, $text);
+
+			return $text;
+		}
+	}
+
+	// Set up init variables
+	$valid_elements = 'p/-div[*],-strong/-b[*],-em/-i[*],-font[*],-ul[*],-ol[*],-li[*],*[*]';
+	$valid_elements = apply_filters('mce_valid_elements', $valid_elements);
+
+	$plugins = array('inlinepopups', 'autosave', 'spellchecker', 'paste', 'wordpress');
+	$plugins = apply_filters('mce_plugins', $plugins);
+	$plugins = implode($plugins, ',');
+
+	$mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'separator', 'bullist', 'numlist', 'outdent', 'indent', 'separator', 'justifyleft', 'justifycenter', 'justifyright', 'separator', 'link', 'unlink', 'image', 'wp_more', 'separator', 'spellchecker', 'separator', 'wp_help', 'wp_adv_start', 'wp_adv', 'separator', 'formatselect', 'underline', 'justifyfull', 'forecolor', 'separator', 'pastetext', 'pasteword', 'separator', 'removeformat', 'cleanup', 'separator', 'charmap', 'separator', 'undo', 'redo', 'wp_adv_end'));
+	$mce_buttons = implode($mce_buttons, ',');
+
+	$mce_buttons_2 = apply_filters('mce_buttons_2', array());
+	$mce_buttons_2 = implode($mce_buttons_2, ',');
+
+	$mce_buttons_3 = apply_filters('mce_buttons_3', array());
+	$mce_buttons_3 = implode($mce_buttons_3, ',');
+
+	$mce_browsers = apply_filters('mce_browsers', array('msie', 'gecko', 'opera', 'safari'));
+	$mce_browsers = implode($mce_browsers, ',');
+
+	$mce_popups_css = get_option('siteurl') . '/wp-includes/js/tinymce/plugins/wordpress/popups.css';
+	$mce_css = get_option('siteurl') . '/wp-includes/js/tinymce/plugins/wordpress/wordpress.css';
+	$mce_css = apply_filters('mce_css', $mce_css);
+	if ( $_SERVER['HTTPS'] == 'on' ) {
+		$mce_css = str_replace('http://', 'https://', $mce_css);
+		$mce_popups_css = str_replace('http://', 'https://', $mce_popups_css);
+	}
+	
+	$mce_locale = ( '' == get_locale() ) ? 'en' : strtolower(get_locale());
+?>
+
+initArray = {
+	mode : "specific_textareas",
+	editor_selector : "mceEditor",
+	width : "100%",
+	theme : "advanced",
+	theme_advanced_buttons1 : "<?php echo $mce_buttons; ?>",
+	theme_advanced_buttons2 : "<?php echo $mce_buttons_2; ?>",
+	theme_advanced_buttons3 : "<?php echo $mce_buttons_3; ?>",
+	language : "<?php echo $mce_locale; ?>",
+	theme_advanced_toolbar_location : "top",
+	theme_advanced_toolbar_align : "left",
+	theme_advanced_path_location : "bottom",
+	theme_advanced_resizing : true,
+	browsers : "<?php echo $mce_browsers; ?>",
+	dialog_type : "modal",
+	theme_advanced_resize_horizontal : false,
+	convert_urls : false,
+	relative_urls : false,
+	remove_script_host : false,
+	force_p_newlines : true,
+	force_br_newlines : false,
+	convert_newlines_to_brs : false,
+	remove_linebreaks : false,
+	fix_list_elements : true,
+	gecko_spellcheck : true,
+	entities : "38,amp,60,lt,62,gt",
+	button_tile_map : true,
+	content_css : "<?php echo $mce_css; ?>",
+	valid_elements : "<?php echo $valid_elements; ?>",
+	save_callback : 'TinyMCE_wordpressPlugin.saveCallback',
+	imp_version : "<?php echo intval($_GET['ver']); ?>",
+<?php do_action('mce_options'); ?>
+	plugins : "<?php echo $plugins; ?>"
+};
+
+<?php
+	// For people who really REALLY know what they're doing with TinyMCE
+	// You can modify initArray to add, remove, change elements of the config before tinyMCE.init
+	do_action('tinymce_before_init');
+?>
+
+tinyMCE.init(initArray);
diff -ruN 2.0.5/wp-includes/js/tinymce/tiny_mce_gzip.php 2.2.2/wp-includes/js/tinymce/tiny_mce_gzip.php
--- 2.0.5/wp-includes/js/tinymce/tiny_mce_gzip.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/tiny_mce_gzip.php	2007-05-01 21:36:44.000000000 -0500
@@ -1,43 +1,230 @@
 <?php
-	/**
-	 * $RCSfile: tiny_mce_gzip.php,v $
-	 * $Revision: $
-	 * $Date: $
-	 *
-	 * @version 1.02
-	 * @author Moxiecode
-	 * @copyright Copyright  2005, Moxiecode Systems AB, All rights reserved.
-	 *
-	 * This file compresses the TinyMCE JavaScript using GZip and
-	 * enables the browser to do two requests instead of one for each .js file.
-	 * Notice: This script defaults the button_tile_map option to true for extra performance.
-	 *
-	 * Todo:
-	 *  - Add local file cache for the GZip:ed version.
-	 */
-
-	/* Heavily edited to add flexibilty in WordPress */
-	@ require('../../../wp-config.php');
-
-	function wp_translate_tinymce_lang($text) {
-		if ( ! function_exists('__') ) {
-			return $text;
-		} else {
-			$search1 = "/^tinyMCELang\\[(['\"])(.*)\\1\]( ?= ?)(['\"])(.*)\\4/Uem";
-			$replace1 = "'tinyMCELang[\\1\\2\\1]\\3'.stripslashes('\\4').__('\\5').stripslashes('\\4')";
-
-			$search2 = "/ : (['\"])(.*)\\1/Uem";
-			$replace2 = "' : '.stripslashes('\\1').__('\\2').stripslashes('\\1')";
+/**
+ * $Id: tiny_mce_gzip.php 158 2006-12-21 14:32:19Z spocke $
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2005-2006, Moxiecode Systems AB, All rights reserved.
+ *
+ * This file compresses the TinyMCE JavaScript using GZip and
+ * enables the browser to do two requests instead of one for each .js file.
+ * Notice: This script defaults the button_tile_map option to true for extra performance.
+ */
+
+	@require_once('../../../wp-config.php');  // For get_bloginfo().
+
+	// Get input
+	$plugins = explode(',', getParam("plugins", ""));
+	$languages = explode(',', getParam("languages", ""));
+	$themes = explode(',', getParam("themes", ""));
+	$diskCache = getParam("diskcache", "") == "true";
+	$isJS = getParam("js", "") == "true";
+	$compress = getParam("compress", "true") == "true";
+	$suffix = getParam("suffix", "_src") == "_src" ? "_src" : "";
+	$cachePath = realpath("."); // Cache path, this is where the .gz files will be stored
+	$expiresOffset = 3600 * 24 * 10; // Cache for 10 days in browser cache
+	$content = "";
+	$encodings = array();
+	$supportsGzip = false;
+	$enc = "";
+	$cacheKey = "";
+
+	// Custom extra javascripts to pack
+	$custom = array(/*
+		"some custom .js file",
+		"some custom .js file"
+	*/);
+
+	// WP
+	$index = getParam("index", -1);
+	$theme = getParam("theme", "");
+	$themes = array($theme);
+	$language = getParam("language", "en");
+	if ( empty($language) )
+		$language = 'en';
+	$languages = array($language);
+	if ( $language != strtolower($language) )
+		$languages[] = strtolower($language);
+	if ( $language != substr($language, 0, 2) )
+		$languages[] = substr($language, 0, 2);
+	$diskCache = false;
+	$isJS = true;
+	$suffix = '';
+
+	// Headers
+	header("Content-Type: text/javascript; charset=" . get_bloginfo('charset'));
+	header("Vary: Accept-Encoding");  // Handle proxies
+	header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
+
+	// Is called directly then auto init with default settings
+	if (!$isJS) {
+		echo getFileContents("tiny_mce_gzip.js");
+		echo "tinyMCE_GZ.init({});";
+		die();
+	}
+
+	// Setup cache info
+	if ($diskCache) {
+		if (!$cachePath)
+			die("alert('Real path failed.');");
+
+		$cacheKey = getParam("plugins", "") . getParam("languages", "") . getParam("themes", "");
+
+		foreach ($custom as $file)
+			$cacheKey .= $file;
+
+		$cacheKey = md5($cacheKey);
+
+		if ($compress)
+			$cacheFile = $cachePath . "/tiny_mce_" . $cacheKey . ".gz";
+		else
+			$cacheFile = $cachePath . "/tiny_mce_" . $cacheKey . ".js";
+	}
+
+	// Check if it supports gzip
+	if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
+		$encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING'])));
+
+	if ((in_array('gzip', $encodings) || in_array('x-gzip', $encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression') && ini_get('output_handler') != 'ob_gzhandler') {
+		$enc = in_array('x-gzip', $encodings) ? "x-gzip" : "gzip";
+		$supportsGzip = true;
+	}
+
+	// Use cached file disk cache
+	if ($diskCache && $supportsGzip && file_exists($cacheFile)) {
+		if ($compress)
+			header("Content-Encoding: " . $enc);
+
+		echo getFileContents($cacheFile);
+		die();
+	}
+
+if ($index > -1) {
+	// Write main script and patch some things
+	if ( $index == 0 ) {
+		// Add core
+		$content .= wp_compact_tinymce_js(getFileContents("tiny_mce" . $suffix . ".js"));
+		$content .= 'TinyMCE.prototype.orgLoadScript = TinyMCE.prototype.loadScript;';
+		$content .= 'TinyMCE.prototype.loadScript = function() {};var realTinyMCE = tinyMCE;';
+	} else
+		$content .= 'tinyMCE = realTinyMCE;';
+
+	// Patch loading functions
+	//$content .= "tinyMCE_GZ.start();";
+	
+	// Do init based on index
+	$content .= "tinyMCE.init(tinyMCECompressed.configs[" . $index . "]);";
+
+	// Load external plugins
+	if ( $index == 0 )
+		$content .= "tinyMCECompressed.loadPlugins();";
+
+	// Add core languages
+	$lang_content = '';
+	foreach ($languages as $lang)
+		$lang_content .= getFileContents("langs/" . $lang . ".js");
+	if ( empty($lang_content) )
+		$lang_content .= getFileContents("langs/en.js");
+	$content .= $lang_content;
+
+	// Add themes
+	foreach ($themes as $theme) {
+		$content .= wp_compact_tinymce_js(getFileContents( "themes/" . $theme . "/editor_template" . $suffix . ".js"));
+
+		$lang_content = '';
+		foreach ($languages as $lang)
+			$lang_content .= getFileContents("themes/" . $theme . "/langs/" . $lang . ".js");
+		if ( empty($lang_content) )
+			$lang_content .= getFileContents("themes/" . $theme . "/langs/en.js");
+		$content .= $lang_content;
+	}
+
+	// Add plugins
+	foreach ($plugins as $plugin) {
+		$content .= getFileContents("plugins/" . $plugin . "/editor_plugin" . $suffix . ".js");
+
+		$lang_content = '';
+		foreach ($languages as $lang)
+			$lang_content .= getFileContents("plugins/" . $plugin . "/langs/" . $lang . ".js");
+		if ( empty($lang_content) )
+			$lang_content .= getFileContents("plugins/" . $plugin . "/langs/en.js");
+		$content .= $lang_content;
+	}
+
+	// Add custom files
+	foreach ($custom as $file)
+		$content .= getFileContents($file);
+
+	// Reset tinyMCE compressor engine
+	$content .= "tinyMCE = tinyMCECompressed;";
+
+	// Restore loading functions
+	//$content .= "tinyMCE_GZ.end();";
+
+	// Generate GZIP'd content
+	if ($supportsGzip) {
+		if ($compress) {
+			header("Content-Encoding: " . $enc);
+			$cacheData = gzencode($content, 9, FORCE_GZIP);
+		} else
+			$cacheData = $content;
+
+		// Write gz file
+		if ($diskCache && $cacheKey != "")
+			putFileContents($cacheFile, $cacheData);
+
+		// Stream to client
+		echo $cacheData;
+	} else {
+		// Stream uncompressed content
+		echo $content;
+	}
+
+	die;
+}
+
+	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+	function getParam($name, $def = false) {
+		if (!isset($_GET[$name]))
+			return $def;
+
+		return preg_replace("/[^0-9a-z\-_,]+/i", "", $_GET[$name]); // Remove anything but 0-9,a-z,-_
+	}
+
+	function getFileContents($path) {
+		$path = realpath($path);
 
-			$search = array($search1, $search2);
-			$replace = array($replace1, $replace2);
+		if (!$path || !@is_file($path))
+			return "";
 
-			$text = preg_replace($search, $replace, $text);
+		if (function_exists("file_get_contents"))
+			return @file_get_contents($path);
 
-			return $text;
+		$content = "";
+		$fp = @fopen($path, "r");
+		if (!$fp)
+			return "";
+
+		while (!feof($fp))
+			$content .= fgets($fp);
+
+		fclose($fp);
+
+		return $content;
+	}
+
+	function putFileContents($path, $content) {
+		if (function_exists("file_put_contents"))
+			return @file_put_contents($path, $content);
+
+		$fp = @fopen($path, "wb");
+		if ($fp) {
+			fwrite($fp, $content);
+			fclose($fp);
 		}
 	}
 
+	// WP specific
 	function wp_compact_tinymce_js($text) {
 		// This function was custom-made for TinyMCE 2.0, not expected to work with any other JS.
 
@@ -50,123 +237,125 @@
 		$text = str_replace("\r", '', $text);
 		$text = preg_replace("!(^|{|}|;|:|\))\n!m", '\\1', $text);
 
-		return $text;
+		return "$text\n";
 	}
+?>
 
-	// General options
-	$expiresOffset = 3600 * 24 * 30; // 30 days util client cache expires
-
-	gzip_compression();
+function TinyMCECompressed() {
+	this.configs = new Array();
+	this.loadedFiles = new Array();
+	this.externalPlugins = new Array();
+	this.loadAdded = false;
+	this.isLoaded = false;
+}
+
+TinyMCECompressed.prototype.init = function(settings) {
+	var elements = document.getElementsByTagName('script');
+	var scriptURL = "";
+
+	for (var i=0; i<elements.length; i++) {
+		if (elements[i].src && elements[i].src.indexOf("tiny_mce_gzip.php") != -1) {
+			scriptURL = elements[i].src;
+			break;
+		}
+	}
 
-	// Output rest of headers
-	header("Content-type: text/javascript; charset: UTF-8");
-	header("Vary: Accept-Encoding"); // Handle proxies
-	header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expiresOffset) . " GMT");
+	settings["theme"] = typeof(settings["theme"]) != "undefined" ? settings["theme"] : "default";
+	settings["plugins"] = typeof(settings["plugins"]) != "undefined" ? settings["plugins"] : "";
+	settings["language"] = typeof(settings["language"]) != "undefined" ? settings["language"] : "en";
+	settings["button_tile_map"] = typeof(settings["button_tile_map"]) != "undefined" ? settings["button_tile_map"] : true;
+	this.configs[this.configs.length] = settings;
+	this.settings = settings;
+
+	scriptURL += (scriptURL.indexOf('?') == -1) ? '?' : '&';
+	scriptURL += "theme=" + escape(this.getOnce(settings["theme"])) + "&language=" + escape(this.getOnce(settings["language"])) + "&plugins=" + escape(this.getOnce(settings["plugins"])) + "&lang=" + settings["language"] + "&index=" + escape(this.configs.length-1);
+	document.write('<sc'+'ript language="javascript" type="text/javascript" src="' + scriptURL + '"></script>');
+
+	if (!this.loadAdded) {
+		tinyMCE.addEvent(window, "DOMContentLoaded", TinyMCECompressed.prototype.onLoad);
+		tinyMCE.addEvent(window, "load", TinyMCECompressed.prototype.onLoad);
+		this.loadAdded = true;
+	}
+}
 
-	// Write main script
-	$tinymce = file_get_contents(realpath("tiny_mce.js"));
-	echo wp_compact_tinymce_js($tinymce);
-	echo "\n\n";
+TinyMCECompressed.prototype.onLoad = function() {
+	if (tinyMCE.isLoaded)
+		return true;
+
+	tinyMCE = realTinyMCE;
+	TinyMCE_Engine.prototype.onLoad();
+	tinyMCE._addUnloadEvents();
+
+	tinyMCE.isLoaded = true;
+}
+
+TinyMCECompressed.prototype.addEvent = function(o, n, h) {
+	if (o.attachEvent)
+		o.attachEvent("on" + n, h);
+	else
+		o.addEventListener(n, h, false);
+}
+
+TinyMCECompressed.prototype.getOnce = function(str) {
+	var ar = str.replace(/\s+/g, '').split(',');
+
+	for (var i=0; i<ar.length; i++) {
+		if (ar[i] == '' || ar[i].charAt(0) == '-') {
+			ar[i] = null;
+			continue;
+		}
 
-	// Remove some functions
-	echo "\n/* WP cancels all TinyMCE language and import handling */\n";
-	echo "TinyMCE.prototype.importThemeLanguagePack = function() {};\n";
-	echo "TinyMCE.prototype.importPluginLanguagePack = function() {};\n\n";
-	echo "TinyMCE.prototype.loadScript = function() {};\n";
+		// Skip load
+		for (var x=0; x<this.loadedFiles.length; x++) {
+			if (this.loadedFiles[x] == ar[i])
+				ar[i] = null;
+		}
 
-	// Load theme, language pack and theme language packs
-	$theme = apply_filters('mce_theme', 'advanced');
+		this.loadedFiles[this.loadedFiles.length] = ar[i];
+	}
 
-	echo wp_compact_tinymce_js(file_get_contents(realpath("themes/" . $theme . "/editor_template.js")));
+	// Glue
+	str = "";
+	for (var i=0; i<ar.length; i++) {
+		if (ar[i] == null)
+			continue;
 
-	// Get the WordPress locale
-	$locale = get_locale();
+		str += ar[i];
 
-	$themeLanguageFile = realpath("themes/" . $theme . "/langs/" . $locale . ".js");
+		if (i != ar.length-1)
+			str += ",";
+	}
 
-	if (!file_exists($themeLanguageFile))
-		$themeLanguageFile = realpath("themes/" . $theme . "/langs/en.js");
-	echo wp_translate_tinymce_lang(file_get_contents($themeLanguageFile));
+	return str;
+};
 
-	$tinymceLanguageFile = realpath("langs/" . $locale . ".js");
+TinyMCECompressed.prototype.loadPlugins = function() {
+	var i, ar;
 
-	if (!file_exists($tinymceLanguageFile))
-		$tinymceLanguageFile = realpath("langs/en.js");
-	echo wp_translate_tinymce_lang(file_get_contents($tinymceLanguageFile));
+	TinyMCE.prototype.loadScript = TinyMCE.prototype.orgLoadScript;
+	tinyMCE = realTinyMCE;
 
-	// Load all plugins and their language packs
-	$plugins = apply_filters('mce_plugins', array('wordpress', 'autosave','wphelp'));
+	ar = tinyMCECompressed.externalPlugins;
+	for (i=0; i<ar.length; i++)
+		tinyMCE.loadPlugin(ar[i].name, ar[i].url);
 
-	foreach ($plugins as $plugin) {
-		$pluginFile = realpath("plugins/" . $plugin . "/editor_plugin.js");
-		$languageFile = realpath("plugins/" . $plugin . "/langs/" . $locale . ".js");
-		if (!file_exists($languageFile))
-			$languageFile = realpath("plugins/" . $plugin . "/langs/en.js");
-
-		if ($pluginFile)
-			echo file_get_contents($pluginFile);
-
-		if ($languageFile)
-			echo wp_translate_tinymce_lang(file_get_contents($languageFile));
-	}
-
-	// Set up init variables
-	if ( current_user_can('unfiltered_html') ) // Use the full XHTML set provided in the docs
-		$valid_elements = 'a[accesskey|charset|class|coords|dir<ltr?rtl|href|hreflang|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rel|rev|shape<circle?default?poly?rect|style|tabindex|title|target|type],abbr[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],acronym[class|dir<ltr?rtl|id|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],address[class|align|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],applet[align<bottom?left?middle?right?top|alt|archive|class|code|codebase|height|hspace|id|name|object|style|title|vspace|width],area[accesskey|alt|class|coords|dir<ltr?rtl|href|id|lang|nohref<nohref|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|shape<circle?default?poly?rect|style|tabindex|title|target],base[href|target],basefont[color|face|id|size],bdo[class|dir<ltr?rtl|id|lang|style|title],big[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],blockquote[dir|style|cite|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],body[alink|background|bgcolor|class|dir<ltr?rtl|id|lang|link|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onload|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onunload|style|title|text|vlink],br[class|clear<all?left?none?right|id|style|title],button[accesskey|class|dir<ltr?rtl|disabled<disabled|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|tabindex|title|type|value],caption[align<bottom?left?right?top|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],center[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
-			. 'cite[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],code[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],col[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|span|style|title|valign<baseline?bottom?middle?top|width],colgroup[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|span|style|title|valign<baseline?bottom?middle?top|width],dd[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],del[cite|class|datetime|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dfn[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dir[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],div[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dl[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],dt[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],em/i[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
-			. 'fieldset[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],font[class|color|dir<ltr?rtl|face|id|lang|size|style|title],form[accept|accept-charset|action|class|dir<ltr?rtl|enctype|id|lang|method<get?post|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onsubmit|style|title|target],frame[class|frameborder|id|longdesc|marginheight|marginwidth|name|noresize<noresize|scrolling<auto?no?yes|src|style|title],frameset[class|cols|id|onload|onunload|rows|style|title],h1[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h2[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h3[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h4[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h5[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],h6[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],head[dir<ltr?rtl|lang|profile],hr[align<center?left?right|class|dir<ltr?rtl|id|lang|noshade<noshade|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|size|style|title|width],html[dir<ltr?rtl|lang|version],'
-			. 'iframe[align<bottom?left?middle?right?top|class|frameborder|height|id|longdesc|marginheight|marginwidth|name|scrolling<auto?no?yes|src|style|title|width],img[align<bottom?left?middle?right?top|alt|border|class|dir<ltr?rtl|height|hspace|id|ismap<ismap|lang|longdesc|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|src|style|title|usemap|vspace|width],input[accept|accesskey|align<bottom?left?middle?right?top|alt|checked<checked|class|dir<ltr?rtl|disabled<disabled|id|ismap<ismap|lang|maxlength|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|size|src|style|tabindex|title|type<button?checkbox?file?hidden?image?password?radio?reset?submit?text|usemap|value],ins[cite|class|datetime|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],isindex[class|dir<ltr?rtl|id|lang|prompt|style|title],kbd[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],label[accesskey|class|dir<ltr?rtl|for|id|lang|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],legend[align<bottom?left?right?top|accesskey|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],li[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type|value],link[charset|class|dir<ltr?rtl|href|hreflang|id|lang|media|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rel|rev|style|title|target|type],map[class|dir<ltr?rtl|id|lang|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
-			. 'menu[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],meta[content|dir<ltr?rtl|http-equiv|lang|name|scheme],noframes[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],noscript[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],object[align<bottom?left?middle?right?top|archive|border|class|classid|codebase|codetype|data|declare|dir<ltr?rtl|height|hspace|id|lang|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|standby|style|tabindex|title|type|usemap|vspace|width],ol[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|start|style|title|type],optgroup[class|dir<ltr?rtl|disabled<disabled|id|label|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],option[class|dir<ltr?rtl|disabled<disabled|id|label|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|selected<selected|style|title|value],p[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],param[id|name|type|value|valuetype<DATA?OBJECT?REF],pre/listing/plaintext/xmp[align|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|width],q[cite|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],'
-			. 's[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],samp[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],script[charset|defer|language|src|type],select[class|dir<ltr?rtl|disabled<disabled|id|lang|multiple<multiple|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|size|style|tabindex|title],small[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],span[align<center?justify?left?right|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],strike[class|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],strong/b[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],style[dir<ltr?rtl|lang|media|title|type],sub[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],sup[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],table[align<center?left?right|bgcolor|border|cellpadding|cellspacing|class|dir<ltr?rtl|frame|height|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rules|style|summary|title|width],'
-			. 'tbody[align<center?char?justify?left?right|char|class|charoff|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],td[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],textarea[accesskey|class|cols|dir<ltr?rtl|disabled<disabled|id|lang|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|rows|style|tabindex|title],tfoot[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],th[abbr|align<center?char?justify?left?right|axis|bgcolor|char|charoff|class|colspan|dir<ltr?rtl|headers|height|id|lang|nowrap<nowrap|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|rowspan|scope<col?colgroup?row?rowgroup|style|title|valign<baseline?bottom?middle?top|width],thead[align<center?char?justify?left?right|char|charoff|class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],'
-			. 'title[dir<ltr?rtl|lang],tr[abbr|align<center?char?justify?left?right|bgcolor|char|charoff|class|rowspan|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|valign<baseline?bottom?middle?top],tt[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],u[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title],ul[class|compact<compact|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type],var[class|dir<ltr?rtl|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title]';
-	else // Use a much smaller set
-		$valid_elements = '-a[id|href|title|rel],-strong/b,-em/i,-strike,-del,-u,p[class|align|dir],-ol,-ul,-li,br,img[class|src|alt|title|width|height|align],-sub,-sup,-blockquote[dir],-table[border|cellspacing|cellpadding|width|height|class|align|dir],thead[class|rowspan|width|height|align|valign|dir],tr[class|rowspan|width|height|align|valign|dir],th[dir|class|colspan|rowspan|width|height|align|valign|scope],td[dir|class|colspan|rowspan|width|height|align|valign],-div[dir|class|align],-span[class|align],-pre[class],-code[class],-address,-h1[class|align|dir],-h2[class|align|dir],-h3[class|align|dir],-h4[class|align|dir],-h5[class|align|dir],-h6[class|align|dir],hr';
-	$valid_elements = apply_filters('mce_valid_elements', $valid_elements);
-	$plugins = implode($plugins, ',');
-	$mce_buttons = apply_filters('mce_buttons', array('bold', 'italic', 'strikethrough', 'separator', 'bullist', 'numlist', 'outdent', 'indent', 'separator', 'justifyleft', 'justifycenter', 'justifyright' ,'separator', 'link', 'unlink', 'image', 'wordpress', 'separator', 'undo', 'redo', 'code', 'wphelp'));
-	$mce_buttons = implode($mce_buttons, ',');
-	$mce_buttons_2 = apply_filters('mce_buttons_2', array());
-	$mce_buttons_2 = implode($mce_buttons_2, ',');
-	$mce_buttons_3 = apply_filters('mce_buttons_3', array());
-	$mce_buttons_3 = implode($mce_buttons_3, ',');
-	$mce_browsers = apply_filters('mce_browsers', array('msie', 'gecko', 'opera'));
-	$mce_browsers = implode($mce_browsers, ',');
-?>
+	TinyMCE.prototype.loadScript = function() {};
+};
 
-initArray = {
-	mode : "specific_textareas",
-	textarea_trigger : "title",
-	width : "100%",
-	theme : "advanced",
-	theme_advanced_buttons1 : "<?php echo $mce_buttons; ?>",
-	theme_advanced_buttons2 : "<?php echo $mce_buttons_2; ?>",
-	theme_advanced_buttons3 : "<?php echo $mce_buttons_3; ?>",
-	theme_advanced_toolbar_location : "top",
-	theme_advanced_toolbar_align : "left",
-	theme_advanced_path_location : "bottom",
-	theme_advanced_resizing : true,
-	browsers : "<?php echo $mce_browsers; ?>",
-	dialog_type : "modal",
-	theme_advanced_resize_horizontal : false,
-	entity_encoding : "raw",
-	relative_urls : false,
-	remove_script_host : false,
-	force_p_newlines : true,
-	force_br_newlines : false,
-	convert_newlines_to_brs : false,
-	remove_linebreaks : true,
-	save_callback : "wp_save_callback",
-	document_base_url : "<?php echo trailingslashit(get_bloginfo('home')); ?>",
-	valid_elements : "<?php echo $valid_elements; ?>",
-<?php do_action('mce_options'); ?>
-	plugins : "<?php echo $plugins; ?>"
+TinyMCECompressed.prototype.loadPlugin = function(n, u) {
+	this.externalPlugins[this.externalPlugins.length] = {name : n, url : u};
 };
 
-<?php
-	// For people who really REALLY know what they're doing with TinyMCE
-	do_action('tinymce_before_init');
-?>
+TinyMCECompressed.prototype.importPluginLanguagePack = function(n, v) {
+	tinyMCE = realTinyMCE;
+	TinyMCE.prototype.loadScript = TinyMCE.prototype.orgLoadScript;
+	tinyMCE.importPluginLanguagePack(n, v);
+};
 
-tinyMCE.init(initArray);
+TinyMCECompressed.prototype.addPlugin = function(n, p) {
+	tinyMCE = realTinyMCE;
+	tinyMCE.addPlugin(n, p);
+};
 
+var tinyMCE = new TinyMCECompressed();
+var tinyMCECompressed = tinyMCE;
diff -ruN 2.0.5/wp-includes/js/tinymce/tiny_mce_popup.js 2.2.2/wp-includes/js/tinymce/tiny_mce_popup.js
--- 2.0.5/wp-includes/js/tinymce/tiny_mce_popup.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/tiny_mce_popup.js	2006-11-20 18:55:06.000000000 -0600
@@ -1,250 +1,288 @@
-/**
- * $RCSfile: tiny_mce_popup.js,v $
- * $Revision: 1.18 $
- * $Date: 2005/10/29 19:13:20 $
- *
- * @author Moxiecode
- * @copyright Copyright  2004, Moxiecode Systems AB, All rights reserved.
- */
-
+// Some global instances, this will be filled later
 var tinyMCE = null, tinyMCELang = null;
 
-function TinyMCEPopup() {
+function TinyMCE_Popup() {
 };
 
-TinyMCEPopup.prototype.init = function() {
-	var win = window.opener ? window.opener : window.dialogArguments;
+TinyMCE_Popup.prototype = {
+	findWin : function(w) {
+		var c;
+
+		// Check parents
+		c = w;
+		while (c && (c = c.parent) != null) {
+			if (typeof(c.tinyMCE) != "undefined")
+				return c;
+		}
 
-	if (!win)
-		win = top;
+		// Check openers
+		c = w;
+		while (c && (c = c.opener) != null) {
+			if (typeof(c.tinyMCE) != "undefined")
+				return c;
+		}
 
-	window.opener = win;
-	this.windowOpener = win;
-	this.onLoadEval = "";
-
-	// Setup parent references
-	tinyMCE = win.tinyMCE;
-	tinyMCELang = win.tinyMCELang;
-
-	if (!tinyMCE) {
-		alert("tinyMCE object reference not found from popup.");
-		return;
-	}
+		// Try top
+		if (typeof(top.tinyMCE) != "undefined")
+			return top;
+
+		return null;
+	},
+
+	init : function() {
+		var win = window.opener ? window.opener : window.dialogArguments, c;
+		var inst;
+
+		if (!win)
+			win = this.findWin(window);
+
+		if (!win) {
+			alert("tinyMCE object reference not found from popup.");
+			return;
+		}
 
-	this.isWindow = tinyMCE.getWindowArg('mce_inside_iframe', false) == false;
-	this.storeSelection = tinyMCE.isMSIE && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true);
+		window.opener = win;
+		this.windowOpener = win;
+		this.onLoadEval = "";
+
+		// Setup parent references
+		tinyMCE = win.tinyMCE;
+		tinyMCELang = win.tinyMCELang;
+
+		inst = tinyMCE.selectedInstance;
+		this.isWindow = tinyMCE.getWindowArg('mce_inside_iframe', false) == false;
+		this.storeSelection = (tinyMCE.isRealIE) && !this.isWindow && tinyMCE.getWindowArg('mce_store_selection', true);
+
+		if (this.isWindow)
+			window.focus();
+
+		// Store selection
+		if (this.storeSelection)
+			inst.selectionBookmark = inst.selection.getBookmark(true);
+
+		// Setup dir
+		if (tinyMCELang['lang_dir'])
+			document.dir = tinyMCELang['lang_dir'];
+
+		// Setup title
+		var re = new RegExp('{|\\\$|}', 'g');
+		var title = document.title.replace(re, "");
+		if (typeof tinyMCELang[title] != "undefined") {
+			var divElm = document.createElement("div");
+			divElm.innerHTML = tinyMCELang[title];
+			document.title = divElm.innerHTML;
 
-	if (this.isWindow)
-		window.focus();
+			if (tinyMCE.setWindowTitle != null)
+				tinyMCE.setWindowTitle(window, divElm.innerHTML);
+		}
 
-	// Store selection
-	if (this.storeSelection)
-		tinyMCE.selectedInstance.execCommand('mceStoreSelection');
-
-	// Setup dir
-	if (tinyMCELang['lang_dir'])
-		document.dir = tinyMCELang['lang_dir'];
-
-	// Setup title
-	var re = new RegExp('{|\\\$|}', 'g');
-	var title = document.title.replace(re, "");
-	if (typeof tinyMCELang[title] != "undefined") {
-		var divElm = document.createElement("div");
-		divElm.innerHTML = tinyMCELang[title];
-		document.title = divElm.innerHTML;
+		// Output Popup CSS class
+		document.write('<link href="' + tinyMCE.getParam("popups_css") + '" rel="stylesheet" type="text/css">');
 
-		if (tinyMCE.setWindowTitle != null)
-			tinyMCE.setWindowTitle(window, divElm.innerHTML);
-	}
+		if (tinyMCE.getParam("popups_css_add")) {
+			c = tinyMCE.getParam("popups_css_add");
 
-	// Output Popup CSS class
-	document.write('<link href="' + tinyMCE.getParam("popups_css") + '" rel="stylesheet" type="text/css">');
+			// Is relative
+			if (c.indexOf('://') == -1 && c.charAt(0) != '/')
+				c = tinyMCE.documentBasePath + "/" + c;
 
-	tinyMCE.addEvent(window, "load", this.onLoad);
-};
+			document.write('<link href="' + c + '" rel="stylesheet" type="text/css">');
+		}
 
-TinyMCEPopup.prototype.onLoad = function() {
-	var body = document.body;
+		tinyMCE.addEvent(window, "load", this.onLoad);
+	},
 
-	body.onkeydown = function (e) {
-		e = e ? e : window.event;
-		if ( e.keyCode == 27 && !e.shiftKey && !e.controlKey && !e.altKey ) {
-			tinyMCEPopup.close();
-		}
-	}
+	onLoad : function() {
+		var dir, i, elms, body = document.body;
 
-	if (tinyMCE.getWindowArg('mce_replacevariables', true))
-		body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
+		if (tinyMCE.getWindowArg('mce_replacevariables', true))
+			body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
 
-	var dir = tinyMCE.selectedInstance.settings['directionality'];
-	if (dir == "rtl") {
-		var elms = document.forms[0].elements;
-		for (var i=0; i<elms.length; i++) {
-			if ((elms[i].type == "text" || elms[i].type == "textarea") && elms[i].getAttribute("dir") != "ltr")
-				elms[i].dir = dir;
+		dir = tinyMCE.selectedInstance.settings['directionality'];
+		if (dir == "rtl" && document.forms && document.forms.length > 0) {
+			elms = document.forms[0].elements;
+			for (i=0; i<elms.length; i++) {
+				if ((elms[i].type == "text" || elms[i].type == "textarea") && elms[i].getAttribute("dir") != "ltr")
+					elms[i].dir = dir;
+			}
 		}
-	}
 
-	if (body.style.display == 'none')
-		body.style.display = 'block';
+		if (body.style.display == 'none')
+			body.style.display = 'block';
 
-	// Execute real onload (Opera fix)
-	if (tinyMCEPopup.onLoadEval != "") {
-		eval(tinyMCEPopup.onLoadEval);
-	}
-};
+		// Execute real onload (Opera fix)
+		if (tinyMCEPopup.onLoadEval != "")
+			eval(tinyMCEPopup.onLoadEval);
+	},
+
+	executeOnLoad : function(str) {
+		if (tinyMCE.isOpera)
+			this.onLoadEval = str;
+		else
+			eval(str);
+	},
+
+	resizeToInnerSize : function() {
+		// Netscape 7.1 workaround
+		if (this.isWindow && tinyMCE.isNS71) {
+			window.resizeBy(0, 10);
+			return;
+		}
 
-TinyMCEPopup.prototype.executeOnLoad = function(str) {
-	if (tinyMCE.isOpera)
-		this.onLoadEval = str;
-	else
-		eval(str);
-};
+		if (this.isWindow) {
+			var doc = document;
+			var body = doc.body;
+			var oldMargin, wrapper, iframe, nodes, dx, dy;
+
+			if (body.style.display == 'none')
+				body.style.display = 'block';
+
+			// Remove margin
+			oldMargin = body.style.margin;
+			body.style.margin = '0';
+
+			// Create wrapper
+			wrapper = doc.createElement("div");
+			wrapper.id = 'mcBodyWrapper';
+			wrapper.style.display = 'none';
+			wrapper.style.margin = '0';
+
+			// Wrap body elements
+			nodes = doc.body.childNodes;
+			for (var i=nodes.length-1; i>=0; i--) {
+				if (wrapper.hasChildNodes())
+					wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);
+				else
+					wrapper.appendChild(nodes[i].cloneNode(true));
+
+				nodes[i].parentNode.removeChild(nodes[i]);
+			}
+
+			// Add wrapper
+			doc.body.appendChild(wrapper);
+
+			// Create iframe
+			iframe = document.createElement("iframe");
+			iframe.id = "mcWinIframe";
+			iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings['default_document'];
+			iframe.width = "100%";
+			iframe.height = "100%";
+			iframe.style.margin = '0';
+
+			// Add iframe
+			doc.body.appendChild(iframe);
+
+			// Measure iframe
+			iframe = document.getElementById('mcWinIframe');
+			dx = tinyMCE.getWindowArg('mce_width') - iframe.clientWidth;
+			dy = tinyMCE.getWindowArg('mce_height') - iframe.clientHeight;
+
+			// Resize window
+			// tinyMCE.debug(tinyMCE.getWindowArg('mce_width') + "," + tinyMCE.getWindowArg('mce_height') + " - " + dx + "," + dy);
+			window.resizeBy(dx, dy);
+
+			// Hide iframe and show wrapper
+			body.style.margin = oldMargin;
+			iframe.style.display = 'none';
+			wrapper.style.display = 'block';
+		}
+	},
 
-TinyMCEPopup.prototype.resizeToInnerSize = function() {
-	// Netscape 7.1 workaround
-	if (this.isWindow && tinyMCE.isNS71) {
-		window.resizeBy(0, 10);
-		return;
-	}
+	resizeToContent : function() {
+		var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
+		var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
+
+		if (isOpera)
+			return;
+
+		if (isMSIE) {
+			try { window.resizeTo(10, 10); } catch (e) {}
+
+			var elm = document.body;
+			var width = elm.offsetWidth;
+			var height = elm.offsetHeight;
+			var dx = (elm.scrollWidth - width) + 4;
+			var dy = elm.scrollHeight - height;
+
+			try { window.resizeBy(dx, dy); } catch (e) {}
+		} else {
+			window.scrollBy(1000, 1000);
+			if (window.scrollX > 0 || window.scrollY > 0) {
+				window.resizeBy(window.innerWidth * 2, window.innerHeight * 2);
+				window.sizeToContent();
+				window.scrollTo(0, 0);
+				var x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
+				var y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
+				window.moveTo(x, y);
+			}
+		}
+	},
 
-	if (this.isWindow) {
-		var doc = document;
-		var body = doc.body;
-		var oldMargin, wrapper, iframe, nodes, dx, dy;
+	getWindowArg : function(name, default_value) {
+		return tinyMCE.getWindowArg(name, default_value);
+	},
 
-		if (body.style.display == 'none')
-			body.style.display = 'block';
+	restoreSelection : function() {
+		if (this.storeSelection) {
+			var inst = tinyMCE.selectedInstance;
 
-		// Remove margin
-		oldMargin = body.style.margin;
-		body.style.margin = '0px';
-
-		// Create wrapper
-		wrapper = doc.createElement("div");
-		wrapper.id = 'mcBodyWrapper';
-		wrapper.style.display = 'none';
-		wrapper.style.margin = '0px';
-
-		// Wrap body elements
-		nodes = doc.body.childNodes;
-		for (var i=nodes.length-1; i>=0; i--) {
-			if (wrapper.hasChildNodes())
-				wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);
-			else
-				wrapper.appendChild(nodes[i].cloneNode(true));
-
-			nodes[i].parentNode.removeChild(nodes[i]);
-		}
-
-		// Add wrapper
-		doc.body.appendChild(wrapper);
-
-		// Create iframe
-		iframe = document.createElement("iframe");
-		iframe.id = "mcWinIframe";
-		iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings['default_document'];
-		iframe.width = "100%";
-		iframe.height = "100%";
-		iframe.style.margin = '0px';
-
-		// Add iframe
-		doc.body.appendChild(iframe);
-
-		// Measure iframe
-		iframe = document.getElementById('mcWinIframe');
-		dx = tinyMCE.getWindowArg('mce_width') - iframe.clientWidth;
-		dy = tinyMCE.getWindowArg('mce_height') - iframe.clientHeight;
-
-		// Resize window
-		// tinyMCE.debug(tinyMCE.getWindowArg('mce_width') + "," + tinyMCE.getWindowArg('mce_height') + " - " + dx + "," + dy);
-		window.resizeBy(dx, dy);
-
-		// Hide iframe and show wrapper
-		body.style.margin = oldMargin;
-		iframe.style.display = 'none';
-		wrapper.style.display = 'block';
-	}
-};
+			inst.getWin().focus();
 
-TinyMCEPopup.prototype.resizeToContent = function() {
-	var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
-	var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
-
-	if (isOpera)
-		return;
-
-	if (isMSIE) {
-		try { window.resizeTo(10, 10); } catch (e) {}
-
-		var elm = document.body;
-		var width = elm.offsetWidth;
-		var height = elm.offsetHeight;
-		var dx = (elm.scrollWidth - width) + 4;
-		var dy = elm.scrollHeight - height;
-
-		try { window.resizeBy(dx, dy); } catch (e) {}
-	} else {
-		window.scrollBy(1000, 1000);
-		if (window.scrollX > 0 || window.scrollY > 0) {
-			window.resizeBy(window.innerWidth * 2, window.innerHeight * 2);
-			window.sizeToContent();
-			window.scrollTo(0, 0);
-			var x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
-			var y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
-			window.moveTo(x, y);
+			if (inst.selectionBookmark)
+				inst.selection.moveToBookmark(inst.selectionBookmark);
 		}
-	}
-};
+	},
 
-TinyMCEPopup.prototype.getWindowArg = function(name, default_value) {
-	return tinyMCE.getWindowArg(name, default_value);
-};
-
-TinyMCEPopup.prototype.execCommand = function(command, user_interface, value) {
-	var inst = tinyMCE.selectedInstance;
+	execCommand : function(command, user_interface, value) {
+		var inst = tinyMCE.selectedInstance;
 
-	// Restore selection
-	if (this.storeSelection) {
-		inst.getWin().focus();
-		inst.execCommand('mceRestoreSelection');
-	}
+		this.restoreSelection();
+		inst.execCommand(command, user_interface, value);
 
-	inst.execCommand(command, user_interface, value);
+		// Store selection
+		if (this.storeSelection)
+			inst.selectionBookmark = inst.selection.getBookmark(true);
+	},
+
+	close : function() {
+		tinyMCE.closeWindow(window);
+	},
+
+	pickColor : function(e, element_id) {
+		tinyMCE.selectedInstance.execCommand('mceColorPicker', true, {
+			element_id : element_id,
+			document : document,
+			window : window,
+			store_selection : false
+		});
+	},
+
+	openBrowser : function(element_id, type, option) {
+		var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
+		var url = document.getElementById(element_id).value;
+
+		tinyMCE.setWindowArg("window", window);
+		tinyMCE.setWindowArg("document", document);
+
+		// Call to external callback
+		if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined")
+			alert("Callback function: " + cb + " could not be found.");
+		else
+			eval("tinyMCEPopup.windowOpener." + cb + "(element_id, url, type, window);");
+	},
 
-	// Store selection
-	if (this.storeSelection)
-		inst.execCommand('mceStoreSelection');
-};
+	importClass : function(c) {
+		window[c] = function() {};
 
-TinyMCEPopup.prototype.close = function() {
-	tinyMCE.closeWindow(window);
-};
+		for (var n in window.opener[c].prototype)
+			window[c].prototype[n] = window.opener[c].prototype[n];
 
-TinyMCEPopup.prototype.pickColor = function(e, element_id) {
-	tinyMCE.selectedInstance.execCommand('mceColorPicker', true, {
-		element_id : element_id,
-		document : document,
-		window : window,
-		store_selection : false
-	});
-};
+		window[c].constructor = window.opener[c].constructor;
+	}
 
-TinyMCEPopup.prototype.openBrowser = function(element_id, type, option) {
-	var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
-	var url = document.getElementById(element_id).value;
-
-	tinyMCE.setWindowArg("window", window);
-	tinyMCE.setWindowArg("document", document);
-
-	// Call to external callback
-	if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined")
-		alert("Callback function: " + cb + " could not be found.");
-	else
-		eval("tinyMCEPopup.windowOpener." + cb + "(element_id, url, type, window);");
-};
+	};
 
 // Setup global instance
-var tinyMCEPopup = new TinyMCEPopup();
+var tinyMCEPopup = new TinyMCE_Popup();
 
 tinyMCEPopup.init();
diff -ruN 2.0.5/wp-includes/js/tinymce/utils/editable_selects.js 2.2.2/wp-includes/js/tinymce/utils/editable_selects.js
--- 2.0.5/wp-includes/js/tinymce/utils/editable_selects.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/utils/editable_selects.js	2007-01-24 19:20:47.000000000 -0600
@@ -0,0 +1,61 @@
+/**
+ * $Id: editable_selects.js 162 2007-01-03 16:16:52Z spocke $
+ *
+ * Makes select boxes editable.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+var TinyMCE_EditableSelects = {
+	editSelectElm : null,
+
+	init : function() {
+		var nl = document.getElementsByTagName("select"), i, d = document, o;
+
+		for (i=0; i<nl.length; i++) {
+			if (nl[i].className.indexOf('mceEditableSelect') != -1) {
+				o = new Option('(value)', '__mce_add_custom__');
+
+				o.className = 'mceAddSelectValue';
+
+				nl[i].options[nl[i].options.length] = o;
+				nl[i].setAttribute('onchange', 'TinyMCE_EditableSelects.onChangeEditableSelect(this);');
+			}
+		}
+	},
+
+	onChangeEditableSelect : function(se) {
+		var d = document, ne;
+
+		if (se.options[se.selectedIndex].value == '__mce_add_custom__') {
+			ne = d.createElement("input");
+			ne.id = se.id + "_custom";
+			ne.name = se.name + "_custom";
+			ne.type = "text";
+
+			ne.style.width = se.clientWidth;
+			se.parentNode.insertBefore(ne, se);
+			se.style.display = 'none';
+			ne.focus();
+			ne.onblur = TinyMCE_EditableSelects.onBlurEditableSelectInput;
+			TinyMCE_EditableSelects.editSelectElm = se;
+		}
+	},
+
+	onBlurEditableSelectInput : function() {
+		var se = TinyMCE_EditableSelects.editSelectElm;
+
+		if (se) {
+			if (se.previousSibling.value != '') {
+				addSelectValue(document.forms[0], se.id, se.previousSibling.value, se.previousSibling.value);
+				selectByValue(document.forms[0], se.id, se.previousSibling.value);
+			} else
+				selectByValue(document.forms[0], se.id, '');
+
+			se.style.display = 'inline';
+			se.parentNode.removeChild(se.previousSibling);
+			TinyMCE_EditableSelects.editSelectElm = null;
+		}
+	}
+};
diff -ruN 2.0.5/wp-includes/js/tinymce/utils/form_utils.js 2.2.2/wp-includes/js/tinymce/utils/form_utils.js
--- 2.0.5/wp-includes/js/tinymce/utils/form_utils.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/utils/form_utils.js	2007-01-24 19:20:47.000000000 -0600
@@ -1,204 +1,210 @@
-/**
- * $RCSfile: form_utils.js,v $
- * $Revision: 1.5 $
- * $Date: 2005/10/25 16:01:51 $
- *
- * Various form utilitiy functions.
- *
- * @author Moxiecode
- * @copyright Copyright  2005, Moxiecode Systems AB, All rights reserved.
- */
-
-function getColorPickerHTML(id, target_form_element) {
-	var html = "";
-
-	html += '<a id="' + id + '_link" href="javascript:void(0);" onkeydown="pickColor(event,\'' + target_form_element +'\');" onmousedown="pickColor(event,\'' + target_form_element +'\');return false;">';
-	html += '<img id="' + id + '" src="../../themes/advanced/images/color.gif"';
-	html += ' onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');"';
-	html += ' onmouseout="tinyMCE.restoreClass(this);"';
-	html += ' onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');"';
-	html += ' width="20" height="16" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
-	html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
-
-	return html;
-}
-
-function pickColor(e, target_form_element) {
-	if ((e.keyCode == 32 || e.keyCode == 13) || e.type == "mousedown")
-		tinyMCEPopup.pickColor(e, target_form_element);
-}
-
-function updateColor(img_id, form_element_id) {
-	document.getElementById(img_id).style.backgroundColor = document.forms[0].elements[form_element_id].value;
-}
-
-function setBrowserDisabled(id, state) {
-	var img = document.getElementById(id);
-	var lnk = document.getElementById(id + "_link");
-
-	if (lnk) {
-		if (state) {
-			lnk.setAttribute("realhref", lnk.getAttribute("href"));
-			lnk.removeAttribute("href");
-			tinyMCE.switchClass(img, 'mceButtonDisabled', true);
-		} else {
-			lnk.setAttribute("href", lnk.getAttribute("realhref"));
-			tinyMCE.switchClass(img, 'mceButtonNormal', false);
-		}
-	}
-}
-
-function getBrowserHTML(id, target_form_element, type, prefix) {
-	var option = prefix + "_" + type + "_browser_callback";
-	var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
-	if (cb == null)
-		return "";
-
-	var html = "";
-
-	html += '<a id="' + id + '_link" href="javascript:openBrower(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;">';
-	html += '<img id="' + id + '" src="../../themes/advanced/images/browse.gif"';
-	html += ' onmouseover="tinyMCE.switchClass(this,\'mceButtonOver\');"';
-	html += ' onmouseout="tinyMCE.restoreClass(this);"';
-	html += ' onmousedown="tinyMCE.restoreAndSwitchClass(this,\'mceButtonDown\');"';
-	html += ' width="20" height="18" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
-	html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
-
-	return html;
-}
-
-function openBrower(img_id, target_form_element, type, option) {
-	var img = document.getElementById(img_id);
-
-	if (img.className != "mceButtonDisabled")
-		tinyMCEPopup.openBrowser(target_form_element, type, option);
-}
-
-function selectByValue(form_obj, field_name, value, add_custom) {
-	if (!form_obj || !form_obj.elements[field_name])
-		return;
-
-	var sel = form_obj.elements[field_name];
-
-	var found = false;
-	for (var i=0; i<sel.options.length; i++) {
-		var option = sel.options[i];
-
-		if (option.value == value) {
-			option.selected = true;
-			found = true;
-		} else
-			option.selected = false;
-	}
-
-	if (!found && add_custom && value != '') {
-		var option = new Option('Value: ' + value, value);
-		option.selected = true;
-		sel.options[sel.options.length] = option;
-	}
-
-	return found;
-}
-
-function getSelectValue(form_obj, field_name) {
-	var elm = form_obj.elements[field_name];
-
-	if (elm == null || elm.options == null)
-		return "";
-
-	return elm.options[elm.selectedIndex].value;
-}
-
-function addClassesToList(list_id, specific_option) {
-return;
-	// Setup class droplist
-	var styleSelectElm = document.getElementById(list_id);
-	var styles = tinyMCE.getParam('theme_advanced_styles', false);
-	styles = tinyMCE.getParam(specific_option, styles);
-
-	if (styles) {
-		var stylesAr = styles.split(';');
-
-		for (var i=0; i<stylesAr.length; i++) {
-			if (stylesAr != "") {
-				var key, value;
-
-				key = stylesAr[i].split('=')[0];
-				value = stylesAr[i].split('=')[1];
-
-				styleSelectElm.options[styleSelectElm.length] = new Option(key, value);
-			}
-		}
-	} else {
-		// Use auto impored classes
-		var csses = tinyMCE.getCSSClasses(tinyMCE.getWindowArg('editor_id'));
-		for (var i=0; i<csses.length; i++)
-			styleSelectElm.options[styleSelectElm.length] = new Option(csses[i], csses[i]);
-	}
-}
-
-function isVisible(element_id) {
-	var elm = document.getElementById(element_id);
-
-	return elm && elm.style.display != "none";
-}
-
-function convertRGBToHex(col) {
-	var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi");
-
-	var rgb = col.replace(re, "$1,$2,$3").split(',');
-	if (rgb.length == 3) {
-		r = parseInt(rgb[0]).toString(16);
-		g = parseInt(rgb[1]).toString(16);
-		b = parseInt(rgb[2]).toString(16);
-
-		r = r.length == 1 ? '0' + r : r;
-		g = g.length == 1 ? '0' + g : g;
-		b = b.length == 1 ? '0' + b : b;
-
-		return "#" + r + g + b;
-	}
-
-	return col;
-}
-
-function convertHexToRGB(col) {
-	if (col.indexOf('#') != -1) {
-		col = col.replace(new RegExp('[^0-9A-F]', 'gi'), '');
-
-		r = parseInt(col.substring(0, 2), 16);
-		g = parseInt(col.substring(2, 4), 16);
-		b = parseInt(col.substring(4, 6), 16);
-
-		return "rgb(" + r + "," + g + "," + b + ")";
-	}
-
-	return col;
-}
-
-function trimSize(size) {
-	return size.replace(new RegExp('[^0-9%]', 'gi'), '');
-}
-
-function getCSSSize(size) {
-	size = trimSize(size);
-
-	if (size == "")
-		return "";
-
-	return size.indexOf('%') != -1 ? size : size + "px";
-}
-
-function getStyle(elm, attrib, style) {
-	var val = tinyMCE.getAttrib(elm, attrib);
-
-	if (val != '')
-		return '' + val;
-
-	if (typeof(style) == 'undefined')
-		style = attrib;
-
-	val = eval('elm.style.' + style);
-
-	return val == null ? '' : '' + val;
-}
+/**
+ * $Id: form_utils.js 162 2007-01-03 16:16:52Z spocke $
+ *
+ * Various form utilitiy functions.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+var themeBaseURL = tinyMCE.baseURL + '/themes/' + tinyMCE.getParam("theme");
+
+function getColorPickerHTML(id, target_form_element) {
+	var h = "";
+
+	h += '<a id="' + id + '_link" href="javascript:void(0);" onkeydown="pickColor(event,\'' + target_form_element +'\');" onmousedown="pickColor(event,\'' + target_form_element +'\');return false;">';
+	h += '<img id="' + id + '" src="' + themeBaseURL + '/images/color.gif"';
+	h += ' onmouseover="this.className=\'mceButtonOver\'"';
+	h += ' onmouseout="this.className=\'mceButtonNormal\'"';
+	h += ' onmousedown="this.className=\'mceButtonDown\'"';
+	h += ' width="20" height="16" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
+	h += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
+
+	return h;
+}
+
+function pickColor(e, target_form_element) {
+	if ((e.keyCode == 32 || e.keyCode == 13) || e.type == "mousedown")
+		tinyMCEPopup.pickColor(e, target_form_element);
+}
+
+function updateColor(img_id, form_element_id) {
+	document.getElementById(img_id).style.backgroundColor = document.forms[0].elements[form_element_id].value;
+}
+
+function setBrowserDisabled(id, state) {
+	var img = document.getElementById(id);
+	var lnk = document.getElementById(id + "_link");
+
+	if (lnk) {
+		if (state) {
+			lnk.setAttribute("realhref", lnk.getAttribute("href"));
+			lnk.removeAttribute("href");
+			tinyMCE.switchClass(img, 'mceButtonDisabled', true);
+		} else {
+			lnk.setAttribute("href", lnk.getAttribute("realhref"));
+			tinyMCE.switchClass(img, 'mceButtonNormal', false);
+		}
+	}
+}
+
+function getBrowserHTML(id, target_form_element, type, prefix) {
+	var option = prefix + "_" + type + "_browser_callback";
+	var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback"));
+	if (cb == null)
+		return "";
+
+	var html = "";
+
+	html += '<a id="' + id + '_link" href="javascript:openBrower(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;">';
+	html += '<img id="' + id + '" src="' + themeBaseURL + '/images/browse.gif"';
+	html += ' onmouseover="this.className=\'mceButtonOver\';"';
+	html += ' onmouseout="this.className=\'mceButtonNormal\';"';
+	html += ' onmousedown="this.className=\'mceButtonDown\';"';
+	html += ' width="20" height="18" border="0" title="' + tinyMCE.getLang('lang_browse') + '"';
+	html += ' class="mceButtonNormal" alt="' + tinyMCE.getLang('lang_browse') + '" /></a>';
+
+	return html;
+}
+
+function openBrower(img_id, target_form_element, type, option) {
+	var img = document.getElementById(img_id);
+
+	if (img.className != "mceButtonDisabled")
+		tinyMCEPopup.openBrowser(target_form_element, type, option);
+}
+
+function selectByValue(form_obj, field_name, value, add_custom, ignore_case) {
+	if (!form_obj || !form_obj.elements[field_name])
+		return;
+
+	var sel = form_obj.elements[field_name];
+
+	var found = false;
+	for (var i=0; i<sel.options.length; i++) {
+		var option = sel.options[i];
+
+		if (option.value == value || (ignore_case && option.value.toLowerCase() == value.toLowerCase())) {
+			option.selected = true;
+			found = true;
+		} else
+			option.selected = false;
+	}
+
+	if (!found && add_custom && value != '') {
+		var option = new Option(value, value);
+		option.selected = true;
+		sel.options[sel.options.length] = option;
+		sel.selectedIndex = sel.options.length - 1;
+	}
+
+	return found;
+}
+
+function getSelectValue(form_obj, field_name) {
+	var elm = form_obj.elements[field_name];
+
+	if (elm == null || elm.options == null)
+		return "";
+
+	return elm.options[elm.selectedIndex].value;
+}
+
+function addSelectValue(form_obj, field_name, name, value) {
+	var s = form_obj.elements[field_name];
+	var o = new Option(name, value);
+	s.options[s.options.length] = o;
+}
+
+function addClassesToList(list_id, specific_option) {
+	// Setup class droplist
+	var styleSelectElm = document.getElementById(list_id);
+	var styles = tinyMCE.getParam('theme_advanced_styles', false);
+	styles = tinyMCE.getParam(specific_option, styles);
+
+	if (styles) {
+		var stylesAr = styles.split(';');
+
+		for (var i=0; i<stylesAr.length; i++) {
+			if (stylesAr != "") {
+				var key, value;
+
+				key = stylesAr[i].split('=')[0];
+				value = stylesAr[i].split('=')[1];
+
+				styleSelectElm.options[styleSelectElm.length] = new Option(key, value);
+			}
+		}
+	} else {
+		// Use auto impored classes
+		var csses = tinyMCE.getCSSClasses(tinyMCE.getWindowArg('editor_id'));
+		for (var i=0; i<csses.length; i++)
+			styleSelectElm.options[styleSelectElm.length] = new Option(csses[i], csses[i]);
+	}
+}
+
+function isVisible(element_id) {
+	var elm = document.getElementById(element_id);
+
+	return elm && elm.style.display != "none";
+}
+
+function convertRGBToHex(col) {
+	var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi");
+
+	var rgb = col.replace(re, "$1,$2,$3").split(',');
+	if (rgb.length == 3) {
+		r = parseInt(rgb[0]).toString(16);
+		g = parseInt(rgb[1]).toString(16);
+		b = parseInt(rgb[2]).toString(16);
+
+		r = r.length == 1 ? '0' + r : r;
+		g = g.length == 1 ? '0' + g : g;
+		b = b.length == 1 ? '0' + b : b;
+
+		return "#" + r + g + b;
+	}
+
+	return col;
+}
+
+function convertHexToRGB(col) {
+	if (col.indexOf('#') != -1) {
+		col = col.replace(new RegExp('[^0-9A-F]', 'gi'), '');
+
+		r = parseInt(col.substring(0, 2), 16);
+		g = parseInt(col.substring(2, 4), 16);
+		b = parseInt(col.substring(4, 6), 16);
+
+		return "rgb(" + r + "," + g + "," + b + ")";
+	}
+
+	return col;
+}
+
+function trimSize(size) {
+	return size.replace(new RegExp('[^0-9%]', 'gi'), '');
+}
+
+function getCSSSize(size) {
+	size = trimSize(size);
+
+	if (size == "")
+		return "";
+
+	return size.indexOf('%') != -1 ? size : size + "px";
+}
+
+function getStyle(elm, attrib, style) {
+	var val = tinyMCE.getAttrib(elm, attrib);
+
+	if (val != '')
+		return '' + val;
+
+	if (typeof(style) == 'undefined')
+		style = attrib;
+
+	val = eval('elm.style.' + style);
+
+	return val == null ? '' : '' + val;
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/utils/mclayer.js 2.2.2/wp-includes/js/tinymce/utils/mclayer.js
--- 2.0.5/wp-includes/js/tinymce/utils/mclayer.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/utils/mclayer.js	2007-01-24 19:20:47.000000000 -0600
@@ -0,0 +1,210 @@
+/**
+ * $Id: mclayer.js 162 2007-01-03 16:16:52Z spocke $
+ *
+ * Moxiecode floating layer script.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+function MCLayer(id) {
+	this.id = id;
+	this.settings = new Array();
+	this.blockerElement = null;
+	this.isMSIE = navigator.appName == "Microsoft Internet Explorer";
+	this.events = false;
+	this.autoHideCallback = null;
+}
+
+MCLayer.prototype = {
+	moveRelativeTo : function(re, p, a) {
+		var rep = this.getAbsPosition(re);
+		var w = parseInt(re.offsetWidth);
+		var h = parseInt(re.offsetHeight);
+		var x, y;
+
+		switch (p) {
+			case "tl":
+				break;
+
+			case "tr":
+				x = rep.absLeft + w;
+				y = rep.absTop;
+				break;
+
+			case "bl":
+				break;
+
+			case "br":
+				break;
+		}
+
+		this.moveTo(x, y);
+	},
+
+	moveBy : function(dx, dy) {
+		var e = this.getElement();
+		var x = parseInt(e.style.left);
+		var y = parseInt(e.style.top);
+
+		e.style.left = (x + dx) + "px";
+		e.style.top = (y + dy) + "px";
+
+		this.updateBlocker();
+	},
+
+	moveTo : function(x, y) {
+		var e = this.getElement();
+
+		e.style.left = x + "px";
+		e.style.top = y + "px";
+
+		this.updateBlocker();
+	},
+
+	show : function() {
+		MCLayer.visibleLayer = this;
+
+		this.getElement().style.display = 'block';
+		this.updateBlocker();
+	},
+
+	hide : function() {
+		this.getElement().style.display = 'none';
+		this.updateBlocker();
+	},
+
+	setAutoHide : function(s, cb) {
+		this.autoHideCallback = cb;
+		this.registerEventHandlers();
+	},
+
+	getElement : function() {
+		return document.getElementById(this.id);
+	},
+
+	updateBlocker : function() {
+		if (!this.isMSIE)
+			return;
+
+		var e = this.getElement();
+		var b = this.getBlocker();
+		var x = this.parseInt(e.style.left);
+		var y = this.parseInt(e.style.top);
+		var w = this.parseInt(e.offsetWidth);
+		var h = this.parseInt(e.offsetHeight);
+
+		b.style.left = x + 'px';
+		b.style.top = y + 'px';
+		b.style.width = w + 'px';
+		b.style.height = h + 'px';
+		b.style.display = e.style.display;
+	},
+
+	getBlocker : function() {
+		if (!this.blockerElement) {
+			var d = document, b = d.createElement("iframe");
+
+			b.style.cssText = 'display: none; left: 0px; position: absolute; top: 0';
+			b.src = 'javascript:false;';
+			b.frameBorder = '0';
+			b.scrolling = 'no';
+
+			d.body.appendChild(b);
+			this.blockerElement = b;
+		}
+
+		return this.blockerElement;
+	},
+
+	getAbsPosition : function(n) {
+		var p = {absLeft : 0, absTop : 0};
+
+		while (n) {
+			p.absLeft += n.offsetLeft;
+			p.absTop += n.offsetTop;
+			n = n.offsetParent;
+		}
+
+		return p;
+	},
+
+	registerEventHandlers : function() {
+		if (!this.events) {
+			var d = document;
+
+			this.addEvent(d, 'mousedown', MCLayer.prototype.onMouseDown);
+
+			this.events = true;
+		}
+	},
+
+	addEvent : function(o, n, h) {
+		if (o.attachEvent)
+			o.attachEvent("on" + n, h);
+		else
+			o.addEventListener(n, h, false);
+	},
+
+	onMouseDown : function(e) {
+		e = typeof(e) == "undefined" ? window.event : e;
+		var b = document.body;
+		var l = MCLayer.visibleLayer;
+
+		if (l) {
+			var mx = l.isMSIE ? e.clientX + b.scrollLeft : e.pageX;
+			var my = l.isMSIE ? e.clientY + b.scrollTop : e.pageY;
+			var el = l.getElement();
+			var x = parseInt(el.style.left);
+			var y = parseInt(el.style.top);
+			var w = parseInt(el.offsetWidth);
+			var h = parseInt(el.offsetHeight);
+
+			if (!(mx > x && mx < x + w && my > y && my < y + h)) {
+				MCLayer.visibleLayer = null;
+
+				if (l.autoHideCallback && l.autoHideCallback(l, e, mx, my))
+					return true;
+
+				l.hide();
+			}
+		}
+	},
+
+	addCSSClass : function(e, c) {
+		this.removeCSSClass(e, c);
+		var a = this.explode(' ', e.className);
+		a[a.length] = c;
+		e.className = a.join(' ');
+	},
+
+	removeCSSClass : function(e, c) {
+		var a = this.explode(' ', e.className), i;
+
+		for (i=0; i<a.length; i++) {
+			if (a[i] == c)
+				a[i] = '';
+		}
+
+		e.className = a.join(' ');
+	},
+
+	explode : function(d, s) {
+		var ar = s.split(d);
+		var oar = new Array();
+
+		for (var i = 0; i<ar.length; i++) {
+			if (ar[i] != "")
+				oar[oar.length] = ar[i];
+		}
+
+		return oar;
+	},
+
+	parseInt : function(s) {
+		if (s == null || s == '')
+			return 0;
+
+		return parseInt(s);
+	}
+}
diff -ruN 2.0.5/wp-includes/js/tinymce/utils/mctabs.js 2.2.2/wp-includes/js/tinymce/utils/mctabs.js
--- 2.0.5/wp-includes/js/tinymce/utils/mctabs.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/utils/mctabs.js	2007-01-24 19:20:47.000000000 -0600
@@ -1,76 +1,74 @@
-/**
- * $RCSfile: mctabs.js,v $
- * $Revision: 1.1 $
- * $Date: 2005/08/01 18:36:35 $
- *
- * Moxiecode DHTML Tabs script.
- *
- * @author Moxiecode
- * @copyright Copyright  2004, Moxiecode Systems AB, All rights reserved.
- */
-
-function MCTabs() {
-	this.settings = new Array();
-};
-
-MCTabs.prototype.init = function(settings) {
-	this.settings = settings;
-};
-
-MCTabs.prototype.getParam = function(name, default_value) {
-	var value = null;
-
-	value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
-
-	// Fix bool values
-	if (value == "true" || value == "false")
-		return (value == "true");
-
-	return value;
-};
-
-MCTabs.prototype.displayTab = function(tab_id, panel_id) {
-	var panelElm = document.getElementById(panel_id);
-	var panelContainerElm = panelElm ? panelElm.parentNode : null;
-	var tabElm = document.getElementById(tab_id);
-	var tabContainerElm = tabElm ? tabElm.parentNode : null;
-	var selectionClass = this.getParam('selection_class', 'current');
-
-	if (tabElm && tabContainerElm) {
-		var nodes = tabContainerElm.childNodes;
-
-		// Hide all other tabs
-		for (var i=0; i<nodes.length; i++) {
-			if (nodes[i].nodeName == "LI")
-				nodes[i].className = '';
-		}
-
-		// Show selected tab
-		tabElm.className = 'current';
-	}
-
-	if (panelElm && panelContainerElm) {
-		var nodes = panelContainerElm.childNodes;
-
-		// Hide all other panels
-		for (var i=0; i<nodes.length; i++) {
-			if (nodes[i].nodeName == "DIV")
-				nodes[i].className = 'panel';
-		}
-
-		// Show selected panel
-		panelElm.className = 'current';
-	}
-};
-
-MCTabs.prototype.getAnchor = function() {
-	var pos, url = document.location.href;
-
-	if ((pos = url.lastIndexOf('#')) != -1)
-		return url.substring(pos + 1);
-
-	return "";
-};
-
-// Global instance
-var mcTabs = new MCTabs();
+/**
+ * $Id: mctabs.js 162 2007-01-03 16:16:52Z spocke $
+ *
+ * Moxiecode DHTML Tabs script.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+function MCTabs() {
+	this.settings = new Array();
+};
+
+MCTabs.prototype.init = function(settings) {
+	this.settings = settings;
+};
+
+MCTabs.prototype.getParam = function(name, default_value) {
+	var value = null;
+
+	value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name];
+
+	// Fix bool values
+	if (value == "true" || value == "false")
+		return (value == "true");
+
+	return value;
+};
+
+MCTabs.prototype.displayTab = function(tab_id, panel_id) {
+	var panelElm = document.getElementById(panel_id);
+	var panelContainerElm = panelElm ? panelElm.parentNode : null;
+	var tabElm = document.getElementById(tab_id);
+	var tabContainerElm = tabElm ? tabElm.parentNode : null;
+	var selectionClass = this.getParam('selection_class', 'current');
+
+	if (tabElm && tabContainerElm) {
+		var nodes = tabContainerElm.childNodes;
+
+		// Hide all other tabs
+		for (var i=0; i<nodes.length; i++) {
+			if (nodes[i].nodeName == "LI")
+				nodes[i].className = '';
+		}
+
+		// Show selected tab
+		tabElm.className = 'current';
+	}
+
+	if (panelElm && panelContainerElm) {
+		var nodes = panelContainerElm.childNodes;
+
+		// Hide all other panels
+		for (var i=0; i<nodes.length; i++) {
+			if (nodes[i].nodeName == "DIV")
+				nodes[i].className = 'panel';
+		}
+
+		// Show selected panel
+		panelElm.className = 'current';
+	}
+};
+
+MCTabs.prototype.getAnchor = function() {
+	var pos, url = document.location.href;
+
+	if ((pos = url.lastIndexOf('#')) != -1)
+		return url.substring(pos + 1);
+
+	return "";
+};
+
+// Global instance
+var mcTabs = new MCTabs();
diff -ruN 2.0.5/wp-includes/js/tinymce/utils/validate.js 2.2.2/wp-includes/js/tinymce/utils/validate.js
--- 2.0.5/wp-includes/js/tinymce/utils/validate.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/utils/validate.js	2007-01-24 19:20:47.000000000 -0600
@@ -1,50 +1,219 @@
-/**
- * $RCSfile: validate.js,v $
- * $Revision: 1.2 $
- * $Date: 2005/08/13 12:20:37 $
- *
- * Various form validation methods.
- *
- * @author Moxiecode
- * @copyright Copyright  2005, Moxiecode Systems AB, All rights reserved.
- */
-
-function testRegExp(form_name, element_name, re) {
-	return new RegExp(re).test(document.forms[form_name].elements[element_name].value);
-}
-
-function validateString(form_name, element_name) {
-	return (document.forms[form_name].elements[element_name].value.length > 0);
-}
-
-function validateSelection(form_name, element_name) {
-	return (document.forms[form_name].elements[element_name].selectedIndex > 0);
-}
-
-function validateCheckBox(form_name, element_name) {
-	return document.forms[form_name].elements[element_name].checked;
-}
-
-function validateCleanString(form_name, element_name) {
-	return testRegExp(form_name, element_name, '^[A-Za-z0-9_]+$');
-}
-
-function validateEmail(form_name, element_name) {
-	return testRegExp(form_name, element_name, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
-}
-
-function validateAbsUrl(form_name, element_name) {
-	return testRegExp(form_name, element_name, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+$');
-}
-
-function validateNumber(form_name, element_name, allow_blank) {
-	return (!allow_blank && value == '') ? false : testRegExp(form_name, element_name, '^-?[0-9]*\\.?[0-9]*$');
-}
-
-function validateSize(form_name, element_name,) {
-	return testRegExp(form_name, element_name, '^[0-9]+(px|%)?$');
-}
-
-function validateID(form_name, element_name,) {
-	return testRegExp(form_name, element_name, '^[A-Za-z_]([A-Za-z0-9_])*$');
-}
+/**
+ * $Id: validate.js 162 2007-01-03 16:16:52Z spocke $
+ *
+ * Various form validation methods.
+ *
+ * @author Moxiecode
+ * @copyright Copyright  2004-2007, Moxiecode Systems AB, All rights reserved.
+ */
+
+/**
+	// String validation:
+
+	if (!Validator.isEmail('myemail'))
+		alert('Invalid email.');
+
+	// Form validation:
+
+	var f = document.forms['myform'];
+
+	if (!Validator.isEmail(f.myemail))
+		alert('Invalid email.');
+*/
+
+var Validator = {
+	isEmail : function(s) {
+		return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
+	},
+
+	isAbsUrl : function(s) {
+		return this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+\\/?.*$');
+	},
+
+	isSize : function(s) {
+		return this.test(s, '^[0-9]+(px|%)?$');
+	},
+
+	isId : function(s) {
+		return this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');
+	},
+
+	isEmpty : function(s) {
+		var nl, i;
+
+		if (s.nodeName == 'SELECT' && s.selectedIndex < 1)
+			return true;
+
+		if (s.type == 'checkbox' && !s.checked)
+			return true;
+
+		if (s.type == 'radio') {
+			for (i=0, nl = s.form.elements; i<nl.length; i++) {
+				if (nl[i].type == "radio" && nl[i].name == s.name && nl[i].checked)
+					return false;
+			}
+
+			return true;
+		}
+
+		return new RegExp('^\\s*$').test(s.nodeType == 1 ? s.value : s);
+	},
+
+	isNumber : function(s, d) {
+		return !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\.[0-9]*$'));
+	},
+
+	test : function(s, p) {
+		s = s.nodeType == 1 ? s.value : s;
+
+		return s == '' || new RegExp(p).test(s);
+	}
+};
+
+var AutoValidator = {
+	settings : {
+		id_cls : 'id',
+		int_cls : 'int',
+		url_cls : 'url',
+		number_cls : 'number',
+		email_cls : 'email',
+		size_cls : 'size',
+		required_cls : 'required',
+		invalid_cls : 'invalid',
+		min_cls : 'min',
+		max_cls : 'max'
+	},
+
+	init : function(s) {
+		var n;
+
+		for (n in s)
+			this.settings[n] = s[n];
+	},
+
+	validate : function(f) {
+		var i, nl, s = this.settings, c = 0;
+
+		nl = this.tags(f, 'label');
+		for (i=0; i<nl.length; i++)
+			this.removeClass(nl[i], s.invalid_cls);
+
+		c += this.validateElms(f, 'input');
+		c += this.validateElms(f, 'select');
+		c += this.validateElms(f, 'textarea');
+
+		return c == 3;
+	},
+
+	invalidate : function(n) {
+		this.mark(n.form, n);
+	},
+
+	reset : function(e) {
+		var t = new Array('label', 'input', 'select', 'textarea');
+		var i, j, nl, s = this.settings;
+
+		if (e == null)
+			return;
+
+		for (i=0; i<t.length; i++) {
+			nl = this.tags(e.form ? e.form : e, t[i]);
+			for (j=0; j<nl.length; j++)
+				this.removeClass(nl[j], s.invalid_cls);
+		}
+	},
+
+	validateElms : function(f, e) {
+		var nl, i, n, s = this.settings, st = true, va = Validator, v;
+
+		nl = this.tags(f, e);
+		for (i=0; i<nl.length; i++) {
+			n = nl[i];
+
+			this.removeClass(n, s.invalid_cls);
+
+			if (this.hasClass(n, s.required_cls) && va.isEmpty(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.number_cls) && !va.isNumber(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.int_cls) && !va.isNumber(n, true))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.email_cls) && !va.isEmail(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.size_cls) && !va.isSize(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.id_cls) && !va.isId(n))
+				st = this.mark(f, n);
+
+			if (this.hasClass(n, s.min_cls, true)) {
+				v = this.getNum(n, s.min_cls);
+
+				if (isNaN(v) || parseInt(n.value) < parseInt(v))
+					st = this.mark(f, n);
+			}
+
+			if (this.hasClass(n, s.max_cls, true)) {
+				v = this.getNum(n, s.max_cls);
+
+				if (isNaN(v) || parseInt(n.value) > parseInt(v))
+					st = this.mark(f, n);
+			}
+		}
+
+		return st;
+	},
+
+	hasClass : function(n, c, d) {
+		return new RegExp('\\b' + c + (d ? '[0-9]+' : '') + '\\b', 'g').test(n.className);
+	},
+
+	getNum : function(n, c) {
+		c = n.className.match(new RegExp('\\b' + c + '([0-9]+)\\b', 'g'))[0];
+		c = c.replace(/[^0-9]/g, '');
+
+		return c;
+	},
+
+	addClass : function(n, c, b) {
+		var o = this.removeClass(n, c);
+		n.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
+	},
+
+	removeClass : function(n, c) {
+		c = n.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
+		return n.className = c != ' ' ? c : '';
+	},
+
+	tags : function(f, s) {
+		return f.getElementsByTagName(s);
+	},
+
+	mark : function(f, n) {
+		var s = this.settings;
+
+		this.addClass(n, s.invalid_cls);
+		this.markLabels(f, n, s.invalid_cls);
+
+		return false;
+	},
+
+	markLabels : function(f, n, ic) {
+		var nl, i;
+
+		nl = this.tags(f, "label");
+		for (i=0; i<nl.length; i++) {
+			if (nl[i].getAttribute("for") == n.id || nl[i].htmlFor == n.id)
+				this.addClass(nl[i], ic);
+		}
+
+		return null;
+	}
+};
diff -ruN 2.0.5/wp-includes/js/tinymce/wp-mce-help.php 2.2.2/wp-includes/js/tinymce/wp-mce-help.php
--- 2.0.5/wp-includes/js/tinymce/wp-mce-help.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tinymce/wp-mce-help.php	2007-03-06 21:05:41.000000000 -0600
@@ -1,13 +1,15 @@
-<?php
-
-require_once('../../../wp-config.php');
-
+<?php require_once('../../../wp-config.php');
+header('Content-Type: text/html; charset=' . get_bloginfo('charset'));
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
 <head>
+<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" />
 <title><?php _e('Rich Editor Help') ?></title>
-<link rel="stylesheet" href="<?php echo get_settings('siteurl') ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+<link rel="stylesheet" href="<?php echo get_option('siteurl') ?>/wp-admin/rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php endif; ?> 
 <style type="text/css">
 	#wphead {
 		padding-top: 5px;
@@ -78,6 +80,20 @@
 		border-bottom: 0px;
 	}
 </style>
+<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+<style type="text/css">
+	#wphead, #adminmenu {
+		padding-left: auto;
+		padding-right: 15px;
+	}
+	#flipper {
+		margin: 5px 0 3px 10px;
+	}
+	#keys .left, .top, .action { text-align: right; }
+	#keys .right { text-align: left; }
+	td b { font-family: Tahoma, "Times New Roman", Times, serif }
+</style>
+<?php endif; ?> 
 <script type="text/javascript">
 	window.onkeydown = window.onkeypress = function (e) {
 		e = e ? e : window.event;
@@ -93,7 +109,7 @@
 			c = d('content'+i.toString());
 			t = d('tab'+i.toString());
 			if ( n == i ) {
-				c.className = '';	
+				c.className = '';
 				t.className = 'current';
 			} else {
 				c.className = 'hidden';
@@ -118,29 +134,27 @@
 
 <div id="content1">
 	<h2><?php _e('Rich Editing Basics') ?></h2>
-	<p><?php _e('<em>Rich editing</em>, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear just as they will on the internet.') ?></p>
-	<p><?php _e('WordPress includes TinyMCE, a rich editor that works well in most web browsers used today. It is powerful but it has limitations. Pasting text from other word processors may not give the results you expect. If you do not like the way the rich editor works, you may turn it off in the My Profile form, under Users in the admin menu.') ?></p>
-	<p><?php _e('Because HTML code depends on the less-than character (&lt;) to render web pages, this character is reserved for HTML code. If you want a "<" to be visible on your site, you must encode it as "&amp;lt;" without the quotes.') ?></p>
+	<p><?php _e('<em>Rich editing</em>, also called WYSIWYG for What You See Is What You Get, means your text is formatted as you type. The rich editor creates HTML code behind the scenes while you concentrate on writing. Font styles, links and images all appear approximately as they will on the internet.') ?></p>
+	<p><?php _e('WordPress includes a rich HTML editor that works well in most web browsers used today. It is powerful but it has limitations. Pasting text from other word processors may not give the results you expect. If you do not like the way the rich editor works, you may turn it off in the Your Profile and Personal Options form, under Users in the admin menu.') ?></p>
 </div>
 
 <div id="content2" class="hidden">
 	<h2><?php _e('Advanced Rich Editing') ?></h2>
 	<h3><?php _e('Images and Attachments') ?></h3>
-	<p><?php _e('Some (not all) browsers allow you to drag images and other items directly into the editor. Most <a href="http://www.mozilla.org/products/firefox/" title="Mozilla.org, home of the Firefox web browser" target="_blank">Firefox</a> users can drag images from the uploading box (directly below the editor) and see their images instantly, complete with a link. If you cannot do this, use your clipboard Copy and Paste functions to insert the image and link tags. The rich editor will display the images after you have saved the post or used the HTML Editor to refresh the display.') ?></p>
+	<p><?php _e('There is a button in the editor toolbar for inserting images that are already hosted somewhere on the internet. If you have a URL for an image, click this button and enter the URL in the box which appears.') ?></p>
+	<p><?php _e('If you need to upload an image or sound file from your computer, you can use the uploading tool below the editor. The tool will attempt to create a thumbnail-sized image when you upload an image. To insert your uploaded image into the post, first click on the thumbnail to reveal a menu of options. Clicking on a "Using.." or "Linked..." option will change that option. For instance, you might want to use the thumbnail in the post and link it to a page showing the original with a caption. When you have selected the options you like, click "Send to Editor" and your image or file will appear in the post you are editing.') ?></p>
 	<h3><?php _e('HTML in the Rich Editor') ?></h3>
-	<p><?php _e('When you want to include HTML elements that are not generated by the toolbar buttons, you must enter it by hand. Examples are &lt;pre> and &lt;code>. Simply type the code into the editor. If the code is valid and allowed by the editor, you should see it rendered the next time you update the display, usually by saving or using the HTML Editor. If you want to display "&lt;" on the web, you must encode it as "&amp;lt;" in the editor.') ?></p>
-	<h3><?php _e('The HTML Editor') ?></h3>
-	<p><?php _e('The editor will not always understand your intentions as your editing gets more complex. Use the HTML Editor to sort out any rough spots, such as extra elements or attributes. WordPress will strip all empty &lt;p> tags and &lt;br /> tags in favor of simple newline characters. However, it will preserve any tag such as this: &lt;p class="anyclass">&lt;/p>. When using the HTML editor, all less-thans are double-encoded: &amp;amp;lt;. This ensures they display as &amp;lt; in the rich editor and &lt; on the web.') ?></p>
+	<p><?php _e('Any HTML entered directly into the rich editor will show up as text when the post is viewed. What you see is what you get. When you want to include HTML elements that cannot be generated with the toolbar buttons, you must enter it by hand in the HTML editor. Examples are tables and &lt;code&gt;. To do this, click the HTML button and edit the code, then click Update. If the code is valid and understood by the editor, you should see it rendered immediately.') ?></p>
 </div>
 
 <div id="content3" class="hidden">
 	<h2><?php _e('Writing at Full Speed') ?></h2>
 	<p><?php _e('Rather than reaching for your mouse to click on the toolbar, use these access keys. Windows and Linux use Alt+&lt;letter>. Macintosh uses Ctrl+&lt;letter>.') ?></p>
 	<table id="keys" width="100%" border="0">
-		<tr class="top"><th class="key center"><?php _e('Key') ?></th><th class="left"><?php _e('Action') ?></th><th class="key center"><?php _e('Key') ?></th><th class="left"><?php _e('Action') ?></th></tr>
-		<tr><th>b</th><td><strong><?php _e('Bold') ?></strong></td><th>f</th><td class="align left"><?php _e('Align Left') ?></td></tr>
-		<tr><th>i</th><td><em><?php _e('Italic') ?></em></td><th>c</th><td class="align center"><?php _e('Align Center') ?></td></tr>
-		<tr><th>d</th><td><strike><?php _e('Strikethrough') ?></strike></td><th>r</th><td class="align right"><?php _e('Align Right') ?></td></tr>
+		<tr class="top"><th class="key center"><?php _e('Letter') ?></th><th class="left"><?php _e('Action') ?></th><th class="key center"><?php _e('Letter') ?></th><th class="left"><?php _e('Action') ?></th></tr>
+		<tr><th>n</th><td><?php _e('Check Spelling') ?></td><th>f</th><td class="align left"><?php _e('Align Left') ?></td></tr>
+		<tr><th>j</th><td><?php _e('Justify Text') ?></td><th>c</th><td class="align center"><?php _e('Align Center') ?></td></tr>
+		<tr><th>k</th><td><strike><?php _e('Strikethrough') ?></strike></td><th>r</th><td class="align right"><?php _e('Align Right') ?></td></tr>
 		<tr><th>l</th><td><b>&bull;</b> <?php _e('List') ?></td><th>a</th><td><?php _e('Insert <span class="anchor">Anchor</span>') ?></td></tr>
 		<tr><th>o</th><td>1. <?php _e('List') ?></td><th>s</th><td><?php _e('Unlink Anchor') ?></td></tr>
 		<tr><th>q</th><td>&rarr;<?php _e('Quote/Indent') ?></td><th>m</th><td><?php _e('Insert Image') ?></td></tr>
@@ -152,8 +166,8 @@
 
 <div id="content4" class="hidden">
 	<h2><?php _e('About TinyMCE'); ?></h2>
-	<p><?php printf(__('Version: %s'), '2.0RC4') ?></p>
-	<p><?php printf(__('TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under %sLGPL</a>	by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.'), '<a href="'.get_bloginfo('home').'/wp-includes/js/tinymce/license.txt" target="_blank" title="'.__('GNU Library General Public Licence').'">') ?></p>
+	<p><?php printf(__('Version: %s'), '2.0.9') ?></p>
+	<p><?php printf(__('TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under %sLGPL</a>	by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.'), '<a href="'.get_bloginfo('url').'/wp-includes/js/tinymce/license.txt" target="_blank" title="'.__('GNU Library General Public Licence').'">') ?></p>
 	<p><?php _e('Copyright &copy; 2005, <a href="http://www.moxiecode.com" target="_blank">Moxiecode Systems AB</a>, All rights reserved.') ?></p>
 	<p><?php _e('For more information about this software visit the <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE website</a>.') ?></p>
 
diff -ruN 2.0.5/wp-includes/js/tw-sack.js 2.2.2/wp-includes/js/tw-sack.js
--- 2.0.5/wp-includes/js/tw-sack.js	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/js/tw-sack.js	2006-04-05 15:58:57.000000000 -0500
@@ -1,133 +1,193 @@
-/* Simple AJAX Code-Kit (SACK) */
+/* Simple AJAX Code-Kit (SACK) v1.6.1 */
 /* 2005 Gregory Wild-Smith */
 /* www.twilightuniverse.com */
-/* Software licenced under a modified X11 licence, see documentation or authors website for more details */
+/* Software licenced under a modified X11 licence,
+   see documentation or authors website for more details */
 
-function sack(file){
-	this.AjaxFailedAlert = "Your browser does not support the enhanced functionality of this website, and therefore you will have an experience that differs from the intended one.\n";
-	this.requestFile = file;
-	this.method = "POST";
-	this.URLString = "";
-	this.encodeURIString = true;
-	this.execute = false;
-
-	this.onLoading = function() { };
-	this.onLoaded = function() { };
-	this.onInteractive = function() { };
-	this.onCompletion = function() { };
+function sack(file) {
+	this.xmlhttp = null;
+
+	this.resetData = function() {
+		this.method = "POST";
+  		this.queryStringSeparator = "?";
+		this.argumentSeparator = "&";
+		this.URLString = "";
+		this.encodeURIString = true;
+  		this.execute = false;
+  		this.element = null;
+		this.elementObj = null;
+		this.requestFile = file;
+		this.vars = new Object();
+		this.responseStatus = new Array(2);
+  	};
+
+	this.resetFunctions = function() {
+  		this.onLoading = function() { };
+  		this.onLoaded = function() { };
+  		this.onInteractive = function() { };
+  		this.onCompletion = function() { };
+  		this.onError = function() { };
+		this.onFail = function() { };
+	};
+
+	this.reset = function() {
+		this.resetFunctions();
+		this.resetData();
+	};
 
 	this.createAJAX = function() {
 		try {
 			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
-		} catch (e) {
+		} catch (e1) {
 			try {
 				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
-			} catch (err) {
+			} catch (e2) {
 				this.xmlhttp = null;
 			}
 		}
-		if(!this.xmlhttp && typeof XMLHttpRequest != "undefined")
-			this.xmlhttp = new XMLHttpRequest();
-		if (!this.xmlhttp){
-			this.failed = true; 
+
+		if (! this.xmlhttp) {
+			if (typeof XMLHttpRequest != "undefined") {
+				this.xmlhttp = new XMLHttpRequest();
+			} else {
+				this.failed = true;
+			}
 		}
 	};
-	
+
 	this.setVar = function(name, value){
-		if (this.URLString.length < 3){
-			this.URLString = name + "=" + value;
+		this.vars[name] = Array(value, false);
+	};
+
+	this.encVar = function(name, value, returnvars) {
+		if (true == returnvars) {
+			return Array(encodeURIComponent(name), encodeURIComponent(value));
 		} else {
-			this.URLString += "&" + name + "=" + value;
+			this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true);
 		}
 	}
-	
-	this.encVar = function(name, value){
-		var varString = encodeURIComponent(name) + "=" + encodeURIComponent(value);
-	return varString;
-	}
-	
-	this.encodeURLString = function(string){
-		varArray = string.split('&');
+
+	this.processURLString = function(string, encode) {
+		encoded = encodeURIComponent(this.argumentSeparator);
+		regexp = new RegExp(this.argumentSeparator + "|" + encoded);
+		varArray = string.split(regexp);
 		for (i = 0; i < varArray.length; i++){
-			urlVars = varArray[i].split('=');
-			if (urlVars[0].indexOf('amp;') != -1){
-				urlVars[0] = urlVars[0].substring(4);
+			urlVars = varArray[i].split("=");
+			if (true == encode){
+				this.encVar(urlVars[0], urlVars[1]);
+			} else {
+				this.setVar(urlVars[0], urlVars[1]);
+			}
+		}
+	}
+
+	this.createURLString = function(urlstring) {
+		if (this.encodeURIString && this.URLString.length) {
+			this.processURLString(this.URLString, true);
+		}
+
+		if (urlstring) {
+			if (this.URLString.length) {
+				this.URLString += this.argumentSeparator + urlstring;
+			} else {
+				this.URLString = urlstring;
+			}
+		}
+
+		// prevents caching of URLString
+		this.setVar("rndval", new Date().getTime());
+
+		urlstringtemp = new Array();
+		for (key in this.vars) {
+			if (false == this.vars[key][1] && true == this.encodeURIString) {
+				encoded = this.encVar(key, this.vars[key][0], true);
+				delete this.vars[key];
+				this.vars[encoded[0]] = Array(encoded[1], true);
+				key = encoded[0];
 			}
-			varArray[i] = this.encVar(urlVars[0],urlVars[1]);
+
+			urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0];
+		}
+		if (urlstring){
+			this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
+		} else {
+			this.URLString += urlstringtemp.join(this.argumentSeparator);
 		}
-	return varArray.join('&');
 	}
-	
-	this.runResponse = function(){
+
+	this.runResponse = function() {
 		eval(this.response);
 	}
-	
-	this.runAJAX = function(urlstring){
-		this.responseStatus = new Array(2);
-		if(this.failed && this.AjaxFailedAlert){ 
-			alert(this.AjaxFailedAlert); 
+
+	this.runAJAX = function(urlstring) {
+		if (this.failed) {
+			this.onFail();
 		} else {
-			if (urlstring){ 
-				if (this.URLString.length){
-					this.URLString = this.URLString + "&" + urlstring; 
-				} else {
-					this.URLString = urlstring; 
-				}
-			}
-			if (this.encodeURIString){
-				var timeval = new Date().getTime(); 
-				this.URLString = this.encodeURLString(this.URLString);
-				this.setVar("rndval", timeval);
+			this.createURLString(urlstring);
+			if (this.element) {
+				this.elementObj = document.getElementById(this.element);
 			}
-			if (this.element) { this.elementObj = document.getElementById(this.element); }
 			if (this.xmlhttp) {
 				var self = this;
 				if (this.method == "GET") {
-					var totalurlstring = this.requestFile + "?" + this.URLString;
+					totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString;
 					this.xmlhttp.open(this.method, totalurlstring, true);
 				} else {
 					this.xmlhttp.open(this.method, this.requestFile, true);
-				}
-				if (this.method == "POST"){
-  					try {
-						this.xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded')  
-					} catch (e) {}
+					try {
+						this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
+					} catch (e) { }
 				}
 
-				this.xmlhttp.send(this.URLString);
 				this.xmlhttp.onreadystatechange = function() {
-					switch (self.xmlhttp.readyState){
+					switch (self.xmlhttp.readyState) {
 						case 1:
 							self.onLoading();
-						break;
+							break;
 						case 2:
 							self.onLoaded();
-						break;
+							break;
 						case 3:
 							self.onInteractive();
-						break;
+							break;
 						case 4:
 							self.response = self.xmlhttp.responseText;
 							self.responseXML = self.xmlhttp.responseXML;
 							self.responseStatus[0] = self.xmlhttp.status;
 							self.responseStatus[1] = self.xmlhttp.statusText;
-							self.onCompletion();
-							if(self.execute){ self.runResponse(); }
+
+							if (self.execute) {
+								self.runResponse();
+							}
+
 							if (self.elementObj) {
-								var elemNodeName = self.elementObj.nodeName;
+								elemNodeName = self.elementObj.nodeName;
 								elemNodeName.toLowerCase();
-								if (elemNodeName == "input" || elemNodeName == "select" || elemNodeName == "option" || elemNodeName == "textarea"){
+								if (elemNodeName == "input"
+								|| elemNodeName == "select"
+								|| elemNodeName == "option"
+								|| elemNodeName == "textarea") {
 									self.elementObj.value = self.response;
 								} else {
 									self.elementObj.innerHTML = self.response;
 								}
 							}
+							if (self.responseStatus[0] == "200") {
+								self.onCompletion();
+							} else {
+								self.onError();
+							}
+
 							self.URLString = "";
-						break;
+							break;
 					}
 				};
+
+				this.xmlhttp.send(this.URLString);
 			}
 		}
 	};
-this.createAJAX();
-}
\ No newline at end of file
+
+	this.reset();
+	this.createAJAX();
+}
diff -ruN 2.0.5/wp-includes/js/wp-ajax.js 2.2.2/wp-includes/js/wp-ajax.js
--- 2.0.5/wp-includes/js/wp-ajax.js	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/js/wp-ajax.js	2007-05-21 07:56:39.000000000 -0500
@@ -0,0 +1,100 @@
+var WPAjax = Class.create();
+Object.extend(WPAjax.prototype, Ajax.Request.prototype);
+Object.extend(WPAjax.prototype, {
+	WPComplete: false, // onComplete function
+	WPError: false, // onWPError function
+	defaultUrl: '', // We get these from WPAjaxL10n
+	permText: '',
+	strangeText: '',
+	whoaText: '',
+
+	initialize: function(url, responseEl) {
+		var tempObj = this;
+		this.transport = Ajax.getTransport();
+		if ( !this.transport )
+			return false;
+		this.setOptions( {
+			parameters: 'cookie=' + encodeURIComponent(document.cookie),
+			onComplete: function(transport) { // transport = XMLHttpRequest object
+				if ( tempObj.parseAjaxResponse() ) {
+					if ( 'function' == typeof tempObj.WPComplete )
+						tempObj.WPComplete(transport);
+				} else if ( 'function' == typeof tempObj.WPError ) // if response corresponds to an error (bad data, say, not 404)
+					tempObj.WPError(transport);
+			}
+		});
+		this.url = url ? url : this.defaultUrl;
+		this.getResponseElement(responseEl);
+	},
+	addArg: function(key, value) {
+		var a = $H();
+		a[encodeURIComponent(key)] = encodeURIComponent(value);
+		this.options.parameters = $H(this.options.parameters).merge(a);
+	},
+	getResponseElement: function(r) {
+		var p = $(r + '-p');
+		if ( !p ) {
+			new Insertion.Bottom(r, "<span id='" + r + "-p'></span>");
+			var p = $(r + '-p');
+		}
+		this.myResponseElement = p;
+	},
+	parseAjaxResponse: function() { // 1 = good, 0 = strange (bad data?), -1 = you lack permission
+		if ( this.transport.responseXML && typeof this.transport.responseXML == 'object' && ( this.transport.responseXML.xml || 'undefined' == typeof this.transport.responseXML.xml ) ) {
+			var err = this.transport.responseXML.getElementsByTagName('wp_error');
+			if ( err[0] ) {
+				var msg = $A(err).inject( '', function(a, b) { return a + '<p>' + b.firstChild.nodeValue + '</p>'; } );
+				Element.update(this.myResponseElement,'<div class="error">' + msg + '</div>');
+				return false;
+			}
+			return true;
+		}
+		var r = this.transport.responseText;
+		if ( isNaN(r) ) {
+			Element.update(this.myResponseElement,'<div class="error"><p>' + r + '</p></div>');
+			return false;
+		}
+		var r = parseInt(r,10);
+		if ( -1 == r ) {
+			Element.update(this.myResponseElement,"<div class='error'><p>" + this.permText + "</p></div>");
+			return false;
+		} else if ( 0 == r ) {
+			Element.update(this.myResponseElement,"<div class='error'><p>" + this.strangeText + "</p></div>");
+			return false;
+		}
+		return true;
+	},
+	addOnComplete: function(f) {
+		if ( 'function' == typeof f ) { var of = this.WPComplete; this.WPComplete = function(t) { if ( of ) of(t); f(t); } }
+	},
+	addOnWPError: function(f) {
+		if ( 'function' == typeof f ) { var of = this.WPError; this.WPError = function(t) { if ( of ) of(t); f(t); } }
+	},
+	notInitialized: function() {
+		return this.transport ? false : true;
+	}
+});
+
+Event.observe( window, 'load', function() { Object.extend(WPAjax.prototype, WPAjaxL10n); }, false )
+
+Ajax.activeSendCount = 0;
+Ajax.Responders.register( {
+	onCreate: function() {
+		Ajax.activeSendCount++;
+		if ( 1 != Ajax.activeSendCount )
+			return;
+		wpBeforeUnload = window.onbeforeunload;
+		window.onbeforeunload = function() {
+			return WPAjax.whoaText;
+		}
+	},
+	onLoading: function() { // Can switch to onLoaded if we lose data
+		Ajax.activeSendCount--;
+		if ( 0 != Ajax.activeSendCount )
+			return;
+		window.onbeforeunload = wpBeforeUnload;
+	}
+});
+
+//Pretty func adapted from ALA http://www.alistapart.com/articles/gettingstartedwithajax
+function getNodeValue(tree,el){try { var r = tree.getElementsByTagName(el)[0].firstChild.nodeValue; } catch(err) { var r = null; } return r; }
diff -ruN 2.0.5/wp-includes/kses.php 2.2.2/wp-includes/kses.php
--- 2.0.5/wp-includes/kses.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/kses.php	2006-12-20 22:44:34.000000000 -0600
@@ -39,7 +39,7 @@
 		//	'ul' => array(),
 	);
 }
-function wp_kses($string, $allowed_html, $allowed_protocols = array ('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'feed', 'gopher', 'mailto'))
+function wp_kses($string, $allowed_html, $allowed_protocols = array ('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'))
 	###############################################################################
 		# This function makes sure that only the allowed HTML element names, attribute
 		# names and attribute values plus only sane HTML entities will occur in
@@ -515,7 +515,7 @@
 
 function wp_filter_kses($data) {
 	global $allowedtags;
-	return wp_kses($data, $allowedtags);
+	return addslashes( wp_kses(stripslashes( $data ), $allowedtags) );
 }
 
 function wp_filter_post_kses($data) {
@@ -523,22 +523,39 @@
 	return addslashes ( wp_kses(stripslashes( $data ), $allowedposttags) );
 }
 
+function wp_filter_nohtml_kses($data) {
+	return addslashes ( wp_kses(stripslashes( $data ), array()) );
+}
+
 function kses_init_filters() {
-		add_filter('pre_comment_author', 'wp_filter_kses');
-		add_filter('pre_comment_content', 'wp_filter_kses');
-		add_filter('content_save_pre', 'wp_filter_post_kses');
-		add_filter('title_save_pre', 'wp_filter_kses');
+	// Normal filtering.
+	add_filter('pre_comment_content', 'wp_filter_kses');
+	add_filter('title_save_pre', 'wp_filter_kses');
+
+	// Post filtering
+	add_filter('content_save_pre', 'wp_filter_post_kses');
+	add_filter('excerpt_save_pre', 'wp_filter_post_kses');
+	add_filter('content_filtered_save_pre', 'wp_filter_post_kses');
 }
 
-function kses_init() {
-	remove_filter('pre_comment_author', 'wp_filter_kses');
+function kses_remove_filters() {
+	// Normal filtering.
 	remove_filter('pre_comment_content', 'wp_filter_kses');
-	remove_filter('content_save_pre', 'wp_filter_post_kses');
 	remove_filter('title_save_pre', 'wp_filter_kses');
 
+	// Post filtering
+	remove_filter('content_save_pre', 'wp_filter_post_kses');
+	remove_filter('excerpt_save_pre', 'wp_filter_post_kses');
+	remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');
+}
+
+function kses_init() {
+	kses_remove_filters();
+
 	if (current_user_can('unfiltered_html') == false)
 		kses_init_filters();
 }
+
 add_action('init', 'kses_init');
 add_action('set_current_user', 'kses_init');
 ?>
diff -ruN 2.0.5/wp-includes/l10n.php 2.2.2/wp-includes/l10n.php
--- 2.0.5/wp-includes/l10n.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/l10n.php	2007-04-12 16:15:44.000000000 -0500
@@ -0,0 +1,110 @@
+<?php
+function get_locale() {
+	global $locale;
+
+	if (isset($locale))
+		return apply_filters( 'locale', $locale );
+
+	// WPLANG is defined in wp-config.
+	if (defined('WPLANG'))
+		$locale = WPLANG;
+
+	if (empty($locale))
+		$locale = '';
+
+	$locale = apply_filters('locale', $locale);
+
+	return $locale;
+}
+
+function translate($text, $domain) {
+	global $l10n;
+
+	if (isset($l10n[$domain]))
+		return apply_filters('gettext', $l10n[$domain]->translate($text), $text);
+	else
+		return $text;
+}
+
+// Return a translated string.
+function __($text, $domain = 'default') {
+	return translate($text, $domain);
+}
+
+// Echo a translated string.
+function _e($text, $domain = 'default') {
+	echo translate($text, $domain);
+}
+
+function _c($text, $domain = 'default') {
+	$whole = translate($text, $domain);
+	$last_bar = strrpos($whole, '|');
+	if ( false == $last_bar ) {
+		return $whole;
+	} else {
+		return substr($whole, 0, $last_bar);
+	}
+}
+
+// Return the plural form.
+function __ngettext($single, $plural, $number, $domain = 'default') {
+	global $l10n;
+
+	if (isset($l10n[$domain])) {
+		return apply_filters('ngettext', $l10n[$domain]->ngettext($single, $plural, $number), $single, $plural, $number);
+	} else {
+		if ($number != 1)
+			return $plural;
+		else
+			return $single;
+	}
+}
+
+function load_textdomain($domain, $mofile) {
+	global $l10n;
+
+	if (isset($l10n[$domain]))
+		return;
+
+	if ( is_readable($mofile))
+		$input = new CachedFileReader($mofile);
+	else
+		return;
+
+	$l10n[$domain] = new gettext_reader($input);
+}
+
+function load_default_textdomain() {
+	global $l10n;
+
+	$locale = get_locale();
+	if ( empty($locale) )
+		$locale = 'en_US';
+
+	$mofile = ABSPATH . LANGDIR . "/$locale.mo";
+
+	load_textdomain('default', $mofile);
+}
+
+function load_plugin_textdomain($domain, $path = false) {
+	$locale = get_locale();
+	if ( empty($locale) )
+		$locale = 'en_US';
+
+	if ( false === $path )
+		$path = PLUGINDIR;
+
+	$mofile = ABSPATH . "$path/$domain-$locale.mo";
+	load_textdomain($domain, $mofile);
+}
+
+function load_theme_textdomain($domain) {
+	$locale = get_locale();
+	if ( empty($locale) )
+		$locale = 'en_US';
+
+	$mofile = get_template_directory() . "/$locale.mo";
+	load_textdomain($domain, $mofile);
+}
+
+?>
diff -ruN 2.0.5/wp-includes/link-template.php 2.2.2/wp-includes/link-template.php
--- 2.0.5/wp-includes/link-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/link-template.php	2007-06-13 21:58:04.000000000 -0500
@@ -0,0 +1,572 @@
+<?php
+
+
+function the_permalink() {
+	echo apply_filters('the_permalink', get_permalink());
+}
+
+
+function permalink_link() { // For backwards compatibility
+	echo apply_filters('the_permalink', get_permalink());
+}
+
+
+/**
+ * Conditionally adds a trailing slash if the permalink structure
+ * has a trailing slash, strips the trailing slash if not
+ * @global object Uses $wp_rewrite
+ * @param $string string a URL with or without a trailing slash
+ * @param $type_of_url string the type of URL being considered (e.g. single, category, etc) for use in the filter
+ * @return string
+ */
+function user_trailingslashit($string, $type_of_url = '') {
+	global $wp_rewrite;
+	if ( $wp_rewrite->use_trailing_slashes )
+		$string = trailingslashit($string);
+	else
+		$string = untrailingslashit($string);
+
+	// Note that $type_of_url can be one of following:
+	// single, single_trackback, single_feed, single_paged, feed, category, page, year, month, day, paged
+	$string = apply_filters('user_trailingslashit', $string, $type_of_url);
+	return $string;
+}
+
+
+function permalink_anchor($mode = 'id') {
+	global $post;
+	switch ( strtolower($mode) ) {
+		case 'title':
+			$title = sanitize_title($post->post_title) . '-' . $id;
+			echo '<a id="'.$title.'"></a>';
+			break;
+		case 'id':
+		default:
+			echo '<a id="post-' . $post->ID . '"></a>';
+			break;
+	}
+}
+
+
+function get_permalink($id = 0) {
+	$rewritecode = array(
+		'%year%',
+		'%monthnum%',
+		'%day%',
+		'%hour%',
+		'%minute%',
+		'%second%',
+		'%postname%',
+		'%post_id%',
+		'%category%',
+		'%author%',
+		'%pagename%'
+	);
+
+	$post = &get_post($id);
+	if ( $post->post_type == 'page' )
+		return get_page_link($post->ID);
+	elseif ($post->post_type == 'attachment')
+		return get_attachment_link($post->ID);
+
+	$permalink = get_option('permalink_structure');
+
+	if ( '' != $permalink && 'draft' != $post->post_status ) {
+		$unixtime = strtotime($post->post_date);
+
+		$category = '';
+		if (strpos($permalink, '%category%') !== false) {
+			$cats = get_the_category($post->ID);
+			if ( $cats )
+				usort($cats, '_get_the_category_usort_by_ID'); // order by ID
+			$category = $cats[0]->category_nicename;
+			if ( $parent=$cats[0]->category_parent )
+				$category = get_category_parents($parent, FALSE, '/', TRUE) . $category;
+		}
+
+		$authordata = get_userdata($post->post_author);
+		$author = $authordata->user_nicename;
+		$date = explode(" ",date('Y m d H i s', $unixtime));
+		$rewritereplace =
+		array(
+			$date[0],
+			$date[1],
+			$date[2],
+			$date[3],
+			$date[4],
+			$date[5],
+			$post->post_name,
+			$post->ID,
+			$category,
+			$author,
+			$post->post_name,
+		);
+		$permalink = get_option('home') . str_replace($rewritecode, $rewritereplace, $permalink);
+		$permalink = user_trailingslashit($permalink, 'single');
+		return apply_filters('post_link', $permalink, $post);
+	} else { // if they're not using the fancy permalink option
+		$permalink = get_option('home') . '/?p=' . $post->ID;
+		return apply_filters('post_link', $permalink, $post);
+	}
+}
+
+// get permalink from post ID
+function post_permalink($post_id = 0, $mode = '') { // $mode legacy
+	return get_permalink($post_id);
+}
+
+// Respects page_on_front.  Use this one.
+function get_page_link($id = false) {
+	global $post;
+
+	$id = (int) $id;
+	if ( !$id )
+		$id = (int) $post->ID;
+
+	if ( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') )
+		$link = get_option('home');
+	else
+		$link = _get_page_link( $id );
+
+	return apply_filters('page_link', $link, $id);
+}
+
+// Ignores page_on_front.  Internal use only.
+function _get_page_link( $id = false ) {
+	global $post, $wp_rewrite;
+
+	if ( !$id )
+		$id = (int) $post->ID;
+
+	$pagestruct = $wp_rewrite->get_page_permastruct();
+
+	if ( '' != $pagestruct && 'draft' != $post->post_status ) {
+		$link = get_page_uri($id);
+		$link = str_replace('%pagename%', $link, $pagestruct);
+		$link = get_option('home') . "/$link";
+		$link = user_trailingslashit($link, 'page');
+	} else {
+		$link = get_option('home') . "/?page_id=$id";
+	}
+
+	return apply_filters( '_get_page_link', $link, $id );
+}
+
+function get_attachment_link($id = false) {
+	global $post, $wp_rewrite;
+
+	$link = false;
+
+	if (! $id) {
+		$id = (int) $post->ID;
+	}
+
+	$object = get_post($id);
+	if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) {
+		$parent = get_post($object->post_parent);
+		if ( 'page' == $parent->post_type )
+			$parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front
+		else
+			$parentlink = get_permalink( $object->post_parent );
+		if (strpos($parentlink, '?') === false)
+			$link = trim($parentlink, '/') . '/' . $object->post_name . '/';
+	}
+
+	if (! $link ) {
+		$link = get_bloginfo('url') . "/?attachment_id=$id";
+	}
+
+	return apply_filters('attachment_link', $link, $id);
+}
+
+function get_year_link($year) {
+	global $wp_rewrite;
+	if ( !$year )
+		$year = gmdate('Y', time()+(get_option('gmt_offset') * 3600));
+	$yearlink = $wp_rewrite->get_year_permastruct();
+	if ( !empty($yearlink) ) {
+		$yearlink = str_replace('%year%', $year, $yearlink);
+		return apply_filters('year_link', get_option('home') . user_trailingslashit($yearlink, 'year'), $year);
+	} else {
+		return apply_filters('year_link', get_option('home') . '/?m=' . $year, $year);
+	}
+}
+
+function get_month_link($year, $month) {
+	global $wp_rewrite;
+	if ( !$year )
+		$year = gmdate('Y', time()+(get_option('gmt_offset') * 3600));
+	if ( !$month )
+		$month = gmdate('m', time()+(get_option('gmt_offset') * 3600));
+	$monthlink = $wp_rewrite->get_month_permastruct();
+	if ( !empty($monthlink) ) {
+		$monthlink = str_replace('%year%', $year, $monthlink);
+		$monthlink = str_replace('%monthnum%', zeroise(intval($month), 2), $monthlink);
+		return apply_filters('month_link', get_option('home') . user_trailingslashit($monthlink, 'month'), $year, $month);
+	} else {
+		return apply_filters('month_link', get_option('home') . '/?m=' . $year . zeroise($month, 2), $year, $month);
+	}
+}
+
+function get_day_link($year, $month, $day) {
+	global $wp_rewrite;
+	if ( !$year )
+		$year = gmdate('Y', time()+(get_option('gmt_offset') * 3600));
+	if ( !$month )
+		$month = gmdate('m', time()+(get_option('gmt_offset') * 3600));
+	if ( !$day )
+		$day = gmdate('j', time()+(get_option('gmt_offset') * 3600));
+
+	$daylink = $wp_rewrite->get_day_permastruct();
+	if ( !empty($daylink) ) {
+		$daylink = str_replace('%year%', $year, $daylink);
+		$daylink = str_replace('%monthnum%', zeroise(intval($month), 2), $daylink);
+		$daylink = str_replace('%day%', zeroise(intval($day), 2), $daylink);
+		return apply_filters('day_link', get_option('home') . user_trailingslashit($daylink, 'day'), $year, $month, $day);
+	} else {
+		return apply_filters('day_link', get_option('home') . '/?m=' . $year . zeroise($month, 2) . zeroise($day, 2), $year, $month, $day);
+	}
+}
+
+function get_feed_link($feed='rss2') {
+	global $wp_rewrite;
+	$do_perma = 0;
+	$feed_url = get_option('siteurl');
+	$comment_feed_url = $feed_url;
+
+	$permalink = $wp_rewrite->get_feed_permastruct();
+	if ( '' != $permalink ) {
+		if ( false !== strpos($feed, 'comments_') ) {
+			$feed = str_replace('comments_', '', $feed);
+			$permalink = $wp_rewrite->get_comment_feed_permastruct();
+		}
+
+		if ( 'rss2' == $feed )
+			$feed = '';
+
+		$permalink = str_replace('%feed%', $feed, $permalink);
+		$permalink = preg_replace('#/+#', '/', "/$permalink");
+		$output =  get_option('home') . user_trailingslashit($permalink, 'feed');
+	} else {
+		if ( false !== strpos($feed, 'comments_') )
+			$feed = str_replace('comments_', 'comments-', $feed);
+
+		$output = get_option('home') . "/?feed={$feed}";
+	}
+
+	return apply_filters('feed_link', $output, $feed);
+}
+
+function get_post_comments_feed_link($post_id = '', $feed = 'rss2') {
+	global $id;
+
+	if ( empty($post_id) )
+		$post_id = (int) $id;
+
+	if ( '' != get_option('permalink_structure') ) {
+		$url = trailingslashit( get_permalink() ) . 'feed';
+		if ( 'rss2' != $feed )
+			$url .= "/$feed";
+		$url = user_trailingslashit($url, 'single_feed');
+	} else {
+		$url = get_option('home') . "/?feed=$feed&amp;p=$id";
+	}
+
+	return apply_filters('post_comments_feed_link', $url);
+}
+
+function edit_post_link($link = 'Edit This', $before = '', $after = '') {
+	global $post;
+
+	if ( is_attachment() )
+		return;
+
+	if( $post->post_type == 'page' ) {
+		if ( ! current_user_can('edit_page', $post->ID) )
+			return;
+		$file = 'page';
+	} else {
+		if ( ! current_user_can('edit_post', $post->ID) )
+			return;
+		$file = 'post';
+	}
+
+	$location = get_option('siteurl') . "/wp-admin/{$file}.php?action=edit&amp;post=$post->ID";
+	echo $before . "<a href=\"$location\">$link</a>" . $after;
+}
+
+function edit_comment_link($link = 'Edit This', $before = '', $after = '') {
+	global $post, $comment;
+
+	if( $post->post_type == 'page' ){
+		if ( ! current_user_can('edit_page', $post->ID) )
+			return;
+	} else {
+		if ( ! current_user_can('edit_post', $post->ID) )
+			return;
+	}
+
+	$location = get_option('siteurl') . "/wp-admin/comment.php?action=editcomment&amp;c=$comment->comment_ID";
+	echo $before . "<a href='$location'>$link</a>" . $after;
+}
+
+// Navigation links
+
+function get_previous_post($in_same_cat = false, $excluded_categories = '') {
+	global $post, $wpdb;
+
+	if( !is_single() || is_attachment() )
+		return null;
+
+	$current_post_date = $post->post_date;
+
+	$join = '';
+	if ( $in_same_cat ) {
+		$join = " INNER JOIN $wpdb->post2cat ON $wpdb->posts.ID= $wpdb->post2cat.post_id ";
+		$cat_array = get_the_category($post->ID);
+		$join .= ' AND (category_id = ' . intval($cat_array[0]->cat_ID);
+		for ( $i = 1; $i < (count($cat_array)); $i++ ) {
+			$join .= ' OR category_id = ' . intval($cat_array[$i]->cat_ID);
+		}
+		$join .= ')';
+	}
+
+	$sql_exclude_cats = '';
+	if ( !empty($excluded_categories) ) {
+		$blah = explode(' and ', $excluded_categories);
+		foreach ( $blah as $category ) {
+			$category = intval($category);
+			$sql_cat_ids = " OR pc.category_ID = '$category'";
+		}
+		$posts_in_ex_cats = $wpdb->get_col("SELECT p.ID FROM $wpdb->posts p LEFT JOIN $wpdb->post2cat pc ON pc.post_id=p.ID WHERE 1 = 0 $sql_cat_ids GROUP BY p.ID");
+		$posts_in_ex_cats_sql = 'AND ID NOT IN (' . implode($posts_in_ex_cats, ',') . ')';
+	}
+
+	$join  = apply_filters( 'get_previous_post_join', $join, $in_same_cat, $excluded_categories );
+	$where = apply_filters( 'get_previous_post_where', "WHERE post_date < '$current_post_date' AND post_type = 'post' AND post_status = 'publish' $posts_in_ex_cats_sql", $in_same_cat, $excluded_categories );
+	$sort  = apply_filters( 'get_previous_post_sort', 'ORDER BY post_date DESC LIMIT 1' );
+
+	return @$wpdb->get_row("SELECT ID, post_title FROM $wpdb->posts $join $where $sort");
+}
+
+function get_next_post($in_same_cat = false, $excluded_categories = '') {
+	global $post, $wpdb;
+
+	if( !is_single() || is_attachment() )
+		return null;
+
+	$current_post_date = $post->post_date;
+
+	$join = '';
+	if ( $in_same_cat ) {
+		$join = " INNER JOIN $wpdb->post2cat ON $wpdb->posts.ID= $wpdb->post2cat.post_id ";
+		$cat_array = get_the_category($post->ID);
+		$join .= ' AND (category_id = ' . intval($cat_array[0]->cat_ID);
+		for ( $i = 1; $i < (count($cat_array)); $i++ ) {
+			$join .= ' OR category_id = ' . intval($cat_array[$i]->cat_ID);
+		}
+		$join .= ')';
+	}
+
+	$sql_exclude_cats = '';
+	if ( !empty($excluded_categories) ) {
+		$blah = explode(' and ', $excluded_categories);
+		foreach ( $blah as $category ) {
+			$category = intval($category);
+			$sql_cat_ids = " OR pc.category_ID = '$category'";
+		}
+		$posts_in_ex_cats = $wpdb->get_col("SELECT p.ID from $wpdb->posts p LEFT JOIN $wpdb->post2cat pc ON pc.post_id = p.ID WHERE 1 = 0 $sql_cat_ids GROUP BY p.ID");
+		$posts_in_ex_cats_sql = 'AND ID NOT IN (' . implode($posts_in_ex_cats, ',') . ')';
+	}
+
+	$join  = apply_filters( 'get_next_post_join', $join, $in_same_cat, $excluded_categories );
+	$where = apply_filters( 'get_next_post_where', "WHERE post_date > '$current_post_date' AND post_type = 'post' AND post_status = 'publish' $posts_in_ex_cats_sql AND ID != $post->ID", $in_same_cat, $excluded_categories );
+	$sort  = apply_filters( 'get_next_post_sort', 'ORDER BY post_date ASC LIMIT 1' );
+
+	return @$wpdb->get_row("SELECT ID, post_title FROM $wpdb->posts $join $where $sort");
+}
+
+
+function previous_post_link($format='&laquo; %link', $link='%title', $in_same_cat = false, $excluded_categories = '') {
+
+	if ( is_attachment() )
+		$post = & get_post($GLOBALS['post']->post_parent);
+	else
+		$post = get_previous_post($in_same_cat, $excluded_categories);
+
+	if ( !$post )
+		return;
+
+	$title = apply_filters('the_title', $post->post_title, $post);
+	$string = '<a href="'.get_permalink($post->ID).'">';
+	$link = str_replace('%title', $title, $link);
+	$link = $pre . $string . $link . '</a>';
+
+	$format = str_replace('%link', $link, $format);
+
+	echo $format;
+}
+
+function next_post_link($format='%link &raquo;', $link='%title', $in_same_cat = false, $excluded_categories = '') {
+	$post = get_next_post($in_same_cat, $excluded_categories);
+
+	if ( !$post )
+		return;
+
+	$title = apply_filters('the_title', $post->post_title, $post);
+	$string = '<a href="'.get_permalink($post->ID).'">';
+	$link = str_replace('%title', $title, $link);
+	$link = $string . $link . '</a>';
+	$format = str_replace('%link', $link, $format);
+
+	echo $format;
+}
+
+function get_pagenum_link($pagenum = 1) {
+	global $wp_rewrite;
+
+	$qstr = $_SERVER['REQUEST_URI'];
+
+	$page_querystring = "paged";
+	$page_modstring = "page/";
+	$page_modregex = "page/?";
+	$permalink = 0;
+
+	$home_root = parse_url(get_option('home'));
+	$home_root = $home_root['path'];
+	$home_root = trailingslashit($home_root);
+	$qstr = preg_replace('|^'. $home_root . '|', '', $qstr);
+	$qstr = preg_replace('|^/+|', '', $qstr);
+
+	$index = $_SERVER['PHP_SELF'];
+	$index = preg_replace('|^'. $home_root . '|', '', $index);
+	$index = preg_replace('|^/+|', '', $index);
+
+	// if we already have a QUERY style page string
+	if ( stripos( $qstr, $page_querystring ) !== false ) {
+		$replacement = "$page_querystring=$pagenum";
+		$qstr = preg_replace("/".$page_querystring."[^\d]+\d+/", $replacement, $qstr);
+		// if we already have a mod_rewrite style page string
+	} elseif ( preg_match( '|'.$page_modregex.'\d+|', $qstr ) ) {
+		$permalink = 1;
+		$qstr = preg_replace('|'.$page_modregex.'\d+|',"$page_modstring$pagenum",$qstr);
+
+		// if we don't have a page string at all ...
+		// lets see what sort of URL we have...
+	} else {
+		// we need to know the way queries are being written
+		// if there's a querystring_start (a "?" usually), it's definitely not mod_rewritten
+		if ( stripos( $qstr, '?' ) !== false ) {
+			// so append the query string (using &, since we already have ?)
+			$qstr .=	'&amp;' . $page_querystring . '=' . $pagenum;
+			// otherwise, it could be rewritten, OR just the default index ...
+		} elseif( '' != get_option('permalink_structure') && ! is_admin() ) {
+			$permalink = 1;
+			$index = $wp_rewrite->index;
+			// If it's not a path info permalink structure, trim the index.
+			if ( !$wp_rewrite->using_index_permalinks() ) {
+				$qstr = preg_replace("#/*" . $index . "/*#", '/', $qstr);
+			} else {
+				// If using path info style permalinks, make sure the index is in
+				// the URL.
+				if ( strpos($qstr, $index) === false )
+					$qstr = '/' . $index . $qstr;
+			}
+
+			$qstr =	trailingslashit($qstr) . $page_modstring . $pagenum;
+		} else {
+			$qstr = $index . '?' . $page_querystring . '=' . $pagenum;
+		}
+	}
+
+	$qstr = preg_replace('|^/+|', '', $qstr);
+	if ( $permalink )
+		$qstr = user_trailingslashit($qstr, 'paged');
+
+	// showing /page/1/ or ?paged=1 is redundant
+	if ( 1 === $pagenum ) {
+		$qstr = str_replace(user_trailingslashit('index.php/page/1', 'paged'), '', $qstr); // for PATHINFO style
+		$qstr = str_replace(user_trailingslashit('page/1', 'paged'), '', $qstr); // for mod_rewrite style
+		$qstr = remove_query_arg('paged', $qstr); // for query style
+	}
+
+	$qstr = preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', trailingslashit( get_option('home') ) . $qstr );
+
+	return $qstr;
+}
+
+function get_next_posts_page_link($max_page = 0) {
+	global $paged, $pagenow;
+
+	if ( !is_single() ) {
+		if ( !$paged )
+			$paged = 1;
+		$nextpage = intval($paged) + 1;
+		if ( !$max_page || $max_page >= $nextpage )
+			return get_pagenum_link($nextpage);
+	}
+}
+
+function next_posts($max_page = 0) {
+	echo clean_url(get_next_posts_page_link($max_page));
+}
+
+function next_posts_link($label='Next Page &raquo;', $max_page=0) {
+	global $paged, $wpdb, $wp_query;
+	if ( !$max_page ) {
+		$max_page = $wp_query->max_num_pages;
+	}
+	if ( !$paged )
+		$paged = 1;
+	$nextpage = intval($paged) + 1;
+	if ( (! is_single()) && (empty($paged) || $nextpage <= $max_page) ) {
+		echo '<a href="';
+		next_posts($max_page);
+		echo '">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $label) .'</a>';
+	}
+}
+
+function get_previous_posts_page_link() {
+	global $paged, $pagenow;
+
+	if ( !is_single() ) {
+		$nextpage = intval($paged) - 1;
+		if ( $nextpage < 1 )
+			$nextpage = 1;
+		return get_pagenum_link($nextpage);
+	}
+}
+
+function previous_posts() {
+	echo clean_url(get_previous_posts_page_link());
+}
+
+function previous_posts_link($label='&laquo; Previous Page') {
+	global $paged;
+	if ( (!is_single())	&& ($paged > 1) ) {
+		echo '<a href="';
+		previous_posts();
+		echo '">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $label) .'</a>';
+	}
+}
+
+function posts_nav_link($sep=' &#8212; ', $prelabel='&laquo; Previous Page', $nxtlabel='Next Page &raquo;') {
+	global $wp_query;
+	if ( !is_singular() ) {
+		$max_num_pages = $wp_query->max_num_pages;
+		$paged = get_query_var('paged');
+
+		//only have sep if there's both prev and next results
+		if ($paged < 2 || $paged >= $max_num_pages) {
+			$sep = '';
+		}
+
+		if ( $max_num_pages > 1 ) {
+			previous_posts_link($prelabel);
+			echo preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $sep);
+			next_posts_link($nxtlabel);
+		}
+	}
+}
+
+?>
diff -ruN 2.0.5/wp-includes/links.php 2.2.2/wp-includes/links.php
--- 2.0.5/wp-includes/links.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/links.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,566 +0,0 @@
-<?php
-
-/** function get_linksbyname()
- ** Gets the links associated with category 'cat_name'.
- ** Parameters:
- **   cat_name (default 'noname')  - The category name to use. If no
- **     match is found uses all
- **   before (default '')  - the html to output before the link
- **   after (default '<br />')  - the html to output after the link
- **   between (default ' ')  - the html to output between the link/image
- **     and it's description. Not used if no image or show_images == true
- **   show_images (default true) - whether to show images (if defined).
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url', 'description' or 'rating'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   show_description (default true) - whether to show the description if
- **     show_images=false/not defined
- **   show_rating (default false) - show rating stars/chars
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **   show_updated (default 0) - whether to show last updated timestamp
- */
-function get_linksbyname($cat_name = "noname", $before = '', $after = '<br />',
-                         $between = " ", $show_images = true, $orderby = 'id',
-                         $show_description = true, $show_rating = false,
-                         $limit = -1, $show_updated = 0) {
-    global $wpdb;
-    $cat_id = -1;
-    $results = $wpdb->get_results("SELECT cat_id FROM $wpdb->linkcategories WHERE cat_name='$cat_name'");
-    if ($results) {
-        foreach ($results as $result) {
-            $cat_id = $result->cat_id;
-        }
-    }
-    get_links($cat_id, $before, $after, $between, $show_images, $orderby,
-              $show_description, $show_rating, $limit, $show_updated);
-}
-
-function bool_from_yn($yn) {
-    if ($yn == 'Y') return 1;
-    return 0;
-}
-
-/** function wp_get_linksbyname()
- ** Gets the links associated with the named category.
- ** Parameters:
- **   category (no default)  - The category to use.
- **/
-function wp_get_linksbyname($category, $args = '') {
-	global $wpdb;
-
-	$cat = $wpdb->get_row("SELECT cat_id, cat_name, auto_toggle, show_images, show_description, "
-												. " show_rating, show_updated, sort_order, sort_desc, text_before_link, text_after_link, "
-												. " text_after_all, list_limit FROM $wpdb->linkcategories WHERE cat_name='$category'");
-
-	if (! $cat) {
-		return;
-	}
-
-	if (empty($args)) {
-		if ($cat->sort_desc == 'Y') {
-			$cat->sort_order = '_'.$cat->sort_order;
-		}
-		get_links($cat->cat_id, $cat->text_before_link, $cat->text_after_all,
-							$cat->text_after_link, bool_from_yn($cat->show_images), $cat->sort_order,
-							bool_from_yn($cat->show_description), bool_from_yn($cat->show_rating),
-							$cat->list_limit, bool_from_yn($cat->show_updated));
-	} else {
-		$args = add_query_arg('category', $cat->cat_id, $args);
-		wp_get_links($args);
-	}
-} // end wp_get_linksbyname
-
-/** function wp_get_links()
- ** Gets the links associated with category n.
- ** Parameters:
- **   category (no default)  - The category to use.
- ** or:
- **   a query string
- **/
-function wp_get_links($args = '') {
-	global $wpdb;
-
-	if (!empty($args) && false === strpos($args, '=')) {
-		// If args is not a query string, it's a category id.
-		$category = $args;
-		$cat = $wpdb->get_row("SELECT cat_id, cat_name, auto_toggle, show_images, show_description, "
-													. " show_rating, show_updated, sort_order, sort_desc, text_before_link, text_after_link, "
-													. " text_after_all, list_limit FROM $wpdb->linkcategories WHERE cat_id=$category");
-		if ($cat) {
-			if ($cat->sort_desc == 'Y') {
-				$cat->sort_order = '_'.$cat->sort_order;
-			}
-			get_links($cat->cat_id, $cat->text_before_link, $cat->text_after_all,
-								$cat->text_after_link, bool_from_yn($cat->show_images), $cat->sort_order,
-								bool_from_yn($cat->show_description), bool_from_yn($cat->show_rating),
-								$cat->list_limit, bool_from_yn($cat->show_updated));
-		}
-	} else {
-		parse_str($args);
-
-		if (! isset($category))	$category = -1;
-		if (! isset($before)) $before = '';
-		if (! isset($after)) $after = '<br />';
-		if (! isset($between))	$between = ' ';
-		if (! isset($show_images)) $show_images = true;
-		if (! isset($orderby)) $orderby = 'name';
-		if (! isset($show_description)) $show_description = true;
-		if (! isset($show_rating)) $show_rating = false;
-		if (! isset($limit)) $limit = -1;
-		if (! isset($show_updated)) $show_updated = 1;
-		if (! isset($echo)) $echo = true;
-
-		return get_links($category, $before, $after, $between, $show_images, $orderby, $show_description, $show_rating, $limit, $show_updated, $echo);
-	}
-} // end wp_get_links
-
-/** function get_links()
- ** Gets the links associated with category n.
- ** Parameters:
- **   category (default -1)  - The category to use. If no category supplied
- **      uses all
- **   before (default '')  - the html to output before the link
- **   after (default '<br />')  - the html to output after the link
- **   between (default ' ')  - the html to output between the link/image
- **     and its description. Not used if no image or show_images == true
- **   show_images (default true) - whether to show images (if defined).
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url', 'description', or 'rating'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   show_description (default true) - whether to show the description if
- **    show_images=false/not defined .
- **   show_rating (default false) - show rating stars/chars
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **   show_updated (default 0) - whether to show last updated timestamp
- **   echo (default true) - whether to echo the results, or return them instead
- */
-function get_links($category = -1,
-			$before = '',
-			$after = '<br />',
-			$between = ' ',
-			$show_images = true,
-			$orderby = 'name',
-			$show_description = true,
-			$show_rating = false,
-			$limit = -1,
-			$show_updated = 1,
-			$echo = true) {
-
-	global $wpdb;
-
-	$direction = ' ASC';
-	$category_query = '';
-	if ($category != -1) {
-		$category_query = " AND link_category = $category ";
-	}
-	if (get_settings('links_recently_updated_time')) {
-		$recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL " . get_settings('links_recently_updated_time') . " MINUTE) >= NOW(), 1,0) as recently_updated ";
-	} else {
-		$recently_updated_test = '';
-	}
-	if ($show_updated) {
-		$get_updated = ", UNIX_TIMESTAMP(link_updated) AS link_updated_f ";
-	}
-
-	$orderby = strtolower($orderby);
-	if ($orderby == '')
-		$orderby = 'id';
-	if (substr($orderby, 0, 1) == '_') {
-		$direction = ' DESC';
-		$orderby = substr($orderby, 1);
-	}
-
-	switch($orderby) {
-		case 'length':
-		$length = ", CHAR_LENGTH(link_name) AS length";
-		break;
-		case 'rand':
-			$orderby = 'rand()';
-			break;
-		default:
-			$orderby = " link_" . $orderby;
-	}
-
-	if (!isset($length)) {
-		$length = '';
-	}
-
-	$sql = "SELECT link_url, link_name, link_image, link_target, link_description, link_rating, link_rel $length $recently_updated_test $get_updated FROM $wpdb->links WHERE link_visible = 'Y' " . $category_query;
-	$sql .= ' ORDER BY ' . $orderby . $direction;
-	/* The next 2 lines implement LIMIT TO processing */
-	if ($limit != -1)
-		$sql .= " LIMIT $limit";
-	$results = $wpdb->get_results($sql);
-	if (!$results) {
-		return;
-	}
-
-	$output = '';
-
-	foreach ($results as $row) {
-		if (!isset($row->recently_updated)) $row->recently_updated = false;
-			$output .= $before;
-		if ($show_updated && $row->recently_updated) {
-			$output .= get_settings('links_recently_updated_prepend');
-		}
-
-		$the_link = '#';
-		if (!empty($row->link_url))
-			$the_link = wp_specialchars($row->link_url);
-
-		$rel = $row->link_rel;
-		if ($rel != '') {
-			$rel = ' rel="' . $rel . '"';
-		}
-
-		$desc = wp_specialchars($row->link_description, ENT_QUOTES);
-		$name = wp_specialchars($row->link_name, ENT_QUOTES);
-		$title = $desc;
-
-		if ($show_updated) {
-			if (substr($row->link_updated_f, 0, 2) != '00') {
-				$title .= ' (Last updated ' . date(get_settings('links_updated_date_format'), $row->link_updated_f + (get_settings('gmt_offset') * 3600)) . ')';
-			}
-		}
-
-		if ('' != $title) {
-			$title = ' title="' . $title . '"';
-		}
-
-		$alt = ' alt="' . $name . '"';
-
-		$target = $row->link_target;
-		if ('' != $target) {
-			$target = ' target="' . $target . '"';
-		}
-
-		$output .= '<a href="' . $the_link . '"' . $rel . $title . $target. '>';
-
-		if (($row->link_image != null) && $show_images) {
-			if (strstr($row->link_image, 'http'))
-				$output .= "<img src=\"$row->link_image\" $alt $title />";
-			else // If it's a relative path
-				$output .= "<img src=\"" . get_settings('siteurl') . "$row->link_image\" $alt $title />";
-		} else {
-			$output .= $name;
-		}
-
-		$output .= '</a>';
-
-		if ($show_updated && $row->recently_updated) {
-			$output .= get_settings('links_recently_updated_append');
-		}
-
-		if ($show_description && ($desc != '')) {
-			$output .= $between . $desc;
-		}
-		$output .= "$after\n";
-	} // end while
-
-	if ($echo) {
-		echo $output;
-	} else {
-		return $output;
-	}
-}
-
-
-/** function get_linkobjectsbyname()
- ** Gets an array of link objects associated with category 'cat_name'.
- ** Parameters:
- **   cat_name (default 'noname')  - The category name to use. If no
- **     match is found uses all
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url', 'description', or 'rating'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **
- ** Use this like:
- ** $links = get_linkobjectsbyname('fred');
- ** foreach ($links as $link) {
- **   echo '<li>'.$link->link_name.'</li>';
- ** }
- **/
-function get_linkobjectsbyname($cat_name = "noname" , $orderby = 'name', $limit = -1) {
-    global $wpdb;
-    $cat_id = -1;
-    $results = $wpdb->get_results("SELECT cat_id FROM $wpdb->linkcategories WHERE cat_name='$cat_name'");
-    if ($results) {
-        foreach ($results as $result) {
-            $cat_id = $result->cat_id;
-        }
-    }
-    return get_linkobjects($cat_id, $orderby, $limit);
-}
-
-/** function get_linkobjects()
- ** Gets an array of link objects associated with category n.
- ** Parameters:
- **   category (default -1)  - The category to use. If no category supplied
- **      uses all
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url', 'description', or 'rating'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **
- ** Use this like:
- ** $links = get_linkobjects(1);
- ** if ($links) {
- **   foreach ($links as $link) {
- **     echo '<li>'.$link->link_name.'<br />'.$link->link_description.'</li>';
- **   }
- ** }
- ** Fields are:
- ** link_id
- ** link_url
- ** link_name
- ** link_image
- ** link_target
- ** link_category
- ** link_description
- ** link_visible
- ** link_owner
- ** link_rating
- ** link_updated
- ** link_rel
- ** link_notes
- **/
-function get_linkobjects($category = -1, $orderby = 'name', $limit = -1) {
-    global $wpdb;
-
-    $sql = "SELECT * FROM $wpdb->links WHERE link_visible = 'Y'";
-    if ($category != -1) {
-        $sql .= " AND link_category = $category ";
-    }
-    if ($orderby == '')
-        $orderby = 'id';
-    if (substr($orderby,0,1) == '_') {
-        $direction = ' DESC';
-        $orderby = substr($orderby,1);
-    }
-    if (strcasecmp('rand',$orderby) == 0) {
-        $orderby = 'rand()';
-    } else {
-        $orderby = " link_" . $orderby;
-    }
-    $sql .= ' ORDER BY ' . $orderby;
-    $sql .= $direction;
-    /* The next 2 lines implement LIMIT TO processing */
-    if ($limit != -1)
-        $sql .= " LIMIT $limit";
-
-    $results = $wpdb->get_results($sql);
-    if ($results) {
-        foreach ($results as $result) {
-            $result->link_url         = $result->link_url;
-            $result->link_name        = $result->link_name;
-            $result->link_description = $result->link_description;
-            $result->link_notes       = $result->link_notes;
-            $newresults[] = $result;
-        }
-    }
-    return $newresults;
-}
-
-function get_linkrating($link) {
-    return apply_filters('link_rating', $link->link_rating);
-}
-
-
-/** function get_linksbyname_withrating()
- ** Gets the links associated with category 'cat_name' and display rating stars/chars.
- ** Parameters:
- **   cat_name (default 'noname')  - The category name to use. If no
- **     match is found uses all
- **   before (default '')  - the html to output before the link
- **   after (default '<br />')  - the html to output after the link
- **   between (default ' ')  - the html to output between the link/image
- **     and it's description. Not used if no image or show_images == true
- **   show_images (default true) - whether to show images (if defined).
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url' or 'description'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   show_description (default true) - whether to show the description if
- **     show_images=false/not defined
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **   show_updated (default 0) - whether to show last updated timestamp
- */
-function get_linksbyname_withrating($cat_name = "noname", $before = '',
-                                    $after = '<br />', $between = " ",
-                                    $show_images = true, $orderby = 'id',
-                                    $show_description = true, $limit = -1, $show_updated = 0) {
-
-    get_linksbyname($cat_name, $before, $after, $between, $show_images,
-                    $orderby, $show_description, true, $limit, $show_updated);
-}
-
-/** function get_links_withrating()
- ** Gets the links associated with category n and display rating stars/chars.
- ** Parameters:
- **   category (default -1)  - The category to use. If no category supplied
- **      uses all
- **   before (default '')  - the html to output before the link
- **   after (default '<br />')  - the html to output after the link
- **   between (default ' ')  - the html to output between the link/image
- **     and it's description. Not used if no image or show_images == true
- **   show_images (default true) - whether to show images (if defined).
- **   orderby (default 'id') - the order to output the links. E.g. 'id', 'name',
- **     'url' or 'description'. Or maybe owner. If you start the
- **     name with an underscore the order will be reversed.
- **     You can also specify 'rand' as the order which will return links in a
- **     random order.
- **   show_description (default true) - whether to show the description if
- **    show_images=false/not defined .
- **   limit (default -1) - Limit to X entries. If not specified, all entries
- **     are shown.
- **   show_updated (default 0) - whether to show last updated timestamp
- */
-function get_links_withrating($category = -1, $before = '', $after = '<br />',
-                              $between = " ", $show_images = true,
-                              $orderby = 'id', $show_description = true,
-                              $limit = -1, $show_updated = 0) {
-
-    get_links($category, $before, $after, $between, $show_images, $orderby,
-              $show_description, true, $limit, $show_updated);
-}
-
-/** function get_linkcatname()
- ** Gets the name of category n.
- ** Parameters: id (default 0)  - The category to get. If no category supplied
- **                uses 0
- */
-function get_linkcatname($id = 0) {
-    $id = (int) $id;
-    global $wpdb;
-    $cat_name = '';
-    if ( !empty($id) ) {
-        $cat_name = $wpdb->get_var("SELECT cat_name FROM $wpdb->linkcategories WHERE cat_id=$id");
-    }
-    return $cat_name;
-}
-
-/** function get_get_autotoggle()
- ** Gets the auto_toggle setting of category n.
- ** Parameters: id (default 0)  - The category to get. If no category supplied
- **                uses 0
- */
-function get_autotoggle($id = 0) {
-    global $wpdb;
-    $auto_toggle = $wpdb->get_var("SELECT auto_toggle FROM $wpdb->linkcategories WHERE cat_id=$id");
-    if ('' == $auto_toggle)
-        $auto_toggle = 'N';
-    return $auto_toggle;
-}
-
-/** function links_popup_script()
- ** This function contributed by Fullo -- http://sprite.csr.unibo.it/fullo/
- ** Show the link to the links popup and the number of links
- ** Parameters:
- **   text (default Links)  - the text of the link
- **   width (default 400)  - the width of the popup window
- **   height (default 400)  - the height of the popup window
- **   file (default linkspopup.php) - the page to open in the popup window
- **   count (default true) - the number of links in the db
- */
-function links_popup_script($text = 'Links', $width=400, $height=400,
-                            $file='links.all.php', $count = true) {
-   if ($count == true) {
-      $counts = $wpdb->get_var("SELECT count(*) FROM $wpdb->links");
-   }
-
-   $javascript = "<a href=\"#\" " .
-                 " onclick=\"javascript:window.open('$file?popup=1', '_blank', " .
-                 "'width=$width,height=$height,scrollbars=yes,status=no'); " .
-                 " return false\">";
-   $javascript .= $text;
-
-   if ($count == true) {
-      $javascript .= " ($counts)";
-   }
-
-   $javascript .="</a>\n\n";
-   echo $javascript;
-}
-
-
-/*
- * function get_links_list()
- *
- * added by Dougal
- *
- * Output a list of all links, listed by category, using the
- * settings in $wpdb->linkcategories and output it as a nested
- * HTML unordered list.
- *
- * Parameters:
- *   order (default 'name')  - Sort link categories by 'name' or 'id'
- *   hide_if_empty (default true)  - Supress listing empty link categories
- */
-function get_links_list($order = 'name', $hide_if_empty = 'obsolete') {
-	global $wpdb;
-
-	$order = strtolower($order);
-
-	// Handle link category sorting
-	if (substr($order,0,1) == '_') {
-		$direction = ' DESC';
-		$order = substr($order,1);
-	}
-
-	// if 'name' wasn't specified, assume 'id':
-	$cat_order = ('name' == $order) ? 'cat_name' : 'cat_id';
-
-	if (!isset($direction)) $direction = '';
-	// Fetch the link category data as an array of hashesa
-	$cats = $wpdb->get_results("
-		SELECT DISTINCT link_category, cat_name, show_images, 
-			show_description, show_rating, show_updated, sort_order, 
-			sort_desc, list_limit
-		FROM `$wpdb->links` 
-		LEFT JOIN `$wpdb->linkcategories` ON (link_category = cat_id)
-		WHERE link_visible =  'Y'
-			AND list_limit <> 0
-		ORDER BY $cat_order $direction ", ARRAY_A);
-
-	// Display each category
-	if ($cats) {
-		foreach ($cats as $cat) {
-			// Handle each category.
-			// First, fix the sort_order info
-			$orderby = $cat['sort_order'];
-			$orderby = (bool_from_yn($cat['sort_desc'])?'_':'') . $orderby;
-
-			// Display the category name
-			echo '	<li id="linkcat-' . $cat['link_category'] . '"><h2>' . $cat['cat_name'] . "</h2>\n\t<ul>\n";
-			// Call get_links() with all the appropriate params
-			get_links($cat['link_category'],
-				'<li>',"</li>","\n",
-				bool_from_yn($cat['show_images']),
-				$orderby,
-				bool_from_yn($cat['show_description']),
-				bool_from_yn($cat['show_rating']),
-				$cat['list_limit'],
-				bool_from_yn($cat['show_updated']));
-
-			// Close the last category
-			echo "\n\t</ul>\n</li>\n";
-		}
-	}
-}
-
-?>
diff -ruN 2.0.5/wp-includes/locale.php 2.2.2/wp-includes/locale.php
--- 2.0.5/wp-includes/locale.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/locale.php	2007-03-19 14:08:15.000000000 -0500
@@ -1,70 +1,141 @@
 <?php
-// Date and Time
-
-// The Weekdays
-$weekday[0] = __('Sunday');
-$weekday[1] = __('Monday');
-$weekday[2] = __('Tuesday');
-$weekday[3] = __('Wednesday');
-$weekday[4] = __('Thursday');
-$weekday[5] = __('Friday');
-$weekday[6] = __('Saturday');
-
-// The first letter of each day.  The _%day%_initial suffix is a hack to make
-// sure the day initials are unique.  They should be translated to a one
-// letter initial.  
-$weekday_initial[__('Sunday')]    = __('S_Sunday_initial');
-$weekday_initial[__('Monday')]    = __('M_Monday_initial');
-$weekday_initial[__('Tuesday')]   = __('T_Tuesday_initial');
-$weekday_initial[__('Wednesday')] = __('W_Wednesday_initial');
-$weekday_initial[__('Thursday')]  = __('T_Thursday_initial');
-$weekday_initial[__('Friday')]    = __('F_Friday_initial');
-$weekday_initial[__('Saturday')]  = __('S_Saturday_initial');
 
-foreach ($weekday_initial as $weekday_ => $weekday_initial_) {
-  $weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_);
-}
-
-// Abbreviations for each day.
-$weekday_abbrev[__('Sunday')]    = __('Sun');
-$weekday_abbrev[__('Monday')]    = __('Mon');
-$weekday_abbrev[__('Tuesday')]   = __('Tue');
-$weekday_abbrev[__('Wednesday')] = __('Wed');
-$weekday_abbrev[__('Thursday')]  = __('Thu');
-$weekday_abbrev[__('Friday')]    = __('Fri');
-$weekday_abbrev[__('Saturday')]  = __('Sat');
-
-// The Months
-$month['01'] = __('January');
-$month['02'] = __('February');
-$month['03'] = __('March');
-$month['04'] = __('April');
-$month['05'] = __('May');
-$month['06'] = __('June');
-$month['07'] = __('July');
-$month['08'] = __('August');
-$month['09'] = __('September');
-$month['10'] = __('October');
-$month['11'] = __('November');
-$month['12'] = __('December');
-
-// Abbreviations for each month. Uses the same hack as above to get around the
-// 'May' duplication.
-$month_abbrev[__('January')] = __('Jan_January_abbreviation');
-$month_abbrev[__('February')] = __('Feb_February_abbreviation');
-$month_abbrev[__('March')] = __('Mar_March_abbreviation');
-$month_abbrev[__('April')] = __('Apr_April_abbreviation');
-$month_abbrev[__('May')] = __('May_May_abbreviation');
-$month_abbrev[__('June')] = __('Jun_June_abbreviation');
-$month_abbrev[__('July')] = __('Jul_July_abbreviation');
-$month_abbrev[__('August')] = __('Aug_August_abbreviation');
-$month_abbrev[__('September')] = __('Sep_September_abbreviation');
-$month_abbrev[__('October')] = __('Oct_October_abbreviation');
-$month_abbrev[__('November')] = __('Nov_November_abbreviation');
-$month_abbrev[__('December')] = __('Dec_December_abbreviation');
+// Date and Time
 
-foreach ($month_abbrev as $month_ => $month_abbrev_) {
-  $month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_);
+class WP_Locale {
+	var $weekday;
+	var $weekday_initial;
+	var $weekday_abbrev;
+
+	var $month;
+	var $month_abbrev;
+
+	var $meridiem;
+
+	var $text_direction = 'ltr';
+	var $locale_vars = array('text_direction');
+
+	function init() {
+		// The Weekdays
+		$this->weekday[0] = __('Sunday');
+		$this->weekday[1] = __('Monday');
+		$this->weekday[2] = __('Tuesday');
+		$this->weekday[3] = __('Wednesday');
+		$this->weekday[4] = __('Thursday');
+		$this->weekday[5] = __('Friday');
+		$this->weekday[6] = __('Saturday');
+
+		// The first letter of each day.  The _%day%_initial suffix is a hack to make
+		// sure the day initials are unique.
+		$this->weekday_initial[__('Sunday')]    = __('S_Sunday_initial');
+		$this->weekday_initial[__('Monday')]    = __('M_Monday_initial');
+		$this->weekday_initial[__('Tuesday')]   = __('T_Tuesday_initial');
+		$this->weekday_initial[__('Wednesday')] = __('W_Wednesday_initial');
+		$this->weekday_initial[__('Thursday')]  = __('T_Thursday_initial');
+		$this->weekday_initial[__('Friday')]    = __('F_Friday_initial');
+		$this->weekday_initial[__('Saturday')]  = __('S_Saturday_initial');
+
+		foreach ($this->weekday_initial as $weekday_ => $weekday_initial_) {
+			$this->weekday_initial[$weekday_] = preg_replace('/_.+_initial$/', '', $weekday_initial_);
+		}
+
+		// Abbreviations for each day.
+		$this->weekday_abbrev[__('Sunday')]    = __('Sun');
+		$this->weekday_abbrev[__('Monday')]    = __('Mon');
+		$this->weekday_abbrev[__('Tuesday')]   = __('Tue');
+		$this->weekday_abbrev[__('Wednesday')] = __('Wed');
+		$this->weekday_abbrev[__('Thursday')]  = __('Thu');
+		$this->weekday_abbrev[__('Friday')]    = __('Fri');
+		$this->weekday_abbrev[__('Saturday')]  = __('Sat');
+
+		// The Months
+		$this->month['01'] = __('January');
+		$this->month['02'] = __('February');
+		$this->month['03'] = __('March');
+		$this->month['04'] = __('April');
+		$this->month['05'] = __('May');
+		$this->month['06'] = __('June');
+		$this->month['07'] = __('July');
+		$this->month['08'] = __('August');
+		$this->month['09'] = __('September');
+		$this->month['10'] = __('October');
+		$this->month['11'] = __('November');
+		$this->month['12'] = __('December');
+
+		// Abbreviations for each month. Uses the same hack as above to get around the
+		// 'May' duplication.
+		$this->month_abbrev[__('January')] = __('Jan_January_abbreviation');
+		$this->month_abbrev[__('February')] = __('Feb_February_abbreviation');
+		$this->month_abbrev[__('March')] = __('Mar_March_abbreviation');
+		$this->month_abbrev[__('April')] = __('Apr_April_abbreviation');
+		$this->month_abbrev[__('May')] = __('May_May_abbreviation');
+		$this->month_abbrev[__('June')] = __('Jun_June_abbreviation');
+		$this->month_abbrev[__('July')] = __('Jul_July_abbreviation');
+		$this->month_abbrev[__('August')] = __('Aug_August_abbreviation');
+		$this->month_abbrev[__('September')] = __('Sep_September_abbreviation');
+		$this->month_abbrev[__('October')] = __('Oct_October_abbreviation');
+		$this->month_abbrev[__('November')] = __('Nov_November_abbreviation');
+		$this->month_abbrev[__('December')] = __('Dec_December_abbreviation');
+
+		foreach ($this->month_abbrev as $month_ => $month_abbrev_) {
+			$this->month_abbrev[$month_] = preg_replace('/_.+_abbreviation$/', '', $month_abbrev_);
+		}
+
+		// The Meridiems
+		$this->meridiem['am'] = __('am');
+		$this->meridiem['pm'] = __('pm');
+		$this->meridiem['AM'] = __('AM');
+		$this->meridiem['PM'] = __('PM');
+
+		// Import global locale vars set during inclusion of $locale.php.
+		foreach ( $this->locale_vars as $var ) {
+			if ( isset($GLOBALS[$var]) )
+				$this->$var = $GLOBALS[$var];
+		}
+
+	}
+
+	function get_weekday($weekday_number) {
+		return $this->weekday[$weekday_number];
+	}
+
+	function get_weekday_initial($weekday_name) {
+		return $this->weekday_initial[$weekday_name];
+	}
+
+	function get_weekday_abbrev($weekday_name) {
+		return $this->weekday_abbrev[$weekday_name];
+	}
+
+	function get_month($month_number) {
+		return $this->month[zeroise($month_number, 2)];
+	}
+
+	function get_month_initial($month_name) {
+		return $this->month_initial[$month_name];
+	}
+
+	function get_month_abbrev($month_name) {
+		return $this->month_abbrev[$month_name];
+	}
+
+	function get_meridiem($meridiem) {
+		return $this->meridiem[$meridiem];
+	}
+
+	// Global variables are deprecated. For backwards compatibility only.
+	function register_globals() {
+		$GLOBALS['weekday']         = $this->weekday;
+		$GLOBALS['weekday_initial'] = $this->weekday_initial;
+		$GLOBALS['weekday_abbrev']  = $this->weekday_abbrev;
+		$GLOBALS['month']           = $this->month;
+		$GLOBALS['month_abbrev']    = $this->month_abbrev;
+	}
+
+	function WP_Locale() {
+		$this->init();
+		$this->register_globals();
+	}
 }
 
 ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/pluggable-functions.php 2.2.2/wp-includes/pluggable-functions.php
--- 2.0.5/wp-includes/pluggable-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/pluggable-functions.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,512 +0,0 @@
-<?php
-
-	/* These functions can be replaced via plugins.  They are loaded after
-	 plugins are loaded. */
-
-if ( !function_exists('set_current_user') ) :
-function set_current_user($id, $name = '') {
-	return wp_set_current_user($id, $name);
-}
-endif;
-
-if ( !function_exists('wp_set_current_user') ) :
-function wp_set_current_user($id, $name = '') {
-	global $current_user;
-
-	if ( isset($current_user) && ($id == $current_user->ID) )
-		return $current_user;
-
-	$current_user = new WP_User($id, $name);
-
-	setup_userdata($current_user->ID);
-
-	do_action('set_current_user');
-
-	return $current_user;
-}
-endif;
-
-if ( !function_exists('wp_get_current_user') ) :
-function wp_get_current_user() {
-	global $current_user;
-
-	get_currentuserinfo();
-
-	return $current_user;
-}
-endif;
-
-if ( !function_exists('get_currentuserinfo') ) :
-function get_currentuserinfo() {
-	global $current_user;
-
-	if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST )
-		return false;
-
-	if ( ! empty($current_user) )
-		return;
-
-	if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) || 
-		!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true) ) {
-		wp_set_current_user(0);
-		return false;
-	}
-
-	$user_login = $_COOKIE[USER_COOKIE];
-	wp_set_current_user(0, $user_login);
-}
-endif;
-
-if ( !function_exists('get_userdata') ) :
-function get_userdata( $user_id ) {
-	global $wpdb;
-	$user_id = (int) $user_id;
-	if ( $user_id == 0 )
-		return false;
-
-	$user = wp_cache_get($user_id, 'users');
-	
-	if ( $user )
-		return $user;
-
-	if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID = '$user_id' LIMIT 1") )
-		return false;
-
-	$wpdb->hide_errors();
-	$metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id'");
-	$wpdb->show_errors();
-
-	if ($metavalues) {
-		foreach ( $metavalues as $meta ) {
-			$value = maybe_unserialize($meta->meta_value);
-			$user->{$meta->meta_key} = $value;
-
-			// We need to set user_level from meta, not row
-			if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
-				$user->user_level = $meta->meta_value;
-		} // end foreach
-	} //end if
-
-	// For backwards compat.
-	if ( isset($user->first_name) )
-		$user->user_firstname = $user->first_name;
-	if ( isset($user->last_name) )
-		$user->user_lastname = $user->last_name;
-	if ( isset($user->description) )
-		$user->user_description = $user->description;
-		
-	wp_cache_add($user_id, $user, 'users');
-	wp_cache_add($user->user_login, $user, 'userlogins');
-	
-	return $user;
-}
-endif;
-
-if ( !function_exists('update_user_cache') ) :
-function update_user_cache() {
-	return true;
-}
-endif;
-
-if ( !function_exists('get_userdatabylogin') ) :
-function get_userdatabylogin($user_login) {
-	global $wpdb;
-	$user_login = sanitize_user( $user_login );
-
-	if ( empty( $user_login ) )
-		return false;
-		
-	$userdata = wp_cache_get($user_login, 'userlogins');
-	if ( $userdata )
-		return $userdata;
-
-	if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_login = '$user_login'") )
-		return false;
-
-	$wpdb->hide_errors();
-	$metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user->ID'");
-	$wpdb->show_errors();
-
-	if ($metavalues) {
-		foreach ( $metavalues as $meta ) {
-			$value = maybe_unserialize($meta->meta_value);
-			$user->{$meta->meta_key} = $value;
-
-			// We need to set user_level from meta, not row
-			if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
-				$user->user_level = $meta->meta_value;
-		}
-	}
-
-	// For backwards compat.
-	if ( isset($user->first_name) )
-		$user->user_firstname = $user->first_name;
-	if ( isset($user->last_name) )
-		$user->user_lastname = $user->last_name;
-	if ( isset($user->description) )
-		$user->user_description = $user->description;
-
-	wp_cache_add($user->ID, $user, 'users');
-	wp_cache_add($user->user_login, $user, 'userlogins');
-
-	return $user;
-
-}
-endif;
-
-if ( !function_exists('wp_mail') ) :
-function wp_mail($to, $subject, $message, $headers = '') {
-	if( $headers == '' ) {
-		$headers = "MIME-Version: 1.0\n" .
-			"From: wordpress@" . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])) . "\n" . 
-			"Content-Type: text/plain; charset=\"" . get_settings('blog_charset') . "\"\n";
-	}
-
-	return @mail($to, $subject, $message, $headers);
-}
-endif;
-
-if ( !function_exists('wp_login') ) :
-function wp_login($username, $password, $already_md5 = false) {
-	global $wpdb, $error;
-
-	if ( '' == $username )
-		return false;
-
-	if ( '' == $password ) {
-		$error = __('<strong>Error</strong>: The password field is empty.');
-		return false;
-	}
-
-	$login = get_userdatabylogin($username);
-	//$login = $wpdb->get_row("SELECT ID, user_login, user_pass FROM $wpdb->users WHERE user_login = '$username'");
-
-	if (!$login) {
-		$error = __('<strong>Error</strong>: Wrong username.');
-		return false;
-	} else {
-		// If the password is already_md5, it has been double hashed.
-		// Otherwise, it is plain text.
-		if ( ($already_md5 && md5($login->user_pass) == $password) || ($login->user_login == $username && $login->user_pass == md5($password)) ) {
-			return true;
-		} else {
-			$error = __('<strong>Error</strong>: Incorrect password.');
-			$pwd = '';
-			return false;
-		}
-	}
-}
-endif;
-
-if ( !function_exists('is_user_logged_in') ) :
-function is_user_logged_in() {
-	$user = wp_get_current_user();
-	
-	if ( $user->id == 0 )
-		return false;
-
-	return true;
-}
-endif;
-
-if ( !function_exists('auth_redirect') ) :
-function auth_redirect() {
-	// Checks if a user is logged in, if not redirects them to the login page
-	if ( (!empty($_COOKIE[USER_COOKIE]) && 
-				!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true)) ||
-			 (empty($_COOKIE[USER_COOKIE])) ) {
-		nocache_headers();
-	
-		wp_redirect(get_settings('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI']));
-		exit();
-	}
-}
-endif;
-
-if ( !function_exists('check_admin_referer') ) :
-function check_admin_referer($action = -1) {
-	$adminurl = strtolower(get_settings('siteurl')).'/wp-admin';
-	$referer = strtolower(wp_get_referer());
-	if ( !wp_verify_nonce($_REQUEST['_wpnonce'], $action) &&
-		!(-1 == $action && strstr($referer, $adminurl)) ) {
-		wp_nonce_ays($action);
-		die();
-	}
-	do_action('check_admin_referer', $action);
-}
-endif;
-
-if ( !function_exists('check_ajax_referer') ) :
-function check_ajax_referer() {
-	$cookie = explode('; ', urldecode(empty($_POST['cookie']) ? $_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass cookie=document.cookie
-	foreach ( $cookie as $tasty ) {
-		if ( false !== strpos($tasty, USER_COOKIE) )
-			$user = urldecode(substr(strstr($tasty, '='), 1)); // Nasty double encoding
-		if ( false !== strpos($tasty, PASS_COOKIE) )
-			$pass = urldecode(substr(strstr($tasty, '='), 1));
-	}
-	if ( wp_login( $user, $pass, true ) )
-		return true;
-	return false;
-}
-endif;
-
-// Cookie safe redirect.  Works around IIS Set-Cookie bug.
-// http://support.microsoft.com/kb/q176113/
-if ( !function_exists('wp_redirect') ) :
-function wp_redirect($location, $status = 302) {
-	global $is_IIS;
-
-	$location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%]|i', '', $location);
-
-	$strip = array('%0d', '%0a');
-	$location = str_replace($strip, '', $location);
-
-	if ( $is_IIS ) {
-		header("Refresh: 0;url=$location");
-	} else {
-		status_header($status); // This causes problems on IIS
-		header("Location: $location");
-	}
-}
-endif;
-
-if ( !function_exists('wp_get_cookie_login') ):
-function wp_get_cookie_login() {
-	if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) )
-		return false;
-
-	return array('login' => $_COOKIE[USER_COOKIE],	'password' => $_COOKIE[PASS_COOKIE]);
-}
-
-endif;
-
-if ( !function_exists('wp_setcookie') ) :
-function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false) {
-	if ( !$already_md5 )
-		$password = md5( md5($password) ); // Double hash the password in the cookie.
-
-	if ( empty($home) )
-		$cookiepath = COOKIEPATH;
-	else
-		$cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' );
-
-	if ( empty($siteurl) ) {
-		$sitecookiepath = SITECOOKIEPATH;
-		$cookiehash = COOKIEHASH;
-	} else {
-		$sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' );
-		$cookiehash = md5($siteurl);
-	}
-
-	if ( $remember )
-		$expire = time() + 31536000;
-	else
-		$expire = 0;
-
-	setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN);
-	setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN);
-
-	if ( $cookiepath != $sitecookiepath ) {
-		setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN);
-		setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN);
-	}
-}
-endif;
-
-if ( !function_exists('wp_clearcookie') ) :
-function wp_clearcookie() {
-	setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
-	setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
-	setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
-	setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
-}
-endif;
-
-if ( ! function_exists('wp_notify_postauthor') ) :
-function wp_notify_postauthor($comment_id, $comment_type='') {
-	global $wpdb;
-    
-	$comment = get_comment($comment_id);
-	$post    = get_post($comment->comment_post_ID);
-	$user    = get_userdata( $post->post_author );
-
-	if ('' == $user->user_email) return false; // If there's no email to send the comment to
-
-	$comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
-
-	$blogname = get_settings('blogname');
-	
-	if ( empty( $comment_type ) ) $comment_type = 'comment';
-	
-	if ('comment' == $comment_type) {
-		$notify_message  = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
-		$notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
-		$notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
-		$notify_message .= sprintf( __('URI    : %s'), $comment->comment_author_url ) . "\r\n";
-		$notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
-		$notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
-		$notify_message .= __('You can see all comments on this post here: ') . "\r\n";
-		$subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title );
-	} elseif ('trackback' == $comment_type) {
-		$notify_message  = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
-		$notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
-		$notify_message .= sprintf( __('URI    : %s'), $comment->comment_author_url ) . "\r\n";
-		$notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
-		$notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n";
-		$subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title );
-	} elseif ('pingback' == $comment_type) {
-		$notify_message  = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
-		$notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
-		$notify_message .= sprintf( __('URI    : %s'), $comment->comment_author_url ) . "\r\n";
-		$notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n";
-		$notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n";
-		$subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title );
-	}
-	$notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n";
-	$notify_message .= sprintf( __('To delete this comment, visit: %s'), get_settings('siteurl').'/wp-admin/post.php?action=confirmdeletecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n";
-
-	$wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
-
-	if ( '' == $comment->comment_author ) {
-		$from = "From: \"$blogname\" <$wp_email>";
-		if ( '' != $comment->comment_author_email )
-			$reply_to = "Reply-To: $comment->comment_author_email";
- 	} else {
-		$from = "From: \"$comment->comment_author\" <$wp_email>";
-		if ( '' != $comment->comment_author_email )
-			$reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>";
- 	}
-
-	$message_headers = "MIME-Version: 1.0\n"
-		. "$from\n"
-		. "Content-Type: text/plain; charset=\"" . get_settings('blog_charset') . "\"\n";
-
-	if ( isset($reply_to) )
-		$message_headers .= $reply_to . "\n";
-
-	$notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id);
-	$subject = apply_filters('comment_notification_subject', $subject, $comment_id);
-	$message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id);
-
-	@wp_mail($user->user_email, $subject, $notify_message, $message_headers);
-   
-	return true;
-}
-endif;
-
-/* wp_notify_moderator
-   notifies the moderator of the blog (usually the admin)
-   about a new comment that waits for approval
-   always returns true
- */
-if ( !function_exists('wp_notify_moderator') ) :
-function wp_notify_moderator($comment_id) {
-	global $wpdb;
-
-	if( get_settings( "moderation_notify" ) == 0 )
-		return true; 
-    
-	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1");
-	$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID='$comment->comment_post_ID' LIMIT 1");
-
-	$comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
-	$comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'");
-
-	$notify_message  = sprintf( __('A new comment on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n";
-	$notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
-	$notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
-	$notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
-	$notify_message .= sprintf( __('URI    : %s'), $comment->comment_author_url ) . "\r\n";
-	$notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
-	$notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
-	$notify_message .= sprintf( __('To approve this comment, visit: %s'),  get_settings('siteurl').'/wp-admin/post.php?action=mailapprovecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n";
-	$notify_message .= sprintf( __('To delete this comment, visit: %s'), get_settings('siteurl').'/wp-admin/post.php?action=confirmdeletecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n";
-	$notify_message .= sprintf( __('Currently %s comments are waiting for approval. Please visit the moderation panel:'), $comments_waiting ) . "\r\n";
-	$notify_message .= get_settings('siteurl') . "/wp-admin/moderation.php\r\n";
-
-	$subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_settings('blogname'), $post->post_title );
-	$admin_email = get_settings('admin_email');
-
-	$notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id);
-	$subject = apply_filters('comment_moderation_subject', $subject, $comment_id);
-
-	@wp_mail($admin_email, $subject, $notify_message);
-    
-	return true;
-}
-endif;
-
-if ( !function_exists('wp_new_user_notification') ) :
-function wp_new_user_notification($user_id, $plaintext_pass = '') {
-	$user = new WP_User($user_id);
-	
-	$user_login = stripslashes($user->user_login);
-	$user_email = stripslashes($user->user_email);
-	
-	$message  = sprintf(__('New user registration on your blog %s:'), get_settings('blogname')) . "\r\n\r\n";
-	$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
-	$message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
-	
-	@wp_mail(get_settings('admin_email'), sprintf(__('[%s] New User Registration'), get_settings('blogname')), $message);
-
-	if ( empty($plaintext_pass) )
-		return;
-
-	$message  = sprintf(__('Username: %s'), $user_login) . "\r\n";
-	$message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n";
-	$message .= get_settings('siteurl') . "/wp-login.php\r\n";
-		
-	wp_mail($user_email, sprintf(__('[%s] Your username and password'), get_settings('blogname')), $message);
-	
-}
-endif;
-
-if ( !function_exists('wp_verify_nonce') ) :
-function wp_verify_nonce($nonce, $action = -1) {
-	$user = wp_get_current_user();
-	$uid = $user->id;
-
-	$i = ceil(time() / 43200);
-
-	//Allow for expanding range, but only do one check if we can
-	if( substr(wp_hash($i . $action . $uid), -12, 10) == $nonce || substr(wp_hash(($i - 1) . $action . $uid), -12, 10) == $nonce )
-		return true;
-	return false;
-}
-endif;
-
-if ( !function_exists('wp_create_nonce') ) :
-function wp_create_nonce($action = -1) {
-	$user = wp_get_current_user();
-	$uid = $user->id;
-
-	$i = ceil(time() / 43200);
-	
-	return substr(wp_hash($i . $action . $uid), -12, 10);
-}
-endif;
-
-if ( !function_exists('wp_salt') ) :
-function wp_salt() {
-	$salt = get_option('secret');
-	if ( empty($salt) )
-		$salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
-
-	return $salt;
-}
-endif;
-
-if ( !function_exists('wp_hash') ) :
-function wp_hash($data) {
-	$salt = wp_salt();
-
-	if ( function_exists('hash_hmac') ) {
-		return hash_hmac('md5', $data, $salt);
-	} else {
-		return md5($data . $salt);
-	}
-}
-endif;
-
-?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/pluggable.php 2.2.2/wp-includes/pluggable.php
--- 2.0.5/wp-includes/pluggable.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/pluggable.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,576 @@
+<?php
+
+	/* These functions can be replaced via plugins.  They are loaded after
+	 plugins are loaded. */
+
+if ( !function_exists('set_current_user') ) :
+function set_current_user($id, $name = '') {
+	return wp_set_current_user($id, $name);
+}
+endif;
+
+if ( !function_exists('wp_set_current_user') ) :
+function wp_set_current_user($id, $name = '') {
+	global $current_user;
+
+	if ( isset($current_user) && ($id == $current_user->ID) )
+		return $current_user;
+
+	$current_user = new WP_User($id, $name);
+
+	setup_userdata($current_user->ID);
+
+	do_action('set_current_user');
+
+	return $current_user;
+}
+endif;
+
+if ( !function_exists('wp_get_current_user') ) :
+function wp_get_current_user() {
+	global $current_user;
+
+	get_currentuserinfo();
+
+	return $current_user;
+}
+endif;
+
+if ( !function_exists('get_currentuserinfo') ) :
+function get_currentuserinfo() {
+	global $current_user;
+
+	if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST )
+		return false;
+
+	if ( ! empty($current_user) )
+		return;
+
+	if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) ||
+		!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true) ) {
+		wp_set_current_user(0);
+		return false;
+	}
+
+	$user_login = $_COOKIE[USER_COOKIE];
+	wp_set_current_user(0, $user_login);
+}
+endif;
+
+if ( !function_exists('get_userdata') ) :
+function get_userdata( $user_id ) {
+	global $wpdb;
+	$user_id = (int) $user_id;
+	if ( $user_id == 0 )
+		return false;
+
+	$user = wp_cache_get($user_id, 'users');
+
+	if ( $user )
+		return $user;
+
+	if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID = '$user_id' LIMIT 1") )
+		return false;
+
+	$wpdb->hide_errors();
+	$metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id'");
+	$wpdb->show_errors();
+
+	if ($metavalues) {
+		foreach ( $metavalues as $meta ) {
+			$value = maybe_unserialize($meta->meta_value);
+			$user->{$meta->meta_key} = $value;
+
+			// We need to set user_level from meta, not row
+			if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
+				$user->user_level = $meta->meta_value;
+		} // end foreach
+	} //end if
+
+	// For backwards compat.
+	if ( isset($user->first_name) )
+		$user->user_firstname = $user->first_name;
+	if ( isset($user->last_name) )
+		$user->user_lastname = $user->last_name;
+	if ( isset($user->description) )
+		$user->user_description = $user->description;
+
+	wp_cache_add($user_id, $user, 'users');
+	wp_cache_add($user->user_login, $user_id, 'userlogins');
+	return $user;
+}
+endif;
+
+if ( !function_exists('update_user_cache') ) :
+function update_user_cache() {
+	return true;
+}
+endif;
+
+if ( !function_exists('get_userdatabylogin') ) :
+function get_userdatabylogin($user_login) {
+	global $wpdb;
+	$user_login = sanitize_user( $user_login );
+
+	if ( empty( $user_login ) )
+		return false;
+
+	$user_id = wp_cache_get($user_login, 'userlogins');
+	$userdata = wp_cache_get($user_id, 'users');
+
+	if ( $userdata )
+		return $userdata;
+
+	$user_login = $wpdb->escape($user_login);
+
+	if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_login = '$user_login'") )
+		return false;
+
+	$wpdb->hide_errors();
+	$metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user->ID'");
+	$wpdb->show_errors();
+
+	if ($metavalues) {
+		foreach ( $metavalues as $meta ) {
+			$value = maybe_unserialize($meta->meta_value);
+			$user->{$meta->meta_key} = $value;
+
+			// We need to set user_level from meta, not row
+			if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
+				$user->user_level = $meta->meta_value;
+		}
+	}
+
+	// For backwards compat.
+	if ( isset($user->first_name) )
+		$user->user_firstname = $user->first_name;
+	if ( isset($user->last_name) )
+		$user->user_lastname = $user->last_name;
+	if ( isset($user->description) )
+		$user->user_description = $user->description;
+
+	wp_cache_add($user->ID, $user, 'users');
+	wp_cache_add($user->user_login, $user->ID, 'userlogins');
+	return $user;
+
+}
+endif;
+
+if ( !function_exists( 'wp_mail' ) ) :
+function wp_mail($to, $subject, $message, $headers = '') {
+	global $phpmailer;
+
+	if ( !is_object( $phpmailer ) ) {
+		require_once(ABSPATH . WPINC . '/class-phpmailer.php');
+		require_once(ABSPATH . WPINC . '/class-smtp.php');
+		$phpmailer = new PHPMailer();
+	}
+
+	$mail = compact('to', 'subject', 'message', 'headers');
+	$mail = apply_filters('wp_mail', $mail);
+	extract($mail, EXTR_SKIP);
+
+	if ( $headers == '' ) {
+		$headers = "MIME-Version: 1.0\n" .
+			"From: " . apply_filters('wp_mail_from', "wordpress@" . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']))) . "\n" . 
+			"Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
+	}
+
+	$phpmailer->ClearAddresses();
+	$phpmailer->ClearCCs();
+	$phpmailer->ClearBCCs();
+	$phpmailer->ClearReplyTos();
+	$phpmailer->ClearAllRecipients();
+	$phpmailer->ClearCustomHeaders();
+
+	$phpmailer->FromName = "WordPress";
+	$phpmailer->AddAddress("$to", "");
+	$phpmailer->Subject = $subject;
+	$phpmailer->Body    = $message;
+	$phpmailer->IsHTML(false);
+	$phpmailer->IsMail(); // set mailer to use php mail()
+
+	do_action_ref_array('phpmailer_init', array(&$phpmailer));
+
+	$mailheaders = (array) explode( "\n", $headers );
+	foreach ( $mailheaders as $line ) {
+		$header = explode( ":", $line );
+		switch ( trim( $header[0] ) ) {
+			case "From":
+				$from = trim( str_replace( '"', '', $header[1] ) );
+				if ( strpos( $from, '<' ) ) {
+					$phpmailer->FromName = str_replace( '"', '', substr( $header[1], 0, strpos( $header[1], '<' ) - 1 ) );
+					$from = trim( substr( $from, strpos( $from, '<' ) + 1 ) );
+					$from = str_replace( '>', '', $from );
+				} else {
+					$phpmailer->FromName = $from;
+				}
+				$phpmailer->From = trim( $from );
+				break;
+			default:
+				if ( $line != '' && $header[0] != 'MIME-Version' && $header[0] != 'Content-Type' )
+					$phpmailer->AddCustomHeader( $line );
+				break;
+		}
+	}
+
+	$result = @$phpmailer->Send();
+
+	return $result;
+}
+endif;
+
+if ( !function_exists('wp_login') ) :
+function wp_login($username, $password, $already_md5 = false) {
+	global $wpdb, $error;
+
+	$username = sanitize_user($username);
+
+	if ( '' == $username )
+		return false;
+
+	if ( '' == $password ) {
+		$error = __('<strong>ERROR</strong>: The password field is empty.');
+		return false;
+	}
+
+	$login = get_userdatabylogin($username);
+	//$login = $wpdb->get_row("SELECT ID, user_login, user_pass FROM $wpdb->users WHERE user_login = '$username'");
+
+	if (!$login) {
+		$error = __('<strong>ERROR</strong>: Invalid username.');
+		return false;
+	} else {
+		// If the password is already_md5, it has been double hashed.
+		// Otherwise, it is plain text.
+		if ( ($already_md5 && md5($login->user_pass) == $password) || ($login->user_login == $username && $login->user_pass == md5($password)) ) {
+			return true;
+		} else {
+			$error = __('<strong>ERROR</strong>: Incorrect password.');
+			$pwd = '';
+			return false;
+		}
+	}
+}
+endif;
+
+if ( !function_exists('is_user_logged_in') ) :
+function is_user_logged_in() {
+	$user = wp_get_current_user();
+
+	if ( $user->id == 0 )
+		return false;
+
+	return true;
+}
+endif;
+
+if ( !function_exists('auth_redirect') ) :
+function auth_redirect() {
+	// Checks if a user is logged in, if not redirects them to the login page
+	if ( (!empty($_COOKIE[USER_COOKIE]) &&
+				!wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true)) ||
+			 (empty($_COOKIE[USER_COOKIE])) ) {
+		nocache_headers();
+
+		wp_redirect(get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI']));
+		exit();
+	}
+}
+endif;
+
+if ( !function_exists('check_admin_referer') ) :
+function check_admin_referer($action = -1) {
+	$adminurl = strtolower(get_option('siteurl')).'/wp-admin';
+	$referer = strtolower(wp_get_referer());
+	if ( !wp_verify_nonce($_REQUEST['_wpnonce'], $action) &&
+		!(-1 == $action && strpos($referer, $adminurl) !== false)) {
+		wp_nonce_ays($action);
+		die();
+	}
+	do_action('check_admin_referer', $action);
+}endif;
+
+if ( !function_exists('check_ajax_referer') ) :
+function check_ajax_referer() {
+	$cookie = explode('; ', urldecode(empty($_POST['cookie']) ? $_GET['cookie'] : $_POST['cookie'])); // AJAX scripts must pass cookie=document.cookie
+	foreach ( $cookie as $tasty ) {
+		if ( false !== strpos($tasty, USER_COOKIE) )
+			$user = substr(strstr($tasty, '='), 1);
+		if ( false !== strpos($tasty, PASS_COOKIE) )
+			$pass = substr(strstr($tasty, '='), 1);
+	}
+	if ( !wp_login( $user, $pass, true ) )
+		die('-1');
+	do_action('check_ajax_referer');
+}
+endif;
+
+// Cookie safe redirect.  Works around IIS Set-Cookie bug.
+// http://support.microsoft.com/kb/q176113/
+if ( !function_exists('wp_redirect') ) :
+function wp_redirect($location, $status = 302) {
+	global $is_IIS;
+
+	$location = apply_filters('wp_redirect', $location, $status);
+
+	if ( !$location ) // allows the wp_redirect filter to cancel a redirect
+		return false; 
+
+	$location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%]|i', '', $location);
+	$location = wp_kses_no_null($location);
+
+	$strip = array('%0d', '%0a');
+	$location = str_replace($strip, '', $location);
+
+	if ( $is_IIS ) {
+		header("Refresh: 0;url=$location");
+	} else {
+		if ( php_sapi_name() != 'cgi-fcgi' )
+			status_header($status); // This causes problems on IIS and some FastCGI setups
+		header("Location: $location");
+	}
+}
+endif;
+
+if ( !function_exists('wp_get_cookie_login') ):
+function wp_get_cookie_login() {
+	if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) )
+		return false;
+
+	return array('login' => $_COOKIE[USER_COOKIE],	'password' => $_COOKIE[PASS_COOKIE]);
+}
+
+endif;
+
+if ( !function_exists('wp_setcookie') ) :
+function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false) {
+	if ( !$already_md5 )
+		$password = md5( md5($password) ); // Double hash the password in the cookie.
+
+	if ( empty($home) )
+		$cookiepath = COOKIEPATH;
+	else
+		$cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' );
+
+	if ( empty($siteurl) ) {
+		$sitecookiepath = SITECOOKIEPATH;
+		$cookiehash = COOKIEHASH;
+	} else {
+		$sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' );
+		$cookiehash = md5($siteurl);
+	}
+
+	if ( $remember )
+		$expire = time() + 31536000;
+	else
+		$expire = 0;
+
+	setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN);
+	setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN);
+
+	if ( $cookiepath != $sitecookiepath ) {
+		setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN);
+		setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN);
+	}
+}
+endif;
+
+if ( !function_exists('wp_clearcookie') ) :
+function wp_clearcookie() {
+	setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
+	setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
+	setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
+	setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
+}
+endif;
+
+if ( ! function_exists('wp_notify_postauthor') ) :
+function wp_notify_postauthor($comment_id, $comment_type='') {
+	global $wpdb;
+
+	$comment = get_comment($comment_id);
+	$post    = get_post($comment->comment_post_ID);
+	$user    = get_userdata( $post->post_author );
+
+	if ('' == $user->user_email) return false; // If there's no email to send the comment to
+
+	$comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
+
+	$blogname = get_option('blogname');
+
+	if ( empty( $comment_type ) ) $comment_type = 'comment';
+
+	if ('comment' == $comment_type) {
+		$notify_message  = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
+		$notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
+		$notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
+		$notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
+		$notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
+		$notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
+		$notify_message .= __('You can see all comments on this post here: ') . "\r\n";
+		$subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title );
+	} elseif ('trackback' == $comment_type) {
+		$notify_message  = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
+		$notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
+		$notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
+		$notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
+		$notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n";
+		$subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title );
+	} elseif ('pingback' == $comment_type) {
+		$notify_message  = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n";
+		$notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
+		$notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
+		$notify_message .= __('Excerpt: ') . "\r\n" . sprintf('[...] %s [...]', $comment->comment_content ) . "\r\n\r\n";
+		$notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n";
+		$subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title );
+	}
+	$notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n";
+	$notify_message .= sprintf( __('Delete it: %s'), get_option('siteurl')."/wp-admin/comment.php?action=cdc&c=$comment_id" ) . "\r\n";
+	$notify_message .= sprintf( __('Spam it: %s'), get_option('siteurl')."/wp-admin/comment.php?action=cdc&dt=spam&c=$comment_id" ) . "\r\n";
+
+	$wp_email = 'wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
+
+	if ( '' == $comment->comment_author ) {
+		$from = "From: \"$blogname\" <$wp_email>";
+		if ( '' != $comment->comment_author_email )
+			$reply_to = "Reply-To: $comment->comment_author_email";
+	} else {
+		$from = "From: \"$comment->comment_author\" <$wp_email>";
+		if ( '' != $comment->comment_author_email )
+			$reply_to = "Reply-To: \"$comment->comment_author_email\" <$comment->comment_author_email>";
+	}
+
+	$message_headers = "MIME-Version: 1.0\n"
+		. "$from\n"
+		. "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n";
+
+	if ( isset($reply_to) )
+		$message_headers .= $reply_to . "\n";
+
+	$notify_message = apply_filters('comment_notification_text', $notify_message, $comment_id);
+	$subject = apply_filters('comment_notification_subject', $subject, $comment_id);
+	$message_headers = apply_filters('comment_notification_headers', $message_headers, $comment_id);
+
+	@wp_mail($user->user_email, $subject, $notify_message, $message_headers);
+   
+	return true;
+}
+endif;
+
+/* wp_notify_moderator
+   notifies the moderator of the blog (usually the admin)
+   about a new comment that waits for approval
+   always returns true
+ */
+if ( !function_exists('wp_notify_moderator') ) :
+function wp_notify_moderator($comment_id) {
+	global $wpdb;
+
+	if( get_option( "moderation_notify" ) == 0 )
+		return true; 
+    
+	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1");
+	$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID='$comment->comment_post_ID' LIMIT 1");
+
+	$comment_author_domain = @gethostbyaddr($comment->comment_author_IP);
+	$comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'");
+
+	$notify_message  = sprintf( __('A new comment on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n";
+	$notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n";
+	$notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
+	$notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n";
+	$notify_message .= sprintf( __('URL    : %s'), $comment->comment_author_url ) . "\r\n";
+	$notify_message .= sprintf( __('Whois  : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n";
+	$notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n";
+	$notify_message .= sprintf( __('Approve it: %s'),  get_option('siteurl')."/wp-admin/comment.php?action=mac&c=$comment_id" ) . "\r\n";
+	$notify_message .= sprintf( __('Delete it: %s'), get_option('siteurl')."/wp-admin/comment.php?action=cdc&c=$comment_id" ) . "\r\n";
+	$notify_message .= sprintf( __('Spam it: %s'), get_option('siteurl')."/wp-admin/comment.php?action=cdc&dt=spam&c=$comment_id" ) . "\r\n";
+	$notify_message .= sprintf( __('Currently %s comments are waiting for approval. Please visit the moderation panel:'), $comments_waiting ) . "\r\n";
+	$notify_message .= get_option('siteurl') . "/wp-admin/moderation.php\r\n";
+
+	$subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_option('blogname'), $post->post_title );
+	$admin_email = get_option('admin_email');
+
+	$notify_message = apply_filters('comment_moderation_text', $notify_message, $comment_id);
+	$subject = apply_filters('comment_moderation_subject', $subject, $comment_id);
+
+	@wp_mail($admin_email, $subject, $notify_message);
+
+	return true;
+}
+endif;
+
+if ( !function_exists('wp_new_user_notification') ) :
+function wp_new_user_notification($user_id, $plaintext_pass = '') {
+	$user = new WP_User($user_id);
+
+	$user_login = stripslashes($user->user_login);
+	$user_email = stripslashes($user->user_email);
+
+	$message  = sprintf(__('New user registration on your blog %s:'), get_option('blogname')) . "\r\n\r\n";
+	$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
+	$message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
+
+	@wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), get_option('blogname')), $message);
+
+	if ( empty($plaintext_pass) )
+		return;
+
+	$message  = sprintf(__('Username: %s'), $user_login) . "\r\n";
+	$message .= sprintf(__('Password: %s'), $plaintext_pass) . "\r\n";
+	$message .= get_option('siteurl') . "/wp-login.php\r\n";
+
+	wp_mail($user_email, sprintf(__('[%s] Your username and password'), get_option('blogname')), $message);
+
+}
+endif;
+
+if ( !function_exists('wp_verify_nonce') ) :
+function wp_verify_nonce($nonce, $action = -1) {
+	$user = wp_get_current_user();
+	$uid = (int) $user->id;
+
+	$i = ceil(time() / 43200);
+
+	//Allow for expanding range, but only do one check if we can
+	if( substr(wp_hash($i . $action . $uid), -12, 10) == $nonce || substr(wp_hash(($i - 1) . $action . $uid), -12, 10) == $nonce )
+		return true;
+	return false;
+}
+endif;
+
+if ( !function_exists('wp_create_nonce') ) :
+function wp_create_nonce($action = -1) {
+	$user = wp_get_current_user();
+	$uid = (int) $user->id;
+
+	$i = ceil(time() / 43200);
+
+	return substr(wp_hash($i . $action . $uid), -12, 10);
+}
+endif;
+
+if ( !function_exists('wp_salt') ) :
+function wp_salt() {
+	$salt = get_option('secret');
+	if ( empty($salt) )
+		$salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
+
+	return $salt;
+}
+endif;
+
+if ( !function_exists('wp_hash') ) :
+function wp_hash($data) {
+	$salt = wp_salt();
+
+	if ( function_exists('hash_hmac') ) {
+		return hash_hmac('md5', $data, $salt);
+	} else {
+		return md5($data . $salt);
+	}
+}
+endif;
+
+?>
diff -ruN 2.0.5/wp-includes/plugin.php 2.2.2/wp-includes/plugin.php
--- 2.0.5/wp-includes/plugin.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/plugin.php	2007-05-08 12:59:32.000000000 -0500
@@ -0,0 +1,281 @@
+<?php
+
+/**
+ * Hooks a function to a specific filter action.
+ * 
+ * Filters are the hooks that WordPress launches to modify text of various types
+ * before adding it to the database or sending it to the browser screen. Plugins 
+ * can specify that one or more of its PHP functions is executed to 
+ * modify specific types of text at these times, using the Filter API.
+ * See the [Plugin API] for a list of filter hooks. 
+ *
+ * @param string $tag The name of the filter to hook the <tt>$function_to_add</tt> to.
+ * @param callback $function_to_add The name of the function to be called when the filter is applied.
+ * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
+ * @param int $accepted_args optional. The number of arguments the function accept (default 1). In WordPress 1.5.1+, hooked functions can take extra arguments that are set when the matching do_action() or apply_filters() call is run.
+ * @return boolean true if the <tt>$function_to_add</tt> is added succesfully to filter <tt>$tag</tt>. How many arguments your function takes. In WordPress 1.5.1+, hooked functions can take extra arguments that are set when the matching <tt>do_action()</tt> or <tt>apply_filters()</tt> call is run. For example, the action <tt>comment_id_not_found</tt> will pass any functions that hook onto it the ID of the requested comment.
+ */
+function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
+	global $wp_filter, $merged_filters;
+
+	// So the format is wp_filter['tag']['array of priorities']['array of functions serialized']['array of ['array (functions, accepted_args)]']
+	$wp_filter[$tag][$priority][serialize($function_to_add)] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
+	unset( $merged_filters[ $tag ] );
+	return true;
+}
+
+/**
+ * Call the functions added to a filter hook.
+ * 
+ * The callback functions attached to filter hook <tt>$tag</tt> are invoked by
+ * calling this function. This function can be used to create a new filter hook
+ * by simply calling this function with the name of the new hook specified using
+ * the <tt>$tag</a> parameter.
+ * @uses merge_filters Merges the filter hooks using this function.
+ * @param string $tag The name of the filter hook.
+ * @param string $string The text on which the filters hooked to <tt>$tag</tt> are applied on.
+ * @param mixed $var,... Additional variables passed to the functions hooked to <tt>$tag</tt>.
+ * @return string The text in <tt>$string</tt> after all hooked functions are applied to it.
+ */
+function apply_filters($tag, $string) {
+	global $wp_filter, $merged_filters;
+
+	if ( !isset( $merged_filters[ $tag ] ) )
+		merge_filters($tag);
+
+	if ( !isset($wp_filter[$tag]) )
+		return $string;
+
+	reset( $wp_filter[ $tag ] );
+
+	$args = func_get_args();
+
+	do{
+		foreach( (array) current($wp_filter[$tag]) as $the_ )
+			if ( !is_null($the_['function']) ){
+				$args[1] = $string;
+				$string = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
+			}
+
+	} while ( next($wp_filter[$tag]) );
+
+	return $string;
+}
+
+/**
+ * Merge the filter functions of a specific filter hook with generic filter functions.
+ * 
+ * It is possible to defined generic filter functions using the filter hook 
+ * <em>all</e>. These functions are called for every filter tag. This function 
+ * merges the functions attached to the <em>all</em> hook with the functions
+ * of a specific hoook defined by <tt>$tag</tt>.
+ * @param string $tag The filter hook of which the functions should be merged.
+ */
+function merge_filters($tag) {
+	global $wp_filter, $merged_filters;
+
+	if ( isset($wp_filter['all']) && is_array($wp_filter['all']) )
+		$wp_filter[$tag] = array_merge($wp_filter['all'], (array) $wp_filter[$tag]);
+
+	if ( isset($wp_filter[$tag]) ){
+		reset($wp_filter[$tag]);
+		uksort($wp_filter[$tag], "strnatcasecmp");
+	}
+	$merged_filters[ $tag ] = true;
+}
+
+/**
+ * Removes a function from a specified filter hook. 
+ * 
+ * This function removes a function attached to a specified filter hook. This 
+ * method can be used to remove default functions attached to a specific filter 
+ * hook and possibly replace them with a substitute.
+ * @param string $tag The filter hook to which the function to be removed is hooked.
+ * @param callback $function_to_remove The name of the function which should be removed.
+ * @param int $priority optional. The priority of the function (default: 10).
+ * @param int $accepted_args optional. The number of arguments the function accpets (default: 1).
+ * @return boolean Whether the function is removed.
+ */
+function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
+	global $wp_filter, $merged_filters;
+
+	unset($GLOBALS['wp_filter'][$tag][$priority][serialize($function_to_remove)]);
+	unset( $merged_filters[ $tag ] );
+
+	return true;
+}
+
+/**
+ * Hooks a function on to a specific action.
+ * 
+ * Actions are the hooks that the WordPress core launches at specific points 
+ * during execution, or when specific events occur. Plugins can specify that
+ * one or more of its PHP functions are executed at these points, using the 
+ * Action API.
+ * 
+ * @param string $tag The name of the action to which the <tt>$function_to-add</tt> is hooked.
+ * @param callback $function_to_add The name of the function you wish to be called. Note: any of the syntaxes explained in the PHP documentation for the 'callback' type (http://us2.php.net/manual/en/language.pseudo-types.php#language.types.callback) are valid.
+ * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
+ * @param int $accepted_args optional. The number of arguments the function accept (default 1). In WordPress 1.5.1+, hooked functions can take extra arguments that are set when the matching do_action() or apply_filters() call is run. 
+ * @return boolean Always true.
+ */
+function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
+	add_filter($tag, $function_to_add, $priority, $accepted_args);
+}
+
+/**
+ * Execute functions hooked on a specific action hook.
+ * 
+ * This function invokes all functions attached to action hook <tt>$tag</tt>.
+ * It is possible to create new action hooks by simply calling this function,
+ * specifying the name of the new hook using the <tt>$tag</tt> parameter.
+ * @uses merge_filters
+ * @param string $tag The name of the action to be executed.
+ * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action. 
+ */
+function do_action($tag, $arg = '') {
+	global $wp_filter, $wp_actions;
+
+	if ( is_array($wp_actions) )
+		$wp_actions[] = $tag;
+	else
+		$wp_actions = array($tag);
+
+	$args = array();
+	if ( is_array($arg) && 1 == count($arg) && is_object($arg[0]) ) // array(&$this)
+		$args[] =& $arg[0];
+	else
+		$args[] = $arg;
+	for ( $a = 2; $a < func_num_args(); $a++ )
+		$args[] = func_get_arg($a);
+
+	merge_filters($tag);
+
+	if ( !isset($wp_filter[$tag]) )
+		return;
+
+	do{
+		foreach( (array) current($wp_filter[$tag]) as $the_ )
+			if ( !is_null($the_['function']) )
+				call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
+
+	} while ( next($wp_filter[$tag]) );
+
+}
+
+/**
+ * Return the number times an action is fired.
+ * @param string $tag The name of the action hook.
+ * @return int The number of times action hook <tt>$tag</tt> is fired
+ */
+function did_action($tag) {
+	global $wp_actions;
+
+	if ( empty($wp_actions) )
+		return 0;
+
+	return count(array_keys($wp_actions, $tag));
+}
+
+/**
+ * Execute functions hooked on a specific action hook, specifying arguments in a array.
+ * 
+ * This function is identical to {@link do_action}, but the argumetns passe to 
+ * the functions hooked to <tt>$tag</tt> are supplied using an array.
+ * @param string $tag The name of the action to be executed.
+ * @param array $args The arguments supplied to the functions hooked to <tt>$tag</tt>
+ */
+function do_action_ref_array($tag, $args) {
+	global $wp_filter, $wp_actions;
+
+	if ( !is_array($wp_actions) )
+		$wp_actions = array($tag);
+	else
+		$wp_actions[] = $tag;
+
+	merge_filters($tag);
+
+	if ( !isset($wp_filter[$tag]) )
+		return;
+
+	do{
+		foreach( (array) current($wp_filter[$tag]) as $the_ )
+			if ( !is_null($the_['function']) )
+				call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
+
+	} while ( next($wp_filter[$tag]) );
+
+}
+
+/**
+ * Removes a function from a specified action hook. 
+ * 
+ * This function removes a function attached to a specified action hook. This 
+ * method can be used to remove default functions attached to a specific filter 
+ * hook and possibly replace them with a substitute.
+ * @param string $tag The action hook to which the function to be removed is hooked.
+ * @param callback $function_to_remove The name of the function which should be removed.
+ * @param int $priority optional The priority of the function (default: 10).
+ * @param int $accepted_args optional. The number of arguments the function accpets (default: 1).
+ * @return boolean Whether the function is removed.
+ */
+function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) {
+	remove_filter($tag, $function_to_remove, $priority, $accepted_args);
+}
+
+//
+// Functions for handling plugins.
+//
+
+/**
+ * Gets the basename of a plugin.
+ * 
+ * This method extract the name of a plugin from its filename.
+ * @param string $file The filename of plugin.
+ * @return string The name of a plugin.
+ */
+function plugin_basename($file) {
+	$file = preg_replace('|\\\\+|', '\\\\', $file);
+	$file = preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '', $file);
+	return $file;
+}
+
+/**
+ * Hook a function on a plugin activation action hook.
+ * 
+ * When a plugin is activated, the action 'activate_PLUGINNAME' hook is
+ * activated. In the name of this hook, PLUGINNAME is replaced with the name of
+ * the plugin, including the optional subdirectory. For example, when the plugin
+ * is located in <tt>wp-content/plugin/sampleplugin/sample.php</tt>, then the 
+ * name of this hook will become 'activate_sampleplugin/sample.php'. 
+ * When the plugin consists of only one file and is (as by default) located at 
+ * <tt>wp-content/plugin/sample.php</tt> the name of this hook will be 
+ * 'activate_sample.php'.
+ * @param string $file The filename of the plugin including the path.
+ * @param string $function the function hooked to the 'activate_PLUGIN' action.
+ */
+function register_activation_hook($file, $function) {
+	$file = plugin_basename($file);
+	add_action('activate_' . $file, $function);
+}
+
+/**
+ * Hook a function on a plugin deactivation action hook.
+ * 
+ * When a plugin is deactivated, the action 'deactivate_PLUGINNAME' hook is
+ * deactivated. In the name of this hook, PLUGINNAME is replaced with the name of
+ * the plugin, including the optional subdirectory. For example, when the plugin
+ * is located in <tt>wp-content/plugin/sampleplugin/sample.php</tt>, then the 
+ * name of this hook will become 'activate_sampleplugin/sample.php'. 
+ * When the plugin consists of only one file and is (as by default) located at 
+ * <tt>wp-content/plugin/sample.php</tt> the name of this hook will be 
+ * 'activate_sample.php'.
+ * @param string $file The filename of the plugin including the path.
+ * @param string $function the function hooked to the 'activate_PLUGIN' action.
+ */
+function register_deactivation_hook($file, $function) {
+	$file = plugin_basename($file);
+	add_action('deactivate_' . $file, $function);
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/post-template.php 2.2.2/wp-includes/post-template.php
--- 2.0.5/wp-includes/post-template.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/post-template.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,469 @@
+<?php
+
+//
+// "The Loop" post functions
+//
+
+function the_ID() {
+	global $id;
+	echo $id;
+}
+
+
+function get_the_ID() {
+	global $id;
+	return $id;
+}
+
+
+function the_title($before = '', $after = '', $echo = true) {
+	$title = get_the_title();
+	if ( strlen($title) > 0 ) {
+		$title = apply_filters('the_title', $before . $title . $after, $before, $after);
+		if ( $echo )
+			echo $title;
+		else
+			return $title;
+	}
+}
+
+
+function get_the_title($id = 0) {
+	$post = &get_post($id);
+
+	$title = $post->post_title;
+	if ( !empty($post->post_password) )
+		$title = sprintf(__('Protected: %s'), $title);
+	else if ( 'private' == $post->post_status )
+		$title = sprintf(__('Private: %s'), $title);
+
+	return $title;
+}
+
+function the_guid( $id = 0 ) {
+	echo get_the_guid($id);
+}
+
+function get_the_guid( $id = 0 ) {
+	$post = &get_post($id);
+
+	return apply_filters('get_the_guid', $post->guid);
+}
+
+function the_content($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
+	$content = get_the_content($more_link_text, $stripteaser, $more_file);
+	$content = apply_filters('the_content', $content);
+	$content = str_replace(']]>', ']]&gt;', $content);
+	echo $content;
+}
+
+
+function get_the_content($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
+	global $id, $post, $more, $single, $withcomments, $page, $pages, $multipage, $numpages;
+	global $preview;
+	global $pagenow;
+	$output = '';
+
+	if ( !empty($post->post_password) ) { // if there's a password
+		if ( stripslashes($_COOKIE['wp-postpass_'.COOKIEHASH]) != $post->post_password ) {	// and it doesn't match the cookie
+			$output = get_the_password_form();
+			return $output;
+		}
+	}
+
+	if ( $more_file != '' )
+		$file = $more_file;
+	else
+		$file = $pagenow; //$_SERVER['PHP_SELF'];
+
+	if ( $page > count($pages) ) // if the requested page doesn't exist
+		$page = count($pages); // give them the highest numbered page that DOES exist
+
+	$content = $pages[$page-1];
+	if ( preg_match('/<!--more(.*?)?-->/', $content, $matches) ) {
+		$content = explode($matches[0], $content, 2);
+		if ( !empty($matches[1]) && !empty($more_link_text) )
+			$more_link_text = strip_tags(wp_kses_no_null(trim($matches[1])));
+	} else {
+		$content = array($content);
+	}
+	if ( (false !== strpos($post->post_content, '<!--noteaser-->') && ((!$multipage) || ($page==1))) )
+		$stripteaser = 1;
+	$teaser = $content[0];
+	if ( ($more) && ($stripteaser) )
+		$teaser = '';
+	$output .= $teaser;
+	if ( count($content) > 1 ) {
+		if ( $more ) {
+			$output .= '<span id="more-'.$id.'"></span>'.$content[1];
+		} else {
+			$output = balanceTags($output);
+			if ( ! empty($more_link_text) )
+				$output .= ' <a href="'. get_permalink() . "#more-$id\" class=\"more-link\">$more_link_text</a>";
+		}
+
+	}
+	if ( $preview ) // preview fix for javascript bug with foreign languages
+		$output =	preg_replace('/\%u([0-9A-F]{4,4})/e',	"'&#'.base_convert('\\1',16,10).';'", $output);
+
+	return $output;
+}
+
+
+function the_excerpt() {
+	echo apply_filters('the_excerpt', get_the_excerpt());
+}
+
+
+function get_the_excerpt($fakeit = true) {
+	global $id, $post;
+	$output = '';
+	$output = $post->post_excerpt;
+	if ( !empty($post->post_password) ) { // if there's a password
+		if ( $_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password ) {  // and it doesn't match the cookie
+			$output = __('There is no excerpt because this is a protected post.');
+			return $output;
+		}
+	}
+
+	return apply_filters('get_the_excerpt', $output);
+}
+
+
+function wp_link_pages($args = '') {
+	global $post;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('before' => '<p>' . __('Pages:'), 'after' => '</p>', 'next_or_number' => 'number', 'nextpagelink' => __('Next page'),
+			'previouspagelink' => __('Previous page'), 'pagelink' => '%', 'more_file' => '', 'echo' => 1);
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	global $id, $page, $numpages, $multipage, $more, $pagenow;
+	if ( $more_file != '' )
+		$file = $more_file;
+	else
+		$file = $pagenow;
+
+	$output = '';
+	if ( $multipage ) {
+		if ( 'number' == $next_or_number ) {
+			$output .= $before;
+			for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) {
+				$j = str_replace('%',"$i",$pagelink);
+				$output .= ' ';
+				if ( ($i != $page) || ((!$more) && ($page==1)) ) {
+					if ( 1 == $i ) {
+						$output .= '<a href="' . get_permalink() . '">';
+					} else {
+						if ( '' == get_option('permalink_structure') || 'draft' == $post->post_status )
+							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">';
+						else
+							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
+					}
+				}
+				$output .= $j;
+				if ( ($i != $page) || ((!$more) && ($page==1)) )
+					$output .= '</a>';
+			}
+			$output .= $after;
+		} else {
+			if ( $more ) {
+				$output .= $before;
+				$i = $page - 1;
+				if ( $i && $more ) {
+					if ( 1 == $i ) {
+						$output .= '<a href="' . get_permalink() . '">' . $previouspagelink . '</a>';
+					} else {
+						if ( '' == get_option('permalink_structure') || 'draft' == $post->post_status )
+							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">' . $previouspagelink . '</a>';
+						else
+							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">' . $previouspagelink . '</a>';
+					}
+				}
+				$i = $page + 1;
+				if ( $i <= $numpages && $more ) {
+					if ( 1 == $i ) {
+						$output .= '<a href="' . get_permalink() . '">' . $nextpagelink . '</a>';
+					} else {
+						if ( '' == get_option('permalink_structure') || 'draft' == $post->post_status )
+							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">' . $nextpagelink . '</a>';
+						else
+							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">' . $nextpagelink . '</a>';
+					}
+				}
+				$output .= $after;
+			}
+		}
+	}
+
+	if ( $echo )
+		echo $output;
+
+	return $output;
+}
+
+
+//
+// Post-meta: Custom per-post fields.
+//
+
+
+function post_custom( $key = '' ) {
+	$custom = get_post_custom();
+
+	if ( 1 == count($custom[$key]) )
+		return $custom[$key][0];
+	else
+		return $custom[$key];
+}
+
+
+// this will probably change at some point...
+function the_meta() {
+	global $id;
+
+	if ( $keys = get_post_custom_keys() ) {
+		echo "<ul class='post-meta'>\n";
+		foreach ( $keys as $key ) {
+			$keyt = trim($key);
+			if ( '_' == $keyt{0} )
+				continue;
+			$values = array_map('trim', get_post_custom_values($key));
+			$value = implode($values,', ');
+			echo apply_filters('the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value);
+		}
+		echo "</ul>\n";
+	}
+}
+
+
+//
+// Pages
+//
+
+function wp_dropdown_pages($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('depth' => 0, 'child_of' => 0, 'selected' => 0, 'echo' => 1,
+		'name' => 'page_id', 'show_option_none' => '');
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	$pages = get_pages($r);
+	$output = '';
+
+	if ( ! empty($pages) ) {
+		$output = "<select name='$name'>\n";
+		if ( $show_option_none )
+			$output .= "\t<option value=''>$show_option_none</option>\n";
+		$output .= walk_page_dropdown_tree($pages, $depth, $r);
+		$output .= "</select>\n";
+	}
+
+	$output = apply_filters('wp_dropdown_pages', $output);
+
+	if ( $echo )
+		echo $output;
+
+	return $output;
+}
+
+function wp_list_pages($args = '') {
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('depth' => 0, 'show_date' => '', 'date_format' => get_option('date_format'),
+		'child_of' => 0, 'exclude' => '', 'title_li' => __('Pages'), 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order, post_title');
+	$r = array_merge($defaults, $r);
+
+	$output = '';
+	$current_page = 0;
+
+	// sanitize, mostly to keep spaces out
+	$r['exclude'] = preg_replace('[^0-9,]', '', $r['exclude']);
+
+	// Allow plugins to filter an array of excluded pages
+	$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));
+
+	// Query pages.
+	$pages = get_pages($r);
+
+	if ( !empty($pages) ) {
+		if ( $r['title_li'] )
+			$output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
+
+		global $wp_query;
+		if ( is_page() )
+			$current_page = $wp_query->get_queried_object_id();
+		$output .= walk_page_tree($pages, $r['depth'], $current_page, $r);
+
+		if ( $r['title_li'] )
+			$output .= '</ul></li>';
+	}
+
+	$output = apply_filters('wp_list_pages', $output);
+
+	if ( $r['echo'] )
+		echo $output;
+	else
+		return $output;
+}
+
+//
+// Page helpers
+//
+
+function walk_page_tree() {
+	$walker = new Walker_Page;
+	$args = func_get_args();
+	return call_user_func_array(array(&$walker, 'walk'), $args);
+}
+
+function walk_page_dropdown_tree() {
+	$walker = new Walker_PageDropdown;
+	$args = func_get_args();
+	return call_user_func_array(array(&$walker, 'walk'), $args);
+}
+
+//
+// Attachments
+//
+
+function the_attachment_link($id = 0, $fullsize = false, $max_dims = false) {
+	echo get_the_attachment_link($id, $fullsize, $max_dims);
+}
+
+function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false) {
+	$id = (int) $id;
+	$_post = & get_post($id);
+
+	if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
+		return __('Missing Attachment');
+
+	$post_title = attribute_escape($_post->post_title);
+
+	$innerHTML = get_attachment_innerHTML($_post->ID, $fullsize, $max_dims);
+	return "<a href='$url' title='$post_title'>$innerHTML</a>";
+}
+
+function get_attachment_icon_src( $id = 0, $fullsize = false ) {
+	$id = (int) $id;
+	if ( !$post = & get_post($id) )
+		return false;
+
+	$imagedata = wp_get_attachment_metadata( $post->ID );
+
+	$file = get_attached_file( $post->ID );
+
+	if ( !$fullsize && $thumbfile = wp_get_attachment_thumb_file( $post->ID ) ) {
+		// We have a thumbnail desired, specified and existing
+
+		$src = wp_get_attachment_thumb_url( $post->ID );
+		$src_file = $thumbfile;
+		$class = 'attachmentthumb';
+	} elseif ( wp_attachment_is_image( $post->ID ) ) {
+		// We have an image without a thumbnail
+
+		$src = wp_get_attachment_url( $post->ID );
+		$src_file = & $file;
+		$class = 'attachmentimage';
+	} elseif ( $src = wp_mime_type_icon( $post->ID ) ) {
+		// No thumb, no image. We'll look for a mime-related icon instead.
+
+		$icon_dir = apply_filters( 'icon_dir', get_template_directory() . '/images' );
+		$src_file = $icon_dir . '/' . basename($src);
+	}
+
+	if ( !isset($src) || !$src )
+		return false;
+
+	return array($src, $src_file);
+}
+
+function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) {
+	$id = (int) $id;
+	if ( !$post = & get_post($id) )
+		return false;
+
+	if ( !$src = get_attachment_icon_src( $post->ID, $fullsize ) )
+		return false;
+
+	list($src, $src_file) = $src;
+
+	// Do we need to constrain the image?
+	if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) {
+
+		$imagesize = getimagesize($src_file);
+
+		if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) {
+			$actual_aspect = $imagesize[0] / $imagesize[1];
+			$desired_aspect = $max_dims[0] / $max_dims[1];
+
+			if ( $actual_aspect >= $desired_aspect ) {
+				$height = $actual_aspect * $max_dims[0];
+				$constraint = "width='{$max_dims[0]}' ";
+				$post->iconsize = array($max_dims[0], $height);
+			} else {
+				$width = $max_dims[1] / $actual_aspect;
+				$constraint = "height='{$max_dims[1]}' ";
+				$post->iconsize = array($width, $max_dims[1]);
+			}
+		} else {
+			$post->iconsize = array($imagesize[0], $imagesize[1]);
+		}
+	}
+
+	$post_title = attribute_escape($post->post_title);
+
+	$icon = "<img src='$src' title='$post_title' alt='$post_title' $constraint/>";
+
+	return apply_filters( 'attachment_icon', $icon, $post->ID );
+}
+
+function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false) {
+	$id = (int) $id;
+	if ( !$post = & get_post($id) )
+		return false;
+
+	if ( $innerHTML = get_attachment_icon($post->ID, $fullsize, $max_dims))
+		return $innerHTML;
+
+
+	$innerHTML = attribute_escape($post->post_title);
+
+	return apply_filters('attachment_innerHTML', $innerHTML, $post->ID);
+}
+
+function prepend_attachment($content) {
+	$p = '<p class="attachment">';
+	$p .= get_the_attachment_link(false, true, array(400, 300));
+	$p .= '</p>';
+	$p = apply_filters('prepend_attachment', $p);
+
+	return "$p\n$content";
+}
+
+//
+// Misc
+//
+
+function get_the_password_form() {
+	$output = '<form action="' . get_option('siteurl') . '/wp-pass.php" method="post">
+	<p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
+	<p><label>' . __("Password:") . ' <input name="post_password" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . __("Submit") . '" /></p>
+	</form>
+	';
+	return $output;
+}
+
+?>
diff -ruN 2.0.5/wp-includes/post.php 2.2.2/wp-includes/post.php
--- 2.0.5/wp-includes/post.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/post.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,1609 @@
+<?php
+
+//
+// Post functions
+//
+
+function get_attached_file( $attachment_id, $unfiltered = false ) {
+	$file = get_post_meta( $attachment_id, '_wp_attached_file', true );
+	if ( $unfiltered )
+		return $file;
+	return apply_filters( 'get_attached_file', $file, $attachment_id );
+}
+
+function update_attached_file( $attachment_id, $file ) {
+	if ( !get_post( $attachment_id ) )
+		return false;
+
+	$old_file = get_attached_file( $attachment_id, true );
+
+	$file = apply_filters( 'update_attached_file', $file, $attachment_id );
+
+	if ( $old_file )
+		return update_post_meta( $attachment_id, '_wp_attached_file', $file, $old_file );
+	else
+		return add_post_meta( $attachment_id, '_wp_attached_file', $file );
+}
+
+function &get_children($args = '', $output = OBJECT) {
+	global $post_cache, $wpdb, $blog_id;
+
+	if ( empty($args) ) {
+		if ( isset($GLOBALS['post']) )
+			$r = array('post_parent' => & $GLOBALS['post']->post_parent);
+		else
+			return false;
+	} elseif ( is_object($args) )
+		$r = array('post_parent' => $post->post_parent);
+	elseif ( is_numeric($args) )
+		$r = array('post_parent' => $args);
+	elseif ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('numberposts' => -1, 'post_type' => '', 'post_status' => '', 'post_parent' => 0);
+	$r = array_merge($defaults, $r);
+
+	$children = get_posts( $r );
+
+	if ( $children ) {
+		foreach ( $children as $key => $child ) {
+			$post_cache[$blog_id][$child->ID] =& $children[$key];
+			$kids[$child->ID] =& $children[$key];
+		}
+	} else {
+		return false;
+	}
+
+	if ( $output == OBJECT ) {
+		return $kids;
+	} elseif ( $output == ARRAY_A ) {
+		foreach ( $kids as $kid )
+			$weeuns[$kid->ID] = get_object_vars($kids[$kid->ID]);
+		return $weeuns;
+	} elseif ( $output == ARRAY_N ) {
+		foreach ( $kids as $kid )
+			$babes[$kid->ID] = array_values(get_object_vars($kids[$kid->ID]));
+		return $babes;
+	} else {
+		return $kids;
+	}
+}
+
+// get extended entry info (<!--more-->)
+function get_extended($post) {
+	//Match the new style more links
+	if ( preg_match('/<!--more(.*?)?-->/', $post, $matches) ) {
+		list($main, $extended) = explode($matches[0], $post, 2);
+	} else {
+		$main = $post;
+		$extended = '';
+	}
+
+	// Strip leading and trailing whitespace
+	$main = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $main);
+	$extended = preg_replace('/^[\s]*(.*)[\s]*$/', '\\1', $extended);
+
+	return array('main' => $main, 'extended' => $extended);
+}
+
+// Retrieves post data given a post ID or post object.
+// Handles post caching.
+function &get_post(&$post, $output = OBJECT) {
+	global $post_cache, $wpdb, $blog_id;
+
+	if ( empty($post) ) {
+		if ( isset($GLOBALS['post']) )
+			$_post = & $GLOBALS['post'];
+		else
+			$_post = null;
+	} elseif ( is_object($post) ) {
+		if ( 'page' == $post->post_type )
+			return get_page($post, $output);
+		if ( !isset($post_cache[$blog_id][$post->ID]) )
+			$post_cache[$blog_id][$post->ID] = &$post;
+		$_post = & $post_cache[$blog_id][$post->ID];
+	} else {
+		$post = (int) $post;
+		if ( isset($post_cache[$blog_id][$post]) )
+			$_post = & $post_cache[$blog_id][$post];
+		elseif ( $_post = wp_cache_get($post, 'pages') )
+			return get_page($_post, $output);
+		else {
+			$query = "SELECT * FROM $wpdb->posts WHERE ID = '$post' LIMIT 1";
+			$_post = & $wpdb->get_row($query);
+			if ( 'page' == $_post->post_type )
+				return get_page($_post, $output);
+			$post_cache[$blog_id][$post] = & $_post;
+		}
+	}
+
+	if ( defined('WP_IMPORTING') )
+		unset($post_cache[$blog_id]);
+
+	if ( $output == OBJECT ) {
+		return $_post;
+	} elseif ( $output == ARRAY_A ) {
+		return get_object_vars($_post);
+	} elseif ( $output == ARRAY_N ) {
+		return array_values(get_object_vars($_post));
+	} else {
+		return $_post;
+	}
+}
+
+// Takes a post ID, returns its mime type.
+function get_post_mime_type($ID = '') {
+	$post = & get_post($ID);
+
+	if ( is_object($post) )
+		return $post->post_mime_type;
+
+	return false;
+}
+
+function get_post_status($ID = '') {
+	$post = get_post($ID);
+
+	if ( is_object($post) ) {
+		if ( ('attachment' == $post->post_type) && $post->post_parent && ($post->ID != $post->post_parent) )
+			return get_post_status($post->post_parent);
+		else
+			return $post->post_status;
+	}
+
+	return false;
+}
+
+function get_post_type($post = false) {
+	global $wpdb, $posts;
+
+	if ( false === $post )
+		$post = $posts[0];
+	elseif ( (int) $post )
+		$post = get_post($post, OBJECT);
+
+	if ( is_object($post) )
+		return $post->post_type;
+
+	return false;
+}
+
+function get_posts($args) {
+	global $wpdb;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('numberposts' => 5, 'offset' => 0, 'category' => 0,
+		'orderby' => 'post_date', 'order' => 'DESC', 'include' => '', 'exclude' => '',
+		'meta_key' => '', 'meta_value' =>'', 'post_type' => 'post', 'post_status' => 'publish', 'post_parent' => 0);
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+	$numberposts = (int) $numberposts;
+	$offset = (int) $offset;
+	$category = (int) $category;
+	$post_parent = (int) $post_parent;
+
+	$inclusions = '';
+	if ( !empty($include) ) {
+		$offset = 0;    //ignore offset, category, exclude, meta_key, and meta_value, post_parent if using include
+		$category = 0;
+		$exclude = '';
+		$meta_key = '';
+		$meta_value = '';
+		$post_parent = 0;
+		$incposts = preg_split('/[\s,]+/',$include);
+		$numberposts = count($incposts);  // only the number of posts included
+		if ( count($incposts) ) {
+			foreach ( $incposts as $incpost ) {
+				if (empty($inclusions))
+					$inclusions = ' AND ( ID = ' . intval($incpost) . ' ';
+				else
+					$inclusions .= ' OR ID = ' . intval($incpost) . ' ';
+			}
+		}
+	}
+	if (!empty($inclusions))
+		$inclusions .= ')';
+
+	$exclusions = '';
+	if ( !empty($exclude) ) {
+		$exposts = preg_split('/[\s,]+/',$exclude);
+		if ( count($exposts) ) {
+			foreach ( $exposts as $expost ) {
+				if (empty($exclusions))
+					$exclusions = ' AND ( ID <> ' . intval($expost) . ' ';
+				else
+					$exclusions .= ' AND ID <> ' . intval($expost) . ' ';
+			}
+		}
+	}
+	if (!empty($exclusions))
+		$exclusions .= ')';
+
+	$query  = "SELECT DISTINCT * FROM $wpdb->posts ";
+	$query .= empty( $category ) ? '' : ", $wpdb->post2cat "; 
+	$query .= empty( $meta_key ) ? '' : ", $wpdb->postmeta ";
+	$query .= " WHERE 1=1 ";
+	$query .= empty( $post_type ) ? '' : "AND post_type = '$post_type' ";
+	$query .= empty( $post_status ) ? '' : "AND post_status = '$post_status' ";
+	$query .= "$exclusions $inclusions " ;
+	$query .= empty( $category ) ? '' : "AND ($wpdb->posts.ID = $wpdb->post2cat.post_id AND $wpdb->post2cat.category_id = " . $category. ") ";
+	$query .= empty( $post_parent ) ? '' : "AND $wpdb->posts.post_parent = '$post_parent' ";
+	$query .= empty( $meta_key ) | empty($meta_value)  ? '' : " AND ($wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '$meta_key' AND $wpdb->postmeta.meta_value = '$meta_value' )";
+	$query .= " GROUP BY $wpdb->posts.ID ORDER BY " . $orderby . ' ' . $order;
+	if ( 0 < $numberposts )
+		$query .= " LIMIT " . $offset . ',' . $numberposts;
+
+	$posts = $wpdb->get_results($query);
+
+	update_post_caches($posts);
+
+	return $posts;
+}
+
+//
+// Post meta functions
+//
+
+function add_post_meta($post_id, $key, $value, $unique = false) {
+	global $wpdb, $post_meta_cache, $blog_id;
+
+	$post_id = (int) $post_id;
+
+	if ( $unique ) {
+		if ( $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
+			return false;
+		}
+	}
+
+	$post_meta_cache[$blog_id][$post_id][$key][] = $value;
+
+	$value = maybe_serialize($value);
+	$value = $wpdb->escape($value);
+
+	$wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
+
+	return true;
+}
+
+function delete_post_meta($post_id, $key, $value = '') {
+	global $wpdb, $post_meta_cache, $blog_id;
+
+	$post_id = (int) $post_id;
+
+	if ( empty($value) ) {
+		$meta_id = $wpdb->get_var("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'");
+	} else {
+		$meta_id = $wpdb->get_var("SELECT meta_id FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key' AND meta_value = '$value'");
+	}
+
+	if ( !$meta_id )
+		return false;
+
+	if ( empty($value) ) {
+		$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'");
+		unset($post_meta_cache[$blog_id][$post_id][$key]);
+	} else {
+		$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key' AND meta_value = '$value'");
+		$cache_key = $post_meta_cache[$blog_id][$post_id][$key];
+		if ($cache_key) foreach ( $cache_key as $index => $data )
+			if ( $data == $value )
+				unset($post_meta_cache[$blog_id][$post_id][$key][$index]);
+	}
+
+	unset($post_meta_cache[$blog_id][$post_id][$key]);
+
+	return true;
+}
+
+function get_post_meta($post_id, $key, $single = false) {
+	global $wpdb, $post_meta_cache, $blog_id;
+
+	$post_id = (int) $post_id;
+
+	if ( isset($post_meta_cache[$blog_id][$post_id][$key]) ) {
+		if ( $single ) {
+			return maybe_unserialize( $post_meta_cache[$blog_id][$post_id][$key][0] );
+		} else {
+			return maybe_unserialize( $post_meta_cache[$blog_id][$post_id][$key] );
+		}
+	}
+
+	if ( !isset($post_meta_cache[$blog_id][$post_id]) )
+		update_postmeta_cache($post_id);
+
+	if ( $single ) {
+		if ( isset($post_meta_cache[$blog_id][$post_id][$key][0]) )
+			return maybe_unserialize($post_meta_cache[$blog_id][$post_id][$key][0]);
+		else
+			return '';
+	}	else {
+		return maybe_unserialize($post_meta_cache[$blog_id][$post_id][$key]);
+	}
+}
+
+function update_post_meta($post_id, $key, $value, $prev_value = '') {
+	global $wpdb, $post_meta_cache, $blog_id;
+
+	$post_id = (int) $post_id;
+
+	$original_value = $value;
+	$value = maybe_serialize($value);
+	$value = $wpdb->escape($value);
+
+	$original_prev = $prev_value;
+	$prev_value = maybe_serialize($prev_value);
+	$prev_value = $wpdb->escape($prev_value);
+
+	if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
+		return false;
+	}
+
+	if ( empty($prev_value) ) {
+		$wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '$value' WHERE meta_key = '$key' AND post_id = '$post_id'");
+		$cache_key = $post_meta_cache[$blog_id][$post_id][$key];
+		if ( !empty($cache_key) )
+			foreach ($cache_key as $index => $data)
+				$post_meta_cache[$blog_id][$post_id][$key][$index] = $original_value;
+	} else {
+		$wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '$value' WHERE meta_key = '$key' AND post_id = '$post_id' AND meta_value = '$prev_value'");
+		$cache_key = $post_meta_cache[$blog_id][$post_id][$key];
+		if ( !empty($cache_key) )
+			foreach ($cache_key as $index => $data)
+				if ( $data == $original_prev )
+					$post_meta_cache[$blog_id][$post_id][$key][$index] = $original_value;
+	}
+
+	return true;
+}
+
+
+function get_post_custom($post_id = 0) {
+	global $id, $post_meta_cache, $wpdb, $blog_id;
+
+	if ( !$post_id )
+		$post_id = (int) $id;
+
+	$post_id = (int) $post_id;
+
+	if ( !isset($post_meta_cache[$blog_id][$post_id]) )
+		update_postmeta_cache($post_id);
+
+	return $post_meta_cache[$blog_id][$post_id];
+}
+
+function get_post_custom_keys( $post_id = 0 ) {
+	$custom = get_post_custom( $post_id );
+
+	if ( !is_array($custom) )
+		return;
+
+	if ( $keys = array_keys($custom) )
+		return $keys;
+}
+
+
+function get_post_custom_values( $key = '', $post_id = 0 ) {
+	$custom = get_post_custom($post_id);
+
+	return $custom[$key];
+}
+
+function wp_delete_post($postid = 0) {
+	global $wpdb, $wp_rewrite;
+	$postid = (int) $postid;
+
+	if ( !$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = $postid") )
+		return $post;
+
+	if ( 'attachment' == $post->post_type )
+		return wp_delete_attachment($postid);
+
+	do_action('delete_post', $postid);
+
+	if ( 'publish' == $post->post_status && 'post' == $post->post_type ) {
+		$categories = wp_get_post_categories($post->ID);
+		if( is_array( $categories ) ) {
+			foreach ( $categories as $cat_id ) {
+				$wpdb->query("UPDATE $wpdb->categories SET category_count = category_count - 1 WHERE cat_ID = '$cat_id'");
+				wp_cache_delete($cat_id, 'category');
+				do_action('edit_category', $cat_id);
+			}
+		}
+	}
+
+	if ( 'page' == $post->post_type )
+		$wpdb->query("UPDATE $wpdb->posts SET post_parent = $post->post_parent WHERE post_parent = $postid AND post_type = 'page'");
+
+	$wpdb->query("UPDATE $wpdb->posts SET post_parent = $post->post_parent WHERE post_parent = $postid AND post_type = 'attachment'");
+
+	$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = $postid");
+
+	$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_post_ID = $postid");
+
+	$wpdb->query("DELETE FROM $wpdb->post2cat WHERE post_id = $postid");
+
+	$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = $postid");
+
+	if ( 'page' == $post->post_type ) {
+		clean_page_cache($postid);
+		$wp_rewrite->flush_rules();
+	}
+
+	do_action('deleted_post', $postid);
+	
+	return $post;
+}
+
+function wp_get_post_categories($post_id = 0) {
+	$post_id = (int) $post_id;
+
+	$cats = &get_the_category($post_id);
+	$cat_ids = array();
+	foreach ( $cats as $cat )
+		$cat_ids[] = (int) $cat->cat_ID;
+	return array_unique($cat_ids);
+}
+
+function wp_get_recent_posts($num = 10) {
+	global $wpdb;
+
+	// Set the limit clause, if we got a limit
+	$num = (int) $num;
+	if ($num) {
+		$limit = "LIMIT $num";
+	}
+
+	$sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'post' ORDER BY post_date DESC $limit";
+	$result = $wpdb->get_results($sql,ARRAY_A);
+
+	return $result?$result:array();
+}
+
+function wp_get_single_post($postid = 0, $mode = OBJECT) {
+	global $wpdb;
+
+	$postid = (int) $postid;
+
+	$post = get_post($postid, $mode);
+
+	// Set categories
+	if($mode == OBJECT) {
+		$post->post_category = wp_get_post_categories($postid);
+	}
+	else {
+		$post['post_category'] = wp_get_post_categories($postid);
+	}
+
+	return $post;
+}
+
+function wp_insert_post($postarr = array()) {
+	global $wpdb, $wp_rewrite, $allowedtags, $user_ID;
+
+	if ( is_object($postarr) )
+		$postarr = get_object_vars($postarr);
+
+	// export array as variables
+	extract($postarr, EXTR_SKIP);
+
+	// Are we updating or creating?
+	$update = false;
+	if ( !empty($ID) ) {
+		$update = true;
+		$post = & get_post($ID);
+		$previous_status = $post->post_status;
+	}
+
+	// Get the basics.
+	if ( empty($no_filter) ) {
+		$post_content    = apply_filters('content_save_pre',   $post_content);
+		$post_content_filtered = apply_filters('content_filtered_save_pre',   $post_content_filtered);
+		$post_excerpt    = apply_filters('excerpt_save_pre',   $post_excerpt);
+		$post_title      = apply_filters('title_save_pre',     $post_title);
+		$post_category   = apply_filters('category_save_pre',  $post_category);
+		$post_status     = apply_filters('status_save_pre',    $post_status);
+		$post_name       = apply_filters('name_save_pre',      $post_name);
+		$comment_status  = apply_filters('comment_status_pre', $comment_status);
+		$ping_status     = apply_filters('ping_status_pre',    $ping_status);
+	}
+
+	if ( ('' == $post_content) && ('' == $post_title) && ('' == $post_excerpt) )
+		return 0;
+
+	// Make sure we set a valid category
+	if (0 == count($post_category) || !is_array($post_category)) {
+		$post_category = array(get_option('default_category'));
+	}
+	$post_cat = $post_category[0];
+
+	if ( empty($post_author) )
+		$post_author = $user_ID;
+
+	if ( empty($post_status) )
+		$post_status = 'draft';
+
+	if ( empty($post_type) )
+		$post_type = 'post';
+
+	// Get the post ID.
+	if ( $update )
+		$post_ID = (int) $ID;
+
+	// Create a valid post name.  Drafts are allowed to have an empty
+	// post name.
+	if ( empty($post_name) ) {
+		if ( 'draft' != $post_status )
+			$post_name = sanitize_title($post_title);
+	} else {
+		$post_name = sanitize_title($post_name);
+	}
+
+
+	// If the post date is empty (due to having been new or a draft) and status is not 'draft', set date to now
+	if (empty($post_date)) {
+		if ( 'draft' != $post_status )
+			$post_date = current_time('mysql');
+	}
+
+	if (empty($post_date_gmt)) {
+		if ( 'draft' != $post_status )
+			$post_date_gmt = get_gmt_from_date($post_date);
+	}
+
+	if ( 'publish' == $post_status ) {
+		$now = gmdate('Y-m-d H:i:59');
+		if ( mysql2date('U', $post_date_gmt) > mysql2date('U', $now) )
+			$post_status = 'future';
+	}
+
+	if ( empty($comment_status) ) {
+		if ( $update )
+			$comment_status = 'closed';
+		else
+			$comment_status = get_option('default_comment_status');
+	}
+	if ( empty($ping_status) )
+		$ping_status = get_option('default_ping_status');
+	if ( empty($post_pingback) )
+		$post_pingback = get_option('default_pingback_flag');
+
+	if ( isset($to_ping) )
+		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
+	else
+		$to_ping = '';
+
+	if ( ! isset($pinged) )
+		$pinged = '';
+
+	if ( isset($post_parent) )
+		$post_parent = (int) $post_parent;
+	else
+		$post_parent = 0;
+
+	if ( isset($menu_order) )
+		$menu_order = (int) $menu_order;
+	else
+		$menu_order = 0;
+
+	if ( !isset($post_password) )
+		$post_password = '';
+
+	if ( 'draft' != $post_status ) {
+		$post_name_check = $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_type = '$post_type' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");
+
+		if ($post_name_check || in_array($post_name, $wp_rewrite->feeds) ) {
+			$suffix = 2;
+			do {
+				$alt_post_name = $post_name . "-$suffix";
+				$post_name_check = $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_type = '$post_type' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");
+				$suffix++;
+			} while ($post_name_check);
+			$post_name = $alt_post_name;
+		}
+	}
+
+	if ($update) {
+		$wpdb->query(
+			"UPDATE IGNORE $wpdb->posts SET
+			post_author = '$post_author',
+			post_date = '$post_date',
+			post_date_gmt = '$post_date_gmt',
+			post_content = '$post_content',
+			post_content_filtered = '$post_content_filtered',
+			post_title = '$post_title',
+			post_excerpt = '$post_excerpt',
+			post_status = '$post_status',
+			post_type = '$post_type',
+			comment_status = '$comment_status',
+			ping_status = '$ping_status',
+			post_password = '$post_password',
+			post_name = '$post_name',
+			to_ping = '$to_ping',
+			pinged = '$pinged',
+			post_modified = '".current_time('mysql')."',
+			post_modified_gmt = '".current_time('mysql',1)."',
+			post_parent = '$post_parent',
+			menu_order = '$menu_order'
+			WHERE ID = $post_ID");
+	} else {
+		$wpdb->query(
+			"INSERT IGNORE INTO $wpdb->posts
+			(post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt,  post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
+			VALUES
+			('$post_author', '$post_date', '$post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', '$post_status', '$post_type', '$comment_status', '$ping_status', '$post_password', '$post_name', '$to_ping', '$pinged', '$post_date', '$post_date_gmt', '$post_parent', '$menu_order', '$post_mime_type')");
+			$post_ID = (int) $wpdb->insert_id;
+	}
+
+	if ( empty($post_name) && 'draft' != $post_status ) {
+		$post_name = sanitize_title($post_title, $post_ID);
+		$wpdb->query( "UPDATE $wpdb->posts SET post_name = '$post_name' WHERE ID = '$post_ID'" );
+	}
+
+	wp_set_post_categories($post_ID, $post_category);
+
+	if ( 'page' == $post_type ) {
+		clean_page_cache($post_ID);
+		$wp_rewrite->flush_rules();
+	} else {
+		clean_post_cache($post_ID);
+	}
+
+	// Set GUID
+	if ( ! $update )
+		$wpdb->query("UPDATE $wpdb->posts SET guid = '" . get_permalink($post_ID) . "' WHERE ID = '$post_ID'");
+
+	if ( $update) {
+		if ($previous_status != 'publish' && $post_status == 'publish') {
+			// Reset GUID if transitioning to publish.
+			$wpdb->query("UPDATE $wpdb->posts SET guid = '" . get_permalink($post_ID) . "' WHERE ID = '$post_ID'");
+			do_action('private_to_published', $post_ID);
+		}
+
+		do_action('edit_post', $post_ID);
+	}
+
+	if ($post_status == 'publish' && $post_type == 'post') {
+		do_action('publish_post', $post_ID);
+		if ( defined('XMLRPC_REQUEST') )
+			do_action('xmlrpc_publish_post', $post_ID);
+		if ( defined('APP_REQUEST') )
+			do_action('app_publish_post', $post_ID);
+
+		if ( !defined('WP_IMPORTING') ) {
+			if ( $post_pingback )
+				$result = $wpdb->query("
+					INSERT INTO $wpdb->postmeta
+					(post_id,meta_key,meta_value)
+					VALUES ('$post_ID','_pingme','1')
+				");
+			$result = $wpdb->query("
+				INSERT INTO $wpdb->postmeta
+				(post_id,meta_key,meta_value)
+				VALUES ('$post_ID','_encloseme','1')
+			");
+			wp_schedule_single_event(time(), 'do_pings');
+		}
+	} else if ($post_type == 'page') {
+		if ( !empty($page_template) )
+			if ( ! update_post_meta($post_ID, '_wp_page_template',  $page_template))
+				add_post_meta($post_ID, '_wp_page_template',  $page_template, true);
+
+		if ( $post_status == 'publish' )
+			do_action('publish_page', $post_ID);
+	}
+
+	// Always clears the hook in case the post status bounced from future to draft.
+	wp_clear_scheduled_hook('publish_future_post', $post_ID);
+
+	// Schedule publication.
+	if ( 'future' == $post_status )
+		wp_schedule_single_event(strtotime($post_date_gmt. ' GMT'), 'publish_future_post', array($post_ID));
+
+	do_action('save_post', $post_ID);
+	do_action('wp_insert_post', $post_ID);
+
+	return $post_ID;
+}
+
+function wp_update_post($postarr = array()) {
+	global $wpdb;
+
+	if ( is_object($postarr) )
+		$postarr = get_object_vars($postarr);
+
+	// First, get all of the original fields
+	$post = wp_get_single_post($postarr['ID'], ARRAY_A);
+
+	// Escape data pulled from DB.
+	$post = add_magic_quotes($post);
+
+	// Passed post category list overwrites existing category list if not empty.
+	if ( isset($postarr['post_category']) && is_array($postarr['post_category'])
+			 && 0 != count($postarr['post_category']) )
+		$post_cats = $postarr['post_category'];
+	else
+		$post_cats = $post['post_category'];
+
+	// Drafts shouldn't be assigned a date unless explicitly done so by the user
+	if ( 'draft' == $post['post_status'] && empty($postarr['edit_date']) && empty($postarr['post_date']) &&
+			 ('0000-00-00 00:00:00' == $post['post_date']) )
+		$clear_date = true;
+	else
+		$clear_date = false;
+
+	// Merge old and new fields with new fields overwriting old ones.
+	$postarr = array_merge($post, $postarr);
+	$postarr['post_category'] = $post_cats;
+	if ( $clear_date ) {
+		$postarr['post_date'] = '';
+		$postarr['post_date_gmt'] = '';
+	}
+
+	if ($postarr['post_type'] == 'attachment')
+		return wp_insert_attachment($postarr);
+
+	return wp_insert_post($postarr);
+}
+
+function wp_publish_post($post_id) {
+	$post = get_post($post_id);
+
+	if ( empty($post) )
+		return;
+
+	if ( 'publish' == $post->post_status )
+		return;
+
+	return wp_update_post(array('post_status' => 'publish', 'ID' => $post_id, 'no_filter' => true));
+}
+
+function wp_set_post_categories($post_ID = 0, $post_categories = array()) {
+	global $wpdb;
+
+	$post_ID = (int) $post_ID;
+	// If $post_categories isn't already an array, make it one:
+	if (!is_array($post_categories) || 0 == count($post_categories) || empty($post_categories))
+		$post_categories = array(get_option('default_category'));
+
+	$post_categories = array_unique($post_categories);
+
+	// First the old categories
+	$old_categories = $wpdb->get_col("
+		SELECT category_id
+		FROM $wpdb->post2cat
+		WHERE post_id = '$post_ID'");
+
+	if (!$old_categories) {
+		$old_categories = array();
+	} else {
+		$old_categories = array_unique($old_categories);
+	}
+
+	// Delete any?
+	$delete_cats = array_diff($old_categories,$post_categories);
+
+	if ($delete_cats) {
+		foreach ($delete_cats as $del) {
+			$wpdb->query("
+				DELETE FROM $wpdb->post2cat
+				WHERE category_id = '$del'
+					AND post_id = '$post_ID'
+				");
+		}
+	}
+
+	// Add any?
+	$add_cats = array_diff($post_categories, $old_categories);
+
+	if ($add_cats) {
+		foreach ($add_cats as $new_cat) {
+			$new_cat = (int) $new_cat;
+			if ( !empty($new_cat) )
+				$wpdb->query("
+					INSERT INTO $wpdb->post2cat (post_id, category_id) 
+					VALUES ('$post_ID', '$new_cat')");
+		}
+	}
+
+	// Update category counts.
+	$all_affected_cats = array_unique(array_merge($post_categories, $old_categories));
+	foreach ( $all_affected_cats as $cat_id ) {
+		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status = 'publish' AND post_type = 'post' AND category_id = '$cat_id'");
+		$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
+		clean_category_cache($cat_id);
+		do_action('edit_category', $cat_id);
+	}
+}	// wp_set_post_categories()
+
+//
+// Trackback and ping functions
+//
+
+function add_ping($post_id, $uri) { // Add a URL to those already pung
+	global $wpdb;
+	$pung = $wpdb->get_var("SELECT pinged FROM $wpdb->posts WHERE ID = $post_id");
+	$pung = trim($pung);
+	$pung = preg_split('/\s/', $pung);
+	$pung[] = $uri;
+	$new = implode("\n", $pung);
+	$new = apply_filters('add_ping', $new);
+	return $wpdb->query("UPDATE $wpdb->posts SET pinged = '$new' WHERE ID = $post_id");
+}
+
+function get_enclosed($post_id) { // Get enclosures already enclosed for a post
+	global $wpdb;
+	$custom_fields = get_post_custom( $post_id );
+	$pung = array();
+	if ( !is_array( $custom_fields ) )
+		return $pung;
+
+	foreach ( $custom_fields as $key => $val ) {
+		if ( 'enclosure' != $key || !is_array( $val ) )
+			continue;
+		foreach( $val as $enc ) {
+			$enclosure = split( "\n", $enc );
+			$pung[] = trim( $enclosure[ 0 ] );
+		}
+	}
+	$pung = apply_filters('get_enclosed', $pung);
+	return $pung;
+}
+
+function get_pung($post_id) { // Get URLs already pung for a post
+	global $wpdb;
+	$pung = $wpdb->get_var("SELECT pinged FROM $wpdb->posts WHERE ID = $post_id");
+	$pung = trim($pung);
+	$pung = preg_split('/\s/', $pung);
+	$pung = apply_filters('get_pung', $pung);
+	return $pung;
+}
+
+function get_to_ping($post_id) { // Get any URLs in the todo list
+	global $wpdb;
+	$to_ping = $wpdb->get_var("SELECT to_ping FROM $wpdb->posts WHERE ID = $post_id");
+	$to_ping = trim($to_ping);
+	$to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);
+	$to_ping = apply_filters('get_to_ping',  $to_ping);
+	return $to_ping;
+}
+
+// do trackbacks for a list of urls
+// accepts a comma-separated list of trackback urls and a post id
+function trackback_url_list($tb_list, $post_id) {
+	if (!empty($tb_list)) {
+		// get post data
+		$postdata = wp_get_single_post($post_id, ARRAY_A);
+
+		// import postdata as variables
+		extract($postdata, EXTR_SKIP);
+
+		// form an excerpt
+		$excerpt = strip_tags($post_excerpt?$post_excerpt:$post_content);
+
+		if (strlen($excerpt) > 255) {
+			$excerpt = substr($excerpt,0,252) . '...';
+		}
+
+		$trackback_urls = explode(',', $tb_list);
+		foreach($trackback_urls as $tb_url) {
+				$tb_url = trim($tb_url);
+				trackback($tb_url, stripslashes($post_title), $excerpt, $post_id);
+		}
+		}
+}
+
+//
+// Page functions
+//
+
+function get_all_page_ids() {
+	global $wpdb;
+
+	if ( ! $page_ids = wp_cache_get('all_page_ids', 'pages') ) {
+		$page_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_type = 'page'");
+		wp_cache_add('all_page_ids', $page_ids, 'pages');
+	}
+
+	return $page_ids;
+}
+
+
+// Retrieves page data given a page ID or page object.
+// Handles page caching.
+function &get_page(&$page, $output = OBJECT) {
+	global $wpdb, $blog_id;
+
+	if ( empty($page) ) {
+		if ( isset($GLOBALS['page']) ) {
+			$_page = & $GLOBALS['page'];
+			wp_cache_add($_page->ID, $_page, 'pages');
+		} else {
+			// shouldn't we just return NULL at this point? ~ Mark
+			$_page = null;
+		}
+	} elseif ( is_object($page) ) {
+		if ( 'post' == $page->post_type )
+			return get_post($page, $output);
+		wp_cache_add($page->ID, $page, 'pages');
+		$_page = $page;
+	} else {
+		$page = (int) $page;
+		// first, check the cache
+		if ( ! ( $_page = wp_cache_get($page, 'pages') ) ) {
+			// not in the page cache?
+			if ( isset($GLOBALS['page']->ID) && ($page == $GLOBALS['page']->ID) ) { // for is_page() views
+				// I don't think this code ever gets executed ~ Mark
+				$_page = & $GLOBALS['page'];
+				wp_cache_add($_page->ID, $_page, 'pages');
+			} elseif ( isset($GLOBALS['post_cache'][$blog_id][$page]) ) { // it's actually a page, and is cached
+				return get_post($page, $output);
+			} else { // it's not in any caches, so off to the DB we go
+				// Why are we using assignment for this query?
+				$_page = & $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID= '$page' LIMIT 1");
+				if ( 'post' == $_page->post_type )
+					return get_post($_page, $output);
+				// Potential issue: we're not checking to see if the post_type = 'page'
+				// So all non-'post' posts will get cached as pages.
+				wp_cache_add($_page->ID, $_page, 'pages');
+			}
+		}
+	}
+
+	// at this point, one way or another, $_post contains the page object
+
+	if ( $output == OBJECT ) {
+		return $_page;
+	} elseif ( $output == ARRAY_A ) {
+		return get_object_vars($_page);
+	} elseif ( $output == ARRAY_N ) {
+		return array_values(get_object_vars($_page));
+	} else {
+		return $_page;
+	}
+}
+
+function get_page_by_path($page_path, $output = OBJECT) {
+	global $wpdb;
+	$page_path = rawurlencode(urldecode($page_path));
+	$page_path = str_replace('%2F', '/', $page_path);
+	$page_path = str_replace('%20', ' ', $page_path);
+	$page_paths = '/' . trim($page_path, '/');
+	$leaf_path  = sanitize_title(basename($page_paths));
+	$page_paths = explode('/', $page_paths);
+	foreach($page_paths as $pathdir)
+		$full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
+
+	$pages = $wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = '$leaf_path' AND post_type='page'");
+
+	if ( empty($pages) )
+		return NULL;
+
+	foreach ($pages as $page) {
+		$path = '/' . $leaf_path;
+		$curpage = $page;
+		while ($curpage->post_parent != 0) {
+			$curpage = $wpdb->get_row("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = '$curpage->post_parent' and post_type='page'");
+			$path = '/' . $curpage->post_name . $path;
+		}
+
+		if ( $path == $full_path )
+			return get_page($page->ID, $output);
+	}
+
+	return NULL;
+}
+
+function get_page_by_title($page_title, $output = OBJECT) {
+	global $wpdb;
+	$page_title = $wpdb->escape($page_title);
+	$page = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_title = '$page_title' AND post_type='page'");
+	if ( $page )
+		return get_page($page, $output);
+
+	return NULL;
+}
+
+function &get_page_children($page_id, $pages) {
+	global $page_cache, $blog_id;
+
+	if ( empty($pages) )
+		$pages = &$page_cache[$blog_id];
+
+	$page_list = array();
+	foreach ( $pages as $page ) {
+		if ( $page->post_parent == $page_id ) {
+			$page_list[] = $page;
+			if ( $children = get_page_children($page->ID, $pages) )
+				$page_list = array_merge($page_list, $children);
+		}
+	}
+	return $page_list;
+}
+
+//fetches the pages returned as a FLAT list, but arranged in order of their hierarchy, i.e., child parents
+//immediately follow their parents
+function get_page_hierarchy($posts, $parent = 0) {
+	$result = array ( );
+	if ($posts) { foreach ($posts as $post) {
+		if ($post->post_parent == $parent) {
+			$result[$post->ID] = $post->post_name;
+			$children = get_page_hierarchy($posts, $post->ID);
+			$result += $children; //append $children to $result
+		}
+	} }
+	return $result;
+}
+
+function get_page_uri($page_id) {
+	$page = get_page($page_id);
+	$uri = urldecode($page->post_name);
+
+	// A page cannot be it's own parent.
+	if ( $page->post_parent == $page->ID )
+		return $uri;
+
+	while ($page->post_parent != 0) {
+		$page = get_page($page->post_parent);
+		$uri = urldecode($page->post_name) . "/" . $uri;
+	}
+
+	return $uri;
+}
+
+function &get_pages($args = '') {
+	global $wpdb;
+
+	if ( is_array($args) )
+		$r = &$args;
+	else
+		parse_str($args, $r);
+
+	$defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title',
+				'hierarchical' => 1, 'exclude' => '', 'include' => '', 'meta_key' => '', 'meta_value' => '', 'authors' => '');
+	$r = array_merge($defaults, $r);
+	extract($r, EXTR_SKIP);
+
+	$key = md5( serialize( $r ) );
+	if ( $cache = wp_cache_get( 'get_pages', 'page' ) )
+		if ( isset( $cache[ $key ] ) )
+			return apply_filters('get_pages', $cache[ $key ], $r );
+
+	$inclusions = '';
+	if ( !empty($include) ) {
+		$child_of = 0; //ignore child_of, exclude, meta_key, and meta_value params if using include 
+		$exclude = '';
+		$meta_key = '';
+		$meta_value = '';
+		$incpages = preg_split('/[\s,]+/',$include);
+		if ( count($incpages) ) {
+			foreach ( $incpages as $incpage ) {
+				if (empty($inclusions))
+					$inclusions = ' AND ( ID = ' . intval($incpage) . ' ';
+				else
+					$inclusions .= ' OR ID = ' . intval($incpage) . ' ';
+			}
+		}
+	}
+	if (!empty($inclusions))
+		$inclusions .= ')';
+
+	$exclusions = '';
+	if ( !empty($exclude) ) {
+		$expages = preg_split('/[\s,]+/',$exclude);
+		if ( count($expages) ) {
+			foreach ( $expages as $expage ) {
+				if (empty($exclusions))
+					$exclusions = ' AND ( ID <> ' . intval($expage) . ' ';
+				else
+					$exclusions .= ' AND ID <> ' . intval($expage) . ' ';
+			}
+		}
+	}
+	if (!empty($exclusions)) 
+		$exclusions .= ')';
+
+	$author_query = '';
+	if (!empty($authors)) {
+		$post_authors = preg_split('/[\s,]+/',$authors);
+
+		if ( count($post_authors) ) {
+			foreach ( $post_authors as $post_author ) {
+				//Do we have an author id or an author login?
+				if ( 0 == intval($post_author) ) {
+					$post_author = get_userdatabylogin($post_author);
+					if ( empty($post_author) )
+						continue;
+					if ( empty($post_author->ID) )
+						continue;
+					$post_author = $post_author->ID;
+				}
+
+				if ( '' == $author_query )
+					$author_query = ' post_author = ' . intval($post_author) . ' ';
+				else
+					$author_query .= ' OR post_author = ' . intval($post_author) . ' ';
+			}
+			if ( '' != $author_query )
+				$author_query = " AND ($author_query)";
+		}
+	}
+
+	$query = "SELECT * FROM $wpdb->posts " ;
+	$query .= ( empty( $meta_key ) ? "" : ", $wpdb->postmeta " ) ; 
+	$query .= " WHERE (post_type = 'page' AND post_status = 'publish') $exclusions $inclusions " ;
+	$query .= ( empty( $meta_key ) | empty($meta_value)  ? "" : " AND ($wpdb->posts.ID = $wpdb->postmeta.post_id AND $wpdb->postmeta.meta_key = '$meta_key' AND $wpdb->postmeta.meta_value = '$meta_value' )" ) ;
+	$query .= $author_query;
+	$query .= " ORDER BY " . $sort_column . " " . $sort_order ;
+
+	$pages = $wpdb->get_results($query);
+	$pages = apply_filters('get_pages', $pages, $r);
+
+	if ( empty($pages) )
+		return array();
+
+	// Update cache.
+	update_page_cache($pages);
+
+	if ( $child_of || $hierarchical )
+		$pages = & get_page_children($child_of, $pages);
+
+	$cache[ $key ] = $pages;
+	wp_cache_set( 'get_pages', $cache, 'page' );
+
+	return $pages;
+}
+
+function generate_page_uri_index() {
+	global $wpdb;
+
+	//get pages in order of hierarchy, i.e. children after parents
+	$posts = get_page_hierarchy($wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'page'"));
+	//now reverse it, because we need parents after children for rewrite rules to work properly
+	$posts = array_reverse($posts, true);
+
+	$page_uris = array();
+	$page_attachment_uris = array();
+
+	if ($posts) {
+
+		foreach ($posts as $id => $post) {
+
+			// URL => page name
+			$uri = get_page_uri($id);
+			$attachments = $wpdb->get_results("SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = '$id'");
+			if ( $attachments ) {
+				foreach ( $attachments as $attachment ) {
+					$attach_uri = get_page_uri($attachment->ID);
+					$page_attachment_uris[$attach_uri] = $attachment->ID;
+				}
+			}
+
+			$page_uris[$uri] = $id;
+		}
+
+		delete_option('page_uris');
+		update_option('page_uris', $page_uris);
+
+		if ( $page_attachment_uris ) {
+			delete_option('page_attachment_uris');
+			update_option('page_attachment_uris', $page_attachment_uris);
+		}
+	}
+}
+
+//
+// Attachment functions
+//
+
+function is_local_attachment($url) {
+	if (strpos($url, get_bloginfo('url')) === false)
+		return false;
+	if (strpos($url, get_bloginfo('url') . '/?attachment_id=') !== false)
+		return true;
+	if ( $id = url_to_postid($url) ) {
+		$post = & get_post($id);
+		if ( 'attachment' == $post->post_type )
+			return true;
+	}
+	return false;
+}
+
+function wp_insert_attachment($object, $file = false, $post_parent = 0) {
+	global $wpdb, $user_ID;
+
+	if ( is_object($object) )
+		$object = get_object_vars($object);
+
+	// Export array as variables
+	extract($object, EXTR_SKIP);
+
+	// Get the basics.
+	$post_content    = apply_filters('content_save_pre',   $post_content);
+	$post_content_filtered = apply_filters('content_filtered_save_pre',   $post_content_filtered);
+	$post_excerpt    = apply_filters('excerpt_save_pre',   $post_excerpt);
+	$post_title      = apply_filters('title_save_pre',     $post_title);
+	$post_category   = apply_filters('category_save_pre',  $post_category);
+	$post_name       = apply_filters('name_save_pre',      $post_name);
+	$comment_status  = apply_filters('comment_status_pre', $comment_status);
+	$ping_status     = apply_filters('ping_status_pre',    $ping_status);
+	$post_mime_type  = apply_filters('post_mime_type_pre', $post_mime_type);
+
+	// Make sure we set a valid category
+	if (0 == count($post_category) || !is_array($post_category)) {
+		$post_category = array(get_option('default_category'));
+	}
+	$post_cat = $post_category[0];
+
+	if ( empty($post_author) )
+		$post_author = $user_ID;
+
+	$post_type = 'attachment';
+	$post_status = 'inherit';
+
+	// Are we updating or creating?
+	$update = false;
+	if ( !empty($ID) ) {
+		$update = true;
+		$post_ID = (int) $ID;
+	}
+
+	// Create a valid post name.
+	if ( empty($post_name) )
+		$post_name = sanitize_title($post_title);
+	else
+		$post_name = sanitize_title($post_name);
+
+	$post_name_check =
+		$wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_status = 'inherit' AND ID != '$post_ID' LIMIT 1");
+
+	if ($post_name_check) {
+		$suffix = 2;
+		while ($post_name_check) {
+			$alt_post_name = $post_name . "-$suffix";
+			$post_name_check = $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$alt_post_name' AND post_status = 'inherit' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");
+			$suffix++;
+		}
+		$post_name = $alt_post_name;
+	}
+
+	if (empty($post_date))
+		$post_date = current_time('mysql');
+	if (empty($post_date_gmt))
+		$post_date_gmt = current_time('mysql', 1);
+
+	if ( empty($comment_status) ) {
+		if ( $update )
+			$comment_status = 'closed';
+		else
+			$comment_status = get_option('default_comment_status');
+	}
+	if ( empty($ping_status) )
+		$ping_status = get_option('default_ping_status');
+	if ( empty($post_pingback) )
+		$post_pingback = get_option('default_pingback_flag');
+
+	if ( isset($to_ping) )
+		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
+	else
+		$to_ping = '';
+
+	if ( isset($post_parent) )
+		$post_parent = (int) $post_parent;
+	else
+		$post_parent = 0;
+
+	if ( isset($menu_order) )
+		$menu_order = (int) $menu_order;
+	else
+		$menu_order = 0;
+
+	if ( !isset($post_password) )
+		$post_password = '';
+
+	if ( isset($to_ping) )
+		$to_ping = preg_replace('|\s+|', "\n", $to_ping);
+	else
+		$to_ping = '';
+
+	if ( ! isset($pinged) )
+		$pinged = '';
+
+	if ($update) {
+		$wpdb->query(
+			"UPDATE $wpdb->posts SET
+			post_author = '$post_author',
+			post_date = '$post_date',
+			post_date_gmt = '$post_date_gmt',
+			post_content = '$post_content',
+			post_content_filtered = '$post_content_filtered',
+			post_title = '$post_title',
+			post_excerpt = '$post_excerpt',
+			post_status = '$post_status',
+			post_type = '$post_type',
+			comment_status = '$comment_status',
+			ping_status = '$ping_status',
+			post_password = '$post_password',
+			post_name = '$post_name',
+			to_ping = '$to_ping',
+			pinged = '$pinged',
+			post_modified = '".current_time('mysql')."',
+			post_modified_gmt = '".current_time('mysql',1)."',
+			post_parent = '$post_parent',
+			menu_order = '$menu_order',
+			post_mime_type = '$post_mime_type',
+			guid = '$guid'
+			WHERE ID = $post_ID");
+	} else {
+		$wpdb->query(
+			"INSERT INTO $wpdb->posts
+			(post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt,  post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid)
+			VALUES
+			('$post_author', '$post_date', '$post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', '$post_status', '$post_type', '$comment_status', '$ping_status', '$post_password', '$post_name', '$to_ping', '$pinged', '$post_date', '$post_date_gmt', '$post_parent', '$menu_order', '$post_mime_type', '$guid')");
+			$post_ID = (int) $wpdb->insert_id;
+	}
+
+	if ( empty($post_name) ) {
+		$post_name = sanitize_title($post_title, $post_ID);
+		$wpdb->query( "UPDATE $wpdb->posts SET post_name = '$post_name' WHERE ID = '$post_ID'" );
+	}
+
+	wp_set_post_categories($post_ID, $post_category);
+
+	if ( $file )
+		update_attached_file( $post_ID, $file );
+
+	clean_post_cache($post_ID);
+
+	if ( $update) {
+		do_action('edit_attachment', $post_ID);
+	} else {
+		do_action('add_attachment', $post_ID);
+	}
+
+	return $post_ID;
+}
+
+function wp_delete_attachment($postid) {
+	global $wpdb;
+	$postid = (int) $postid;
+
+	if ( !$post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID = '$postid'") )
+		return $post;
+
+	if ( 'attachment' != $post->post_type )
+		return false;
+
+	$meta = wp_get_attachment_metadata( $postid );
+	$file = get_attached_file( $postid );
+
+	$wpdb->query("DELETE FROM $wpdb->posts WHERE ID = '$postid'");
+
+	$wpdb->query("DELETE FROM $wpdb->comments WHERE comment_post_ID = '$postid'");
+
+	$wpdb->query("DELETE FROM $wpdb->post2cat WHERE post_id = '$postid'");
+
+	$wpdb->query("DELETE FROM $wpdb->postmeta WHERE post_id = '$postid'");
+
+	if ( ! empty($meta['thumb']) ) {
+		// Don't delete the thumb if another attachment uses it
+		if (! $wpdb->get_row("SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE '%".$wpdb->escape($meta['thumb'])."%' AND post_id <> $postid")) {
+			$thumbfile = str_replace(basename($file), $meta['thumb'], $file);
+			$thumbfile = apply_filters('wp_delete_file', $thumbfile);
+			@ unlink($thumbfile);
+		}
+	}
+
+	$file = apply_filters('wp_delete_file', $file);
+
+	if ( ! empty($file) )
+		@ unlink($file);
+
+	do_action('delete_attachment', $postid);
+
+	return $post;
+}
+
+function wp_get_attachment_metadata( $post_id, $unfiltered = false ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+
+	$data = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
+	if ( $unfiltered )
+		return $data;
+	return apply_filters( 'wp_get_attachment_metadata', $data, $post->ID );
+}
+
+function wp_update_attachment_metadata( $post_id, $data ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+
+	$old_data = wp_get_attachment_metadata( $post->ID, true );
+
+	$data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID );
+
+	if ( $old_data )
+		return update_post_meta( $post->ID, '_wp_attachment_metadata', $data, $old_data );
+	else
+		return add_post_meta( $post->ID, '_wp_attachment_metadata', $data );
+}
+
+function wp_get_attachment_url( $post_id = 0 ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+
+	$url = get_the_guid( $post->ID );
+
+	if ( 'attachment' != $post->post_type || !$url )
+		return false;
+
+	return apply_filters( 'wp_get_attachment_url', $url, $post->ID );
+}
+
+function wp_get_attachment_thumb_file( $post_id = 0 ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+	if ( !$imagedata = wp_get_attachment_metadata( $post->ID ) )
+		return false;
+
+	$file = get_attached_file( $post->ID );
+
+	if ( !empty($imagedata['thumb']) && ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file)) && file_exists($thumbfile) )
+		return apply_filters( 'wp_get_attachment_thumb_file', $thumbfile, $post->ID );
+	return false;
+}
+
+function wp_get_attachment_thumb_url( $post_id = 0 ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+	if ( !$url = wp_get_attachment_url( $post->ID ) )
+		return false;
+
+	if ( !$thumb = wp_get_attachment_thumb_file( $post->ID ) )
+		return false;
+
+	$url = str_replace(basename($url), basename($thumb), $url);
+
+	return apply_filters( 'wp_get_attachment_thumb_url', $url, $post->ID );
+}
+
+function wp_attachment_is_image( $post_id = 0 ) {
+	$post_id = (int) $post_id;
+	if ( !$post =& get_post( $post_id ) )
+		return false;
+
+	if ( !$file = get_attached_file( $post->ID ) )
+		return false;
+
+	$ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false;
+
+	$image_exts = array('jpg', 'jpeg', 'gif', 'png');
+
+	if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )
+		return true;
+	return false;
+}
+
+function wp_mime_type_icon( $mime = 0 ) {
+	$post_id = 0;
+	if ( is_numeric($mime) ) {
+		$mime = (int) $mime;
+		if ( !$post =& get_post( $mime ) )
+			return false;
+		$post_id = (int) $post->ID;
+		$mime = $post->post_mime_type;
+	}
+
+	if ( empty($mime) )
+		return false;
+
+	$icon_dir = apply_filters( 'icon_dir', get_template_directory() . '/images' );
+	$icon_dir_uri = apply_filters( 'icon_dir_uri', get_template_directory_uri() . '/images' );
+
+	$types = array(
+		substr($mime, 0, strpos($mime, '/')),
+		substr($mime, strpos($mime, '/') + 1),
+		str_replace('/', '_', $mime)
+	);
+
+	$exts = array('jpg', 'gif', 'png');
+
+	$src = false;
+
+	foreach ( $types as $type ) {
+		foreach ( $exts as $ext ) {
+			$src_file = "$icon_dir/$type.$ext";
+			if ( file_exists($src_file) ) {
+				$src = "$icon_dir_uri/$type.$ext";
+				break 2;
+			}
+		}
+	}
+
+	return apply_filters( 'wp_mime_type_icon', $src, $mime, $post_id ); // Last arg is 0 if function pass mime type.
+}
+
+function wp_check_for_changed_slugs($post_id) {
+	if ( !strlen($_POST['wp-old-slug']) )
+		return $post_id;
+
+	$post = &get_post($post_id);
+
+	// we're only concerned with published posts
+	if ( $post->post_status != 'publish' || $post->post_type != 'post' )
+		return $post_id;
+
+	// only bother if the slug has changed
+	if ( $post->post_name == $_POST['wp-old-slug'] )
+		return $post_id;
+
+	$old_slugs = (array) get_post_meta($post_id, '_wp_old_slug');
+
+	// if we haven't added this old slug before, add it now
+	if ( !count($old_slugs) || !in_array($_POST['wp-old-slug'], $old_slugs) )
+		add_post_meta($post_id, '_wp_old_slug', $_POST['wp-old-slug']);
+
+	// if the new slug was used previously, delete it from the list
+	if ( in_array($post->post_name, $old_slugs) )
+		delete_post_meta($post_id, '_wp_old_slug', $post->post_name);
+
+	return $post_id;
+}
+
+/**
+ * This function provides a standardized way to appropriately select on
+ * the post_status of posts/pages. The function will return a piece of
+ * SQL code that can be added to a WHERE clause; this SQL is constructed
+ * to allow all published posts, and all private posts to which the user
+ * has access.
+ * 
+ * @param string $post_type currently only supports 'post' or 'page'.
+ * @return string SQL code that can be added to a where clause.
+ */
+function get_private_posts_cap_sql($post_type) {
+	global $user_ID;
+	$cap = '';
+
+	// Private posts
+	if ($post_type == 'post') {
+		$cap = 'read_private_posts';
+	// Private pages
+	} elseif ($post_type == 'page') {
+		$cap = 'read_private_pages';
+	// Dunno what it is, maybe plugins have their own post type?
+	} else {
+		$cap = apply_filters('pub_priv_sql_capability', $cap);
+
+		if (empty($cap)) {
+			// We don't know what it is, filters don't change anything,
+			// so set the SQL up to return nothing.
+			return '1 = 0';
+		}
+	}
+
+	$sql = '(post_status = \'publish\'';
+
+	if (current_user_can($cap)) {
+		// Does the user have the capability to view private posts? Guess so.
+		$sql .= ' OR post_status = \'private\'';
+	} elseif (is_user_logged_in()) {
+		// Users can view their own private posts.
+		$sql .= ' OR post_status = \'private\' AND post_author = \'' . $user_ID . '\'';
+	}
+
+	$sql .= ')';
+
+	return $sql;
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/query.php 2.2.2/wp-includes/query.php
--- 2.0.5/wp-includes/query.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/query.php	2007-04-25 13:54:29.000000000 -0500
@@ -0,0 +1,1319 @@
+<?php
+
+/*
+ * The Big Query.
+ */
+
+function get_query_var($var) {
+	global $wp_query;
+
+	return $wp_query->get($var);
+}
+
+function set_query_var($var, $value) {
+	global $wp_query;
+
+	return $wp_query->set($var, $value);
+}
+
+function &query_posts($query) {
+	unset($GLOBALS['wp_query']);
+	$GLOBALS['wp_query'] =& new WP_Query();
+	return $GLOBALS['wp_query']->query($query);
+}
+
+/*
+ * Query type checks.
+ */
+
+function is_admin () {
+	global $wp_query;
+
+	return ($wp_query->is_admin || (strpos($_SERVER['REQUEST_URI'], 'wp-admin/') !== false));
+}
+
+function is_archive () {
+	global $wp_query;
+
+	return $wp_query->is_archive;
+}
+
+function is_attachment () {
+	global $wp_query;
+
+	return $wp_query->is_attachment;
+}
+
+function is_author ($author = '') {
+	global $wp_query;
+
+	if ( !$wp_query->is_author )
+		return false;
+
+	if ( empty($author) )
+		return true;
+
+	$author_obj = $wp_query->get_queried_object();
+
+	if ( $author == $author_obj->ID )
+		return true;
+	elseif ( $author == $author_obj->nickname )
+		return true;
+	elseif ( $author == $author_obj->user_nicename )
+		return true;
+
+	return false;
+}
+
+function is_category ($category = '') {
+	global $wp_query;
+
+	if ( !$wp_query->is_category )
+		return false;
+
+	if ( empty($category) )
+		return true;
+
+	$cat_obj = $wp_query->get_queried_object();
+
+	if ( $category == $cat_obj->cat_ID )
+		return true;
+	else if ( $category == $cat_obj->cat_name )
+		return true;
+	elseif ( $category == $cat_obj->category_nicename )
+		return true;
+
+	return false;
+}
+
+function is_comments_popup () {
+	global $wp_query;
+
+	return $wp_query->is_comments_popup;
+}
+
+function is_date () {
+	global $wp_query;
+
+	return $wp_query->is_date;
+}
+
+function is_day () {
+	global $wp_query;
+
+	return $wp_query->is_day;
+}
+
+function is_feed () {
+	global $wp_query;
+
+	return $wp_query->is_feed;
+}
+
+function is_home () {
+	global $wp_query;
+
+	return $wp_query->is_home;
+}
+
+function is_month () {
+	global $wp_query;
+
+	return $wp_query->is_month;
+}
+
+function is_page ($page = '') {
+	global $wp_query;
+
+	if ( !$wp_query->is_page )
+		return false;
+
+	if ( empty($page) )
+		return true;
+
+	$page_obj = $wp_query->get_queried_object();
+
+	if ( $page == $page_obj->ID )
+		return true;
+	elseif ( $page == $page_obj->post_title )
+		return true;
+	else if ( $page == $page_obj->post_name )
+		return true;
+
+	return false;
+}
+
+function is_paged () {
+	global $wp_query;
+
+	return $wp_query->is_paged;
+}
+
+function is_plugin_page() {
+	global $plugin_page;
+
+	if ( isset($plugin_page) )
+		return true;
+
+	return false;
+}
+
+function is_preview() {
+	global $wp_query;
+
+	return $wp_query->is_preview;
+}
+
+function is_robots() {
+	global $wp_query;
+
+	return $wp_query->is_robots;
+}
+
+function is_search () {
+	global $wp_query;
+
+	return $wp_query->is_search;
+}
+
+function is_single ($post = '') {
+	global $wp_query;
+
+	if ( !$wp_query->is_single )
+		return false;
+
+	if ( empty( $post) )
+		return true;
+
+	$post_obj = $wp_query->get_queried_object();
+
+	if ( $post == $post_obj->ID )
+		return true;
+	elseif ( $post == $post_obj->post_title )
+		return true;
+	elseif ( $post == $post_obj->post_name )
+		return true;
+
+	return false;
+}
+
+function is_singular() {
+	global $wp_query;
+
+	return $wp_query->is_singular;
+}
+
+function is_time () {
+	global $wp_query;
+
+	return $wp_query->is_time;
+}
+
+function is_trackback () {
+	global $wp_query;
+
+	return $wp_query->is_trackback;
+}
+
+function is_year () {
+	global $wp_query;
+
+	return $wp_query->is_year;
+}
+
+function is_404 () {
+	global $wp_query;
+
+	return $wp_query->is_404;
+}
+
+/*
+ * The Loop.  Post loop control.
+ */
+
+function have_posts() {
+	global $wp_query;
+
+	return $wp_query->have_posts();
+}
+
+function in_the_loop() {
+	global $wp_query;
+
+	return $wp_query->in_the_loop;
+}
+
+function rewind_posts() {
+	global $wp_query;
+
+	return $wp_query->rewind_posts();
+}
+
+function the_post() {
+	global $wp_query;
+
+	$wp_query->the_post();
+}
+
+/*
+ * Comments loop. 
+ */ 
+
+function have_comments() { 
+	global $wp_query; 
+	return $wp_query->have_comments(); 
+} 
+
+function the_comment() { 
+	global $wp_query; 
+	return $wp_query->the_comment(); 
+}  
+
+/*
+ * WP_Query
+ */
+
+class WP_Query {
+	var $query;
+	var $query_vars = array();
+	var $queried_object;
+	var $queried_object_id;
+	var $request;
+
+	var $posts;
+	var $post_count = 0;
+	var $current_post = -1;
+	var $in_the_loop = false;
+	var $post;
+
+	var $comments;
+	var $comment_count = 0;
+	var $current_comment = -1;
+	var $comment;
+
+	var $found_posts = 0;
+	var $max_num_pages = 0;
+
+	var $is_single = false;
+	var $is_preview = false;
+	var $is_page = false;
+	var $is_archive = false;
+	var $is_date = false;
+	var $is_year = false;
+	var $is_month = false;
+	var $is_day = false;
+	var $is_time = false;
+	var $is_author = false;
+	var $is_category = false;
+	var $is_search = false;
+	var $is_feed = false;
+	var $is_comment_feed = false;
+	var $is_trackback = false;
+	var $is_home = false;
+	var $is_404 = false;
+	var $is_comments_popup = false;
+	var $is_admin = false;
+	var $is_attachment = false;
+	var $is_singular = false;
+	var $is_robots = false;
+	var $is_posts_page = false;
+
+	function init_query_flags() {
+		$this->is_single = false;
+		$this->is_page = false;
+		$this->is_archive = false;
+		$this->is_date = false;
+		$this->is_year = false;
+		$this->is_month = false;
+		$this->is_day = false;
+		$this->is_time = false;
+		$this->is_author = false;
+		$this->is_category = false;
+		$this->is_search = false;
+		$this->is_feed = false;
+		$this->is_comment_feed = false;
+		$this->is_trackback = false;
+		$this->is_home = false;
+		$this->is_404 = false;
+		$this->is_paged = false;
+		$this->is_admin = false;
+		$this->is_attachment = false;
+		$this->is_singular = false;
+		$this->is_robots = false;
+		$this->is_posts_page = false;
+	}
+
+	function init () {
+		unset($this->posts);
+		unset($this->query);
+		$this->query_vars = array();
+		unset($this->queried_object);
+		unset($this->queried_object_id);
+		$this->post_count = 0;
+		$this->current_post = -1;
+		$this->in_the_loop = false;
+
+		$this->init_query_flags();
+	}
+
+	// Reparse the query vars.
+	function parse_query_vars() {
+		$this->parse_query('');
+	}
+
+	function fill_query_vars($array) {
+		$keys = array(
+			'error'
+			, 'm'
+			, 'p'
+			, 'subpost'
+			, 'subpost_id'
+			, 'attachment'
+			, 'attachment_id'
+			, 'name'
+			, 'hour'
+			, 'static'
+			, 'pagename'
+			, 'page_id'
+			, 'second'
+			, 'minute'
+			, 'hour'
+			, 'day'
+			, 'monthnum'
+			, 'year'
+			, 'w'
+			, 'category_name'
+			, 'author_name'
+			, 'feed'
+			, 'tb'
+			, 'paged'
+			, 'comments_popup'
+			, 'preview'
+		);
+
+		foreach ($keys as $key) {
+			if ( !isset($array[$key]))
+				$array[$key] = '';
+		}
+
+		return $array;
+	}
+
+	// Parse a query string and set query type booleans.
+	function parse_query ($query) {
+		if ( !empty($query) || !isset($this->query) ) {
+			$this->init();
+			if ( is_array($query) )
+				$this->query_vars = $query;
+			else
+				parse_str($query, $this->query_vars);
+			$this->query = $query;
+		}
+
+		$this->query_vars = $this->fill_query_vars($this->query_vars);
+		$qv = &$this->query_vars;
+
+		if ( ! empty($qv['robots']) ) {
+			$this->is_robots = true;
+			return;
+		}
+
+		if ('404' == $qv['error']) {
+			$this->is_404 = true;
+			if ( !empty($query) ) {
+				do_action_ref_array('parse_query', array(&$this));
+			}
+			return;
+		}
+
+		$qv['p'] =  (int) $qv['p'];
+		$qv['page_id'] =  (int) $qv['page_id'];
+		$qv['year'] = (int) $qv['year'];
+		$qv['monthnum'] = (int) $qv['monthnum'];
+		$qv['day'] = (int) $qv['day'];
+		$qv['w'] = (int) $qv['w'];
+		$qv['m'] =  (int) $qv['m'];
+		if ( '' != $qv['hour'] ) $qv['hour'] = (int) $qv['hour'];
+		if ( '' != $qv['minute'] ) $qv['minute'] = (int) $qv['minute'];
+		if ( '' != $qv['second'] ) $qv['second'] = (int) $qv['second'];
+
+		// Compat.  Map subpost to attachment.
+		if ( '' != $qv['subpost'] )
+			$qv['attachment'] = $qv['subpost'];
+		if ( '' != $qv['subpost_id'] )
+			$qv['attachment_id'] = $qv['subpost_id'];
+
+		$qv['attachment_id'] = (int) $qv['attachment_id'];
+		
+		if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) {
+			$this->is_single = true;
+			$this->is_attachment = true;
+		} elseif ( '' != $qv['name'] ) {
+			$this->is_single = true;
+		} elseif ( $qv['p'] ) {
+			$this->is_single = true;
+		} elseif ( ('' != $qv['hour']) && ('' != $qv['minute']) &&('' != $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) {
+			// If year, month, day, hour, minute, and second are set, a single
+			// post is being queried.
+			$this->is_single = true;
+		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
+			$this->is_page = true;
+			$this->is_single = false;
+		} elseif ( !empty($qv['s']) ) {
+			$this->is_search = true;
+		} else {
+		// Look for archive queries.  Dates, categories, authors.
+
+			if ( '' != $qv['second'] ) {
+				$this->is_time = true;
+				$this->is_date = true;
+			}
+
+			if ( '' != $qv['minute'] ) {
+				$this->is_time = true;
+				$this->is_date = true;
+			}
+
+			if ( '' != $qv['hour'] ) {
+				$this->is_time = true;
+				$this->is_date = true;
+			}
+
+			if ( $qv['day'] ) {
+				if (! $this->is_date) {
+					$this->is_day = true;
+					$this->is_date = true;
+				}
+			}
+
+			if ( $qv['monthnum'] ) {
+				if (! $this->is_date) {
+					$this->is_month = true;
+					$this->is_date = true;
+				}
+			}
+
+			if ( $qv['year'] ) {
+				if (! $this->is_date) {
+					$this->is_year = true;
+					$this->is_date = true;
+				}
+			}
+
+			if ( $qv['m'] ) {
+				$this->is_date = true;
+				if (strlen($qv['m']) > 9) {
+					$this->is_time = true;
+				} else if (strlen($qv['m']) > 7) {
+					$this->is_day = true;
+				} else if (strlen($qv['m']) > 5) {
+					$this->is_month = true;
+				} else {
+					$this->is_year = true;
+				}
+			}
+
+			if ('' != $qv['w']) {
+				$this->is_date = true;
+			}
+
+			if ( empty($qv['cat']) || ($qv['cat'] == '0') ) {
+				$this->is_category = false;
+			} else {
+				if (strpos($qv['cat'], '-') !== false) {
+					$this->is_category = false;
+				} else {
+					$this->is_category = true;
+				}
+			}
+
+			if ( '' != $qv['category_name'] ) {
+				$this->is_category = true;
+			}
+
+			if ( empty($qv['author']) || ($qv['author'] == '0') ) {
+				$this->is_author = false;
+			} else {
+				$this->is_author = true;
+			}
+
+			if ( '' != $qv['author_name'] ) {
+				$this->is_author = true;
+			}
+
+			if ( ($this->is_date || $this->is_author || $this->is_category) )
+				$this->is_archive = true;
+		}
+
+		if ( '' != $qv['feed'] )
+			$this->is_feed = true;
+
+		if ( '' != $qv['tb'] )
+			$this->is_trackback = true;
+
+		if ( '' != $qv['paged'] )
+			$this->is_paged = true;
+
+		if ( '' != $qv['comments_popup'] )
+			$this->is_comments_popup = true;
+
+		// if we're previewing inside the write screen
+		if ('' != $qv['preview'])
+			$this->is_preview = true;
+
+		if ( strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false )
+			$this->is_admin = true;
+
+		if ( false !== strpos($qv['feed'], 'comments-') ) {
+			$qv['feed'] = str_replace('comments-', '', $qv['feed']);
+			$qv['withcomments'] = 1;
+		}
+
+		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
+
+		if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) )
+			$this->is_comment_feed = true;
+
+		if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup ) )
+			$this->is_home = true;
+
+		// Correct is_* for page_on_front and page_for_posts
+		if ( $this->is_home && ( empty($this->query) || $qv['preview'] == 'true' ) && 'page' == get_option('show_on_front') && get_option('page_on_front') ) {
+			$this->is_page = true;
+			$this->is_home = false;
+			$qv['page_id'] = get_option('page_on_front');
+		}
+
+		if ( '' != $qv['pagename'] ) {
+			$this->queried_object =& get_page_by_path($qv['pagename']);
+			if ( !empty($this->queried_object) )
+				$this->queried_object_id = (int) $this->queried_object->ID;
+			else
+				unset($this->queried_object);
+
+			if  ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) {
+				$this->is_page = false;
+				$this->is_home = true;
+				$this->is_posts_page = true;
+			}
+		}
+
+		if ( $qv['page_id'] ) {
+			if  ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) {
+				$this->is_page = false;
+				$this->is_home = true;
+				$this->is_posts_page = true;
+			}
+		}
+
+		if ( $this->is_posts_page && !$qv['withcomments'] )
+			$this->is_comment_feed = false;
+
+		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
+		// Done correcting is_* for page_on_front and page_for_posts
+
+		if ( !empty($query) )
+			do_action_ref_array('parse_query', array(&$this));
+	}
+
+	function set_404() {
+		$is_feed = $this->is_feed;
+
+		$this->init_query_flags();
+		$this->is_404 = true;
+
+		$this->is_feed = $is_feed;
+	}
+
+	function get($query_var) {
+		if (isset($this->query_vars[$query_var])) {
+			return $this->query_vars[$query_var];
+		}
+
+		return '';
+	}
+
+	function set($query_var, $value) {
+		$this->query_vars[$query_var] = $value;
+	}
+
+	function &get_posts() {
+		global $wpdb, $pagenow, $user_ID;
+
+		do_action_ref_array('pre_get_posts', array(&$this));
+
+		// Shorthand.
+		$q = &$this->query_vars;
+
+		$q = $this->fill_query_vars($q);
+
+		// First let's clear some variables
+		$distinct = '';
+		$whichcat = '';
+		$whichauthor = '';
+		$whichpage = '';
+		$result = '';
+		$where = '';
+		$limits = '';
+		$join = '';
+		$search = '';
+		$groupby = '';
+
+		if ( !isset($q['post_type']) )
+			$q['post_type'] = 'post';
+		$post_type = $q['post_type'];
+		if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
+			$q['posts_per_page'] = get_option('posts_per_page');
+		if ( isset($q['showposts']) && $q['showposts'] ) {
+			$q['showposts'] = (int) $q['showposts'];
+			$q['posts_per_page'] = $q['showposts'];
+		}
+		if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
+			$q['posts_per_page'] = $q['posts_per_archive_page'];
+		if ( !isset($q['nopaging']) ) {
+			if ($q['posts_per_page'] == -1) {
+				$q['nopaging'] = true;
+			} else {
+				$q['nopaging'] = false;
+			}
+		}
+		if ( $this->is_feed ) {
+			$q['posts_per_page'] = get_option('posts_per_rss');
+			$q['nopaging'] = false;
+		}
+		$q['posts_per_page'] = (int) $q['posts_per_page'];
+		if ( $q['posts_per_page'] < -1 )
+			$q['posts_per_page'] = abs($q['posts_per_page']);
+		else if ( $q['posts_per_page'] == 0 )
+			$q['posts_per_page'] = 1;
+
+		if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
+			$this->is_page = true;
+			$this->is_home = false;
+			$q['page_id'] = get_option('page_on_front');
+		}
+
+		if (isset($q['page'])) {
+			$q['page'] = trim($q['page'], '/');
+			$q['page'] = (int) $q['page'];
+			$q['page'] = abs($q['page']);
+		}
+
+		$add_hours = intval(get_option('gmt_offset'));
+		$add_minutes = intval(60 * (get_option('gmt_offset') - $add_hours));
+		$wp_posts_post_date_field = "post_date"; // "DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)";
+
+		// If a month is specified in the querystring, load that month
+		if ( $q['m'] ) {
+			$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
+			$where .= ' AND YEAR(post_date)=' . substr($q['m'], 0, 4);
+			if (strlen($q['m'])>5)
+				$where .= ' AND MONTH(post_date)=' . substr($q['m'], 4, 2);
+			if (strlen($q['m'])>7)
+				$where .= ' AND DAYOFMONTH(post_date)=' . substr($q['m'], 6, 2);
+			if (strlen($q['m'])>9)
+				$where .= ' AND HOUR(post_date)=' . substr($q['m'], 8, 2);
+			if (strlen($q['m'])>11)
+				$where .= ' AND MINUTE(post_date)=' . substr($q['m'], 10, 2);
+			if (strlen($q['m'])>13)
+				$where .= ' AND SECOND(post_date)=' . substr($q['m'], 12, 2);
+		}
+
+		if ( '' != $q['hour'] )
+			$where .= " AND HOUR(post_date)='" . $q['hour'] . "'";
+
+		if ( '' != $q['minute'] )
+			$where .= " AND MINUTE(post_date)='" . $q['minute'] . "'";
+
+		if ( '' != $q['second'] )
+			$where .= " AND SECOND(post_date)='" . $q['second'] . "'";
+
+		if ( $q['year'] )
+			$where .= " AND YEAR(post_date)='" . $q['year'] . "'";
+
+		if ( $q['monthnum'] )
+			$where .= " AND MONTH(post_date)='" . $q['monthnum'] . "'";
+
+		if ( $q['day'] )
+			$where .= " AND DAYOFMONTH(post_date)='" . $q['day'] . "'";
+
+		if ('' != $q['name']) {
+			$q['name'] = sanitize_title($q['name']);
+			$where .= " AND post_name = '" . $q['name'] . "'";
+		} else if ('' != $q['pagename']) {
+			if ( isset($this->queried_object_id) )
+				$reqpage = $this->queried_object_id;
+			else {
+				$reqpage = get_page_by_path($q['pagename']);
+				if ( !empty($reqpage) )
+					$reqpage = $reqpage->ID;
+				else
+					$reqpage = 0;
+			}
+
+			if  ( ('page' != get_option('show_on_front') ) || ( $reqpage != get_option('page_for_posts') ) ) {
+				$q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename'])));
+				$page_paths = '/' . trim($q['pagename'], '/');
+				$q['pagename'] = sanitize_title(basename($page_paths));
+				$q['name'] = $q['pagename'];
+				$where .= " AND (ID = '$reqpage')";
+			}
+		} elseif ('' != $q['attachment']) {
+			$q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment'])));
+			$attach_paths = '/' . trim($q['attachment'], '/');
+			$q['attachment'] = sanitize_title(basename($attach_paths));
+			$q['name'] = $q['attachment'];
+			$where .= " AND post_name = '" . $q['attachment'] . "'";
+		}
+
+		if ( $q['w'] )
+			$where .= " AND WEEK(post_date, 1)='" . $q['w'] . "'";
+
+		if ( intval($q['comments_popup']) )
+			$q['p'] = intval($q['comments_popup']);
+
+		// If an attachment is requested by number, let it supercede any post number.
+		if ( $q['attachment_id'] )
+			$q['p'] = $q['attachment_id'];
+
+		// If a post number is specified, load that post
+		if ( $q['p'] )
+			$where = ' AND ID = ' . $q['p'];
+
+		if ( $q['page_id'] ) {
+			if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
+				$q['p'] = $q['page_id'];
+				$where = ' AND ID = ' . $q['page_id'];
+			}
+		}
+
+		// If a search pattern is specified, load the posts that match
+		if ( !empty($q['s']) ) {
+			// added slashes screw with quote grouping when done early, so done later
+			$q['s'] = stripslashes($q['s']);
+			if ($q['sentence']) {
+				$q['search_terms'] = array($q['s']);
+			}
+			else {
+				preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q[s], $matches);
+				$q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
+			}
+			$n = ($q['exact']) ? '' : '%';
+			$searchand = '';
+			foreach((array)$q['search_terms'] as $term) {
+				$term = addslashes_gpc($term);
+				$search .= "{$searchand}((post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}'))";
+				$searchand = ' AND ';
+			}
+			$term = addslashes_gpc($q['s']); 
+			if (!$q['sentence'] && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] )
+				$search .= " OR (post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}')";
+
+			if ( !empty($search) )
+				$search = " AND ({$search}) ";
+		}
+
+		// Category stuff
+
+		if ( empty($q['cat']) || ($q['cat'] == '0') ||
+				// Bypass cat checks if fetching specific posts
+				$this->is_singular ) {
+			$whichcat = '';
+		} else {
+			$q['cat'] = ''.urldecode($q['cat']).'';
+			$q['cat'] = addslashes_gpc($q['cat']);
+			$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) ";
+			$cat_array = preg_split('/[,\s]+/', $q['cat']);
+			$in_cats = $out_cats = $out_posts = '';
+			foreach ( $cat_array as $cat ) {
+				$cat = intval($cat);
+				$in = (strpos($cat, '-') !== false) ? false : true;
+				$cat = trim($cat, '-');
+				if ( $in )
+					$in_cats .= "$cat, " . get_category_children($cat, '', ', ');
+				else
+					$out_cats .= "$cat, " . get_category_children($cat, '', ', ');
+			}
+			$in_cats = substr($in_cats, 0, -2);
+			$out_cats = substr($out_cats, 0, -2);
+			if ( strlen($in_cats) > 0 )
+				$in_cats = " AND $wpdb->post2cat.category_id IN ($in_cats)";
+			if ( strlen($out_cats) > 0 ) {
+				$ids = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE $wpdb->post2cat.category_id IN ($out_cats)");
+				if ( is_array($ids) && count($ids > 0) ) {
+					foreach ( $ids as $id )
+						$out_posts .= "$id, ";
+					$out_posts = substr($out_posts, 0, -2);
+				}
+				if ( strlen($out_posts) > 0 )
+					$out_cats = " AND $wpdb->posts.ID NOT IN ($out_posts)";
+				else
+					$out_cats = '';
+			}
+			$whichcat = $in_cats . $out_cats;
+			$groupby = "{$wpdb->posts}.ID";
+		}
+
+		// Category stuff for nice URLs
+		if ( '' != $q['category_name'] ) {
+			$reqcat = get_category_by_path($q['category_name']);
+			$q['category_name'] = str_replace('%2F', '/', urlencode(urldecode($q['category_name'])));
+			$cat_paths = '/' . trim($q['category_name'], '/');
+			$q['category_name'] = sanitize_title(basename($cat_paths));
+
+			$cat_paths = '/' . trim(urldecode($q['category_name']), '/');
+			$q['category_name'] = sanitize_title(basename($cat_paths));
+			$cat_paths = explode('/', $cat_paths);
+			$cat_path = '';
+			foreach ( (array) $cat_paths as $pathdir )
+				$cat_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir);
+
+			//if we don't match the entire hierarchy fallback on just matching the nicename
+			if ( empty($reqcat) )
+				$reqcat = get_category_by_path($q['category_name'], false);
+
+			if ( !empty($reqcat) )
+				$reqcat = $reqcat->cat_ID;
+			else
+				$reqcat = 0;
+
+			$q['cat'] = $reqcat;
+
+			$tables = ", $wpdb->post2cat, $wpdb->categories";
+			$join = " LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) LEFT JOIN $wpdb->categories ON ($wpdb->post2cat.category_id = $wpdb->categories.cat_ID) ";
+			$whichcat = " AND category_id IN ({$q['cat']}, ";
+			$whichcat .= get_category_children($q['cat'], '', ', ');
+			$whichcat = substr($whichcat, 0, -2);
+			$whichcat .= ")";
+			$groupby = "{$wpdb->posts}.ID";
+		}
+
+
+
+		// Author/user stuff
+
+		if ( empty($q['author']) || ($q['author'] == '0') ) {
+			$whichauthor='';
+		} else {
+			$q['author'] = ''.urldecode($q['author']).'';
+			$q['author'] = addslashes_gpc($q['author']);
+			if (strpos($q['author'], '-') !== false) {
+				$eq = '!=';
+				$andor = 'AND';
+				$q['author'] = explode('-', $q['author']);
+				$q['author'] = ''.intval($q['author'][1]);
+			} else {
+				$eq = '=';
+				$andor = 'OR';
+			}
+			$author_array = preg_split('/[,\s]+/', $q['author']);
+			$whichauthor .= ' AND (post_author '.$eq.' '.intval($author_array[0]);
+			for ($i = 1; $i < (count($author_array)); $i = $i + 1) {
+				$whichauthor .= ' '.$andor.' post_author '.$eq.' '.intval($author_array[$i]);
+			}
+			$whichauthor .= ')';
+		}
+
+		// Author stuff for nice URLs
+
+		if ('' != $q['author_name']) {
+			if (strpos($q['author_name'], '/') !== false) {
+				$q['author_name'] = explode('/',$q['author_name']);
+				if ($q['author_name'][count($q['author_name'])-1]) {
+					$q['author_name'] = $q['author_name'][count($q['author_name'])-1];#no trailing slash
+				} else {
+					$q['author_name'] = $q['author_name'][count($q['author_name'])-2];#there was a trailling slash
+				}
+			}
+			$q['author_name'] = sanitize_title($q['author_name']);
+			$q['author'] = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_nicename='".$q['author_name']."'");
+			$whichauthor .= ' AND (post_author = '.intval($q['author']).')';
+		}
+
+		$where .= $search.$whichcat.$whichauthor;
+
+		if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
+			$q['order'] = 'DESC';
+
+		// Order by
+		if ( empty($q['orderby']) ) {
+			$q['orderby'] = 'post_date '.$q['order'];
+		} else {
+			// Used to filter values
+			$allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order');
+			$q['orderby'] = urldecode($q['orderby']);
+			$q['orderby'] = addslashes_gpc($q['orderby']);
+			$orderby_array = explode(' ',$q['orderby']);
+			if ( empty($orderby_array) )
+				$orderby_array[] = $q['orderby'];
+			$q['orderby'] = '';
+			for ($i = 0; $i < count($orderby_array); $i++) {
+				// Only allow certain values for safety
+				$orderby = $orderby_array[$i];
+				if ( 'menu_order' != $orderby )
+					$orderby = 'post_' . $orderby;
+				if ( in_array($orderby_array[$i], $allowed_keys) )
+					$q['orderby'] .= (($i == 0) ? '' : ',') . "$orderby {$q['order']}";
+			}
+			if ( empty($q['orderby']) )
+				$q['orderby'] = 'post_date '.$q['order'];
+		}
+
+		if ( $this->is_attachment ) {
+			$where .= " AND (post_type = 'attachment')";
+		} elseif ($this->is_page) {
+			$where .= " AND (post_type = 'page')";
+		} elseif ($this->is_single) {
+			$where .= " AND (post_type = 'post')";
+		} else {
+			$where .= " AND (post_type = '$post_type' AND (post_status = 'publish'";
+
+			if ( is_admin() )
+				$where .= " OR post_status = 'future' OR post_status = 'draft'";
+
+			if ( is_user_logged_in() ) {
+				if ( 'post' == $post_type )
+					$cap = 'read_private_posts';
+				else
+					$cap = 'read_private_pages';
+
+				if ( current_user_can($cap) )
+					$where .= " OR post_status = 'private'";
+				else
+				$where .= " OR post_author = $user_ID AND post_status = 'private'";
+			}
+
+			$where .= '))';
+		}
+
+		// Apply filters on where and join prior to paging so that any
+		// manipulations to them are reflected in the paging by day queries.
+		$where = apply_filters('posts_where', $where);
+		$join = apply_filters('posts_join', $join);
+
+		// Paging
+		if ( empty($q['nopaging']) && !$this->is_singular ) {
+			$page = abs(intval($q['paged']));
+			if (empty($page)) {
+				$page = 1;
+			}
+
+			if ( empty($q['offset']) ) {
+				$pgstrt = '';
+				$pgstrt = (intval($page) -1) * $q['posts_per_page'] . ', ';
+				$limits = 'LIMIT '.$pgstrt.$q['posts_per_page'];
+			} else { // we're ignoring $page and using 'offset'
+				$q['offset'] = abs(intval($q['offset']));
+				$pgstrt = $q['offset'] . ', ';
+				$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
+			}
+		}
+
+		// Comments feeds
+		if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) {
+			if ( $this->is_archive || $this->is_search ) {
+				$cjoin = "LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join ";
+				$cwhere = "WHERE comment_approved = '1' $where";
+				$cgroupby = "GROUP BY $wpdb->comments.comment_id";
+			} else { // Other non singular e.g. front
+				$cjoin = "LEFT JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )";
+				$cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'";
+				$cgroupby = '';
+			}
+
+			$cjoin = apply_filters('comment_feed_join', $cjoin);
+			$cwhere = apply_filters('comment_feed_where', $cwhere);
+			$cgroupby = apply_filters('comment_feed_groupby', $cgroupby);
+
+			$this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby ORDER BY comment_date_gmt DESC LIMIT " . get_option('posts_per_rss'));
+			$this->comment_count = count($this->comments);
+
+			$post_ids = array();
+
+			foreach ($this->comments as $comment)
+				$post_ids[] = (int) $comment->comment_post_ID;
+
+			$post_ids = join(',', $post_ids);
+			$join = '';
+			if ( $post_ids )
+				$where = "AND $wpdb->posts.ID IN ($post_ids) ";
+			else
+				$where = "AND 0";
+		}
+
+		// Apply post-paging filters on where and join.  Only plugins that
+		// manipulate paging queries should use these hooks.
+		$where = apply_filters('posts_where_paged', $where);
+		$groupby = apply_filters('posts_groupby', $groupby);
+		if ( ! empty($groupby) )
+			$groupby = 'GROUP BY ' . $groupby;
+		$join = apply_filters('posts_join_paged', $join);
+		$orderby = apply_filters('posts_orderby', $q['orderby']);
+		$distinct = apply_filters('posts_distinct', $distinct);
+		$fields = apply_filters('posts_fields', "$wpdb->posts.*");
+		$limits = apply_filters( 'post_limits', $limits );
+		$found_rows = '';
+		if ( !empty($limits) )
+			$found_rows = 'SQL_CALC_FOUND_ROWS';
+
+		$request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby ORDER BY $orderby $limits";
+		$this->request = apply_filters('posts_request', $request);
+
+		$this->posts = $wpdb->get_results($this->request);
+
+		if ( $this->is_comment_feed && $this->is_singular ) {
+			$cjoin = apply_filters('comment_feed_join', '');
+			$cwhere = apply_filters('comment_feed_where', "WHERE comment_post_ID = {$this->posts[0]->ID} AND comment_approved = '1'");
+			$comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere ORDER BY comment_date_gmt DESC LIMIT " . get_option('posts_per_rss');
+			$this->comments = $wpdb->get_results($comments_request);
+			$this->comment_count = count($this->comments);
+		}
+
+		if ( !empty($limits) ) {
+			$found_posts_query = apply_filters( 'found_posts_query', 'SELECT FOUND_ROWS()' );
+			$this->found_posts = $wpdb->get_var( $found_posts_query );
+			$this->found_posts = apply_filters( 'found_posts', $this->found_posts );
+			$this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']);
+		}
+
+		// Check post status to determine if post should be displayed.
+		if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
+			$status = get_post_status($this->posts[0]);
+			//$type = get_post_type($this->posts[0]);
+			if ( ('publish' != $status) ) {
+				if ( ! is_user_logged_in() ) {
+					// User must be logged in to view unpublished posts.
+					$this->posts = array();
+				} else {
+					if ('draft' == $status) {
+						// User must have edit permissions on the draft to preview.
+						if (! current_user_can('edit_post', $this->posts[0]->ID)) {
+							$this->posts = array();
+						} else {
+							$this->is_preview = true;
+							$this->posts[0]->post_date = current_time('mysql');
+						}
+					}  else if ('future' == $status) {
+						$this->is_preview = true;
+						if (!current_user_can('edit_post', $this->posts[0]->ID)) {
+							$this->posts = array ( );
+						}
+					} else {
+						if (! current_user_can('read_post', $this->posts[0]->ID))
+							$this->posts = array();
+					}
+				}
+			}
+		}
+
+		$this->posts = apply_filters('the_posts', $this->posts);
+
+		update_post_caches($this->posts);
+
+		$this->post_count = count($this->posts);
+		if ($this->post_count > 0) {
+			$this->post = $this->posts[0];
+		}
+
+		return $this->posts;
+	}
+
+	function next_post() {
+
+		$this->current_post++;
+
+		$this->post = $this->posts[$this->current_post];
+		return $this->post;
+	}
+
+	function the_post() {
+		global $post;
+		$this->in_the_loop = true;
+		$post = $this->next_post();
+		setup_postdata($post);
+
+		if ( $this->current_post == 0 ) // loop has just started
+			do_action('loop_start');
+	}
+
+	function have_posts() {
+		if ($this->current_post + 1 < $this->post_count) {
+			return true;
+		} elseif ($this->current_post + 1 == $this->post_count) {
+			do_action('loop_end');
+			// Do some cleaning up after the loop
+			$this->rewind_posts();
+		}
+
+		$this->in_the_loop = false;
+		return false;
+	}
+
+	function rewind_posts() {
+		$this->current_post = -1;
+		if ($this->post_count > 0) {
+			$this->post = $this->posts[0];
+		}
+	}
+
+	function next_comment() {
+		$this->current_comment++;
+
+		$this->comment = $this->comments[$this->current_comment];
+		return $this->comment;
+	}
+
+	function the_comment() {
+		global $comment;
+
+		$comment = $this->next_comment();
+
+		if ($this->current_comment == 0) {
+			do_action('comment_loop_start');
+		}
+	}
+
+	function have_comments() {
+		if ($this->current_comment + 1 < $this->comment_count) {
+			return true;
+		} elseif ($this->current_comment + 1 == $this->comment_count) {
+			$this->rewind_comments();
+		}
+
+		return false;
+	}
+
+	function rewind_comments() {
+		$this->current_comment = -1;
+		if ($this->comment_count > 0) {
+			$this->comment = $this->comments[0];
+		}
+	}
+
+	function &query($query) {
+		$this->parse_query($query);
+		return $this->get_posts();
+	}
+
+	function get_queried_object() {
+		if (isset($this->queried_object)) {
+			return $this->queried_object;
+		}
+
+		$this->queried_object = NULL;
+		$this->queried_object_id = 0;
+
+		if ($this->is_category) {
+			$cat = $this->get('cat');
+			$category = &get_category($cat);
+			$this->queried_object = &$category;
+			$this->queried_object_id = (int) $cat;
+		} else if ($this->is_posts_page) {
+			$this->queried_object = & get_page(get_option('page_for_posts'));
+			$this->queried_object_id = (int) $this->queried_object->ID;
+		} else if ($this->is_single) {
+			$this->queried_object = $this->post;
+			$this->queried_object_id = (int) $this->post->ID;
+		} else if ($this->is_page) {
+			$this->queried_object = $this->post;
+			$this->queried_object_id = (int) $this->post->ID;
+		} else if ($this->is_author) {
+			$author_id = (int) $this->get('author');
+			$author = get_userdata($author_id);
+			$this->queried_object = $author;
+			$this->queried_object_id = $author_id;
+		}
+
+		return $this->queried_object;
+	}
+
+	function get_queried_object_id() {
+		$this->get_queried_object();
+
+		if (isset($this->queried_object_id)) {
+			return $this->queried_object_id;
+		}
+
+		return 0;
+	}
+
+	function WP_Query ($query = '') {
+		if (! empty($query)) {
+			$this->query($query);
+		}
+	}
+}
+
+
+// Redirect old slugs
+function wp_old_slug_redirect () {
+	global $wp_query;
+	if ( is_404() && '' != $wp_query->query_vars['name'] ) :
+		global $wpdb;
+
+		$query = "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value='" . $wp_query->query_vars['name'] . "'";
+
+		// if year, monthnum, or day have been specified, make our query more precise
+		// just in case there are multiple identical _wp_old_slug values
+		if ( '' != $wp_query->query_vars['year'] )
+			$query .= " AND YEAR(post_date) = '{$wp_query->query_vars['year']}'";
+		if ( '' != $wp_query->query_vars['monthnum'] )
+			$query .= " AND MONTH(post_date) = '{$wp_query->query_vars['monthnum']}'";
+		if ( '' != $wp_query->query_vars['day'] )
+			$query .= " AND DAYOFMONTH(post_date) = '{$wp_query->query_vars['day']}'";
+
+		$id = (int) $wpdb->get_var($query);
+
+		if ( !$id )
+			return;
+
+		$link = get_permalink($id);
+
+		if ( !$link )
+			return;
+
+		wp_redirect($link, '301'); // Permanent redirect
+		exit;
+	endif;
+}
+
+
+//
+// Private helper functions
+//
+
+// Setup global post data.
+function setup_postdata($post) {
+	global $id, $postdata, $authordata, $day, $page, $pages, $multipage, $more, $numpages, $wp_query;
+	global $pagenow;
+
+	$id = (int) $post->ID;
+
+	$authordata = get_userdata($post->post_author);
+
+	$day = mysql2date('d.m.y', $post->post_date);
+	$currentmonth = mysql2date('m', $post->post_date);
+	$numpages = 1;
+	$page = get_query_var('page');
+	if ( !$page )
+		$page = 1;
+	if ( is_single() || is_page() )
+		$more = 1;
+	$content = $post->post_content;
+	if ( preg_match('/<!--nextpage-->/', $content) ) {
+		if ( $page > 1 )
+			$more = 1;
+		$multipage = 1;
+		$content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content);
+		$content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content);
+		$content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content);
+		$pages = explode('<!--nextpage-->', $content);
+		$numpages = count($pages);
+	} else {
+		$pages[0] = $post->post_content;
+		$multipage = 0;
+	}
+	return true;
+}
+
+?>
diff -ruN 2.0.5/wp-includes/registration-functions.php 2.2.2/wp-includes/registration-functions.php
--- 2.0.5/wp-includes/registration-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/registration-functions.php	2007-05-04 16:48:43.000000000 -0500
@@ -1,170 +1,4 @@
 <?php
-
-function username_exists( $username ) {
-	global $wpdb;
-	$username = sanitize_user( $username );
-	$user = get_userdatabylogin($username);
-	if ( $user )
-		return $user->ID;
-
-	return null;
-}
-
-function validate_username( $username ) {
-	$name = sanitize_user($username, true);
-	$valid = true;
-
-	if ( $name != $username )
-		$valid = false;	
-
-	return apply_filters('validate_username', $valid, $username);	
-}
-
-function wp_insert_user($userdata) {
-	global $wpdb;
-
-	extract($userdata);
-
-	// Are we updating or creating?
-	if ( !empty($ID) ) {
-		$ID = (int) $ID;
-		$update = true;
-	} else {
-		$update = false;
-		// Password is not hashed when creating new user.
-		$user_pass = md5($user_pass);
-	}
-	
-	$user_login = sanitize_user($user_login, true);
-	$user_login = apply_filters('pre_user_login', $user_login);
-
-	if ( empty($user_nicename) )
-		$user_nicename = sanitize_title( $user_login );
-	$user_nicename = apply_filters('pre_user_nicename', $user_nicename);
-
-	if ( empty($user_url) )
-		$user_url = '';
-	$user_url = apply_filters('pre_user_url', $user_url);
-
-	if ( empty($user_email) )
-		$user_email = '';
-	$user_email = apply_filters('pre_user_email', $user_email);
-
-	if ( empty($display_name) )
-		$display_name = $user_login;
-	$display_name = apply_filters('pre_user_display_name', $display_name);
-
-	if ( empty($nickname) )
-		$nickname = $user_login;
-	$nickname = apply_filters('pre_user_nickname', $nickname);
-
-	if ( empty($first_name) )
-		$first_name = '';
-	$first_name = apply_filters('pre_user_first_name', $first_name);
-
-	if ( empty($last_name) )
-		$last_name = '';
-	$last_name = apply_filters('pre_user_last_name', $last_name);
-
-	if ( empty($description) )
-		$description = '';
-	$description = apply_filters('pre_user_description', $description);
-
-	if ( empty($user_registered) )
-		$user_registered = gmdate('Y-m-d H:i:s');
-
-	if ( $update ) {
-		$query = "UPDATE $wpdb->users SET user_pass='$user_pass', user_email='$user_email', user_url='$user_url', user_nicename = '$user_nicename', display_name = '$display_name' WHERE ID = '$ID'";
-		$query = apply_filters('update_user_query', $query);
-		$wpdb->query( $query );
-		$user_id = $ID;
-	} else {
-		$query = "INSERT INTO $wpdb->users 
-		(user_login, user_pass, user_email, user_url, user_registered, user_nicename, display_name)
-	VALUES 
-		('$user_login', '$user_pass', '$user_email', '$user_url', '$user_registered', '$user_nicename', '$display_name')";
-		$query = apply_filters('create_user_query', $query);
-		$wpdb->query( $query );
-		$user_id = $wpdb->insert_id;
-	}
-	
-	update_usermeta( $user_id, 'first_name', $first_name);
-	update_usermeta( $user_id, 'last_name', $last_name);
-	update_usermeta( $user_id, 'nickname', $nickname );
-	update_usermeta( $user_id, 'description', $description );
-	update_usermeta( $user_id, 'jabber', $jabber );
-	update_usermeta( $user_id, 'aim', $aim );
-	update_usermeta( $user_id, 'yim', $yim );
-
-	if ($update && !empty($role)) {
-		$user = new WP_User($user_id);
-		$user->set_role($role);
-	}
-
-	if ( !$update ) {
-		$user = new WP_User($user_id);
-		$user->set_role(get_settings('default_role'));
-	}
-
-	wp_cache_delete($user_id, 'users');
-	wp_cache_delete($user_login, 'userlogins');
-	
-	if ( $update )
-		do_action('profile_update', $user_id);
-	else
-		do_action('user_register', $user_id);
-		
-	return $user_id;	
-}
-
-function wp_update_user($userdata) {
-	global $wpdb;
-
-	$ID = (int) $userdata['ID'];
-	
-	// First, get all of the original fields
-	$user = get_userdata($ID);	
-
-	// Escape data pulled from DB.
-	$user = add_magic_quotes(get_object_vars($user));
-
-	// If password is changing, hash it now.
-	if ( ! empty($userdata['user_pass']) ) {
-		$plaintext_pass = $userdata['user_pass'];
-		$userdata['user_pass'] = md5($userdata['user_pass']);
-	}
-
-	// Merge old and new fields with new fields overwriting old ones.
-	$userdata = array_merge($user, $userdata);
-	$user_id = wp_insert_user($userdata);
-
-	// Update the cookies if the password changed.	
-	$current_user = wp_get_current_user();
-	if( $current_user->id == $ID ) {
-		if ( isset($plaintext_pass) ) {
-			wp_clearcookie();
-			wp_setcookie($userdata['user_login'], $plaintext_pass);
-		}
-	}
-	
-	return $user_id;
-}
-
-function wp_create_user( $username, $password, $email = '') {
-	global $wpdb;
-	
-	$user_login = $wpdb->escape( $username );
-	$user_email = $wpdb->escape( $email );
-	$user_pass = $password;
-
-	$userdata = compact('user_login', 'user_email', 'user_pass');
-	return wp_insert_user($userdata);
-}
-
-
-function create_user( $username, $password, $email ) {
-	return wp_create_user( $username, $password, $email );	
-}
-
-
+// Deprecated.  Use registration.php.
+require_once(ABSPATH . WPINC .  '/registration.php');
 ?>
diff -ruN 2.0.5/wp-includes/registration.php 2.2.2/wp-includes/registration.php
--- 2.0.5/wp-includes/registration.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/registration.php	2007-06-15 12:45:21.000000000 -0500
@@ -0,0 +1,184 @@
+<?php
+
+function username_exists( $username ) {
+	global $wpdb;
+	$username = sanitize_user( $username );
+	$user = get_userdatabylogin($username);
+	if ( $user )
+		return $user->ID;
+
+	return null;
+}
+
+
+function email_exists( $email ) {
+	global $wpdb;
+	$email = addslashes( $email );
+	return $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_email = '$email'");
+}
+
+
+function validate_username( $username ) {
+	$name = sanitize_user($username, true);
+	$valid = true;
+
+	if ( $name != $username )
+		$valid = false;
+
+	return apply_filters('validate_username', $valid, $username);
+}
+
+
+function wp_insert_user($userdata) {
+	global $wpdb;
+
+	extract($userdata, EXTR_SKIP);
+
+	// Are we updating or creating?
+	if ( !empty($ID) ) {
+		$ID = (int) $ID;
+		$update = true;
+	} else {
+		$update = false;
+		// Password is not hashed when creating new user.
+		$user_pass = md5($user_pass);
+	}
+
+	$user_login = sanitize_user($user_login, true);
+	$user_login = apply_filters('pre_user_login', $user_login);
+
+	if ( empty($user_nicename) )
+		$user_nicename = sanitize_title( $user_login );
+	$user_nicename = apply_filters('pre_user_nicename', $user_nicename);
+
+	if ( empty($user_url) )
+		$user_url = '';
+	$user_url = apply_filters('pre_user_url', $user_url);
+
+	if ( empty($user_email) )
+		$user_email = '';
+	$user_email = apply_filters('pre_user_email', $user_email);
+
+	if ( empty($display_name) )
+		$display_name = $user_login;
+	$display_name = apply_filters('pre_user_display_name', $display_name);
+
+	if ( empty($nickname) )
+		$nickname = $user_login;
+	$nickname = apply_filters('pre_user_nickname', $nickname);
+
+	if ( empty($first_name) )
+		$first_name = '';
+	$first_name = apply_filters('pre_user_first_name', $first_name);
+
+	if ( empty($last_name) )
+		$last_name = '';
+	$last_name = apply_filters('pre_user_last_name', $last_name);
+
+	if ( empty($description) )
+		$description = '';
+	$description = apply_filters('pre_user_description', $description);
+
+	if ( empty($rich_editing) )
+		$rich_editing = 'true';
+
+	if ( empty($user_registered) )
+		$user_registered = gmdate('Y-m-d H:i:s');
+
+	if ( $update ) {
+		$query = "UPDATE $wpdb->users SET user_pass='$user_pass', user_email='$user_email', user_url='$user_url', user_nicename = '$user_nicename', display_name = '$display_name' WHERE ID = '$ID'";
+		$query = apply_filters('update_user_query', $query);
+		$wpdb->query( $query );
+		$user_id = (int) $ID;
+	} else {
+		$query = "INSERT INTO $wpdb->users
+		(user_login, user_pass, user_email, user_url, user_registered, user_nicename, display_name)
+	VALUES
+		('$user_login', '$user_pass', '$user_email', '$user_url', '$user_registered', '$user_nicename', '$display_name')";
+		$query = apply_filters('create_user_query', $query);
+		$wpdb->query( $query );
+		$user_id = (int) $wpdb->insert_id;
+	}
+
+	update_usermeta( $user_id, 'first_name', $first_name);
+	update_usermeta( $user_id, 'last_name', $last_name);
+	update_usermeta( $user_id, 'nickname', $nickname );
+	update_usermeta( $user_id, 'description', $description );
+	update_usermeta( $user_id, 'jabber', $jabber );
+	update_usermeta( $user_id, 'aim', $aim );
+	update_usermeta( $user_id, 'yim', $yim );
+	update_usermeta( $user_id, 'rich_editing', $rich_editing);
+
+	if ( $update && isset($role) ) {
+		$user = new WP_User($user_id);
+		$user->set_role($role);
+	}
+
+	if ( !$update ) {
+		$user = new WP_User($user_id);
+		$user->set_role(get_option('default_role'));
+	}
+
+	wp_cache_delete($user_id, 'users');
+	wp_cache_delete($user_login, 'userlogins');
+
+	if ( $update )
+		do_action('profile_update', $user_id);
+	else
+		do_action('user_register', $user_id);
+
+	return $user_id;
+}
+
+
+function wp_update_user($userdata) {
+	global $wpdb;
+
+	$ID = (int) $userdata['ID'];
+
+	// First, get all of the original fields
+	$user = get_userdata($ID);
+
+	// Escape data pulled from DB.
+	$user = add_magic_quotes(get_object_vars($user));
+
+	// If password is changing, hash it now.
+	if ( ! empty($userdata['user_pass']) ) {
+		$plaintext_pass = $userdata['user_pass'];
+		$userdata['user_pass'] = md5($userdata['user_pass']);
+	}
+
+	// Merge old and new fields with new fields overwriting old ones.
+	$userdata = array_merge($user, $userdata);
+	$user_id = wp_insert_user($userdata);
+
+	// Update the cookies if the password changed.
+	$current_user = wp_get_current_user();
+	if ( $current_user->id == $ID ) {
+		if ( isset($plaintext_pass) ) {
+			wp_clearcookie();
+			wp_setcookie($userdata['user_login'], $plaintext_pass);
+		}
+	}
+
+	return $user_id;
+}
+
+
+function wp_create_user($username, $password, $email = '') {
+	global $wpdb;
+
+	$user_login = $wpdb->escape($username);
+	$user_email = $wpdb->escape($email);
+	$user_pass = $password;
+
+	$userdata = compact('user_login', 'user_email', 'user_pass');
+	return wp_insert_user($userdata);
+}
+
+
+function create_user($username, $password, $email) {
+	return wp_create_user($username, $password, $email);
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/rewrite.php 2.2.2/wp-includes/rewrite.php
--- 2.0.5/wp-includes/rewrite.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/rewrite.php	2007-04-19 17:26:52.000000000 -0500
@@ -0,0 +1,904 @@
+<?php
+
+/* WP_Rewrite API
+*******************************************************************************/
+
+//Add a straight rewrite rule
+function add_rewrite_rule($regex, $redirect) {
+	global $wp_rewrite;
+	$wp_rewrite->add_rule($regex, $redirect);
+}
+
+//Add a new tag (like %postname%)
+//warning: you must call this on init or earlier, otherwise the query var addition stuff won't work
+function add_rewrite_tag($tagname, $regex) {
+	//validation
+	if (strlen($tagname) < 3 || $tagname{0} != '%' || $tagname{strlen($tagname)-1} != '%') {
+		return;
+	}
+
+	$qv = trim($tagname, '%');
+
+	global $wp_rewrite, $wp;
+	$wp->add_query_var($qv);
+	$wp_rewrite->add_rewrite_tag($tagname, $regex, $qv . '=');
+}
+
+//Add a new feed type like /atom1/
+function add_feed($feedname, $function) {
+	global $wp_rewrite;
+	if (!in_array($feedname, $wp_rewrite->feeds)) { //override the file if it is
+		$wp_rewrite->feeds[] = $feedname;
+	}
+	$hook = 'do_feed_' . $feedname;
+	remove_action($hook, $function, 10, 1);
+	add_action($hook, $function, 10, 1);
+	return $hook;
+}
+
+define('EP_PERMALINK',  1   );
+define('EP_ATTACHMENT', 2   );
+define('EP_DATE',       4   );
+define('EP_YEAR',       8   );
+define('EP_MONTH',      16  );
+define('EP_DAY',        32  );
+define('EP_ROOT',       64  );
+define('EP_COMMENTS',   128 );
+define('EP_SEARCH',     256 );
+define('EP_CATEGORIES', 512 );
+define('EP_AUTHORS',    1024);
+define('EP_PAGES',      2048);
+//pseudo-places
+define('EP_NONE',       0  );
+define('EP_ALL',        4095);
+
+//and an endpoint, like /trackback/
+function add_rewrite_endpoint($name, $places) {
+	global $wp_rewrite;
+	$wp_rewrite->add_endpoint($name, $places);
+}
+
+// examine a url (supposedly from this blog) and try to
+// determine the post ID it represents.
+function url_to_postid($url) {
+	global $wp_rewrite;
+	
+	$url = apply_filters('url_to_postid', $url);
+
+	// First, check to see if there is a 'p=N' or 'page_id=N' to match against
+	preg_match('#[?&](p|page_id)=(\d+)#', $url, $values);
+	$id = intval($values[2]);
+	if ( $id ) return $id;
+
+	// Check to see if we are using rewrite rules
+	$rewrite = $wp_rewrite->wp_rewrite_rules();
+
+	// Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options
+	if ( empty($rewrite) )
+		return 0;
+
+	// $url cleanup by Mark Jaquith
+	// This fixes things like #anchors, ?query=strings, missing 'www.',
+	// added 'www.', or added 'index.php/' that will mess up our WP_Query
+	// and return a false negative
+
+	// Get rid of the #anchor
+	$url_split = explode('#', $url);
+	$url = $url_split[0];
+
+	// Get rid of URL ?query=string
+	$url_split = explode('?', $url);
+	$url = $url_split[0];
+
+	// Add 'www.' if it is absent and should be there
+	if ( false !== strpos(get_option('home'), '://www.') && false === strpos($url, '://www.') )
+		$url = str_replace('://', '://www.', $url);
+
+	// Strip 'www.' if it is present and shouldn't be
+	if ( false === strpos(get_option('home'), '://www.') )
+		$url = str_replace('://www.', '://', $url);
+
+	// Strip 'index.php/' if we're not using path info permalinks
+	if ( !$wp_rewrite->using_index_permalinks() )
+		$url = str_replace('index.php/', '', $url);
+
+	if ( false !== strpos($url, get_option('home')) ) {
+		// Chop off http://domain.com
+		$url = str_replace(get_option('home'), '', $url);
+	} else {
+		// Chop off /path/to/blog
+		$home_path = parse_url(get_option('home'));
+		$home_path = $home_path['path'];
+		$url = str_replace($home_path, '', $url);
+	}
+
+	// Trim leading and lagging slashes
+	$url = trim($url, '/');
+
+	$request = $url;
+
+	// Done with cleanup
+
+	// Look for matches.
+	$request_match = $request;
+	foreach ($rewrite as $match => $query) {
+		// If the requesting file is the anchor of the match, prepend it
+		// to the path info.
+		if ( (! empty($url)) && (strpos($match, $url) === 0) ) {
+			$request_match = $url . '/' . $request;
+		}
+
+		if ( preg_match("!^$match!", $request_match, $matches) ) {
+			// Got a match.
+			// Trim the query of everything up to the '?'.
+			$query = preg_replace("!^.+\?!", '', $query);
+
+			// Substitute the substring matches into the query.
+			eval("\$query = \"$query\";");
+			$query = new WP_Query($query);
+			if ( $query->is_single || $query->is_page )
+				return $query->post->ID;
+			else
+				return 0;
+		}
+	}
+	return 0;
+}
+
+/* WP_Rewrite class
+*******************************************************************************/
+
+class WP_Rewrite {
+	var $permalink_structure;
+	var $use_trailing_slashes;
+	var $category_base;
+	var $category_structure;
+	var $author_base = 'author';
+	var $author_structure;
+	var $date_structure;
+	var $page_structure;
+	var $search_base = 'search';
+	var $search_structure;
+	var $comments_base = 'comments';
+	var $feed_base = 'feed';
+	var $comments_feed_structure;
+	var $feed_structure;
+	var $front;
+	var $root = '';
+	var $index = 'index.php';
+	var $matches = '';
+	var $rules;
+	var $extra_rules; //those not generated by the class, see add_rewrite_rule()
+	var $non_wp_rules; //rules that don't redirect to WP's index.php
+	var $endpoints;
+	var $use_verbose_rules = false;
+	var $rewritecode =
+		array(
+					'%year%',
+					'%monthnum%',
+					'%day%',
+					'%hour%',
+					'%minute%',
+					'%second%',
+					'%postname%',
+					'%post_id%',
+					'%category%',
+					'%author%',
+					'%pagename%',
+					'%search%'
+					);
+
+	var $rewritereplace =
+		array(
+					'([0-9]{4})',
+					'([0-9]{1,2})',
+					'([0-9]{1,2})',
+					'([0-9]{1,2})',
+					'([0-9]{1,2})',
+					'([0-9]{1,2})',
+					'([^/]+)',
+					'([0-9]+)',
+					'(.+?)',
+					'([^/]+)',
+					'([^/]+)',
+					'(.+)'
+					);
+
+	var $queryreplace =
+		array (
+					'year=',
+					'monthnum=',
+					'day=',
+					'hour=',
+					'minute=',
+					'second=',
+					'name=',
+					'p=',
+					'category_name=',
+					'author_name=',
+					'pagename=',
+					's='
+					);
+
+	var $feeds = array ( 'feed', 'rdf', 'rss', 'rss2', 'atom' );
+
+	function using_permalinks() {
+		if (empty($this->permalink_structure))
+			return false;
+		else
+			return true;
+	}
+
+	function using_index_permalinks() {
+		if (empty($this->permalink_structure)) {
+			return false;
+		}
+
+		// If the index is not in the permalink, we're using mod_rewrite.
+		if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
+			return true;
+		}
+
+		return false;
+	}
+
+	function using_mod_rewrite_permalinks() {
+		if ( $this->using_permalinks() && ! $this->using_index_permalinks())
+			return true;
+		else
+			return false;
+	}
+
+	function preg_index($number) {
+		$match_prefix = '$';
+		$match_suffix = '';
+
+		if (! empty($this->matches)) {
+			$match_prefix = '$' . $this->matches . '[';
+			$match_suffix = ']';
+		}
+
+		return "$match_prefix$number$match_suffix";
+	}
+
+	function page_rewrite_rules() {
+		$uris = get_option('page_uris');
+		$attachment_uris = get_option('page_attachment_uris');
+
+		$rewrite_rules = array();
+		$page_structure = $this->get_page_permastruct();
+		if( is_array( $attachment_uris ) ) {
+			foreach ($attachment_uris as $uri => $pagename) {
+				$this->add_rewrite_tag('%pagename%', "($uri)", 'attachment=');
+				$rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
+			}
+		}
+		if( is_array( $uris ) ) {
+			foreach ($uris as $uri => $pagename) {
+				$this->add_rewrite_tag('%pagename%', "($uri)", 'pagename=');
+				$rewrite_rules = array_merge($rewrite_rules, $this->generate_rewrite_rules($page_structure, EP_PAGES));
+			}
+		}
+
+		return $rewrite_rules;
+	}
+
+	function get_date_permastruct() {
+		if (isset($this->date_structure)) {
+			return $this->date_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->date_structure = '';
+			return false;
+		}
+
+		// The date permalink must have year, month, and day separated by slashes.
+		$endians = array('%year%/%monthnum%/%day%', '%day%/%monthnum%/%year%', '%monthnum%/%day%/%year%');
+
+		$this->date_structure = '';
+		$date_endian = '';
+
+		foreach ($endians as $endian) {
+			if (false !== strpos($this->permalink_structure, $endian)) {
+				$date_endian= $endian;
+				break;
+			}
+		}
+
+		if ( empty($date_endian) )
+			$date_endian = '%year%/%monthnum%/%day%';
+
+		// Do not allow the date tags and %post_id% to overlap in the permalink
+		// structure. If they do, move the date tags to $front/date/.
+		$front = $this->front;
+		preg_match_all('/%.+?%/', $this->permalink_structure, $tokens);
+		$tok_index = 1;
+		foreach ($tokens[0] as $token) {
+			if ( ($token == '%post_id%') && ($tok_index <= 3) ) {
+				$front = $front . 'date/';
+				break;
+			}
+			$tok_index++;
+		}
+
+		$this->date_structure = $front . $date_endian;
+
+		return $this->date_structure;
+	}
+
+	function get_year_permastruct() {
+		$structure = $this->get_date_permastruct($this->permalink_structure);
+
+		if (empty($structure)) {
+			return false;
+		}
+
+		$structure = str_replace('%monthnum%', '', $structure);
+		$structure = str_replace('%day%', '', $structure);
+
+		$structure = preg_replace('#/+#', '/', $structure);
+
+		return $structure;
+	}
+
+	function get_month_permastruct() {
+		$structure = $this->get_date_permastruct($this->permalink_structure);
+
+		if (empty($structure)) {
+			return false;
+		}
+
+		$structure = str_replace('%day%', '', $structure);
+
+		$structure = preg_replace('#/+#', '/', $structure);
+
+		return $structure;
+	}
+
+	function get_day_permastruct() {
+		return $this->get_date_permastruct($this->permalink_structure);
+	}
+
+	function get_category_permastruct() {
+		if (isset($this->category_structure)) {
+			return $this->category_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->category_structure = '';
+			return false;
+		}
+
+		if (empty($this->category_base))
+			$this->category_structure = $this->front . 'category/';
+		else
+			$this->category_structure = $this->category_base . '/';
+
+		$this->category_structure .= '%category%';
+
+		return $this->category_structure;
+	}
+
+	function get_author_permastruct() {
+		if (isset($this->author_structure)) {
+			return $this->author_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->author_structure = '';
+			return false;
+		}
+
+		$this->author_structure = $this->front . $this->author_base . '/%author%';
+
+		return $this->author_structure;
+	}
+
+	function get_search_permastruct() {
+		if (isset($this->search_structure)) {
+			return $this->search_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->search_structure = '';
+			return false;
+		}
+
+		$this->search_structure = $this->root . $this->search_base . '/%search%';
+
+		return $this->search_structure;
+	}
+
+	function get_page_permastruct() {
+		if (isset($this->page_structure)) {
+			return $this->page_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->page_structure = '';
+			return false;
+		}
+
+		$this->page_structure = $this->root . '%pagename%';
+
+		return $this->page_structure;
+	}
+
+	function get_feed_permastruct() {
+		if (isset($this->feed_structure)) {
+			return $this->feed_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->feed_structure = '';
+			return false;
+		}
+
+		$this->feed_structure = $this->root . $this->feed_base . '/%feed%';
+
+		return $this->feed_structure;
+	}
+
+	function get_comment_feed_permastruct() {
+		if (isset($this->comment_feed_structure)) {
+			return $this->comment_feed_structure;
+		}
+
+		if (empty($this->permalink_structure)) {
+			$this->comment_feed_structure = '';
+			return false;
+		}
+
+		$this->comment_feed_structure = $this->root . $this->comments_base . '/' . $this->feed_base . '/%feed%';
+
+		return $this->comment_feed_structure;
+	}
+
+	function add_rewrite_tag($tag, $pattern, $query) {
+		// If the tag already exists, replace the existing pattern and query for
+		// that tag, otherwise add the new tag, pattern, and query to the end of
+		// the arrays.
+		$position = array_search($tag, $this->rewritecode);
+		if (FALSE !== $position && NULL !== $position) {
+			$this->rewritereplace[$position] = $pattern;
+			$this->queryreplace[$position] = $query;
+		} else {
+			$this->rewritecode[] = $tag;
+			$this->rewritereplace[] = $pattern;
+			$this->queryreplace[] = $query;
+		}
+	}
+
+	//the main WP_Rewrite function. generate the rules from permalink structure
+	function generate_rewrite_rules($permalink_structure, $ep_mask = EP_NONE, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true) {
+		//build a regex to match the feed section of URLs, something like (feed|atom|rss|rss2)/?
+		$feedregex2 = '';
+		foreach ($this->feeds as $feed_name) {
+			$feedregex2 .= $feed_name . '|';
+		}
+		$feedregex2 = '(' . trim($feedregex2, '|') .  ')/?$';
+		//$feedregex is identical but with /feed/ added on as well, so URLs like <permalink>/feed/atom
+		//and <permalink>/atom are both possible
+		$feedregex = $this->feed_base  . '/' . $feedregex2;
+
+		//build a regex to match the trackback and page/xx parts of URLs
+		$trackbackregex = 'trackback/?$';
+		$pageregex = 'page/?([0-9]{1,})/?$';
+
+		//build up an array of endpoint regexes to append => queries to append
+		if ($endpoints) {
+			$ep_query_append = array ();
+			foreach ($this->endpoints as $endpoint) {
+				//match everything after the endpoint name, but allow for nothing to appear there
+				$epmatch = $endpoint[1] . '(/(.*))?/?$';
+				//this will be appended on to the rest of the query for each dir
+				$epquery = '&' . $endpoint[1] . '=';
+				$ep_query_append[$epmatch] = array ( $endpoint[0], $epquery );
+			}
+		}
+
+		//get everything up to the first rewrite tag
+		$front = substr($permalink_structure, 0, strpos($permalink_structure, '%'));
+		//build an array of the tags (note that said array ends up being in $tokens[0])
+		preg_match_all('/%.+?%/', $permalink_structure, $tokens);
+
+		$num_tokens = count($tokens[0]);
+
+		$index = $this->index; //probably 'index.php'
+		$feedindex = $index;
+		$trackbackindex = $index;
+		//build a list from the rewritecode and queryreplace arrays, that will look something like
+		//tagname=$matches[i] where i is the current $i
+		for ($i = 0; $i < $num_tokens; ++$i) {
+			if (0 < $i) {
+				$queries[$i] = $queries[$i - 1] . '&';
+			}
+
+			$query_token = str_replace($this->rewritecode, $this->queryreplace, $tokens[0][$i]) . $this->preg_index($i+1);
+			$queries[$i] .= $query_token;
+		}
+
+		//get the structure, minus any cruft (stuff that isn't tags) at the front
+		$structure = $permalink_structure;
+		if ($front != '/') {
+			$structure = str_replace($front, '', $structure);
+		}
+		//create a list of dirs to walk over, making rewrite rules for each level
+		//so for example, a $structure of /%year%/%month%/%postname% would create
+		//rewrite rules for /%year%/, /%year%/%month%/ and /%year%/%month%/%postname%
+		$structure = trim($structure, '/');
+		if ($walk_dirs) {
+			$dirs = explode('/', $structure);
+		} else {
+			$dirs[] = $structure;
+		}
+		$num_dirs = count($dirs);
+
+		//strip slashes from the front of $front
+		$front = preg_replace('|^/+|', '', $front);
+
+		//the main workhorse loop
+		$post_rewrite = array();
+		$struct = $front;
+		for ($j = 0; $j < $num_dirs; ++$j) {
+			//get the struct for this dir, and trim slashes off the front
+			$struct .= $dirs[$j] . '/'; //accumulate. see comment near explode('/', $structure) above
+			$struct = ltrim($struct, '/');
+			//replace tags with regexes
+			$match = str_replace($this->rewritecode, $this->rewritereplace, $struct);
+			//make a list of tags, and store how many there are in $num_toks
+			$num_toks = preg_match_all('/%.+?%/', $struct, $toks);
+			//get the 'tagname=$matches[i]'
+			$query = $queries[$num_toks - 1];
+
+			//set up $ep_mask_specific which is used to match more specific URL types
+			switch ($dirs[$j]) {
+				case '%year%': $ep_mask_specific = EP_YEAR; break;
+				case '%monthnum%': $ep_mask_specific = EP_MONTH; break;
+				case '%day%': $ep_mask_specific = EP_DAY; break;
+			}
+
+			//create query for /page/xx
+			$pagematch = $match . $pageregex;
+			$pagequery = $index . '?' . $query . '&paged=' . $this->preg_index($num_toks + 1);
+
+			//create query for /feed/(feed|atom|rss|rss2|rdf)
+			$feedmatch = $match . $feedregex;
+			$feedquery = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
+
+			//create query for /(feed|atom|rss|rss2|rdf) (see comment near creation of $feedregex)
+			$feedmatch2 = $match . $feedregex2;
+			$feedquery2 = $feedindex . '?' . $query . '&feed=' . $this->preg_index($num_toks + 1);
+
+			//if asked to, turn the feed queries into comment feed ones
+			if ($forcomments) {
+				$feedquery .= '&withcomments=1';
+				$feedquery2 .= '&withcomments=1';
+			}
+
+			//start creating the array of rewrites for this dir
+			$rewrite = array();
+			if ($feed) //...adding on /feed/ regexes => queries
+				$rewrite = array($feedmatch => $feedquery, $feedmatch2 => $feedquery2);
+			if ($paged) //...and /page/xx ones
+				$rewrite = array_merge($rewrite, array($pagematch => $pagequery));
+
+			//do endpoints
+			if ($endpoints) {
+				foreach ($ep_query_append as $regex => $ep) {
+					//add the endpoints on if the mask fits
+					if ($ep[0] & $ep_mask || $ep[0] & $ep_mask_specific) {
+						$rewrite[$match . $regex] = $index . '?' . $query . $ep[1] . $this->preg_index($num_toks + 2);
+					}
+				}
+			}
+
+			//if we've got some tags in this dir
+			if ($num_toks) {
+				$post = false;
+				$page = false;
+
+				//check to see if this dir is permalink-level: i.e. the structure specifies an
+				//individual post. Do this by checking it contains at least one of 1) post name,
+				//2) post ID, 3) page name, 4) timestamp (year, month, day, hour, second and
+				//minute all present). Set these flags now as we need them for the endpoints.
+				if (strpos($struct, '%postname%') !== false || strpos($struct, '%post_id%') !== false
+						|| strpos($struct, '%pagename%') !== false
+						|| (strpos($struct, '%year%') !== false && strpos($struct, '%monthnum%') !== false && strpos($struct, '%day%') !== false && strpos($struct, '%hour%') !== false && strpos($struct, '%minute%') !== false && strpos($struct, '%second%') !== false)) {
+					$post = true;
+					if (strpos($struct, '%pagename%') !== false)
+						$page = true;
+				}
+
+				//if we're creating rules for a permalink, do all the endpoints like attachments etc
+				if ($post) {
+					$post = true;
+					//create query and regex for trackback
+					$trackbackmatch = $match . $trackbackregex;
+					$trackbackquery = $trackbackindex . '?' . $query . '&tb=1';
+					//trim slashes from the end of the regex for this dir
+					$match = rtrim($match, '/');
+					//get rid of brackets
+					$submatchbase = str_replace(array('(',')'),'',$match);
+
+					//add a rule for at attachments, which take the form of <permalink>/some-text
+					$sub1 = $submatchbase . '/([^/]+)/';
+					$sub1tb = $sub1 . $trackbackregex; //add trackback regex <permalink>/trackback/...
+					$sub1feed = $sub1 . $feedregex; //and <permalink>/feed/(atom|...)
+					$sub1feed2 = $sub1 . $feedregex2; //and <permalink>/(feed|atom...)
+					//add an ? as we don't have to match that last slash, and finally a $ so we
+					//match to the end of the URL
+
+					//add another rule to match attachments in the explicit form:
+					//<permalink>/attachment/some-text
+					$sub2 = $submatchbase . '/attachment/([^/]+)/';
+					$sub2tb = $sub2 . $trackbackregex; //and add trackbacks <permalink>/attachment/trackback
+					$sub2feed = $sub2 . $feedregex;    //feeds, <permalink>/attachment/feed/(atom|...)
+					$sub2feed2 = $sub2 . $feedregex2;  //and feeds again on to this <permalink>/attachment/(feed|atom...)
+
+					//create queries for these extra tag-ons we've just dealt with
+					$subquery = $index . '?attachment=' . $this->preg_index(1);
+					$subtbquery = $subquery . '&tb=1';
+					$subfeedquery = $subquery . '&feed=' . $this->preg_index(2);
+
+					//do endpoints for attachments
+					if ($endpoint) { foreach ($ep_query_append as $regex => $ep) {
+						if ($ep[0] & EP_ATTACHMENT) {
+							$rewrite[$sub1 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2);
+							$rewrite[$sub2 . $regex] = $subquery . '?' . $ep[1] . $this->preg_index(2);
+						}
+					} }
+
+					//now we've finished with endpoints, finish off the $sub1 and $sub2 matches
+					$sub1 .= '?$';
+					$sub2 .= '?$';
+
+					//allow URLs like <permalink>/2 for <permalink>/page/2
+					$match = $match . '(/[0-9]+)?/?$';
+					$query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1);
+				} else { //not matching a permalink so this is a lot simpler
+					//close the match and finalise the query
+					$match .= '?$';
+					$query = $index . '?' . $query;
+				}
+
+				//create the final array for this dir by joining the $rewrite array (which currently
+				//only contains rules/queries for trackback, pages etc) to the main regex/query for
+				//this dir
+				$rewrite = array_merge($rewrite, array($match => $query));
+
+				//if we're matching a permalink, add those extras (attachments etc) on
+				if ($post) {
+					//add trackback
+					$rewrite = array_merge(array($trackbackmatch => $trackbackquery), $rewrite);
+
+					//add regexes/queries for attachments, attachment trackbacks and so on
+					if ( ! $page ) //require <permalink>/attachment/stuff form for pages because of confusion with subpages
+						$rewrite = array_merge($rewrite, array($sub1 => $subquery, $sub1tb => $subtbquery, $sub1feed => $subfeedquery, $sub1feed2 => $subfeedquery));
+					$rewrite = array_merge($rewrite, array($sub2 => $subquery, $sub2tb => $subtbquery, $sub2feed => $subfeedquery, $sub2feed2 => $subfeedquery));
+				}
+			} //if($num_toks)
+			//add the rules for this dir to the accumulating $post_rewrite
+			$post_rewrite = array_merge($rewrite, $post_rewrite);
+		} //foreach ($dir)
+		return $post_rewrite; //the finished rules. phew!
+	}
+
+	function generate_rewrite_rule($permalink_structure, $walk_dirs = false) {
+		return $this->generate_rewrite_rules($permalink_structure, EP_NONE, false, false, false, $walk_dirs);
+	}
+
+	/* rewrite_rules
+	 * Construct rewrite matches and queries from permalink structure.
+	 * Returns an associate array of matches and queries.
+	 */
+	function rewrite_rules() {
+		$rewrite = array();
+
+		if (empty($this->permalink_structure)) {
+			return $rewrite;
+		}
+
+		// robots.txt
+		$robots_rewrite = array('robots.txt$' => $this->index . '?robots=1');
+
+		//Default Feed rules - These are require to allow for the direct access files to work with permalink structure starting with %category%
+		$default_feeds = array(	'wp-atom.php$'	=>	$this->index .'?feed=atom',
+								'wp-rdf.php$'	=>	$this->index .'?feed=rdf',
+								'wp-rss.php$'	=>	$this->index .'?feed=rss',
+								'wp-rss2.php$'	=>	$this->index .'?feed=rss2',
+								'wp-feed.php$'	=>	$this->index .'?feed=feed',
+								'wp-commentsrss2.php$'	=>	$this->index . '?feed=rss2&withcomments=1');
+
+		// Post
+		$post_rewrite = $this->generate_rewrite_rules($this->permalink_structure, EP_PERMALINK);
+		$post_rewrite = apply_filters('post_rewrite_rules', $post_rewrite);
+
+		// Date
+		$date_rewrite = $this->generate_rewrite_rules($this->get_date_permastruct(), EP_DATE);
+		$date_rewrite = apply_filters('date_rewrite_rules', $date_rewrite);
+
+		// Root
+		$root_rewrite = $this->generate_rewrite_rules($this->root . '/', EP_ROOT);
+		$root_rewrite = apply_filters('root_rewrite_rules', $root_rewrite);
+
+		// Comments
+		$comments_rewrite = $this->generate_rewrite_rules($this->root . $this->comments_base, EP_COMMENTS, true, true, true, false);
+		$comments_rewrite = apply_filters('comments_rewrite_rules', $comments_rewrite);
+
+		// Search
+		$search_structure = $this->get_search_permastruct();
+		$search_rewrite = $this->generate_rewrite_rules($search_structure, EP_SEARCH);
+		$search_rewrite = apply_filters('search_rewrite_rules', $search_rewrite);
+
+		// Categories
+		$category_rewrite = $this->generate_rewrite_rules($this->get_category_permastruct(), EP_CATEGORIES);
+		$category_rewrite = apply_filters('category_rewrite_rules', $category_rewrite);
+
+		// Authors
+		$author_rewrite = $this->generate_rewrite_rules($this->get_author_permastruct(), EP_AUTHORS);
+		$author_rewrite = apply_filters('author_rewrite_rules', $author_rewrite);
+
+		// Pages
+		$page_rewrite = $this->page_rewrite_rules();
+		$page_rewrite = apply_filters('page_rewrite_rules', $page_rewrite);
+
+		// Put them together.
+		$this->rules = array_merge($robots_rewrite, $default_feeds, $page_rewrite, $root_rewrite, $comments_rewrite, $search_rewrite, $category_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $this->extra_rules);
+
+		do_action_ref_array('generate_rewrite_rules', array(&$this));
+		$this->rules = apply_filters('rewrite_rules_array', $this->rules);
+
+		return $this->rules;
+	}
+
+	function wp_rewrite_rules() {
+		$this->rules = get_option('rewrite_rules');
+		if ( empty($this->rules) ) {
+			$this->matches = 'matches';
+			$this->rewrite_rules();
+			update_option('rewrite_rules', $this->rules);
+		}
+
+		return $this->rules;
+	}
+
+	function mod_rewrite_rules() {
+		if ( ! $this->using_permalinks()) {
+			return '';
+		}
+
+		$site_root = parse_url(get_option('siteurl'));
+		$site_root = trailingslashit($site_root['path']);
+
+		$home_root = parse_url(get_option('home'));
+		$home_root = trailingslashit($home_root['path']);
+
+		$rules = "<IfModule mod_rewrite.c>\n";
+		$rules .= "RewriteEngine On\n";
+		$rules .= "RewriteBase $home_root\n";
+
+		//add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all)
+		foreach ($this->non_wp_rules as $match => $query) {
+			// Apache 1.3 does not support the reluctant (non-greedy) modifier.
+			$match = str_replace('.+?', '.+', $match);
+
+			// If the match is unanchored and greedy, prepend rewrite conditions
+			// to avoid infinite redirects and eclipsing of real files.
+			if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
+				//nada.
+			}
+
+			$rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
+		}
+
+		if ($this->use_verbose_rules) {
+			$this->matches = '';
+			$rewrite = $this->rewrite_rules();
+			$num_rules = count($rewrite);
+			$rules .= "RewriteCond %{REQUEST_FILENAME} -f [OR]\n" .
+				"RewriteCond %{REQUEST_FILENAME} -d\n" .
+				"RewriteRule ^.*$ - [S=$num_rules]\n";
+
+			foreach ($rewrite as $match => $query) {
+				// Apache 1.3 does not support the reluctant (non-greedy) modifier.
+				$match = str_replace('.+?', '.+', $match);
+
+				// If the match is unanchored and greedy, prepend rewrite conditions
+				// to avoid infinite redirects and eclipsing of real files.
+				if ($match == '(.+)/?$' || $match == '([^/]+)/?$' ) {
+					//nada.
+				}
+
+				if (strpos($query, $this->index) !== false) {
+					$rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
+				} else {
+					$rules .= 'RewriteRule ^' . $match . ' ' . $site_root . $query . " [QSA,L]\n";
+				}
+			}
+		} else {
+			$rules .= "RewriteCond %{REQUEST_FILENAME} !-f\n" .
+				"RewriteCond %{REQUEST_FILENAME} !-d\n" .
+				"RewriteRule . {$home_root}{$this->index} [L]\n";
+		}
+
+		$rules .= "</IfModule>\n";
+
+		$rules = apply_filters('mod_rewrite_rules', $rules);
+		$rules = apply_filters('rewrite_rules', $rules);  // Deprecated
+
+		return $rules;
+	}
+
+	//Add a straight rewrite rule
+	function add_rule($regex, $redirect) {
+		//get everything up to the first ?
+		$index = (strpos($redirect, '?') == false ? strlen($redirect) : strpos($redirect, '?'));
+		$front = substr($redirect, 0, $index);
+		if ($front != $this->index) { //it doesn't redirect to WP's index.php
+			$this->add_external_rule($regex, $redirect);
+		} else {
+			$this->extra_rules[$regex] = $redirect;
+		}
+	}
+
+	//add a rule that doesn't redirect to index.php
+	function add_external_rule($regex, $redirect) {
+		$this->non_wp_rules[$regex] = $redirect;
+	}
+
+	//add an endpoint, like /trackback/, to be inserted after certain URL types (specified in $places)
+	function add_endpoint($name, $places) {
+		global $wp;
+		$this->endpoints[] = array ( $places, $name );
+		$wp->add_query_var($name);
+	}
+
+	function flush_rules() {
+		generate_page_uri_index();
+		delete_option('rewrite_rules');
+		$this->wp_rewrite_rules();
+		if ( function_exists('save_mod_rewrite_rules') )
+			save_mod_rewrite_rules();
+	}
+
+	function init() {
+		$this->extra_rules = $this->non_wp_rules = $this->endpoints = array();
+		$this->permalink_structure = get_option('permalink_structure');
+		$this->front = substr($this->permalink_structure, 0, strpos($this->permalink_structure, '%'));
+		$this->root = '';
+		if ($this->using_index_permalinks()) {
+			$this->root = $this->index . '/';
+		}
+		$this->category_base = get_option('category_base');
+		unset($this->category_structure);
+		unset($this->author_structure);
+		unset($this->date_structure);
+		unset($this->page_structure);
+		unset($this->search_structure);
+		unset($this->feed_structure);
+		unset($this->comment_feed_structure);
+		$this->use_trailing_slashes = ( substr($this->permalink_structure, -1, 1) == '/' ) ? true : false;
+	}
+
+	function set_permalink_structure($permalink_structure) {
+		if ($permalink_structure != $this->permalink_structure) {
+			update_option('permalink_structure', $permalink_structure);
+			$this->init();
+		}
+	}
+
+	function set_category_base($category_base) {
+		if ($category_base != $this->category_base) {
+			update_option('category_base', $category_base);
+			$this->init();
+		}
+	}
+
+	function WP_Rewrite() {
+		$this->init();
+	}
+}
+
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/rss-functions.php 2.2.2/wp-includes/rss-functions.php
--- 2.0.5/wp-includes/rss-functions.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/rss-functions.php	2007-05-04 16:48:43.000000000 -0500
@@ -1,856 +1,4 @@
 <?php
-/*
- * Project:     MagpieRSS: a simple RSS integration tool
- * File:        A compiled file for RSS syndication
- * Author:      Kellan Elliott-McCrea <kellan@protest.net>
- * Version:		0.51
- * License:		GPL
- */
-
-define('RSS', 'RSS');
-define('ATOM', 'Atom');
-define('MAGPIE_USER_AGENT', 'WordPress/' . $wp_version);
-
-class MagpieRSS { 
-	var $parser;
-	var $current_item	= array();	// item currently being parsed
-	var $items			= array();	// collection of parsed items
-	var $channel		= array();	// hash of channel fields
-	var $textinput		= array();
-	var $image			= array();
-	var $feed_type;
-	var $feed_version;
-
-	// parser variables
-	var $stack				= array(); // parser stack
-	var $inchannel			= false;
-	var $initem 			= false;
-	var $incontent			= false; // if in Atom <content mode="xml"> field 
-	var $intextinput		= false;
-	var $inimage 			= false;
-	var $current_field		= '';
-	var $current_namespace	= false;
-	
-	//var $ERROR = "";
-	
-	var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
-
-	function MagpieRSS ($source) {
-		
-		# if PHP xml isn't compiled in, die
-		#
-		if ( !function_exists('xml_parser_create') )
-			trigger_error( "Failed to load PHP's XML Extension. http://www.php.net/manual/en/ref.xml.php" );
-		
-		$parser = @xml_parser_create();
-		
-		if ( !is_resource($parser) )
-			trigger_error( "Failed to create an instance of PHP's XML parser. http://www.php.net/manual/en/ref.xml.php");
-
-		
-		$this->parser = $parser;
-		
-		# pass in parser, and a reference to this object
-		# setup handlers
-		#
-		xml_set_object( $this->parser, $this );
-		xml_set_element_handler($this->parser, 
-				'feed_start_element', 'feed_end_element' );
-						
-		xml_set_character_data_handler( $this->parser, 'feed_cdata' ); 
-	
-		$status = xml_parse( $this->parser, $source );
-		
-		if (! $status ) {
-			$errorcode = xml_get_error_code( $this->parser );
-			if ( $errorcode != XML_ERROR_NONE ) {
-				$xml_error = xml_error_string( $errorcode );
-				$error_line = xml_get_current_line_number($this->parser);
-				$error_col = xml_get_current_column_number($this->parser);
-				$errormsg = "$xml_error at line $error_line, column $error_col";
-
-				$this->error( $errormsg );
-			}
-		}
-		
-		xml_parser_free( $this->parser );
-
-		$this->normalize();
-	}
-	
-	function feed_start_element($p, $element, &$attrs) {
-		$el = $element = strtolower($element);
-		$attrs = array_change_key_case($attrs, CASE_LOWER);
-		
-		// check for a namespace, and split if found
-		$ns	= false;
-		if ( strpos( $element, ':' ) ) {
-			list($ns, $el) = split( ':', $element, 2); 
-		}
-		if ( $ns and $ns != 'rdf' ) {
-			$this->current_namespace = $ns;
-		}
-			
-		# if feed type isn't set, then this is first element of feed
-		# identify feed from root element
-		#
-		if (!isset($this->feed_type) ) {
-			if ( $el == 'rdf' ) {
-				$this->feed_type = RSS;
-				$this->feed_version = '1.0';
-			}
-			elseif ( $el == 'rss' ) {
-				$this->feed_type = RSS;
-				$this->feed_version = $attrs['version'];
-			}
-			elseif ( $el == 'feed' ) {
-				$this->feed_type = ATOM;
-				$this->feed_version = $attrs['version'];
-				$this->inchannel = true;
-			}
-			return;
-		}
-	
-		if ( $el == 'channel' ) 
-		{
-			$this->inchannel = true;
-		}
-		elseif ($el == 'item' or $el == 'entry' ) 
-		{
-			$this->initem = true;
-			if ( isset($attrs['rdf:about']) ) {
-				$this->current_item['about'] = $attrs['rdf:about'];	
-			}
-		}
-		
-		// if we're in the default namespace of an RSS feed,
-		//  record textinput or image fields
-		elseif ( 
-			$this->feed_type == RSS and 
-			$this->current_namespace == '' and 
-			$el == 'textinput' ) 
-		{
-			$this->intextinput = true;
-		}
-		
-		elseif (
-			$this->feed_type == RSS and 
-			$this->current_namespace == '' and 
-			$el == 'image' ) 
-		{
-			$this->inimage = true;
-		}
-		
-		# handle atom content constructs
-		elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
-		{
-			// avoid clashing w/ RSS mod_content
-			if ($el == 'content' ) {
-				$el = 'atom_content';
-			}
-			
-			$this->incontent = $el;
-			
-			
-		}
-		
-		// if inside an Atom content construct (e.g. content or summary) field treat tags as text
-		elseif ($this->feed_type == ATOM and $this->incontent ) 
-		{
-			// if tags are inlined, then flatten
-			$attrs_str = join(' ', 
-					array_map('map_attrs', 
-					array_keys($attrs), 
-					array_values($attrs) ) );
-			
-			$this->append_content( "<$element $attrs_str>"  );
-					
-			array_unshift( $this->stack, $el );
-		}
-		
-		// Atom support many links per containging element.
-		// Magpie treats link elements of type rel='alternate'
-		// as being equivalent to RSS's simple link element.
-		//
-		elseif ($this->feed_type == ATOM and $el == 'link' ) 
-		{
-			if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' ) 
-			{
-				$link_el = 'link';
-			}
-			else {
-				$link_el = 'link_' . $attrs['rel'];
-			}
-			
-			$this->append($link_el, $attrs['href']);
-		}
-		// set stack[0] to current element
-		else {
-			array_unshift($this->stack, $el);
-		}
-	}
-	
-
-	
-	function feed_cdata ($p, $text) {
-		
-		if ($this->feed_type == ATOM and $this->incontent) 
-		{
-			$this->append_content( $text );
-		}
-		else {
-			$current_el = join('_', array_reverse($this->stack));
-			$this->append($current_el, $text);
-		}
-	}
-	
-	function feed_end_element ($p, $el) {
-		$el = strtolower($el);
-		
-		if ( $el == 'item' or $el == 'entry' ) 
-		{
-			$this->items[] = $this->current_item;
-			$this->current_item = array();
-			$this->initem = false;
-		}
-		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' ) 
-		{
-			$this->intextinput = false;
-		}
-		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' ) 
-		{
-			$this->inimage = false;
-		}
-		elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
-		{	
-			$this->incontent = false;
-		}
-		elseif ($el == 'channel' or $el == 'feed' ) 
-		{
-			$this->inchannel = false;
-		}
-		elseif ($this->feed_type == ATOM and $this->incontent  ) {
-			// balance tags properly
-			// note:  i don't think this is actually neccessary
-			if ( $this->stack[0] == $el ) 
-			{
-				$this->append_content("</$el>");
-			}
-			else {
-				$this->append_content("<$el />");
-			}
-
-			array_shift( $this->stack );
-		}
-		else {
-			array_shift( $this->stack );
-		}
-		
-		$this->current_namespace = false;
-	}
-	
-	function concat (&$str1, $str2="") {
-		if (!isset($str1) ) {
-			$str1="";
-		}
-		$str1 .= $str2;
-	}
-	
-	function append_content($text) {
-		if ( $this->initem ) {
-			$this->concat( $this->current_item[ $this->incontent ], $text );
-		}
-		elseif ( $this->inchannel ) {
-			$this->concat( $this->channel[ $this->incontent ], $text );
-		}
-	}
-	
-	// smart append - field and namespace aware
-	function append($el, $text) {
-		if (!$el) {
-			return;
-		}
-		if ( $this->current_namespace ) 
-		{
-			if ( $this->initem ) {
-				$this->concat(
-					$this->current_item[ $this->current_namespace ][ $el ], $text);
-			}
-			elseif ($this->inchannel) {
-				$this->concat(
-					$this->channel[ $this->current_namespace][ $el ], $text );
-			}
-			elseif ($this->intextinput) {
-				$this->concat(
-					$this->textinput[ $this->current_namespace][ $el ], $text );
-			}
-			elseif ($this->inimage) {
-				$this->concat(
-					$this->image[ $this->current_namespace ][ $el ], $text );
-			}
-		}
-		else {
-			if ( $this->initem ) {
-				$this->concat(
-					$this->current_item[ $el ], $text);
-			}
-			elseif ($this->intextinput) {
-				$this->concat(
-					$this->textinput[ $el ], $text );
-			}
-			elseif ($this->inimage) {
-				$this->concat(
-					$this->image[ $el ], $text );
-			}
-			elseif ($this->inchannel) {
-				$this->concat(
-					$this->channel[ $el ], $text );
-			}
-			
-		}
-	}
-	
-	function normalize () {
-		// if atom populate rss fields
-		if ( $this->is_atom() ) {
-			$this->channel['descripton'] = $this->channel['tagline'];
-			for ( $i = 0; $i < count($this->items); $i++) {
-				$item = $this->items[$i];
-				if ( isset($item['summary']) )
-					$item['description'] = $item['summary'];
-				if ( isset($item['atom_content']))
-					$item['content']['encoded'] = $item['atom_content'];
-				
-				$this->items[$i] = $item;
-			}		
-		}
-		elseif ( $this->is_rss() ) {
-			$this->channel['tagline'] = $this->channel['description'];
-			for ( $i = 0; $i < count($this->items); $i++) {
-				$item = $this->items[$i];
-				if ( isset($item['description']))
-					$item['summary'] = $item['description'];
-				if ( isset($item['content']['encoded'] ) )
-					$item['atom_content'] = $item['content']['encoded'];
-			
-				$this->items[$i] = $item;
-			}
-		}
-	}
-	
-	function is_rss () {
-		if ( $this->feed_type == RSS ) {
-			return $this->feed_version;	
-		}
-		else {
-			return false;
-		}
-	}
-	
-	function is_atom() {
-		if ( $this->feed_type == ATOM ) {
-			return $this->feed_version;
-		}
-		else {
-			return false;
-		}
-	}
-
-	function map_attrs($k, $v) {
-		return "$k=\"$v\"";
-	}
-
-	function error( $errormsg, $lvl = E_USER_WARNING ) {
-		// append PHP's error message if track_errors enabled
-		if ( isset($php_errormsg) ) {
-			$errormsg .= " ($php_errormsg)";
-		}
-		if ( MAGPIE_DEBUG ) {
-			trigger_error( $errormsg, $lvl);
-		} else {
-			error_log( $errormsg, 0);
-		}
-	}
-
-}
-require_once( dirname(__FILE__) . '/class-snoopy.php');
-
-function fetch_rss ($url) {
-	// initialize constants
-	init();
-	
-	if ( !isset($url) ) {
-		// error("fetch_rss called without a url");
-		return false;
-	}
-	
-	// if cache is disabled
-	if ( !MAGPIE_CACHE_ON ) {
-		// fetch file, and parse it
-		$resp = _fetch_remote_file( $url );
-		if ( is_success( $resp->status ) ) {
-			return _response_to_rss( $resp );
-		}
-		else {
-			// error("Failed to fetch $url and cache is off");
-			return false;
-		}
-	} 
-	// else cache is ON
-	else {
-		// Flow
-		// 1. check cache
-		// 2. if there is a hit, make sure its fresh
-		// 3. if cached obj fails freshness check, fetch remote
-		// 4. if remote fails, return stale object, or error
-		
-		$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
-		
-		if (MAGPIE_DEBUG and $cache->ERROR) {
-			debug($cache->ERROR, E_USER_WARNING);
-		}
-		
-		
-		$cache_status 	 = 0;		// response of check_cache
-		$request_headers = array(); // HTTP headers to send with fetch
-		$rss 			 = 0;		// parsed RSS object
-		$errormsg		 = 0;		// errors, if any
-		
-		if (!$cache->ERROR) {
-			// return cache HIT, MISS, or STALE
-			$cache_status = $cache->check_cache( $url );
-		}
-
-		// if object cached, and cache is fresh, return cached obj
-		if ( $cache_status == 'HIT' ) {
-			$rss = $cache->get( $url );
-			if ( isset($rss) and $rss ) {
-				$rss->from_cache = 1;
-				if ( MAGPIE_DEBUG > 1) {
-				debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
-			}
-				return $rss;
-			}
-		}
-		
-		// else attempt a conditional get
-		
-		// setup headers
-		if ( $cache_status == 'STALE' ) {
-			$rss = $cache->get( $url );
-			if ( $rss->etag and $rss->last_modified ) {
-				$request_headers['If-None-Match'] = $rss->etag;
-				$request_headers['If-Last-Modified'] = $rss->last_modified;
-			}
-		}
-		
-		$resp = _fetch_remote_file( $url, $request_headers );
-		
-		if (isset($resp) and $resp) {
-			if ($resp->status == '304' ) {
-				// we have the most current copy
-				if ( MAGPIE_DEBUG > 1) {
-					debug("Got 304 for $url");
-				}
-				// reset cache on 304 (at minutillo insistent prodding)
-				$cache->set($url, $rss);
-				return $rss;
-			}
-			elseif ( is_success( $resp->status ) ) {
-				$rss = _response_to_rss( $resp );
-				if ( $rss ) {
-					if (MAGPIE_DEBUG > 1) {
-						debug("Fetch successful");
-					}
-					// add object to cache
-					$cache->set( $url, $rss );
-					return $rss;
-				}
-			}
-			else {
-				$errormsg = "Failed to fetch $url. ";
-				if ( $resp->error ) {
-					# compensate for Snoopy's annoying habbit to tacking
-					# on '\n'
-					$http_error = substr($resp->error, 0, -2); 
-					$errormsg .= "(HTTP Error: $http_error)";
-				}
-				else {
-					$errormsg .=  "(HTTP Response: " . $resp->response_code .')';
-				}
-			}
-		}
-		else {
-			$errormsg = "Unable to retrieve RSS file for unknown reasons.";
-		}
-		
-		// else fetch failed
-		
-		// attempt to return cached object
-		if ($rss) {
-			if ( MAGPIE_DEBUG ) {
-				debug("Returning STALE object for $url");
-			}
-			return $rss;
-		}
-		
-		// else we totally failed
-		// error( $errormsg );	
-		
-		return false;
-		
-	} // end if ( !MAGPIE_CACHE_ON ) {
-} // end fetch_rss()
-
-function _fetch_remote_file ($url, $headers = "" ) {
-	// Snoopy is an HTTP client in PHP
-	$client = new Snoopy();
-	$client->agent = MAGPIE_USER_AGENT;
-	$client->read_timeout = MAGPIE_FETCH_TIME_OUT;
-	$client->use_gzip = MAGPIE_USE_GZIP;
-	if (is_array($headers) ) {
-		$client->rawheaders = $headers;
-	}
-	
-	@$client->fetch($url);
-	return $client;
-
-}
-
-function _response_to_rss ($resp) {
-	$rss = new MagpieRSS( $resp->results );
-	
-	// if RSS parsed successfully		
-	if ( $rss and !$rss->ERROR) {
-		
-		// find Etag, and Last-Modified
-		foreach($resp->headers as $h) {
-			// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
-			if (strpos($h, ": ")) {
-				list($field, $val) = explode(": ", $h, 2);
-			}
-			else {
-				$field = $h;
-				$val = "";
-			}
-			
-			if ( $field == 'ETag' ) {
-				$rss->etag = $val;
-			}
-			
-			if ( $field == 'Last-Modified' ) {
-				$rss->last_modified = $val;
-			}
-		}
-		
-		return $rss;	
-	} // else construct error message
-	else {
-		$errormsg = "Failed to parse RSS file.";
-		
-		if ($rss) {
-			$errormsg .= " (" . $rss->ERROR . ")";
-		}
-		// error($errormsg);
-		
-		return false;
-	} // end if ($rss and !$rss->error)
-}
-
-/*=======================================================================*\
-	Function:	init
-	Purpose:	setup constants with default values
-				check for user overrides
-\*=======================================================================*/
-function init () {
-	if ( defined('MAGPIE_INITALIZED') ) {
-		return;
-	}
-	else {
-		define('MAGPIE_INITALIZED', 1);
-	}
-	
-	if ( !defined('MAGPIE_CACHE_ON') ) {
-		define('MAGPIE_CACHE_ON', 1);
-	}
-
-	if ( !defined('MAGPIE_CACHE_DIR') ) {
-		define('MAGPIE_CACHE_DIR', './cache');
-	}
-
-	if ( !defined('MAGPIE_CACHE_AGE') ) {
-		define('MAGPIE_CACHE_AGE', 60*60); // one hour
-	}
-
-	if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
-		define('MAGPIE_CACHE_FRESH_ONLY', 0);
-	}
-	
-		if ( !defined('MAGPIE_DEBUG') ) {
-		define('MAGPIE_DEBUG', 0);
-	}
-
-	if ( !defined('MAGPIE_USER_AGENT') ) {
-		$ua = 'WordPress/' . $wp_version;
-		
-		if ( MAGPIE_CACHE_ON ) {
-			$ua = $ua . ')';
-		}
-		else {
-			$ua = $ua . '; No cache)';
-		}
-		
-		define('MAGPIE_USER_AGENT', $ua);
-	}
-	
-	if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
-		define('MAGPIE_FETCH_TIME_OUT', 2);	// 2 second timeout
-	}
-	
-	// use gzip encoding to fetch rss files if supported?
-	if ( !defined('MAGPIE_USE_GZIP') ) {
-		define('MAGPIE_USE_GZIP', true);	
-	}
-}
-
-function is_info ($sc) { 
-	return $sc >= 100 && $sc < 200; 
-}
-
-function is_success ($sc) { 
-	return $sc >= 200 && $sc < 300; 
-}
-
-function is_redirect ($sc) { 
-	return $sc >= 300 && $sc < 400; 
-}
-
-function is_error ($sc) { 
-	return $sc >= 400 && $sc < 600; 
-}
-
-function is_client_error ($sc) { 
-	return $sc >= 400 && $sc < 500; 
-}
-
-function is_server_error ($sc) { 
-	return $sc >= 500 && $sc < 600; 
-}
-
-class RSSCache {
-	var $BASE_CACHE = 'wp-content/cache';	// where the cache files are stored
-	var $MAX_AGE	= 43200;  		// when are files stale, default twelve hours
-	var $ERROR 		= '';			// accumulate error messages
-	
-	function RSSCache ($base='', $age='') {
-		if ( $base ) {
-			$this->BASE_CACHE = $base;
-		}
-		if ( $age ) {
-			$this->MAX_AGE = $age;
-		}
-	
-	}
-	
-/*=======================================================================*\
-	Function:	set
-	Purpose:	add an item to the cache, keyed on url
-	Input:		url from wich the rss file was fetched
-	Output:		true on sucess	
-\*=======================================================================*/
-	function set ($url, $rss) {
-		global $wpdb;
-		$cache_option = 'rss_' . $this->file_name( $url );
-		$cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
-		
-		if ( !$wpdb->get_var("SELECT option_name FROM $wpdb->options WHERE option_name = '$cache_option'") )
-			add_option($cache_option, '', '', 'no');
-		if ( !$wpdb->get_var("SELECT option_name FROM $wpdb->options WHERE option_name = '$cache_timestamp'") )
-			add_option($cache_timestamp, '', '', 'no');
-		
-		update_option($cache_option, $rss);
-		update_option($cache_timestamp, time() );
-		
-		return $cache_option;
-	}
-	
-/*=======================================================================*\
-	Function:	get
-	Purpose:	fetch an item from the cache
-	Input:		url from wich the rss file was fetched
-	Output:		cached object on HIT, false on MISS	
-\*=======================================================================*/	
-	function get ($url) {
-		$this->ERROR = "";
-		$cache_option = 'rss_' . $this->file_name( $url );
-		
-		if ( ! get_option( $cache_option ) ) {
-			$this->debug( 
-				"Cache doesn't contain: $url (cache option: $cache_option)"
-			);
-			return 0;
-		}
-		
-		$rss = get_option( $cache_option );
-		
-		return $rss;
-	}
-
-/*=======================================================================*\
-	Function:	check_cache
-	Purpose:	check a url for membership in the cache
-				and whether the object is older then MAX_AGE (ie. STALE)
-	Input:		url from wich the rss file was fetched
-	Output:		cached object on HIT, false on MISS	
-\*=======================================================================*/		
-	function check_cache ( $url ) {
-		$this->ERROR = "";
-		$cache_option = $this->file_name( $url );
-		$cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
-
-		if ( $mtime = get_option($cache_timestamp) ) {
-			// find how long ago the file was added to the cache
-			// and whether that is longer then MAX_AGE
-			$age = time() - $mtime;
-			if ( $this->MAX_AGE > $age ) {
-				// object exists and is current
-				return 'HIT';
-			}
-			else {
-				// object exists but is old
-				return 'STALE';
-			}
-		}
-		else {
-			// object does not exist
-			return 'MISS';
-		}
-	}
-
-/*=======================================================================*\
-	Function:	serialize
-\*=======================================================================*/		
-	function serialize ( $rss ) {
-		return serialize( $rss );
-	}
-
-/*=======================================================================*\
-	Function:	unserialize
-\*=======================================================================*/		
-	function unserialize ( $data ) {
-		return unserialize( $data );
-	}
-	
-/*=======================================================================*\
-	Function:	file_name
-	Purpose:	map url to location in cache
-	Input:		url from wich the rss file was fetched
-	Output:		a file name
-\*=======================================================================*/		
-	function file_name ($url) {
-		return md5( $url );
-	}
-	
-/*=======================================================================*\
-	Function:	error
-	Purpose:	register error
-\*=======================================================================*/			
-	function error ($errormsg, $lvl=E_USER_WARNING) {
-		// append PHP's error message if track_errors enabled
-		if ( isset($php_errormsg) ) { 
-			$errormsg .= " ($php_errormsg)";
-		}
-		$this->ERROR = $errormsg;
-		if ( MAGPIE_DEBUG ) {
-			trigger_error( $errormsg, $lvl);
-		}
-		else {
-			error_log( $errormsg, 0);
-		}
-	}
-			function debug ($debugmsg, $lvl=E_USER_NOTICE) {
-		if ( MAGPIE_DEBUG ) {
-			$this->error("MagpieRSS [debug] $debugmsg", $lvl);
-		}
-	}
-}
-
-function parse_w3cdtf ( $date_str ) {
-	
-	# regex to match wc3dtf
-	$pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
-	
-	if ( preg_match( $pat, $date_str, $match ) ) {
-		list( $year, $month, $day, $hours, $minutes, $seconds) = 
-			array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
-		
-		# calc epoch for current date assuming GMT
-		$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
-		
-		$offset = 0;
-		if ( $match[10] == 'Z' ) {
-			# zulu time, aka GMT
-		}
-		else {
-			list( $tz_mod, $tz_hour, $tz_min ) =
-				array( $match[8], $match[9], $match[10]);
-			
-			# zero out the variables
-			if ( ! $tz_hour ) { $tz_hour = 0; }
-			if ( ! $tz_min ) { $tz_min = 0; }
-		
-			$offset_secs = (($tz_hour*60)+$tz_min)*60;
-			
-			# is timezone ahead of GMT?  then subtract offset
-			#
-			if ( $tz_mod == '+' ) {
-				$offset_secs = $offset_secs * -1;
-			}
-			
-			$offset = $offset_secs;	
-		}
-		$epoch = $epoch + $offset;
-		return $epoch;
-	}
-	else {
-		return -1;
-	}
-	}
-function wp_rss ($url, $num) {
-	//ini_set("display_errors", false); uncomment to suppress php errors thrown if the feed is not returned.
-	$num_items = $num;
-	$rss = fetch_rss($url);
-		if ( $rss ) {
-			echo "<ul>";
-			$rss->items = array_slice($rss->items, 0, $num_items);
-				foreach ($rss->items as $item ) {
-					echo "<li>\n";
-					echo "<a href='$item[link]' title='$item[description]'>";
-					echo htmlentities($item['title']);
-					echo "</a><br />\n";
-					echo "</li>\n";
-				}		
-			echo "</ul>";
-	}
-		else {
-			echo "an error has occured the feed is probably down, try again later.";
-	}
-}
-
-function get_rss ($uri, $num = 5) { // Like get posts, but for RSS
-	$rss = fetch_rss($url);
-	if ( $rss ) {
-		$rss->items = array_slice($rss->items, 0, $num_items);
-		foreach ($rss->items as $item ) {
-			echo "<li>\n";
-			echo "<a href='$item[link]' title='$item[description]'>";
-			echo htmlentities($item['title']);
-			echo "</a><br />\n";
-			echo "</li>\n";
-		}
-		return $posts;
-	} else {
-		return false;
-	}
-}
-?>
\ No newline at end of file
+// Deprecated.  Use rss.php instead.
+require_once (ABSPATH . WPINC . '/rss.php');
+?>
diff -ruN 2.0.5/wp-includes/rss.php 2.2.2/wp-includes/rss.php
--- 2.0.5/wp-includes/rss.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/rss.php	2007-03-07 11:04:03.000000000 -0600
@@ -0,0 +1,854 @@
+<?php
+/*
+ * Project:     MagpieRSS: a simple RSS integration tool
+ * File:        A compiled file for RSS syndication
+ * Author:      Kellan Elliott-McCrea <kellan@protest.net>
+ * Version:		0.51
+ * License:		GPL
+ */
+
+define('RSS', 'RSS');
+define('ATOM', 'Atom');
+define('MAGPIE_USER_AGENT', 'WordPress/' . $wp_version);
+
+class MagpieRSS {
+	var $parser;
+	var $current_item	= array();	// item currently being parsed
+	var $items			= array();	// collection of parsed items
+	var $channel		= array();	// hash of channel fields
+	var $textinput		= array();
+	var $image			= array();
+	var $feed_type;
+	var $feed_version;
+
+	// parser variables
+	var $stack				= array(); // parser stack
+	var $inchannel			= false;
+	var $initem 			= false;
+	var $incontent			= false; // if in Atom <content mode="xml"> field
+	var $intextinput		= false;
+	var $inimage 			= false;
+	var $current_field		= '';
+	var $current_namespace	= false;
+
+	//var $ERROR = "";
+
+	var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
+
+	function MagpieRSS ($source) {
+
+		# if PHP xml isn't compiled in, die
+		#
+		if ( !function_exists('xml_parser_create') )
+			trigger_error( "Failed to load PHP's XML Extension. http://www.php.net/manual/en/ref.xml.php" );
+
+		$parser = @xml_parser_create();
+
+		if ( !is_resource($parser) )
+			trigger_error( "Failed to create an instance of PHP's XML parser. http://www.php.net/manual/en/ref.xml.php");
+
+
+		$this->parser = $parser;
+
+		# pass in parser, and a reference to this object
+		# setup handlers
+		#
+		xml_set_object( $this->parser, $this );
+		xml_set_element_handler($this->parser,
+				'feed_start_element', 'feed_end_element' );
+
+		xml_set_character_data_handler( $this->parser, 'feed_cdata' );
+
+		$status = xml_parse( $this->parser, $source );
+
+		if (! $status ) {
+			$errorcode = xml_get_error_code( $this->parser );
+			if ( $errorcode != XML_ERROR_NONE ) {
+				$xml_error = xml_error_string( $errorcode );
+				$error_line = xml_get_current_line_number($this->parser);
+				$error_col = xml_get_current_column_number($this->parser);
+				$errormsg = "$xml_error at line $error_line, column $error_col";
+
+				$this->error( $errormsg );
+			}
+		}
+
+		xml_parser_free( $this->parser );
+
+		$this->normalize();
+	}
+
+	function feed_start_element($p, $element, &$attrs) {
+		$el = $element = strtolower($element);
+		$attrs = array_change_key_case($attrs, CASE_LOWER);
+
+		// check for a namespace, and split if found
+		$ns	= false;
+		if ( strpos( $element, ':' ) ) {
+			list($ns, $el) = split( ':', $element, 2);
+		}
+		if ( $ns and $ns != 'rdf' ) {
+			$this->current_namespace = $ns;
+		}
+
+		# if feed type isn't set, then this is first element of feed
+		# identify feed from root element
+		#
+		if (!isset($this->feed_type) ) {
+			if ( $el == 'rdf' ) {
+				$this->feed_type = RSS;
+				$this->feed_version = '1.0';
+			}
+			elseif ( $el == 'rss' ) {
+				$this->feed_type = RSS;
+				$this->feed_version = $attrs['version'];
+			}
+			elseif ( $el == 'feed' ) {
+				$this->feed_type = ATOM;
+				$this->feed_version = $attrs['version'];
+				$this->inchannel = true;
+			}
+			return;
+		}
+
+		if ( $el == 'channel' )
+		{
+			$this->inchannel = true;
+		}
+		elseif ($el == 'item' or $el == 'entry' )
+		{
+			$this->initem = true;
+			if ( isset($attrs['rdf:about']) ) {
+				$this->current_item['about'] = $attrs['rdf:about'];
+			}
+		}
+
+		// if we're in the default namespace of an RSS feed,
+		//  record textinput or image fields
+		elseif (
+			$this->feed_type == RSS and
+			$this->current_namespace == '' and
+			$el == 'textinput' )
+		{
+			$this->intextinput = true;
+		}
+
+		elseif (
+			$this->feed_type == RSS and
+			$this->current_namespace == '' and
+			$el == 'image' )
+		{
+			$this->inimage = true;
+		}
+
+		# handle atom content constructs
+		elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
+		{
+			// avoid clashing w/ RSS mod_content
+			if ($el == 'content' ) {
+				$el = 'atom_content';
+			}
+
+			$this->incontent = $el;
+
+
+		}
+
+		// if inside an Atom content construct (e.g. content or summary) field treat tags as text
+		elseif ($this->feed_type == ATOM and $this->incontent )
+		{
+			// if tags are inlined, then flatten
+			$attrs_str = join(' ',
+					array_map('map_attrs',
+					array_keys($attrs),
+					array_values($attrs) ) );
+
+			$this->append_content( "<$element $attrs_str>"  );
+
+			array_unshift( $this->stack, $el );
+		}
+
+		// Atom support many links per containging element.
+		// Magpie treats link elements of type rel='alternate'
+		// as being equivalent to RSS's simple link element.
+		//
+		elseif ($this->feed_type == ATOM and $el == 'link' )
+		{
+			if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
+			{
+				$link_el = 'link';
+			}
+			else {
+				$link_el = 'link_' . $attrs['rel'];
+			}
+
+			$this->append($link_el, $attrs['href']);
+		}
+		// set stack[0] to current element
+		else {
+			array_unshift($this->stack, $el);
+		}
+	}
+
+
+
+	function feed_cdata ($p, $text) {
+
+		if ($this->feed_type == ATOM and $this->incontent)
+		{
+			$this->append_content( $text );
+		}
+		else {
+			$current_el = join('_', array_reverse($this->stack));
+			$this->append($current_el, $text);
+		}
+	}
+
+	function feed_end_element ($p, $el) {
+		$el = strtolower($el);
+
+		if ( $el == 'item' or $el == 'entry' )
+		{
+			$this->items[] = $this->current_item;
+			$this->current_item = array();
+			$this->initem = false;
+		}
+		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
+		{
+			$this->intextinput = false;
+		}
+		elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
+		{
+			$this->inimage = false;
+		}
+		elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
+		{
+			$this->incontent = false;
+		}
+		elseif ($el == 'channel' or $el == 'feed' )
+		{
+			$this->inchannel = false;
+		}
+		elseif ($this->feed_type == ATOM and $this->incontent  ) {
+			// balance tags properly
+			// note:  i don't think this is actually neccessary
+			if ( $this->stack[0] == $el )
+			{
+				$this->append_content("</$el>");
+			}
+			else {
+				$this->append_content("<$el />");
+			}
+
+			array_shift( $this->stack );
+		}
+		else {
+			array_shift( $this->stack );
+		}
+
+		$this->current_namespace = false;
+	}
+
+	function concat (&$str1, $str2="") {
+		if (!isset($str1) ) {
+			$str1="";
+		}
+		$str1 .= $str2;
+	}
+
+	function append_content($text) {
+		if ( $this->initem ) {
+			$this->concat( $this->current_item[ $this->incontent ], $text );
+		}
+		elseif ( $this->inchannel ) {
+			$this->concat( $this->channel[ $this->incontent ], $text );
+		}
+	}
+
+	// smart append - field and namespace aware
+	function append($el, $text) {
+		if (!$el) {
+			return;
+		}
+		if ( $this->current_namespace )
+		{
+			if ( $this->initem ) {
+				$this->concat(
+					$this->current_item[ $this->current_namespace ][ $el ], $text);
+			}
+			elseif ($this->inchannel) {
+				$this->concat(
+					$this->channel[ $this->current_namespace][ $el ], $text );
+			}
+			elseif ($this->intextinput) {
+				$this->concat(
+					$this->textinput[ $this->current_namespace][ $el ], $text );
+			}
+			elseif ($this->inimage) {
+				$this->concat(
+					$this->image[ $this->current_namespace ][ $el ], $text );
+			}
+		}
+		else {
+			if ( $this->initem ) {
+				$this->concat(
+					$this->current_item[ $el ], $text);
+			}
+			elseif ($this->intextinput) {
+				$this->concat(
+					$this->textinput[ $el ], $text );
+			}
+			elseif ($this->inimage) {
+				$this->concat(
+					$this->image[ $el ], $text );
+			}
+			elseif ($this->inchannel) {
+				$this->concat(
+					$this->channel[ $el ], $text );
+			}
+
+		}
+	}
+
+	function normalize () {
+		// if atom populate rss fields
+		if ( $this->is_atom() ) {
+			$this->channel['descripton'] = $this->channel['tagline'];
+			for ( $i = 0; $i < count($this->items); $i++) {
+				$item = $this->items[$i];
+				if ( isset($item['summary']) )
+					$item['description'] = $item['summary'];
+				if ( isset($item['atom_content']))
+					$item['content']['encoded'] = $item['atom_content'];
+
+				$this->items[$i] = $item;
+			}
+		}
+		elseif ( $this->is_rss() ) {
+			$this->channel['tagline'] = $this->channel['description'];
+			for ( $i = 0; $i < count($this->items); $i++) {
+				$item = $this->items[$i];
+				if ( isset($item['description']))
+					$item['summary'] = $item['description'];
+				if ( isset($item['content']['encoded'] ) )
+					$item['atom_content'] = $item['content']['encoded'];
+
+				$this->items[$i] = $item;
+			}
+		}
+	}
+
+	function is_rss () {
+		if ( $this->feed_type == RSS ) {
+			return $this->feed_version;
+		}
+		else {
+			return false;
+		}
+	}
+
+	function is_atom() {
+		if ( $this->feed_type == ATOM ) {
+			return $this->feed_version;
+		}
+		else {
+			return false;
+		}
+	}
+
+	function map_attrs($k, $v) {
+		return "$k=\"$v\"";
+	}
+
+	function error( $errormsg, $lvl = E_USER_WARNING ) {
+		// append PHP's error message if track_errors enabled
+		if ( isset($php_errormsg) ) {
+			$errormsg .= " ($php_errormsg)";
+		}
+		if ( MAGPIE_DEBUG ) {
+			trigger_error( $errormsg, $lvl);
+		} else {
+			error_log( $errormsg, 0);
+		}
+	}
+
+}
+require_once( dirname(__FILE__) . '/class-snoopy.php');
+
+function fetch_rss ($url) {
+	// initialize constants
+	init();
+
+	if ( !isset($url) ) {
+		// error("fetch_rss called without a url");
+		return false;
+	}
+
+	// if cache is disabled
+	if ( !MAGPIE_CACHE_ON ) {
+		// fetch file, and parse it
+		$resp = _fetch_remote_file( $url );
+		if ( is_success( $resp->status ) ) {
+			return _response_to_rss( $resp );
+		}
+		else {
+			// error("Failed to fetch $url and cache is off");
+			return false;
+		}
+	}
+	// else cache is ON
+	else {
+		// Flow
+		// 1. check cache
+		// 2. if there is a hit, make sure its fresh
+		// 3. if cached obj fails freshness check, fetch remote
+		// 4. if remote fails, return stale object, or error
+
+		$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
+
+		if (MAGPIE_DEBUG and $cache->ERROR) {
+			debug($cache->ERROR, E_USER_WARNING);
+		}
+
+
+		$cache_status 	 = 0;		// response of check_cache
+		$request_headers = array(); // HTTP headers to send with fetch
+		$rss 			 = 0;		// parsed RSS object
+		$errormsg		 = 0;		// errors, if any
+
+		if (!$cache->ERROR) {
+			// return cache HIT, MISS, or STALE
+			$cache_status = $cache->check_cache( $url );
+		}
+
+		// if object cached, and cache is fresh, return cached obj
+		if ( $cache_status == 'HIT' ) {
+			$rss = $cache->get( $url );
+			if ( isset($rss) and $rss ) {
+				$rss->from_cache = 1;
+				if ( MAGPIE_DEBUG > 1) {
+				debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
+			}
+				return $rss;
+			}
+		}
+
+		// else attempt a conditional get
+
+		// setup headers
+		if ( $cache_status == 'STALE' ) {
+			$rss = $cache->get( $url );
+			if ( $rss->etag and $rss->last_modified ) {
+				$request_headers['If-None-Match'] = $rss->etag;
+				$request_headers['If-Last-Modified'] = $rss->last_modified;
+			}
+		}
+
+		$resp = _fetch_remote_file( $url, $request_headers );
+
+		if (isset($resp) and $resp) {
+			if ($resp->status == '304' ) {
+				// we have the most current copy
+				if ( MAGPIE_DEBUG > 1) {
+					debug("Got 304 for $url");
+				}
+				// reset cache on 304 (at minutillo insistent prodding)
+				$cache->set($url, $rss);
+				return $rss;
+			}
+			elseif ( is_success( $resp->status ) ) {
+				$rss = _response_to_rss( $resp );
+				if ( $rss ) {
+					if (MAGPIE_DEBUG > 1) {
+						debug("Fetch successful");
+					}
+					// add object to cache
+					$cache->set( $url, $rss );
+					return $rss;
+				}
+			}
+			else {
+				$errormsg = "Failed to fetch $url. ";
+				if ( $resp->error ) {
+					# compensate for Snoopy's annoying habbit to tacking
+					# on '\n'
+					$http_error = substr($resp->error, 0, -2);
+					$errormsg .= "(HTTP Error: $http_error)";
+				}
+				else {
+					$errormsg .=  "(HTTP Response: " . $resp->response_code .')';
+				}
+			}
+		}
+		else {
+			$errormsg = "Unable to retrieve RSS file for unknown reasons.";
+		}
+
+		// else fetch failed
+
+		// attempt to return cached object
+		if ($rss) {
+			if ( MAGPIE_DEBUG ) {
+				debug("Returning STALE object for $url");
+			}
+			return $rss;
+		}
+
+		// else we totally failed
+		// error( $errormsg );
+
+		return false;
+
+	} // end if ( !MAGPIE_CACHE_ON ) {
+} // end fetch_rss()
+
+function _fetch_remote_file ($url, $headers = "" ) {
+	// Snoopy is an HTTP client in PHP
+	$client = new Snoopy();
+	$client->agent = MAGPIE_USER_AGENT;
+	$client->read_timeout = MAGPIE_FETCH_TIME_OUT;
+	$client->use_gzip = MAGPIE_USE_GZIP;
+	if (is_array($headers) ) {
+		$client->rawheaders = $headers;
+	}
+
+	@$client->fetch($url);
+	return $client;
+
+}
+
+function _response_to_rss ($resp) {
+	$rss = new MagpieRSS( $resp->results );
+
+	// if RSS parsed successfully
+	if ( $rss and !$rss->ERROR) {
+
+		// find Etag, and Last-Modified
+		foreach($resp->headers as $h) {
+			// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
+			if (strpos($h, ": ")) {
+				list($field, $val) = explode(": ", $h, 2);
+			}
+			else {
+				$field = $h;
+				$val = "";
+			}
+
+			if ( $field == 'ETag' ) {
+				$rss->etag = $val;
+			}
+
+			if ( $field == 'Last-Modified' ) {
+				$rss->last_modified = $val;
+			}
+		}
+
+		return $rss;
+	} // else construct error message
+	else {
+		$errormsg = "Failed to parse RSS file.";
+
+		if ($rss) {
+			$errormsg .= " (" . $rss->ERROR . ")";
+		}
+		// error($errormsg);
+
+		return false;
+	} // end if ($rss and !$rss->error)
+}
+
+/*=======================================================================*\
+	Function:	init
+	Purpose:	setup constants with default values
+				check for user overrides
+\*=======================================================================*/
+function init () {
+	if ( defined('MAGPIE_INITALIZED') ) {
+		return;
+	}
+	else {
+		define('MAGPIE_INITALIZED', 1);
+	}
+
+	if ( !defined('MAGPIE_CACHE_ON') ) {
+		define('MAGPIE_CACHE_ON', 1);
+	}
+
+	if ( !defined('MAGPIE_CACHE_DIR') ) {
+		define('MAGPIE_CACHE_DIR', './cache');
+	}
+
+	if ( !defined('MAGPIE_CACHE_AGE') ) {
+		define('MAGPIE_CACHE_AGE', 60*60); // one hour
+	}
+
+	if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
+		define('MAGPIE_CACHE_FRESH_ONLY', 0);
+	}
+
+		if ( !defined('MAGPIE_DEBUG') ) {
+		define('MAGPIE_DEBUG', 0);
+	}
+
+	if ( !defined('MAGPIE_USER_AGENT') ) {
+		$ua = 'WordPress/' . $wp_version;
+
+		if ( MAGPIE_CACHE_ON ) {
+			$ua = $ua . ')';
+		}
+		else {
+			$ua = $ua . '; No cache)';
+		}
+
+		define('MAGPIE_USER_AGENT', $ua);
+	}
+
+	if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
+		define('MAGPIE_FETCH_TIME_OUT', 2);	// 2 second timeout
+	}
+
+	// use gzip encoding to fetch rss files if supported?
+	if ( !defined('MAGPIE_USE_GZIP') ) {
+		define('MAGPIE_USE_GZIP', true);
+	}
+}
+
+function is_info ($sc) {
+	return $sc >= 100 && $sc < 200;
+}
+
+function is_success ($sc) {
+	return $sc >= 200 && $sc < 300;
+}
+
+function is_redirect ($sc) {
+	return $sc >= 300 && $sc < 400;
+}
+
+function is_error ($sc) {
+	return $sc >= 400 && $sc < 600;
+}
+
+function is_client_error ($sc) {
+	return $sc >= 400 && $sc < 500;
+}
+
+function is_server_error ($sc) {
+	return $sc >= 500 && $sc < 600;
+}
+
+class RSSCache {
+	var $BASE_CACHE = 'wp-content/cache';	// where the cache files are stored
+	var $MAX_AGE	= 43200;  		// when are files stale, default twelve hours
+	var $ERROR 		= '';			// accumulate error messages
+
+	function RSSCache ($base='', $age='') {
+		if ( $base ) {
+			$this->BASE_CACHE = $base;
+		}
+		if ( $age ) {
+			$this->MAX_AGE = $age;
+		}
+
+	}
+
+/*=======================================================================*\
+	Function:	set
+	Purpose:	add an item to the cache, keyed on url
+	Input:		url from wich the rss file was fetched
+	Output:		true on sucess
+\*=======================================================================*/
+	function set ($url, $rss) {
+		global $wpdb;
+		$cache_option = 'rss_' . $this->file_name( $url );
+		$cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
+
+		if ( !$wpdb->get_var("SELECT option_name FROM $wpdb->options WHERE option_name = '$cache_option'") )
+			add_option($cache_option, '', '', 'no');
+		if ( !$wpdb->get_var("SELECT option_name FROM $wpdb->options WHERE option_name = '$cache_timestamp'") )
+			add_option($cache_timestamp, '', '', 'no');
+
+		update_option($cache_option, $rss);
+		update_option($cache_timestamp, time() );
+
+		return $cache_option;
+	}
+
+/*=======================================================================*\
+	Function:	get
+	Purpose:	fetch an item from the cache
+	Input:		url from wich the rss file was fetched
+	Output:		cached object on HIT, false on MISS
+\*=======================================================================*/
+	function get ($url) {
+		$this->ERROR = "";
+		$cache_option = 'rss_' . $this->file_name( $url );
+
+		if ( ! get_option( $cache_option ) ) {
+			$this->debug(
+				"Cache doesn't contain: $url (cache option: $cache_option)"
+			);
+			return 0;
+		}
+
+		$rss = get_option( $cache_option );
+
+		return $rss;
+	}
+
+/*=======================================================================*\
+	Function:	check_cache
+	Purpose:	check a url for membership in the cache
+				and whether the object is older then MAX_AGE (ie. STALE)
+	Input:		url from wich the rss file was fetched
+	Output:		cached object on HIT, false on MISS
+\*=======================================================================*/
+	function check_cache ( $url ) {
+		$this->ERROR = "";
+		$cache_option = $this->file_name( $url );
+		$cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
+
+		if ( $mtime = get_option($cache_timestamp) ) {
+			// find how long ago the file was added to the cache
+			// and whether that is longer then MAX_AGE
+			$age = time() - $mtime;
+			if ( $this->MAX_AGE > $age ) {
+				// object exists and is current
+				return 'HIT';
+			}
+			else {
+				// object exists but is old
+				return 'STALE';
+			}
+		}
+		else {
+			// object does not exist
+			return 'MISS';
+		}
+	}
+
+/*=======================================================================*\
+	Function:	serialize
+\*=======================================================================*/
+	function serialize ( $rss ) {
+		return serialize( $rss );
+	}
+
+/*=======================================================================*\
+	Function:	unserialize
+\*=======================================================================*/
+	function unserialize ( $data ) {
+		return unserialize( $data );
+	}
+
+/*=======================================================================*\
+	Function:	file_name
+	Purpose:	map url to location in cache
+	Input:		url from wich the rss file was fetched
+	Output:		a file name
+\*=======================================================================*/
+	function file_name ($url) {
+		return md5( $url );
+	}
+
+/*=======================================================================*\
+	Function:	error
+	Purpose:	register error
+\*=======================================================================*/
+	function error ($errormsg, $lvl=E_USER_WARNING) {
+		// append PHP's error message if track_errors enabled
+		if ( isset($php_errormsg) ) {
+			$errormsg .= " ($php_errormsg)";
+		}
+		$this->ERROR = $errormsg;
+		if ( MAGPIE_DEBUG ) {
+			trigger_error( $errormsg, $lvl);
+		}
+		else {
+			error_log( $errormsg, 0);
+		}
+	}
+			function debug ($debugmsg, $lvl=E_USER_NOTICE) {
+		if ( MAGPIE_DEBUG ) {
+			$this->error("MagpieRSS [debug] $debugmsg", $lvl);
+		}
+	}
+}
+
+function parse_w3cdtf ( $date_str ) {
+
+	# regex to match wc3dtf
+	$pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
+
+	if ( preg_match( $pat, $date_str, $match ) ) {
+		list( $year, $month, $day, $hours, $minutes, $seconds) =
+			array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7]);
+
+		# calc epoch for current date assuming GMT
+		$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
+
+		$offset = 0;
+		if ( $match[11] == 'Z' ) {
+			# zulu time, aka GMT
+		}
+		else {
+			list( $tz_mod, $tz_hour, $tz_min ) =
+				array( $match[8], $match[9], $match[10]);
+
+			# zero out the variables
+			if ( ! $tz_hour ) { $tz_hour = 0; }
+			if ( ! $tz_min ) { $tz_min = 0; }
+
+			$offset_secs = (($tz_hour*60)+$tz_min)*60;
+
+			# is timezone ahead of GMT?  then subtract offset
+			#
+			if ( $tz_mod == '+' ) {
+				$offset_secs = $offset_secs * -1;
+			}
+
+			$offset = $offset_secs;
+		}
+		$epoch = $epoch + $offset;
+		return $epoch;
+	}
+	else {
+		return -1;
+	}
+	}
+function wp_rss ($url, $num_items) {
+	//ini_set("display_errors", false); uncomment to suppress php errors thrown if the feed is not returned.
+	$rss = fetch_rss($url);
+		if ( $rss ) {
+			echo "<ul>";
+			$rss->items = array_slice($rss->items, 0, $num_items);
+				foreach ($rss->items as $item ) {
+					echo "<li>\n";
+					echo "<a href='$item[link]' title='$item[description]'>";
+					echo htmlentities($item['title']);
+					echo "</a><br />\n";
+					echo "</li>\n";
+				}
+			echo "</ul>";
+	}
+		else {
+			echo "an error has occured the feed is probably down, try again later.";
+	}
+}
+
+function get_rss ($url, $num_items = 5) { // Like get posts, but for RSS
+	$rss = fetch_rss($url);
+	if ( $rss ) {
+		$rss->items = array_slice($rss->items, 0, $num_items);
+		foreach ($rss->items as $item ) {
+			echo "<li>\n";
+			echo "<a href='$item[link]' title='$item[description]'>";
+			echo htmlentities($item['title']);
+			echo "</a><br />\n";
+			echo "</li>\n";
+		}
+	} else {
+		return false;
+	}
+}
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/script-loader.php 2.2.2/wp-includes/script-loader.php
--- 2.0.5/wp-includes/script-loader.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/script-loader.php	2007-04-17 15:56:41.000000000 -0500
@@ -0,0 +1,402 @@
+<?php
+class WP_Scripts {
+	var $scripts = array();
+	var $queue = array();
+	var $printed = array();
+	var $args = array();
+
+	function WP_Scripts() {
+		$this->default_scripts();
+	}
+
+	function default_scripts() {
+		$this->add( 'dbx', '/wp-includes/js/dbx.js', false, '2.05' );
+		$this->add( 'fat', '/wp-includes/js/fat.js', false, '1.0-RC1_3660' );
+		$this->add( 'sack', '/wp-includes/js/tw-sack.js', false, '1.6.1' );
+		$this->add( 'quicktags', '/wp-includes/js/quicktags.js', false, '3958' );
+		$this->localize( 'quicktags', 'quicktagsL10n', array(
+			'quickLinks' => __('(Quick Links)'),
+			'wordLookup' => __('Enter a word to look up:'),
+			'dictionaryLookup' => attribute_escape(__('Dictionary lookup')),
+			'lookup' => attribute_escape(__('lookup')),
+			'closeAllOpenTags' => attribute_escape(__('Close all open tags')),
+			'closeTags' => attribute_escape(__('close tags')),
+			'enterURL' => __('Enter the URL'),
+			'enterImageURL' => __('Enter the URL of the image'),
+			'enterImageDescription' => __('Enter a description of the image')
+		) );
+		$this->add( 'colorpicker', '/wp-includes/js/colorpicker.js', false, '3517' );
+		$this->add( 'tiny_mce', '/wp-includes/js/tinymce/tiny_mce_gzip.php', false, '20070326' );
+		$mce_config = apply_filters('tiny_mce_config_url', '/wp-includes/js/tinymce/tiny_mce_config.php');
+		$this->add( 'wp_tiny_mce', $mce_config, array('tiny_mce'), '20070225' );
+		$this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.5.0-0');
+		$this->add( 'autosave', '/wp-includes/js/autosave.js', array('prototype', 'sack'), '20070306');
+		$this->localize( 'autosave', 'autosaveL10n', array(
+			'autosaveInterval' => apply_filters('autosave_interval', '120'),
+			'errorText' => __('Error: %response%'),
+			'saveText' => __('Saved at %time%.'),
+			'requestFile' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php',
+			'savingText' => __('Saving Draft...')
+		) );
+		$this->add( 'wp-ajax', '/wp-includes/js/wp-ajax.js', array('prototype'), '20070306');
+		$this->localize( 'wp-ajax', 'WPAjaxL10n', array(
+			'defaultUrl' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php',
+			'permText' => __("You don't have permission to do that."),
+			'strangeText' => __("Something strange happened.  Try refreshing the page."),
+			'whoaText' => __("Slow down, I'm still sending your data!")
+		) );
+		$this->add( 'listman', '/wp-includes/js/list-manipulation.js', array('wp-ajax', 'fat'), '20070306' );
+		$this->localize( 'listman', 'listManL10n', array(
+			'jumpText' => __('Jump to new item'),
+			'delText' => __('Are you sure you want to delete this %thing%?')
+		) );
+		$this->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/wp-scriptaculous.js', array('prototype'), '1.7.0');
+		$this->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.7.0');
+		$this->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.7.0');
+		$this->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.7.0');
+		$this->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.7.0');
+		$this->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.7.0');
+		$this->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.7.0');
+		$this->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop'), '20070118');
+		$this->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.1.2');
+		$this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2');
+		if ( is_admin() ) {
+			global $pagenow;
+			$man = false;
+			switch ( $pagenow ) :
+			case 'post.php' :
+			case 'post-new.php' :
+				$man = 'postmeta';
+				break;
+			case 'page.php' :
+			case 'page-new.php' :
+				$man = 'pagemeta';
+				break;
+			case 'link-add.php' :
+			case 'link.php' :
+				$man = 'linkmeta';
+				break;
+			endswitch;
+			if ( $man ) {
+				$this->add( 'dbx-admin-key', '/wp-admin/dbx-admin-key.js', array('dbx'), '20070417' );
+				$this->localize( 'dbx-admin-key', 'dbxL10n', array(
+					'manager' => $man,
+					'open' => __('open'),
+					'close' => __('close'),
+					'moveMouse' => __('click-down and drag to move this box'),
+					'toggleMouse' => __('click to %toggle% this box'),
+					'moveKey' => __('use the arrow keys to move this box'),
+					'toggleKey' => __(', or press the enter key to %toggle% it'),
+				) );
+			}
+			$this->add( 'ajaxcat', '/wp-admin/cat.js', array('listman'), '20070417' );
+			$this->localize( 'ajaxcat', 'catL10n', array(
+				'add' => attribute_escape(__('Add')),
+				'how' => __('Separate multiple categories with commas.')
+			) );
+			$this->add( 'admin-categories', '/wp-admin/categories.js', array('listman'), '3684' );
+			$this->add( 'admin-custom-fields', '/wp-admin/custom-fields.js', array('listman'), '3733' );
+			$this->add( 'admin-comments', '/wp-admin/edit-comments.js', array('listman'), '20070327' );
+			$this->add( 'admin-users', '/wp-admin/users.js', array('listman'), '4583' );
+			$this->add( 'xfn', '/wp-admin/xfn.js', false, '3517' );
+			$this->add( 'upload', '/wp-admin/upload.js', array('prototype'), '20070306' );
+			$this->localize( 'upload', 'uploadL10n', array(
+				'browseTitle' => attribute_escape(__('Browse your files')),
+				'back' => __('&laquo; Back'),
+				'directTitle' => attribute_escape(__('Direct link to file')),
+				'edit' => __('Edit'),
+				'thumb' => __('Thumbnail'),
+				'full' => __('Full size'),
+				'icon' => __('Icon'),
+				'title' => __('Title'),
+				'show' => __('Show:'),
+				'link' => __('Link to:'),
+				'file' => __('File'),
+				'page' => __('Page'),
+				'none' => __('None'),
+				'editorText' => attribute_escape(__('Send to editor &raquo;')),
+				'insert' => __('Insert'),
+				'urlText' => __('URL'),
+				'desc' => __('Description'),
+				'deleteText' => attribute_escape(__('Delete File')),
+				'saveText' => attribute_escape(__('Save &raquo;')),
+				'confirmText' => __("Are you sure you want to delete the file '%title%'?\nClick ok to delete or cancel to go back.")
+			) );
+		}
+	}
+
+	/**
+	 * Prints script tags
+	 *
+	 * Prints the scripts passed to it or the print queue.  Also prints all necessary dependencies.
+	 *
+	 * @param mixed handles (optional) Scripts to be printed.  (void) prints queue, (string) prints that script, (array of strings) prints those scripts.
+	 * @return array Scripts that have been printed
+	 */
+	function print_scripts( $handles = false ) {
+		// Print the queue if nothing is passed.  If a string is passed, print that script.  If an array is passed, print those scripts.
+		$handles = false === $handles ? $this->queue : (array) $handles;
+		$handles = $this->all_deps( $handles );
+		$this->_print_scripts( $handles );
+		return $this->printed;
+	}
+
+	/**
+	 * Internally used helper function for printing script tags
+	 *
+	 * @param array handles Hierarchical array of scripts to be printed
+	 * @see WP_Scripts::all_deps()
+	 */
+	function _print_scripts( $handles ) {
+		global $wp_db_version;
+
+		foreach( array_keys($handles) as $handle ) {
+			if ( !$handles[$handle] )
+				return;
+			elseif ( is_array($handles[$handle]) )
+				$this->_print_scripts( $handles[$handle] );
+			if ( !in_array($handle, $this->printed) && isset($this->scripts[$handle]) ) {
+				if ( $this->scripts[$handle]->src ) { // Else it defines a group.
+					$ver = $this->scripts[$handle]->ver ? $this->scripts[$handle]->ver : $wp_db_version;
+					if ( isset($this->args[$handle]) )
+						$ver .= '&amp;' . $this->args[$handle];
+					$src = 0 === strpos($this->scripts[$handle]->src, 'http://') ? $this->scripts[$handle]->src : get_option( 'siteurl' ) . $this->scripts[$handle]->src;
+					$src = $this->scripts[$handle]->src;
+					
+					if (!preg_match('|^https?://|', $src)) {
+						$src = get_option('siteurl') . $src;
+					}
+					
+					$src = add_query_arg('ver', $ver, $src);
+					$src = clean_url(apply_filters( 'script_loader_src', $src ));
+					echo "<script type='text/javascript' src='$src'></script>\n";
+					$this->print_scripts_l10n( $handle );
+				}
+				$this->printed[] = $handle;
+			}
+		}
+	}
+
+	function print_scripts_l10n( $handle ) {
+		if ( empty($this->scripts[$handle]->l10n_object) || empty($this->scripts[$handle]->l10n) || !is_array($this->scripts[$handle]->l10n) )
+			return;
+
+		$object_name = $this->scripts[$handle]->l10n_object;
+
+		echo "<script type='text/javascript'>\n";
+		echo "/* <![CDATA[ */\n";
+		echo "\t$object_name = {\n";
+		$eol = '';
+		foreach ( $this->scripts[$handle]->l10n as $var => $val ) {
+			echo "$eol\t\t$var: \"" . js_escape( $val ) . '"';
+			$eol = ",\n";
+		}
+		echo "\n\t}\n";
+		echo "/* ]]> */\n";
+		echo "</script>\n";
+	}
+
+	/**
+	 * Determines dependencies of scripts
+	 *
+	 * Recursively builds hierarchical array of script dependencies.  Does NOT catch infinite loops.
+	 *
+	 * @param mixed handles Accepts (string) script name or (array of strings) script names
+	 * @param bool recursion Used internally when function calls itself
+	 * @return array Hierarchical array of dependencies
+	 */
+	function all_deps( $handles, $recursion = false ) {
+		if ( ! $handles = (array) $handles )
+			return array();
+		$return = array();
+		foreach ( $handles as $handle ) {
+			$handle = explode('?', $handle);
+			if ( isset($handle[1]) )
+				$this->args[$handle[0]] = $handle[1];
+			$handle = $handle[0];
+			if ( is_null($return[$handle]) ) // Prime the return array with $handles
+				$return[$handle] = true;
+			if ( $this->scripts[$handle]->deps ) {
+				if ( false !== $return[$handle] && array_diff($this->scripts[$handle]->deps, array_keys($this->scripts)) )
+					$return[$handle] = false; // Script required deps which don't exist
+				else
+					$return[$handle] = $this->all_deps( $this->scripts[$handle]->deps, true ); // Build the hierarchy
+			}
+			if ( $recursion && false === $return[$handle] )
+				return false; // Cut the branch
+		}
+		return $return;
+	}
+
+	/**
+	 * Adds script
+	 *
+	 * Adds the script only if no script of that name already exists
+	 *
+	 * @param string handle Script name
+	 * @param string src Script url
+	 * @param array deps (optional) Array of script names on which this script depends
+	 * @param string ver (optional) Script version (used for cache busting)
+	 * @return array Hierarchical array of dependencies
+	 */
+	function add( $handle, $src, $deps = array(), $ver = false ) {
+		if ( isset($this->scripts[$handle]) )
+			return false;
+		$this->scripts[$handle] = new _WP_Script( $handle, $src, $deps, $ver );
+		return true;
+	}
+
+	/**
+	 * Localizes a script
+	 *
+	 * Localizes only if script has already been added
+	 *
+	 * @param string handle Script name
+	 * @param string object_name Name of JS object to hold l10n info
+	 * @param array l10n Array of JS var name => localized string
+	 * @return bool Successful localization
+	 */
+	function localize( $handle, $object_name, $l10n ) {
+		if ( !isset($this->scripts[$handle]) )
+			return false;
+		return $this->scripts[$handle]->localize( $object_name, $l10n );
+	}
+
+	function remove( $handles ) {
+		foreach ( (array) $handles as $handle )
+			unset($this->scripts[$handle]);
+	}
+
+	function enqueue( $handles ) {
+		foreach ( (array) $handles as $handle ) {
+			$handle = explode('?', $handle);
+			if ( !in_array($handle[0], $this->queue) && isset($this->scripts[$handle[0]]) ) {
+				$this->queue[] = $handle[0];
+				if ( isset($handle[1]) )
+					$this->args[$handle[0]] = $handle[1];
+			}
+		}
+	}
+
+	function dequeue( $handles ) {
+		foreach ( (array) $handles as $handle )
+			unset( $this->queue[$handle] );
+	}
+
+	function query( $handle, $list = 'scripts' ) { // scripts, queue, or printed
+		switch ( $list ) :
+		case 'scripts':
+			if ( isset($this->scripts[$handle]) )
+				return $this->scripts[$handle];
+			break;
+		default:
+			if ( in_array($handle, $this->$list) )
+				return true;
+			break;
+		endswitch;
+		return false;
+	}
+
+}
+
+class _WP_Script {
+	var $handle;
+	var $src;
+	var $deps = array();
+	var $ver = false;
+	var $l10n_object = '';
+	var $l10n = array();
+
+	function _WP_Script() {
+		@list($this->handle, $this->src, $this->deps, $this->ver) = func_get_args();
+		if ( !is_array($this->deps) )
+			$this->deps = array();
+		if ( !$this->ver )
+			$this->ver = false;
+	}
+
+	function localize( $object_name, $l10n ) {
+		if ( !$object_name || !is_array($l10n) )
+			return false;
+		$this->l10n_object = $object_name;
+		$this->l10n = $l10n;
+		return true;
+	}
+}
+
+/**
+ * Prints script tags in document head
+ *
+ * Called by admin-header.php and by wp_head hook. Since it is called by wp_head on every page load,
+ * the function does not instantiate the WP_Scripts object unless script names are explicitly passed.
+ * Does make use of already instantiated $wp_scripts if present.
+ * Use provided wp_print_scripts hook to register/enqueue new scripts.
+ *
+ * @see WP_Scripts::print_scripts()
+ */
+function wp_print_scripts( $handles = false ) {
+	do_action( 'wp_print_scripts' );
+	if ( '' === $handles ) // for wp_head
+		$handles = false;
+
+	global $wp_scripts;
+	if ( !is_a($wp_scripts, 'WP_Scripts') ) {
+		if ( !$handles )
+			return array(); // No need to instantiate if nothing's there.
+		else
+			$wp_scripts = new WP_Scripts();
+	}
+
+	return $wp_scripts->print_scripts( $handles );
+}
+
+function wp_register_script( $handle, $src, $deps = array(), $ver = false ) {
+	global $wp_scripts;
+	if ( !is_a($wp_scripts, 'WP_Scripts') )
+		$wp_scripts = new WP_Scripts();
+
+	$wp_scripts->add( $handle, $src, $deps, $ver );
+}
+
+/**
+ * Localizes a script
+ *
+ * Localizes only if script has already been added
+ *
+ * @see WP_Script::localize()
+ */
+function wp_localize_script( $handle, $object_name, $l10n ) {
+	global $wp_scripts;
+	if ( !is_a($wp_scripts, 'WP_Scripts') )
+		return false;
+
+	return $wp_scripts->localize( $handle, $object_name, $l10n );
+}
+
+function wp_deregister_script( $handle ) {
+	global $wp_scripts;
+	if ( !is_a($wp_scripts, 'WP_Scripts') )
+		$wp_scripts = new WP_Scripts();
+
+	$wp_scripts->remove( $handle );
+}
+
+/**
+ * Equeues script
+ *
+ * Registers the script if src provided (does NOT overwrite) and enqueues.
+ *
+ * @see WP_Script::add(), WP_Script::enqueue()
+*/
+function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false ) {
+	global $wp_scripts;
+	if ( !is_a($wp_scripts, 'WP_Scripts') )
+		$wp_scripts = new WP_Scripts();
+
+	if ( $src ) {
+		$_handle = explode('?', $handle);
+		$wp_scripts->add( $_handle[0], $src, $deps, $ver );
+	}
+	$wp_scripts->enqueue( $handle );
+}
+?>
diff -ruN 2.0.5/wp-includes/template-functions-author.php 2.2.2/wp-includes/template-functions-author.php
--- 2.0.5/wp-includes/template-functions-author.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-functions-author.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,238 +0,0 @@
-<?php
-
-function get_the_author($deprecated = '') {
-	global $authordata;
-	return apply_filters('the_author', $authordata->display_name);
-}
-
-// Using echo = false is deprecated.  Use get_the_author instead.
-function the_author($deprecated = '', $deprecated_echo = true) {
-	if ( $deprecated_echo )
-		echo get_the_author();
-	return get_the_author();
-}
-
-function get_the_author_description() {
-	global $authordata;
-	return $authordata->description;
-}
-function the_author_description() {
-	echo get_the_author_description();
-}
-
-function get_the_author_login() {
-	global $authordata;
-	return $authordata->user_login;
-}
-
-function the_author_login() {
-	echo get_the_author_login();
-}
-
-function get_the_author_firstname() {
-	global $authordata;
-	return $authordata->first_name;
-}
-function the_author_firstname() {
-	echo get_the_author_firstname();
-}
-
-function get_the_author_lastname() {
-	global $authordata;
-	return $authordata->last_name;
-}
-
-function the_author_lastname() {
-	echo get_the_author_lastname();
-}
-
-function get_the_author_nickname() {
-	global $authordata;
-	return $authordata->nickname;
-}
-
-function the_author_nickname() {
-	echo get_the_author_nickname();
-}
-
-function get_the_author_ID() {
-	global $authordata;
-	return $authordata->ID;
-}
-function the_author_ID() {
-	echo get_the_author_id();
-}
-
-function get_the_author_email() {
-	global $authordata;
-	return $authordata->user_email;
-}
-
-function the_author_email() {
-	echo apply_filters('the_author_email', get_the_author_email() );
-}
-
-function get_the_author_url() {
-	global $authordata;
-	return $authordata->user_url;
-}
-
-function the_author_url() {
-	echo get_the_author_url();
-}
-
-function get_the_author_icq() {
-	global $authordata;
-	return $authordata->icq;
-}
-
-function the_author_icq() {
-	echo get_the_author_icq();
-}
-
-function get_the_author_aim() {
-	global $authordata;
-	return str_replace(' ', '+', $authordata->aim);
-}
-
-function the_author_aim() {
-	echo get_the_author_aim();
-}
-
-function get_the_author_yim() {
-	global $authordata;
-	return $authordata->yim;
-}
-
-function the_author_yim() {
-	echo get_the_author_yim();
-}
-
-function get_the_author_msn() {
-	global $authordata;
-	return $authordata->msn;
-}
-
-function the_author_msn() {
-	echo get_the_author_msn();
-}
-
-function get_the_author_posts() {
-	global $post;
-	$posts = get_usernumposts($post->post_author);
-	return $posts;
-}
-
-function the_author_posts() {
-	echo get_the_author_posts();
-}
-
-/* the_author_posts_link() requires no get_, use get_author_link() */
-function the_author_posts_link($deprecated = '') {
-	global $authordata;
-
-	echo '<a href="' . get_author_link(0, $authordata->ID, $authordata->user_nicename) . '" title="' . sprintf(__("Posts by %s"), wp_specialchars(get_the_author())) . '">' . get_the_author() . '</a>';
-}
-
-function get_author_link($echo = false, $author_id, $author_nicename = '') {
-	global $wpdb, $wp_rewrite, $post, $cache_userdata;
-	$auth_ID = $author_id;
-	$link = $wp_rewrite->get_author_permastruct();
-
-	if ( empty($link) ) {
-		$file = get_settings('home') . '/';
-		$link = $file . '?author=' . $auth_ID;
-	} else {
-		if ( '' == $author_nicename ) {
-			$user = get_userdata($author_id);
-			if ( !empty($user->user_nicename) )
-				$author_nicename = $user->user_nicename;
-		}
-		$link = str_replace('%author%', $author_nicename, $link);
-		$link = get_settings('home') . trailingslashit($link);
-	}
-
-	$link = apply_filters('author_link', $link, $author_id, $author_nicename);
-
-	if ( $echo )
-		echo $link;
-	return $link;
-}
-
-function wp_list_authors($args = '') {
-	parse_str($args, $r);
-
-	if ( !isset($r['optioncount']) )
-		$r['optioncount'] = false;
-	if ( !isset($r['exclude_admin']) )
-		$r['exclude_admin'] = true;
-	if ( !isset($r['show_fullname']) )
-		$r['show_fullname'] = false;
-	if ( !isset($r['hide_empty']) )
-		$r['hide_empty'] = true;
-	if ( !isset($r['feed']) )
-		$r['feed'] = '';
-	if ( !isset($r['feed_image']) )
-		$r['feed_image'] = '';
-
-	list_authors($r['optioncount'], $r['exclude_admin'], $r['show_fullname'], $r['hide_empty'], $r['feed'], $r['feed_image']);
-}
-
-function list_authors($optioncount = false, $exclude_admin = true, $show_fullname = false, $hide_empty = true, $feed = '', $feed_image = '') {
-	global $wpdb;
-	$query = "SELECT ID, user_nicename from $wpdb->users " . ($exclude_admin ? "WHERE user_login <> 'admin' " : '') . "ORDER BY display_name";
-	$authors = $wpdb->get_results($query);
-
-	foreach ( $authors as $author ) {
-		$author = get_userdata( $author->ID );
-		$posts = get_usernumposts($author->ID);
-		$name = $author->nickname;
-
-		if ( $show_fullname && ($author->first_name != '' && $author->last_name != '') )
-			$name = "$author->first_name $author->last_name";
-
-		if ( !($posts == 0 && $hide_empty) )
-			echo "<li>";
-		if ( $posts == 0 ) {
-			if ( !$hide_empty )
-				$link = $name;
-		} else {
-			$link = '<a href="' . get_author_link(0, $author->ID, $author->user_nicename) . '" title="' . sprintf(__("Posts by %s"), wp_specialchars($author->display_name)) . '">' . $name . '</a>';
-
-			if ( (! empty($feed_image)) || (! empty($feed)) ) {
-				$link .= ' ';
-				if (empty($feed_image))
-					$link .= '(';
-				$link .= '<a href="' . get_author_rss_link(0, $author->ID, $author->user_nicename) . '"';
-
-				if ( !empty($feed) ) {
-					$title = ' title="' . $feed . '"';
-					$alt = ' alt="' . $feed . '"';
-					$name = $feed;
-					$link .= $title;
-				}
-
-				$link .= '>';
-
-				if ( !empty($feed_image) )
-					$link .= "<img src=\"$feed_image\" border=\"0\"$alt$title" . ' />';
-				else
-					$link .= $name;
-
-				$link .= '</a>';
-
-				if ( empty($feed_image) )
-					$link .= ')';
-			}
-
-			if ( $optioncount )
-				$link .= ' ('. $posts . ')';
-
-		}
-
-		if ( !($posts == 0 && $hide_empty) )
-			echo "$link</li>";
-	}
-}
-
-?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/template-functions-category.php 2.2.2/wp-includes/template-functions-category.php
--- 2.0.5/wp-includes/template-functions-category.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-functions-category.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,415 +0,0 @@
-<?php
-
-function get_the_category($id = false) {
-global $post, $category_cache;
-
-	if ( !$id )
-		$id = $post->ID;
-
-	if ( !isset($category_cache[$id]) )
-		update_post_category_cache($id);
-
-	$categories = $category_cache[$id];
-
-	if ( !empty($categories) )
-		sort($categories);
-	else
-		$categories = array();
-
-	return $categories;
-}
-
-function get_category_link($category_id) {
-	global $wp_rewrite;
-	$catlink = $wp_rewrite->get_category_permastruct();
-
-	if ( empty($catlink) ) {
-		$file = get_settings('home') . '/';
-		$catlink = $file . '?cat=' . $category_id;
-	} else {
-		$category = &get_category($category_id);
-		$category_nicename = $category->category_nicename;
-
-		if ( $parent = $category->category_parent )
-			$category_nicename = get_category_parents($parent, false, '/', true) . $category_nicename . '/';
-
-		$catlink = str_replace('%category%', $category_nicename, $catlink);
-		$catlink = get_settings('home') . trailingslashit($catlink);
-	}
-	return apply_filters('category_link', $catlink, $category_id);
-}
-
-function get_the_category_list($separator = '', $parents='') {
-	$categories = get_the_category();
-	if (empty($categories))
-		return apply_filters('the_category', __('Uncategorized'), $separator, $parents);
-
-	$thelist = '';
-	if ( '' == $separator ) {
-		$thelist .= '<ul class="post-categories">';
-		foreach ( $categories as $category ) {
-			$category->cat_name = $category->cat_name;
-			$thelist .= "\n\t<li>";
-			switch ( strtolower($parents) ) {
-				case 'multiple':
-					if ($category->category_parent)
-						$thelist .= get_category_parents($category->category_parent, TRUE);
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" rel="category tag">'.$category->cat_name.'</a></li>';
-					break;
-				case 'single':
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . ' rel="category tag">';
-					if ($category->category_parent)
-						$thelist .= get_category_parents($category->category_parent, FALSE);
-					$thelist .= $category->cat_name.'</a></li>';
-					break;
-				case '':
-				default:
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" rel="category tag">'.$category->cat_name.'</a></li>';
-			}
-		}
-		$thelist .= '</ul>';
-	} else {
-		$i = 0;
-		foreach ( $categories as $category ) {
-			$category->cat_name = $category->cat_name;
-			if ( 0 < $i )
-				$thelist .= $separator . ' ';
-			switch ( strtolower($parents) ) {
-				case 'multiple':
-					if ( $category->category_parent )
-						$thelist .= get_category_parents($category->category_parent, TRUE);
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" rel="category tag">'.$category->cat_name.'</a>';
-					break;
-				case 'single':
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" rel="category tag">';
-					if ( $category->category_parent )
-						$thelist .= get_category_parents($category->category_parent, FALSE);
-					$thelist .= "$category->cat_name</a>";
-					break;
-				case '':
-				default:
-					$thelist .= '<a href="' . get_category_link($category->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $category->cat_name) . '" rel="category tag">'.$category->cat_name.'</a>';
-			}
-			++$i;
-		}
-	}
-	return apply_filters('the_category', $thelist, $separator, $parents);
-}
-
-function the_category($separator = '', $parents='') {
-	echo get_the_category_list($separator, $parents);
-}
-
-function get_the_category_by_ID($cat_ID) {
-	$cat_ID = (int) $cat_ID;
-	$category = &get_category($cat_ID);
-	return $category->cat_name;
-}
-
-function get_category_parents($id, $link = FALSE, $separator = '/', $nicename = FALSE){
-	$chain = '';
-	$parent = &get_category($id);
-
-	if ( $nicename )
-		$name = $parent->category_nicename;
-	else
-		$name = $parent->cat_name;
-
-	if ( $parent->category_parent )
-		$chain .= get_category_parents($parent->category_parent, $link, $separator, $nicename);
-
-	if ( $link )
-		$chain .= '<a href="' . get_category_link($parent->cat_ID) . '" title="' . sprintf(__("View all posts in %s"), $parent->cat_name) . '">'.$name.'</a>' . $separator;
-	else
-		$chain .= $name.$separator;
-	return $chain;
-}
-
-function get_category_children($id, $before = '/', $after = '') {
-	if ( 0 == $id )
-		return '';
-
-	$cat_ids = get_all_category_ids();
-	foreach ( $cat_ids as $cat_id ) {
-		if ( $cat_id == $id)
-			continue;
-
-		$category = get_category($cat_id);
-		if ( $category->category_parent == $id ) {
-			$chain .= $before.$category->cat_ID.$after;
-			$chain .= get_category_children($category->cat_ID, $before, $after);
-		}
-	}
-	return $chain;
-}
-
-// Deprecated.
-function the_category_ID($echo = true) {
-	// Grab the first cat in the list.
-	$categories = get_the_category();
-	$cat = $categories[0]->cat_ID;
-
-	if ( $echo )
-		echo $cat;
-
-	return $cat;
-}
-
-// Deprecated.
-function the_category_head($before='', $after='') {
-	global $currentcat, $previouscat;
-	// Grab the first cat in the list.
-	$categories = get_the_category();
-	$currentcat = $categories[0]->category_id;
-	if ( $currentcat != $previouscat ) {
-		echo $before;
-		echo get_the_category_by_ID($currentcat);
-		echo $after;
-		$previouscat = $currentcat;
-	}
-}
-
-function category_description($category = 0) {
-	global $cat;
-	if ( !$category )
-		$category = $cat;
-	$category = & get_category($category);
-	return apply_filters('category_description', $category->category_description, $category->cat_ID);
-}
-
-// out of the WordPress loop
-function dropdown_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc',
-		$optiondates = 0, $optioncount = 0, $hide_empty = 1, $optionnone=FALSE,
-		$selected=0, $hide=0) {
-	global $wpdb;
-	if ( ($file == 'blah') || ($file == '') )
-		$file = get_settings('home') . '/';
-	if ( !$selected )
-		$selected=$cat;
-	$sort_column = 'cat_'.$sort_column;
-
-	$query = "
-		SELECT cat_ID, cat_name, category_nicename,category_parent,
-		COUNT($wpdb->post2cat.post_id) AS cat_count,
-		DAYOFMONTH(MAX(post_date)) AS lastday, MONTH(MAX(post_date)) AS lastmonth
-		FROM $wpdb->categories LEFT JOIN $wpdb->post2cat ON (cat_ID = category_id)
-		LEFT JOIN $wpdb->posts ON (ID = post_id)
-		WHERE cat_ID > 0
-		";
-	if ( $hide ) {
-		$query .= " AND cat_ID != $hide";
-		$query .= get_category_children($hide, " AND cat_ID != ");
-	}
-	$query .=" GROUP BY cat_ID";
-	if ( intval($hide_empty) == 1 )
-		$query .= " HAVING cat_count > 0";
-	$query .= " ORDER BY $sort_column $sort_order, post_date DESC";
-
-	$categories = $wpdb->get_results($query);
-	echo "<select name='cat' class='postform'>\n";
-	if ( intval($optionall) == 1 ) {
-		$all = apply_filters('list_cats', $all);
-		echo "\t<option value='0'>$all</option>\n";
-	}
-	if ( intval($optionnone) == 1 )
-		echo "\t<option value='-1'>".__('None')."</option>\n";
-	if ( $categories ) {
-		foreach ( $categories as $category ) {
-			$cat_name = apply_filters('list_cats', $category->cat_name, $category);
-			echo "\t<option value=\"".$category->cat_ID."\"";
-			if ( $category->cat_ID == $selected )
-				echo ' selected="selected"';
-			echo '>';
-			echo $cat_name;
-			if ( intval($optioncount) == 1 )
-				echo '&nbsp;&nbsp;('.$category->cat_count.')';
-			if ( intval($optiondates) == 1 )
-				echo '&nbsp;&nbsp;'.$category->lastday.'/'.$category->lastmonth;
-			echo "</option>\n";
-		}
-	}
-	echo "</select>\n";
-}
-
-// out of the WordPress loop
-function wp_list_cats($args = '') {
-	parse_str($args, $r);
-	if ( !isset($r['optionall']))
-		$r['optionall'] = 0;
-	if ( !isset($r['all']))
-		$r['all'] = 'All';
-	if ( !isset($r['sort_column']) )
-		$r['sort_column'] = 'ID';
-	if ( !isset($r['sort_order']) )
-		$r['sort_order'] = 'asc';
-	if ( !isset($r['file']) )
-		$r['file'] = '';
-	if ( !isset($r['list']) )
-		$r['list'] = true;
-	if ( !isset($r['optiondates']) )
-		$r['optiondates'] = 0;
-	if ( !isset($r['optioncount']) )
-		$r['optioncount'] = 0;
-	if ( !isset($r['hide_empty']) )
-		$r['hide_empty'] = 1;
-	if ( !isset($r['use_desc_for_title']) )
-		$r['use_desc_for_title'] = 1;
-	if ( !isset($r['children']) )
-		$r['children'] = true;
-	if ( !isset($r['child_of']) )
-		$r['child_of'] = 0;
-	if ( !isset($r['categories']) )
-		$r['categories'] = 0;
-	if ( !isset($r['recurse']) )
-		$r['recurse'] = 0;
-	if ( !isset($r['feed']) )
-		$r['feed'] = '';
-	if ( !isset($r['feed_image']) )
-		$r['feed_image'] = '';
-	if ( !isset($r['exclude']) )
-		$r['exclude'] = '';
-	if ( !isset($r['hierarchical']) )
-		$r['hierarchical'] = true;
-
-	return list_cats($r['optionall'], $r['all'], $r['sort_column'], $r['sort_order'], $r['file'],	$r['list'], $r['optiondates'], $r['optioncount'], $r['hide_empty'], $r['use_desc_for_title'], $r['children'], $r['child_of'], $r['categories'], $r['recurse'], $r['feed'], $r['feed_image'], $r['exclude'], $r['hierarchical']);
-}
-
-function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_order = 'asc', $file = '', $list = true, $optiondates = 0, $optioncount = 0, $hide_empty = 1, $use_desc_for_title = 1, $children=FALSE, $child_of=0, $categories=0, $recurse=0, $feed = '', $feed_image = '', $exclude = '', $hierarchical=FALSE) {
-	global $wpdb, $wp_query;
-	// Optiondates now works
-	if ( '' == $file )
-		$file = get_settings('home') . '/';
-
-	$exclusions = '';
-	if ( !empty($exclude) ) {
-		$excats = preg_split('/[\s,]+/',$exclude);
-		if ( count($excats) ) {
-			foreach ( $excats as $excat ) {
-				$exclusions .= ' AND cat_ID <> ' . intval($excat) . ' ';
-			}
-		}
-	}
-
-	$exclusions = apply_filters('list_cats_exclusions', $exclusions );
-
-	if ( intval($categories) == 0 ) {
-		$sort_column = 'cat_'.$sort_column;
-
-		$query = "
-			SELECT cat_ID, cat_name, category_nicename, category_description, category_parent, category_count
-			FROM $wpdb->categories
-			WHERE cat_ID > 0 $exclusions
-			ORDER BY $sort_column $sort_order";
-
-		$categories = $wpdb->get_results($query);
-	}
-
-	if ( $optiondates ) {
-		$cat_dates = $wpdb->get_results("	SELECT category_id,
-		UNIX_TIMESTAMP( MAX(post_date) ) AS ts
-		FROM $wpdb->posts, $wpdb->post2cat, $wpdb->categories
-		WHERE post_status = 'publish' AND post_id = ID $exclusions
-		GROUP BY category_id");
-		foreach ( $cat_dates as $cat_date ) {
-			$category_timestamp["$cat_date->category_id"] = $cat_date->ts;
-		}
-	}
-
-	$num_found=0;
-	$thelist = "";
-
-	foreach ( (array) $categories as $category ) {
-		if ( ( intval($hide_empty) == 0 || $category->category_count) && (!$hierarchical || $category->category_parent == $child_of) ) {
-			$num_found++;
-			$link = '<a href="'.get_category_link($category->cat_ID).'" ';
-			if ( $use_desc_for_title == 0 || empty($category->category_description) )
-				$link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"';
-			else
-				$link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"';
-			$link .= '>';
-			$link .= apply_filters('list_cats', $category->cat_name, $category).'</a>';
-
-			if ( (! empty($feed_image)) || (! empty($feed)) ) {
-
-				$link .= ' ';
-
-				if ( empty($feed_image) )
-					$link .= '(';
-
-				$link .= '<a href="' . get_category_rss_link(0, $category->cat_ID, $category->category_nicename) . '"';
-
-				if ( !empty($feed) ) {
-					$title = ' title="' . $feed . '"';
-					$alt = ' alt="' . $feed . '"';
-					$name = $feed;
-					$link .= $title;
-				}
-
-				$link .= '>';
-
-				if ( !empty($feed_image) )
-					$link .= "<img src='$feed_image' $alt$title" . ' />';
-				else
-					$link .= $name;
-
-				$link .= '</a>';
-
-				if (empty($feed_image))
-					$link .= ')';
-			}
-
-			if ( intval($optioncount) == 1 )
-				$link .= ' ('.intval($category->category_count).')';
-
-			if ( $optiondates ) {
-				if ( $optiondates == 1 )
-					$optiondates = 'Y-m-d';
-				$link .= ' ' . gmdate($optiondates, $category_timestamp["$category->cat_ID"]);
-			}
-
-			if ( $list ) {
-				$thelist .= "\t<li";
-				if (($category->cat_ID == $wp_query->get_queried_object_id()) && is_category()) {
-					$thelist .=  ' class="current-cat"';
-				}
-				$thelist .= ">$link\n";
-			} else {
-				$thelist .= "\t$link<br />\n";
-			}
-
-			if ($hierarchical && $children)
-				$thelist .= list_cats($optionall, $all, $sort_column, $sort_order, $file, $list, $optiondates, $optioncount, $hide_empty, $use_desc_for_title, $hierarchical, $category->cat_ID, $categories, 1, $feed, $feed_image, $exclude, $hierarchical);
-			if ($list)
-				$thelist .= "</li>\n";
-		}
-	}
-	if ( !$num_found && !$child_of ) {
-		if ( $list ) {
-			$before = '<li>';
-			$after = '</li>';
-		}
-		echo $before . __("No categories") . $after . "\n";
-		return;
-	}
-	if ( $list && $child_of && $num_found && $recurse ) {
-		$pre = "\t\t<ul class='children'>";
-		$post = "\t\t</ul>\n";
-	} else {
-		$pre = $post = '';
-	}
-	$thelist = $pre . $thelist . $post;
-	if ( $recurse )
-		return $thelist;
-	echo apply_filters('list_cats', $thelist);
-}
-
-function in_category($category) { // Check if the current post is in the given category
-	global $category_cache, $post;
-
-	if ( isset( $category_cache[$post->ID][$category] ) )
-		return true;
-	else
-		return false;
-}
-
-?>
diff -ruN 2.0.5/wp-includes/template-functions-general.php 2.2.2/wp-includes/template-functions-general.php
--- 2.0.5/wp-includes/template-functions-general.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-functions-general.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,710 +0,0 @@
-<?php
-
-/* Note: these tags go anywhere in the template */
-
-function get_header() {
-	if ( file_exists( TEMPLATEPATH . '/header.php') )
-		load_template( TEMPLATEPATH . '/header.php');
-	else
-		load_template( ABSPATH . 'wp-content/themes/default/header.php');
-}
-
-
-function get_footer() {
-	if ( file_exists( TEMPLATEPATH . '/footer.php') )
-		load_template( TEMPLATEPATH . '/footer.php');
-	else
-		load_template( ABSPATH . 'wp-content/themes/default/footer.php');
-}
-
-
-function get_sidebar() {
-	if ( file_exists( TEMPLATEPATH . '/sidebar.php') )
-		load_template( TEMPLATEPATH . '/sidebar.php');
-	else
-		load_template( ABSPATH . 'wp-content/themes/default/sidebar.php');
-}
-
-
-function wp_loginout() {
-	if ( ! is_user_logged_in() )
-		$link = '<a href="' . get_settings('siteurl') . '/wp-login.php">' . __('Login') . '</a>';
-	else
-		$link = '<a href="' . get_settings('siteurl') . '/wp-login.php?action=logout">' . __('Logout') . '</a>';
-
-	echo apply_filters('loginout', $link);
-}
-
-
-function wp_register( $before = '<li>', $after = '</li>' ) {
-
-	if ( ! is_user_logged_in() ) {
-		if ( get_settings('users_can_register') )
-			$link = $before . '<a href="' . get_settings('siteurl') . '/wp-register.php">' . __('Register') . '</a>' . $after;
-		else
-			$link = '';
-	} else {
-		$link = $before . '<a href="' . get_settings('siteurl') . '/wp-admin/">' . __('Site Admin') . '</a>' . $after;
-	}
-
-	echo apply_filters('register', $link);
-}
-
-
-function wp_meta() {
-	do_action('wp_meta');
-}
-
-
-function bloginfo($show='') {
-	$info = get_bloginfo($show);
-	if (!strstr($show, 'url') && //don't filter URLs
-		!strstr($show, 'directory') &&
-		!strstr($show, 'home')) {
-		$info = apply_filters('bloginfo', $info, $show);
-		$info = convert_chars($info);
-	} else {
-		$info = apply_filters('bloginfo_url', $info, $show);
-	}
-
-	echo $info;
-}
-
-
-function get_bloginfo($show='') {
-
-	switch($show) {
-		case 'url' :
-		case 'home' :
-		case 'siteurl' :
-			$output = get_settings('home');
-			break;
-		case 'wpurl' :
-			$output = get_settings('siteurl');
-			break;
-		case 'description':
-			$output = get_settings('blogdescription');
-			break;
-		case 'rdf_url':
-			$output = get_feed_link('rdf');
-			break;
-		case 'rss_url':
-			$output = get_feed_link('rss');
-			break;
-		case 'rss2_url':
-			$output = get_feed_link('rss2');
-			break;
-		case 'atom_url':
-			$output = get_feed_link('atom');
-			break;
-		case 'comments_rss2_url':
-			$output = get_feed_link('comments_rss2');
-			break;
-		case 'pingback_url':
-			$output = get_settings('siteurl') .'/xmlrpc.php';
-			break;
-		case 'stylesheet_url':
-			$output = get_stylesheet_uri();
-			break;
-		case 'stylesheet_directory':
-			$output = get_stylesheet_directory_uri();
-			break;
-		case 'template_directory':
-		case 'template_url':
-			$output = get_template_directory_uri();
-			break;
-		case 'admin_email':
-			$output = get_settings('admin_email');
-			break;
-		case 'charset':
-			$output = get_settings('blog_charset');
-			if ('' == $output) $output = 'UTF-8';
-			break;
-		case 'html_type' :
-			$output = get_option('html_type');
-			break;
-		case 'version':
-			global $wp_version;
-			$output = $wp_version;
-			break;
-		case 'name':
-		default:
-			$output = get_settings('blogname');
-			break;
-	}
-	return $output;
-}
-
-
-function wp_title($sep = '&raquo;', $display = true) {
-	global $wpdb;
-	global $m, $year, $monthnum, $day, $category_name, $month, $posts;
-
-	$cat = get_query_var('cat');
-	$p = get_query_var('p');
-	$name = get_query_var('name');
-	$category_name = get_query_var('category_name');
-	$author = get_query_var('author');
-	$author_name = get_query_var('author_name');
-
-	// If there's a category
-	if ( !empty($cat) ) {
-			// category exclusion
-			if ( !stristr($cat,'-') )
-				$title = get_the_category_by_ID($cat);
-	}
-	if ( !empty($category_name) ) {
-		if ( stristr($category_name,'/') ) {
-				$category_name = explode('/',$category_name);
-				if ( $category_name[count($category_name)-1] )
-					$category_name = $category_name[count($category_name)-1]; // no trailing slash
-				else
-					$category_name = $category_name[count($category_name)-2]; // there was a trailling slash
-		}
-		$title = $wpdb->get_var("SELECT cat_name FROM $wpdb->categories WHERE category_nicename = '$category_name'");
-	}
-
-	// If there's an author
-	if ( !empty($author) ) {
-		$title = get_userdata($author);
-		$title = $title->display_name;
-	}
-	if ( !empty($author_name) ) {
-		// We do a direct query here because we don't cache by nicename.
-		$title = $wpdb->get_var("SELECT display_name FROM $wpdb->users WHERE user_nicename = '$author_name'");
-	}
-
-	// If there's a month
-	if ( !empty($m) ) {
-		$my_year = substr($m, 0, 4);
-		$my_month = $month[substr($m, 4, 2)];
-		$title = "$my_year $sep $my_month";
-	}
-
-	if ( !empty($year) ) {
-		$title = $year;
-		if ( !empty($monthnum) )
-			$title .= " $sep ".$month[zeroise($monthnum, 2)];
-		if ( !empty($day) )
-			$title .= " $sep ".zeroise($day, 2);
-	}
-
-	// If there is a post
-	if ( is_single() || is_page() ) {
-		$title = strip_tags($posts[0]->post_title);
-		$title = apply_filters('single_post_title', $title);
-	}
-
-	$prefix = '';
-	if ( isset($title) )
-		$prefix = " $sep ";
-
-	$title = $prefix . $title;
-	$title = apply_filters('wp_title', $title, $sep);
-
-	// Send it out
-	if ( $display )
-		echo $title;
-	else
-		return $title;
-}
-
-
-function single_post_title($prefix = '', $display = true) {
-	global $wpdb;
-	$p = get_query_var('p');
-	$name = get_query_var('name');
-
-	if ( intval($p) || '' != $name ) {
-		if ( !$p )
-			$p = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_name = '$name'");
-		$post = & get_post($p);
-		$title = $post->post_title;
-		$title = apply_filters('single_post_title', $title);
-		if ( $display )
-			echo $prefix.strip_tags($title);
-		else
-			return strip_tags($title);
-	}
-}
-
-
-function single_cat_title($prefix = '', $display = true ) {
-	$cat = intval( get_query_var('cat') );
-	if ( !empty($cat) && !(strtoupper($cat) == 'ALL') ) {
-		$my_cat_name = get_the_category_by_ID($cat);
-		if ( !empty($my_cat_name) ) {
-			if ( $display )
-				echo $prefix.strip_tags($my_cat_name);
-			else
-				return strip_tags($my_cat_name);
-		}
-	}
-}
-
-
-function single_month_title($prefix = '', $display = true ) {
-	global $m, $monthnum, $month, $year;
-	if ( !empty($monthnum) && !empty($year) ) {
-		$my_year = $year;
-		$my_month = $month[str_pad($monthnum, 2, '0', STR_PAD_LEFT)];
-	} elseif ( !empty($m) ) {
-		$my_year = substr($m, 0, 4);
-		$my_month = $month[substr($m, 4, 2)];
-	}
-
-	if ( !empty($my_month) && $display )
-		echo $prefix . $my_month . $prefix . $my_year;
-	else
-		return $monthnum;
-}
-
-
-/* link navigation hack by Orien http://icecode.com/ */
-function get_archives_link($url, $text, $format = 'html', $before = '', $after = '') {
-	$text = wptexturize($text);
-	$title_text = wp_specialchars($text, 1);
-
-	if ('link' == $format)
-		return "\t<link rel='archives' title='$title_text' href='$url' />\n";
-	elseif ('option' == $format)
-		return "\t<option value='$url'>$before $text $after</option>\n";
-	elseif ('html' == $format)
-		return "\t<li>$before<a href='$url' title='$title_text'>$text</a>$after</li>\n";
-	else // custom
-		return "\t$before<a href='$url' title='$title_text'>$text</a>$after\n";
-}
-
-
-function wp_get_archives($args = '') {
-	parse_str($args, $r);
-	if ( !isset($r['type']) )
-		$r['type'] = '';
-	if ( !isset($r['limit']) )
-		$r['limit'] = '';
-	if ( !isset($r['format']) )
-		$r['format'] = 'html';
-	if ( !isset($r['before']) )
-		$r['before'] = '';
-	if ( !isset($r['after']) )
-		$r['after'] = '';
-	if ( !isset($r['show_post_count']) )
-		$r['show_post_count'] = false;
-
-	get_archives($r['type'], $r['limit'], $r['format'], $r['before'], $r['after'], $r['show_post_count']);
-}
-
-
-function get_archives($type='', $limit='', $format='html', $before = '', $after = '', $show_post_count = false) {
-	global $month, $wpdb;
-
-	if ( '' == $type )
-		$type = 'monthly';
-
-	if ( '' != $limit ) {
-		$limit = (int) $limit;
-		$limit = ' LIMIT '.$limit;
-	}
-	// this is what will separate dates on weekly archive links
-	$archive_week_separator = '&#8211;';
-
-	// over-ride general date format ? 0 = no: use the date format set in Options, 1 = yes: over-ride
-	$archive_date_format_over_ride = 0;
-
-	// options for daily archive (only if you over-ride the general date format)
-	$archive_day_date_format = 'Y/m/d';
-
-	// options for weekly archive (only if you over-ride the general date format)
-	$archive_week_start_date_format = 'Y/m/d';
-	$archive_week_end_date_format	= 'Y/m/d';
-
-	if ( !$archive_date_format_over_ride ) {
-		$archive_day_date_format = get_settings('date_format');
-		$archive_week_start_date_format = get_settings('date_format');
-		$archive_week_end_date_format = get_settings('date_format');
-	}
-
-	$add_hours = intval(get_settings('gmt_offset'));
-	$add_minutes = intval(60 * (get_settings('gmt_offset') - $add_hours));
-
-	$now = current_time('mysql');
-
-	if ( 'monthly' == $type ) {
-		$arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts WHERE post_date < '$now' AND post_date != '0000-00-00 00:00:00' AND post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC" . $limit);
-		if ( $arcresults ) {
-			$afterafter = $after;
-			foreach ( $arcresults as $arcresult ) {
-				$url	= get_month_link($arcresult->year,	$arcresult->month);
-				if ( $show_post_count ) {
-					$text = sprintf('%s %d', $month[zeroise($arcresult->month,2)], $arcresult->year);
-					$after = '&nbsp;('.$arcresult->posts.')' . $afterafter;
-				} else {
-					$text = sprintf('%s %d', $month[zeroise($arcresult->month,2)], $arcresult->year);
-				}
-				echo get_archives_link($url, $text, $format, $before, $after);
-			}
-		}
-	} elseif ( 'daily' == $type ) {
-		$arcresults = $wpdb->get_results("SELECT DISTINCT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth` FROM $wpdb->posts WHERE post_date < '$now' AND post_date != '0000-00-00 00:00:00' AND post_status = 'publish' ORDER BY post_date DESC" . $limit);
-		if ( $arcresults ) {
-			foreach ( $arcresults as $arcresult ) {
-				$url	= get_day_link($arcresult->year, $arcresult->month, $arcresult->dayofmonth);
-				$date = sprintf("%d-%02d-%02d 00:00:00", $arcresult->year, $arcresult->month, $arcresult->dayofmonth);
-				$text = mysql2date($archive_day_date_format, $date);
-				echo get_archives_link($url, $text, $format, $before, $after);
-			}
-		}
-	} elseif ( 'weekly' == $type ) {
-		$start_of_week = get_settings('start_of_week');
-		$arcresults = $wpdb->get_results("SELECT DISTINCT WEEK(post_date, $start_of_week) AS `week`, YEAR(post_date) AS yr, DATE_FORMAT(post_date, '%Y-%m-%d') AS yyyymmdd FROM $wpdb->posts WHERE post_date < '$now' AND post_status = 'publish' ORDER BY post_date DESC" . $limit);
-		$arc_w_last = '';
-		if ( $arcresults ) {
-				foreach ( $arcresults as $arcresult ) {
-					if ( $arcresult->week != $arc_w_last ) {
-						$arc_year = $arcresult->yr;
-						$arc_w_last = $arcresult->week;
-						$arc_week = get_weekstartend($arcresult->yyyymmdd, get_settings('start_of_week'));
-						$arc_week_start = date_i18n($archive_week_start_date_format, $arc_week['start']);
-						$arc_week_end = date_i18n($archive_week_end_date_format, $arc_week['end']);
-						$url  = sprintf('%s/%s%sm%s%s%sw%s%d', get_settings('home'), '', '?', '=', $arc_year, '&amp;', '=', $arcresult->week);
-						$text = $arc_week_start . $archive_week_separator . $arc_week_end;
-						echo get_archives_link($url, $text, $format, $before, $after);
-					}
-				}
-		}
-	} elseif ( 'postbypost' == $type ) {
-		$arcresults = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_date < '$now' AND post_status = 'publish' ORDER BY post_date DESC" . $limit);
-		if ( $arcresults ) {
-			foreach ( $arcresults as $arcresult ) {
-				if ( $arcresult->post_date != '0000-00-00 00:00:00' ) {
-					$url  = get_permalink($arcresult);
-					$arc_title = $arcresult->post_title;
-					if ( $arc_title )
-						$text = strip_tags($arc_title);
-					else
-						$text = $arcresult->ID;
-					echo get_archives_link($url, $text, $format, $before, $after);
-				}
-			}
-		}
-	}
-}
-
-
-// Used in get_calendar
-function calendar_week_mod($num) {
-	$base = 7;
-	return ($num - $base*floor($num/$base));
-}
-
-
-function get_calendar($daylength = 1) {
-	global $wpdb, $m, $monthnum, $year, $timedifference, $month, $month_abbrev, $weekday, $weekday_initial, $weekday_abbrev, $posts;
-
-	$now = current_time('mysql');
-
-	// Quick check. If we have no posts yet published, abort!
-	if ( !$posts ) {
-		$gotsome = $wpdb->get_var("SELECT ID from $wpdb->posts WHERE post_status = 'publish' AND post_date < '$now' ORDER BY post_date DESC LIMIT 1");
-		if ( !$gotsome )
-			return;
-	}
-
-	if ( isset($_GET['w']) )
-		$w = ''.intval($_GET['w']);
-
-	// week_begins = 0 stands for Sunday
-	$week_begins = intval(get_settings('start_of_week'));
-	$add_hours = intval(get_settings('gmt_offset'));
-	$add_minutes = intval(60 * (get_settings('gmt_offset') - $add_hours));
-
-	// Let's figure out when we are
-	if ( !empty($monthnum) && !empty($year) ) {
-		$thismonth = ''.zeroise(intval($monthnum), 2);
-		$thisyear = ''.intval($year);
-	} elseif ( !empty($w) ) {
-		// We need to get the month from MySQL
-		$thisyear = ''.intval(substr($m, 0, 4));
-		$d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
-		$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('${thisyear}0101', INTERVAL $d DAY) ), '%m')");
-	} elseif ( !empty($m) ) {
-		$calendar = substr($m, 0, 6);
-		$thisyear = ''.intval(substr($m, 0, 4));
-		if ( strlen($m) < 6 )
-				$thismonth = '01';
-		else
-				$thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
-	} else {
-		$thisyear = gmdate('Y', current_time('timestamp'));
-		$thismonth = gmdate('m', current_time('timestamp'));
-	}
-
-	$unixmonth = mktime(0, 0 , 0, $thismonth, 1, $thisyear);
-
-	// Get the next and previous month and year with at least one post
-	$previous = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
-		FROM $wpdb->posts
-		WHERE post_date < '$thisyear-$thismonth-01'
-		AND post_status = 'publish'
-			ORDER BY post_date DESC
-			LIMIT 1");
-	$next = $wpdb->get_row("SELECT	DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
-		FROM $wpdb->posts
-		WHERE post_date >	'$thisyear-$thismonth-01'
-		AND post_date < '$now'
-		AND MONTH( post_date ) != MONTH( '$thisyear-$thismonth-01' )
-		AND post_status = 'publish' 
-			ORDER	BY post_date ASC
-			LIMIT 1");
-
-	echo '<table id="wp-calendar">
-	<caption>' . $month[zeroise($thismonth, 2)] . ' ' . date('Y', $unixmonth) . '</caption>
-	<thead>
-	<tr>';
-
-	$day_abbrev = $weekday_initial;
-	if ( $daylength > 1 )
-		$day_abbrev = $weekday_abbrev;
-
-	$myweek = array();
-
-	for ( $wdcount=0; $wdcount<=6; $wdcount++ ) {
-		$myweek[]=$weekday[($wdcount+$week_begins)%7];
-	}
-
-	foreach ( $myweek as $wd ) {
-		echo "\n\t\t<th abbr=\"$wd\" scope=\"col\" title=\"$wd\">" . $day_abbrev[$wd] . '</th>';
-	}
-
-	echo '
-	</tr>
-	</thead>
-
-	<tfoot>
-	<tr>';
-
-	if ( $previous ) {
-		echo "\n\t\t".'<td abbr="' . $month[zeroise($previous->month, 2)] . '" colspan="3" id="prev"><a href="' .
-		get_month_link($previous->year, $previous->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $month[zeroise($previous->month, 2)],
-			date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year))) . '">&laquo; ' . $month_abbrev[$month[zeroise($previous->month, 2)]] . '</a></td>';
-	} else {
-		echo "\n\t\t".'<td colspan="3" id="prev" class="pad">&nbsp;</td>';
-	}
-
-	echo "\n\t\t".'<td class="pad">&nbsp;</td>';
-
-	if ( $next ) {
-		echo "\n\t\t".'<td abbr="' . $month[zeroise($next->month, 2)] . '" colspan="3" id="next"><a href="' .
-		get_month_link($next->year, $next->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $month[zeroise($next->month, 2)],
-			date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year))) . '">' . $month_abbrev[$month[zeroise($next->month, 2)]] . ' &raquo;</a></td>';
-	} else {
-		echo "\n\t\t".'<td colspan="3" id="next" class="pad">&nbsp;</td>';
-	}
-
-	echo '
-	</tr>
-	</tfoot>
-
-	<tbody>
-	<tr>';
-
-	// Get days with posts
-	$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
-		FROM $wpdb->posts WHERE MONTH(post_date) = '$thismonth'
-		AND YEAR(post_date) = '$thisyear'
-		AND post_status = 'publish'
-		AND post_date < '" . current_time('mysql') . '\'', ARRAY_N);
-	if ( $dayswithposts ) {
-		foreach ( $dayswithposts as $daywith ) {
-			$daywithpost[] = $daywith[0];
-		}
-	} else {
-		$daywithpost = array();
-	}
-
-
-
-	if ( strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') || strstr(strtolower($_SERVER['HTTP_USER_AGENT']), 'camino') || strstr(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari') )
-		$ak_title_separator = "\n";
-	else
-		$ak_title_separator = ', ';
-
-	$ak_titles_for_day = array();
-	$ak_post_titles = $wpdb->get_results("SELECT post_title, DAYOFMONTH(post_date) as dom "
-		."FROM $wpdb->posts "
-		."WHERE YEAR(post_date) = '$thisyear' "
-		."AND MONTH(post_date) = '$thismonth' "
-		."AND post_date < '".current_time('mysql')."' "
-		."AND post_status = 'publish'"
-	);
-	if ( $ak_post_titles ) {
-		foreach ( $ak_post_titles as $ak_post_title ) {
-				if ( empty($ak_titles_for_day['day_'.$ak_post_title->dom]) )
-					$ak_titles_for_day['day_'.$ak_post_title->dom] = '';
-				if ( empty($ak_titles_for_day["$ak_post_title->dom"]) ) // first one
-					$ak_titles_for_day["$ak_post_title->dom"] = str_replace('"', '&quot;', wptexturize($ak_post_title->post_title));
-				else
-					$ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . str_replace('"', '&quot;', wptexturize($ak_post_title->post_title));
-		}
-	}
-
-
-	// See how much we should pad in the beginning
-	$pad = calendar_week_mod(date('w', $unixmonth)-$week_begins);
-	if ( 0 != $pad )
-		echo "\n\t\t".'<td colspan="'.$pad.'" class="pad">&nbsp;</td>';
-
-	$daysinmonth = intval(date('t', $unixmonth));
-	for ( $day = 1; $day <= $daysinmonth; ++$day ) {
-		if ( isset($newrow) && $newrow )
-			echo "\n\t</tr>\n\t<tr>\n\t\t";
-		$newrow = false;
-
-		if ( $day == gmdate('j', (time() + (get_settings('gmt_offset') * 3600))) && $thismonth == gmdate('m', time()+(get_settings('gmt_offset') * 3600)) && $thisyear == gmdate('Y', time()+(get_settings('gmt_offset') * 3600)) )
-			echo '<td id="today">';
-		else
-			echo '<td>';
-
-		if ( in_array($day, $daywithpost) ) // any posts today?
-				echo '<a href="' . get_day_link($thisyear, $thismonth, $day) . "\" title=\"$ak_titles_for_day[$day]\">$day</a>";
-		else
-			echo $day;
-		echo '</td>';
-
-		if ( 6 == calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins) )
-			$newrow = true;
-	}
-
-	$pad = 7 - calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins);
-	if ( $pad != 0 && $pad != 7 )
-		echo "\n\t\t".'<td class="pad" colspan="'.$pad.'">&nbsp;</td>';
-
-	echo "\n\t</tr>\n\t</tbody>\n\t</table>";
-}
-
-
-function allowed_tags() {
-	global $allowedtags;
-	$allowed = '';
-	foreach ( $allowedtags as $tag => $attributes ) {
-		$allowed .= '<'.$tag;
-		if ( 0 < count($attributes) ) {
-			foreach ( $attributes as $attribute => $limits ) {
-				$allowed .= ' '.$attribute.'=""';
-			}
-		}
-		$allowed .= '> ';
-	}
-	return htmlentities($allowed);
-}
-
-
-/***** Date/Time tags *****/
-
-
-function the_date_xml() {
-	global $post;
-	echo mysql2date('Y-m-d', $post->post_date);
-	//echo ""+$post->post_date;
-}
-
-
-function the_date($d='', $before='', $after='', $echo = true) {
-	global $id, $post, $day, $previousday, $newday;
-	$the_date = '';
-	if ( $day != $previousday ) {
-		$the_date .= $before;
-		if ( $d=='' )
-			$the_date .= mysql2date(get_settings('date_format'), $post->post_date);
-		else
-			$the_date .= mysql2date($d, $post->post_date);
-		$the_date .= $after;
-		$previousday = $day;
-	}
-	$the_date = apply_filters('the_date', $the_date, $d, $before, $after);
-	if ( $echo )
-		echo $the_date;
-	else
-		return $the_date;
-}
-
-
-function the_time( $d = '' ) {
-	echo apply_filters('the_time', get_the_time( $d ), $d);
-}
-
-
-function get_the_time( $d = '' ) {
-	if ( '' == $d )
-		$the_time = get_post_time(get_settings('time_format'));
-	else
-		$the_time = get_post_time($d);
-	return apply_filters('get_the_time', $the_time, $d);
-}
-
-
-function get_post_time( $d = 'U', $gmt = false ) { // returns timestamp
-	global $post;
-	if ( $gmt )
-		$time = $post->post_date_gmt;
-	else
-		$time = $post->post_date;
-
-	$time = mysql2date($d, $time);
-	return apply_filters('get_the_time', $time, $d, $gmt);
-}
-
-
-function the_modified_time($d = '') {
-	echo apply_filters('the_modified_time', get_the_modified_time($d), $d);
-}
-
-
-function get_the_modified_time($d = '') {
-	if ( '' == $d )
-		$the_time = get_post_modified_time(get_settings('time_format'));
-	else
-		$the_time = get_post_modified_time($d);
-	return apply_filters('get_the_modified_time', $the_time, $d);
-}
-
-
-function get_post_modified_time( $d = 'U', $gmt = false ) { // returns timestamp
-	global $post;
-
-	if ( $gmt )
-		$time = $post->post_modified_gmt;
-	else
-		$time = $post->post_modified;
-	$time = mysql2date($d, $time);
-
-	return apply_filters('get_the_modified_time', $time, $d, $gmt);
-}
-
-
-function the_weekday() {
-	global $weekday, $id, $post;
-	$the_weekday = $weekday[mysql2date('w', $post->post_date)];
-	$the_weekday = apply_filters('the_weekday', $the_weekday);
-	echo $the_weekday;
-}
-
-
-function the_weekday_date($before='',$after='') {
-	global $weekday, $id, $post, $day, $previousweekday;
-	$the_weekday_date = '';
-	if ( $day != $previousweekday ) {
-		$the_weekday_date .= $before;
-		$the_weekday_date .= $weekday[mysql2date('w', $post->post_date)];
-		$the_weekday_date .= $after;
-		$previousweekday = $day;
-	}
-	$the_weekday_date = apply_filters('the_weekday_date', $the_weekday_date, $before, $after);
-	echo $the_weekday_date;
-}
-
-function rsd_link() {
-	echo '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="' . get_bloginfo('wpurl') . "/xmlrpc.php?rsd\" />\n";
-}
-
-?>
diff -ruN 2.0.5/wp-includes/template-functions-links.php 2.2.2/wp-includes/template-functions-links.php
--- 2.0.5/wp-includes/template-functions-links.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-functions-links.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,527 +0,0 @@
-<?php
-
-
-function the_permalink() {
-	echo apply_filters('the_permalink', get_permalink());
-}
-
-
-function permalink_link() { // For backwards compatibility
-	echo apply_filters('the_permalink', get_permalink());
-}
-
-
-function permalink_anchor($mode = 'id') {
-	global $post;
-	switch ( strtolower($mode) ) {
-		case 'title':
-			$title = sanitize_title($post->post_title) . '-' . $id;
-			echo '<a id="'.$title.'"></a>';
-			break;
-		case 'id':
-		default:
-			echo '<a id="post-' . $post->ID . '"></a>';
-			break;
-	}
-}
-
-
-function get_permalink($id = 0) {
-	$rewritecode = array(
-		'%year%',
-		'%monthnum%',
-		'%day%',
-		'%hour%',
-		'%minute%',
-		'%second%',
-		'%postname%',
-		'%post_id%',
-		'%category%',
-		'%author%',
-		'%pagename%'
-	);
-
-	$post = &get_post($id);
-	if ( $post->post_status == 'static' )
-		return get_page_link($post->ID);
-	elseif ($post->post_status == 'attachment')
-		return get_attachment_link($post->ID);
-
-	$permalink = get_settings('permalink_structure');
-
-	if ( '' != $permalink && 'draft' != $post->post_status ) {
-		$unixtime = strtotime($post->post_date);
-
-		$category = '';
-		if ( strstr($permalink, '%category%') ) {
-			$cats = get_the_category($post->ID);
-			$category = $cats[0]->category_nicename;
-			if ( $parent=$cats[0]->category_parent )
-				$category = get_category_parents($parent, FALSE, '/', TRUE) . $category;
-		}
-
-		$authordata = get_userdata($post->post_author);
-		$author = $authordata->user_nicename;
-		$date = explode(" ",date('Y m d H i s', $unixtime));
-		$rewritereplace = 
-		array(
-			$date[0],
-			$date[1],
-			$date[2],
-			$date[3],
-			$date[4],
-			$date[5],
-			$post->post_name,
-			$post->ID,
-			$category,
-			$author,
-			$post->post_name,
-		);
-		return apply_filters('post_link', get_settings('home') . str_replace($rewritecode, $rewritereplace, $permalink), $post);
-	} else { // if they're not using the fancy permalink option
-		$permalink = get_settings('home') . '/?p=' . $post->ID;
-		return apply_filters('post_link', $permalink, $post);
-	}
-}
-
-function get_page_link($id = false) {
-	global $post, $wp_rewrite;
-
-	if ( !$id )
-		$id = $post->ID;
-
-	$pagestruct = $wp_rewrite->get_page_permastruct();
-
-	if ( '' != $pagestruct ) {
-		$link = get_page_uri($id);
-		$link = str_replace('%pagename%', $link, $pagestruct);
-		$link = get_settings('home') . "/$link/";
-	} else {
-		$link = get_settings('home') . "/?page_id=$id";
-	}
-
-	return apply_filters('page_link', $link, $id);
-}
-
-function get_attachment_link($id = false) {
-	global $post, $wp_rewrite;
-
-	$link = false;
-
-	if (! $id) {
-		$id = $post->ID;
-	}
-
-	$object = get_post($id);
-	if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) ) {
-		$parent = get_post($object->post_parent);
-		$parentlink = get_permalink($object->post_parent);
-		if (! strstr($parentlink, '?') )
-			$link = trim($parentlink, '/') . '/' . $object->post_name . '/';
-	}
-
-	if (! $link ) {
-		$link = get_bloginfo('home') . "/?attachment_id=$id";
-	}
-
-	return apply_filters('attachment_link', $link, $id);
-}
-
-function get_year_link($year) {
-	global $wp_rewrite;
-	if ( !$year )
-		$year = gmdate('Y', time()+(get_settings('gmt_offset') * 3600));
-	$yearlink = $wp_rewrite->get_year_permastruct();
-	if ( !empty($yearlink) ) {
-		$yearlink = str_replace('%year%', $year, $yearlink);
-		return apply_filters('year_link', get_settings('home') . trailingslashit($yearlink), $year);
-	} else {
-		return apply_filters('year_link', get_settings('home') . '/?m=' . $year, $year);
-	}
-}
-
-function get_month_link($year, $month) {
-	global $wp_rewrite;
-	if ( !$year )
-		$year = gmdate('Y', time()+(get_settings('gmt_offset') * 3600));
-	if ( !$month )
-		$month = gmdate('m', time()+(get_settings('gmt_offset') * 3600));
-	$monthlink = $wp_rewrite->get_month_permastruct();
-	if ( !empty($monthlink) ) {
-		$monthlink = str_replace('%year%', $year, $monthlink);
-		$monthlink = str_replace('%monthnum%', zeroise(intval($month), 2), $monthlink);
-		return apply_filters('month_link', get_settings('home') . trailingslashit($monthlink), $year, $month);
-	} else {
-		return apply_filters('month_link', get_settings('home') . '/?m=' . $year . zeroise($month, 2), $year, $month);
-	}
-}
-
-function get_day_link($year, $month, $day) {
-	global $wp_rewrite;
-	if ( !$year )
-		$year = gmdate('Y', time()+(get_settings('gmt_offset') * 3600));
-	if ( !$month )
-		$month = gmdate('m', time()+(get_settings('gmt_offset') * 3600));
-	if ( !$day )
-		$day = gmdate('j', time()+(get_settings('gmt_offset') * 3600));
-
-	$daylink = $wp_rewrite->get_day_permastruct();
-	if ( !empty($daylink) ) {
-		$daylink = str_replace('%year%', $year, $daylink);
-		$daylink = str_replace('%monthnum%', zeroise(intval($month), 2), $daylink);
-		$daylink = str_replace('%day%', zeroise(intval($day), 2), $daylink);
-		return apply_filters('day_link', get_settings('home') . trailingslashit($daylink), $year, $month, $day);
-	} else {
-		return apply_filters('day_link', get_settings('home') . '/?m=' . $year . zeroise($month, 2) . zeroise($day, 2), $year, $month, $day);
-	}
-}
-
-function get_feed_link($feed='rss2') {
-	global $wp_rewrite;
-	$do_perma = 0;
-	$feed_url = get_settings('siteurl');
-	$comment_feed_url = $feed_url;
-
-	$permalink = $wp_rewrite->get_feed_permastruct();
-	if ( '' != $permalink ) {
-		if ( false !== strpos($feed, 'comments_') ) {
-			$feed = str_replace('comments_', '', $feed);
-			$permalink = $wp_rewrite->get_comment_feed_permastruct();
-		}
-
-		if ( 'rss2' == $feed )
-			$feed = '';
-
-		$permalink = str_replace('%feed%', $feed, $permalink);
-		$permalink = preg_replace('#/+#', '/', "/$permalink/");
-		$output =  get_settings('home') . $permalink;
-	} else {
-		if ( false !== strpos($feed, 'comments_') )
-			$feed = str_replace('comments_', 'comments-', $feed);
-
-		$output = get_settings('home') . "/?feed={$feed}";
-	}
-
-	return apply_filters('feed_link', $output, $feed);
-}
-
-function edit_post_link($link = 'Edit This', $before = '', $after = '') {
-	global $post;
-
-	if ( ! current_user_can('edit_post', $post->ID) )
-		return;
-
-	if ( is_attachment() )
-		return;
-	else
-		$file = 'post';
-
-	$location = get_settings('siteurl') . "/wp-admin/{$file}.php?action=edit&amp;post=$post->ID";
-	echo $before . "<a href=\"$location\">$link</a>" . $after;
-}
-
-function edit_comment_link($link = 'Edit This', $before = '', $after = '') {
-	global $post, $comment;
-
-	if ( ! current_user_can('edit_post', $post->ID) )
-		return;
-
-	$location = get_settings('siteurl') . "/wp-admin/post.php?action=editcomment&amp;comment=$comment->comment_ID";
-	echo $before . "<a href='$location'>$link</a>" . $after;
-}
-
-// Navigation links
-
-function get_previous_post($in_same_cat = false, $excluded_categories = '') {
-	global $post, $wpdb;
-
-	if( !is_single() || is_attachment() )
-		return null;
-
-	$current_post_date = $post->post_date;
-
-	$join = '';
-	if ( $in_same_cat ) {
-		$join = " INNER JOIN $wpdb->post2cat ON $wpdb->posts.ID= $wpdb->post2cat.post_id ";
-		$cat_array = get_the_category($post->ID);
-		$join .= ' AND (category_id = ' . intval($cat_array[0]->cat_ID);
-		for ( $i = 1; $i < (count($cat_array)); $i++ ) {
-			$join .= ' OR category_id = ' . intval($cat_array[$i]->cat_ID);
-		}
-		$join .= ')'; 
-	}
-
-	$sql_exclude_cats = '';
-	if ( !empty($excluded_categories) ) {
-		$blah = explode('and', $excluded_categories);
-		foreach ( $blah as $category ) {
-			$category = intval($category);
-			$sql_exclude_cats .= " AND post_category != $category";
-		}
-	}
-
-	return @$wpdb->get_row("SELECT ID, post_title FROM $wpdb->posts $join WHERE post_date < '$current_post_date' AND post_status = 'publish' $sqlcat $sql_exclude_cats ORDER BY post_date DESC LIMIT 1");
-}
-
-function get_next_post($in_same_cat = false, $excluded_categories = '') {
-	global $post, $wpdb;
-
-	if( !is_single() || is_attachment() )
-		return null;
-
-	$current_post_date = $post->post_date;
-	
-	$join = '';
-	if ( $in_same_cat ) {
-		$join = " INNER JOIN $wpdb->post2cat ON $wpdb->posts.ID= $wpdb->post2cat.post_id ";
-		$cat_array = get_the_category($post->ID);
-		$join .= ' AND (category_id = ' . intval($cat_array[0]->cat_ID);
-		for ( $i = 1; $i < (count($cat_array)); $i++ ) {
-			$join .= ' OR category_id = ' . intval($cat_array[$i]->cat_ID);
-		}
-		$join .= ')'; 
-	}
-
-	$sql_exclude_cats = '';
-	if ( !empty($excluded_categories) ) {
-		$blah = explode('and', $excluded_categories);
-		foreach ( $blah as $category ) {
-			$category = intval($category);
-			$sql_exclude_cats .= " AND post_category != $category";
-		}
-	}
-
-	$now = current_time('mysql');
-	
-	return @$wpdb->get_row("SELECT ID,post_title FROM $wpdb->posts $join WHERE post_date > '$current_post_date' AND post_date < '$now' AND post_status = 'publish' $sqlcat $sql_exclude_cats AND ID != $post->ID ORDER BY post_date ASC LIMIT 1");
-}
-
-
-function previous_post_link($format='&laquo; %link', $link='%title', $in_same_cat = false, $excluded_categories = '') {
-
-	if ( is_attachment() )
-		$post = & get_post($GLOBALS['post']->post_parent);
-	else
-		$post = get_previous_post($in_same_cat, $excluded_categories);
-
-	if ( !$post )
-		return;
-
-	$title = apply_filters('the_title', $post->post_title, $post);
-	$string = '<a href="'.get_permalink($post->ID).'">';
-	$link = str_replace('%title', $title, $link);
-	$link = $pre . $string . $link . '</a>';
-
-	$format = str_replace('%link', $link, $format);
-
-	echo $format;	    
-}
-
-function next_post_link($format='%link &raquo;', $link='%title', $in_same_cat = false, $excluded_categories = '') {
-	$post = get_next_post($in_same_cat, $excluded_categories);
-
-	if ( !$post )
-		return;
-
-	$title = apply_filters('the_title', $post->post_title, $post);
-	$string = '<a href="'.get_permalink($post->ID).'">';
-	$link = str_replace('%title', $title, $link);
-	$link = $string . $link . '</a>';
-	$format = str_replace('%link', $link, $format);
-
-	echo $format;	    
-}
-
-
-// Deprecated.	Use previous_post_link().
-function previous_post($format='%', $previous='previous post: ', $title='yes', $in_same_cat='no', $limitprev=1, $excluded_categories='') {
-
-	if ( empty($in_same_cat) || 'no' == $in_same_cat )
-		$in_same_cat = false;
-	else
-		$in_same_cat = true;
-
-	$post = get_previous_post($in_same_cat, $excluded_categories);
-
-	if ( !$post )
-		return;
-
-	$string = '<a href="'.get_permalink($post->ID).'">'.$previous;
-	if ( 'yes' == $title )
-		$string .= apply_filters('the_title', $post->post_title, $post);
-	$string .= '</a>';
-	$format = str_replace('%', $string, $format);
-	echo $format;
-}
-
-// Deprecated.	Use next_post_link().
-function next_post($format='%', $next='next post: ', $title='yes', $in_same_cat='no', $limitnext=1, $excluded_categories='') {
-
-	if ( empty($in_same_cat) || 'no' == $in_same_cat )
-		$in_same_cat = false;
-	else
-		$in_same_cat = true;
-
-	$post = get_next_post($in_same_cat, $excluded_categories);
-
-	if ( !$post	)
-		return;
-
-	$string = '<a href="'.get_permalink($post->ID).'">'.$next;
-	if ( 'yes' == $title )
-		$string .= apply_filters('the_title', $post->post_title, $nextpost);
-	$string .= '</a>';
-	$format = str_replace('%', $string, $format);
-	echo $format;
-}
-
-function get_pagenum_link($pagenum = 1) {
-	global $wp_rewrite;
-
-	$qstr = wp_specialchars($_SERVER['REQUEST_URI']);
-
-	$page_querystring = "paged"; 
-	$page_modstring = "page/";
-	$page_modregex = "page/?";
-	$permalink = 0;
-
-	$home_root = parse_url(get_settings('home'));
-	$home_root = $home_root['path'];
-	$home_root = trailingslashit($home_root);
-	$qstr = preg_replace('|^'. $home_root . '|', '', $qstr);
-	$qstr = preg_replace('|^/+|', '', $qstr);
-
-	$index = $_SERVER['PHP_SELF'];
-	$index = preg_replace('|^'. $home_root . '|', '', $index);
-	$index = preg_replace('|^/+|', '', $index);
-
-	// if we already have a QUERY style page string
-	if ( stristr( $qstr, $page_querystring ) ) {
-		$replacement = "$page_querystring=$pagenum";
-		$qstr = preg_replace("/".$page_querystring."[^\d]+\d+/", $replacement, $qstr);
-		// if we already have a mod_rewrite style page string
-	} elseif ( preg_match( '|'.$page_modregex.'\d+|', $qstr ) ) {
-		$permalink = 1;
-		$qstr = preg_replace('|'.$page_modregex.'\d+|',"$page_modstring$pagenum",$qstr);
-
-		// if we don't have a page string at all ...
-		// lets see what sort of URL we have...
-	} else {
-		// we need to know the way queries are being written
-		// if there's a querystring_start (a "?" usually), it's definitely not mod_rewritten
-		if ( stristr( $qstr, '?' ) ) {
-			// so append the query string (using &, since we already have ?)
-			$qstr .=	'&amp;' . $page_querystring . '=' . $pagenum;
-			// otherwise, it could be rewritten, OR just the default index ...
-		} elseif( '' != get_settings('permalink_structure') && ! is_admin() ) {
-			$permalink = 1;
-			$index = $wp_rewrite->index;
-			// If it's not a path info permalink structure, trim the index.
-			if ( !$wp_rewrite->using_index_permalinks() ) {
-				$qstr = preg_replace("#/*" . $index . "/*#", '/', $qstr);
-			} else {
-				// If using path info style permalinks, make sure the index is in
-				// the URI.
-				if ( strpos($qstr, $index) === false )
-					$qstr = '/' . $index . $qstr;
-			}
-
-			$qstr =	trailingslashit($qstr) . $page_modstring . $pagenum;
-		} else {
-			$qstr = $index . '?' . $page_querystring . '=' . $pagenum;
-		}
-	}
-
-	$qstr = preg_replace('|^/+|', '', $qstr);
-	if ( $permalink )
-		$qstr = trailingslashit($qstr);
-	$qstr = preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', trailingslashit( get_settings('home') ) . $qstr );
-	
-	// showing /page/1/ or ?paged=1 is redundant
-	if ( 1 === $pagenum ) {
-		$qstr = str_replace('page/1/', '', $qstr); // for mod_rewrite style
-		$qstr = remove_query_arg('paged', $qstr); // for query style
-	}
-	return $qstr;
-}
-
-function next_posts($max_page = 0) { // original by cfactor at cooltux.org
-	global $paged, $pagenow;
-
-	if ( !is_single() ) {
-		if ( !$paged )
-			$paged = 1;
-		$nextpage = intval($paged) + 1;
-		if ( !$max_page || $max_page >= $nextpage )
-			echo get_pagenum_link($nextpage);
-	}
-}
-
-function next_posts_link($label='Next Page &raquo;', $max_page=0) {
-	global $paged, $result, $request, $posts_per_page, $wpdb, $max_num_pages;
-	if ( !$max_page ) {
-			if ( isset($max_num_pages) ) {
-				$max_page = $max_num_pages;
-			} else {
-				preg_match('#FROM\s(.*)\sGROUP BY#siU', $request, $matches);
-				$fromwhere = $matches[1];
-				$numposts = $wpdb->get_var("SELECT COUNT(DISTINCT ID) FROM $fromwhere");
-				$max_page = $max_num_pages = ceil($numposts / $posts_per_page);
-			}
-	}
-	if ( !$paged )
-		$paged = 1;
-	$nextpage = intval($paged) + 1;
-	if ( (! is_single()) && (empty($paged) || $nextpage <= $max_page) ) {
-		echo '<a href="';
-		next_posts($max_page);
-		echo '">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $label) .'</a>';
-	}
-}
-
-
-function previous_posts() { // original by cfactor at cooltux.org
-	global $paged, $pagenow;
-
-	if ( !is_single() ) {
-		$nextpage = intval($paged) - 1;
-		if ( $nextpage < 1 )
-			$nextpage = 1;
-		echo get_pagenum_link($nextpage);
-	}
-}
-
-
-function previous_posts_link($label='&laquo; Previous Page') {
-	global $paged;
-	if ( (!is_single())	&& ($paged > 1) ) {
-		echo '<a href="';
-		previous_posts();
-		echo '">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $label) .'</a>';
-	}
-}
-
-function posts_nav_link($sep=' &#8212; ', $prelabel='&laquo; Previous Page', $nxtlabel='Next Page &raquo;') {
-	global $request, $posts_per_page, $wpdb, $max_num_pages;
-	if ( !is_single() ) {
-
-		if ( 'posts' == get_query_var('what_to_show') ) {
-			if ( !isset($max_num_pages) ) {
-				preg_match('#FROM\s(.*)\sGROUP BY#siU', $request, $matches);
-				$fromwhere = $matches[1];
-				$numposts = $wpdb->get_var("SELECT COUNT(DISTINCT ID) FROM $fromwhere");
-				$max_num_pages = ceil($numposts / $posts_per_page);
-			}
-		} else {
-			$max_num_pages = 999999;
-		}
-
-		if ( $max_num_pages > 1 ) {
-			previous_posts_link($prelabel);
-			echo preg_replace('/&([^#])(?![a-z]{1,8};)/', '&#038;$1', $sep);
-			next_posts_link($nxtlabel, $max_page);
-		}
-	}
-}
-
-?>
diff -ruN 2.0.5/wp-includes/template-functions-post.php 2.2.2/wp-includes/template-functions-post.php
--- 2.0.5/wp-includes/template-functions-post.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-functions-post.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,575 +0,0 @@
-<?php
-
-function get_the_password_form() {
-	$output = '<form action="' . get_settings('siteurl') . '/wp-pass.php" method="post">
-	<p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
-	<p><label>' . __("Password:") . ' <input name="post_password" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . __("Submit") . '" /></p>
-	</form>
-	';
-	return $output;
-}
-
-
-function the_ID() {
-	global $id;
-	echo $id;
-}
-
-
-function the_title($before = '', $after = '', $echo = true) {
-	$title = get_the_title();
-	if ( strlen($title) > 0 ) {
-		$title = apply_filters('the_title', $before . $title . $after, $before, $after);
-		if ( $echo )
-			echo $title;
-		else
-			return $title;
-	}
-}
-
-
-function get_the_title($id = 0) {
-	$post = &get_post($id);
-
-	$title = $post->post_title;
-	if ( !empty($post->post_password) )
-		$title = sprintf(__('Protected: %s'), $title);
-
-	return $title;
-}
-
-
-function get_the_guid( $id = 0 ) {
-	$post = &get_post($id);
-
-	return apply_filters('get_the_guid', $post->guid);
-}
-
-
-function the_guid( $id = 0 ) {
-	echo get_the_guid($id);
-}
-
-
-function the_content($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
-	$content = get_the_content($more_link_text, $stripteaser, $more_file);
-	$content = apply_filters('the_content', $content);
-	$content = str_replace(']]>', ']]&gt;', $content);
-	echo $content;
-}
-
-
-function get_the_content($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
-	global $id, $post, $more, $single, $withcomments, $page, $pages, $multipage, $numpages;
-	global $preview;
-	global $pagenow;
-	$output = '';
-
-	if ( !empty($post->post_password) ) { // if there's a password
-		if ( stripslashes($_COOKIE['wp-postpass_'.COOKIEHASH]) != $post->post_password ) {	// and it doesn't match the cookie
-			$output = get_the_password_form();
-			return $output;
-		}
-	}
-
-	if ( $more_file != '' )
-		$file = $more_file;
-	else
-		$file = $pagenow; //$_SERVER['PHP_SELF'];
-
-	if ( $page > count($pages) ) // if the requested page doesn't exist
-		$page = count($pages); // give them the highest numbered page that DOES exist
-
-	$content = $pages[$page-1];
-	$content = explode('<!--more-->', $content, 2);
-	if ( (preg_match('/<!--noteaser-->/', $post->post_content) && ((!$multipage) || ($page==1))) )
-		$stripteaser = 1;
-	$teaser = $content[0];
-	if ( ($more) && ($stripteaser) )
-		$teaser = '';
-	$output .= $teaser;
-	if ( count($content) > 1 ) {
-		if ( $more )
-			$output .= '<a id="more-'.$id.'"></a>'.$content[1];
-		else
-			$output .= ' <a href="'. get_permalink() . "#more-$id\">$more_link_text</a>";
-	}
-	if ( $preview ) // preview fix for javascript bug with foreign languages
-		$output =	preg_replace('/\%u([0-9A-F]{4,4})/e',	"'&#'.base_convert('\\1',16,10).';'", $output);
-
-	return $output;
-}
-
-
-function the_excerpt() {
-	echo apply_filters('the_excerpt', get_the_excerpt());
-}
-
-
-function get_the_excerpt($fakeit = true) {
-	global $id, $post;
-	$output = '';
-	$output = $post->post_excerpt;
-	if ( !empty($post->post_password) ) { // if there's a password
-		if ( $_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password ) {  // and it doesn't match the cookie
-			$output = __('There is no excerpt because this is a protected post.');
-			return $output;
-		}
-	}
-
-	return apply_filters('get_the_excerpt', $output);
-}
-
-
-function wp_link_pages($args = '') {
-	parse_str($args, $r);
-	if ( !isset($r['before']) )
-		$r['before'] = '<p>' . __('Pages:');
-	if ( !isset($r['after']) )
-		$r['after'] = '</p>';
-	if ( !isset($r['next_or_number']) )
-		$r['next_or_number'] = 'number';
-	if ( !isset($r['nextpagelink']) )
-		$r['nextpagelink'] = 'Next page';
-	if ( !isset($r['previouspagelink']) )
-		$r['previouspagelink'] = 'Previous page';
-	if ( !isset($r['pagelink']) )
-		$r['pagelink'] = '%';
-	if ( !isset($r['more_file']) )
-		$r['more_file'] = '';
-
-	link_pages($r['before'], $r['after'], $r['next_or_number'], $r['nextpagelink'], $r['previouspagelink'], $r['pagelink'], $r['more_file']);
-}
-
-
-function link_pages($before='<br />', $after='<br />', $next_or_number='number', $nextpagelink='next page', $previouspagelink='previous page', $pagelink='%', $more_file='') {
-	global $id, $page, $numpages, $multipage, $more, $pagenow;
-	if ( $more_file != '' )
-		$file = $more_file;
-	else
-		$file = $pagenow;
-	if ( $multipage ) {
-		if ( 'number' == $next_or_number ) {
-			echo $before;
-			for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) {
-				$j = str_replace('%',"$i",$pagelink);
-				echo ' ';
-				if ( ($i != $page) || ((!$more) && ($page==1)) ) {
-					if ( '' == get_settings('permalink_structure') )
-						echo '<a href="' . get_permalink() . '&amp;page=' . $i . '">';
-					else
-						echo '<a href="' . trailingslashit( get_permalink() ) . $i . '/">';
-				}
-				echo $j;
-				if ( ($i != $page) || ((!$more) && ($page==1)) )
-					echo '</a>';
-			}
-			echo $after;
-		} else {
-			if ( $more ) {
-				echo $before;
-				$i = $page - 1;
-				if ( $i && $more ) {
-					if ( '' == get_settings('permalink_structure') )
-						echo '<a href="' . get_permalink() . '&amp;page=' . $i . '">'.$previouspagelink.'</a>';
-					else
-						echo '<a href="' . get_permalink() . $i . '/">'.$previouspagelink.'</a>';
-				}
-				$i = $page + 1;
-				if ( $i <= $numpages && $more ) {
-					if ( '' == get_settings('permalink_structure') )
-						echo '<a href="'.get_permalink() . '&amp;page=' . $i . '">'.$nextpagelink.'</a>';
-					else
-						echo '<a href="'.get_permalink().$i.'/">'.$nextpagelink.'</a>';
-				}
-				echo $after;
-			}
-		}
-	}
-}
-
-
-/*
-Post-meta: Custom per-post fields.
-*/
-
-
-function get_post_custom( $post_id = 0 ) {
-	global $id, $post_meta_cache, $wpdb;
-
-	if ( ! $post_id )
-		$post_id = $id;
-
-	$post_id = (int) $post_id;
-
-	if ( isset($post_meta_cache[$post_id]) )
-		return $post_meta_cache[$post_id];
-
-	if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta	WHERE post_id = '$post_id' ORDER BY post_id, meta_key", ARRAY_A) ) {
-		// Change from flat structure to hierarchical:
-		$post_meta_cache = array();
-		foreach ( $meta_list as $metarow ) {
-			$mpid = (int) $metarow['post_id'];
-			$mkey = $metarow['meta_key'];
-			$mval = $metarow['meta_value'];
-
-			// Force subkeys to be array type:
-			if ( !isset($post_meta_cache[$mpid]) || !is_array($post_meta_cache[$mpid]) )
-				$post_meta_cache[$mpid] = array();
-				
-			if ( !isset($post_meta_cache[$mpid]["$mkey"]) || !is_array($post_meta_cache[$mpid]["$mkey"]) )
-				$post_meta_cache[$mpid]["$mkey"] = array();
-
-			// Add a value to the current pid/key:
-			$post_meta_cache[$mpid][$mkey][] = $mval;
-		}
-		return $post_meta_cache[$mpid];
-	}
-}
-
-
-function get_post_custom_keys() {
-	$custom = get_post_custom();
-
-	if ( ! is_array($custom) )
-		return;
-
-	if ( $keys = array_keys($custom) )
-		return $keys;
-}
-
-
-function get_post_custom_values( $key = '' ) {
-	$custom = get_post_custom();
-
-	return $custom[$key];
-}
-
-
-function post_custom( $key = '' ) {
-	$custom = get_post_custom();
-
-	if ( 1 == count($custom[$key]) )
-		return $custom[$key][0];
-	else
-		return $custom[$key];
-}
-
-
-// this will probably change at some point...
-function the_meta() {
-	global $id;
-
-	if ( $keys = get_post_custom_keys() ) {
-		echo "<ul class='post-meta'>\n";
-		foreach ( $keys as $key ) {
-			$keyt = trim($key);
-			if ( '_' == $keyt{0} )
-				continue;
-			$values = array_map('trim', get_post_custom_values($key));
-			$value = implode($values,', ');
-			echo "<li><span class='post-meta-key'>$key:</span> $value</li>\n";
-		}
-		echo "</ul>\n";
-	}
-}
-
-
-/*
-Pages
-*/
-
-
-function &get_page_children($page_id, $pages) {
-	global $page_cache;
-
-	if ( empty($pages) )
-		$pages = &$page_cache;
-
-	$page_list = array();
-	foreach ( $pages as $page ) {
-		if ( $page->post_parent == $page_id ) {
-			$page_list[] = $page;
-			if ( $children = get_page_children($page->ID, $pages) )
-				$page_list = array_merge($page_list, $children);
-		}
-	}
-	return $page_list;
-}
-
-
-function &get_pages($args = '') {
-	global $wpdb;
-
-	parse_str($args, $r);
-
-	if ( !isset($r['child_of']) )
-		$r['child_of'] = 0;
-	if ( !isset($r['sort_column']) )
-		$r['sort_column'] = 'post_title';
-	if ( !isset($r['sort_order']) )
-		$r['sort_order'] = 'ASC';
-
-	$exclusions = '';
-	if ( !empty($r['exclude']) ) {
-		$expages = preg_split('/[\s,]+/',$r['exclude']);
-		if ( count($expages) ) {
-			foreach ( $expages as $expage ) {
-				$exclusions .= ' AND ID <> ' . intval($expage) . ' ';
-			}
-		}
-	}
-
-	$pages = $wpdb->get_results("SELECT * " .
-		"FROM $wpdb->posts " .
-		"WHERE post_status = 'static' " .
-		"$exclusions " .
-		"ORDER BY " . $r['sort_column'] . " " . $r['sort_order']);
-
-	if ( empty($pages) )
-		return array();
-
-	// Update cache.
-	update_page_cache($pages);
-
-	if ( $r['child_of'] )
-		$pages = & get_page_children($r['child_of'], $pages);
-
-	return $pages;
-}
-
-
-function wp_list_pages($args = '') {
-	parse_str($args, $r);
-	if ( !isset($r['depth']) )
-		$r['depth'] = 0;
-	if ( !isset($r['show_date']) )
-		$r['show_date'] = '';
-	if ( !isset($r['child_of']) )
-		$r['child_of'] = 0;
-	if ( !isset($r['title_li']) )
-		$r['title_li'] = __('Pages');
-	if ( !isset($r['echo']) )
-		$r['echo'] = 1;
-
-	$output = '';
-
-	// Query pages.
-	$pages = & get_pages($args);
-	if ( $pages ) {
-
-		if ( $r['title_li'] )
-			$output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
-
-		// Now loop over all pages that were selected
-		$page_tree = Array();
-		foreach ( $pages as $page ) {
-			// set the title for the current page
-			$page_tree[$page->ID]['title'] = $page->post_title;
-			$page_tree[$page->ID]['name'] = $page->post_name;
-
-			// set the selected date for the current page
-			// depending on the query arguments this is either
-			// the createtion date or the modification date
-			// as a unix timestamp. It will also always be in the
-			// ts field.
-			if ( !empty($r['show_date']) ) {
-				if ( 'modified' == $r['show_date'] )
-					$page_tree[$page->ID]['ts'] = $page->post_modified;
-				else
-					$page_tree[$page->ID]['ts'] = $page->post_date;
-			}
-
-			// The tricky bit!!
-			// Using the parent ID of the current page as the
-			// array index we set the curent page as a child of that page.
-			// We can now start looping over the $page_tree array
-			// with any ID which will output the page links from that ID downwards.
-			if ( $page->post_parent != $page->ID)
-				$page_tree[$page->post_parent]['children'][] = $page->ID;
-		}
-		// Output of the pages starting with child_of as the root ID.
-		// child_of defaults to 0 if not supplied in the query.
-		$output .= _page_level_out($r['child_of'],$page_tree, $r, 0, false);
-		if ( $r['title_li'] )
-			$output .= '</ul></li>';
-	}
-
-	$output = apply_filters('wp_list_pages', $output);
-
-	if ( $r['echo'] )
-		echo $output;
-	else
-		return $output;
-}
-
-
-function _page_level_out($parent, $page_tree, $args, $depth = 0, $echo = true) {
-	global $wp_query;
-	$queried_obj = $wp_query->get_queried_object();
-	$output = '';
-
-	if ( $depth )
-		$indent = str_repeat("\t", $depth);
-		//$indent = join('', array_fill(0,$depth,"\t"));
-
-	if ( !is_array($page_tree[$parent]['children']) )
-		return false;
-
-	foreach ( $page_tree[$parent]['children'] as $page_id ) {
-		$cur_page = $page_tree[$page_id];
-		$title = wp_specialchars($cur_page['title']);
-
-		$css_class = 'page_item';
-		if ( $page_id == $queried_obj->ID )
-			$css_class .= ' current_page_item';
-
-		$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page_id) . '" title="' . $title . '">' . $title . '</a>';
-
-		if ( isset($cur_page['ts']) ) {
-			$format = get_settings('date_format');
-			if ( isset($args['date_format']) )
-				$format = $args['date_format'];
-			$output .= " " . mysql2date($format, $cur_page['ts']);
-		}
-
-		if ( isset($cur_page['children']) && is_array($cur_page['children']) ) {
-			$new_depth = $depth + 1;
-
-			if ( !$args['depth'] || $depth < ($args['depth']-1) ) {
-				$output .= "$indent<ul>\n";
-				$output .= _page_level_out($page_id, $page_tree, $args, $new_depth, false);
-				$output .= "$indent</ul>\n";
-			}
-		}
-		$output .= "$indent</li>\n";
-	}
-	if ( $echo )
-		echo $output;
-	else
-		return $output;
-}
-
-function the_attachment_link($id = 0, $fullsize = false, $max_dims = false) {
-	echo get_the_attachment_link($id, $fullsize, $max_dims);
-}
-
-function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false) {
-	$id = (int) $id;
-	$_post = & get_post($id);
-
-	if ( ('attachment' != $_post->post_status) || ('' == $_post->guid) )
-		return __('Missing Attachment');
-
-	if (! empty($_post->guid) ) {
-		$innerHTML = get_attachment_innerHTML($_post->ID, $fullsize, $max_dims);
-
-		return "<a href=\"{$_post->guid}\" title=\"{$_post->post_title}\" >{$innerHTML}</a>";
-
-	} else {
-		$p .= __('Missing attachment');
-	}
-	return $p;
-}
-
-function get_attachment_icon($id = 0, $fullsize = false, $max_dims = false) {
-	$id = (int) $id;
-	$post = & get_post($id);
-
-	$mime = $post->post_mime_type;
-
-	$imagedata = get_post_meta($post->ID, '_wp_attachment_metadata', true);
-
-	$file = get_post_meta($post->ID, '_wp_attached_file', true);
-
-	if ( !$fullsize && !empty($imagedata['thumb'])
-			&& ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file))
-			&& file_exists($thumbfile) ) {
-
-		// We have a thumbnail desired, specified and existing
-
-		$src = str_replace(basename($post->guid), $imagedata['thumb'], $post->guid);
-		$src_file = $thumbfile;
-		$class = 'attachmentthumb';
-
-	} elseif ( substr($mime, 0, 6) == 'image/'
-			&& file_exists($file) ) {
-
-		// We have an image without a thumbnail
-
-		$src = $post->guid;
-		$src_file = & $file;
-		$class = 'attachmentimage';
-	} elseif (! empty($mime) ) {
-
-		// No thumb, no image. We'll look for a mime-related icon instead.
-		$icon_dir = apply_filters('icon_dir', get_template_directory().'/images');
-		$icon_dir_uri = apply_filters('icon_dir_uri', get_template_directory_uri().'/images');
-
-		$types = array(substr($mime, 0, strpos($mime, '/')), substr($mime, strpos($mime, '/') + 1), str_replace('/', '_', $mime));
-		$exts = array('jpg', 'gif', 'png');
-		foreach ($types as $type) {
-			foreach ($exts as $ext) {
-				$src_file = "$icon_dir/$type.$ext";
-				if ( file_exists($src_file) ) {
-					$src = "$icon_dir_uri/$type.$ext";
-					break 2;
-				}
-			}
-		}
-	}
-
-	if (! isset($src) )
-		return false;
-
-	// Do we need to constrain the image?
-	if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) {
-
-		$imagesize = getimagesize($src_file);
-
-		if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) {
-			$actual_aspect = $imagesize[0] / $imagesize[1];
-			$desired_aspect = $max_dims[0] / $max_dims[1];
-
-			if ( $actual_aspect >= $desired_aspect ) {
-				$height = $actual_aspect * $max_dims[0];
-				$constraint = "width=\"{$max_dims[0]}\" ";
-				$post->iconsize = array($max_dims[0], $height);
-			} else {
-				$width = $max_dims[1] / $actual_aspect;
-				$constraint = "height=\"{$max_dims[1]}\" ";
-				$post->iconsize = array($width, $max_dims[1]);
-			}
-		} else {
-			$post->iconsize = array($imagesize[0], $imagesize[1]);
-		}
-	}
-
-	$icon = "<img src=\"{$src}\" title=\"{$post->post_title}\" alt=\"{$post->post_title}\" {$constraint}/>";
-
-	return apply_filters('attachment_icon', $icon, $post->ID);
-}
-
-function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false) {
-	$id = (int) $id;
-
-	if ( $innerHTML = get_attachment_icon($id, $fullsize, $max_dims))
-		return $innerHTML;
-
-	$post = & get_post($id);
-
-	$innerHTML = $post->post_title;
-
-	return apply_filters('attachment_innerHTML', $innerHTML, $post->ID);
-}
-
-function prepend_attachment($content) {
-	$p = '<p class="attachment">';
-	$p .= get_the_attachment_link(false, true, array(400, 300));
-	$p .= '</p>';
-	$p = apply_filters('prepend_attachment', $p);
-
-	return "$p\n$content";
-}
-
-?>
diff -ruN 2.0.5/wp-includes/template-loader.php 2.2.2/wp-includes/template-loader.php
--- 2.0.5/wp-includes/template-loader.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/template-loader.php	2007-04-19 17:26:52.000000000 -0500
@@ -1,66 +1,72 @@
 <?php
 if ( defined('WP_USE_THEMES') && constant('WP_USE_THEMES') ) {
 	do_action('template_redirect');
-	if ( is_feed() ) {
-		include(ABSPATH . '/wp-feed.php');
-		exit;
+	if ( is_robots() ) {
+		do_action('do_robots');
+		return;
+	} else if ( is_feed() ) {
+		do_feed();
+		return;
 	} else if ( is_trackback() ) {
 		include(ABSPATH . '/wp-trackback.php');
-		exit;
+		return;
 	} else if ( is_404() && $template = get_404_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_search() && $template = get_search_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_home() && $template = get_home_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_attachment() && $template = get_attachment_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_single() && $template = get_single_template() ) {
 		if ( is_attachment() )
 			add_filter('the_content', 'prepend_attachment');
 		include($template);
-		exit;
+		return;
 	} else if ( is_page() && $template = get_page_template() ) {
 		if ( is_attachment() )
 			add_filter('the_content', 'prepend_attachment');
 		include($template);
-		exit;
+		return;
 	} else if ( is_category() && $template = get_category_template()) {
 		include($template);
-		exit;		
+		return;
 	} else if ( is_author() && $template = get_author_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_date() && $template = get_date_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_archive() && $template = get_archive_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_comments_popup() && $template = get_comments_popup_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( is_paged() && $template = get_paged_template() ) {
 		include($template);
-		exit;
+		return;
 	} else if ( file_exists(TEMPLATEPATH . "/index.php") ) {
 		if ( is_attachment() )
 			add_filter('the_content', 'prepend_attachment');
 		include(TEMPLATEPATH . "/index.php");
-		exit;
+		return;
 	}
 } else {
 	// Process feeds and trackbacks even if not using themes.
-	if ( is_feed() ) {
-		include(ABSPATH . '/wp-feed.php');
-		exit;
+	if ( is_robots() ) {
+		do_action('do_robots');
+		return;
+	} else if ( is_feed() ) {
+		do_feed();
+		return;
 	} else if ( is_trackback() ) {
 		include(ABSPATH . '/wp-trackback.php');
-		exit;
+		return;
 	}
 }
 
diff -ruN 2.0.5/wp-includes/theme.php 2.2.2/wp-includes/theme.php
--- 2.0.5/wp-includes/theme.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/theme.php	2007-06-27 17:45:52.000000000 -0500
@@ -0,0 +1,512 @@
+<?php
+/*
+ * Theme/template/stylesheet functions.
+ */
+
+function get_stylesheet() {
+	return apply_filters('stylesheet', get_option('stylesheet'));
+}
+
+function get_stylesheet_directory() {
+	$stylesheet = get_stylesheet();
+	$stylesheet_dir = get_theme_root() . "/$stylesheet";
+	return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
+}
+
+function get_stylesheet_directory_uri() {
+	$stylesheet = get_stylesheet();
+	$stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
+	return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
+}
+
+function get_stylesheet_uri() {
+	$stylesheet_dir_uri = get_stylesheet_directory_uri();
+	$stylesheet_uri = $stylesheet_dir_uri . "/style.css";
+	return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
+}
+
+function get_locale_stylesheet_uri() {
+	global $wp_locale;
+	$stylesheet_dir_uri = get_stylesheet_directory_uri();
+	$dir = get_stylesheet_directory();
+	$locale = get_locale();
+	if ( file_exists("$dir/$locale.css") )
+		$stylesheet_uri = "$stylesheet_dir_uri/$locale.css";
+	elseif ( !empty($wp_locale->text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") )
+		$stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css";
+	else
+		$stylesheet_uri = '';
+	return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
+}
+
+function get_template() {
+	return apply_filters('template', get_option('template'));
+}
+
+function get_template_directory() {
+	$template = get_template();
+	$template_dir = get_theme_root() . "/$template";
+	return apply_filters('template_directory', $template_dir, $template);
+}
+
+function get_template_directory_uri() {
+	$template = get_template();
+	$template_dir_uri = get_theme_root_uri() . "/$template";
+	return apply_filters('template_directory_uri', $template_dir_uri, $template);
+}
+
+function get_theme_data( $theme_file ) {
+	$theme_data = implode( '', file( $theme_file ) );
+	$theme_data = str_replace ( '\r', '\n', $theme_data ); 
+	preg_match( '|Theme Name:(.*)|i', $theme_data, $theme_name );
+	preg_match( '|Theme URI:(.*)|i', $theme_data, $theme_uri );
+	preg_match( '|Description:(.*)|i', $theme_data, $description );
+	preg_match( '|Author:(.*)|i', $theme_data, $author_name );
+	preg_match( '|Author URI:(.*)|i', $theme_data, $author_uri );
+	preg_match( '|Template:(.*)|i', $theme_data, $template );
+	if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) )
+		$version = trim( $version[1] );
+	else
+		$version ='';
+	if ( preg_match('|Status:(.*)|i', $theme_data, $status) )
+		$status = trim($status[1]);
+	else
+		$status = 'publish';
+
+	$description = wptexturize( trim( $description[1] ) );
+
+	$name = $theme_name[1];
+	$name = trim( $name );
+	$theme = $name;
+	$theme_uri = trim( $theme_uri[1] );
+	$template = trim( $template[1] );
+
+	if ( '' == $author_uri[1] ) {
+		$author = trim( $author_name[1] );
+	} else {
+		$author = '<a href="' . trim( $author_uri[1] ) . '" title="' . __('Visit author homepage') . '">' . trim( $author_name[1] ) . '</a>';
+	}
+
+	return array( 'Name' => $name, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Status' => $status );
+}
+
+function get_themes() {
+	global $wp_themes, $wp_broken_themes;
+
+	if ( isset($wp_themes) )
+		return $wp_themes;
+
+	$themes = array();
+	$wp_broken_themes = array();
+	$theme_root = get_theme_root();
+	$theme_loc = str_replace(ABSPATH, '', $theme_root);
+
+	// Files in wp-content/themes directory and one subdir down
+	$themes_dir = @ dir($theme_root);
+	if ( !$themes_dir )
+		return false;
+
+	while ( ($theme_dir = $themes_dir->read()) !== false ) {
+		if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
+			if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
+				continue;
+			$stylish_dir = @ dir($theme_root . '/' . $theme_dir);
+			$found_stylesheet = false;
+			while ( ($theme_file = $stylish_dir->read()) !== false ) {
+				if ( $theme_file == 'style.css' ) {
+					$theme_files[] = $theme_dir . '/' . $theme_file;
+					$found_stylesheet = true;
+					break;
+				}
+			}
+			if ( !$found_stylesheet ) { // look for themes in that dir
+				$subdir = "$theme_root/$theme_dir";
+				$subdir_name = $theme_dir;
+				$theme_subdir = @dir( $subdir );
+				while ( ($theme_dir = $theme_subdir->read()) !== false ) {
+					if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
+						if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
+							continue;
+						$stylish_dir = @ dir($subdir . '/' . $theme_dir);
+						$found_stylesheet = false;
+						while ( ($theme_file = $stylish_dir->read()) !== false ) {
+							if ( $theme_file == 'style.css' ) {
+								$theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
+								$found_stylesheet = true;
+								break;
+							}
+						}
+					}
+				}
+				$wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
+			}
+		}
+	}
+
+	if ( !$themes_dir || !$theme_files )
+		return $themes;
+
+	sort($theme_files);
+
+	foreach ( (array) $theme_files as $theme_file ) {
+		if ( !is_readable("$theme_root/$theme_file") ) {
+			$wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
+			continue;
+		}
+
+		$theme_data = get_theme_data("$theme_root/$theme_file");
+
+		$name        = $theme_data['Name'];
+		$title       = $theme_data['Title'];
+		$description = wptexturize($theme_data['Description']);
+		$version     = $theme_data['Version'];
+		$author      = $theme_data['Author'];
+		$template    = $theme_data['Template'];
+		$stylesheet  = dirname($theme_file);
+
+		$screenshot = false;
+		foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) {
+			if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {
+				$screenshot = "screenshot.$ext";
+				break;
+			}
+		}
+
+		if ( empty($name) ) {
+			$name = dirname($theme_file);
+			$title = $name;
+		}
+
+		if ( empty($template) ) {
+			if ( file_exists(dirname("$theme_root/$theme_file/index.php")) )
+				$template = dirname($theme_file);
+			else
+				continue;
+		}
+
+		$template = trim($template);
+
+		if ( !file_exists("$theme_root/$template/index.php") ) {
+			$parent_dir = dirname(dirname($theme_file));
+			if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
+				$template = "$parent_dir/$template"; 
+			} else {
+				$wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
+				continue;
+			}
+		}
+
+		$stylesheet_files = array();
+		$stylesheet_dir = @ dir("$theme_root/$stylesheet");
+		if ( $stylesheet_dir ) {
+			while ( ($file = $stylesheet_dir->read()) !== false ) {
+				if ( !preg_match('|^\.+$|', $file) && preg_match('|\.css$|', $file) )
+					$stylesheet_files[] = "$theme_loc/$stylesheet/$file";
+			}
+		}
+
+		$template_files = array();
+		$template_dir = @ dir("$theme_root/$template");
+		if ( $template_dir ) {
+			while(($file = $template_dir->read()) !== false) {
+				if ( !preg_match('|^\.+$|', $file) && preg_match('|\.php$|', $file) )
+					$template_files[] = "$theme_loc/$template/$file";
+			}
+		}
+
+		$template_dir = dirname($template_files[0]);
+		$stylesheet_dir = dirname($stylesheet_files[0]);
+
+		if ( empty($template_dir) )
+			$template_dir = '/';
+		if ( empty($stylesheet_dir) )
+			$stylesheet_dir = '/';
+
+		// Check for theme name collision.  This occurs if a theme is copied to
+		// a new theme directory and the theme header is not updated.  Whichever
+		// theme is first keeps the name.  Subsequent themes get a suffix applied.
+		// The Default and Classic themes always trump their pretenders.
+		if ( isset($themes[$name]) ) {
+			if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) &&
+					 ('default' == $stylesheet || 'classic' == $stylesheet) ) {
+				// If another theme has claimed to be one of our default themes, move
+				// them aside.
+				$suffix = $themes[$name]['Stylesheet'];
+				$new_name = "$name/$suffix";
+				$themes[$new_name] = $themes[$name];
+				$themes[$new_name]['Name'] = $new_name;
+			} else {
+				$name = "$name/$stylesheet";
+			}
+		}
+
+		$themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot);
+	}
+
+	// Resolve theme dependencies.
+	$theme_names = array_keys($themes);
+
+	foreach ( (array) $theme_names as $theme_name ) {
+		$themes[$theme_name]['Parent Theme'] = '';
+		if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) {
+			foreach ( (array) $theme_names as $parent_theme_name ) {
+				if ( ($themes[$parent_theme_name]['Stylesheet'] == $themes[$parent_theme_name]['Template']) && ($themes[$parent_theme_name]['Template'] == $themes[$theme_name]['Template']) ) {
+					$themes[$theme_name]['Parent Theme'] = $themes[$parent_theme_name]['Name'];
+					break;
+				}
+			}
+		}
+	}
+
+	$wp_themes = $themes;
+
+	return $themes;
+}
+
+function get_theme($theme) {
+	$themes = get_themes();
+
+	if ( array_key_exists($theme, $themes) )
+		return $themes[$theme];
+
+	return NULL;
+}
+
+function get_current_theme() {
+	$themes = get_themes();
+	$theme_names = array_keys($themes);
+	$current_template = get_option('template');
+	$current_stylesheet = get_option('stylesheet');
+	$current_theme = 'WordPress Default';
+
+	if ( $themes ) {
+		foreach ( (array) $theme_names as $theme_name ) {
+			if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet &&
+					$themes[$theme_name]['Template'] == $current_template ) {
+				$current_theme = $themes[$theme_name]['Name'];
+				break;
+			}
+		}
+	}
+
+	return $current_theme;
+}
+
+function get_theme_root() {
+	return apply_filters('theme_root', ABSPATH . "wp-content/themes");
+}
+
+function get_theme_root_uri() {
+	return apply_filters('theme_root_uri', get_option('siteurl') . "/wp-content/themes", get_option('siteurl'));
+}
+
+function get_query_template($type) {
+	$template = '';
+	if ( file_exists(TEMPLATEPATH . "/{$type}.php") )
+		$template = TEMPLATEPATH . "/{$type}.php";
+
+	return apply_filters("{$type}_template", $template);
+}
+
+function get_404_template() {
+	return get_query_template('404');
+}
+
+function get_archive_template() {
+	return get_query_template('archive');
+}
+
+function get_author_template() {
+	return get_query_template('author');
+}
+
+function get_category_template() {
+	$template = '';
+	if ( file_exists(TEMPLATEPATH . "/category-" . get_query_var('cat') . '.php') )
+		$template = TEMPLATEPATH . "/category-" . get_query_var('cat') . '.php';
+	elseif ( file_exists(TEMPLATEPATH . "/category.php") )
+		$template = TEMPLATEPATH . "/category.php";
+
+	return apply_filters('category_template', $template);
+}
+
+function get_date_template() {
+	return get_query_template('date');
+}
+
+function get_home_template() {
+	$template = '';
+
+	if ( file_exists(TEMPLATEPATH . "/home.php") )
+		$template = TEMPLATEPATH . "/home.php";
+	elseif ( file_exists(TEMPLATEPATH . "/index.php") )
+		$template = TEMPLATEPATH . "/index.php";
+
+	return apply_filters('home_template', $template);
+}
+
+function get_page_template() {
+	global $wp_query;
+
+	$id = (int) $wp_query->post->ID;
+	$template = get_post_meta($id, '_wp_page_template', true);
+
+	if ( 'default' == $template )
+		$template = '';
+
+	if ( !empty($template) && file_exists(TEMPLATEPATH . "/$template") )
+		$template = TEMPLATEPATH . "/$template";
+	elseif ( file_exists(TEMPLATEPATH . "/page.php") )
+		$template = TEMPLATEPATH . "/page.php";
+	else
+		$template = '';
+
+	return apply_filters('page_template', $template);
+}
+
+function get_paged_template() {
+	return get_query_template('paged');
+}
+
+function get_search_template() {
+	return get_query_template('search');
+}
+
+function get_single_template() {
+	return get_query_template('single');
+}
+
+function get_attachment_template() {
+	global $posts;
+	$type = explode('/', $posts[0]->post_mime_type);
+	if ( $template = get_query_template($type[0]) )
+		return $template;
+	elseif ( $template = get_query_template($type[1]) )
+		return $template;
+	elseif ( $template = get_query_template("$type[0]_$type[1]") )
+		return $template;
+	else
+		return get_query_template('attachment');
+}
+
+function get_comments_popup_template() {
+	if ( file_exists( TEMPLATEPATH . '/comments-popup.php') )
+		$template = TEMPLATEPATH . '/comments-popup.php';
+	else
+		$template = get_theme_root() . '/default/comments-popup.php';
+
+	return apply_filters('comments_popup_template', $template);
+}
+
+function load_template($_template_file) {
+	global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query,
+		$wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment;
+
+	if ( is_array($wp_query->query_vars) )
+		extract($wp_query->query_vars, EXTR_SKIP);
+
+	require_once($_template_file);
+}
+
+function locale_stylesheet() {
+	$stylesheet = get_locale_stylesheet_uri();
+	if ( empty($stylesheet) )
+		return;
+	echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />';
+}
+
+function validate_current_theme() {
+	// Don't validate during an install/upgrade.
+	if ( defined('WP_INSTALLING') )
+		return true;
+
+	if ( get_template() != 'default' && !file_exists(get_template_directory() . '/index.php') ) {
+		update_option('template', 'default');
+		update_option('stylesheet', 'default');
+		do_action('switch_theme', 'Default');
+		return false;
+	}
+
+	if ( get_stylesheet() != 'default' && !file_exists(get_template_directory() . '/style.css') ) {
+		update_option('template', 'default');
+		update_option('stylesheet', 'default');
+		do_action('switch_theme', 'Default');
+		return false;
+	}
+
+	return true;
+}
+
+function get_theme_mod($name, $default = false) {
+	$theme = get_current_theme();
+
+	$mods = get_option("mods_$theme");
+
+	if ( isset($mods[$name]) )
+		return apply_filters( "theme_mod_$name", $mods[$name] );
+
+	return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri()) );
+}
+
+function set_theme_mod($name, $value) {
+	$theme = get_current_theme();
+
+	$mods = get_option("mods_$theme");
+
+	$mods[$name] = $value;
+
+	update_option("mods_$theme", $mods);
+	wp_cache_delete("mods_$theme", 'options');
+}
+
+function remove_theme_mod( $name ) {
+	$theme = get_current_theme();
+
+	$mods = get_option("mods_$theme");
+
+	if ( !isset($mods[$name]) )
+		return;
+
+	unset($mods[$name]);
+
+	if ( empty($mods) )
+		return remove_theme_mods();
+
+	update_option("mods_$theme", $mods);
+	wp_cache_delete("mods_$theme", 'options');
+}
+
+function remove_theme_mods() {
+	$theme = get_current_theme();
+
+	delete_option("mods_$theme");
+}
+
+function get_header_textcolor() {
+	return get_theme_mod('header_textcolor', HEADER_TEXTCOLOR);
+}
+
+function header_textcolor() {
+	echo get_header_textcolor();
+}
+
+function get_header_image() {
+	return get_theme_mod('header_image', HEADER_IMAGE);
+}
+
+function header_image() {
+	echo get_header_image();
+}
+
+function add_custom_image_header($header_callback, $admin_header_callback) {
+	if ( ! empty($header_callback) )
+		add_action('wp_head', $header_callback);
+
+	if ( ! is_admin() )
+		return;
+	require_once(ABSPATH . 'wp-admin/custom-header.php');
+	$GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback);
+	add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init'));
+}
+
+?>
diff -ruN 2.0.5/wp-includes/user.php 2.2.2/wp-includes/user.php
--- 2.0.5/wp-includes/user.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/user.php	2007-04-06 09:53:46.000000000 -0500
@@ -0,0 +1,182 @@
+<?php
+
+function get_profile($field, $user = false) {
+	global $wpdb;
+	if ( !$user )
+		$user = $wpdb->escape($_COOKIE[USER_COOKIE]);
+	return $wpdb->get_var("SELECT $field FROM $wpdb->users WHERE user_login = '$user'");
+}
+
+function get_usernumposts($userid) {
+	global $wpdb;
+	$userid = (int) $userid;
+	return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_author = '$userid' AND post_type = 'post' AND " . get_private_posts_cap_sql('post'));
+}
+
+// TODO: xmlrpc only.  Maybe move to xmlrpc.php.
+function user_pass_ok($user_login,$user_pass) {
+	global $cache_userdata;
+	if ( empty($cache_userdata[$user_login]) ) {
+		$userdata = get_userdatabylogin($user_login);
+	} else {
+		$userdata = $cache_userdata[$user_login];
+	}
+	return (md5($user_pass) == $userdata->user_pass);
+}
+
+//
+// User option functions
+//
+
+function get_user_option( $option, $user = 0 ) {
+	global $wpdb;
+
+	if ( empty($user) )
+		$user = wp_get_current_user();
+	else
+		$user = get_userdata($user);
+
+	if ( isset( $user->{$wpdb->prefix . $option} ) ) // Blog specific
+		return $user->{$wpdb->prefix . $option};
+	elseif ( isset( $user->{$option} ) ) // User specific and cross-blog
+		return $user->{$option};
+	else // Blog global
+		return get_option( $option );
+}
+
+function update_user_option( $user_id, $option_name, $newvalue, $global = false ) {
+	global $wpdb;
+	if ( !$global )
+		$option_name = $wpdb->prefix . $option_name;
+	return update_usermeta( $user_id, $option_name, $newvalue );
+}
+
+// Get users with capabilities for the current blog.
+// For setups that use the multi-blog feature.
+function get_users_of_blog( $id = '' ) {
+	global $wpdb, $blog_id;
+	if ( empty($id) )
+		$id = (int) $blog_id;
+	$users = $wpdb->get_results( "SELECT user_id, user_login, display_name, user_email, meta_value FROM $wpdb->users, $wpdb->usermeta WHERE " . $wpdb->users . ".ID = " . $wpdb->usermeta . ".user_id AND meta_key = '" . $wpdb->prefix . "capabilities' ORDER BY {$wpdb->usermeta}.user_id" );
+	return $users;
+}
+
+//
+// User meta functions
+//
+
+function delete_usermeta( $user_id, $meta_key, $meta_value = '' ) {
+	global $wpdb;
+	if ( !is_numeric( $user_id ) )
+		return false;
+	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+
+	if ( is_array($meta_value) || is_object($meta_value) )
+		$meta_value = serialize($meta_value);
+	$meta_value = trim( $meta_value );
+
+	if ( ! empty($meta_value) )
+		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key' AND meta_value = '$meta_value'");
+	else
+		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
+
+	$user = get_userdata($user_id);
+	wp_cache_delete($user_id, 'users');
+	wp_cache_delete($user->user_login, 'userlogins');
+
+	return true;
+}
+
+function get_usermeta( $user_id, $meta_key = '') {
+	global $wpdb;
+	$user_id = (int) $user_id;
+
+	if ( !empty($meta_key) ) {
+		$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+		$metas = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
+	} else {
+		$metas = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id'");
+	}
+
+	if ( empty($metas) ) {
+		if ( empty($meta_key) )
+			return array();
+		else
+			return '';
+	}
+
+	foreach ($metas as $index => $meta) {
+		@ $value = unserialize($meta->meta_value);
+		if ( $value === FALSE )
+			$value = $meta->meta_value;
+
+		$values[] = $value;
+	}
+
+	if ( count($values) == 1 )
+		return $values[0];
+	else
+		return $values;
+}
+
+function update_usermeta( $user_id, $meta_key, $meta_value ) {
+	global $wpdb;
+	if ( !is_numeric( $user_id ) )
+		return false;
+	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+
+	// FIXME: usermeta data is assumed to be already escaped
+	if ( is_string($meta_value) )
+		$meta_value = stripslashes($meta_value);
+	$meta_value = maybe_serialize($meta_value);
+	$meta_value = $wpdb->escape($meta_value);
+
+	if (empty($meta_value)) {
+		return delete_usermeta($user_id, $meta_key);
+	}
+
+	$cur = $wpdb->get_row("SELECT * FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
+	if ( !$cur ) {
+		$wpdb->query("INSERT INTO $wpdb->usermeta ( user_id, meta_key, meta_value )
+		VALUES
+		( '$user_id', '$meta_key', '$meta_value' )");
+	} else if ( $cur->meta_value != $meta_value ) {
+		$wpdb->query("UPDATE $wpdb->usermeta SET meta_value = '$meta_value' WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
+	} else {
+		return false;
+	}
+
+	$user = get_userdata($user_id);
+	wp_cache_delete($user_id, 'users');
+	wp_cache_delete($user->user_login, 'userlogins');
+
+	return true;
+}
+
+//
+// Private helper functions
+//
+
+// Setup global user vars.  Used by set_current_user() for back compat.
+function setup_userdata($user_id = '') {
+	global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity;
+
+	if ( '' == $user_id )
+		$user = wp_get_current_user();
+	else
+		$user = new WP_User($user_id);
+
+	if ( 0 == $user->ID )
+		return;
+
+	$userdata = $user->data;
+	$user_login	= $user->user_login;
+	$user_level	= (int) $user->user_level;
+	$user_ID	= (int) $user->ID;
+	$user_email	= $user->user_email;
+	$user_url	= $user->user_url;
+	$user_pass_md5	= md5($user->user_pass);
+	$user_identity	= $user->display_name;
+}
+
+?>
diff -ruN 2.0.5/wp-includes/vars.php 2.2.2/wp-includes/vars.php
--- 2.0.5/wp-includes/vars.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/vars.php	2007-03-19 22:18:44.000000000 -0500
@@ -1,9 +1,9 @@
 <?php
 
 // On which page are we ?
-if (preg_match('#([^/]+\.php)$#', $PHP_SELF, $self_matches)) {
+if ( preg_match('#([^/]+\.php)$#', $PHP_SELF, $self_matches) ) {
 	$pagenow = $self_matches[1];
-} else if (strstr($PHP_SELF, '?')) {
+} elseif ( strpos($PHP_SELF, '?') !== false ) {
 	$pagenow = explode('/', $PHP_SELF);
 	$pagenow = trim($pagenow[(sizeof($pagenow)-1)]);
 	$pagenow = explode('?', $pagenow);
@@ -13,88 +13,26 @@
 }
 
 // Simple browser detection
-$is_lynx = 0; $is_gecko = 0; $is_winIE = 0; $is_macIE = 0; $is_opera = 0; $is_NS4 = 0;
+$is_lynx = $is_gecko = $is_winIE = $is_macIE = $is_opera = $is_NS4 = false;
 
-if (preg_match('/Lynx/', $_SERVER['HTTP_USER_AGENT'])) {
-	$is_lynx = 1;
-} elseif (preg_match('/Gecko/', $_SERVER['HTTP_USER_AGENT'])) {
-	$is_gecko = 1;
-} elseif ((preg_match('/MSIE/', $_SERVER['HTTP_USER_AGENT'])) && (preg_match('/Win/', $_SERVER['HTTP_USER_AGENT']))) {
-	$is_winIE = 1;
-} elseif ((preg_match('/MSIE/', $_SERVER['HTTP_USER_AGENT'])) && (preg_match('/Mac/', $_SERVER['HTTP_USER_AGENT']))) {
-	$is_macIE = 1;
-} elseif (preg_match('/Opera/', $_SERVER['HTTP_USER_AGENT'])) {
-	$is_opera = 1;
-} elseif ((preg_match('/Nav/', $_SERVER['HTTP_USER_AGENT']) ) || (preg_match('/Mozilla\/4\./', $_SERVER['HTTP_USER_AGENT']))) {
-	$is_NS4 = 1;
+if (strpos($_SERVER['HTTP_USER_AGENT'], 'Lynx') !== false) {
+	$is_lynx = true;
+} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false) {
+	$is_gecko = true;
+} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Win') !== false) {
+	$is_winIE = true;
+} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') !== false) {
+	$is_macIE = true;
+} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') !== false) {
+	$is_opera = true;
+} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Nav') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Mozilla/4.') !== false) {
+	$is_NS4 = true;
 }
-$is_IE    = (($is_macIE) || ($is_winIE));
 
-// Server detection
-$is_apache = ( strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') || strstr($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') ) ? 1 : 0;
-$is_IIS = strstr($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') ? 1 : 0;
-
-// On OS X Server, $_SERVER['REMOTE_ADDR'] is the server's address. Workaround this 
-// by using $_SERVER['HTTP_PC_REMOTE_ADDR'], which *is* the remote address.
-if ( isset($_SERVER['HTTP_PC_REMOTE_ADDR']) )
-	$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_PC_REMOTE_ADDR'];
-
-// if the config file does not provide the smilies array, let's define it here
-if (!isset($wpsmiliestrans)) {
-	$wpsmiliestrans = array(
-	':mrgreen:'	=> 'icon_mrgreen.gif',
-	':neutral:'	=> 'icon_neutral.gif',
-	':twisted:'	=> 'icon_twisted.gif',
-	':arrow:'	=> 'icon_arrow.gif',
-	':shock:'	=> 'icon_eek.gif',
-	':smile:'	=> 'icon_smile.gif',
-	' :???:'	=> 'icon_confused.gif',
-	':cool:'	=> 'icon_cool.gif',
-	':evil:'	=> 'icon_evil.gif',
-	':grin:'	=> 'icon_biggrin.gif',
-	':idea:'	=> 'icon_idea.gif',
-	':oops:'	=> 'icon_redface.gif',
-	':razz:'	=> 'icon_razz.gif',
-	':roll:'	=> 'icon_rolleyes.gif',
-	':wink:'	=> 'icon_wink.gif',
-	':cry:'		=> 'icon_cry.gif',
-	':eek:'		=> 'icon_surprised.gif',
-	':lol:'		=> 'icon_lol.gif',
-	':mad:'		=> 'icon_mad.gif',
-	':sad:'		=> 'icon_sad.gif',
-	' 8-)'		=> 'icon_cool.gif',
-	' 8-O'		=> 'icon_eek.gif',
-	' :-('		=> 'icon_sad.gif',
-	' :-)'		=> 'icon_smile.gif',
-	' :-?'		=> 'icon_confused.gif',
-	' :-D'		=> 'icon_biggrin.gif',
-	' :-P'		=> 'icon_razz.gif',
-	' :-o'		=> 'icon_surprised.gif',
-	' :-x'		=> 'icon_mad.gif',
-	' :-|'		=> 'icon_neutral.gif',
-	' ;-)'		=> 'icon_wink.gif',
-	' 8)'		=> 'icon_cool.gif',
-	' 8O'		=> 'icon_eek.gif',
-	' :('		=> 'icon_sad.gif',
-	' :)'		=> 'icon_smile.gif',
-	' :?'		=> 'icon_confused.gif',
-	' :D'		=> 'icon_biggrin.gif',
-	' :P'		=> 'icon_razz.gif',
-	' :o'		=> 'icon_surprised.gif',
-	' :x'		=> 'icon_mad.gif',
-	' :|'		=> 'icon_neutral.gif',
-	' ;)'		=> 'icon_wink.gif',
-	':!:'		=> 'icon_exclaim.gif',
-	':?:'		=> 'icon_question.gif',
-	);
-}
+$is_IE = ( $is_macIE || $is_winIE );
 
+// Server detection
+$is_apache = ((strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) || (strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false)) ? true : false;
+$is_IIS = (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) ? true : false;
 
-// generates smilies' search & replace arrays
-foreach($wpsmiliestrans as $smiley => $img) {
-	$wp_smiliessearch[] = $smiley;
-	$smiley_masked = htmlspecialchars( trim($smiley) , ENT_QUOTES);
-	$wp_smiliesreplace[] = " <img src='" . get_settings('siteurl') . "/wp-includes/images/smilies/$img' alt='$smiley_masked' class='wp-smiley' /> ";
-}
-
-?>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/version.php 2.2.2/wp-includes/version.php
--- 2.0.5/wp-includes/version.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/version.php	2007-08-05 00:39:35.000000000 -0500
@@ -1,8 +1,8 @@
 <?php
 
-// This just holds the version number, in a separate file so we can bump it without cluttering the SVN
+// This holds the version number in a separate file so we can bump it without cluttering the SVN
 
-$wp_version = '2.0.5';
-$wp_db_version = 3441;
+$wp_version = '2.2.2';
+$wp_db_version = 5183;
 
 ?>
diff -ruN 2.0.5/wp-includes/widgets.php 2.2.2/wp-includes/widgets.php
--- 2.0.5/wp-includes/widgets.php	1969-12-31 18:00:00.000000000 -0600
+++ 2.2.2/wp-includes/widgets.php	2007-07-30 11:23:45.000000000 -0500
@@ -0,0 +1,996 @@
+<?php
+
+/* Global Variables */
+
+global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_styles, $wp_registered_widget_defaults;
+
+$wp_registered_sidebars = array();
+$wp_registered_widgets = array();
+$wp_registered_widget_controls = array();
+$wp_registered_widget_styles = array();
+$wp_register_widget_defaults = false;
+
+/* Template tags & API functions */
+
+function register_sidebars($number = 1, $args = array()) {
+	$number = (int) $number;
+
+	if ( is_string($args) )
+		parse_str($args, $args);
+
+	$i = 1;
+
+	while ( $i <= $number ) {
+		$_args = $args;
+		if ( $number > 1 ) {
+			$_args['name'] = isset($args['name']) ? $args['name'] : sprintf(__('Sidebar %d'), $i);
+		} else {
+			$_args['name'] = isset($args['name']) ? $args['name'] : __('Sidebar');
+		}
+		$_args['id'] = isset($args['id']) ? $args['id'] : "sidebar-$i";
+		register_sidebar($_args);
+		++$i;
+	}
+}
+
+function register_sidebar($args = array()) {
+	global $wp_registered_sidebars;
+
+	if ( is_string($args) )
+		parse_str($args, $args);
+
+	$i = count($wp_registered_sidebars) + 1;
+
+	$defaults = array(
+		'name' => sprintf(__('Sidebar %d'), $i ),
+		'id' => "sidebar-$i",
+		'before_widget' => '<li id="%1$s" class="widget %2$s">',
+		'after_widget' => "</li>\n",
+		'before_title' => '<h2 class="widgettitle">',
+		'after_title' => "</h2>\n",
+	);
+
+	$sidebar = array_merge($defaults, $args);
+
+	$wp_registered_sidebars[$sidebar['id']] = $sidebar;
+
+	return $sidebar['id'];
+}
+
+function unregister_sidebar( $name ) {
+	global $wp_registered_sidebars;
+		
+	if ( isset( $wp_registered_sidebars[$name] ) )
+		unset( $wp_registered_sidebars[$name] );
+}
+
+function register_sidebar_widget($name, $output_callback, $classname = '') {
+	// Compat
+	if ( is_array($name) ) {
+		if ( count($name) == 3 )
+			$name = sprintf($name[0], $name[2]);
+		else
+			$name = $name[0];
+	}
+
+	$id = sanitize_title($name);
+	$options = array();
+	if ( !empty($classname) && is_string($classname) )
+		$options['classname'] = $classname;
+	$params = array_slice(func_get_args(), 2);
+	$args = array($id, $name, $output_callback, $options);
+	if ( !empty($params) )
+		$args = array_merge($args, $params);
+
+	call_user_func_array('wp_register_sidebar_widget', $args);
+}
+
+function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) {
+
+	global $wp_registered_widgets, $wp_register_widget_defaults;
+
+	$id = sanitize_title($id);
+
+	if ( empty($output_callback) ) {
+		unset($wp_registered_widgets[$id]);
+		return;
+	}
+
+	$defaults = array('classname' => $output_callback);
+	$options = wp_parse_args($options, $defaults);
+	$widget = array(
+		'name' => $name,
+		'id' => $id,
+		'callback' => $output_callback,
+		'params' => array_slice(func_get_args(), 4)
+	);
+	$widget = array_merge($widget, $options);
+
+	if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || !$wp_register_widget_defaults) )
+		$wp_registered_widgets[$id] = $widget;
+}
+
+function unregister_sidebar_widget($id) {
+	return wp_unregister_sidebar_widget($id);
+}
+
+function wp_unregister_sidebar_widget($id) {
+	wp_register_sidebar_widget($id, '', '');
+	wp_unregister_widget_control($id);
+}
+
+function register_widget_control($name, $control_callback, $width = '', $height = '') {
+	// Compat
+	if ( is_array($name) ) {
+		if ( count($name) == 3 )
+			$name = sprintf($name[0], $name[2]);
+		else
+			$name = $name[0];
+	}
+
+	$id = sanitize_title($name);
+	$options = array();
+	if ( !empty($width) )
+		$options['width'] = $width;
+	if ( !empty($height) )
+		$options['height'] = $height;
+	$params = array_slice(func_get_args(), 4);
+	$args = array($id, $name, $control_callback, $options);
+	if ( !empty($params) )
+		$args = array_merge($args, $params);
+
+	call_user_func_array('wp_register_widget_control', $args);
+}
+
+function wp_register_widget_control($id, $name, $control_callback, $options = array()) {
+	global $wp_registered_widget_controls, $wp_register_widget_defaults;
+
+	$id = sanitize_title($id);
+
+	if ( empty($control_callback) ) {
+		unset($wp_registered_widget_controls[$id]);
+		return;
+	}
+
+	if ( isset($wp_registered_widget_controls[$id]) && $wp_register_widget_defaults )
+		return;
+
+	$defaults = array('width' => 300, 'height' => 200);
+	$options = wp_parse_args($options, $defaults);
+	$options['width'] = (int) $options['width'];
+	$options['height'] = (int) $options['height'];
+	$options['width'] = $options['width'] > 90 ? $options['width'] + 60 : 360;
+	$options['height'] = $options['height'] > 60 ? $options['height'] + 40 : 240;
+
+	$widget = array(
+		'name' => $name,
+		'id' => $id,
+		'callback' => $control_callback,
+		'params' => array_slice(func_get_args(), 4)
+	);
+	$widget = array_merge($widget, $options);
+
+	$wp_registered_widget_controls[$id] = $widget;
+}
+
+function unregister_widget_control($id) {
+	return wp_unregister_widget_control($id);
+}
+
+function wp_unregister_widget_control($id) {
+	return wp_register_widget_control($id, '', '');
+}
+
+function dynamic_sidebar($index = 1) {
+	global $wp_registered_sidebars, $wp_registered_widgets;
+
+	if ( is_int($index) ) {
+		$index = "sidebar-$index";
+	} else {
+		$index = sanitize_title($index);
+		foreach ( $wp_registered_sidebars as $key => $value ) {
+			if ( sanitize_title($value['name']) == $index ) {
+				$index = $key;
+				break;
+			}
+		}
+	}
+
+	$sidebars_widgets = wp_get_sidebars_widgets();
+
+	if ( empty($wp_registered_sidebars[$index]) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) )
+		return false;
+
+	$sidebar = $wp_registered_sidebars[$index];
+
+	$did_one = false;
+	foreach ( $sidebars_widgets[$index] as $id ) {
+		$callback = $wp_registered_widgets[$id]['callback'];
+
+		$params = array_merge(array($sidebar), (array) $wp_registered_widgets[$id]['params']);
+
+		// Substitute HTML id and class attributes into before_widget
+		$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $wp_registered_widgets[$id]['classname']);
+
+		if ( is_callable($callback) ) {
+			call_user_func_array($callback, $params);
+			$did_one = true;
+		}
+	}
+
+	return $did_one;
+}
+
+function is_active_widget($callback) {
+	global $wp_registered_widgets;
+
+	$sidebars_widgets = wp_get_sidebars_widgets(false);
+
+	if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $sidebar => $widgets )
+		if ( is_array($widgets) ) foreach ( $widgets as $widget )
+			if ( $wp_registered_widgets[$widget]['callback'] == $callback )
+				return true;
+
+	return false;
+}
+
+function is_dynamic_sidebar() {
+	global $wp_registered_widgets, $wp_registered_sidebars;
+	$sidebars_widgets = get_option('sidebars_widgets');
+	foreach ( $wp_registered_sidebars as $index => $sidebar ) {
+		if ( count($sidebars_widgets[$index]) ) {
+			foreach ( $sidebars_widgets[$index] as $widget )
+				if ( array_key_exists($widget, $wp_registered_widgets) )
+					return true;
+		}
+	}
+	return false;
+}
+
+/* Internal Functions */
+
+function wp_get_sidebars_widgets($update = true) {
+	global $wp_registered_widgets, $wp_registered_sidebars;
+
+	$sidebars_widgets = get_option('sidebars_widgets');
+	$_sidebars_widgets = array();
+
+	if ( !isset($sidebars_widgets['array_version']) )
+		$sidebars_widgets['array_version'] = 1;
+
+	switch ( $sidebars_widgets['array_version'] ) {
+		case 1 :
+			foreach ( $sidebars_widgets as $index => $sidebar )
+			if ( is_array($sidebar) )
+			foreach ( $sidebar as $i => $name ) {
+				$id = strtolower($name);
+				if ( isset($wp_registered_widgets[$id]) ) {
+					$_sidebars_widgets[$index][$i] = $id;
+					continue;
+				}
+				$id = sanitize_title($name);
+				if ( isset($wp_registered_widgets[$id]) ) {
+					$_sidebars_widgets[$index][$i] = $id;
+					continue;
+				}
+				unset($_sidebars_widgets[$index][$i]);
+			}
+			$_sidebars_widgets['array_version'] = 2;
+			$sidebars_widgets = $_sidebars_widgets;
+			unset($_sidebars_widgets);
+
+		case 2 :
+			$sidebars = array_keys( $wp_registered_sidebars );
+			if ( !empty( $sidebars ) ) {
+				// Move the known-good ones first
+				foreach ( $sidebars as $id ) {
+					if ( array_key_exists( $id, $sidebars_widgets ) ) {
+						$_sidebars_widgets[$id] = $sidebars_widgets[$id];
+						unset($sidebars_widgets[$id], $sidebars[$id]);
+					}
+				}
+
+				// Assign to each unmatched registered sidebar the first available orphan
+				unset( $sidebars_widgets[ 'array_version' ] );
+				while ( ( $sidebar = array_shift( $sidebars ) ) && $widgets = array_shift( $sidebars_widgets ) )
+					$_sidebars_widgets[ $sidebar ] = $widgets;
+
+				$_sidebars_widgets['array_version'] = 3;
+				$sidebars_widgets = $_sidebars_widgets;
+				unset($_sidebars_widgets);
+			}
+
+			if ( $update )
+				update_option('sidebars_widgets', $sidebars_widgets);
+	}
+
+	unset($sidebars_widgets['array_version']);
+
+	return $sidebars_widgets;
+}
+
+function wp_set_sidebars_widgets( $sidebars_widgets ) {
+	update_option( 'sidebars_widgets', $sidebars_widgets );
+}
+
+function wp_get_widget_defaults() {
+	global $wp_registered_sidebars;
+
+	$defaults = array();
+
+	foreach ( $wp_registered_sidebars as $index => $sidebar )
+		$defaults[$index] = array();
+
+	return $defaults;
+}
+
+/* Default Widgets */
+
+function wp_widget_pages( $args ) {
+	extract( $args );
+	$options = get_option( 'widget_pages' );
+	
+	$title = empty( $options['title'] ) ? __( 'Pages' ) : $options['title'];
+	$sortby = empty( $options['sortby'] ) ? 'menu_order' : $options['sortby'];
+	$exclude = empty( $options['exclude'] ) ? '' : '&exclude=' . $options['exclude'];
+	
+	if ( $sortby == 'menu_order' ) {
+		$sortby = 'menu_order, post_title';
+	}
+	
+	$out = wp_list_pages( 'title_li=&echo=0&sort_column=' . $sortby . $exclude );
+	
+	if ( !empty( $out ) ) {
+?>
+	<?php echo $before_widget; ?>
+		<?php echo $before_title . $title . $after_title; ?>
+		<ul>
+			<?php echo $out; ?>
+		</ul>
+	<?php echo $after_widget; ?>
+<?php
+	}
+}
+
+function wp_widget_pages_control() {
+	$options = $newoptions = get_option('widget_pages');
+	if ( $_POST['pages-submit'] ) {
+		$newoptions['title'] = strip_tags(stripslashes($_POST['pages-title']));
+		
+		$sortby = stripslashes( $_POST['pages-sortby'] );
+		
+		if ( in_array( $sortby, array( 'post_title', 'menu_order', 'ID' ) ) ) {
+			$newoptions['sortby'] = $sortby;
+		} else {
+			$newoptions['sortby'] = 'menu_order';
+		}
+		
+		$newoptions['exclude'] = strip_tags( stripslashes( $_POST['pages-exclude'] ) );
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_pages', $options);
+	}
+	$title = attribute_escape($options['title']);
+	$exclude = attribute_escape( $options['exclude'] );
+?>
+			<p><label for="pages-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="pages-title" name="pages-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<p><label for="pages-sortby"><?php _e( 'Sort by:' ); ?> 
+				<select name="pages-sortby" id="pages-sortby">
+					<option value="post_title"<?php selected( $options['sortby'], 'post_title' ); ?>><?php _e('Page title'); ?></option>
+					<option value="menu_order"<?php selected( $options['sortby'], 'menu_order' ); ?>><?php _e('Page order'); ?></option>
+					<option value="ID"<?php selected( $options['sortby'], 'ID' ); ?>><?php _e( 'Page ID' ); ?></option>
+				</select></label></p>
+			<p><label for="pages-exclude"><?php _e( 'Exclude:' ); ?> <input type="text" value="<?php echo $exclude; ?>" name="pages-exclude" id="pages-exclude" style="width: 180px;" /></label><br />
+			<small><?php _e( 'Page IDs, separated by commas.' ); ?></small></p>
+			<input type="hidden" id="pages-submit" name="pages-submit" value="1" />
+<?php
+}
+
+function wp_widget_links($args) {
+	global $wp_db_version;
+	extract($args, EXTR_SKIP);
+	if ( $wp_db_version < 3582 ) {
+		// This ONLY works with li/h2 sidebars.
+		get_links_list();
+	} else {
+		wp_list_bookmarks(array(
+			'title_before' => $before_title, 'title_after' => $after_title, 
+			'category_before' => $before_widget, 'category_after' => $after_widget, 
+			'show_images' => true, 'class' => 'linkcat widget'
+		));
+	}
+}
+
+function wp_widget_search($args) {
+	extract($args);
+?>
+		<?php echo $before_widget; ?>
+			<form id="searchform" method="get" action="<?php bloginfo('home'); ?>">
+			<div>
+			<input type="text" name="s" id="s" size="15" /><br />
+			<input type="submit" value="<?php echo attribute_escape(__('Search')); ?>" />
+			</div>
+			</form>
+		<?php echo $after_widget; ?>
+<?php
+}
+
+function wp_widget_archives($args) {
+	extract($args);
+	$options = get_option('widget_archives');
+	$c = $options['count'] ? '1' : '0';
+	$d = $options['dropdown'] ? '1' : '0';
+	$title = empty($options['title']) ? __('Archives') : $options['title'];
+
+	echo $before_widget; 
+	echo $before_title . $title . $after_title;
+
+	if($d) { 
+?>
+		<select name="archive-dropdown" onChange='document.location.href=this.options[this.selectedIndex].value;'> <option value=""><?php echo attribute_escape(__('Select Month')); ?></option> <?php wp_get_archives("type=monthly&format=option&show_post_count=$c"); ?> </select>
+<?php	
+	} else { 
+?>
+		<ul>
+		<?php wp_get_archives("type=monthly&show_post_count=$c"); ?>
+		</ul>
+<?php
+	}
+
+	echo $after_widget; 
+}
+
+function wp_widget_archives_control() {
+	$options = $newoptions = get_option('widget_archives');
+	if ( $_POST["archives-submit"] ) {
+		$newoptions['count'] = isset($_POST['archives-count']);
+		$newoptions['dropdown'] = isset($_POST['archives-dropdown']);
+		$newoptions['title'] = strip_tags(stripslashes($_POST["archives-title"]));
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_archives', $options);
+	}
+	$count = $options['count'] ? 'checked="checked"' : '';
+	$dropdown = $options['dropdown'] ? 'checked="checked"' : '';
+	$title = attribute_escape($options['title']);
+?>
+			<p><label for="archives-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="archives-title" name="archives-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<p style="text-align:right;margin-right:40px;"><label for="archives-count"><?php _e('Show post counts'); ?> <input class="checkbox" type="checkbox" <?php echo $count; ?> id="archives-count" name="archives-count" /></label></p>
+			<p style="text-align:right;margin-right:40px;"><label for="archives-dropdown"><?php _e('Display as a drop down'); ?> <input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="archives-dropdown" name="archives-dropdown" /></label></p>
+			<input type="hidden" id="archives-submit" name="archives-submit" value="1" />
+<?php
+}
+
+function wp_widget_meta($args) {
+	extract($args);
+	$options = get_option('widget_meta');
+	$title = empty($options['title']) ? __('Meta') : $options['title'];
+?>
+		<?php echo $before_widget; ?>
+			<?php echo $before_title . $title . $after_title; ?>
+			<ul>
+			<?php wp_register(); ?>
+			<li><?php wp_loginout(); ?></li>
+			<li><a href="<?php bloginfo('rss2_url'); ?>" title="<?php echo attribute_escape(__('Syndicate this site using RSS 2.0')); ?>"><?php _e('Entries <abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
+			<li><a href="<?php bloginfo('comments_rss2_url'); ?>" title="<?php echo attribute_escape(__('The latest comments to all posts in RSS')); ?>"><?php _e('Comments <abbr title="Really Simple Syndication">RSS</abbr>'); ?></a></li>
+			<li><a href="http://wordpress.org/" title="<?php echo attribute_escape(__('Powered by WordPress, state-of-the-art semantic personal publishing platform.')); ?>">WordPress.org</a></li>
+			<?php wp_meta(); ?>
+			</ul>
+		<?php echo $after_widget; ?>
+<?php
+}
+function wp_widget_meta_control() {
+	$options = $newoptions = get_option('widget_meta');
+	if ( $_POST["meta-submit"] ) {
+		$newoptions['title'] = strip_tags(stripslashes($_POST["meta-title"]));
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_meta', $options);
+	}
+	$title = attribute_escape($options['title']);
+?>
+			<p><label for="meta-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="meta-title" name="meta-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<input type="hidden" id="meta-submit" name="meta-submit" value="1" />
+<?php
+}
+
+function wp_widget_calendar($args) {
+	extract($args);
+	$options = get_option('widget_calendar');
+	$title = $options['title'];
+	if ( empty($title) )
+		$title = '&nbsp;';
+	echo $before_widget . $before_title . $title . $after_title;
+	echo '<div id="calendar_wrap">';
+	get_calendar();
+	echo '</div>';
+	echo $after_widget;
+}
+function wp_widget_calendar_control() {
+	$options = $newoptions = get_option('widget_calendar');
+	if ( $_POST["calendar-submit"] ) {
+		$newoptions['title'] = strip_tags(stripslashes($_POST["calendar-title"]));
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_calendar', $options);
+	}
+	$title = attribute_escape($options['title']);
+?>
+			<p><label for="calendar-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="calendar-title" name="calendar-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<input type="hidden" id="calendar-submit" name="calendar-submit" value="1" />
+<?php
+}
+
+function wp_widget_text($args, $number = 1) {
+	extract($args);
+	$options = get_option('widget_text');
+	$title = $options[$number]['title'];
+	$text = apply_filters( 'widget_text', $options[$number]['text'] );
+?>
+		<?php echo $before_widget; ?>
+			<?php if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
+			<div class="textwidget"><?php echo $text; ?></div>
+		<?php echo $after_widget; ?>
+<?php
+}
+
+function wp_widget_text_control($number) {
+	$options = $newoptions = get_option('widget_text');
+	if ( !is_array($options) )
+		$options = $newoptions = array();
+	if ( $_POST["text-submit-$number"] ) {
+		$newoptions[$number]['title'] = strip_tags(stripslashes($_POST["text-title-$number"]));
+		$newoptions[$number]['text'] = stripslashes($_POST["text-text-$number"]);
+		if ( !current_user_can('unfiltered_html') )
+			$newoptions[$number]['text'] = stripslashes(wp_filter_post_kses($newoptions[$number]['text']));
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_text', $options);
+	}
+	$title = attribute_escape($options[$number]['title']);
+	$text = format_to_edit($options[$number]['text']);
+?>
+			<input style="width: 450px;" id="text-title-<?php echo $number; ?>" name="text-title-<?php echo $number; ?>" type="text" value="<?php echo $title; ?>" />
+			<textarea style="width: 450px; height: 280px;" id="text-text-<?php echo $number; ?>" name="text-text-<?php echo $number; ?>"><?php echo $text; ?></textarea>
+			<input type="hidden" id="text-submit-<?php echo "$number"; ?>" name="text-submit-<?php echo "$number"; ?>" value="1" />
+<?php
+}
+
+function wp_widget_text_setup() {
+	$options = $newoptions = get_option('widget_text');
+	if ( isset($_POST['text-number-submit']) ) {
+		$number = (int) $_POST['text-number'];
+		if ( $number > 9 ) $number = 9;
+		if ( $number < 1 ) $number = 1;
+		$newoptions['number'] = $number;
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_text', $options);
+		wp_widget_text_register($options['number']);
+	}
+}
+
+function wp_widget_text_page() {
+	$options = $newoptions = get_option('widget_text');
+?>
+	<div class="wrap">
+		<form method="POST">
+			<h2><?php _e('Text Widgets'); ?></h2>
+			<p style="line-height: 30px;"><?php _e('How many text widgets would you like?'); ?>
+			<select id="text-number" name="text-number" value="<?php echo $options['number']; ?>">
+<?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?>
+			</select>
+			<span class="submit"><input type="submit" name="text-number-submit" id="text-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p>
+		</form>
+	</div>
+<?php
+}
+
+function wp_widget_text_register() {
+	$options = get_option('widget_text');
+	$number = $options['number'];
+	if ( $number < 1 ) $number = 1;
+	if ( $number > 9 ) $number = 9;
+	$dims = array('width' => 460, 'height' => 350);
+	$class = array('classname' => 'widget_text');
+	for ($i = 1; $i <= 9; $i++) {
+		$name = sprintf(__('Text %d'), $i);
+		$id = "text-$i"; // Never never never translate an id
+		wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_text' : /* unregister */ '', $class, $i);
+		wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_text_control' : /* unregister */ '', $dims, $i);
+	}
+	add_action('sidebar_admin_setup', 'wp_widget_text_setup');
+	add_action('sidebar_admin_page', 'wp_widget_text_page');
+}
+
+function wp_widget_categories($args) {
+	extract($args);
+	$options = get_option('widget_categories');
+	$c = $options['count'] ? '1' : '0';
+	$h = $options['hierarchical'] ? '1' : '0';
+	$d = $options['dropdown'] ? '1' : '0';
+	$title = empty($options['title']) ? __('Categories') : $options['title'];
+
+	echo $before_widget;
+	echo $before_title . $title . $after_title; 
+
+	$cat_args = "orderby=name&show_count={$c}&hierarchical={$h}";
+
+	if($d) {
+		wp_dropdown_categories($cat_args . '&show_option_none= ' . __('Select Category'));
+?>
+
+<script lang='javascript'><!--
+    var dropdown = document.getElementById("cat");
+    function onCatChange() {
+		if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
+			location.href = "<?php echo get_option('home'); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value;
+		}
+    }
+    dropdown.onchange = onCatChange;
+--></script>
+
+<?php
+	} else {
+?>
+		<ul>
+		<?php wp_list_categories($cat_args . '&title_li='); ?>
+		</ul>
+<?php
+	}
+
+	echo $after_widget;
+}
+
+function wp_widget_categories_control() {
+	$options = $newoptions = get_option('widget_categories');
+	if ( $_POST['categories-submit'] ) {
+		$newoptions['count'] = isset($_POST['categories-count']);
+		$newoptions['hierarchical'] = isset($_POST['categories-hierarchical']);
+		$newoptions['dropdown'] = isset($_POST['categories-dropdown']);
+		$newoptions['title'] = strip_tags(stripslashes($_POST['categories-title']));
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_categories', $options);
+	}
+	$count = $options['count'] ? 'checked="checked"' : '';
+	$hierarchical = $options['hierarchical'] ? 'checked="checked"' : '';
+	$dropdown = $options['dropdown'] ? 'checked="checked"' : '';
+	$title = attribute_escape($options['title']);
+?>
+			<p><label for="categories-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="categories-title" name="categories-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<p style="text-align:right;margin-right:40px;"><label for="categories-count"><?php _e('Show post counts'); ?> <input class="checkbox" type="checkbox" <?php echo $count; ?> id="categories-count" name="categories-count" /></label></p>
+			<p style="text-align:right;margin-right:40px;"><label for="categories-hierarchical" style="text-align:right;"><?php _e('Show hierarchy'); ?> <input class="checkbox" type="checkbox" <?php echo $hierarchical; ?> id="categories-hierarchical" name="categories-hierarchical" /></label></p>
+			<p style="text-align:right;margin-right:40px;"><label for="categories-dropdown" style="text-align:right;"><?php _e('Display as a drop down'); ?> <input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="categories-dropdown" name="categories-dropdown" /></label></p>
+			<input type="hidden" id="categories-submit" name="categories-submit" value="1" />
+<?php
+}
+
+function wp_widget_recent_entries($args) {
+	if ( $output = wp_cache_get('widget_recent_entries') )
+		return print($output);
+
+	ob_start();
+	extract($args);
+	$options = get_option('widget_recent_entries');
+	$title = empty($options['title']) ? __('Recent Posts') : $options['title'];
+	if ( !$number = (int) $options['number'] )
+		$number = 10;
+	else if ( $number < 1 )
+		$number = 1;
+	else if ( $number > 15 )
+		$number = 15;
+
+	$r = new WP_Query("showposts=$number&what_to_show=posts&nopaging=0");
+	if ($r->have_posts()) :
+?>
+		<?php echo $before_widget; ?>
+			<?php echo $before_title . $title . $after_title; ?>
+			<ul>
+			<?php  while ($r->have_posts()) : $r->the_post(); ?>
+			<li><a href="<?php the_permalink() ?>"><?php if ( get_the_title() ) the_title(); else the_ID(); ?> </a></li>
+			<?php endwhile; ?>
+			</ul>
+		<?php echo $after_widget; ?>
+<?php
+	endif;
+	wp_cache_add('widget_recent_entries', ob_get_flush());
+}
+
+function wp_flush_widget_recent_entries() {
+	wp_cache_delete('widget_recent_entries');
+}
+
+add_action('save_post', 'wp_flush_widget_recent_entries');
+add_action('post_deleted', 'wp_flush_widget_recent_entries');
+
+function wp_widget_recent_entries_control() {
+	$options = $newoptions = get_option('widget_recent_entries');
+	if ( $_POST["recent-entries-submit"] ) {
+		$newoptions['title'] = strip_tags(stripslashes($_POST["recent-entries-title"]));
+		$newoptions['number'] = (int) $_POST["recent-entries-number"];
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_recent_entries', $options);
+		wp_flush_widget_recent_entries();
+	}
+	$title = attribute_escape($options['title']);
+	if ( !$number = (int) $options['number'] )
+		$number = 5;
+?>
+			<p><label for="recent-entries-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-entries-title" name="recent-entries-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<p><label for="recent-entries-number"><?php _e('Number of posts to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-entries-number" name="recent-entries-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p>
+			<input type="hidden" id="recent-entries-submit" name="recent-entries-submit" value="1" />
+<?php
+}
+
+function wp_widget_recent_comments($args) {
+	global $wpdb, $comments, $comment;
+	extract($args, EXTR_SKIP);
+	$options = get_option('widget_recent_comments');
+	$title = empty($options['title']) ? __('Recent Comments') : $options['title'];
+	if ( !$number = (int) $options['number'] )
+		$number = 5;
+	else if ( $number < 1 )
+		$number = 1;
+	else if ( $number > 15 )
+		$number = 15;
+
+	if ( !$comments = wp_cache_get( 'recent_comments', 'widget' ) ) {
+		$comments = $wpdb->get_results("SELECT comment_author, comment_author_url, comment_ID, comment_post_ID FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT $number");
+		wp_cache_add( 'recent_comments', $comments, 'widget' );
+	}
+?>
+
+		<?php echo $before_widget; ?>
+			<?php echo $before_title . $title . $after_title; ?>
+			<ul id="recentcomments"><?php
+			if ( $comments ) : foreach ($comments as $comment) :
+			echo  '<li class="recentcomments">' . sprintf(__('%1$s on %2$s'), get_comment_author_link(), '<a href="'. get_permalink($comment->comment_post_ID) . '#comment-' . $comment->comment_ID . '">' . get_the_title($comment->comment_post_ID) . '</a>') . '</li>';
+			endforeach; endif;?></ul>
+		<?php echo $after_widget; ?>
+<?php
+}
+
+function wp_delete_recent_comments_cache() {
+	wp_cache_delete( 'recent_comments', 'widget' );
+}
+add_action( 'comment_post', 'wp_delete_recent_comments_cache' );
+add_action( 'wp_set_comment_status', 'wp_delete_recent_comments_cache' );
+
+function wp_widget_recent_comments_control() {
+	$options = $newoptions = get_option('widget_recent_comments');
+	if ( $_POST["recent-comments-submit"] ) {
+		$newoptions['title'] = strip_tags(stripslashes($_POST["recent-comments-title"]));
+		$newoptions['number'] = (int) $_POST["recent-comments-number"];
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_recent_comments', $options);
+		wp_delete_recent_comments_cache();
+	}
+	$title = attribute_escape($options['title']);
+	if ( !$number = (int) $options['number'] )
+		$number = 5;
+?>
+			<p><label for="recent-comments-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-comments-title" name="recent-comments-title" type="text" value="<?php echo $title; ?>" /></label></p>
+			<p><label for="recent-comments-number"><?php _e('Number of comments to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-comments-number" name="recent-comments-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p>
+			<input type="hidden" id="recent-comments-submit" name="recent-comments-submit" value="1" />
+<?php
+}
+
+function wp_widget_recent_comments_style() {
+?>
+<style type="text/css">.recentcomments a{display:inline !important;padding: 0 !important;margin: 0 !important;}</style>
+<?php
+}
+
+function wp_widget_recent_comments_register() {
+	$dims = array('width' => 320, 'height' => 90);
+	$class = array('classname' => 'widget_recent_comments');
+	wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $class);
+	wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control', $dims);
+	
+	if ( is_active_widget('wp_widget_recent_comments') )
+		add_action('wp_head', 'wp_widget_recent_comments_style');
+}
+
+function wp_widget_rss($args, $number = 1) {
+	require_once(ABSPATH . WPINC . '/rss.php');
+	extract($args, EXTR_SKIP);
+	$options = get_option('widget_rss');
+	if ( isset($options['error']) && $options['error'] )
+		return;
+	$num_items = (int) $options[$number]['items'];
+	$show_summary = $options[$number]['show_summary'];
+	if ( empty($num_items) || $num_items < 1 || $num_items > 10 ) $num_items = 10;
+	$url = $options[$number]['url'];
+	while ( strstr($url, 'http') != $url )
+		$url = substr($url, 1);
+	if ( empty($url) )
+		return;
+	$rss = fetch_rss($url);
+	$link = clean_url(strip_tags($rss->channel['link']));
+	while ( strstr($link, 'http') != $link )
+		$link = substr($link, 1);
+	$desc = attribute_escape(strip_tags(html_entity_decode($rss->channel['description'], ENT_QUOTES)));
+	$title = $options[$number]['title'];
+	if ( empty($title) )
+		$title = htmlentities(strip_tags($rss->channel['title']));
+	if ( empty($title) )
+		$title = $desc;
+	if ( empty($title) )
+		$title = __('Unknown Feed');
+	$url = clean_url(strip_tags($url));
+	if ( file_exists(dirname(__FILE__) . '/rss.png') )
+		$icon = str_replace(ABSPATH, get_option('siteurl').'/', dirname(__FILE__)) . '/rss.png';
+	else
+		$icon = get_option('siteurl').'/wp-includes/images/rss.png';
+	$title = "<a class='rsswidget' href='$url' title='" . attribute_escape(__('Syndicate this content')) ."'><img style='background:orange;color:white;border:none;' width='14' height='14' src='$icon' alt='RSS' /></a> <a class='rsswidget' href='$link' title='$desc'>$title</a>";
+?>
+		<?php echo $before_widget; ?>
+			<?php $title ? print($before_title . $title . $after_title) : null; ?>
+			<ul>
+<?php
+	if ( is_array( $rss->items ) ) {
+		$rss->items = array_slice($rss->items, 0, $num_items);
+		foreach ($rss->items as $item ) {
+			while ( strstr($item['link'], 'http') != $item['link'] )
+				$item['link'] = substr($item['link'], 1);
+			$link = clean_url(strip_tags($item['link']));
+			$title = attribute_escape(strip_tags($item['title']));
+			if ( empty($title) )
+				$title = __('Untitled');
+			$desc = '';
+			if ( $show_summary ) {
+				$summary = '<div class="rssSummary">' . $item['description'] . '</div>';
+			} else {
+				if ( isset( $item['description'] ) && is_string( $item['description'] ) )
+					$desc = str_replace(array("\n", "\r"), ' ', attribute_escape(strip_tags(html_entity_decode($item['description'], ENT_QUOTES))));
+				$summary = '';
+			}
+			echo "<li><a class='rsswidget' href='$link' title='$desc'>$title</a>$summary</li>";
+		}
+	} else {
+		echo '<li>' . __( 'An error has occurred; the feed is probably down. Try again later.' ) . '</li>';
+	}
+?>
+			</ul>
+		<?php echo $after_widget; ?>
+<?php
+}
+
+function wp_widget_rss_control($number) {
+	$options = $newoptions = get_option('widget_rss');
+	if ( $_POST["rss-submit-$number"] ) {
+		$newoptions[$number]['items'] = (int) $_POST["rss-items-$number"];
+		$url = clean_url(strip_tags(stripslashes($_POST["rss-url-$number"])));
+		$newoptions[$number]['title'] = trim(strip_tags(stripslashes($_POST["rss-title-$number"])));
+		if ( $url !== $options[$number]['url'] ) {
+			require_once(ABSPATH . WPINC . '/rss.php');
+			$rss = fetch_rss($url);
+			if ( is_object($rss) ) {
+				$newoptions[$number]['url'] = $url;
+				$newoptions[$number]['error'] = false;
+			} else {
+				$newoptions[$number]['error'] = true;
+				$newoptions[$number]['url'] = wp_specialchars(__('Error: could not find an RSS or ATOM feed at that URL.'), 1);
+				$error = sprintf(__('Error in RSS %1$d: %2$s'), $number, $newoptions[$number]['error']);
+			}
+		}
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_rss', $options);
+	}
+	$url = attribute_escape($options[$number]['url']);
+	$items = (int) $options[$number]['items'];
+	$title = attribute_escape($options[$number]['title']);
+	if ( empty($items) || $items < 1 ) $items = 10;
+?>
+			<p style="text-align:center;"><?php _e('Enter the RSS feed URL here:'); ?></p>
+			<input style="width: 400px;" id="rss-url-<?php echo "$number"; ?>" name="rss-url-<?php echo "$number"; ?>" type="text" value="<?php echo $url; ?>" />
+			<p style="text-align:center;"><?php _e('Give the feed a title (optional):'); ?></p>
+			<input style="width: 400px;" id="rss-title-<?php echo "$number"; ?>" name="rss-title-<?php echo "$number"; ?>" type="text" value="<?php echo $title; ?>" />
+			<p style="text-align:center; line-height: 30px;"><?php _e('How many items would you like to display?'); ?> <select id="rss-items-<?php echo $number; ?>" name="rss-items-<?php echo $number; ?>"><?php for ( $i = 1; $i <= 10; ++$i ) echo "<option value='$i' ".($items==$i ? "selected='selected'" : '').">$i</option>"; ?></select></p>
+			<input type="hidden" id="rss-submit-<?php echo "$number"; ?>" name="rss-submit-<?php echo "$number"; ?>" value="1" />
+<?php
+}
+
+function wp_widget_rss_setup() {
+	$options = $newoptions = get_option('widget_rss');
+	if ( isset($_POST['rss-number-submit']) ) {
+		$number = (int) $_POST['rss-number'];
+		if ( $number > 9 ) $number = 9;
+		if ( $number < 1 ) $number = 1;
+		$newoptions['number'] = $number;
+	}
+	if ( $options != $newoptions ) {
+		$options = $newoptions;
+		update_option('widget_rss', $options);
+		wp_widget_rss_register($options['number']);
+	}
+}
+
+function wp_widget_rss_page() {
+	$options = $newoptions = get_option('widget_rss');
+?>
+	<div class="wrap">
+		<form method="POST">
+			<h2><?php _e('RSS Feed Widgets'); ?></h2>
+			<p style="line-height: 30px;"><?php _e('How many RSS widgets would you like?'); ?>
+			<select id="rss-number" name="rss-number" value="<?php echo $options['number']; ?>">
+<?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?>
+			</select>
+			<span class="submit"><input type="submit" name="rss-number-submit" id="rss-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p>
+		</form>
+	</div>
+<?php
+}
+
+function wp_widget_rss_register() {
+	$options = get_option('widget_rss');
+	$number = $options['number'];
+	if ( $number < 1 ) $number = 1;
+	if ( $number > 9 ) $number = 9;
+	$dims = array('width' => 410, 'height' => 200);
+	$class = array('classname' => 'widget_rss');
+	for ($i = 1; $i <= 9; $i++) {
+		$name = sprintf(__('RSS %d'), $i);
+		$id = "rss-$i"; // Never never never translate an id
+		wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_rss' : /* unregister */ '', $class, $i);
+		wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_rss_control' : /* unregister */ '', $dims, $i);
+	}
+	add_action('sidebar_admin_setup', 'wp_widget_rss_setup');
+	add_action('sidebar_admin_page', 'wp_widget_rss_page');
+}
+
+function wp_widgets_init() {
+	global $wp_register_widget_defaults;
+
+	$wp_register_widget_defaults = true;
+	$dims90 = array('height' => 90, 'width' => 300);
+	$dims100 = array('height' => 100, 'width' => 300);
+	$dims150 = array('height' => 150, 'width' => 300);
+	$class = array('classname' => 'widget_pages');
+	wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $class);
+	wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control', $dims150);
+	$class['classname'] = 'widget_calendar';
+	wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $class);
+	wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control', $dims90);
+	$class['classname'] = 'widget_archives';
+	wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $class);
+	wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control', $dims100);
+	$class['classname'] = 'widget_links';
+	wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $class);
+	$class['classname'] = 'widget_meta';
+	wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $class);
+	wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control', $dims90);
+	$class['classname'] = 'widget_search';
+	wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $class);
+	$class['classname'] = 'widget_categories';
+	wp_register_sidebar_widget('categories', __('Categories'), 'wp_widget_categories', $class);
+	wp_register_widget_control('categories', __('Categories'), 'wp_widget_categories_control', $dims150);
+	$class['classname'] = 'widget_recent_entries';
+	wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $class);
+	wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control', $dims90);
+	wp_widget_text_register();
+	wp_widget_rss_register();
+	wp_widget_recent_comments_register();
+
+	$wp_register_widget_defaults = false;
+
+	do_action('widgets_init');
+}
+
+add_action('init', 'wp_widgets_init', 1);
+
+?>
diff -ruN 2.0.5/wp-includes/wp-db.php 2.2.2/wp-includes/wp-db.php
--- 2.0.5/wp-includes/wp-db.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/wp-db.php	2007-04-06 12:22:53.000000000 -0500
@@ -16,7 +16,7 @@
 class wpdb {
 
 	var $show_errors = true;
-	var $num_queries = 0;	
+	var $num_queries = 0;
 	var $last_query;
 	var $col_info;
 	var $queries;
@@ -28,7 +28,6 @@
 	var $post2cat;
 	var $comments;
 	var $links;
-	var $linkcategories;
 	var $options;
 	var $optiontypes;
 	var $optionvalues;
@@ -36,10 +35,29 @@
 	var $optiongroup_options;
 	var $postmeta;
 
-	// ==================================================================
-	//	DB Constructor - connects to the server and selects a database
+	var $charset;
+	var $collate;
 
+	/**
+	 * Connects to the database server and selects a database
+	 * @param string $dbuser
+	 * @param string $dbpassword
+	 * @param string $dbname
+	 * @param string $dbhost
+	 */
 	function wpdb($dbuser, $dbpassword, $dbname, $dbhost) {
+		return $this->__construct($dbuser, $dbpassword, $dbname, $dbhost);
+	}
+
+	function __construct($dbuser, $dbpassword, $dbname, $dbhost) {
+		register_shutdown_function(array(&$this, "__destruct"));
+
+		if ( defined('DB_CHARSET') )
+			$this->charset = DB_CHARSET;
+
+		if ( defined('DB_COLLATE') )
+			$this->collate = DB_COLLATE;
+
 		$this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword);
 		if (!$this->dbh) {
 			$this->bail("
@@ -54,12 +72,20 @@
 ");
 		}
 
+		if ( !empty($this->charset) && version_compare(mysql_get_server_info(), '4.1.0', '>=') )
+ 			$this->query("SET NAMES '$this->charset'");
+
 		$this->select($dbname);
 	}
 
-	// ==================================================================
-	//	Select a DB (if another one needs to be selected)
+	function __destruct() {
+		return true;	
+	}
 
+	/**
+	 * Selects a database using the current class's $this->dbh
+	 * @param string $db name
+	 */
 	function select($db) {
 		if (!@mysql_select_db($db, $this->dbh)) {
 			$this->bail("
@@ -73,9 +99,12 @@
 		}
 	}
 
-	// ====================================================================
-	//	Format a string correctly for safe insert under all PHP conditions
-	
+	/**
+	 * Escapes content for insertion into the database, for security
+	 *
+	 * @param string $string
+	 * @return string query safe string
+	 */
 	function escape($string) {
 		return addslashes( $string ); // Disable rest for now, causing problems
 		if( !$this->dbh || version_compare( phpversion(), '4.3.0' ) == '-1' )
@@ -89,8 +118,8 @@
 
 	function print_error($str = '') {
 		global $EZSQL_ERROR;
-		if (!$str) $str = mysql_error();
-		$EZSQL_ERROR[] = 
+		if (!$str) $str = mysql_error($this->dbh);
+		$EZSQL_ERROR[] =
 		array ('query' => $this->last_query, 'error_str' => $str);
 
 		$str = htmlspecialchars($str, ENT_QUOTES);
@@ -103,7 +132,7 @@
 			<code>$query</code></p>
 			</div>";
 		} else {
-			return false;	
+			return false;
 		}
 	}
 
@@ -113,7 +142,7 @@
 	function show_errors() {
 		$this->show_errors = true;
 	}
-	
+
 	function hide_errors() {
 		$this->show_errors = false;
 	}
@@ -131,6 +160,11 @@
 	//	Basic Query	- see docs for more detail
 
 	function query($query) {
+		// filter the query, if filters are available
+		// NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
+		if ( function_exists('apply_filters') )
+			$query = apply_filters('query', $query);
+
 		// initialise return
 		$return_val = 0;
 		$this->flush();
@@ -144,7 +178,7 @@
 		// Perform the query via std mysql_query function..
 		if (SAVEQUERIES)
 			$this->timer_start();
-		
+
 		$this->result = @mysql_query($query, $this->dbh);
 		++$this->num_queries;
 
@@ -152,16 +186,16 @@
 			$this->queries[] = array( $query, $this->timer_stop() );
 
 		// If there is an error then take note of it..
-		if ( mysql_error() ) {
+		if ( mysql_error($this->dbh) ) {
 			$this->print_error();
 			return false;
 		}
 
 		if ( preg_match("/^\\s*(insert|delete|update|replace) /i",$query) ) {
-			$this->rows_affected = mysql_affected_rows();
+			$this->rows_affected = mysql_affected_rows($this->dbh);
 			// Take note of the insert_id
 			if ( preg_match("/^\\s*(insert|replace) /i",$query) ) {
-				$this->insert_id = mysql_insert_id($this->dbh);	
+				$this->insert_id = mysql_insert_id($this->dbh);
 			}
 			// Return number of rows affected
 			$return_val = $this->rows_affected;
@@ -181,7 +215,7 @@
 
 			// Log number of rows the query returned
 			$this->num_rows = $num_rows;
-			
+
 			// Return number of rows selected
 			$return_val = $this->num_rows;
 		}
@@ -189,9 +223,13 @@
 		return $return_val;
 	}
 
-	// ==================================================================
-	//	Get one variable from the DB - see docs for more detail
-
+	/**
+	 * Get one variable from the database
+	 * @param string $query (can be null as well, for caching, see codex)
+	 * @param int $x = 0 row num to return
+	 * @param int $y = 0 col num to return
+	 * @return mixed results
+	 */
 	function get_var($query=null, $x = 0, $y = 0) {
 		$this->func_call = "\$db->get_var(\"$query\",$x,$y)";
 		if ( $query )
@@ -206,13 +244,20 @@
 		return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
 	}
 
-	// ==================================================================
-	//	Get one row from the DB - see docs for more detail
-
+	/**
+	 * Get one row from the database
+	 * @param string $query
+	 * @param string $output ARRAY_A | ARRAY_N | OBJECT
+	 * @param int $y row num to return
+	 * @return mixed results
+	 */
 	function get_row($query = null, $output = OBJECT, $y = 0) {
 		$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
 		if ( $query )
 			$this->query($query);
+	
+		if ( !isset($this->last_result[$y]) )
+			return null;
 
 		if ( $output == OBJECT ) {
 			return $this->last_result[$y] ? $this->last_result[$y] : null;
@@ -225,10 +270,12 @@
 		}
 	}
 
-	// ==================================================================
-	//	Function to get 1 column from the cached result set based in X index
-	// se docs for usage and info
-
+	/**
+	 * Gets one column from the database
+	 * @param string $query (can be null as well, for caching, see codex)
+	 * @param int $x col num to return
+	 * @return array results
+	 */
 	function get_col($query = null , $x = 0) {
 		if ( $query )
 			$this->query($query);
@@ -240,9 +287,12 @@
 		return $new_array;
 	}
 
-	// ==================================================================
-	// Return the the query as a result set - see docs for more details
-
+	/**
+	 * Return an entire result set from the database
+	 * @param string $query (can also be null to pull from the cache)
+	 * @param string $output ARRAY_A | ARRAY_N | OBJECT
+	 * @return mixed results
+	 */
 	function get_results($query = null, $output = OBJECT) {
 		$this->func_call = "\$db->get_results(\"$query\", $output)";
 
@@ -269,11 +319,12 @@
 		}
 	}
 
-
-	// ==================================================================
-	// Function to get column meta data info pertaining to the last query
-	// see docs for more info and usage
-
+	/**
+	 * Grabs column metadata from the last query
+	 * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
+	 * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
+	 * @return mixed results
+	 */
 	function get_col_info($info_type = 'name', $col_offset = -1) {
 		if ( $this->col_info ) {
 			if ( $col_offset == -1 ) {
@@ -289,14 +340,21 @@
 		}
 	}
 
+	/**
+	 * Starts the timer, for debugging purposes
+	 */
 	function timer_start() {
 		$mtime = microtime();
 		$mtime = explode(' ', $mtime);
 		$this->time_start = $mtime[1] + $mtime[0];
 		return true;
 	}
-	
-	function timer_stop($precision = 3) {
+
+	/**
+	 * Stops the debugging timer
+	 * @return int total time spent on the query, in milliseconds
+	 */
+	function timer_stop() {
 		$mtime = microtime();
 		$mtime = explode(' ', $mtime);
 		$time_end = $mtime[1] + $mtime[0];
@@ -304,62 +362,39 @@
 		return $time_total;
 	}
 
+	/**
+	 * Wraps fatal errors in a nice header and footer and dies.
+	 * @param string $message
+	 */
 	function bail($message) { // Just wraps errors in a nice header and footer
-	if ( !$this->show_errors )
-		return false;
-	header( 'Content-Type: text/html; charset=utf-8');		
-	echo <<<HEAD
-	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-	<html xmlns="http://www.w3.org/1999/xhtml">
-	<head>
-		<title>WordPress &rsaquo; Error</title>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<style media="screen" type="text/css">
-		<!--
-		html {
-			background: #eee;
-		}
-		body {
-			background: #fff;
-			color: #000;
-			font-family: Georgia, "Times New Roman", Times, serif;
-			margin-left: 25%;
-			margin-right: 25%;
-			padding: .2em 2em;
-		}
-		
-		h1 {
-			color: #006;
-			font-size: 18px;
-			font-weight: lighter;
-		}
-		
-		h2 {
-			font-size: 16px;
-		}
-		
-		p, li, dt {
-			line-height: 140%;
-			padding-bottom: 2px;
-		}
-	
-		ul, ol {
-			padding: 5px 5px 5px 20px;
-		}
-		#logo {
-			margin-bottom: 2em;
-		}
-		-->
-		</style>
-	</head>
-	<body>
-	<h1 id="logo"><img alt="WordPress" src="http://static.wordpress.org/logo.png" /></h1>
-HEAD;
-	echo $message;
-	echo "</body></html>";
-	die();
+		if ( !$this->show_errors )
+			return false;
+
+		header('Content-Type: text/html; charset=utf-8');
+
+		if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false)
+			$admin_dir = '';
+		else
+			$admin_dir = 'wp-admin/';
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>WordPress &rsaquo; Error</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<link rel="stylesheet" href="<?php echo $admin_dir; ?>install.css" type="text/css" />
+</head>
+<body>
+	<h1 id="logo"><img alt="WordPress" src="<?php echo $admin_dir; ?>images/wordpress-logo.png" /></h1>
+	<p><?php echo $message; ?></p>
+</body>
+</html>
+<?php
+		die();
 	}
 }
 
-$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
+if ( ! isset($wpdb) )
+	$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
 ?>
\ No newline at end of file
diff -ruN 2.0.5/wp-includes/wp-l10n.php 2.2.2/wp-includes/wp-l10n.php
--- 2.0.5/wp-includes/wp-l10n.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-includes/wp-l10n.php	1969-12-31 18:00:00.000000000 -0600
@@ -1,97 +0,0 @@
-<?php
-
-if ( defined('WPLANG') && '' != constant('WPLANG') ) {
-	include_once(ABSPATH . 'wp-includes/streams.php');
-	include_once(ABSPATH . 'wp-includes/gettext.php');
-}
-
-function get_locale() {
-	global $locale;
-
-	if (isset($locale))
-		return $locale;
-
-	// WPLANG is defined in wp-config.
-	if (defined('WPLANG'))
-		$locale = WPLANG;
-	
-	if (empty($locale))
-		$locale = 'en_US';
-
-	$locale = apply_filters('locale', $locale);
-
-	return $locale;
-}
-
-// Return a translated string.    
-function __($text, $domain = 'default') {
-	global $l10n;
-
-	if (isset($l10n[$domain]))
-		return apply_filters('gettext', $l10n[$domain]->translate($text), $text);
-	else
-		return $text;
-}
-
-// Echo a translated string.
-function _e($text, $domain = 'default') {
-	global $l10n;
-
-	if (isset($l10n[$domain]))
-		echo apply_filters('gettext', $l10n[$domain]->translate($text), $text);
-	else
-		echo $text;
-}
-
-// Return the plural form.
-function __ngettext($single, $plural, $number, $domain = 'default') {
-	global $l10n;
-
-	if (isset($l10n[$domain])) {
-		return $l10n[$domain]->ngettext($single, $plural, $number);
-	} else {
-		if ($number != 1)
-			return $plural;
-		else
-			return $single;
-	}
-}
-
-function load_textdomain($domain, $mofile) {
-	global $l10n;
-
-	if (isset($l10n[$domain]))
-		return;
-
-	if ( is_readable($mofile))
-		$input = new CachedFileReader($mofile);
-	else
-		return;
-
-	$l10n[$domain] = new gettext_reader($input);
-}
-
-function load_default_textdomain() {
-	global $l10n;
-
-	$locale = get_locale();
-	$mofile = ABSPATH . "wp-includes/languages/$locale.mo";
-	
-	load_textdomain('default', $mofile);
-}
-
-function load_plugin_textdomain($domain, $path = 'wp-content/plugins') {
-	$locale = get_locale();
-	
-	$mofile = ABSPATH . "$path/$domain-$locale.mo";
-	load_textdomain($domain, $mofile);
-}
-
-function load_theme_textdomain($domain) {
-	$locale = get_locale();
-	
-	$mofile = get_template_directory() . "/$locale.mo";
-	load_textdomain($domain, $mofile);
-}
-
-?>
\ No newline at end of file
diff -ruN 2.0.5/wp-links-opml.php 2.2.2/wp-links-opml.php
--- 2.0.5/wp-links-opml.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-links-opml.php	2007-03-31 15:15:10.000000000 -0500
@@ -1,61 +1,53 @@
-<?php 
-$doing_rss = 1;
+<?php
+
+if (empty($wp)) {
+	require_once('./wp-config.php');
+	wp();
+}
 
-require('wp-blog-header.php');
-header('Content-type: text/xml; charset=' . get_settings('blog_charset'), true);
+header('Content-type: text/xml; charset=' . get_option('blog_charset'), true);
 $link_cat = $_GET['link_cat'];
-if ((empty($link_cat)) || ($link_cat == 'all') || ($link_cat == '0')) {
-    $sql_cat = '';
+if ((empty ($link_cat)) || ($link_cat == 'all') || ($link_cat == '0')) {
+	$link_cat = '';
 } else { // be safe
-    $link_cat = ''.urldecode($link_cat).'';
-    $link_cat = addslashes_gpc($link_cat);
-    $link_cat = intval($link_cat);
-    if ($link_cat != 0) {
-        $sql_cat = "AND $wpdb->links.link_category = $link_cat";
-        $cat_name = $wpdb->get_var("SELECT $wpdb->linkcategories.cat_name FROM $wpdb->linkcategories WHERE $wpdb->linkcategories.cat_id = $link_cat");
-        if (!empty($cat_name)) {
-            $cat_name = ": category $cat_name";
-        }
-    }
+	$link_cat = '' . urldecode($link_cat) . '';
+	$link_cat = intval($link_cat);
 }
 ?><?php echo '<?xml version="1.0"?'.">\n"; ?>
-<!-- generator="wordpress/<?php echo $wp_version ?>" -->
+<!-- generator="wordpress/<?php bloginfo_rss('version') ?>" -->
 <opml version="1.0">
-    <head>
-        <title>Links for <?php echo get_bloginfo('name').$cat_name ?></title>
-        <dateCreated><?php echo gmdate("D, d M Y H:i:s"); ?> GMT</dateCreated>
-    </head>
-    <body>
-<?php $sql = "SELECT $wpdb->links.link_url, link_rss, $wpdb->links.link_name, $wpdb->links.link_category, $wpdb->linkcategories.cat_name, link_updated 
-FROM $wpdb->links 
- JOIN $wpdb->linkcategories on $wpdb->links.link_category = $wpdb->linkcategories.cat_id
- AND $wpdb->links.link_visible = 'Y'
- $sql_cat
- ORDER BY $wpdb->linkcategories.cat_name, $wpdb->links.link_name \n";
- //echo("<!-- $sql -->");
- $prev_cat_id = 0;
- $results = $wpdb->get_results($sql);
- if ($results) {
-     foreach ($results as $result) {
-         if ($result->link_category != $prev_cat_id) { // new category
-             if ($prev_cat_id != 0)  { // not first time
-?>
-        </outline>
+	<head>
+		<title>Links for <?php echo attribute_escape(get_bloginfo('name').$cat_name); ?></title>
+		<dateCreated><?php echo gmdate("D, d M Y H:i:s"); ?> GMT</dateCreated>
+	</head>
+	<body>
 <?php
-             } // end if not first time
+
+if (empty ($link_cat))
+	$cats = get_categories("type=link&hierarchical=0");
+else
+	$cats = array (get_category($link_cat));
+
+foreach ((array) $cats as $cat) {
+	$catname = apply_filters('link_category', $cat->cat_name);
+
 ?>
-        <outline type="category" title="<?php echo wp_specialchars($result->cat_name); ?>">
+<outline type="category" title="<?php echo attribute_escape($catname); ?>">
 <?php
-             $prev_cat_id = $result->link_category;
-        } // end if new category
+
+	$bookmarks = get_bookmarks("category={$cat->cat_ID}");
+	foreach ((array) $bookmarks as $bookmark) {
+		$title = attribute_escape(apply_filters('link_title', $bookmark->link_name));
 ?>
-            <outline text="<?php echo wp_specialchars($result->link_name); ?>" type="link" xmlUrl="<?php echo wp_specialchars($result->link_rss); ?>" htmlUrl="<?php echo wp_specialchars($result->link_url); ?>" updated="<?php if ('0000-00-00 00:00:00' != $result->link_updated) echo $result->link_updated; ?>" />
+	<outline text="<?php echo $title; ?>" type="link" xmlUrl="<?php echo attribute_escape($bookmark->link_rss); ?>" htmlUrl="<?php echo attribute_escape($bookmark->link_url); ?>" updated="<?php if ('0000-00-00 00:00:00' != $bookmark->link_updated) echo $bookmark->link_updated; ?>" />
 <?php
-        } // end foreach
+
+	}
 ?>
-	</outline>
+</outline>
 <?php
-    } // end if
+
+}
 ?>
 </body>
 </opml>
\ No newline at end of file
diff -ruN 2.0.5/wp-login.php 2.2.2/wp-login.php
--- 2.0.5/wp-login.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-login.php	2007-04-18 21:53:19.000000000 -0500
@@ -2,7 +2,10 @@
 require( dirname(__FILE__) . '/wp-config.php' );
 
 $action = $_REQUEST['action'];
-$error = '';
+$errors = array();
+
+if ( isset($_GET['key']) )
+	$action = 'resetpass';
 
 nocache_headers();
 
@@ -13,165 +16,285 @@
 		$_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] );
 
 	$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
-	if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_settings('siteurl') )
+	if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_option('siteurl') )
 		update_option('siteurl', dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) );
 }
 
-switch($action) {
 
-case 'logout':
+// Rather than duplicating this HTML all over the place, we'll stick it in function
+function login_header($title = 'Login', $message = '') {
+	global $errors, $error, $wp_locale;
+
+	?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
+<head>
+	<title><?php bloginfo('name'); ?> &rsaquo; <?php echo $title; ?></title>
+	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
+	<link rel="stylesheet" href="<?php bloginfo('wpurl'); ?>/wp-admin/wp-admin.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php if ( ('rtl' == $wp_locale->text_direction) ) : ?>
+	<link rel="stylesheet" href="<?php bloginfo('wpurl'); ?>/wp-admin/rtl.css?version=<?php bloginfo('version'); ?>" type="text/css" />
+<?php endif; ?>
+	<!--[if IE]><style type="text/css">#login h1 a { margin-top: 35px; } #login #login_error { margin-bottom: 10px; }</style><![endif]--><!-- Curse you, IE! -->
+	<script type="text/javascript">
+		function focusit() {
+			document.getElementById('user_login').focus();
+		}
+		window.onload = focusit;
+	</script>
+<?php do_action('login_head'); ?>
+</head>
+<body class="login">
+
+<div id="login"><h1><a href="<?php echo apply_filters('login_headerurl', 'http://wordpress.org/'); ?>" title="<?php echo apply_filters('login_headertitle', __('Powered by WordPress')); ?>"><?php bloginfo('name'); ?></a></h1>
+<?php
+	if ( !empty( $message ) ) echo apply_filters('login_message', $message) . "\n";
+
+	// Incase a plugin uses $error rather than the $errors array
+	if ( !empty( $error ) ) {
+		$errors['error'] = $error;
+		unset($error);
+	}
+
+	if ( !empty( $errors ) ) {
+		if ( is_array( $errors ) ) {
+			$newerrors = "\n";
+			foreach ( $errors as $error ) $newerrors .= '	' . $error . "<br />\n";
+			$errors = $newerrors;
+		}
+
+		echo '<div id="login_error">' . apply_filters('login_errors', $errors) . "</div>\n";
+	}
+} // End of login_header()
+
+
+switch ($action) {
+
+case 'logout' :
 
 	wp_clearcookie();
 	do_action('wp_logout');
-	nocache_headers();
 
-	$redirect_to = 'wp-login.php';
-	if ( isset($_REQUEST['redirect_to']) )
+	$redirect_to = 'wp-login.php?loggedout=true';
+	if ( isset( $_REQUEST['redirect_to'] ) )
 		$redirect_to = $_REQUEST['redirect_to'];
-			
+
 	wp_redirect($redirect_to);
 	exit();
 
 break;
 
-case 'lostpassword':
-do_action('lost_password');
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<title>WordPress &raquo; <?php _e('Lost Password') ?></title>
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
-	<link rel="stylesheet" href="<?php echo get_settings('siteurl'); ?>/wp-admin/wp-admin.css" type="text/css" />
-	<script type="text/javascript">
-	function focusit() {
-		// focus on first input field
-		document.getElementById('user_login').focus();
-	}
-	window.onload = focusit;
-	</script>
-	<style type="text/css">
-	#user_login, #email, #submit {
-		font-size: 1.7em;
+case 'lostpassword' :
+case 'retrievepassword' :
+	$user_login = '';
+	$user_pass = '';
+
+	if ( $_POST ) {
+		if ( empty( $_POST['user_login'] ) )
+			$errors['user_login'] = __('<strong>ERROR</strong>: The username field is empty.');
+		if ( empty( $_POST['user_email'] ) )
+			$errors['user_email'] = __('<strong>ERROR</strong>: The e-mail field is empty.');
+
+		do_action('lostpassword_post');
+
+		if ( empty( $errors ) ) {
+			$user_data = get_userdatabylogin(trim($_POST['user_login']));
+			// redefining user_login ensures we return the right case in the email
+			$user_login = $user_data->user_login;
+			$user_email = $user_data->user_email;
+
+			if (!$user_email || $user_email != $_POST['user_email']) {
+				$errors['invalidcombo'] = __('<strong>ERROR</strong>: Invalid username / e-mail combination.');
+			} else {
+				do_action('retreive_password', $user_login);  // Misspelled and deprecated
+				do_action('retrieve_password', $user_login);
+
+				// Generate something random for a password... md5'ing current time with a rand salt
+				$key = substr( md5( uniqid( microtime() ) ), 0, 8);
+				// Now insert the new pass md5'd into the db
+				$wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
+				$message = __('Someone has asked to reset the password for the following site and username.') . "\r\n\r\n";
+				$message .= get_option('siteurl') . "\r\n\r\n";
+				$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
+				$message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\r\n\r\n";
+				$message .= get_option('siteurl') . "/wp-login.php?action=rp&key=$key\r\n";
+
+				if (FALSE == wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_option('blogname')), $message)) {
+					die('<p>' . __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') . '</p>');
+				} else {
+					wp_redirect('wp-login.php?checkemail=confirm');
+					exit();
+				}
+			}
+		}
 	}
-	</style>
-</head>
-<body>
-<div id="login">
-<h1><a href="http://wordpress.org/">WordPress</a></h1>
-<p><?php _e('Please enter your information here. We will send you a new password.') ?></p>
-<?php
-if ($error)
-	echo "<div id='login_error'>$error</div>";
+
+	if ( 'invalidkey' == $_GET['error'] ) $errors['invalidkey'] = __('Sorry, that key does not appear to be valid.');
+
+	do_action('lost_password');
+	login_header(__('Lost Password'), '<p class="message">' . __('Please enter your username and e-mail address. You will receive a new password via e-mail.') . '</p>');
 ?>
 
-<form name="lostpass" action="wp-login.php" method="post" id="lostpass">
-<p>
-<input type="hidden" name="action" value="retrievepassword" />
-<label><?php _e('Username:') ?><br />
-<input type="text" name="user_login" id="user_login" value="" size="20" tabindex="1" /></label></p>
-<p><label><?php _e('E-mail:') ?><br />
-<input type="text" name="email" id="email" value="" size="25" tabindex="2" /></label><br />
-</p>
-<p class="submit"><input type="submit" name="submit" id="submit" value="<?php _e('Retrieve Password'); ?> &raquo;" tabindex="3" /></p>
+<form name="lostpasswordform" id="lostpasswordform" action="wp-login.php?action=lostpassword" method="post">
+	<p>
+		<label><?php _e('Username:') ?><br />
+		<input type="text" name="user_login" id="user_login" class="input" value="<?php echo attribute_escape(stripslashes($_POST['user_login'])); ?>" size="20" tabindex="10" /></label>
+	</p>
+	<p>
+		<label><?php _e('E-mail:') ?><br />
+		<input type="text" name="user_email" id="user_email" class="input" value="<?php echo attribute_escape(stripslashes($_POST['user_email'])); ?>" size="25" tabindex="20" /></label>
+	</p>
+<?php do_action('lostpassword_form'); ?>
+	<p class="submit"><input type="submit" name="wp-submit" id="wp-submit" value="<?php _e('Get New Password &raquo;'); ?>" tabindex="100" /></p>
 </form>
+</div>
+
 <ul>
-	<li><a href="<?php bloginfo('home'); ?>/" title="<?php _e('Are you lost?') ?>">&laquo; <?php _e('Back to blog') ?></a></li>
-<?php if (get_settings('users_can_register')) : ?>
-	<li><a href="<?php bloginfo('wpurl'); ?>/wp-register.php"><?php _e('Register') ?></a></li>
-<?php endif; ?>
+<?php if (get_option('users_can_register')) : ?>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php"><?php _e('Login') ?></a></li>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=register"><?php _e('Register') ?></a></li>
+	<li><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('Back to %s'), get_bloginfo('title')); ?></a></li>
+<?php else : ?>
+	<li><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('Back to %s'), get_bloginfo('title')); ?></a></li>
 	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php"><?php _e('Login') ?></a></li>
+<?php endif; ?>
 </ul>
-</div>
+
 </body>
 </html>
 <?php
 break;
 
-case 'retrievepassword':
-	$user_data = get_userdatabylogin($_POST['user_login']);
-	// redefining user_login ensures we return the right case in the email
-	$user_login = $user_data->user_login;
-	$user_email = $user_data->user_email;
-
-	if (!$user_email || $user_email != $_POST['email'])
-		die(sprintf(__('Sorry, that user does not seem to exist in our database. Perhaps you have the wrong username or e-mail address? <a href="%s">Try again</a>.'), 'wp-login.php?action=lostpassword'));
-
-do_action('retreive_password', $user_login);  // Misspelled and deprecated.
-do_action('retrieve_password', $user_login);
-
-	// Generate something random for a password... md5'ing current time with a rand salt
-	$key = substr( md5( uniqid( microtime() ) ), 0, 50);
-	// now insert the new pass md5'd into the db
- 	$wpdb->query("UPDATE $wpdb->users SET user_activation_key = '$key' WHERE user_login = '$user_login'");
-	$message = __('Someone has asked to reset the password for the following site and username.') . "\r\n\r\n";
-	$message .= get_option('siteurl') . "\r\n\r\n";
-	$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
-	$message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\r\n\r\n";
-	$message .= get_settings('siteurl') . "/wp-login.php?action=resetpass&key=$key\r\n";
-
-	$m = wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_settings('blogname')), $message);
-
-	if ($m == false) {
-		 echo '<p>' . __('The e-mail could not be sent.') . "<br />\n";
-         echo  __('Possible reason: your host may have disabled the mail() function...') . "</p>";
-		die();
-	} else {
-		echo '<p>' .  sprintf(__("The e-mail was sent successfully to %s's e-mail address."), $user_login) . '<br />';
-		echo  "<a href='wp-login.php' title='" . __('Check your e-mail first, of course') . "'>" . __('Click here to login!') . '</a></p>';
-		die();
-	}
-
-break;
-
 case 'resetpass' :
+case 'rp' :
+	$key = preg_replace('/[^a-z0-9]/i', '', $_GET['key']);
+	if ( empty( $key ) ) {
+		wp_redirect('wp-login.php?action=lostpassword&error=invalidkey');
+		exit();
+	}
 
-	// Generate something random for a password... md5'ing current time with a rand salt
-	$key = preg_replace('/a-z0-9/i', '', $_GET['key']);
-	if ( empty($key) )
-		die( __('Sorry, that key does not appear to be valid.') );
 	$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_activation_key = '$key'");
-	if ( !$user )
-		die( __('Sorry, that key does not appear to be valid.') );
+	if ( empty( $user ) ) {
+		wp_redirect('wp-login.php?action=lostpassword&error=invalidkey');
+		exit();
+	}
 
 	do_action('password_reset');
 
+	// Generate something random for a password... md5'ing current time with a rand salt
 	$new_pass = substr( md5( uniqid( microtime() ) ), 0, 7);
- 	$wpdb->query("UPDATE $wpdb->users SET user_pass = MD5('$new_pass'), user_activation_key = '' WHERE user_login = '$user->user_login'");
+	$wpdb->query("UPDATE $wpdb->users SET user_pass = MD5('$new_pass'), user_activation_key = '' WHERE user_login = '$user->user_login'");
 	wp_cache_delete($user->ID, 'users');
-	wp_cache_delete($user->user_login, 'userlogins');	
+	wp_cache_delete($user->user_login, 'userlogins');
 	$message  = sprintf(__('Username: %s'), $user->user_login) . "\r\n";
 	$message .= sprintf(__('Password: %s'), $new_pass) . "\r\n";
-	$message .= get_settings('siteurl') . "/wp-login.php\r\n";
-
-	$m = wp_mail($user->user_email, sprintf(__('[%s] Your new password'), get_settings('blogname')), $message);
+	$message .= get_option('siteurl') . "/wp-login.php\r\n";
 
-	if ($m == false) {
-		echo '<p>' . __('The e-mail could not be sent.') . "<br />\n";
-		echo  __('Possible reason: your host may have disabled the mail() function...') . '</p>';
-		die();
+	if (FALSE == wp_mail($user->user_email, sprintf(__('[%s] Your new password'), get_option('blogname')), $message)) {
+		die('<p>' . __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function...') . '</p>');
 	} else {
-		echo '<p>' .  sprintf(__('Your new password is in the mail.'), $user_login) . '<br />';
-        echo  "<a href='wp-login.php' title='" . __('Check your e-mail first, of course') . "'>" . __('Click here to login!') . '</a></p>';
 		// send a copy of password change notification to the admin
-		$message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n";
-		wp_mail(get_settings('admin_email'), sprintf(__('[%s] Password Lost/Change'), get_settings('blogname')), $message);
-		die();
+		// but check to see if it's the admin whose password we're changing, and skip this
+		if ($user->user_email != get_option('admin_email')) {
+			$message = sprintf(__('Password Lost and Changed for user: %s'), $user->user_login) . "\r\n";
+			wp_mail(get_option('admin_email'), sprintf(__('[%s] Password Lost/Changed'), get_option('blogname')), $message);
+		}
+
+		wp_redirect('wp-login.php?checkemail=newpass');
+		exit();
 	}
 break;
 
-case 'login' : 
-default:
+case 'register' :
+	if ( FALSE == get_option('users_can_register') ) {
+		wp_redirect('wp-login.php?registration=disabled');
+		exit();
+	}
+
+	if ( $_POST ) {
+		require_once( ABSPATH . WPINC . '/registration.php');
+
+		$user_login = sanitize_user( $_POST['user_login'] );
+		$user_email = apply_filters( 'user_registration_email', $_POST['user_email'] ); 
+
+		// Check the username
+		if ( $user_login == '' )
+			$errors['user_login'] = __('<strong>ERROR</strong>: Please enter a username.');
+		elseif ( !validate_username( $user_login ) ) {
+			$errors['user_login'] = __('<strong>ERROR</strong>: This username is invalid.  Please enter a valid username.');
+			$user_login = '';
+		} elseif ( username_exists( $user_login ) )
+			$errors['user_login'] = __('<strong>ERROR</strong>: This username is already registered, please choose another one.');
+
+		// Check the e-mail address
+		if ($user_email == '') {
+			$errors['user_email'] = __('<strong>ERROR</strong>: Please type your e-mail address.');
+		} elseif ( !is_email( $user_email ) ) {
+			$errors['user_email'] = __('<strong>ERROR</strong>: The email address isn&#8217;t correct.');
+			$user_email = '';
+		} elseif ( email_exists( $user_email ) )
+			$errors['user_email'] = __('<strong>ERROR</strong>: This email is already registered, please choose another one.');
+
+		do_action('register_post');
+
+		$errors = apply_filters( 'registration_errors', $errors );
+
+		if ( empty( $errors ) ) {
+			$user_pass = substr( md5( uniqid( microtime() ) ), 0, 7);
+
+			$user_id = wp_create_user( $user_login, $user_pass, $user_email );
+			if ( !$user_id )
+				$errors['registerfail'] = sprintf(__('<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href="mailto:%s">webmaster</a> !'), get_option('admin_email'));
+			else {
+				wp_new_user_notification($user_id, $user_pass);
+
+				wp_redirect('wp-login.php?checkemail=registered');
+				exit();
+			}
+		}
+	}
+
+	login_header(__('Registration Form'), '<p class="message register">' . __('Register For This Site') . '</p>');
+?>
+
+<form name="registerform" id="registerform" action="wp-login.php?action=register" method="post">
+	<p>
+		<label><?php _e('Username:') ?><br />
+		<input type="text" name="user_login" id="user_login" class="input" value="<?php echo attribute_escape(stripslashes($user_login)); ?>" size="20" tabindex="10" /></label>
+	</p>
+	<p>
+		<label><?php _e('E-mail:') ?><br />
+		<input type="text" name="user_email" id="user_email" class="input" value="<?php echo attribute_escape(stripslashes($user_email)); ?>" size="25" tabindex="20" /></label>
+	</p>
+<?php do_action('register_form'); ?>
+	<p id="reg_passmail"><?php _e('A password will be e-mailed to you.') ?></p>
+	<p class="submit"><input type="submit" name="wp-submit" id="wp-submit" value="<?php _e('Register &raquo;'); ?>" tabindex="100" /></p>
+</form>
+</div>
 
+<ul>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php"><?php _e('Login') ?></a></li>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=lostpassword" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a></li>
+	<li><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('Back to %s'), get_bloginfo('title')); ?></a></li>
+</ul>
+
+</body>
+</html>
+<?php
+break;
+
+case 'login' :
+default:
 	$user_login = '';
 	$user_pass = '';
-	$using_cookie = false;
-	if ( !isset( $_REQUEST['redirect_to'] ) )
+	$using_cookie = FALSE;
+
+	if ( !isset( $_REQUEST['redirect_to'] ) || is_user_logged_in() )
 		$redirect_to = 'wp-admin/';
 	else
 		$redirect_to = $_REQUEST['redirect_to'];
 
-	if( $_POST ) {
+	if ( $_POST ) {
 		$user_login = $_POST['log'];
 		$user_login = sanitize_user( $user_login );
 		$user_pass  = $_POST['pwd'];
@@ -185,70 +308,71 @@
 		}
 	}
 
-	do_action('wp_authenticate', array(&$user_login, &$user_pass));
+	do_action_ref_array('wp_authenticate', array(&$user_login, &$user_pass));
 
-	if ( $user_login && $user_pass ) {
+	if ( $user_login && $user_pass && empty( $errors ) ) {
 		$user = new WP_User(0, $user_login);
-	
+
 		// If the user can't edit posts, send them to their profile.
 		if ( !$user->has_cap('edit_posts') && ( empty( $redirect_to ) || $redirect_to == 'wp-admin/' ) )
-			$redirect_to = get_settings('siteurl') . '/wp-admin/profile.php';
-	
+			$redirect_to = get_option('siteurl') . '/wp-admin/profile.php';
+
 		if ( wp_login($user_login, $user_pass, $using_cookie) ) {
 			if ( !$using_cookie )
 				wp_setcookie($user_login, $user_pass, false, '', '', $rememberme);
 			do_action('wp_login', $user_login);
 			wp_redirect($redirect_to);
-			exit;
+			exit();
 		} else {
-			if ( $using_cookie )			
-				$error = __('Your session has expired.');
+			if ( $using_cookie )
+				$errors['expiredsession'] = __('Your session has expired.');
 		}
-	} else if ( $user_login || $user_pass ) {
-		$error = __('<strong>Error</strong>: The password field is empty.');
 	}
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<title>WordPress &rsaquo; <?php _e('Login') ?></title>
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
-	<link rel="stylesheet" href="<?php bloginfo('wpurl'); ?>/wp-admin/wp-admin.css" type="text/css" />
-	<script type="text/javascript">
-	function focusit() {
-		document.getElementById('log').focus();
-	}
-	window.onload = focusit;
-	</script>
-</head>
-<body>
 
-<div id="login">
-<h1><a href="http://wordpress.org/">WordPress</a></h1>
-<?php
-if ( $error )
-	echo "<div id='login_error'>$error</div>";
+	if ( $_POST && empty( $user_login ) )
+		$errors['user_login'] = __('<strong>ERROR</strong>: The username field is empty.');
+	if ( $_POST && empty( $user_pass ) )
+		$errors['user_pass'] = __('<strong>ERROR</strong>: The password field is empty.');
+
+	// Some parts of this script use the main login form to display a message
+	if		( TRUE == $_GET['loggedout'] )			$errors['loggedout']		= __('Successfully logged you out.');
+	elseif	( 'disabled' == $_GET['registration'] )	$errors['registerdiabled']	= __('User registration is currently not allowed.');
+	elseif	( 'confirm' == $_GET['checkemail'] )	$errors['confirm']			= __('Check your e-mail for the confirmation link.');
+	elseif	( 'newpass' == $_GET['checkemail'] )	$errors['newpass']			= __('Check your e-mail for your new password.');
+	elseif	( 'registered' == $_GET['checkemail'] )	$errors['registered']		= __('Registration complete. Please check your e-mail.');
+
+	login_header(__('Login'));
 ?>
 
 <form name="loginform" id="loginform" action="wp-login.php" method="post">
-<p><label><?php _e('Username:') ?><br /><input type="text" name="log" id="log" value="<?php echo wp_specialchars(stripslashes($user_login), 1); ?>" size="20" tabindex="1" /></label></p>
-<p><label><?php _e('Password:') ?><br /> <input type="password" name="pwd" id="pwd" value="" size="20" tabindex="2" /></label></p>
-<p>
-  <label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="3" /> 
-  <?php _e('Remember me'); ?></label></p>
-<p class="submit">
-	<input type="submit" name="submit" id="submit" value="<?php _e('Login'); ?> &raquo;" tabindex="4" />
-	<input type="hidden" name="redirect_to" value="<?php echo wp_specialchars($redirect_to); ?>" />
-</p>
+	<p>
+		<label><?php _e('Username:') ?><br />
+		<input type="text" name="log" id="user_login" class="input" value="<?php echo attribute_escape(stripslashes($user_login)); ?>" size="20" tabindex="10" /></label>
+	</p>
+	<p>
+		<label><?php _e('Password:') ?><br />
+		<input type="password" name="pwd" id="user_pass" class="input" value="" size="20" tabindex="20" /></label>
+	</p>
+<?php do_action('login_form'); ?>
+	<p><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90" /> <?php _e('Remember me'); ?></label></p>
+	<p class="submit">
+		<input type="submit" name="wp-submit" id="wp-submit" value="<?php _e('Login'); ?> &raquo;" tabindex="100" />
+		<input type="hidden" name="redirect_to" value="<?php echo attribute_escape($redirect_to); ?>" />
+	</p>
 </form>
+</div>
+
 <ul>
-	<li><a href="<?php bloginfo('home'); ?>/" title="<?php _e('Are you lost?') ?>">&laquo; <?php _e('Back to blog') ?></a></li>
-<?php if (get_settings('users_can_register')) : ?>
-	<li><a href="<?php bloginfo('wpurl'); ?>/wp-register.php"><?php _e('Register') ?></a></li>
-<?php endif; ?>
+<?php if (get_option('users_can_register')) : ?>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=register"><?php _e('Register') ?></a></li>
+	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=lostpassword" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a></li>
+	<li><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('Back to %s'), get_bloginfo('title')); ?></a></li>
+<?php else : ?>
+	<li><a href="<?php bloginfo('url'); ?>/" title="<?php _e('Are you lost?') ?>"><?php printf(__('Back to %s'), get_bloginfo('title')); ?></a></li>
 	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=lostpassword" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a></li>
+<?php endif; ?>
 </ul>
-</div>
+
 
 </body>
 </html>
diff -ruN 2.0.5/wp-mail.php 2.2.2/wp-mail.php
--- 2.0.5/wp-mail.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-mail.php	2007-05-04 21:51:20.000000000 -0500
@@ -5,19 +5,17 @@
 
 error_reporting(2037);
 
-$time_difference = get_settings('gmt_offset') * 3600;
+$time_difference = get_option('gmt_offset') * 3600;
 
 $phone_delim = '::';
 
 $pop3 = new POP3();
 
-if (!$pop3->connect(get_settings('mailserver_url'), get_settings('mailserver_port'))) :
-	echo "Ooops $pop3->ERROR <br />\n";
-	exit;
-endif;
+if (!$pop3->connect(get_option('mailserver_url'), get_option('mailserver_port')))
+	wp_die($pop3->ERROR);
 
-$count = $pop3->login(get_settings('mailserver_login'), get_settings('mailserver_pass'));
-if (0 == $count) die(__('There doesn&#8217;t seem to be any new mail.'));
+$count = $pop3->login(get_option('mailserver_login'), get_option('mailserver_pass'));
+if (0 == $count) wp_die(__('There doesn&#8217;t seem to be any new mail.'));
 
 
 for ($i=1; $i <= $count; $i++) :
@@ -26,10 +24,10 @@
 
 	$content = '';
 	$content_type = '';
+	$content_transfer_encoding = '';
 	$boundary = '';
 	$bodysignal = 0;
-	$dmonths = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-					 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+	$dmonths = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
 	foreach ($message as $line) :
 		if (strlen($line) < 3) $bodysignal = 1;
 
@@ -42,6 +40,12 @@
 				$content_type = explode(';', $content_type);
 				$content_type = $content_type[0];
 			}
+			if (preg_match('/Content-Transfer-Encoding: /i', $line)) {
+				$content_transfer_encoding = trim($line);
+				$content_transfer_encoding = substr($content_transfer_encoding, 27, strlen($content_transfer_encoding)-14);
+				$content_transfer_encoding = explode(';', $content_transfer_encoding);
+				$content_transfer_encoding = $content_transfer_encoding[0];
+			}
 			if (($content_type == 'multipart/alternative') && (preg_match('/boundary="/', $line)) && ($boundary == '')) {
 				$boundary = trim($line);
 				$boundary = explode('"', $boundary);
@@ -58,7 +62,7 @@
 
 			// Set the author using the email address (To or Reply-To, the last used)
 			// otherwise use the site admin
-			if (preg_match('/From: /', $line) | preg_match('Reply-To: /', $line))  {
+			if (preg_match('/From: /', $line) | preg_match('/Reply-To: /', $line))  {
 				$author=trim($line);
 			if ( ereg("([a-zA-Z0-9\_\-\.]+@[\a-zA-z0-9\_\-\.]+)", $author , $regs) ) {
 				$author = $regs[1];
@@ -81,11 +85,11 @@
 				}
 				$date_arr = explode(' ', $ddate);
 				$date_time = explode(':', $date_arr[3]);
-				
+
 				$ddate_H = $date_time[0];
 				$ddate_i = $date_time[1];
 				$ddate_s = $date_time[2];
-				
+
 				$ddate_m = $date_arr[1];
 				$ddate_d = $date_arr[0];
 				$ddate_Y = $date_arr[2];
@@ -104,7 +108,7 @@
 		}
 	endforeach;
 
-	$subject = trim(str_replace(get_settings('subjectprefix'), '', $subject));
+	$subject = trim(str_replace(get_option('subjectprefix'), '', $subject));
 
 	if ($content_type == 'multipart/alternative') {
 		$content = explode('--'.$boundary, $content);
@@ -113,11 +117,16 @@
 		$content = strip_tags($content[1], '<img><p><br><i><b><u><em><strong><strike><font><span><div>');
 	}
 	$content = trim($content);
+	
+	if (stripos($content_transfer_encoding, "quoted-printable") !== false) {
+		$content = quoted_printable_decode($content);
+	}
+
 	// Captures any text in the body after $phone_delim as the body
 	$content = explode($phone_delim, $content);
 	$content[1] ? $content = $content[1] : $content = $content[0];
 
-	echo "<p><b>Content-type:</b> $content_type, <b>boundary:</b> $boundary</p>\n";
+	echo "<p><b>Content-type:</b> $content_type, <b>Content-Transfer-Encoding:</b> $content_transfer_encoding, <b>boundary:</b> $boundary</p>\n";
 	echo "<p><b>Raw content:</b><br /><pre>".$content.'</pre></p>';
 
 	$content = trim($content);
@@ -128,7 +137,7 @@
 
 	if ($post_title == '') $post_title = $subject;
 
-	if (empty($post_categories)) $post_categories[] = get_settings('default_email_category');
+	if (empty($post_categories)) $post_categories[] = get_option('default_email_category');
 
 	$post_category = $post_categories;
 
@@ -163,4 +172,4 @@
 
 $pop3->quit();
 
-?>
\ No newline at end of file
+?>
diff -ruN 2.0.5/wp-rdf.php 2.2.2/wp-rdf.php
--- 2.0.5/wp-rdf.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-rdf.php	2007-02-22 20:50:05.000000000 -0600
@@ -5,53 +5,6 @@
 	wp('feed=rdf');
 }
 
-header('Content-type: application/rdf+xml; charset=' . get_settings('blog_charset'), true);
-$more = 1;
+require (ABSPATH . WPINC . '/feed-rdf.php');
 
-?>
-<?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
-<!-- generator="wordpress/<?php echo $wp_version ?>" -->
-<rdf:RDF
-	xmlns="http://purl.org/rss/1.0/"
-	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-	xmlns:dc="http://purl.org/dc/elements/1.1/"
-	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
-	xmlns:admin="http://webns.net/mvcb/"
-	xmlns:content="http://purl.org/rss/1.0/modules/content/"
-	<?php do_action('rdf_ns'); ?>
->
-<channel rdf:about="<?php bloginfo_rss("url") ?>">
-	<title><?php bloginfo_rss('name') ?></title>
-	<link><?php bloginfo_rss('url') ?></link>
-	<description><?php bloginfo_rss('description') ?></description>
-	<dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></dc:date>
-	<admin:generatorAgent rdf:resource="http://wordpress.org/?v=<?php echo $wp_version ?>"/>
-	<sy:updatePeriod>hourly</sy:updatePeriod>
-	<sy:updateFrequency>1</sy:updateFrequency>
-	<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
-	<?php do_action('rdf_header'); ?>
-	<items>
-		<rdf:Seq>
-		<?php while (have_posts()): the_post(); ?>
-			<rdf:li rdf:resource="<?php permalink_single_rss() ?>"/>
-		<?php endwhile; ?>
-		</rdf:Seq>
-	</items>
-</channel>
-<?php rewind_posts(); while (have_posts()): the_post(); ?>
-<item rdf:about="<?php permalink_single_rss() ?>">
-	<title><?php the_title_rss() ?></title>
-	<link><?php permalink_single_rss() ?></link>
-	 <dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', $post->post_date_gmt, false); ?></dc:date>
-	<dc:creator><?php the_author() ?></dc:creator>
-	<?php the_category_rss('rdf') ?>
-<?php if (get_settings('rss_use_excerpt')) : ?>
-	<description><?php the_excerpt_rss() ?></description>
-<?php else : ?>
-	<description><?php the_content_rss('', 0, '', get_settings('rss_excerpt_length'), 2) ?></description>
-	<content:encoded><![CDATA[<?php the_content('', 0, '') ?>]]></content:encoded>
-<?php endif; ?>
-	<?php do_action('rdf_item'); ?>
-</item>
-<?php endwhile;  ?>
-</rdf:RDF>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-register.php 2.2.2/wp-register.php
--- 2.0.5/wp-register.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-register.php	2006-10-11 04:26:13.000000000 -0500
@@ -1,161 +1,9 @@
 <?php
-require('./wp-config.php');
-require_once( ABSPATH . WPINC . '/registration-functions.php');
-
-$action = $_REQUEST['action'];
-if ( !get_settings('users_can_register') )
-	$action = 'disabled';
-
-header( 'Content-Type: ' . get_bloginfo('html_type') . '; charset=' . get_bloginfo('charset') );
-
-switch( $action ) {
-
-case 'register':
-
-	$user_login = sanitize_user( $_POST['user_login'] );
-	$user_email = $_POST['user_email'];
-	
-	$errors = array();
-		
-	if ( $user_login == '' )
-		$errors['user_login'] = __('<strong>ERROR</strong>: Please enter a username.');
-
-	/* checking e-mail address */
-	if ($user_email == '') {
-		$errors['user_email'] = __('<strong>ERROR</strong>: Please type your e-mail address.');
-	} else if (!is_email($user_email)) {
-		$errors['user_email'] = __('<strong>ERROR</strong>: The email address isn&#8217;t correct.');
-		$user_email = '';
-	}
-
-	if ( ! validate_username($user_login) ) {
-		$errors['user_login'] = __('<strong>ERROR</strong>: This username is invalid.  Please enter a valid username.');
-		$user_login = '';
-	}
-
-	if ( username_exists( $user_login ) )
-		$errors['user_login'] = __('<strong>ERROR</strong>: This username is already registered, please choose another one.');
-
-	/* checking the email isn't already used by another user */
-	$email_exists = $wpdb->get_row("SELECT user_email FROM $wpdb->users WHERE user_email = '$user_email'");
-	if ( $email_exists)
-		die (__('<strong>ERROR</strong>: This email address is already registered, please supply another.'));
-
-	if ( 0 == count($errors) ) {
-		$password = substr( md5( uniqid( microtime() ) ), 0, 7);
-
-		$user_id = wp_create_user( $user_login, $password, $user_email );
-		if ( !$user_id )
-			$errors['user_id'] = sprintf(__('<strong>ERROR</strong>: Couldn&#8217;t register you... please contact the <a href="mailto:%s">webmaster</a> !'), get_settings('admin_email'));
-		else
-			wp_new_user_notification($user_id, $password);
-	}
-	
-	if ( 0 == count($errors) ) {
-			
-	?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<title>WordPress &raquo; <?php _e('Registration Complete') ?></title>
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />	
-	<link rel="stylesheet" href="wp-admin/wp-admin.css" type="text/css" />
-	<style type="text/css">
-	.submit {
-		font-size: 1.7em;
-	}
-	</style>
-</head>
-<body>
-
-<div id="login"> 
-	<h2><?php _e('Registration Complete') ?></h2>
-	<p><?php printf(__('Username: %s'), "<strong>" . wp_specialchars($user_login) . "</strong>") ?><br />
-	<?php printf(__('Password: %s'), '<strong>' . __('emailed to you') . '</strong>') ?> <br />
-	<?php printf(__('E-mail: %s'), "<strong>" . wp_specialchars($user_email) . "</strong>") ?></p>
-	<p class="submit"><a href="wp-login.php"><?php _e('Login'); ?> &raquo;</a></p>
-</div>
-</body>
-</html>
 
-		<?php
-		break;
-	}
+# This file is deprecated, but you shouldn't have been linking to it directly anyway :P
+# Use wp_register() to create a registration link instead, it's much better ;)
 
-default:
-
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<title>WordPress &raquo; <?php _e('Registration Form') ?></title>
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
-	<link rel="stylesheet" href="wp-admin/wp-admin.css" type="text/css" />
-	<style type="text/css">
-	#user_email, #user_login, #submit {
-		font-size: 1.7em;
-	}
-	</style>
-</head>
-
-<body>
-<div id="login">
-<h1><a href="http://wordpress.org/">WordPress</a></h1>
-<h2><?php _e('Register for this blog') ?></h2>
-<?php if ( isset($errors) ) : ?>
-<div class="error">
-	<ul>
-	<?php
-	foreach($errors as $error) echo "<li>$error</li>";
-	?>
-	</ul>
-</div>
-<?php endif; ?>
-<form method="post" action="wp-register.php" id="registerform">
-	<p><input type="hidden" name="action" value="register" />
-	<label for="user_login"><?php _e('Username:') ?></label><br /> <input type="text" name="user_login" id="user_login" size="20" maxlength="20" value="<?php echo wp_specialchars($user_login); ?>" /><br /></p>
-	<p><label for="user_email"><?php _e('E-mail:') ?></label><br /> <input type="text" name="user_email" id="user_email" size="25" maxlength="100" value="<?php echo wp_specialchars($user_email); ?>" /></p>
-	<p><?php _e('A password will be emailed to you.') ?></p>
-	<p class="submit"><input type="submit" value="<?php _e('Register') ?> &raquo;" id="submit" name="submit" /></p>
-</form>
-<ul>
-	<li><a href="<?php bloginfo('home'); ?>/" title="<?php _e('Are you lost?') ?>">&laquo; <?php _e('Back to blog') ?></a></li>
-	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php"><?php _e('Login') ?></a></li>
-	<li><a href="<?php bloginfo('wpurl'); ?>/wp-login.php?action=lostpassword" title="<?php _e('Password Lost and Found') ?>"><?php _e('Lost your password?') ?></a></li>
-</ul>
-</div>
-
-</body>
-</html>
-<?php
-
-break;
-
-case 'disabled':
-
-	?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<title>WordPress &raquo; <?php _e('Registration Currently Disabled') ?></title>
-	<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_settings('blog_charset'); ?>" />
-	<link rel="stylesheet" href="wp-admin/wp-admin.css" type="text/css">
-</head>
-
-<body>
-
-<div id="login">
-	<h2><?php _e('Registration Disabled') ?></h2>
-	<p><?php _e('User registration is currently not allowed.') ?><br />
-	<a href="<?php echo get_settings('home'); ?>/" title="<?php _e('Go back to the blog') ?>"><?php _e('Home') ?></a>
-	</p>
-</div>
-
-</body>
-</html>
-
-	<?php
-break;
+require('./wp-config.php');
+wp_redirect('wp-login.php?action=register');
 
-}
-?>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-rss.php 2.2.2/wp-rss.php
--- 2.0.5/wp-rss.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-rss.php	2007-02-22 20:50:05.000000000 -0600
@@ -5,33 +5,6 @@
 	wp('feed=rss');
 }
 
-header('Content-type: text/xml; charset=' . get_settings('blog_charset'), true);
-$more = 1;
+require (ABSPATH . WPINC . '/feed-rss.php');
 
-?>
-<?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
-<!-- generator="wordpress/<?php echo $wp_version ?>" -->
-<rss version="0.92">
-<channel>
-	<title><?php bloginfo_rss('name') ?></title>
-	<link><?php bloginfo_rss('url') ?></link>
-	<description><?php bloginfo_rss('description') ?></description>
-	<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
-	<docs>http://backend.userland.com/rss092</docs>
-	<language><?php echo get_option('rss_language'); ?></language>
-	<?php do_action('rss_head'); ?>
-
-<?php $items_count = 0; if ($posts) { foreach ($posts as $post) { start_wp(); ?>
-	<item>
-		<title><?php the_title_rss() ?></title>
-<?php if (get_settings('rss_use_excerpt')) { ?>
-		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
-<?php } else { // use content ?>
-		<description><?php the_content_rss('', 0, '', get_settings('rss_excerpt_length')) ?></description>
-<?php } ?>
-		<link><?php permalink_single_rss() ?></link>
-		<?php do_action('rss_item'); ?>
-	</item>
-<?php $items_count++; if (($items_count == get_settings('posts_per_rss')) && empty($m)) { break; } } } ?>
-</channel>
-</rss>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-rss2.php 2.2.2/wp-rss2.php
--- 2.0.5/wp-rss2.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-rss2.php	2007-02-22 20:50:05.000000000 -0600
@@ -5,52 +5,6 @@
 	wp('feed=rss2');
 }
 
-header('Content-type: text/xml; charset=' . get_settings('blog_charset'), true);
-$more = 1;
+require (ABSPATH . WPINC . '/feed-rss2.php');
 
-?>
-<?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
-
-<!-- generator="wordpress/<?php bloginfo_rss('version') ?>" -->
-<rss version="2.0" 
-	xmlns:content="http://purl.org/rss/1.0/modules/content/"
-	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
-	xmlns:dc="http://purl.org/dc/elements/1.1/"
-	<?php do_action('rss2_ns'); ?>
->
-
-<channel>
-	<title><?php bloginfo_rss('name'); ?></title>
-	<link><?php bloginfo_rss('url') ?></link>
-	<description><?php bloginfo_rss("description") ?></description>
-	<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></pubDate>
-	<generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator>
-	<language><?php echo get_option('rss_language'); ?></language>
-	<?php do_action('rss2_head'); ?>
-	<?php $items_count = 0; if ($posts) { foreach ($posts as $post) { start_wp(); ?>
-	<item>
-		<title><?php the_title_rss() ?></title>
-		<link><?php permalink_single_rss() ?></link>
-		<comments><?php comments_link(); ?></comments>
-		<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
-		<dc:creator><?php the_author() ?></dc:creator>
-		<?php the_category_rss() ?>
-
-		<guid isPermaLink="false"><?php the_guid(); ?></guid>
-<?php if (get_settings('rss_use_excerpt')) : ?>
-		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
-<?php else : ?>
-		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
-	<?php if ( strlen( $post->post_content ) > 0 ) : ?>
-		<content:encoded><![CDATA[<?php the_content('', 0, '') ?>]]></content:encoded>
-	<?php else : ?>
-		<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
-	<?php endif; ?>
-<?php endif; ?>
-		<wfw:commentRss><?php echo comments_rss(); ?></wfw:commentRss>
-<?php rss_enclosure(); ?>
-	<?php do_action('rss2_item'); ?>
-	</item>
-	<?php $items_count++; if (($items_count == get_settings('posts_per_rss')) && empty($m)) { break; } } } ?>
-</channel>
-</rss>
+?>
\ No newline at end of file
diff -ruN 2.0.5/wp-settings.php 2.2.2/wp-settings.php
--- 2.0.5/wp-settings.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-settings.php	2007-06-22 17:14:17.000000000 -0500
@@ -1,6 +1,6 @@
 <?php
 // Turn register globals off
-function unregister_GLOBALS() {
+function wp_unregister_GLOBALS() {
 	if ( !ini_get('register_globals') )
 		return;
 
@@ -9,14 +9,16 @@
 
 	// Variables that shouldn't be unset
 	$noUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES', 'table_prefix');
-	
+
 	$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
 	foreach ( $input as $k => $v ) 
-		if ( !in_array($k, $noUnset) && isset($GLOBALS[$k]) )
+		if ( !in_array($k, $noUnset) && isset($GLOBALS[$k]) ) {
+			$GLOBALS[$k] = NULL;
 			unset($GLOBALS[$k]);
+		}
 }
 
-unregister_GLOBALS(); 
+wp_unregister_GLOBALS(); 
 
 unset( $wp_filter, $cache_userdata, $cache_lastcommentmodified, $cache_lastpostdate, $cache_settings, $category_cache, $cache_categories );
 
@@ -26,7 +28,7 @@
 // Fix for IIS, which doesn't set REQUEST_URI
 if ( empty( $_SERVER['REQUEST_URI'] ) ) {
 	$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME']; // Does this work under CGI?
-	
+
 	// Append the query string if it exists and isn't null
 	if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
 		$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
@@ -38,7 +40,7 @@
 	$_SERVER['SCRIPT_FILENAME'] = $_SERVER['PATH_TRANSLATED'];
 
 // Fix for Dreamhost and other PHP as CGI hosts
-if ( strstr( $_SERVER['SCRIPT_NAME'], 'php.cgi' ) )
+if (strpos($_SERVER['SCRIPT_NAME'], 'php.cgi') !== false)
 	unset($_SERVER['PATH_INFO']);
 
 // Fix empty PHP_SELF
@@ -46,10 +48,10 @@
 if ( empty($PHP_SELF) )
 	$_SERVER['PHP_SELF'] = $PHP_SELF = preg_replace("/(\?.*)?$/",'',$_SERVER["REQUEST_URI"]);
 
-if ( !(phpversion() >= '4.1') )
-	die( 'Your server is running PHP version ' . phpversion() . ' but WordPress requires at least 4.1' );
+if ( !(phpversion() >= '4.2') )
+	die( 'Your server is running PHP version ' . phpversion() . ' but WordPress requires at least 4.2.' );
 
-if ( !extension_loaded('mysql') )
+if ( !extension_loaded('mysql') && !file_exists(ABSPATH . 'wp-content/db.php') )
 	die( 'Your PHP installation appears to be missing the MySQL which is required for WordPress.' );
 
 function timer_start() {
@@ -59,6 +61,19 @@
 	$timestart = $mtime;
 	return true;
 }
+
+function timer_stop($display = 0, $precision = 3) { //if called like timer_stop(1), will echo $timetotal
+	global $timestart, $timeend;
+	$mtime = microtime();
+	$mtime = explode(' ',$mtime);
+	$mtime = $mtime[1] + $mtime[0];
+	$timeend = $mtime;
+	$timetotal = $timeend-$timestart;
+	$r = number_format($timetotal, $precision);
+	if ( $display )
+		echo $r;
+	return $r;
+}
 timer_start();
 
 // Change to E_ALL for development/debugging
@@ -66,118 +81,130 @@
 
 // For an advanced caching plugin to use, static because you would only want one
 if ( defined('WP_CACHE') )
-	require (ABSPATH . 'wp-content/advanced-cache.php');
+	@include ABSPATH . 'wp-content/advanced-cache.php';
 
 define('WPINC', 'wp-includes');
-require_once (ABSPATH . WPINC . '/wp-db.php');
 
-// Table names
-$wpdb->posts            = $table_prefix . 'posts';
-$wpdb->users            = $table_prefix . 'users';
-$wpdb->categories       = $table_prefix . 'categories';
-$wpdb->post2cat         = $table_prefix . 'post2cat';
-$wpdb->comments         = $table_prefix . 'comments';
-$wpdb->links            = $table_prefix . 'links';
-$wpdb->linkcategories   = $table_prefix . 'linkcategories';
-$wpdb->options          = $table_prefix . 'options';
-$wpdb->postmeta         = $table_prefix . 'postmeta';
-$wpdb->usermeta         = $table_prefix . 'usermeta';
+if ( !defined('LANGDIR') ) {
+	if ( file_exists(ABSPATH . 'wp-content/languages') && @is_dir(ABSPATH . 'wp-content/languages') )
+		define('LANGDIR', 'wp-content/languages'); // no leading slash, no trailing slash
+	else
+		define('LANGDIR', WPINC . '/languages'); // no leading slash, no trailing slash
+}
+
+if ( !defined('PLUGINDIR') )
+	define('PLUGINDIR', 'wp-content/plugins'); // no leading slash, no trailing slash
+if ( file_exists(ABSPATH . 'wp-content/db.php') )
+	require (ABSPATH . 'wp-content/db.php');
+else
+	require_once (ABSPATH . WPINC . '/wp-db.php');
 
-$wpdb->prefix           = $table_prefix;
+// $table_prefix is deprecated as of 2.1
+$wpdb->prefix = $table_prefix;
+
+if ( preg_match('|[^a-z0-9_]|i', $wpdb->prefix) && !file_exists(ABSPATH . 'wp-content/db.php') )
+	die("<strong>ERROR</strong>: <code>$table_prefix</code> in <code>wp-config.php</code> can only contain numbers, letters, and underscores.");
+
+// Table names
+$wpdb->posts          = $wpdb->prefix . 'posts';
+$wpdb->users          = $wpdb->prefix . 'users';
+$wpdb->categories     = $wpdb->prefix . 'categories';
+$wpdb->post2cat       = $wpdb->prefix . 'post2cat';
+$wpdb->comments       = $wpdb->prefix . 'comments';
+$wpdb->link2cat       = $wpdb->prefix . 'link2cat';
+$wpdb->links          = $wpdb->prefix . 'links';
+$wpdb->options        = $wpdb->prefix . 'options';
+$wpdb->postmeta       = $wpdb->prefix . 'postmeta';
+$wpdb->usermeta       = $wpdb->prefix . 'usermeta';
 
 if ( defined('CUSTOM_USER_TABLE') )
 	$wpdb->users = CUSTOM_USER_TABLE;
 if ( defined('CUSTOM_USER_META_TABLE') )
 	$wpdb->usermeta = CUSTOM_USER_META_TABLE;
 
-// We're going to need to keep this around for a few months even though we're not using it internally
-
-$tableposts = $wpdb->posts;
-$tableusers = $wpdb->users;
-$tablecategories = $wpdb->categories;
-$tablepost2cat = $wpdb->post2cat;
-$tablecomments = $wpdb->comments;
-$tablelinks = $wpdb->links;
-$tablelinkcategories = $wpdb->linkcategories;
-$tableoptions = $wpdb->options;
-$tablepostmeta = $wpdb->postmeta;
-
 if ( file_exists(ABSPATH . 'wp-content/object-cache.php') )
 	require (ABSPATH . 'wp-content/object-cache.php');
 else
 	require (ABSPATH . WPINC . '/cache.php');
 
-// To disable persistant caching, add the below line to your wp-config.php file, uncommented of course.
-// define('DISABLE_CACHE', true);
-
 wp_cache_init();
 
 require (ABSPATH . WPINC . '/functions.php');
+require (ABSPATH . WPINC . '/classes.php');
+require (ABSPATH . WPINC . '/plugin.php');
 require (ABSPATH . WPINC . '/default-filters.php');
-require_once (ABSPATH . WPINC . '/wp-l10n.php');
+include_once(ABSPATH . WPINC . '/streams.php');
+include_once(ABSPATH . WPINC . '/gettext.php');
+require_once (ABSPATH . WPINC . '/l10n.php');
 
-$wpdb->hide_errors();
-$db_check = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'");
-if ( !$db_check && (!strstr($_SERVER['PHP_SELF'], 'install.php') && !defined('WP_INSTALLING')) ) {
-	if ( strstr($_SERVER['PHP_SELF'], 'wp-admin') )
+if ( !is_blog_installed() && (strpos($_SERVER['PHP_SELF'], 'install.php') === false && !defined('WP_INSTALLING')) ) {
+	if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false)
 		$link = 'install.php';
 	else
 		$link = 'wp-admin/install.php';
-	die(sprintf(__("It doesn't look like you've installed WP yet. Try running <a href='%s'>install.php</a>."), $link));
+	wp_die(sprintf("It doesn't look like you've installed WP yet. Try running <a href='%s'>install.php</a>.", $link));
 }
-$wpdb->show_errors();
 
-require (ABSPATH . WPINC . '/functions-formatting.php');
-require (ABSPATH . WPINC . '/functions-post.php');
+require (ABSPATH . WPINC . '/formatting.php');
 require (ABSPATH . WPINC . '/capabilities.php');
-require (ABSPATH . WPINC . '/classes.php');
-require (ABSPATH . WPINC . '/template-functions-general.php');
-require (ABSPATH . WPINC . '/template-functions-links.php');
-require (ABSPATH . WPINC . '/template-functions-author.php');
-require (ABSPATH . WPINC . '/template-functions-post.php');
-require (ABSPATH . WPINC . '/template-functions-category.php');
-require (ABSPATH . WPINC . '/comment-functions.php');
-require (ABSPATH . WPINC . '/feed-functions.php');
-require (ABSPATH . WPINC . '/links.php');
+require (ABSPATH . WPINC . '/query.php');
+require (ABSPATH . WPINC . '/theme.php');
+require (ABSPATH . WPINC . '/user.php');
+require (ABSPATH . WPINC . '/general-template.php');
+require (ABSPATH . WPINC . '/link-template.php');
+require (ABSPATH . WPINC . '/author-template.php');
+require (ABSPATH . WPINC . '/post.php');
+require (ABSPATH . WPINC . '/post-template.php');
+require (ABSPATH . WPINC . '/category.php');
+require (ABSPATH . WPINC . '/category-template.php');
+require (ABSPATH . WPINC . '/comment.php');
+require (ABSPATH . WPINC . '/comment-template.php');
+require (ABSPATH . WPINC . '/rewrite.php');
+require (ABSPATH . WPINC . '/feed.php');
+require (ABSPATH . WPINC . '/bookmark.php');
+require (ABSPATH . WPINC . '/bookmark-template.php');
 require (ABSPATH . WPINC . '/kses.php');
+require (ABSPATH . WPINC . '/cron.php');
 require (ABSPATH . WPINC . '/version.php');
+require (ABSPATH . WPINC . '/deprecated.php');
+require (ABSPATH . WPINC . '/script-loader.php');
 
-if (!strstr($_SERVER['PHP_SELF'], 'install.php')) :
+if (strpos($_SERVER['PHP_SELF'], 'install.php') === false) {
     // Used to guarantee unique hash cookies
-    $cookiehash = md5(get_settings('siteurl')); // Remove in 1.4
+    $cookiehash = md5(get_option('siteurl'));
 	define('COOKIEHASH', $cookiehash); 
-endif;
+}
 
 if ( !defined('USER_COOKIE') )
 	define('USER_COOKIE', 'wordpressuser_'. COOKIEHASH);
 if ( !defined('PASS_COOKIE') )
 	define('PASS_COOKIE', 'wordpresspass_'. COOKIEHASH);
 if ( !defined('COOKIEPATH') )
-	define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_settings('home') . '/' ) );
+	define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('home') . '/' ) );
 if ( !defined('SITECOOKIEPATH') )
-	define('SITECOOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_settings('siteurl') . '/' ) );
+	define('SITECOOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('siteurl') . '/' ) );
 if ( !defined('COOKIE_DOMAIN') )
 	define('COOKIE_DOMAIN', false);
 
 require (ABSPATH . WPINC . '/vars.php');
 
 // Check for hacks file if the option is enabled
-if (get_settings('hack_file')) {
+if (get_option('hack_file')) {
 	if (file_exists(ABSPATH . '/my-hacks.php'))
 		require(ABSPATH . '/my-hacks.php');
 }
 
-if ( get_settings('active_plugins') ) {
-	$current_plugins = get_settings('active_plugins');
+if ( get_option('active_plugins') ) {
+	$current_plugins = get_option('active_plugins');
 	if ( is_array($current_plugins) ) {
 		foreach ($current_plugins as $plugin) {
-			if ('' != $plugin && file_exists(ABSPATH . 'wp-content/plugins/' . $plugin))
-				include_once(ABSPATH . 'wp-content/plugins/' . $plugin);
+			if ('' != $plugin && file_exists(ABSPATH . PLUGINDIR . '/' . $plugin))
+				include_once(ABSPATH . PLUGINDIR . '/' . $plugin);
 		}
 	}
 }
 
-require (ABSPATH . WPINC . '/pluggable-functions.php');
+require (ABSPATH . WPINC . '/pluggable.php');
 
 if ( defined('WP_CACHE') && function_exists('wp_cache_postload') )
 	wp_cache_postload();
@@ -199,21 +226,33 @@
 
 do_action('sanitize_comment_cookies');
 
-$wp_query   = new WP_Query();
-$wp_rewrite = new WP_Rewrite();
-$wp         = new WP();
+$wp_the_query =& new WP_Query();
+$wp_query     =& $wp_the_query;
+$wp_rewrite   =& new WP_Rewrite();
+$wp           =& new WP();
 
+validate_current_theme();
 define('TEMPLATEPATH', get_template_directory());
+define('STYLESHEETPATH', get_stylesheet_directory());
 
 // Load the default text localization domain.
 load_default_textdomain();
 
+$locale = get_locale();
+$locale_file = ABSPATH . LANGDIR . "/$locale.php";
+if ( is_readable($locale_file) )
+	require_once($locale_file);
+
 // Pull in locale data after loading text domain.
 require_once(ABSPATH . WPINC . '/locale.php');
 
+$wp_locale =& new WP_Locale();
+
 // Load functions for active theme.
-if ( file_exists(TEMPLATEPATH . "/functions.php") )
-	include(TEMPLATEPATH . "/functions.php");
+if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists(STYLESHEETPATH . '/functions.php') )
+	include(STYLESHEETPATH . '/functions.php');
+if ( file_exists(TEMPLATEPATH . '/functions.php') )
+	include(TEMPLATEPATH . '/functions.php');
 
 function shutdown_action_hook() {
 	do_action('shutdown');
@@ -224,4 +263,4 @@
 // Everything is loaded and initialized.
 do_action('init');
 
-?>
\ No newline at end of file
+?>
diff -ruN 2.0.5/wp-trackback.php 2.2.2/wp-trackback.php
--- 2.0.5/wp-trackback.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/wp-trackback.php	2007-03-22 19:59:21.000000000 -0500
@@ -30,11 +30,13 @@
 	$tb_id = intval( $tb_id[ count($tb_id) - 1 ] );
 }
 
-$tb_url    = $_POST['url'];
-$title     = $_POST['title'];
-$excerpt   = $_POST['excerpt'];
-$blog_name = $_POST['blog_name'];
-$charset   = $_POST['charset'];
+$tb_url  = $_POST['url'];
+$charset = $_POST['charset'];
+
+// These three are stripslashed here so that they can be properly escaped after mb_convert_encoding()
+$title     = stripslashes($_POST['title']);
+$excerpt   = stripslashes($_POST['excerpt']);
+$blog_name = stripslashes($_POST['blog_name']);
 
 if ($charset)
 	$charset = strtoupper( trim($charset) );
@@ -42,13 +44,18 @@
 	$charset = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS';
 
 if ( function_exists('mb_convert_encoding') ) { // For international trackbacks
-	$title     = mb_convert_encoding($title, get_settings('blog_charset'), $charset);
-	$excerpt   = mb_convert_encoding($excerpt, get_settings('blog_charset'), $charset);
-	$blog_name = mb_convert_encoding($blog_name, get_settings('blog_charset'), $charset);
+	$title     = mb_convert_encoding($title, get_option('blog_charset'), $charset);
+	$excerpt   = mb_convert_encoding($excerpt, get_option('blog_charset'), $charset);
+	$blog_name = mb_convert_encoding($blog_name, get_option('blog_charset'), $charset);
 }
 
-if ( is_single() || is_page() ) 
-    $tb_id = $posts[0]->ID;
+// Now that mb_convert_encoding() has been given a swing, we need to escape these three
+$title     = $wpdb->escape($title);
+$excerpt   = $wpdb->escape($excerpt);
+$blog_name = $wpdb->escape($blog_name);
+
+if ( is_single() || is_page() )
+	$tb_id = $posts[0]->ID;
 
 if ( !intval( $tb_id ) )
 	trackback_response(1, 'I really need an ID for this to work.');
@@ -59,7 +66,7 @@
 	exit;
 }
 
-if ( !empty($tb_url) && !empty($title) && !empty($tb_url) ) {
+if ( !empty($tb_url) && !empty($title) ) {
 	header('Content-Type: text/xml; charset=' . get_option('blog_charset') );
 
 	$pingstatus = $wpdb->get_var("SELECT ping_status FROM $wpdb->posts WHERE ID = $tb_id");
@@ -70,14 +77,14 @@
 	$title =  wp_specialchars( strip_tags( $title ) );
 	$excerpt = strip_tags($excerpt);
 	if ( function_exists('mb_strcut') ) { // For international trackbacks
-		$excerpt = mb_strcut($excerpt, 0, 252, get_settings('blog_charset')) . '...';
-		$title = mb_strcut($title, 0, 250, get_settings('blog_charset')) . '...';
+		$excerpt = mb_strcut($excerpt, 0, 252, get_option('blog_charset')) . '...';
+		$title = mb_strcut($title, 0, 250, get_option('blog_charset')) . '...';
 	} else {
 		$excerpt = (strlen($excerpt) > 255) ? substr($excerpt, 0, 252) . '...' : $excerpt;
 		$title = (strlen($title) > 250) ? substr($title, 0, 250) . '...' : $title;
 	}
 
-	$comment_post_ID = $tb_id;
+	$comment_post_ID = (int) $tb_id;
 	$comment_author = $blog_name;
 	$comment_author_email = '';
 	$comment_author_url = $tb_url;
@@ -86,7 +93,7 @@
 
 	$dupe = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$comment_post_ID' AND comment_author_url = '$comment_author_url'");
 	if ( $dupe )
-		trackback_response(1, 'We already have a ping from that URI for this post.');
+		trackback_response(1, 'We already have a ping from that URL for this post.');
 
 	$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type');
 
diff -ruN 2.0.5/xmlrpc.php 2.2.2/xmlrpc.php
--- 2.0.5/xmlrpc.php	2006-10-31 09:05:37.000000000 -0600
+++ 2.2.2/xmlrpc.php	2007-06-19 14:37:05.000000000 -0500
@@ -5,6 +5,12 @@
 // Some browser-embedded clients send cookies. We don't want them.
 $_COOKIE = array();
 
+// A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, 
+// but we can do it ourself.
+if ( !isset( $HTTP_RAW_POST_DATA ) ) {
+	$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );
+}
+
 # fix for mozBlog and other cases where '<?xml' isn't on the very first line
 if ( isset($HTTP_RAW_POST_DATA) )
 	$HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
@@ -12,19 +18,20 @@
 include('./wp-config.php');
 
 if ( isset( $_GET['rsd'] ) ) { // http://archipelago.phrasewise.com/rsd 
-header('Content-type: text/xml; charset=' . get_settings('blog_charset'), true);
+header('Content-type: text/xml; charset=' . get_option('blog_charset'), true);
 
 ?>
-<?php echo '<?xml version="1.0" encoding="'.get_settings('blog_charset').'"?'.'>'; ?>
+<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
 <rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
   <service>
     <engineName>WordPress</engineName>
     <engineLink>http://wordpress.org/</engineLink>
     <homePageLink><?php bloginfo_rss('url') ?></homePageLink>
     <apis>
-      <api name="Movable Type" blogID="1" preferred="true" apiLink="<?php bloginfo_rss('url') ?>/xmlrpc.php" />
-      <api name="MetaWeblog" blogID="1" preferred="false" apiLink="<?php bloginfo_rss('url') ?>/xmlrpc.php" />
-      <api name="Blogger" blogID="1" preferred="false" apiLink="<?php bloginfo_rss('url') ?>/xmlrpc.php" />
+      <api name="WordPress" blogID="1" preferred="false" apiLink="<?php bloginfo_rss('wpurl') ?>/xmlrpc.php" />
+      <api name="Movable Type" blogID="1" preferred="true" apiLink="<?php bloginfo_rss('wpurl') ?>/xmlrpc.php" />
+      <api name="MetaWeblog" blogID="1" preferred="false" apiLink="<?php bloginfo_rss('wpurl') ?>/xmlrpc.php" />
+      <api name="Blogger" blogID="1" preferred="false" apiLink="<?php bloginfo_rss('wpurl') ?>/xmlrpc.php" />
     </apis>
   </service>
 </rsd>
@@ -32,6 +39,7 @@
 exit;
 }
 
+include_once(ABSPATH . 'wp-admin/admin-functions.php');
 include_once(ABSPATH . WPINC . '/class-IXR.php');
 
 // Turn off all warnings and errors.
@@ -66,48 +74,61 @@
 
 	function wp_xmlrpc_server() {
 		$this->methods = array(
-		  // Blogger API
-		  'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',
-		  'blogger.getUserInfo' => 'this:blogger_getUserInfo',
-		  'blogger.getPost' => 'this:blogger_getPost',
-		  'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',
-		  'blogger.getTemplate' => 'this:blogger_getTemplate',
-		  'blogger.setTemplate' => 'this:blogger_setTemplate',
-		  'blogger.newPost' => 'this:blogger_newPost',
-		  'blogger.editPost' => 'this:blogger_editPost',
-		  'blogger.deletePost' => 'this:blogger_deletePost',
-
-		  // MetaWeblog API (with MT extensions to structs)
-		  'metaWeblog.newPost' => 'this:mw_newPost',
-		  'metaWeblog.editPost' => 'this:mw_editPost',
-		  'metaWeblog.getPost' => 'this:mw_getPost',
-		  'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',
-		  'metaWeblog.getCategories' => 'this:mw_getCategories',
-		  'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',
-
-		  // MetaWeblog API aliases for Blogger API
-		  // see http://www.xmlrpc.com/stories/storyReader$2460
-		  'metaWeblog.deletePost' => 'this:blogger_deletePost',
-		  'metaWeblog.getTemplate' => 'this:blogger_getTemplate',
-		  'metaWeblog.setTemplate' => 'this:blogger_setTemplate',
-		  'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',
-
-		  // MovableType API
-		  'mt.getCategoryList' => 'this:mt_getCategoryList',
-		  'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',
-		  'mt.getPostCategories' => 'this:mt_getPostCategories',
-		  'mt.setPostCategories' => 'this:mt_setPostCategories',
-		  'mt.supportedMethods' => 'this:mt_supportedMethods',
-		  'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',
-		  'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',
-		  'mt.publishPost' => 'this:mt_publishPost',
-
-		  // PingBack
-		  'pingback.ping' => 'this:pingback_ping',
-		  'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
+			// WordPress API
+			'wp.getPage'			=> 'this:wp_getPage',
+			'wp.getPages'			=> 'this:wp_getPages',
+			'wp.newPage'			=> 'this:wp_newPage',
+			'wp.deletePage'			=> 'this:wp_deletePage',
+			'wp.editPage'			=> 'this:wp_editPage',
+			'wp.getPageList'		=> 'this:wp_getPageList',
+			'wp.getAuthors'			=> 'this:wp_getAuthors',
+			'wp.getCategories'		=> 'this:mw_getCategories',		// Alias
+			'wp.newCategory'		=> 'this:wp_newCategory',
+			'wp.suggestCategories'	=> 'this:wp_suggestCategories',
+			'wp.uploadFile'			=> 'this:mw_newMediaObject',	// Alias
+
+			// Blogger API
+			'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',
+			'blogger.getUserInfo' => 'this:blogger_getUserInfo',
+			'blogger.getPost' => 'this:blogger_getPost',
+			'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',
+			'blogger.getTemplate' => 'this:blogger_getTemplate',
+			'blogger.setTemplate' => 'this:blogger_setTemplate',
+			'blogger.newPost' => 'this:blogger_newPost',
+			'blogger.editPost' => 'this:blogger_editPost',
+			'blogger.deletePost' => 'this:blogger_deletePost',
+
+			// MetaWeblog API (with MT extensions to structs)
+			'metaWeblog.newPost' => 'this:mw_newPost',
+			'metaWeblog.editPost' => 'this:mw_editPost',
+			'metaWeblog.getPost' => 'this:mw_getPost',
+			'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',
+			'metaWeblog.getCategories' => 'this:mw_getCategories',
+			'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',
+
+			// MetaWeblog API aliases for Blogger API
+			// see http://www.xmlrpc.com/stories/storyReader$2460
+			'metaWeblog.deletePost' => 'this:blogger_deletePost',
+			'metaWeblog.getTemplate' => 'this:blogger_getTemplate',
+			'metaWeblog.setTemplate' => 'this:blogger_setTemplate',
+			'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',
+
+			// MovableType API
+			'mt.getCategoryList' => 'this:mt_getCategoryList',
+			'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',
+			'mt.getPostCategories' => 'this:mt_getPostCategories',
+			'mt.setPostCategories' => 'this:mt_setPostCategories',
+			'mt.supportedMethods' => 'this:mt_supportedMethods',
+			'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',
+			'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',
+			'mt.publishPost' => 'this:mt_publishPost',
+
+			// PingBack
+			'pingback.ping' => 'this:pingback_ping',
+			'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
 
-		  'demo.sayHello' => 'this:sayHello',
-		  'demo.addTwoNumbers' => 'this:addTwoNumbers'
+			'demo.sayHello' => 'this:sayHello',
+			'demo.addTwoNumbers' => 'this:addTwoNumbers'
 		);
 		$this->methods = apply_filters('xmlrpc_methods', $this->methods);
 		$this->IXR_Server($this->methods);
@@ -124,27 +145,423 @@
 	}
 
 	function login_pass_ok($user_login, $user_pass) {
-	  if (!user_pass_ok($user_login, $user_pass)) {
-	    $this->error = new IXR_Error(403, 'Bad login/pass combination.');
-	    return false;
-	  }
-	  return true;
+		if (!user_pass_ok($user_login, $user_pass)) {
+			$this->error = new IXR_Error(403, __('Bad login/pass combination.'));
+			return false;
+		}
+		return true;
 	}
 
 	function escape(&$array) {
 		global $wpdb;
 
-		foreach ( (array) $array as $k => $v ) {
-			if (is_array($v)) {
-				$this->escape($array[$k]);
-			} else if (is_object($v)) {
-				//skip
-			} else {
-				$array[$k] = $wpdb->escape($v);
+		if(!is_array($array)) {
+			return($wpdb->escape($array));
+		}
+		else {
+			foreach ( (array) $array as $k => $v ) {
+				if (is_array($v)) {
+					$this->escape($array[$k]);
+				} else if (is_object($v)) {
+					//skip
+				} else {
+					$array[$k] = $wpdb->escape($v);
+				}
 			}
 		}
 	}
 
+	/**
+	 * WordPress XML-RPC API
+	 * wp_getPage
+	 */
+	function wp_getPage($args) {
+		$this->escape($args);
+
+		$blog_id	= (int) $args[0];
+		$page_id	= (int) $args[1];
+		$username	= $args[2];
+		$password	= $args[3];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Lookup page info.
+		$page = get_page($page_id);
+
+		// If we found the page then format the data.
+		if($page->ID && ($page->post_type == "page")) {
+			// Get all of the page content and link.
+			$full_page = get_extended($page->post_content);
+			$link = post_permalink($page->ID);
+
+			// Get info the page parent if there is one.
+			$parent_title = "";
+			if(!empty($page->post_parent)) {
+				$parent = get_page($page->post_parent);
+				$parent_title = $parent->post_title;
+			}
+
+			// Determine comment and ping settings.
+			$allow_comments = ("open" == $page->comment_status) ? 1 : 0;
+			$allow_pings = ("open" == $page->ping_status) ? 1 : 0;
+
+			// Format page date.
+			$page_date = mysql2date("Ymd\TH:i:s\Z", $page->post_date_gmt);
+
+			// Pull the categories info together.
+			$categories = array();
+			foreach(wp_get_post_categories($page->ID) as $cat_id) {
+				$categories[] = get_cat_name($cat_id);
+			}
+
+			// Get the author info.
+			$author = get_userdata($page->post_author);
+
+			$page_struct = array(
+				"dateCreated"			=> new IXR_Date($page_date),
+				"userid"				=> $page->post_author,
+				"page_id"				=> $page->ID,
+				"page_status"			=> $page->post_status,
+				"description"			=> $full_page["main"],
+				"title"					=> $page->post_title,
+				"link"					=> $link,
+				"permaLink"				=> $link,
+				"categories"			=> $categories,
+				"excerpt"				=> $page->post_excerpt,
+				"text_more"				=> $full_page["extended"],
+				"mt_allow_comments"		=> $allow_comments,
+				"mt_allow_pings"		=> $allow_pings,
+				"wp_slug"				=> $page->post_name,
+				"wp_password"			=> $page->post_password,
+				"wp_author"				=> $author->display_name,
+				"wp_page_parent_id"		=> $page->post_parent,
+				"wp_page_parent_title"	=> $parent_title,
+				"wp_page_order"			=> $page->menu_order,
+				"wp_author_id"			=> $author->ID,
+				"wp_author_display_name"	=> $author->display_name
+			);
+
+			return($page_struct);
+		}
+		// If the page doesn't exist indicate that.
+		else {
+			return(new IXR_Error(404, __("Sorry, no such page.")));
+		}
+	}
+
+	/**
+	 * WordPress XML-RPC API
+ 	 * wp_getPages
+	 */
+	function wp_getPages($args) {
+		$this->escape($args);
+
+		$blog_id	= (int) $args[0];
+		$username	= $args[1];
+		$password	= $args[2];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Lookup info on pages.
+		$pages = get_pages();
+		$num_pages = count($pages);
+
+		// If we have pages, put together their info.
+		if($num_pages >= 1) {
+			$pages_struct = array();
+
+			for($i = 0; $i < $num_pages; $i++) {
+				$page = wp_xmlrpc_server::wp_getPage(array(
+					$blog_id, $pages[$i]->ID, $username, $password
+				));
+				$pages_struct[] = $page;
+			}
+
+			return($pages_struct);
+		}
+		// If no pages were found return an error.
+		else {
+			return(array());
+		}
+	}
+
+	/**
+	 * WordPress XML-RPC API
+ 	 * wp_newPage
+	 */
+	function wp_newPage($args) {
+		// Items not escaped here will be escaped in newPost.
+		$username	= $this->escape($args[1]);
+		$password	= $this->escape($args[2]);
+		$page		= $args[3];
+		$publish	= $args[4];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Set the user context and check if they are allowed
+		// to add new pages.
+		$user = set_current_user(0, $username);
+		if(!current_user_can("publish_pages")) {
+			return(new IXR_Error(401, __("Sorry, you can not add new pages.")));
+		}
+
+		// Mark this as content for a page.
+		$args[3]["post_type"] = "page";
+
+		// Let mw_newPost do all of the heavy lifting.
+		return($this->mw_newPost($args));
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_deletePage
+	 */
+	function wp_deletePage($args) {
+		$this->escape($args);
+
+		$blog_id	= (int) $args[0];
+		$username	= $args[1];
+		$password	= $args[2];
+		$page_id	= (int) $args[3];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Get the current page based on the page_id and
+		// make sure it is a page and not a post.
+		$actual_page = wp_get_single_post($page_id, ARRAY_A);
+		if(
+			!$actual_page
+			|| ($actual_page["post_type"] != "page")
+		) {
+			return(new IXR_Error(404, __("Sorry, no such page.")));
+		}
+
+		// Set the user context and make sure they can delete pages.
+		set_current_user(0, $username);
+		if(!current_user_can("delete_page", $page_id)) {
+			return(new IXR_Error(401, __("Sorry, you do not have the right to delete this page.")));
+		}
+
+		// Attempt to delete the page.
+		$result = wp_delete_post($page_id);
+		if(!$result) {
+			return(new IXR_Error(500, __("Failed to delete the page.")));
+		}
+
+		return(true);
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_editPage
+	 */
+	function wp_editPage($args) {
+		// Items not escaped here will be escaped in editPost.
+		$blog_id	= (int) $args[0];
+		$page_id	= (int) $this->escape($args[1]);
+		$username	= $this->escape($args[2]);
+		$password	= $this->escape($args[3]);
+		$content	= $args[4];
+		$publish	= $args[5];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Get the page data and make sure it is a page.
+		$actual_page = wp_get_single_post($page_id, ARRAY_A);
+		if(
+			!$actual_page
+			|| ($actual_page["post_type"] != "page")
+		) {
+			return(new IXR_Error(404, __("Sorry, no such page.")));
+		}
+
+		// Set the user context and make sure they are allowed to edit pages.
+		set_current_user(0, $username);
+		if(!current_user_can("edit_page", $page_id)) {
+			return(new IXR_Error(401, __("Sorry, you do not have the right to edit this page.")));
+		}
+
+		// Mark this as content for a page.
+		$content["post_type"] = "page";
+
+		// Arrange args in the way mw_editPost understands.
+		$args = array(
+			$page_id,
+			$username,
+			$password,
+			$content,
+			$publish
+		);
+
+		// Let mw_editPost do all of the heavy lifting.
+		return($this->mw_editPost($args));
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_getPageList
+	 */
+	function wp_getPageList($args) {
+		global $wpdb;
+
+		$this->escape($args);
+
+		$blog_id				= (int) $args[0];
+		$username				= $args[1];
+		$password				= $args[2];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Get list of pages ids and titles
+		$page_list = $wpdb->get_results("
+			SELECT ID page_id,
+				post_title page_title,
+				post_parent page_parent_id,
+				post_date_gmt
+			FROM {$wpdb->posts}
+			WHERE post_type = 'page'
+			ORDER BY ID
+		");
+
+		// The date needs to be formated properly.
+		$num_pages = count($page_list);
+		for($i = 0; $i < $num_pages; $i++) {
+			$post_date = mysql2date("Ymd\TH:i:s\Z", $page_list[$i]->post_date_gmt);
+			$page_list[$i]->dateCreated = new IXR_Date($post_date);
+
+			unset($page_list[$i]->post_date_gmt);
+		}
+
+		return($page_list);
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_getAuthors
+	 */
+	function wp_getAuthors($args) {
+		global $wpdb;
+
+		$this->escape($args);
+
+		$blog_id	= (int) $args[0];
+		$username	= $args[1];
+		$password	= $args[2];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		return(get_users_of_blog());
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_newCategory
+	 */
+	function wp_newCategory($args) {
+		$this->escape($args);
+
+		$blog_id				= (int) $args[0];
+		$username				= $args[1];
+		$password				= $args[2];
+		$category				= $args[3];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Set the user context and make sure they are
+		// allowed to add a category.
+		set_current_user(0, $username);
+		if(!current_user_can("manage_categories", $page_id)) {
+			return(new IXR_Error(401, __("Sorry, you do not have the right to add a category.")));
+		}
+
+		// We need this to make use of the wp_insert_category()
+		// funciton.
+		require_once(ABSPATH . "wp-admin/admin-db.php");
+
+		// If no slug was provided make it empty so that
+		// WordPress will generate one.
+		if(empty($category["slug"])) {
+			$category["slug"] = "";
+		}
+
+		// If no parent_id was provided make it empty
+		// so that it will be a top level page (no parent).
+		if ( !isset($category["parent_id"]) )
+			$category["parent_id"] = "";
+
+		// If no description was provided make it empty.
+		if(empty($category["description"])) {
+			$category["description"] = "";
+		}
+	
+		$new_category = array(
+			"cat_name"				=> $category["name"],
+			"category_nicename"		=> $category["slug"],
+			"category_parent"		=> $category["parent_id"],
+			"category_description"	=> $category["description"]
+		);
+
+		$cat_id = wp_insert_category($new_category);
+		if(!$cat_id) {
+			return(new IXR_Error(500, __("Sorry, the new category failed.")));
+		}
+
+		return($cat_id);
+	}
+
+	/**
+	 * WordPress XML-RPC API
+	 * wp_suggestCategories
+	 */
+	function wp_suggestCategories($args) {
+		global $wpdb;
+
+		$this->escape($args);
+
+		$blog_id				= (int) $args[0];
+		$username				= $args[1];
+		$password				= $args[2];
+		$category				= $args[3];
+		$max_results			= (int) $args[4];
+
+		if(!$this->login_pass_ok($username, $password)) {
+			return($this->error);
+		}
+
+		// Only set a limit if one was provided.
+		$limit = "";
+		if(!empty($max_results)) {
+			$limit = "LIMIT {$max_results}";
+		}
+
+		$category_suggestions = $wpdb->get_results("
+			SELECT cat_ID category_id,
+				cat_name category_name
+			FROM {$wpdb->categories}
+			WHERE cat_name LIKE '{$category}%'
+			{$limit}
+		");
+
+		return($category_suggestions);
+	}
+
+
 	/* Blogger API functions
 	 * specs on http://plant.blogger.com/api and http://groups.yahoo.com/group/bloggerDev/
 	 */
@@ -155,24 +572,24 @@
 
 		$this->escape($args);
 
-	  $user_login = $args[1];
-	  $user_pass  = $args[2];
+		$user_login = $args[1];
+		$user_pass  = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  set_current_user(0, $user_login);
-	  $is_admin = current_user_can('level_8');
+		set_current_user(0, $user_login);
+		$is_admin = current_user_can('level_8');
 
-	  $struct = array(
-	    'isAdmin'  => $is_admin,
-	    'url'      => get_settings('home') . '/',
-	    'blogid'   => '1',
-	    'blogName' => get_settings('blogname')
-	  );
+		$struct = array(
+			'isAdmin'  => $is_admin,
+			'url'      => get_option('home') . '/',
+			'blogid'   => '1',
+			'blogName' => get_option('blogname')
+		);
 
-	  return array($struct);
+		return array($struct);
 	}
 
 
@@ -181,25 +598,25 @@
 
 		$this->escape($args);
 
-	  $user_login = $args[1];
-	  $user_pass  = $args[2];
+		$user_login = $args[1];
+		$user_pass  = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $user_data = get_userdatabylogin($user_login);
+		$user_data = get_userdatabylogin($user_login);
 
-	  $struct = array(
-	    'nickname'  => $user_data->nickname,
-	    'userid'    => $user_data->ID,
-	    'url'       => $user_data->user_url,
-	    'email'     => $user_data->user_email,
-	    'lastname'  => $user_data->last_name,
-	    'firstname' => $user_data->first_name
-	  );
+		$struct = array(
+			'nickname'  => $user_data->nickname,
+			'userid'    => $user_data->ID,
+			'url'       => $user_data->user_url,
+			'email'     => $user_data->user_email,
+			'lastname'  => $user_data->last_name,
+			'firstname' => $user_data->first_name
+		);
 
-	  return $struct;
+		return $struct;
 	}
 
 
@@ -208,81 +625,81 @@
 
 		$this->escape($args);
 
-	  $post_ID    = $args[1];
-	  $user_login = $args[2];
-	  $user_pass  = $args[3];
+		$post_ID    = (int) $args[1];
+		$user_login = $args[2];
+		$user_pass  = $args[3];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $user_data = get_userdatabylogin($user_login);
-	  $post_data = wp_get_single_post($post_ID, ARRAY_A);
+		$user_data = get_userdatabylogin($user_login);
+		$post_data = wp_get_single_post($post_ID, ARRAY_A);
 
-	  $categories = implode(',', wp_get_post_cats(1, $post_ID));
+		$categories = implode(',', wp_get_post_categories($post_ID));
 
-	  $content  = '<title>'.stripslashes($post_data['post_title']).'</title>';
-	  $content .= '<category>'.$categories.'</category>';
-	  $content .= stripslashes($post_data['post_content']);
-
-	  $struct = array(
-	    'userid'    => $post_data['post_author'],
-	    'dateCreated' => new IXR_Date(mysql2date('Ymd\TH:i:s', $post_data['post_date'])),
-	    'content'     => $content,
-	    'postid'  => $post_data['ID']
-	  );
+		$content  = '<title>'.stripslashes($post_data['post_title']).'</title>';
+		$content .= '<category>'.$categories.'</category>';
+		$content .= stripslashes($post_data['post_content']);
+
+		$struct = array(
+			'userid'    => $post_data['post_author'],
+			'dateCreated' => new IXR_Date(mysql2date('Ymd\TH:i:s', $post_data['post_date'])),
+			'content'     => $content,
+			'postid'  => $post_data['ID']
+		);
 
-	  return $struct;
+		return $struct;
 	}
 
 
 	/* blogger.getRecentPosts ...gets recent posts */
 	function blogger_getRecentPosts($args) {
 
-	  global $wpdb;
+		global $wpdb;
 
 		$this->escape($args);
 
-	  $blog_ID    = $args[1]; /* though we don't use it yet */
-	  $user_login = $args[2];
-	  $user_pass  = $args[3];
-	  $num_posts  = $args[4];
+		$blog_ID    = (int) $args[1]; /* though we don't use it yet */
+		$user_login = $args[2];
+		$user_pass  = $args[3];
+		$num_posts  = $args[4];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $posts_list = wp_get_recent_posts($num_posts);
+		$posts_list = wp_get_recent_posts($num_posts);
 
-	  if (!$posts_list) {
-	    $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.');
-	    return $this->error;
-	  }
+		if (!$posts_list) {
+			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
+			return $this->error;
+		}
 
-	  foreach ($posts_list as $entry) {
-	  
-	    $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);
-	    $categories = implode(',', wp_get_post_cats(1, $entry['ID']));
+		foreach ($posts_list as $entry) {
 
-	    $content  = '<title>'.stripslashes($entry['post_title']).'</title>';
-	    $content .= '<category>'.$categories.'</category>';
-	    $content .= stripslashes($entry['post_content']);
+			$post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);
+			$categories = implode(',', wp_get_post_categories($entry['ID']));
 
-	    $struct[] = array(
-	      'userid' => $entry['post_author'],
-	      'dateCreated' => new IXR_Date($post_date),
-	      'content' => $content,
-	      'postid' => $entry['ID'],
-	    );
+			$content  = '<title>'.stripslashes($entry['post_title']).'</title>';
+			$content .= '<category>'.$categories.'</category>';
+			$content .= stripslashes($entry['post_content']);
+
+			$struct[] = array(
+				'userid' => $entry['post_author'],
+				'dateCreated' => new IXR_Date($post_date),
+				'content' => $content,
+				'postid' => $entry['ID'],
+			);
 
-	  }
+		}
 
-	  $recent_posts = array();
-	  for ($j=0; $j<count($struct); $j++) {
-	    array_push($recent_posts, $struct[$j]);
-	  }
+		$recent_posts = array();
+		for ($j=0; $j<count($struct); $j++) {
+			array_push($recent_posts, $struct[$j]);
+		}
 
-	  return $recent_posts;
+		return $recent_posts;
 	}
 
 
@@ -291,7 +708,7 @@
 
 		$this->escape($args);
 
-	  $blog_ID    = $args[1];
+	  $blog_ID    = (int) $args[1];
 	  $user_login = $args[2];
 	  $user_pass  = $args[3];
 	  $template   = $args[4]; /* could be 'main' or 'archiveIndex', but we don't use it */
@@ -302,11 +719,11 @@
 
 	  set_current_user(0, $user_login);
 	  if ( !current_user_can('edit_themes') ) {
-	    return new IXR_Error(401, 'Sorry, this user can not edit the template.');
+	    return new IXR_Error(401, __('Sorry, this user can not edit the template.'));
 	  }
 
-	  /* warning: here we make the assumption that the weblog's URI is on the same server */
-	  $filename = get_settings('home') . '/';
+	  /* warning: here we make the assumption that the weblog's URL is on the same server */
+	  $filename = get_option('home') . '/';
 	  $filename = preg_replace('#https?://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename);
 
 	  $f = fopen($filename, 'r');
@@ -325,7 +742,7 @@
 
 		$this->escape($args);
 
-	  $blog_ID    = $args[1];
+	  $blog_ID    = (int) $args[1];
 	  $user_login = $args[2];
 	  $user_pass  = $args[3];
 	  $content    = $args[4];
@@ -337,18 +754,18 @@
 
 	  set_current_user(0, $user_login);
 	  if ( !current_user_can('edit_themes') ) {
-	    return new IXR_Error(401, 'Sorry, this user can not edit the template.');
+	    return new IXR_Error(401, __('Sorry, this user can not edit the template.'));
 	  }
 
-	  /* warning: here we make the assumption that the weblog's URI is on the same server */
-	  $filename = get_settings('home') . '/';
+	  /* warning: here we make the assumption that the weblog's URL is on the same server */
+	  $filename = get_option('home') . '/';
 	  $filename = preg_replace('#https?://.+?/#', $_SERVER['DOCUMENT_ROOT'].'/', $filename);
 
 	  if ($f = fopen($filename, 'w+')) {
 	    fwrite($f, $content);
 	    fclose($f);
 	  } else {
-	    return new IXR_Error(500, 'Either the file is not writable, or something wrong happened. The file has not been updated.');
+	    return new IXR_Error(500, __('Either the file is not writable, or something wrong happened. The file has not been updated.'));
 	  }
 
 	  return true;
@@ -362,7 +779,7 @@
 
 		$this->escape($args);
 
-	  $blog_ID    = $args[1]; /* though we don't use it yet */
+	  $blog_ID    = (int) $args[1]; /* though we don't use it yet */
 	  $user_login = $args[2];
 	  $user_pass  = $args[3];
 	  $content    = $args[4];
@@ -375,7 +792,7 @@
 	  $cap = ($publish) ? 'publish_posts' : 'edit_posts';
 	  $user = set_current_user(0, $user_login);
 	  if ( !current_user_can($cap) )
-	    return new IXR_Error(401, 'Sorry, you can not post on this weblog or category.');
+	    return new IXR_Error(401, __('Sorry, you can not post on this weblog or category.'));
 
 	  $post_status = ($publish) ? 'publish' : 'draft';
 
@@ -393,8 +810,9 @@
 	  $post_ID = wp_insert_post($post_data);
 
 	  if (!$post_ID) {
-	    return new IXR_Error(500, 'Sorry, your entry could not be posted. Something wrong happened.');
+	    return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
 	  }
+	  $this->attach_uploads( $post_ID, $post_content );
 
 	  logIO('O', "Posted ! ID: $post_ID");
 
@@ -409,7 +827,7 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[1];
+	  $post_ID     = (int) $args[1];
 	  $user_login  = $args[2];
 	  $user_pass   = $args[3];
 	  $content     = $args[4];
@@ -422,16 +840,19 @@
 	  $actual_post = wp_get_single_post($post_ID,ARRAY_A);
 
 	  if (!$actual_post) {
-	  	return new IXR_Error(404, 'Sorry, no such post.');
+	  	return new IXR_Error(404, __('Sorry, no such post.'));
 	  }
 
 		$this->escape($actual_post);
 
 	  set_current_user(0, $user_login);
 	  if ( !current_user_can('edit_post', $post_ID) )
-	    return new IXR_Error(401, 'Sorry, you do not have the right to edit this post.');
+	    return new IXR_Error(401, __('Sorry, you do not have the right to edit this post.'));
 
-	  extract($actual_post);
+	  extract($actual_post, EXTR_SKIP);
+
+	  if ( ('publish' == $post_status) && !current_user_can('publish_posts') )
+	  	return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));
 
 	  $post_title = xmlrpc_getposttitle($content);
 	  $post_category = xmlrpc_getpostcategory($content);
@@ -442,8 +863,9 @@
 	  $result = wp_update_post($postdata);
 
 	  if (!$result) {
-	  	return new IXR_Error(500, 'For some strange yet very annoying reason, this post could not be edited.');
+	  	return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be edited.'));
 	  }
+	  $this->attach_uploads( $ID, $post_content );
 
 	  return true;
 	}
@@ -456,7 +878,7 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[1];
+	  $post_ID     = (int) $args[1];
 	  $user_login  = $args[2];
 	  $user_pass   = $args[3];
 	  $publish     = $args[4];
@@ -468,17 +890,17 @@
 	  $actual_post = wp_get_single_post($post_ID,ARRAY_A);
 
 	  if (!$actual_post) {
-	  	return new IXR_Error(404, 'Sorry, no such post.');
+	  	return new IXR_Error(404, __('Sorry, no such post.'));
 	  }
 
 	  set_current_user(0, $user_login);
 	  if ( !current_user_can('edit_post', $post_ID) )
-	    return new IXR_Error(401, 'Sorry, you do not have the right to delete this post.');
+	    return new IXR_Error(401, __('Sorry, you do not have the right to delete this post.'));
 
 	  $result = wp_delete_post($post_ID);
 
 	  if (!$result) {
-	  	return new IXR_Error(500, 'For some strange yet very annoying reason, this post could not be deleted.');
+	  	return new IXR_Error(500, __('For some strange yet very annoying reason, this post could not be deleted.'));
 	  }
 
 	  return true;
@@ -497,7 +919,7 @@
 
 		$this->escape($args);
 
-	  $blog_ID     = $args[0]; // we will support this in the near future
+	  $blog_ID     = (int) $args[0]; // we will support this in the near future
 	  $user_login  = $args[1];
 	  $user_pass   = $args[2];
 	  $content_struct = $args[3];
@@ -507,12 +929,69 @@
 	    return $this->error;
 	  }
 
+      $cap = ($publish) ? 'publish_posts' : 'edit_posts';
 	  $user = set_current_user(0, $user_login);
-	  if ( !current_user_can('publish_posts') )
-	    return new IXR_Error(401, 'Sorry, you can not post on this weblog or category.');
+	  if ( !current_user_can($cap) )
+	    return new IXR_Error(401, __('Sorry, you can not post on this weblog or category.'));
+
+		// The post_type defaults to post, but could also be page.
+		$post_type = "post";
+		if(
+			!empty($content_struct["post_type"])
+			&& ($content_struct["post_type"] == "page")
+		) {
+			$post_type = "page";
+		}
+
+		// Let WordPress generate the post_name (slug) unless
+		// one has been provided.
+		$post_name = "";
+		if(isset($content_struct["wp_slug"])) {
+			$post_name = $content_struct["wp_slug"];
+		}
+
+		// Only use a password if one was given.
+		if(isset($content_struct["wp_password"])) {
+			$post_password = $content_struct["wp_password"];
+		}
+
+		// Only set a post parent if one was provided.
+		if(isset($content_struct["wp_page_parent_id"])) {
+			$post_parent = $content_struct["wp_page_parent_id"];
+		}
+
+		// Only set the menu_order if it was provided.
+		if(isset($content_struct["wp_page_order"])) {
+			$menu_order = $content_struct["wp_page_order"];
+		}
 
 	  $post_author = $user->ID;
 
+		// If an author id was provided then use it instead.
+		if(
+			isset($content_struct["wp_author_id"])
+			&& ($user->ID != $content_struct["wp_author_id"])
+		) {
+			switch($post_type) {
+				case "post":
+					if(!current_user_can("edit_others_posts")) {
+						return(new IXR_Error(401, "You are not allowed to " .
+							"post as this user"));
+					}
+					break;
+				case "page":
+					if(!current_user_can("edit_others_pages")) {
+						return(new IXR_Error(401, "You are not allowed to " .
+							"create pages as this user"));
+					}
+					break;
+				default:
+					return(new IXR_Error(401, __("Invalid post type.")));
+					break;
+			}
+			$post_author = $content_struct["wp_author_id"];
+		}
+
 	  $post_title = $content_struct['title'];
 	  $post_content = apply_filters( 'content_save_pre', $content_struct['description'] );
 	  $post_status = $publish ? 'publish' : 'draft';
@@ -520,26 +999,84 @@
 	  $post_excerpt = $content_struct['mt_excerpt'];
 	  $post_more = $content_struct['mt_text_more'];
 
-	  $comment_status = (empty($content_struct['mt_allow_comments'])) ?
-	    get_settings('default_comment_status')
-	    : $content_struct['mt_allow_comments'];
-
-	  $ping_status = (empty($content_struct['mt_allow_pings'])) ?
-	    get_settings('default_ping_status')
-	    : $content_struct['mt_allow_pings'];
+		if(isset($content_struct["mt_allow_comments"])) {
+			if(!is_numeric($content_struct["mt_allow_comments"])) {
+				switch($content_struct["mt_allow_comments"]) {
+					case "closed":
+						$comment_status = "closed";
+						break;
+					case "open":
+						$comment_status = "open";
+						break;
+					default:
+						$comment_status = get_option("default_comment_status");
+						break;
+				}
+			}
+			else {
+				switch((int) $content_struct["mt_allow_comments"]) {
+					case 0:
+						$comment_status = "closed";
+						break;
+					case 1:
+						$comment_status = "open";
+						break;
+					default:
+						$comment_status = get_option("default_comment_status");
+						break;
+				}
+			}
+		}
+		else {
+			$comment_status = get_option("default_comment_status");
+		}
+
+		if(isset($content_struct["mt_allow_pings"])) {
+			if(!is_numeric($content_struct["mt_allow_pings"])) {
+				switch($content["mt_allow_pings"]) {
+					case "closed":
+						$ping_status = "closed";
+						break;
+					case "open":
+						$ping_status = "open";
+						break;
+					default:
+						$ping_status = get_option("default_ping_status");
+						break;
+				}
+			}
+			else {
+				switch((int) $content_struct["mt_allow_pings"]) {
+					case 0:
+						$ping_status = "closed";
+						break;
+					case 1:
+						$ping_status = "open";
+						break;
+					default:
+						$ping_status = get_option("default_ping_status");
+						break;
+				}
+			}
+		}
+		else {
+			$ping_status = get_option("default_ping_status");
+		}
 
 	  if ($post_more) {
 	    $post_content = $post_content . "\n<!--more-->\n" . $post_more;
 	  }
 
-		$to_ping = $content_struct['mt_tb_ping_urls'];
+	  $to_ping = $content_struct['mt_tb_ping_urls'];
+	  if ( is_array($to_ping) )
+	  	$to_ping = implode(' ', $to_ping);
 
 	  // Do some timestamp voodoo
 	  $dateCreatedd = $content_struct['dateCreated'];
 	  if (!empty($dateCreatedd)) {
 	    $dateCreated = $dateCreatedd->getIso();
 	    $post_date     = get_date_from_gmt(iso8601_to_datetime($dateCreated));
-	    $post_date_gmt = iso8601_to_datetime($dateCreated, GMT);
+	    $post_date_gmt = iso8601_to_datetime($dateCreated. "Z", GMT);
 	  } else {
 	    $post_date     = current_time('mysql');
 	    $post_date_gmt = current_time('mysql', 1);
@@ -554,21 +1091,36 @@
 	      $post_category[] = get_cat_ID($cat);
 	    }
 	  }
-		
+
 	  // We've got all the data -- post it:
-	  $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping');
+	  $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'to_ping', 'post_type', 'post_name', 'post_password', 'post_parent', 'menu_order');
 
 	  $post_ID = wp_insert_post($postdata);
 
 	  if (!$post_ID) {
-	    return new IXR_Error(500, 'Sorry, your entry could not be posted. Something wrong happened.');
+	    return new IXR_Error(500, __('Sorry, your entry could not be posted. Something wrong happened.'));
 	  }
 
+	  $this->attach_uploads( $post_ID, $post_content );
+
 	  logIO('O', "Posted ! ID: $post_ID");
 
 	  return strval($post_ID);
 	}
 
+	function attach_uploads( $post_ID, $post_content ) {
+		global $wpdb;
+
+		// find any unattached files
+		$attachments = $wpdb->get_results( "SELECT ID, guid FROM {$wpdb->posts} WHERE post_parent = '-1' AND post_type = 'attachment'" );
+		if( is_array( $attachments ) ) {
+			foreach( $attachments as $file ) {
+				if( strpos( $post_content, $file->guid ) !== false ) {
+					$wpdb->query( "UPDATE {$wpdb->posts} SET post_parent = '$post_ID' WHERE ID = '{$file->ID}'" );
+				}
+			}
+		}
+	}
 
 	/* metaweblog.editPost ...edits a post */
 	function mw_editPost($args) {
@@ -577,7 +1129,7 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[0];
+	  $post_ID     = (int) $args[0];
 	  $user_login  = $args[1];
 	  $user_pass   = $args[2];
 	  $content_struct = $args[3];
@@ -587,20 +1139,145 @@
 	    return $this->error;
 	  }
 
-	  set_current_user(0, $user_login);
-	  if ( !current_user_can('edit_post', $post_ID) )
-	    return new IXR_Error(401, 'Sorry, you can not edit this post.');
+		$user = set_current_user(0, $user_login);
+
+		// The post_type defaults to post, but could also be page.
+		$post_type = "post";
+		if(
+			!empty($content_struct["post_type"])
+			&& ($content_struct["post_type"] == "page")
+		) {
+			$post_type = "page";
+		}
+
+	  // Edit page caps are checked in editPage.  Just check post here.
+	  if ( ( 'post' == $post_type ) && !current_user_can('edit_post', $post_ID) )
+	    return new IXR_Error(401, __('Sorry, you can not edit this post.'));
 
 	  $postdata = wp_get_single_post($post_ID, ARRAY_A);
-	  extract($postdata);
+
+		// If there is no post data for the give post id, stop
+		// now and return an error.  Other wise a new post will be
+		// created (which was the old behavior).
+		if(empty($postdata["ID"])) {
+			return(new IXR_Error(404, __("Invalid post id.")));
+		}
+
 		$this->escape($postdata);
+		extract($postdata, EXTR_SKIP);
+
+		// Let WordPress manage slug if none was provided.
+		$post_name = "";
+		if(isset($content_struct["wp_slug"])) {
+			$post_name = $content_struct["wp_slug"];
+		}
+
+		// Only use a password if one was given.
+		if(isset($content_struct["wp_password"])) {
+			$post_password = $content_struct["wp_password"];
+		}
+
+		// Only set a post parent if one was given.
+		if(isset($content_struct["wp_page_parent_id"])) {
+			$post_parent = $content_struct["wp_page_parent_id"];
+		}
+
+		// Only set the menu_order if it was given.
+		if(isset($content_struct["wp_page_order"])) {
+			$menu_order = $content_struct["wp_page_order"];
+		}
+
+		$post_author = $postdata["post_author"];
+
+		// Only set the post_author if one is set.
+		if(
+			isset($content_struct["wp_author_id"])
+			&& ($user->ID != $content_struct["wp_author_id"])
+		) {
+			switch($post_type) {
+				case "post":
+					if(!current_user_can("edit_others_posts")) {
+						return(new IXR_Error(401, "You are not allowed to " .
+							"change the post author as this user."));
+					}
+					break;
+				case "page":
+					if(!current_user_can("edit_others_pages")) {
+						return(new IXR_Error(401, "You are not allowed to " .
+							"change the page author as this user."));
+					}
+					break;
+				default:
+					return(new IXR_Error(401, __("Invalid post type.")));
+					break;
+			}
+			$post_author = $content_struct["wp_author_id"];
+		}
+
+		if(isset($content_struct["mt_allow_comments"])) {
+			if(!is_numeric($content_struct["mt_allow_comments"])) {
+				switch($content_struct["mt_allow_comments"]) {
+					case "closed":
+						$comment_status = "closed";
+						break;
+					case "open":
+						$comment_status = "open";
+						break;
+					default:
+						$comment_status = get_option("default_comment_status");
+						break;
+				}
+			}
+			else {
+				switch((int) $content_struct["mt_allow_comments"]) {
+					case 0:
+						$comment_status = "closed";
+						break;
+					case 1:
+						$comment_status = "open";
+						break;
+					default:
+						$comment_status = get_option("default_comment_status");
+						break;
+				}
+			}
+		}
+
+		if(isset($content_struct["mt_allow_pings"])) {
+			if(!is_numeric($content_struct["mt_allow_pings"])) {
+				switch($content["mt_allow_pings"]) {
+					case "closed":
+						$ping_status = "closed";
+						break;
+					case "open":
+						$ping_status = "open";
+						break;
+					default:
+						$ping_status = get_option("default_ping_status");
+						break;
+				}
+			}
+			else {
+				switch((int) $content_struct["mt_allow_pings"]) {
+					case 0:
+						$ping_status = "closed";
+						break;
+					case 1:
+						$ping_status = "open";
+						break;
+					default:
+						$ping_status = get_option("default_ping_status");
+						break;
+				}
+			}
+		}
 
 	  $post_title = $content_struct['title'];
 	  $post_content = apply_filters( 'content_save_pre', $content_struct['description'] );
 	  $catnames = $content_struct['categories'];
 
 	  $post_category = array();
-		
+
 	  if (is_array($catnames)) {
 	    foreach ($catnames as $cat) {
 	      $post_category[] = get_cat_ID($cat);
@@ -611,38 +1288,40 @@
 	  $post_more = $content_struct['mt_text_more'];
 	  $post_status = $publish ? 'publish' : 'draft';
 
+	  if ( ('publish' == $post_status) ) {
+	  	if ( ( 'page' == $post_type ) && !current_user_can('publish_pages') )
+	  		return new IXR_Error(401, __('Sorry, you do not have the right to publish this page.'));
+	  	else if ( !current_user_can('publish_posts') )
+		  	return new IXR_Error(401, __('Sorry, you do not have the right to publish this post.'));
+	  }
+
 	  if ($post_more) {
 	    $post_content = $post_content . "\n<!--more-->\n" . $post_more;
 	  }
 
-		$to_ping = $content_struct['mt_tb_ping_urls'];
-
-	  $comment_status = (empty($content_struct['mt_allow_comments'])) ?
-	    get_settings('default_comment_status')
-	    : $content_struct['mt_allow_comments'];
-
-	  $ping_status = (empty($content_struct['mt_allow_pings'])) ?
-	    get_settings('default_ping_status')
-	    : $content_struct['mt_allow_pings'];
+	  $to_ping = $content_struct['mt_tb_ping_urls'];
+	  if ( is_array($to_ping) )
+	  	$to_ping = implode(' ', $to_ping);
 
 	  // Do some timestamp voodoo
 	  $dateCreatedd = $content_struct['dateCreated'];
 	  if (!empty($dateCreatedd)) {
 	    $dateCreated = $dateCreatedd->getIso();
 	    $post_date     = get_date_from_gmt(iso8601_to_datetime($dateCreated));
-	    $post_date_gmt = iso8601_to_datetime($dateCreated, GMT);
+	    $post_date_gmt = iso8601_to_datetime($dateCreated . "Z", GMT);
 	  } else {
 	    $post_date     = $postdata['post_date'];
 	    $post_date_gmt = $postdata['post_date_gmt'];
 	  }
 
 	  // We've got all the data -- post it:
-	  $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt', 'to_ping');
+	  $newpost = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'comment_status', 'ping_status', 'post_date', 'post_date_gmt', 'to_ping', 'post_name', 'post_password', 'post_parent', 'menu_order', 'post_author');
 
 	  $result = wp_update_post($newpost);
 	  if (!$result) {
-	    return new IXR_Error(500, 'Sorry, your entry could not be edited. Something wrong happened.');
+	    return new IXR_Error(500, __('Sorry, your entry could not be edited. Something wrong happened.'));
 	  }
+	  $this->attach_uploads( $ID, $post_content );
 
 	  logIO('O',"(MW) Edited ! ID: $post_ID");
 
@@ -657,7 +1336,7 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[0];
+	  $post_ID     = (int) $args[0];
 	  $user_login  = $args[1];
 	  $user_pass   = $args[2];
 
@@ -669,10 +1348,10 @@
 
 	  if ($postdata['post_date'] != '') {
 
-	    $post_date = mysql2date('Ymd\TH:i:s', $postdata['post_date']);
+	    $post_date = mysql2date('Ymd\TH:i:s\Z', $postdata['post_date_gmt']);
 
 	    $categories = array();
-	    $catids = wp_get_post_cats('', $post_ID);
+	    $catids = wp_get_post_categories($post_ID);
 	    foreach($catids as $catid) {
 	      $categories[] = get_cat_name($catid);
 	    }
@@ -680,6 +1359,9 @@
 	    $post = get_extended($postdata['post_content']);
 	    $link = post_permalink($postdata['ID']);
 
+		// Get the author info.
+		$author = get_userdata($postdata['post_author']);
+
 	    $allow_comments = ('open' == $postdata['comment_status']) ? 1 : 0;
 	    $allow_pings = ('open' == $postdata['ping_status']) ? 1 : 0;
 
@@ -697,12 +1379,16 @@
 	      'mt_excerpt' => $postdata['post_excerpt'],
 	      'mt_text_more' => $post['extended'],
 	      'mt_allow_comments' => $allow_comments,
-	      'mt_allow_pings' => $allow_pings
+	      'mt_allow_pings' => $allow_pings,
+          'wp_slug' => $postdata['post_name'],
+          'wp_password' => $postdata['post_password'],
+          'wp_author_id' => $author->ID,
+          'wp_author_display_name'	=> $author->display_name
 	    );
 
 	    return $resp;
 	  } else {
-	  	return new IXR_Error(404, 'Sorry, no such post.');
+	  	return new IXR_Error(404, __('Sorry, no such post.'));
 	  }
 	}
 
@@ -712,96 +1398,104 @@
 
 		$this->escape($args);
 
-	  $blog_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
-	  $num_posts   = $args[3];
+		$blog_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
+		$num_posts   = (int) $args[3];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $posts_list = wp_get_recent_posts($num_posts);
+		$posts_list = wp_get_recent_posts($num_posts);
 
-	  if (!$posts_list) {
-	    $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.');
-	    return $this->error;
-	  }
+		if (!$posts_list) {
+			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
+			return $this->error;
+		}
 
-	  foreach ($posts_list as $entry) {
-	  
-	    $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);
-	    $categories = array();
-	    $catids = wp_get_post_cats('', $entry['ID']);
-	    foreach($catids as $catid) {
-	      $categories[] = get_cat_name($catid);
-	    }
+		foreach ($posts_list as $entry) {
 
-	    $post = get_extended($entry['post_content']);
-	    $link = post_permalink($entry['ID']);
+			$post_date = mysql2date('Ymd\TH:i:s\Z', $entry['post_date_gmt']);
+			$categories = array();
+			$catids = wp_get_post_categories($entry['ID']);
+			foreach($catids as $catid) {
+				$categories[] = get_cat_name($catid);
+			}
 
-	    $allow_comments = ('open' == $entry['comment_status']) ? 1 : 0;
-	    $allow_pings = ('open' == $entry['ping_status']) ? 1 : 0;
+			$post = get_extended($entry['post_content']);
+			$link = post_permalink($entry['ID']);
 
-	    $struct[] = array(
-	      'dateCreated' => new IXR_Date($post_date),
-	      'userid' => $entry['post_author'],
-	      'postid' => $entry['ID'],
-	      'description' => $post['main'],
-	      'title' => $entry['post_title'],
-	      'link' => $link,
-	      'permaLink' => $link,
+			// Get the post author info.
+			$author = get_userdata($entry['post_author']);
+
+			$allow_comments = ('open' == $entry['comment_status']) ? 1 : 0;
+			$allow_pings = ('open' == $entry['ping_status']) ? 1 : 0;
+
+			$struct[] = array(
+				'dateCreated' => new IXR_Date($post_date),
+				'userid' => $entry['post_author'],
+				'postid' => $entry['ID'],
+				'description' => $post['main'],
+				'title' => $entry['post_title'],
+				'link' => $link,
+				'permaLink' => $link,
 // commented out because no other tool seems to use this
 //	      'content' => $entry['post_content'],
-	      'categories' => $categories,
-	      'mt_excerpt' => $entry['post_excerpt'],
-	      'mt_text_more' => $post['extended'],
-	      'mt_allow_comments' => $allow_comments,
-	      'mt_allow_pings' => $allow_pings
-	    );
+				'categories' => $categories,
+				'mt_excerpt' => $entry['post_excerpt'],
+				'mt_text_more' => $post['extended'],
+				'mt_allow_comments' => $allow_comments,
+				'mt_allow_pings' => $allow_pings,
+				'wp_slug' => $entry['post_name'],
+				'wp_password' => $entry['post_password'],
+				'wp_author_id' => $author->ID,
+				'wp_author_display_name' => $author->display_name
+			);
 
-	  }
+		}
 
-	  $recent_posts = array();
-	  for ($j=0; $j<count($struct); $j++) {
-	    array_push($recent_posts, $struct[$j]);
-	  }
-	  
-	  return $recent_posts;
+		$recent_posts = array();
+		for ($j=0; $j<count($struct); $j++) {
+			array_push($recent_posts, $struct[$j]);
+		}
+
+		return $recent_posts;
 	}
 
 
 	/* metaweblog.getCategories ...returns the list of categories on a given weblog */
 	function mw_getCategories($args) {
 
-	  global $wpdb;
+		global $wpdb;
 
 		$this->escape($args);
 
-	  $blog_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
+		$blog_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $categories_struct = array();
+		$categories_struct = array();
 
-	  // FIXME: can we avoid using direct SQL there?
-	  if ($cats = $wpdb->get_results("SELECT cat_ID,cat_name FROM $wpdb->categories", ARRAY_A)) {
-	    foreach ($cats as $cat) {
-	      $struct['categoryId'] = $cat['cat_ID'];
-	      $struct['description'] = $cat['cat_name'];
-	      $struct['categoryName'] = $cat['cat_name'];
-	      $struct['htmlUrl'] = wp_specialchars(get_category_link($cat['cat_ID']));
-	      $struct['rssUrl'] = wp_specialchars(get_category_rss_link(false, $cat['cat_ID'], $cat['cat_name']));
+		// FIXME: can we avoid using direct SQL there?
+		if ($cats = $wpdb->get_results("SELECT cat_ID,cat_name,category_parent FROM $wpdb->categories", ARRAY_A)) {
+			foreach ($cats as $cat) {
+				$struct['categoryId'] = $cat['cat_ID'];
+				$struct['parentId'] = $cat['category_parent'];
+				$struct['description'] = $cat['cat_name'];
+				$struct['categoryName'] = $cat['cat_name'];
+				$struct['htmlUrl'] = wp_specialchars(get_category_link($cat['cat_ID']));
+				$struct['rssUrl'] = wp_specialchars(get_category_rss_link(false, $cat['cat_ID'], $cat['cat_name']));
 
-	      $categories_struct[] = $struct;
-	    }
-	  }
+				$categories_struct[] = $struct;
+			}
+		}
 
-	  return $categories_struct;
+		return $categories_struct;
 	}
 
 
@@ -812,12 +1506,12 @@
 
 		global $wpdb;
 
-		$blog_ID     = $wpdb->escape($args[0]);
+		$blog_ID     = (int) $args[0];
 		$user_login  = $wpdb->escape($args[1]);
 		$user_pass   = $wpdb->escape($args[2]);
 		$data        = $args[3];
 
-		$name = $data['name'];
+		$name = sanitize_file_name( $data['name'] );
 		$type = $data['type'];
 		$bits = $data['bits'];
 
@@ -829,17 +1523,54 @@
 		set_current_user(0, $user_login);
 		if ( !current_user_can('upload_files') ) {
 			logIO('O', '(MW) User does not have upload_files capability');
-			$this->error = new IXR_Error(401, 'You are not allowed to upload files to this site.');
+			$this->error = new IXR_Error(401, __('You are not allowed to upload files to this site.'));
 			return $this->error;
 		}
 
-		$upload = wp_upload_bits($name, $type, $bits);
+		if ( $upload_err = apply_filters( "pre_upload_error", false ) )
+			return new IXR_Error(500, $upload_err);
+
+		if(!empty($data["overwrite"]) && ($data["overwrite"] == true)) {
+			// Get postmeta info on the object.
+			$old_file = $wpdb->get_row("
+				SELECT ID
+				FROM {$wpdb->posts}
+				WHERE post_title = '{$name}'
+					AND post_type = 'attachment'
+			");
+
+			// Delete previous file.
+			wp_delete_attachment($old_file->ID);
+
+			// Make sure the new name is different by pre-pending the
+			// previous post id.
+			$filename = preg_replace("/^wpid\d+-/", "", $name);
+			$name = "wpid{$old_file->ID}-{$filename}";
+		}
+
+		$upload = wp_upload_bits($name, $type, $bits, $overwrite);
 		if ( ! empty($upload['error']) ) {
-			logIO('O', '(MW) Could not write file '.$name);
-			return new IXR_Error(500, 'Could not write file '.$name);
+			$errorString = 'Could not write file ' . $name . ' (' . $upload['error'] . ')';
+			logIO('O', '(MW) ' . $errorString);
+			return new IXR_Error(500, $errorString);
 		}
-		
-		return array('url' => $upload['url']);
+		// Construct the attachment array
+		// attach to post_id -1
+		$post_id = -1;
+		$attachment = array(
+			'post_title' => $name,
+			'post_content' => '',
+			'post_type' => 'attachment',
+			'post_parent' => $post_id,
+			'post_mime_type' => $type,
+			'guid' => $upload[ 'url' ]
+		);
+
+		// Save the data
+		$id = wp_insert_attachment( $attachment, $upload[ 'file' ], $post_id );
+		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
+
+		return apply_filters( 'wp_handle_upload', array( 'file' => $name, 'url' => $upload[ 'url' ], 'type' => $type ) );
 	}
 
 
@@ -852,72 +1583,72 @@
 
 		$this->escape($args);
 
-	  $blog_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
-	  $num_posts   = $args[3];
+		$blog_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
+		$num_posts   = (int) $args[3];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $posts_list = wp_get_recent_posts($num_posts);
+		$posts_list = wp_get_recent_posts($num_posts);
 
-	  if (!$posts_list) {
-	    $this->error = new IXR_Error(500, 'Either there are no posts, or something went wrong.');
-	    return $this->error;
-	  }
+		if (!$posts_list) {
+			$this->error = new IXR_Error(500, __('Either there are no posts, or something went wrong.'));
+			return $this->error;
+		}
 
-	  foreach ($posts_list as $entry) {
-	  
-	    $post_date = mysql2date('Ymd\TH:i:s', $entry['post_date']);
+		foreach ($posts_list as $entry) {
 
-	    $struct[] = array(
-	      'dateCreated' => new IXR_Date($post_date),
-	      'userid' => $entry['post_author'],
-	      'postid' => $entry['ID'],
-	      'title' => $entry['post_title'],
-	    );
+			$post_date = mysql2date('Ymd\TH:i:s\Z', $entry['post_date_gmt']);
 
-	  }
+			$struct[] = array(
+				'dateCreated' => new IXR_Date($post_date),
+				'userid' => $entry['post_author'],
+				'postid' => $entry['ID'],
+				'title' => $entry['post_title'],
+			);
 
-	  $recent_posts = array();
-	  for ($j=0; $j<count($struct); $j++) {
-	    array_push($recent_posts, $struct[$j]);
-	  }
-	  
-	  return $recent_posts;
+		}
+
+		$recent_posts = array();
+		for ($j=0; $j<count($struct); $j++) {
+			array_push($recent_posts, $struct[$j]);
+		}
+
+		return $recent_posts;
 	}
 
 
 	/* mt.getCategoryList ...returns the list of categories on a given weblog */
 	function mt_getCategoryList($args) {
 
-	  global $wpdb;
+		global $wpdb;
 
 		$this->escape($args);
 
-	  $blog_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
+		$blog_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $categories_struct = array();
+		$categories_struct = array();
 
-	  // FIXME: can we avoid using direct SQL there?
-	  if ($cats = $wpdb->get_results("SELECT cat_ID, cat_name FROM $wpdb->categories", ARRAY_A)) {
-	    foreach ($cats as $cat) {
-	      $struct['categoryId'] = $cat['cat_ID'];
-	      $struct['categoryName'] = $cat['cat_name'];
+		// FIXME: can we avoid using direct SQL there?
+		if ($cats = $wpdb->get_results("SELECT cat_ID, cat_name FROM $wpdb->categories", ARRAY_A)) {
+			foreach ($cats as $cat) {
+				$struct['categoryId'] = $cat['cat_ID'];
+				$struct['categoryName'] = $cat['cat_name'];
 
-	      $categories_struct[] = $struct;
-	    }
-	  }
+				$categories_struct[] = $struct;
+			}
+		}
 
-	  return $categories_struct;
+		return $categories_struct;
 	}
 
 
@@ -926,28 +1657,28 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
+		$post_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  $categories = array();
-	  $catids = wp_get_post_cats('', intval($post_ID));
-	  // first listed category will be the primary category
-	  $isPrimary = true;
-	  foreach($catids as $catid) {
-	    $categories[] = array(
-	      'categoryName' => get_cat_name($catid),
-	      'categoryId' => $catid,
-	      'isPrimary' => $isPrimary
-	    );
-	    $isPrimary = false;
-	  }
- 
-	  return $categories;
+		$categories = array();
+		$catids = wp_get_post_categories(intval($post_ID));
+		// first listed category will be the primary category
+		$isPrimary = true;
+		foreach($catids as $catid) {
+			$categories[] = array(
+				'categoryName' => get_cat_name($catid),
+				'categoryId' => (string) $catid,
+				'isPrimary' => $isPrimary
+			);
+			$isPrimary = false;
+		}
+
+		return $categories;
 	}
 
 
@@ -956,81 +1687,81 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
-	  $categories  = $args[3];
+		$post_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
+		$categories  = $args[3];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  set_current_user(0, $user_login);
-	  if ( !current_user_can('edit_post', $post_ID) )
-	    return new IXR_Error(401, 'Sorry, you can not edit this post.');
+		set_current_user(0, $user_login);
+		if ( !current_user_can('edit_post', $post_ID) )
+			return new IXR_Error(401, __('Sorry, you can not edit this post.'));
 
-	  foreach($categories as $cat) {
-	    $catids[] = $cat['categoryId'];
-	  }
-	
-	  wp_set_post_cats('', $post_ID, $catids);
+		foreach($categories as $cat) {
+			$catids[] = $cat['categoryId'];
+		}
 
-	  return true;
+		wp_set_post_categories($post_ID, $catids);
+
+		return true;
 	}
 
 
 	/* mt.supportedMethods ...returns an array of methods supported by this server */
 	function mt_supportedMethods($args) {
 
-	  $supported_methods = array();
-	  foreach($this->methods as $key=>$value) {
-	    $supported_methods[] = $key;
-	  }
+		$supported_methods = array();
+		foreach($this->methods as $key=>$value) {
+			$supported_methods[] = $key;
+		}
 
-	  return $supported_methods;
+		return $supported_methods;
 	}
 
 
 	/* mt.supportedTextFilters ...returns an empty array because we don't
-	   support per-post text filters yet */
+		 support per-post text filters yet */
 	function mt_supportedTextFilters($args) {
-	  return array();
+		return apply_filters('xmlrpc_text_filters', array());
 	}
 
 
 	/* mt.getTrackbackPings ...returns trackbacks sent to a given post */
 	function mt_getTrackbackPings($args) {
 
-	  global $wpdb;
+		global $wpdb;
 
-	  $post_ID = intval($args);
+		$post_ID = intval($args);
 
-	  $actual_post = wp_get_single_post($post_ID, ARRAY_A);
+		$actual_post = wp_get_single_post($post_ID, ARRAY_A);
 
-	  if (!$actual_post) {
-	  	return new IXR_Error(404, 'Sorry, no such post.');
-	  }
+		if (!$actual_post) {
+			return new IXR_Error(404, __('Sorry, no such post.'));
+		}
 
-	  $comments = $wpdb->get_results("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = $post_ID");
+		$comments = $wpdb->get_results("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = $post_ID");
 
-	  if (!$comments) {
-	  	return array();
-	  }
+		if (!$comments) {
+			return array();
+		}
 
-	  $trackback_pings = array();
-	  foreach($comments as $comment) {
-	    if ( 'trackback' == $comment->comment_type ) {
-	      $content = $comment->comment_content;
-	      $title = substr($content, 8, (strpos($content, '</strong>') - 8));
-	      $trackback_pings[] = array(
-	        'pingTitle' => $title,
-	        'pingURL'   => $comment->comment_author_url,
-	        'pingIP'    => $comment->comment_author_IP
-	      );
+		$trackback_pings = array();
+		foreach($comments as $comment) {
+			if ( 'trackback' == $comment->comment_type ) {
+				$content = $comment->comment_content;
+				$title = substr($content, 8, (strpos($content, '</strong>') - 8));
+				$trackback_pings[] = array(
+					'pingTitle' => $title,
+					'pingURL'   => $comment->comment_author_url,
+					'pingIP'    => $comment->comment_author_IP
+				);
+		}
 		}
-	  }
 
-	  return $trackback_pings;
+		return $trackback_pings;
 	}
 
 
@@ -1039,30 +1770,30 @@
 
 		$this->escape($args);
 
-	  $post_ID     = $args[0];
-	  $user_login  = $args[1];
-	  $user_pass   = $args[2];
+		$post_ID     = (int) $args[0];
+		$user_login  = $args[1];
+		$user_pass   = $args[2];
 
-	  if (!$this->login_pass_ok($user_login, $user_pass)) {
-	    return $this->error;
-	  }
+		if (!$this->login_pass_ok($user_login, $user_pass)) {
+			return $this->error;
+		}
 
-	  set_current_user(0, $user_login);
-	  if ( !current_user_can('edit_post', $post_ID) )
-	    return new IXR_Error(401, 'Sorry, you can not edit this post.');
+		set_current_user(0, $user_login);
+		if ( !current_user_can('edit_post', $post_ID) )
+			return new IXR_Error(401, __('Sorry, you can not edit this post.'));
 
-	  $postdata = wp_get_single_post($post_ID,ARRAY_A);
+		$postdata = wp_get_single_post($post_ID,ARRAY_A);
 
-	  $postdata['post_status'] = 'publish';
+		$postdata['post_status'] = 'publish';
 
-	  // retain old cats
-	  $cats = wp_get_post_cats('',$post_ID);
-	  $postdata['post_category'] = $cats;
+		// retain old cats
+		$cats = wp_get_post_categories($post_ID);
+		$postdata['post_category'] = $cats;
 		$this->escape($postdata);
 
-	  $result = wp_update_post($postdata);
+		$result = wp_update_post($postdata);
 
-	  return $result;
+		return $result;
 	}
 
 
@@ -1073,7 +1804,7 @@
 
 	/* pingback.ping gets a pingback and registers it */
 	function pingback_ping($args) {
-		global $wpdb, $wp_version; 
+		global $wpdb, $wp_version;
 
 		$this->escape($args);
 
@@ -1088,9 +1819,9 @@
 		$error_code = -1;
 
 		// Check if the page linked to is in our site
-		$pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_settings('home')));
+		$pos1 = strpos($pagelinkedto, str_replace(array('http://www.','http://','https://www.','https://'), '', get_option('home')));
 		if( !$pos1 )
-	  		return new IXR_Error(0, 'Is there no link to us?');
+				return new IXR_Error(0, __('Is there no link to us?'));
 
 		// let's find which post is linked to
 		// FIXME: does url_to_postid() cover all these cases already?
@@ -1101,18 +1832,18 @@
 		} elseif (preg_match('#p/[0-9]{1,}#', $urltest['path'], $match)) {
 			// the path defines the post_ID (archives/p/XXXX)
 			$blah = explode('/', $match[0]);
-			$post_ID = $blah[1];
+			$post_ID = (int) $blah[1];
 			$way = 'from the path';
 		} elseif (preg_match('#p=[0-9]{1,}#', $urltest['query'], $match)) {
 			// the querystring defines the post_ID (?p=XXXX)
 			$blah = explode('=', $match[0]);
-			$post_ID = $blah[1];
+			$post_ID = (int) $blah[1];
 			$way = 'from the querystring';
 		} elseif (isset($urltest['fragment'])) {
 			// an #anchor is there, it's either...
 			if (intval($urltest['fragment'])) {
 				// ...an integer #XXXX (simpliest case)
-				$post_ID = $urltest['fragment'];
+				$post_ID = (int) $urltest['fragment'];
 				$way = 'from the fragment (numeric)';
 			} elseif (preg_match('/post-[0-9]+/',$urltest['fragment'])) {
 				// ...a post id in the form 'post-###'
@@ -1130,30 +1861,30 @@
 			}
 		} else {
 			// TODO: Attempt to extract a post ID from the given URL
-	  		return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
+	  		return new IXR_Error(33, 'The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
 		}
 		$post_ID = (int) $post_ID;
 
 
-		logIO("O","(PB) URI='$pagelinkedto' ID='$post_ID' Found='$way'");
+		logIO("O","(PB) URL='$pagelinkedto' ID='$post_ID' Found='$way'");
 
 		$post = get_post($post_ID);
 
 		if ( !$post ) // Post_ID not found
-	  		return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
+	  		return new IXR_Error(33, 'The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
 
 		if ( $post_ID == url_to_postid($pagelinkedfrom) )
-			return new IXR_Error(0, 'The source URI and the target URI cannot both point to the same resource.');
+			return new IXR_Error(0, __('The source URL and the target URL cannot both point to the same resource.'));
 
 		// Check if pings are on
 		if ( 'closed' == $post->ping_status )
-	  		return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
+	  		return new IXR_Error(33, 'The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
 
 		// Let's check that the remote site didn't already pingback this entry
 		$result = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = '$post_ID' AND comment_author_url = '$pagelinkedfrom'");
 
 		if ( $wpdb->num_rows ) // We already have a Pingback from this URL
-	  		return new IXR_Error(48, 'The pingback has already been registered.');
+	  		return new IXR_Error(48, __('The pingback has already been registered.'));
 
 		// very stupid, but gives time to the 'from' server to publish !
 		sleep(1);
@@ -1161,7 +1892,7 @@
 		// Let's check the remote site
 		$linea = wp_remote_fopen( $pagelinkedfrom );
 		if ( !$linea )
-	  		return new IXR_Error(16, 'The source URI does not exist.');
+	  		return new IXR_Error(16, __('The source URL does not exist.'));
 
 		// Work around bug in strip_tags():
 		$linea = str_replace('<!DOC', '<DOC', $linea);
@@ -1171,32 +1902,43 @@
 		preg_match('|<title>([^<]*?)</title>|is', $linea, $matchtitle);
 		$title = $matchtitle[1];
 		if ( empty( $title ) )
-			return new IXR_Error(32, 'We cannot find a title on that page.');
+			return new IXR_Error(32, __('We cannot find a title on that page.'));
 
 		$linea = strip_tags( $linea, '<a>' ); // just keep the tag we need
 
 		$p = explode( "\n\n", $linea );
-		
-		$sem_regexp_pb = "/(\\/|\\\|\*|\?|\+|\.|\^|\\$|\(|\)|\[|\]|\||\{|\})/";
-		$sem_regexp_fix = "\\\\$1";
-		$link = preg_replace( $sem_regexp_pb, $sem_regexp_fix, $pagelinkedfrom );
-		
-		$finished = false;
+
+		$preg_target = preg_quote($pagelinkedto);
+
 		foreach ( $p as $para ) {
-			if ( $finished )
-				continue;
-			if ( strstr( $para, $pagelinkedto ) ) {
-				$context = preg_replace( "/.*<a[^>]+".$link."[^>]*>([^>]+)<\/a>.*/", "$1", $para );
-				$excerpt = strip_tags( $para );
-				$excerpt = trim( $excerpt );
-				$use     = preg_quote( $context );
-				$excerpt = preg_replace("|.*?\s(.{0,100}$use.{0,100})\s|s", "$1", $excerpt);
-				$finished = true;
+			if ( strpos($para, $pagelinkedto) !== false ) { // it exists, but is it a link?
+				preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context);
+
+				// If the URL isn't in a link context, keep looking
+				if ( empty($context) )
+					continue;
+
+				// We're going to use this fake tag to mark the context in a bit
+				// the marker is needed in case the link text appears more than once in the paragraph
+				$excerpt = preg_replace('|\</?wpcontext\>|', '', $para);
+
+				// prevent really long link text
+				if ( strlen($context[1]) > 100 )
+					$context[1] = substr($context[1], 0, 100) . '...';
+
+				$marker = '<wpcontext>'.$context[1].'</wpcontext>';    // set up our marker
+				$excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker
+				$excerpt = strip_tags($excerpt, '<wpcontext>');        // strip all tags but our context marker
+				$excerpt = trim($excerpt);
+				$preg_marker = preg_quote($marker);
+				$excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt);
+				$excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper
+				break;
 			}
 		}
 
-		if ( empty($context) ) // URL pattern not found
-			return new IXR_Error(17, 'The source URI does not contain a link to the target URI, and so cannot be used as a source.');
+		if ( empty($context) ) // Link to target not found
+			return new IXR_Error(17, __('The source URL does not contain a link to the target URL, and so cannot be used as a source.'));
 
 		$pagelinkedfrom = preg_replace('#&([^amp\;])#is', '&amp;$1', $pagelinkedfrom);
 
@@ -1215,16 +1957,16 @@
 
 		$commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_url', 'comment_content', 'comment_type');
 
-		wp_new_comment($commentdata);
-		do_action('pingback_post', $wpdb->insert_id);
-		
+		$comment_ID = wp_new_comment($commentdata);
+		do_action('pingback_post', $comment_ID);
+
 		return "Pingback from $pagelinkedfrom to $pagelinkedto registered. Keep the web talking! :-)";
 	}
 
 
 	/* pingback.extensions.getPingbacks returns an array of URLs
-	   that pingbacked the given URL
-	   specs on http://www.aquarionics.com/misc/archives/blogite/0198.html */
+	that pingbacked the given URL
+	specs on http://www.aquarionics.com/misc/archives/blogite/0198.html */
 	function pingback_extensions_getPingbacks($args) {
 
 		global $wpdb;
@@ -1236,14 +1978,14 @@
 		$post_ID = url_to_postid($url);
 		if (!$post_ID) {
 			// We aren't sure that the resource is available and/or pingback enabled
-	  		return new IXR_Error(33, 'The specified target URI cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
+	  		return new IXR_Error(33, 'The specified target URL cannot be used as a target. It either doesn\'t exist, or it is not a pingback-enabled resource.');
 		}
 
 		$actual_post = wp_get_single_post($post_ID, ARRAY_A);
 
 		if (!$actual_post) {
 			// No such post = resource not found
-	  		return new IXR_Error(32, 'The specified target URI does not exist.');
+	  		return new IXR_Error(32, __('The specified target URL does not exist.'));
 		}
 
 		$comments = $wpdb->get_results("SELECT comment_author_url, comment_content, comment_author_IP, comment_type FROM $wpdb->comments WHERE comment_post_ID = $post_ID");
