diff --git a/wp-content/plugins/feedwordpress/admin-ui.php b/wp-content/plugins/feedwordpress/admin-ui.php
index d9eee616d283643e4ec5e95f9f7e0c611ae01f50..8256a9450edad44fab9001379747f73bad771cee 100644
--- a/wp-content/plugins/feedwordpress/admin-ui.php
+++ b/wp-content/plugins/feedwordpress/admin-ui.php
@@ -50,7 +50,7 @@ class FeedWordPressAdminPage {
 		elseif ($this->save_requested_in($post)) : // User mashed Save Changes
 			$this->save_settings($post);
 		endif;
-		do_action($this->dispatch.'_post', &$post, &$this);		
+		do_action($this->dispatch.'_post', $post, $this);		
 	}
 
 	function update_feed () {
@@ -81,7 +81,7 @@ class FeedWordPressAdminPage {
 	}
 
 	function save_settings ($post) {
-		do_action($this->dispatch.'_save', &$post, &$this);
+		do_action($this->dispatch.'_save', $post, $this);
 
 		if ($this->for_feed_settings()) :
 			// Save settings
@@ -163,12 +163,12 @@ class FeedWordPressAdminPage {
 		);
 		foreach ($submit_buttons as $field) :
 			if (isset($fwp_post[$field])) :
-				$link_id = $_REQUEST['save_link_id'];
+				$link_id = MyPHP::request('save_link_id');
 			endif;
 		endforeach;
 		
 		if (is_null($link_id) and isset($_REQUEST['link_id'])) :
-			$link_id = $_REQUEST['link_id'];
+			$link_id = MyPHP::request('link_id');
 		endif;
 
 		return $link_id;
@@ -187,7 +187,7 @@ class FeedWordPressAdminPage {
 	function stamp_link_id ($field = null) {
 		if (is_null($field)) : $field = 'save_link_id'; endif;
 		?>
-	<input type="hidden" name="<?php print esc_html($field); ?>" value="<?php print ($this->for_feed_settings() ? $this->link->id : '*'); ?>" />
+	<input type="hidden" name="<?php print esc_attr($field); ?>" value="<?php print ($this->for_feed_settings() ? $this->link->id : '*'); ?>" />
 		<?php
 	} /* FeedWordPressAdminPage::stamp_link_id () */
 
@@ -257,7 +257,7 @@ class FeedWordPressAdminPage {
 			"Feed" => array('page' => 'feeds-page.php', 'long' => 'Feeds & Updates'),
 			"Posts" => array('page' => 'posts-page.php', 'long' => 'Posts & Links'),
 			"Authors" => array('page' => 'authors-page.php', 'long' => 'Authors'),
-			'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories'.FEEDWORDPRESS_AND_TAGS),
+			'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories & Tags'),
 		);
 		
 		$hrefPrefix = 'admin.php?';
@@ -444,7 +444,7 @@ class FeedWordPressAdminPage {
 			add_meta_box(
 				/*id=*/ $id,
 				/*title=*/ $title,
-				/*callback=*/ array(&$this, $method),
+				/*callback=*/ array($this, $method),
 				/*page=*/ $this->meta_box_context(),
 				/*context=*/ $this->meta_box_context()
 			);
@@ -732,17 +732,10 @@ function fwp_option_box_opener ($legend, $id, $class = "stuffbox") {
 }
 
 function fwp_option_box_closer () {
-	global $wp_db_version;
-	if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
 ?>
 	</div> <!-- class="inside" -->
 	</div> <!-- class="stuffbox" -->
 <?php
-	else :
-?>
-	</div> <!-- class="wrap" -->
-<?php
-	endif;
 }
 
 function fwp_tags_box ($tags, $object, $params = array()) {
@@ -853,11 +846,6 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
 	<?php
 	$newcat = 'new'.$taxonomy;
 	
-	// Well, thank God they added "egory" before WP 3.0 came out.
-	if ('newcategory'==$newcat
-	and !FeedWordPressCompatibility::test_version(FWP_SCHEMA_30)) :
-		$newcat = 'newcat';
-	endif;
 	?>
     <label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>"><?php _e('Add New Category'); ?></label>
     <input
@@ -880,7 +868,7 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
 		'show_option_none' => __('Parent category'),
 		'tab_index' => 3,
     ) ); ?>
-	<input type="button" id="<?php print $idPrefix; ?><?php print $taxonomy; ?>-add-sumbit" class="add:<?php print $idPrefix; ?><?php print $taxonomy; ?>checklist:<?php print $taxonomy; ?>-add add-categorychecklist-category-add button category-add-submit" value="<?php _e( 'Add' ); ?>" tabindex="3" />
+	<input type="button" id="<?php print $idPrefix; ?><?php print $taxonomy; ?>-add-sumbit" class="add:<?php print $idPrefix; ?><?php print $taxonomy; ?>checklist:<?php print $idPrefix.$taxonomy; ?>-add add-categorychecklist-category-add button category-add-submit" value="<?php _e( 'Add' ); ?>" tabindex="3" />
 	<?php /* wp_nonce_field currently doesn't let us set an id different from name, but we need a non-unique name and a unique id */ ?>
 	<input type="hidden" id="_ajax_nonce<?php print esc_html($idSuffix); ?>" name="_ajax_nonce" value="<?php print wp_create_nonce('add-'.$taxonomy); ?>" />
 	<input type="hidden" id="_ajax_nonce-add-<?php print $taxonomy; ?><?php print esc_html($idSuffix); ?>" name="_ajax_nonce-add-<?php print $taxonomy; ?>" value="<?php print wp_create_nonce('add-'.$taxonomy); ?>" />
@@ -945,9 +933,6 @@ class FeedWordPressSettingsUI {
 		global $fwp_path;
 	
 		wp_enqueue_script('post'); // for magic tag and category boxes
-		if (!FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) : // < 2.9
-			wp_enqueue_script('thickbox'); // for fold-up boxes
-		endif;
 		wp_enqueue_script('admin-forms'); // for checkbox selection
 	
 		wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
@@ -1118,8 +1103,17 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 				endif;
 
 				// Prep: get last error timestamp, if any
+				$fileSizeLines = array();
 				if (is_null($sLink->setting('update/error'))) :
 					$errorsSince = '';
+					if (!is_null($sLink->setting('link/item count'))) :
+						$N = $sLink->setting('link/item count');	
+						$fileSizeLines[] = sprintf((($N==1) ? __('%d item') : __('%d items')), $N);
+					endif;
+
+					if (!is_null($sLink->setting('link/filesize'))) :
+						$fileSizeLines[] = size_format($sLink->setting('link/filesize')). ' total';
+					endif;
 				else :
 					$trClass[] = 'feed-error';
 
@@ -1173,6 +1167,11 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 				endif;
 				$nextUpdate .= "</div></div>";
 
+				$fileSize = '';
+				if (count($fileSizeLines) > 0) :
+					$fileSize = '<div>'.implode(" / ", $fileSizeLines)."</div>";
+				endif;
+				
 				unset($sLink);
 				
 				$alt_row = !$alt_row;
@@ -1221,6 +1220,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 	<input type="submit" class="button" name="update_uri[<?php print esc_html($link->link_rss); ?>]" value="<?php _e('Update Now'); ?>" />
 	</div>
 	<?php print $lastUpdated; ?>
+	<?php print $fileSize; ?>
 	<?php print $errorsSince; ?>
 	<?php print $nextUpdate; ?>
 	</td>
diff --git a/wp-content/plugins/feedwordpress/categories-page.php b/wp-content/plugins/feedwordpress/categories-page.php
index 823713ccb9c29d35b774aff21d65eaa3cc88ee33..528a81ef8d306ce77fcd1e992091e6674afc4203 100644
--- a/wp-content/plugins/feedwordpress/categories-page.php
+++ b/wp-content/plugins/feedwordpress/categories-page.php
@@ -10,9 +10,9 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 		FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
 		$this->dispatch = 'feedwordpress_admin_page_categories';
 		$this->pagenames = array(
-			'default' => 'Categories'.FEEDWORDPRESS_AND_TAGS,
-			'settings-update' => 'Syndicated Categories'.FEEDWORDPRESS_AND_TAGS,
-			'open-sheet' => 'Categories'.FEEDWORDPRESS_AND_TAGS,
+			'default' => 'Categories & Tags',
+			'settings-update' => 'Syndicated Categories & Tags',
+			'open-sheet' => 'Categories & Tags',
 		);
 		$this->filename = __FILE__;
 	}
@@ -599,12 +599,9 @@ blank.</p></td>
 		////////////////////////////////////////////////
 	
 		$this->boxes_by_methods = array(
-			'feed_categories_box' => __('Feed Categories'.FEEDWORDPRESS_AND_TAGS),
+			'feed_categories_box' => __('Feed Categories & Tags'),
 			'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
 		);
-		if (!FeedWordPressCompatibility::post_tags()) :
-			unset($this->boxes_by_methods['tags_box']);
-		endif;
 
 		parent::display();	
 	}
diff --git a/wp-content/plugins/feedwordpress/compatability.php b/wp-content/plugins/feedwordpress/compatability.php
index 0099488a14581ed2c9a88317473912c94ccd1b90..6b62752f2e104146073898ab5f52fbae469bb642 100644
--- a/wp-content/plugins/feedwordpress/compatability.php
+++ b/wp-content/plugins/feedwordpress/compatability.php
@@ -69,10 +69,6 @@ class FeedWordPressCompatibility {
 		return $cat_id;
 	} /* FeedWordPressCompatibility::link_category_id () */
 
-	/*static*/ function post_tags () {
-		return FeedWordPressCompatibility::test_version(FWP_SCHEMA_23);
-	} /* FeedWordPressCompatibility::post_tags () */
-
 	/*static*/ function validate_http_request ($action = -1, $capability = null) {
 		// Only worry about this if we're using a method with significant side-effects
 		if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') :
@@ -102,47 +98,11 @@ class FeedWordPressCompatibility {
 	/*static*/ function bottom_script_hook ($filename) {
 		global $fwp_path;
 
-		$hook = 'admin_footer';
-		if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_28)) : // WordPress 2.8+
-			$hook = $hook . '-' . $fwp_path . '/' . basename($filename);
-		endif;
+		$hook = 'admin_footer-'.$fwp_path.'/'.basename($filename);
 		return $hook;
 	} /* FeedWordPressCompatibility::bottom_script_hook() */
 } /* class FeedWordPressCompatibility */
 
-define('FEEDWORDPRESS_AND_TAGS', (FeedWordPressCompatibility::post_tags() ? ' & Tags' : ''));
-
-if (!function_exists('stripslashes_deep')) {
-	function stripslashes_deep($value) {
-		$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
-		return $value;
-	}
-}
-
-if (!function_exists('sanitize_user')) {
-	function sanitize_user ($text, $strict = false) {
-		return $text; // Don't munge it if it wasn't munged going in...
-	}
-}
-
-if (!function_exists('disabled')) {
-	/**
-	 * Outputs the html disabled attribute.
-	 *
-	 * Compares the first two arguments and if identical marks as disabled
-	 *
-	 * @since 3.0.0
-	 *
-	 * @param mixed $disabled One of the values to compare
-	 * @param mixed $current (true) The other value to compare if not just true
-	 * @param bool $echo Whether to echo or just return the string
-	 * @return string html attribute or empty string
-	 */
-	function disabled( $disabled, $current = true, $echo = true ) {
-		return __checked_selected_helper( $disabled, $current, $echo, 'disabled' );
-	}
-} /* if */
-
 // Compat
 
 if (!function_exists('set_post_field')) {
@@ -175,13 +135,6 @@ if (!function_exists('set_post_field')) {
 
 } /* if */
 
-if (!function_exists('term_exists')) {
-	// Fucking WordPress 3.0 wordsmithing.
-	function term_exists ( $term, $taxonomy = '', $parent = 0 ) {
-		return is_term($term, $taxonomy, $parent);
-	}
-} /* if */
-
 require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
 
 function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $params = array()) {
diff --git a/wp-content/plugins/feedwordpress/diagnostics-page.php b/wp-content/plugins/feedwordpress/diagnostics-page.php
index d062b00f3290822cf9eedf988c20ef246ddc1574..ec74b2ec39f2fede1cf9c653111c54047ce5e3eb 100644
--- a/wp-content/plugins/feedwordpress/diagnostics-page.php
+++ b/wp-content/plugins/feedwordpress/diagnostics-page.php
@@ -7,6 +7,9 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressdiagnosticspage');
 		$this->dispatch = 'feedwordpress_diagnostics';
 		$this->filename = __FILE__;
+		
+		$this->test_html = array();
+		add_action('feedwordpress_diagnostics_do_http_test', array($this, 'do_http_test'), 10, 1);
 	}
 
 	function has_link () { return false; }
@@ -42,6 +45,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 			'info_box' => __('Diagnostic Information'),
 			'diagnostics_box' => __('Display Diagnostics'),
 			'updates_box' => __('Updates'),
+			'tests_box' => __('Diagnostic Tests'),
 		);
 	
 		foreach ($boxes_by_methods as $method => $title) :
@@ -68,7 +72,8 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 
 	function accept_POST ($post) {
 		if (isset($post['submit'])
-		or isset($post['save'])) :
+		or isset($post['save'])
+		or isset($post['feedwordpress_diagnostics_do'])) :
 			update_option('feedwordpress_debug', $post['feedwordpress_debug']);
 			update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
 			
@@ -102,12 +107,19 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 				delete_option('feedwordpress_diagnostics_email_destination');
 			endif;
 			
+			if (isset($post['feedwordpress_diagnostics_do'])) :
+				foreach ($post['feedwordpress_diagnostics_do'] as $do => $value) :
+					do_action('feedwordpress_diagnostics_do_'.$do, $post);
+				endforeach;
+			endif;
+			
 			$this->updated = true; // Default update message
 		endif;
 	} /* FeedWordPressDiagnosticsPage::accept_POST () */
 
 	function info_box ($page, $box = NULL) {
 		global $feedwordpress;
+		global $wp_version;
 		$link_category_id = FeedWordPress::link_category_id();
 	?>
 		<table class="edit-form narrow">
@@ -122,6 +134,20 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		<td>You are using FeedWordPress version <strong><?php print FEEDWORDPRESS_VERSION; ?></strong>.</td>
 		</tr>
 
+		<tr>
+		<th scope="row">Hosting Environment:</th>
+		<td><ul style="margin-top: 0; padding-top: 0;">
+		<li><em>WordPress:</em> version <?php print $wp_version; ?></li>
+		<?php if (function_exists('phpversion')) : ?>
+		<li><em>PHP:</em> version <?php print phpversion(); ?></li>
+		<?php endif; ?>
+		<?php if (function_exists('apache_get_version')) : ?>
+		<li><sem>Web Server:</em> <?php print apache_get_version(); ?></li>
+		<?php endif; ?>
+		</ul>
+		</td>
+		</tr>
+		
 		<tr>
 		<th scope="row">Link Category:</th>
 		<td><?php if (!is_wp_error($link_category_id)) :
@@ -242,6 +268,7 @@ testing but absolutely inappropriate for a production server.</p>
 				'updated_feeds' => 'as each feed is checked for updates',
 				'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
 				'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
+				'updated_feeds:http' => "displaying the raw HTTP data passed to and from the feed being checked for updates",
 				'syndicated_posts' => 'as each syndicated post is added to the database',
 				'feed_items' => 'as each syndicated item is considered on the feed',
 				'memory_usage' => 'indicating how much memory was used',
@@ -252,6 +279,7 @@ testing but absolutely inappropriate for a production server.</p>
 				'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
 			),
 			'Advanced Diagnostics' => array(
+				'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
 				'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates', 
 				'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
 			),
@@ -289,6 +317,101 @@ testing but absolutely inappropriate for a production server.</p>
 </table>
 		<?php
 	} /* FeedWordPressDiagnosticsPage::updates_box () */
+	
+	function tests_box ($page, $box = NULL) {
+?>
+<script type="text/javascript">
+function clone_http_test_args_keyvalue_prototype () {
+	var next = jQuery('#http-test-args').find('.http-test-args-keyvalue').length;
+	var newRow = jQuery('#http-test-args-keyvalue-prototype').clone().attr('id', 'http-test-args-keyvalue-' + next);
+	newRow.find('.http_test_args_key').attr('name', 'http_test_args_key['+next+']').val('');
+	newRow.find('.http_test_args_value').attr('name', 'http_test_args_value['+next+']').val('');
+
+	newRow.appendTo('#http-test-args');	
+	return false;
+}
+</script>
+
+<table class="edit-form">
+	<tr>
+	<th scope="row">HTTP:</th>
+	<td><div><input type="url" name="http_test_url" value="" placeholder="http://www.example.com/" size="127" style="width: 80%; max-width: 80.0em;" />
+	<input type="submit" name="feedwordpress_diagnostics_do[http_test]" value="Test &raquo;" /></div>
+	<div><select name="http_test_method" size="1">
+		<option value="wp_remote_request">wp_remote_request</option>
+		<option value="FeedWordPress_File">FeedWordPress_File</option>
+	</select></div>
+	<table>
+	<tr>
+	<td>
+	<div id="http-test-args">
+	<div id="http-test-args-keyvalue-prototype" class="http-test-args-keyvalue"><label>Args:
+	<input type="text" class='http_test_args_key' name="http_test_args_key[0]" value="" placeholder="key" /></label>
+	<label>= <input type="text" class='http_test_args_value' name="http_test_args_value[0]" value="" placeholder="value" /></label>
+	</div>
+	</div>
+	</td>
+	<td><a href="#http-test-args" onclick="return clone_http_test_args_keyvalue_prototype();">+ Add</a></td>
+	</tr>
+	</table>
+	
+	<?php if (isset($page->test_html['http_test'])) : ?>
+	<div style="position: relative">
+	<div style="width: 100%; overflow: scroll; background-color: #eed">
+	<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -o-pre-wrap;"><?php print $page->test_html['http_test']; ?></pre>
+	</div>
+	</div>
+	<?php endif; ?>
+	</td>
+	</tr>
+</table>
+
+<?php
+	} /* FeedWordPressDiagnosticsPage::tests_box () */
+
+	var $test_html;
+	function do_http_test ($post) {
+		if (isset($post['http_test_url']) and isset($post['http_test_method'])) :
+			$url = $post['http_test_url'];
+			
+			$args = array();
+			if (isset($post['http_test_args_key'])) :
+				foreach ($post['http_test_args_key'] as $idx => $name) :
+					$name = trim($name);
+					if (strlen($name) > 0) :
+						$value = NULL;
+						if (isset($post['http_test_args_value'])
+						and isset($post['http_test_args_value'][$idx])) :
+							$value = $post['http_test_args_value'][$idx];
+						endif;
+						
+						if (preg_match('/^javascript:(.*)$/i', $value, $refs)) :
+							if (function_exists('json_decode')) :	
+								$json_value = json_decode($refs[1]);
+								if (!is_null($json_value)) :
+									$value = $json_value;
+								endif;
+							endif;
+						endif;
+						
+						$args[$name] = $value;
+					endif;
+				endforeach;
+			endif;
+			
+			switch ($post['http_test_method']) :
+			case 'wp_remote_request' :
+				$out = wp_remote_request($url, $args);
+				break;
+			case 'FeedWordPress_File' :
+				$out = new FeedWordPress_File($url);
+				break;
+			endswitch;
+			
+			$this->test_html['http_test'] = esc_html(FeedWordPress::val($out));
+		endif;
+	} /* FeedWordPressDiagnosticsPage::do_http_test () */
+	
 } /* class FeedWordPressDiagnosticsPage */
 
 	$diagnosticsPage = new FeedWordPressDiagnosticsPage;
diff --git a/wp-content/plugins/feedwordpress/feeds-page.php b/wp-content/plugins/feedwordpress/feeds-page.php
index ac62d18f88d41c3d7fd9cfb3f0df1ca843d55deb..491c93d4e0f9c3778180d6df9f17885d30a72b3a 100644
--- a/wp-content/plugins/feedwordpress/feeds-page.php
+++ b/wp-content/plugins/feedwordpress/feeds-page.php
@@ -111,7 +111,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 			'global_feeds_box' => __('Update Scheduling'),
 			'updated_posts_box' => __('Updated Posts'),
 			'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
-			'fetch_settings_box' => __('Settings for Fetching Feeds (Advanced)'),
+			'advanced_settings_box' => __('Advanced Settings'),
 		);
 		if ($this->for_default_settings()) :
 			unset($this->boxes_by_methods['custom_settings_box']);
@@ -265,13 +265,13 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 			
 			$this->setting_radio_control(
 				'update/window', 'update_window',
-				array(&$this, 'update_window_edit_box'),
+				array($this, 'update_window_edit_box'),
 				array(
 					'global-setting-default' => DEFAULT_UPDATE_PERIOD,
 					'default-input-name' => 'use_default_update_window',
 					'default-input-id' => 'use-default-update-window-yes',
 					'default-input-id-no' => 'use-default-update-window-no',
-					'labels' => array(&$this, 'update_window_currently'),
+					'labels' => array($this, 'update_window_currently'),
 				)
 			);
 			?></td>
@@ -363,22 +363,63 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 		print number_format(intval($setting)) . " " . (($setting==1) ? "second" : "seconds");
 	}
 	
-	function fetch_settings_box ($page, $box = NULL) {
+	function advanced_settings_box ($page, $box = NULL) {
+		?>
+		<table class="edit-form">
+		<tr>
+		<th>Fetch Timeout:</th>
+		<td>
+		<?php
 		$this->setting_radio_control(
 			'fetch timeout', 'fetch_timeout',
-			array(&$this, 'fetch_timeout_setting'),
+			array($this, 'fetch_timeout_setting'),
 			array(
 				'global-setting-default' => FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT,
 				'input-name' => 'fetch_timeout',
 				'default-input-name' => 'fetch_timeout_default',
-				'labels' => array(&$this, 'fetch_timeout_setting_value'),
+				'labels' => array($this, 'fetch_timeout_setting_value'),
 			)
 		);
-	} /* FeedWordPressFeedsPage::fetch_settings_box () */
+		?>
+		</td>
+		</tr>
+		<tr>
+		<th>Feed Update Type:</th>
+		<td><?php
+		$this->setting_radio_control('update_incremental', 'update_incremental',
+			/*options=*/ array(
+				'incremental' => '<strong>Incremental.</strong> When items no longer appear on the feed, keep them in the WordPress posts table.',
+				'complete' => '<strong>Complete.</strong> When items no longer appear on the feed, they are obsolete; retire them from the WordPress posts table.',
+			),
+			/*params=*/ array(
+				'setting-default' => NULL,
+				'global-setting-default' => 'incremental',
+				'default-input-value' => 'default', 
+			)
+		); ?></td>
+		</tr>
+		<tr>
+		<th>Allow Feeds to Delete Posts:</th>
+		<td><?php
+		$this->setting_radio_control('tombstones', 'tombstones',
+			/*options=*/ array(
+				'yes' => 'Yes. If a feed indicates that one of its posts has been deleted, delete the local copy syndicated to this website.',
+				'no' => 'No. Even if a feed indicates that one of its posts has been deleted, retain the local copy on this website.',
+			),
+			/*params=*/ array(
+				'setting-default' => NULL,
+				'global-setting-default' => 'yes',
+				'default-input-value' => 'default',
+			)
+		); ?></td>
+		</tr>
+		</table>
+		<?php
+	} /* FeedWordPressFeedsPage::advanced_settings_box () */
 	
 	function display_authentication_credentials_box ($params = array()) {
 		static $count = 0;
-		
+
 		$params = wp_parse_args($params, array(
 		'username' => NULL,
 		'password' => NULL,
@@ -502,7 +543,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 
 		global $feedwordpress;
 
-		if (is_null($auth)) :
+		if (is_null($auth) or (strlen($auth)==0)) :
 			$auth = '-';
 			$hideAuth = true;
 		endif;
@@ -734,9 +775,9 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 	
 		$lookup = (isset($_REQUEST['lookup']) ? $_REQUEST['lookup'] : NULL);
 		
-		$auth = FeedWordPress::param('link_rss_auth_method');
-		$username = FeedWordPress::param('link_rss_username');
-		$password = FeedWordPress::param('link_rss_password');
+		$auth = MyPHP::request('link_rss_auth_method');
+		$username = MyPHP::request('link_rss_username');
+		$password = MyPHP::request('link_rss_password');
 		$credentials = array(
 				"authentication" => $auth,
 				"username" => $username,
@@ -789,7 +830,21 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 		$feeds = array_values( // Renumber from 0..(N-1)
 			$feeds
 		);
-
+		
+		// Allow for some simple FeedFinder results filtering
+		$feeds = apply_filters(
+			'feedwordpress_feedfinder_results',
+			$feeds,
+			array(
+				"url" => $lookup,
+				"auth" => $auth,
+				"username" => $username,
+				"password" => $password,
+				"finder" => $finder,
+			),
+			$this
+		);
+		
 		if (count($feeds) > 0):
 			if ($feedSwitch) :
 				?>
@@ -815,7 +870,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 			foreach ($feeds as $key => $f):
 				$ofc = $fwp_credentials;
 				$fwp_credentials = $credentials; // Set
-				$pie = FeedWordPress::fetch($f);
+				$pie = FeedWordPress::fetch($f, array("cache" => false));
 				$fwp_credentials = $ofc; // Re-Set
 				
 				$rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
@@ -1161,6 +1216,14 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 			endif;
 			$this->update_setting('fetch timeout', $timeout);
 		endif;
+		
+		if (isset($post['update_incremental'])) :
+			$this->update_setting('update_incremental', $post['update_incremental']);
+		endif;
+
+		if (isset($post['tombstones'])) :
+			$this->update_setting('tombstones', $post['tombstones']);
+		endif;
 
 		if (isset($post['update_minimum'])) :
 			$this->update_setting('update/minimum', $post['update_minimum']);
diff --git a/wp-content/plugins/feedwordpress/feedtime.class.php b/wp-content/plugins/feedwordpress/feedtime.class.php
index 5cfc3a26a081a69fcde0a68d279242f697cfe64b..067c584300ec8339b4695e1f7ec8578a098c5b46 100644
--- a/wp-content/plugins/feedwordpress/feedtime.class.php
+++ b/wp-content/plugins/feedwordpress/feedtime.class.php
@@ -1,7 +1,24 @@
 <?php
 /**
  * class FeedTime: handle common date-time formats used in feeds.
+ * We will try to be as tolerant as possible of different representations, since
+ * RSS Is A Fucking Mess, broken dates seem to be especially pervasive, etc.
+ * Supports anything that your version of PHP's strtotime() can handle; also has
+ * a built-in parser for W3C DTF, in case your PHP doesn't have that.
  *
+ * Tries to parse a W3C DTF first; then falls back to strtotime(). If strtotime
+ * fails due to a mystery timezone, then we will try again on local time, with
+ * the timezone stripped out.
+ *
+ * To parse a string representation of a date-time from a feed, instantiate and
+ * then pull the timestamp:
+ *
+ * 	$time = new FeedTime($s);
+ *	if (!$time->failed()) :
+ * 		$ts = $time->timestamp();
+ *	else :
+ *		// ...
+ *	endif;
  */
 class FeedTime {
 	var $rep;
@@ -21,10 +38,10 @@ class FeedTime {
 			$this->ts = $this->parse_w3cdtf();
 			
 			if ($this->failed()) :
-				// In some versions of PHP, strtotime() does not support
-				// the UT timezone. Since UT is by definition within 1
-				// second of UTC, we'll just convert it preemptively to avoid
-				// problems.
+				// In some versions of PHP, strtotime() does not
+				// support the UT timezone. But since UT is by
+				// definition within 1 second of UTC, we'll just
+				// convert it preemptively to avoid problems.
 				$time = preg_replace(
 					'/(\s)UT$/',
 					'$1UTC',
diff --git a/wp-content/plugins/feedwordpress/feedwordpie.class.php b/wp-content/plugins/feedwordpress/feedwordpie.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..49bf11195d081bfc21f1865a3be7c7ef5848a472
--- /dev/null
+++ b/wp-content/plugins/feedwordpress/feedwordpie.class.php
@@ -0,0 +1,73 @@
+<?php
+define('FEEDWORDPIE_TYPE_CUSTOM_XML', ~SIMPLEPIE_TYPE_NONE & ~SIMPLEPIE_TYPE_ALL);
+
+class FeedWordPie extends SimplePie {
+	var $subscription = NULL;
+	
+	function set_feed_url ($url) {
+		global $fwp_oLinks;
+		if ($url InstanceOf SyndicatedLink) :
+
+			// Get URL with relevant parameters attached.
+			// Credentials will be handled further down.
+			$new_url = $url->uri(array('add_params' => true));
+			
+			// Store for reference.
+			$this->subscription = $url->id();
+			
+			// Pass it along down the line.
+			$url = $new_url;
+			
+		else :
+			$this->subscription = NULL;
+		endif;
+		
+		// OK, let's go.
+		return parent::set_feed_url($url);
+	} /* class SimplePie */
+	
+	function get_type () {
+		// Allow filters to pre-empt a type determination from SimplePie
+		$ret = apply_filters(
+			'feedwordpie_get_type',
+			NULL,
+			$this
+		);
+				
+		// If not preempted by a filter, fall back on SimplePie
+		if (is_null($ret)) :
+			$ret = parent::get_type();
+		endif;
+
+		return $ret;
+	}
+	
+	function get_feed_tags ($namespace, $tag) {
+		// Allow filters to filter SimplePie handling
+		return apply_filters(
+			'feedwordpie_get_feed_tags',
+			parent::get_feed_tags($namespace, $tag),
+			$namespace,
+			$tag,
+			$this
+		);
+	}
+	
+	function get_items ($start = 0, $end = 0) {
+		// Allow filters to set up for, or pre-empt, SimplePie handling
+		$ret = apply_filters(
+			'feedwordpie_get_items',
+			NULL,
+			$start,
+			$end,
+			$this
+		);
+		
+		if (is_null($ret)) :
+			$ret = parent::get_items();
+		endif;
+		return $ret;
+	}
+	
+} /* class FeedWordPie */
+
diff --git a/wp-content/plugins/feedwordpress/feedwordpie_item.class.php b/wp-content/plugins/feedwordpress/feedwordpie_item.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e3697cce12e2bafbb439273c039a302e83edd05
--- /dev/null
+++ b/wp-content/plugins/feedwordpress/feedwordpie_item.class.php
@@ -0,0 +1,55 @@
+<?php
+class FeedWordPie_Item extends SimplePie_Item {
+
+	function get_id ($hash = false) {
+		return apply_filters('feedwordpie_item_get_id', parent::get_id($hash), $hash, $this);
+	}
+	
+	function get_title () {
+		return apply_filters('feedwordpie_item_get_title', parent::get_title(), $this);
+	}
+	
+	function get_description ($description_only = false) {
+		return apply_filters('feedwordpie_item_get_description', parent::get_description($description_only), $description_only, $this);
+	}
+
+	function get_content ($content_only = false) {
+		return apply_filters('feedwordpie_item_get_content', parent::get_content($content_only), $content_only, $this);
+	}
+	
+	function get_categories () {
+		return apply_filters('feedwordpie_item_get_categories', parent::get_categories(), $this);
+	}
+	
+	function get_authors () {
+		return apply_filters('feedwordpie_item_get_authors', parent::get_authors(), $this);
+	}
+	function get_contributors () {
+		return apply_filters('feedwordpie_item_get_contributors', parent::get_contributors(), $this);
+	}
+	function get_copyright () {
+		return apply_filters('feedwordpie_item_get_copyright', parent::get_copyright(), $this);
+	}
+	function get_date ($date_format = 'j F Y, g:i a') {
+		return apply_filters('feedwordpie_item_get_date', parent::get_date($date_format), $date_format, $this);
+	}
+	function get_local_date ($date_format = '%c') {
+		return apply_filters('feedwordpie_item_get_local_date', parent::get_local_date($date_format), $date_format, $this);
+	}
+	function get_links ($rel = 'alternate') {
+		return apply_filters('feedwordpie_item_get_links', parent::get_links($rel), $rel, $this);
+	}
+	function get_enclosures () {
+		return apply_filters('feedwordpie_item_get_enclosures', parent::get_enclosures(), $this);
+	}
+	function get_latitude () {
+		return apply_filters('feedwordpie_item_get_lattitude', parent::get_lattitude(), $this);
+	}
+	function get_longitude () {
+		return apply_filters('feedwordpie_item_get_longitude', parent::get_longtidue(), $this);
+	}
+	function get_source () {
+		return apply_filters('feedwordpie_item_get_source', parent::get_source(), $this);
+	}
+} /* class FeedWordPie_Item */
+
diff --git a/wp-content/plugins/feedwordpress/feedwordpress-content-type-sniffer.class.php b/wp-content/plugins/feedwordpress/feedwordpress-content-type-sniffer.class.php
index 02cb19e854821d7843e948c3bd0637930049b096..15bab37423c7df2d9dc6071fb26acab4a54c80f8 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress-content-type-sniffer.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress-content-type-sniffer.class.php
@@ -17,7 +17,7 @@ class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer
 			endif;
 
 			foreach ($this->file->headers['content-type'] as $type) :
-				$parts = array_map('trim', split(";", $type, 2));
+				$parts = array_map('trim', explode(";", $type, 2));
 				if (isset($parts[1])) :
 					$type = $parts[0];
 					$charset = $parts[1];
diff --git a/wp-content/plugins/feedwordpress/feedwordpress-elements.css b/wp-content/plugins/feedwordpress/feedwordpress-elements.css
index 9e92b099cf0230f3fd952d02dfcc07ca82e27f5a..11fcf2903d0e8a4e1a9941a3ae32abe37dfcfea5 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress-elements.css
+++ b/wp-content/plugins/feedwordpress/feedwordpress-elements.css
@@ -13,8 +13,7 @@
 	width: 120px;
 }
 .feedwordpress-category-div ul.category-tabs li.tabs {
-	-moz-border-radius: 3px 0 0 3px;
-	-webkit-border-radius: 3px 0 0 3px;
+	display: block;
 	border-radius: 3px 0 0 3px;
 	border-color: #DFDFDF;
 	border-style: solid none solid solid;
@@ -430,3 +429,43 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
 
 #feedwordpress-admin-feeds #link-rss-params td { width: auto !important; }
 
+/* Feed Contents picker & XPath test results widgets */
+
+.fwp-xpath-test-results {
+	position: absolute;
+	top: auto; left: auto;
+	z-index: 9999999;
+	overflow: auto;
+	max-height: 100px; max-width: 400px;
+	background-color: #ccffcc;
+	padding: 10px;
+}
+.fwp-xpath-test-results-close {
+	position: absolute;
+	top: 10px; right: 10px;
+	
+}
+.fwp-xpath-test-setting {
+	font-size: smaller;
+}
+
+.fwp-feed-contents-picker h4, .fwp-xpath-test-results h4 {
+	margin-top: 0;
+	margin-bottom: 5px;
+	border-bottom: 1px dotted black;
+}
+.fwp-feed-contents-picker-close {
+	position: absolute;
+	top: 10px; right: 10px;
+}
+.fwp-feed-contents-picker, .fwp-feeds-picker {
+	position: absolute;
+	top: auto; left: auto;
+	z-index: 9999999;
+	overflow: auto;
+	max-height: 100px; max-width: 400px;
+	background-color: #ccffcc;
+	padding: 10px;
+}
+
+
diff --git a/wp-content/plugins/feedwordpress/feedwordpress-elements.js b/wp-content/plugins/feedwordpress/feedwordpress-elements.js
index fa793373b25a1e888d1b6b9202c35778cd2b97e5..c3d799a767db6a9a631cb5613dbf27bab84015e0 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress-elements.js
+++ b/wp-content/plugins/feedwordpress/feedwordpress-elements.js
@@ -249,7 +249,7 @@ fwpList = {
 			el = el.get(0);
 		var elem = el, color, rgbaTrans = new RegExp( "rgba\\(\\s*0,\\s*0,\\s*0,\\s*0\\s*\\)", "i" );
 		do {
-			color = jQuery.curCSS(elem, 'backgroundColor');
+			color = jQuery(elem).css('backgroundColor');
 			if ( color != '' && color != 'transparent' && !color.match(rgbaTrans) || jQuery.nodeName(elem, "body") )
 				break;
 		} while ( elem = elem.parentNode );
@@ -299,7 +299,6 @@ fwpList = {
 			color = fwpList.getColor( e );
 			e.css( 'backgroundColor', s.addColor ).animate( { backgroundColor: color }, { complete: function() { $(this).css( 'backgroundColor', '' ); } } );
 		}
-		
 		list.each( function() { this.fwpList.process( e ); } );
 		return e;
 	},
@@ -394,14 +393,6 @@ function feedAuthenticationMethod (params) {
 	var elMethod = elTable.find('.link-rss-auth-method');
 	var elLink = elDiv.find('.link-rss-userpass-use');
 
-	console.log('--- ---');
-	console.log(s.node);
-	console.log(elDiv);
-	console.log(elTable);
-	console.log(elMethod);
-	console.log(elLink);
-	console.log(elMethod.val());
-	
 	// Set.
 	if (s.value != null) {
 		elMethod.val(s.value);
@@ -495,7 +486,252 @@ jQuery(document).ready( function($) {
 	} ); /* $('.feedwordpress-category-div').each() */
 } ); /* jQuery(document).ready() */
 
+
+function fwp_feedspiper () {
+	var data = {
+		action: 'fwp_feeds'
+	};
+	
+	return jQuery.ajax({
+		type: "POST",
+		url: ajaxurl,
+		data: data
+	});
+}
+
+function fwp_feedcontentspiper (feed_id, callbackOK, callbackFail) {
+	var data = {
+		action: 'fwp_feedcontents',
+		feed_id: feed_id
+	};
+	
+	jQuery.ajax({
+		type: "POST",
+		url: ajaxurl,
+		data: data
+	})
+	.done(function (response) { callbackOK(response); })
+	.fail(function (response) { callbackFail(response); });
+}
+
+function fwp_feedcontentspicker (feed_id, destination, pickCallback, closeCallback) {
+	var picker_id = 'fwp-feed-contents-picker-' + feed_id;
+	
+	jQuery('<div class="fwp-feed-contents-picker" style="display: none;" id="'+picker_id+'"><p>Loading...</p></div>').insertAfter(destination);
+	jQuery('#'+picker_id).show(500);
+	
+	fwp_feedcontentspiper(feed_id, function (response) {
+		var ul = '<h4>Using post...</h4><ul>';
+		for (var i=0; i < response.length; i++) {
+			ul += '<li><a class="fwp-feed-contents-picker-pick-'+feed_id+'" href="'
+				+response[i].guid
+				+'">' + response[i].post_title + '</a></li>';
+		}
+		ul += '</ul>';
+		ul += '<a class="fwp-feed-contents-picker-close" href="#" id="fwp-feed-contents-picker-' + feed_id + '-close">x</a>';
+
+		jQuery('#fwp-feed-contents-picker-' + feed_id).html(ul);
+
+		// Set up event handlers.
+		jQuery('#fwp-feed-contents-picker-' + feed_id + '-close').click(function (e) {
+			jQuery('#fwp-feed-contents-picker-' + feed_id).hide(500, function () { jQuery('#fwp-feed-contents-picker-' + feed_id).remove(); });
+			if (typeof(closeCallback)=='function') {
+				closeCallback(feed_id);
+			}
+			e.preventDefault();
+			return false;
+		});
+		jQuery('.fwp-feed-contents-picker-pick-' + feed_id).click(function (e) {
+			jQuery('#fwp-feed-contents-picker-' + feed_id).hide(500, function () { jQuery('#fwp-feed-contents-picker-' + feed_id).remove(); });
+			if (typeof(pickCallback)=='function') {
+				pickCallback(feed_id, jQuery(this).attr('href'));
+			}
+			e.preventDefault();
+			return false;
+		});
+	},
+	function (response) {
+		jQuery('#' + picker_id).addClass('error').html('There was a problem getting a listing of the feed. Sorry!').delay(5000).hide(500, function () { jQuery(this).remove(); });
+	});
+}
+
+function fwp_feedspicker (destination, pickCallback, closeCallback) {
+	var dabber = jQuery(destination).attr('id');
+	var picker_id = 'fwp-feeds-picker-' + dabber;
+	
+	jQuery('<div class="fwp-feeds-picker" style="display: none;" id="'+picker_id+'"><p>Loading...</p></div>').insertAfter(destination);
+	jQuery('#'+picker_id).show(500);
+	
+	fwp_feedspiper()
+	.done(function (response) {
+		var ul = '<h4>Using subscription...</h4><ul>';
+		for (var i=0; i < response.length; i++) {
+			ul += '<li><a class="fwp-feeds-picker-pick-'+dabber+'" href="#feed-'
+				+response[i].id
+				+'">' + response[i].name + '</a></li>';
+		}
+		ul += '</ul>';
+		ul += '<a class="fwp-feeds-picker-close" href="#" id="fwp-feeds-picker-' + dabber + '-close">x</a>';
+
+		jQuery('#fwp-feeds-picker-' + dabber).html(ul);;
+		
+		// Set up event handlers.
+		jQuery('#fwp-feeds-picker-' + dabber + '-close').click(function (e) {
+			jQuery('#fwp-feeds-picker-' + dabber).hide(500, function () { jQuery('#fwp-feeds-picker-' + dabber).remove(); });
+			if (typeof(closeCallback)=='function') {
+				closeCallback(destination);
+			}
+			e.preventDefault();
+			return false;
+		});
+		jQuery('.fwp-feeds-picker-pick-' + dabber).click(function (e) {
+			jQuery('#fwp-feeds-picker-' + dabber).hide(500, function () {
+				jQuery('#fwp-feeds-picker-' + dabber).remove();
+			});
+			
+			var feed_id = jQuery(this).attr('href').replace(/^#feed-/, '');
+			
+			if (typeof(pickCallback)=='function') {
+				pickCallback(feed_id, jQuery(this));
+			}
+			e.preventDefault();
+			return false;
+		});
+	})
+	.fail(function (response) {
+		jQuery('#' + picker_id).addClass('error').html('There was a problem getting a listing of your subscriptions. Sorry!').delay(5000).hide(500, function () { jQuery(this).remove(); });
+	});
+}
+
+function fwp_xpathtest_ajax (expression, feed_id, post_id) {
+	var data = {
+	action: 'fwp_xpathtest',
+	xpath: expression,
+	feed_id: feed_id,
+	post_id: post_id
+	};
+			
+	return jQuery.ajax({
+		type: "GET",
+		url: ajaxurl,
+		data: data
+	});
+}
+
+function fwp_xpathtest_fail (response, result_id, destination) {
+	jQuery('<div class="fwp-xpath-test-results error" style="display: none;" id="'+result_id+'">There was a problem communicating with the server.<p>result = <code>'+response+'</code></p></div>').insertAfter(destination);
+	jQuery('#'+result_id).show(500).delay(3000).hide(500, function () { jQuery(this).remove(); });
+}
+
+function fwp_xpathtest_ok (response, result_id, destination) {
+	var dabber = jQuery(destination).attr('id');
+	var resultsHtml = '<ul>';
+	
+	if (response.results instanceof Array) {
+		for (var i = 0; i < response.results.length; i++) {
+			resultsHtml += '<li>result['+i.toString()+'] = <code>'+response.results[i]+'</code></li>';
+		}
+	} else {
+		resultsHtml += '<li>result = <code>' + response.results + '</code></li>';
+	} /* if */
+	resultsHtml += '</ul>';
+	
+	jQuery('<div class="fwp-xpath-test-results" style="display: none;" id="'+result_id+'"><h4>'+response.expression+'</h4>'+resultsHtml+'</code> <a class="fwp-xpath-test-results-close">x</a></div>').insertAfter(destination);
+	
+	var link_id = 'fwp-xpath-test-results-post-'+dabber; 
+	if (jQuery('#'+link_id).length > 0) {
+		jQuery('#'+link_id).attr('href', response.guid).html(response.post_title);
+	} else {
+		jQuery('<div id="contain-'+link_id+'" class="fwp-xpath-test-results-post fwp-xpath-test-setting">Using post: <a id="'+link_id+'" href="'+response.guid+'"> '+response.post_title+'</a> (<a href="#" class="fwp-xpath-test-results-post-change">reset</a>)</div>').insertAfter('#'+result_id);
+	} /* if */
+	
+	jQuery('#'+result_id).find('.fwp-xpath-test-results-close').click(function (e) {
+		e.preventDefault();
+		
+		jQuery('#'+result_id).hide(500, function () { jQuery(this).remove(); });
+		return false;
+	});
+	jQuery('#contain-'+link_id).find('.fwp-xpath-test-results-post-change').click(function (e) {
+		e.preventDefault();
+		jQuery('#contain-'+link_id).remove();
+
+		return false;
+	});
+	jQuery('#'+result_id).show(500);
+}
+
+function fwp_xpathtest (expression, destination, feed_id) {
+	var dabber = jQuery(destination).attr('id');
+	var result_id = 'fwp-xpath-test-results-'+dabber;
+	var preset_post_id = 'fwp-xpath-test-results-post-'+dabber; 
+	var post_id = jQuery('#'+preset_post_id).attr('href');
+	
+	// Clear out any previous results.
+	jQuery('#'+result_id).remove();
+	
+	if (jQuery('#xpath-test-feed-id-'+dabber).length > 0) {
+		feed_id = jQuery('#xpath-test-feed-id-'+dabber).val();		
+	}
+	
+	if ('*' == feed_id) {
+	
+		fwp_feedspicker(destination, function (feed_id, a) {
+			var href = a.attr('href');
+			var text = a.text();
+			
+			jQuery('<div class="fwp-xpath-test-feed-id fwp-xpath-test-setting" id="contain-xpath-test-feed-id-'+dabber+'">Using sub: <a href="'+href+'">'+text+'</a><input type="hidden" id="xpath-test-feed-id-'+dabber+'" name="xpath_test_feed_id" value="'+feed_id+'" /> (<a href="#" class="fwp-xpath-test-feed-id-change">reset</a>)</div>').insertAfter(destination);
+			
+			jQuery('#contain-xpath-test-feed-id-'+dabber).find('.fwp-xpath-test-feed-id-change').click(function (e) {
+				e.preventDefault();
+				
+				// If there is a post set, we need to reset that
+				console.log(('#contain-fwp-xpath-test-results-post-'+dabber), jQuery('#contain-fwp-xpath-test-results-post-'+dabber));
+				jQuery('#contain-fwp-xpath-test-results-post-'+dabber).remove();
+				
+				// Show yourself out.
+				jQuery('#contain-xpath-test-feed-id-'+dabber).remove();
+				return false;
+			});
+			
+			// Now recursively call the function in order to force
+			// a post-picker.
+			fwp_xpathtest(expression, destination, feed_id);
+		});
+	}
+	
+	// Check for a pre-selected post GUID.
+	else if (post_id) {
+		fwp_xpathtest_ajax(expression, feed_id, post_id)
+			.done( function (response) { fwp_xpathtest_ok(response, result_id, destination); } )
+			.fail( function (response) { fwp_xpathtest_fail(response, result_id, destination); } );
+	}
+	else {
+		// Pop up the feed content picker
+		fwp_feedcontentspicker(feed_id, destination, function (feed_id, post_id) {
+			fwp_xpathtest_ajax(expression, feed_id, post_id)
+			.done( function (response) { fwp_xpathtest_ok(response, result_id, destination); } )
+			.fail( function (response) { fwp_xpathtest_fail(response, result_id, destination); } );			
+		});
+	}
+	
+}
+
 jQuery(document).ready(function($){
+	if ( $('.xpath-test').length ) {
+		$('.xpath-test').click ( function (e) {
+			e.preventDefault();
+
+			// Pull the local expression from the text box
+			var expr = jQuery(this).closest('tr').find('textarea').val();
+			
+			// Check to see if we are on a Feed settings page or
+			// on the global settings page;
+			var feed_id = jQuery('input[name="save_link_id"]').val();
+			
+			fwp_xpathtest(expr, jQuery(this), feed_id);
+			return false;
+		});
+	}
 	if ( $('.jaxtag').length ) {
 		tagBox.init();
 	}
diff --git a/wp-content/plugins/feedwordpress/feedwordpress.php b/wp-content/plugins/feedwordpress/feedwordpress.php
index fbccc1c65961df747cf244d8ff1b7f5ecbc43dfe..ca1311090db739f140acfcb407a5b6f5e10a902b 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress.php
@@ -3,7 +3,7 @@
 Plugin Name: FeedWordPress
 Plugin URI: http://feedwordpress.radgeek.com/
 Description: simple and flexible Atom/RSS syndication for WordPress
-Version: 2011.1019
+Version: 2013.0502
 Author: Charles Johnson
 Author URI: http://radgeek.com/
 License: GPL
@@ -11,30 +11,28 @@ License: GPL
 
 /**
  * @package FeedWordPress
- * @version 2011.1019
+ * @version 2013.0502
  */
 
 # This uses code derived from:
 # -	wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
-# -	MagpieRSS by Kellan Elliot-McCrea <kellan@protest.net>
+# -	SimplePie feed parser by Ryan Parman, Geoffrey Sneddon, Ryan McCue, et al.
+# -	MagpieRSS feed parser by Kellan Elliot-McCrea <kellan@protest.net>
 # -	Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
 # -	WordPress Blog Tool and Publishing Platform <http://wordpress.org/>
 # according to the terms of the GNU General Public License.
 #
-# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
+# INSTALLATION: see readme.txt or <http://feedwordpress.radgeek.com/install>
 #
 # USAGE: once FeedWordPress is installed, you manage just about everything from
-# the WordPress Dashboard, under the Syndication menu. To ensure that fresh
-# content is added as it becomes available, you can convince your contributors
-# to put your XML-RPC URI (if WordPress is installed at
-# <http://www.zyx.com/blog>, XML-RPC requests should be sent to
-# <http://www.zyx.com/blog/xmlrpc.php>), or update manually under the
-# Syndication menu, or set up automatic updates under Syndication --> Settings,
-# or use a cron job.
+# the WordPress Dashboard, under the Syndication menu. To keep fresh content
+# coming in as it becomes available, you'll have to either check for updates
+# manually, or set up one of the automatically-scheduled update methods. See 
+# <http://feedwordpress.radgeek.com/wiki/quick-start/> for some details.
 
 # -- Don't change these unless you know what you're doing...
 
-define ('FEEDWORDPRESS_VERSION', '2011.1019');
+define ('FEEDWORDPRESS_VERSION', '2013.0502');
 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
 
 if (!defined('FEEDWORDPRESS_BLEG')) :
@@ -54,6 +52,8 @@ else :
 	endif;
 endif;
 define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
+$feedwordpress_compatibility = true;
+define ('FEEDWORDPRESS_COMPATIBILITY', $feedwordpress_compatibility);
 
 define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
 define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
@@ -64,14 +64,6 @@ define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
 
 define ('FWP_SCHEMA_HAS_USERMETA', 2966);
 define ('FWP_SCHEMA_USES_ARGS_TAXONOMY', 12694); // Revision # for using $args['taxonomy'] to get link categories
-define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
-define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
-define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
-define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
-define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
-define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
-define ('FWP_SCHEMA_28', 11548); // Database schema # for WP 2.8
-define ('FWP_SCHEMA_29', 12329); // Database schema # for WP 2.9
 define ('FWP_SCHEMA_30', 12694); // Database schema # for WP 3.0
 
 if (FEEDWORDPRESS_DEBUG) :
@@ -110,6 +102,7 @@ if (!function_exists('wp_insert_user')) :
 endif;
 
 $dir = dirname(__FILE__); 
+require_once("${dir}/externals/myphp/myphp.class.php");
 require_once("${dir}/admin-ui.php");
 require_once("${dir}/feedwordpresssyndicationpage.class.php");
 require_once("${dir}/compatability.php"); // Legacy API             
@@ -119,10 +112,13 @@ require_once("${dir}/feedwordpresshtml.class.php");
 require_once("${dir}/feedwordpress-content-type-sniffer.class.php");
 require_once("${dir}/inspectpostmeta.class.php");
 require_once("${dir}/syndicationdataqueries.class.php");
+require_once("${dir}/feedwordpie.class.php");
+require_once("${dir}/feedwordpie_item.class.php");
 require_once("${dir}/feedwordpress_file.class.php");
 require_once("${dir}/feedwordpress_parser.class.php");
 require_once("${dir}/feedwordpressrpc.class.php");
 require_once("${dir}/feedwordpresshttpauthenticator.class.php");
+require_once("${dir}/feedwordpresslocalpost.class.php");
 
 // Magic quotes are just about the stupidest thing ever.
 if (is_array($_POST)) :
@@ -167,7 +163,8 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 	
 	# Filter in original permalinks if the user wants that
 	add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
-
+	add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
+	
 	# When foreign URLs are used for permalinks in feeds or display
 	# contexts, they need to be escaped properly.
 	add_filter('the_permalink', 'syndication_permalink_escaped');
@@ -183,6 +180,7 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 	remove_filter('pre_link_url', 'wp_filter_kses');
 	
 	# Admin menu
+	add_action('admin_init', array('feedwordpress', 'admin_init'));
 	add_action('admin_menu', 'fwp_add_pages');
 	add_action('admin_notices', 'fwp_check_debug');
 
@@ -214,17 +212,18 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 	# Cron-less auto-update. Hooray!
 	$autoUpdateHook = $feedwordpress->automatic_update_hook();
 	if (!is_null($autoUpdateHook)) :
-		add_action($autoUpdateHook, array(&$feedwordpress, 'auto_update'));
+		add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
 	endif;
 	
-	add_action('init', array(&$feedwordpress, 'init'));
-	add_action('shutdown', array(&$feedwordpress, 'email_diagnostic_log'));
-	add_action('wp_dashboard_setup', array(&$feedwordpress, 'dashboard_setup'));
+	add_action('init', array($feedwordpress, 'init'));
+	add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
+	add_action('wp_dashboard_setup', array($feedwordpress, 'dashboard_setup'));
 
 	# Default sanitizers
 	add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
 	add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
 
+	add_action('plugins_loaded', array('FeedWordPress', 'admin_api'));
 else :
 	# Hook in the menus, which will just point to the upgrade interface
 	add_action('admin_menu', 'fwp_add_pages');
@@ -315,7 +314,8 @@ function debug_out_feedwordpress_footer () {
  * @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise 
  */ 
 function is_syndicated ($id = NULL) {
-	return (strlen(get_syndication_feed_id($id)) > 0);
+	$p = new FeedWordPressLocalPost($id);
+	return $p->is_syndicated();
 } /* function is_syndicated() */
 
 function feedwordpress_display_url ($url, $before = 60, $after = 0) {
@@ -341,74 +341,59 @@ function feedwordpress_display_url ($url, $before = 60, $after = 0) {
 } /* feedwordpress_display_url () */
 
 function get_syndication_source_property ($original, $id, $local, $remote = NULL) {
-	$ret = NULL;
-	if (is_null($original)) :
-		$original = FeedWordPress::use_aggregator_source_data();
-	endif;
-	
-	if (is_null($remote)) :
-		$remote = $local . '_original';
-	endif;
-	
-	$vals = ($original ? get_post_custom_values($remote, $id) : array());
-	if (count($vals) < 1) :
-		$vals = get_post_custom_values($local, $id);
-	endif;
-	
-	if (count($vals) > 0) :
-		$ret = $vals[0];
-	endif;
-	return $ret;
+	$p = new FeedWordPressLocalPost($id);
+	return $p->meta($local, array("unproxy" => $original, "unproxied setting" => $remote));
 } /* function get_syndication_source_property () */
 
-function the_syndication_source_link ($original = NULL, $id = NULL) { echo get_syndication_source_link($original, $id); }
 function get_syndication_source_link ($original = NULL, $id = NULL) {
-	return get_syndication_source_property($original, $id, 'syndication_source_uri');
+	$p = new FeedWordPressLocalPost($id);
+	return $p->syndication_source_link($original);
 } /* function get_syndication_source_link() */
 
-function the_syndication_source ($original = NULL, $id = NULL) { echo get_syndication_source($original, $id); }
+function the_syndication_source_link ($original = NULL, $id = NULL) {
+	echo get_syndication_source_link($original, $id);
+} /* function the_syndication_source_link() */
+
 function get_syndication_source ($original = NULL, $id = NULL) {
-	$ret = get_syndication_source_property($original, $id, 'syndication_source');
-	if (is_null($ret) or strlen(trim($ret)) == 0) : // Fall back to URL of blog
-		$ret = feedwordpress_display_url(get_syndication_source_link());
-	endif;
-	return $ret;
+	$p = new FeedWordPressLocalPost($id);
+	return $p->syndication_source($original);
 } /* function get_syndication_source() */
 
-function the_syndication_feed ($original = NULL, $id = NULL) { echo get_syndication_feed($original, $id); }
+function the_syndication_source ($original = NULL, $id = NULL) {
+	echo get_syndication_source($original, $id);
+} /* function the_syndication_source () */
+
 function get_syndication_feed ($original = NULL, $id = NULL) {
-	return get_syndication_source_property($original, $id, 'syndication_feed');
+	$p = new FeedWordPressLocalPost($id);
+	return $p->syndication_feed($original);
 } /* function get_syndication_feed() */
 
-function the_syndication_feed_guid ($original = NULL, $id = NULL) { echo get_syndication_feed_guid($original, $id); }
+function the_syndication_feed ($original = NULL, $id = NULL) {
+	echo get_syndication_feed($original, $id);
+} /* function the_syndication_feed() */
+
 function get_syndication_feed_guid ($original = NULL, $id = NULL) {
-	$ret = get_syndication_source_property($original, $id, 'syndication_source_id');
-	if (is_null($ret) or strlen(trim($ret))==0) : // Fall back to URL of feed
-		$ret = get_syndication_feed();
-	endif;
-	return $ret;
+	$p = new FeedWordPressLocalPost($id);
+	return $p->syndication_feed_guid($original);
 } /* function get_syndication_feed_guid () */
 
-function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
-function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
+function the_syndication_feed_guid ($original = NULL, $id = NULL) {
+	echo get_syndication_feed_guid($original, $id);
+} /* function the_syndication_feed_guid () */
 
-$feedwordpress_linkcache =  array (); // only load links from database once
-function get_syndication_feed_object ($id = NULL) {
-	global $feedwordpress_linkcache;
+function get_syndication_feed_id ($id = NULL) {
+	$p = new FeedWordPressLocalPost($id);
+	return $p->feed_id();
+} /* function get_syndication_feed_id () */
 
-	$link = NULL;
+function the_syndication_feed_id ($id = NULL) {
+	echo get_syndication_feed_id($id);
+} /* function the_syndication_feed_id () */
 
-	$feed_id = get_syndication_feed_id($id);
-	if (strlen($feed_id) > 0):
-		if (isset($feedwordpress_linkcache[$feed_id])) :
-			$link = $feedwordpress_linkcache[$feed_id];
-		else :
-			$link = new SyndicatedLink($feed_id);
-			$feedwordpress_linkcache[$feed_id] = $link;
-		endif;
-	endif;
-	return $link;
-}
+function get_syndication_feed_object ($id = NULL) {
+	$p = new FeedWordPressLocalPost($id);
+	return $p->feed();
+} /* function get_syndication_feed_object() */
 
 function get_feed_meta ($key, $id = NULL) {
 	$ret = NULL;
@@ -418,14 +403,16 @@ function get_feed_meta ($key, $id = NULL) {
 		$ret = $link->settings[$key];
 	endif;
 	return $ret;
-} /* get_feed_meta() */
+} /* function get_feed_meta() */
 
 function get_syndication_permalink ($id = NULL) {
-	list($u) = get_post_custom_values('syndication_permalink', $id); return $u;
-}
+	$p = new FeedWordPressLocalPost($id);
+	return $p->syndication_permalink();
+} /* function get_syndication_permalink () */
+
 function the_syndication_permalink ($id = NULL) {
 	echo get_syndication_permalink($id);
-}
+} /* function the_syndication_permalink () */
 
 /**
  * get_local_permalink: returns a string containing the internal permalink
@@ -478,11 +465,8 @@ $feedwordpress_the_original_permalink = NULL;
 function feedwordpress_preserve_syndicated_content ($text) {
 	global $feedwordpress_the_syndicated_content;
 
-	$globalExpose = (get_option('feedwordpress_formatting_filters') == 'yes');
-	$localExpose = get_post_custom_values('_feedwordpress_formatting_filters');
-	$expose = ($globalExpose or ((count($localExpose) > 0) and $localExpose[0]));
-
-	if ( is_syndicated() and !$expose ) :
+	$p = new FeedWordPressLocalPost;
+	if (!$p->is_exposed_to_formatting_filters()) :
 		$feedwordpress_the_syndicated_content = $text;
 	else :
 		$feedwordpress_the_syndicated_content = NULL;
@@ -544,7 +528,7 @@ function feedwordpress_item_feed_data () {
  * @global $id
  * @global $feedwordpress_the_original_permalink
  */
-function syndication_permalink ($permalink = '', $post = null, $leavename = false) {
+function syndication_permalink ($permalink = '', $post = null, $leavename = false, $sample = false) {
 	global $id;
 	global $feedwordpress_the_original_permalink;
 	
@@ -618,6 +602,7 @@ function syndication_comments_feed_link ($link) {
 		// that value here.
 		$source = get_syndication_feed_object();
 		$replacement = NULL;
+		
 		if ($source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
 			$commentFeeds = get_post_custom_values('wfw:commentRSS');
 			if (
@@ -668,6 +653,8 @@ function syndication_comments_feed_link ($link) {
 ################################################################################
 
 function fwp_add_pages () {
+	global $feedwordpress;
+	
 	$menu_cap = FeedWordPress::menu_cap();
 	$settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
 	$syndicationMenu = FeedWordPress::path('syndication.php');
@@ -680,6 +667,12 @@ function fwp_add_pages () {
 		WP_PLUGIN_URL.'/'.FeedWordPress::path('feedwordpress-tiny.png')
 	);
 
+	do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
+	add_submenu_page(
+		$syndicationMenu, 'Syndicated Sites', 'Syndicated Sites',
+		$settings_cap, $syndicationMenu
+	);
+
 	do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
 	add_submenu_page(
 		$syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
@@ -700,7 +693,7 @@ function fwp_add_pages () {
 
 	do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
 	add_submenu_page(
-		$syndicationMenu, 'Categories'.FEEDWORDPRESS_AND_TAGS, 'Categories'.FEEDWORDPRESS_AND_TAGS,
+		$syndicationMenu, 'Categories & Tags', 'Categories & Tags',
 		$settings_cap, FeedWordPress::path('categories-page.php')
 	);
 
@@ -715,6 +708,9 @@ function fwp_add_pages () {
 		$syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
 		$settings_cap, FeedWordPress::path('diagnostics-page.php')
 	);
+	
+	add_filter('page_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
+	add_filter('post_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
 } /* function fwp_add_pages () */
 
 function fwp_check_debug () {
@@ -797,7 +793,13 @@ function fwp_publish_post_hook ($post_id) {
 }
 
 	function feedwordpress_add_post_edit_controls () {
+		global $feedwordpress;
+		
+		// Put in Manual Editing checkbox
 		add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
+		
+		add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
+		
 		if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
 			$GLOBALS['inspectPostMeta'] = new InspectPostMeta;
 		endif;
@@ -897,19 +899,60 @@ class FeedWordPress {
 	);
 
 	var $feeds = NULL;
-
+	var $feedurls = NULL;
 	var $httpauth = NULL;
+	
 	# function FeedWordPress (): Contructor; retrieve a list of feeds 
 	function FeedWordPress () {
 		$this->feeds = array ();
+		$this->feedurls  = array();
 		$links = FeedWordPress::syndicated_links();
 		if ($links): foreach ($links as $link):
-			$this->feeds[] = new SyndicatedLink($link);
+			$id = intval($link->link_id);
+			$url = $link->link_rss;
+			
+			// Store for later reference.
+			$this->feeds[$id] = $id;
+			if (strlen($url) > 0) :
+				$this->feedurls[$url] = $id;
+			endif;
 		endforeach; endif;
-		
+
 		$this->httpauth = new FeedWordPressHTTPAuthenticator;
 	} // FeedWordPress::FeedWordPress ()
 
+	function subscribed ($id) {
+		return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
+	} /* FeedWordPress::subscribed () */
+	
+	function subscription ($which) {
+		$sub = NULL;
+		
+		if (is_string($which) and isset($this->feedurls[$which])) :
+			$which = $this->feedurls[$which];
+		endif;
+		
+		if (isset($this->feeds[$which])) :
+			$sub = $this->feeds[$which];
+		endif;
+
+		// If it's not in the in-memory cache already, try to load it from DB.
+		// This is necessary to fill requests for subscriptions that we don't
+		// cache in memory, e.g. for deactivated feeds.
+		if (is_null($sub)) :
+			$sub = get_bookmark($which);
+		endif;
+
+		// Load 'er up if you haven't already.
+		if (!is_null($sub) and !($sub InstanceOf SyndicatedLink)) :
+			$link = new SyndicatedLink($sub);
+			$this->feeds[$which] = $link;
+			$sub = $link;
+		endif;
+		
+		return $sub;
+	} /* FeedWordPress::subscription () */
+	
 	# function update (): polls for updates on one or more Contributor feeds
 	#
 	# Arguments:
@@ -986,7 +1029,7 @@ class FeedWordPress {
 		endif;
 		
 		// Randomize order for load balancing purposes
-		$feed_set = $this->feeds;
+		$feed_set = array_keys($this->feeds);
 		shuffle($feed_set);
 
 		$updateWindow = (int) get_option('feedwordpress_update_window', DEFAULT_UPDATE_PERIOD) * 60 /* sec/min */;
@@ -1001,10 +1044,13 @@ class FeedWordPress {
 		), $uri);
 
 		$feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
-
+		
+	
 		// Loop through and check for new posts
 		$delta = NULL; $remaining = $max_polls;
-		foreach ($feed_set as $feed) :
+		foreach ($feed_set as $feed_id) :
+
+			$feed = $this->subscription($feed_id);
 
 			// Has this process overstayed its welcome?
 			if (
@@ -1157,6 +1203,38 @@ class FeedWordPress {
 		return $ret;
 	} // FeedWordPress::stale()
 
+	static function admin_init () {
+		// WordPress 3.5+ compat: the WP devs are in the midst of removing Links from the WordPress core. Eventually we'll have to deal
+		// with the possible disappearance of the wp_links table as a whole; but in the meantime, we just need to turn on the interface
+		// element to avoid problems with user capabilities that presume the presence of the Links Manager in the admin UI.
+		if (!intval(get_option('link_manager_enabled', false))) :
+			update_option('link_manager_enabled', true);
+		endif;
+	} /* FeedWordPress::admin_init() */
+
+	function admin_api () {
+		// This sucks, but WordPress doesn't give us any other way to
+		// easily invoke a permanent-delete from a plugged in post
+		// actions link. So we create a magic parameter, and when this
+		// magic parameter is activated, the WordPress trashcan is
+		// temporarily de-activated.
+		
+		if (MyPHP::request('fwp_post_delete')=='nuke') :
+			// Get post ID #
+			$post_id = MyPHP::request('post');
+			if (!$post_id) :
+				$post_id = MyPHP::request('post_ID');
+			endif;
+			
+			// Make sure we've got the right nonce and all that.
+			check_admin_referer('delete-post_' . $post_id);
+			
+			// If so, disable the trashcan.
+			define('EMPTY_TRASH_DAYS', 0);
+		endif;
+
+	}
+
 	function init () {
 		global $fwp_path;
 		
@@ -1174,15 +1252,185 @@ class FeedWordPress {
 			wp_enqueue_style('dashboard');
 			wp_enqueue_style('feedwordpress-elements');
 		
-			if (function_exists('wp_admin_css')) :
+			/*if (function_exists('wp_admin_css')) :
 				wp_admin_css('css/dashboard');
-			endif;
+			endif;*/
 		endif;
 
+		// This is a special post status for hiding posts that have expired
+		register_post_status('fwpretired', array(
+		'label' => _x('Retired', 'post'),
+		'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
+		'exclude_from_search' => true,
+		'public' => false,
+		'publicly_queryable' => false,
+		'show_in_admin_all_list' => false,
+		'show_in_admin_status_list' => true,
+		));
+		add_action(
+			/*hook=*/ 'template_redirect',
+			/*function=*/ array($this, 'redirect_retired'),
+			/*priority=*/ -100
+		);
+
+		add_action('wp_ajax_fwp_feeds', array($this, 'fwp_feeds'));
+		add_action('wp_ajax_fwp_feedcontents', array($this, 'fwp_feedcontents'));
+		add_action('wp_ajax_fwp_xpathtest', array($this, 'fwp_xpathtest'));
+		
 		$this->clear_cache_magic_url();
 		$this->update_magic_url();
 	} /* FeedWordPress::init() */
 	
+	function fwp_feeds () {
+		$feeds = array();
+		$feed_ids = $this->feeds;
+		
+		foreach ($feed_ids as $id) :
+			$sub = $this->subscription($id);
+			$feeds[] = array(
+			"id" => $id,
+			"url" => $sub->uri(),
+			"name" => $sub->name(/*fromFeed=*/ false),
+			);
+		endforeach;
+
+		header("Content-Type: application/json");	
+		echo json_encode($feeds);
+		exit;
+	}
+
+	function fwp_feedcontents () {
+		$feed_id = MyPHP::request('feed_id');
+		
+		// Let's load up some data from the feed . . .
+		$feed = $this->subscription($feed_id);
+		$posts = $feed->live_posts();
+		
+		if (is_wp_error($posts)) :
+			header("HTTP/1.1 502 Bad Gateway");
+			$result = $posts;
+		else :
+			$result = array();
+
+			foreach ($posts as $post) :
+				$p = new SyndicatedPost($post, $feed);
+				
+				$result[] = array(
+					"post_title" => $p->entry->get_title(),
+					"post_link" => $p->permalink(),
+					"guid" => $p->guid(),
+					"post_date" => $p->published(),
+				);
+			endforeach;
+		endif;
+		
+		header("Content-Type: application/json");
+		
+		echo json_encode($result);
+		
+		// This is an AJAX request, so close it out thus.
+		die;
+	} /* FeedWordPress::fwp_feedcontents () */
+	
+	function fwp_xpathtest () {
+		$xpath = MyPHP::request('xpath');
+		$feed_id = MyPHP::request('feed_id');
+		$post_id = MyPHP::request('post_id');
+		
+		$expr = new FeedWordPressParsedPostMeta($xpath);
+		
+		// Let's load up some data from the feed . . .
+		$feed = $this->subscription($feed_id);
+		$posts = $feed->live_posts();
+		
+		if (!is_wp_error($posts)) :
+			if (strlen($post_id) == 0) :
+				$post = $posts[0];
+			else :
+				$post = null;
+	
+				foreach ($posts as $p) :
+					if ($p->get_id() == $post_id) :
+						$post = $p;
+					endif;
+				endforeach;
+			endif;
+		
+			$post = new SyndicatedPost($post, $feed);
+			$meta = $expr->do_substitutions($post);
+			
+			$result = array(
+			"post_title" => $post->entry->get_title(),
+			"post_link" => $post->permalink(),
+			"guid" => $post->guid(),
+			"expression" => $xpath,
+			"results" => $meta
+			);
+		else :
+			$result = array(
+			"expression" => $xpath,
+			"feed_id" => $feed_id,
+			"post_id" => $post_id,
+			"results" => $posts
+			);
+			
+			header("HTTP/1.1 503 Bad Gateway");
+		endif;
+		
+		header("Content-Type: application/json");
+		
+		echo json_encode($result);
+		
+		// This is an AJAX request, so close it out thus.
+		die;
+	} /* FeedWordPress::fwp_xpathtest () */
+	
+	function redirect_retired () {
+		global $wp_query;
+		if (is_singular()) :
+			if ('fwpretired'==$wp_query->post->post_status) :
+				do_action('feedwordpress_redirect_retired', $wp_query->post);
+				
+				if (!($template = get_404_template())) :
+					$template = get_index_template();
+				endif;
+				if ($template = apply_filters('template_include', $template)) :
+					header("HTTP/1.1 410 Gone");
+					include($template);
+				endif;
+				exit;
+			endif;
+		endif;
+	}
+	
+	function row_actions ($actions, $post) {
+		if (is_syndicated($post->ID)) :
+			$link = get_delete_post_link($post->ID, '', true);
+			$link = MyPHP::url($link, array("fwp_post_delete" => "nuke"));
+			
+			$caption = 'Erase the record of this post (will be re-syndicated if it still appears on the feed).';
+			$linktext = 'Erase/Resyndicate';
+			
+			$keys = array_keys($actions);
+			$links = array();
+			foreach ($keys as $key) :
+				$links[$key] = $actions[$key];
+				
+				if ('trash'==$key) :
+					$links[$key] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash (will NOT be re-syndicated)' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash/Don&#8217;t Resyndicate' ) . "</a>";
+					
+					// Placeholder.
+					$links['delete'] = '';
+				endif;
+			endforeach;
+			
+			$links['delete'] = '<a class="submitdelete" title="'.esc_attr(__($caption)).'" href="' . $link . '">' . __($linktext) . '</a>';
+
+			$actions = $links;
+		endif;
+		return $actions;
+	}
+	
 	function dashboard_setup () {
 		$see_it = FeedWordPress::menu_cap();
 		
@@ -1202,12 +1450,12 @@ class FeedWordPress {
 			add_meta_box(
 				/*id=*/ $widget_id,
 				/*title=*/ $widget_name,
-				/*callback=*/ array(&$this, 'dashboard'),
+				/*callback=*/ array($this, 'dashboard'),
 				/*page=*/ 'dashboard',
 				/*context=*/ $column,
 				/*priority=*/ $priority
 			);
-			/*control_callback= array(&$this, 'dashboard_control') */
+			/*control_callback= array($this, 'dashboard_control') */
 			
 			// This is kind of rude, I know, but the dashboard widget isn't
 			// worth much if users don't know that it exists, and I don't
@@ -1244,6 +1492,20 @@ class FeedWordPress {
 		$syndicationPage->dashboard_box($syndicationPage);
 	} /* FeedWordPress::dashboard () */
 
+	function user_can_richedit ($rich_edit) {
+
+		$post = new FeedWordPressLocalPost;
+		
+		if (!$post->is_exposed_to_formatting_filters()) :
+			// Disable visual editor and only allow operations
+			// directly on HTML if post is bypassing fmt filters
+			$rich_edit = false;
+		endif;
+		
+		return $rich_edit;
+
+	} /* FeedWordPress::user_can_richedit () */
+	
 	function update_magic_url () {
 		global $wpdb;
 
@@ -1287,10 +1549,7 @@ class FeedWordPress {
 	} /* FeedWordPress::clear_cache_magic_url() */
 	
 	function clear_cache_requested () {
-		return (
-			isset($_GET['clear_cache'])
-			and $_GET['clear_cache']
-		);
+		return MyPHP::request('clear_cache');
 	} /* FeedWordPress::clear_cache_requested() */
 
 	function update_requested () {
@@ -1416,6 +1675,7 @@ class FeedWordPress {
 		else :
 			$links = array();
 		endif;
+
 		return $links;
 	} // function FeedWordPress::syndicated_links()
 
@@ -1604,11 +1864,11 @@ class FeedWordPress {
 		endif;
 		$timeout = intval($timeout);
 		
-		$pie_class = apply_filters('feedwordpress_simplepie_class', 'SimplePie');
+		$pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
 		$cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
 		$file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
 		$parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
-
+		$item_class = apply_filters('feedwordpress_item_class', 'FeedWordPie_Item');
 		$sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
 
 		$feed = new $pie_class;
@@ -1619,8 +1879,9 @@ class FeedWordPress {
 		$feed->set_content_type_sniffer_class($sniffer_class);
 		$feed->set_file_class($file_class);
 		$feed->set_parser_class($parser_class);
+		$feed->set_item_class($item_class);
 		$feed->force_feed($force_feed);
-		$feed->set_cache_duration(FeedWordPress::cache_duration());
+		$feed->set_cache_duration(FeedWordPress::cache_duration($params));
 		$feed->init();
 		$feed->handle_content_type();
 		
@@ -1657,9 +1918,15 @@ class FeedWordPress {
 		return ($magpies + $simplepies);
 	} /* FeedWordPress::clear_cache () */
 
-	function cache_duration () {
+	function cache_duration ($params = array()) {
+		$params = wp_parse_args($params, array(
+		"cache" => true,
+		));
+		
 		$duration = NULL;
-		if (defined('FEEDWORDPRESS_CACHE_AGE')) :
+		if (!$params['cache']) :
+			$duration = 0;
+		elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
 			$duration = FEEDWORDPRESS_CACHE_AGE;
 		endif;
 		return $duration;
@@ -1760,6 +2027,7 @@ class FeedWordPress {
 					error_log(FeedWordPress::log_prefix().' '.$out);
 					break;
 				case 'email' :
+					
 					if (is_null($persist)) :
 						$sect = 'occurrent';
 						$hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
@@ -1801,7 +2069,11 @@ class FeedWordPress {
 		return $ret;
 	}
 	
-	function email_diagnostic_log () {
+	function email_diagnostic_log ($params = array()) {
+		$params = wp_parse_args($params, array(
+		"force" => false,
+		));
+
 		$dlog = get_option('feedwordpress_diagnostics_log', array());
 		
 		if ($this->has_emailed_diagnostics($dlog)) :
@@ -1886,9 +2158,26 @@ EOMAIL;
 						$recipients = FeedWordPressDiagnostic::admin_emails();
 					endif;
 
+					$mesgId = 'feedwordpress+'.time().'@'.$home;
+					$parentId = get_option('feedwordpress_diagnostics_email_root_message_id', NULL);
+
+					$head = array("Message-ID: <$mesgId>");
+					if (!is_null($parentId)) :
+						// We've already sent off a diagnostic message in the past. Let's do some
+						// magic to help with threading, in the hopes that all diagnostic messages
+						// get threaded together.
+						$head[] = "References: <$parentId>";
+						$head[] = "In-Reply-To: <$parentId>";
+						$subj = "Re: ".$subj;
+					else :
+						// This is the first of its kind. Let's mark it as such.
+						update_option('feedwordpress_diagnostics_email_root_message_id', $mesgId);
+					endif;
+					$head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
+
 					foreach ($recipients as $email) :						
 						add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
-						wp_mail($email, $subj, $body);
+						wp_mail($email, $subj, $body, $head);
 						remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
 					endforeach;
 				endif;
@@ -1949,21 +2238,13 @@ EOMAIL;
 		return $path;
 	}
 	
+	// These are superceded by MyPHP::param/post/get/request, but kept
+	// here for backward compatibility.
 	function param ($key, $type = 'REQUEST', $default = NULL) {
-		$where = '_'.strtoupper($type);
-		$ret = $default;
-		if (isset($GLOBALS[$where]) and is_array($GLOBALS[$where])) :
-			if (isset($GLOBALS[$where][$key])) :
-				$ret = $GLOBALS[$where][$key];
-				if (get_magic_quotes_gpc()) :
-					$ret = stripslashes_deep($ret);
-				endif;
-			endif;
-		endif;
-		return $ret;
+		return MyPHP::param($key, $default, $type);
 	}
 	function post ($key, $default = NULL) {
-		return FeedWordPress::param($key, 'POST');
+		return MyPHP::post($key, $default);
 	}
 } // class FeedWordPress
 
diff --git a/wp-content/plugins/feedwordpress/feedwordpress_file.class.php b/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
index c78bbbd6329ee9425ef796de9cc6b6a49125405d..9130a710bb1092fa00d69c72bc657035f0143a45 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
@@ -7,25 +7,44 @@ class FeedWordPress_File extends WP_SimplePie_File {
 	}
 	
 	function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
+		global $feedwordpress;
+		global $wp_version;
+
+		$source = NULL;
+		if ($feedwordpress->subscribed($url)) :
+			$source = $feedwordpress->subscription($url);
+		endif;
+		
 		$this->url = $url;
 		$this->timeout = $timeout;
 		$this->redirects = $redirects;
 		$this->headers = $headers;
 		$this->useragent = $useragent;
-		
+
 		$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
 		
 		global $wpdb;
 		global $fwp_credentials;
 		
-		if ( preg_match('/^http(s)?:\/\//i', $url) ) {
+		if ( preg_match('/^http(s)?:\/\//i', $url) ) :
 			$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
 	
 			if ( !empty($this->headers) )
 				$args['headers'] = $this->headers;
 
-			if ( SIMPLEPIE_USERAGENT != $this->useragent ) //Use default WP user agent unless custom has been specified
+			// Use default FWP user agent unless custom has been specified
+			if ( SIMPLEPIE_USERAGENT != $this->useragent ) :
 				$args['user-agent'] = $this->useragent;
+			else :
+				$args['user-agent'] = apply_filters('feedwordpress_user_agent',
+					'FeedWordPress/'.FEEDWORDPRESS_VERSION
+					.' (aggregator:feedwordpress; WordPress/'.$wp_version
+					.' + '.SIMPLEPIE_NAME.'/'.SIMPLEPIE_VERSION
+					.'; Allow like Gecko; +http://feedwordpress.radgeek.com/) at '
+					. feedwordpress_display_url(get_bloginfo('url')),
+					$this
+				);
+			endif;
 
 			// This is ugly as hell, but communicating up and down the chain
 			// in any other way is difficult.
@@ -36,21 +55,17 @@ class FeedWordPress_File extends WP_SimplePie_File {
 				$args['username'] = $fwp_credentials['username'];
 				$args['password'] = $fwp_credentials['password'];
 
-			else :
-			
-				$links = $wpdb->get_results(
-					$wpdb->prepare("SELECT * FROM {$wpdb->links} WHERE link_rss = '%s'", $url)
-				);
-				if ($links) :
-					$source = new SyndicatedLink($links[0]);
-					$args['authentication'] = $source->authentication_method();
-					$args['username'] = $source->username();
-					$args['password'] = $source->password();
-				endif;
+			elseif ($source InstanceOf SyndicatedLink) :
+
+				$args['authentication'] = $source->authentication_method();
+				$args['username'] = $source->username();
+				$args['password'] = $source->password();
 			
 			endif;
-			
+
+			FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] &#8668; ".esc_html(FeedWordPress::val($args)));
 			$res = wp_remote_request($url, $args);
+			FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] &#8669; ".esc_html(FeedWordPress::val($res)));
 
 			if ( is_wp_error($res) ) {
 				$this->error = 'WP HTTP Error: ' . $res->get_error_message();
@@ -60,12 +75,22 @@ class FeedWordPress_File extends WP_SimplePie_File {
 				$this->body = wp_remote_retrieve_body( $res );
 				$this->status_code = wp_remote_retrieve_response_code( $res );
 			}
-		} else {
-			if ( ! $this->body = file_get_contents($url) ) {
-				$this->error = 'file_get_contents could not read the file';
-				$this->success = false;
-			}
-		}
+			
+			if ($source InstanceOf SyndicatedLink) :
+				$source->update_setting('link/filesize', strlen($this->body));
+				$source->update_setting('link/http status', $this->status_code);
+				$source->save_settings(/*reload=*/ true);
+			endif;
+		
+		// Do not allow schemes other than http(s)? for the time being.
+		// They are unlikely to be used; and unrestricted use of schemes
+		// allows for user to use an unrestricted file:/// scheme, which
+		// may result in exploits by WordPress users against the web
+		// hosting environment.
+		else :
+			$this->error = 'FeedWordPress only allows http or https URLs';
+			$this->success = false;
+		endif;
 
 		// SimplePie makes a strongly typed check against integers with
 		// this, but WordPress puts a string in. Which causes caching
diff --git a/wp-content/plugins/feedwordpress/feedwordpress_parser.class.php b/wp-content/plugins/feedwordpress/feedwordpress_parser.class.php
index 49c2239bffcdb543c2ff7ee4a571422624f8a418..971bb6c4cded9bcd0ba623ac3509e35981d17c48 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress_parser.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress_parser.class.php
@@ -1,6 +1,20 @@
 <?php
 class FeedWordPress_Parser extends SimplePie_Parser {
+	function reset_parser (&$xml) {
+		xml_parser_free($xml);
+				
+		$xml = xml_parser_create_ns($this->encoding, $this->separator);
+		xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
+		xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
+		xml_set_object($xml, $this);
+		xml_set_character_data_handler($xml, 'cdata');
+		xml_set_element_handler($xml, 'tag_open', 'tag_close');
+		xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
+	}
+	
 	function parse (&$data, $encoding) {
+		$data = apply_filters('feedwordpress_parser_parse', $data, $encoding, $this);
+		
 		// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
 		if (strtoupper($encoding) === 'US-ASCII')
 		{
@@ -40,7 +54,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
 
 		if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
 		{
-			$declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
+			$declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
 			if ($declaration->parse())
 			{
 				$data = substr($data, $pos + 2);
@@ -76,10 +90,37 @@ class FeedWordPress_Parser extends SimplePie_Parser {
 			xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
 
 			// Parse!
-			if (!xml_parse($xml, $data, true))
+			$parseResults = xml_parse($xml, $data, true);
+
+			$endOfJunk = strpos($data, '<?xml');
+			if (!$parseResults and $endOfJunk > 0) :
+				// There is some junk before the feed prolog. Try to get rid of it.
+				$newData = substr($data, $endOfJunk);
+				$newData = trim($newData);
+				$this->reset_parser($xml);
+			
+				$parseResults = xml_parse($xml, $newData, true);
+			endif;
+			
+			if (!$parseResults)
 			{
+				if (class_exists('DOMDocument')) :
+					libxml_use_internal_errors(true);	
+					$doc = new DOMDocument;
+					$doc->loadHTML('<html>'.$data.'</html>');
+					///*DBG*/ echo "<plaintext>";
+					///*DBG*/ $dd = $doc->getElementsByTagName('html');
+					///*DBG*/ for ($i = 0; $i < $dd->length; $i++) :
+					///*DBG*/		var_dump($dd->item($i)->nodeName);
+					///*DBG*/ endfor;
+					///*DBG*/ var_dump($doc);
+					libxml_use_internal_errors(false);
+					///*DBG*/ die;
+				endif;
+				
 				$this->error_code = xml_get_error_code($xml);
 				$this->error_string = xml_error_string($this->error_code);
+				///*DBG*/ echo "WOOGA WOOGA"; var_dump($this->error_string); die;
 				$return = false;
 			}
 
@@ -93,7 +134,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
 		else
 		{
 			libxml_clear_errors();
-			$xml =& new XMLReader();
+			$xml = new XMLReader();
 			$xml->xml($data);
 			while (@$xml->read())
 			{
diff --git a/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php b/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
index 1cefd5a5f5f8ec8566257ee2910584daa94d3312..91cb5ed9030abc99343c134beca4d324c5d9934f 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
@@ -38,7 +38,7 @@ class FeedWordPressHTML {
 		);
 	} /* function FeedWordPressHTML::attributeMatch () */
 
-	function tagWithAttributeRegex ($tag, $attr, $value) {
+	function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
 		return ":(
 		(<($tag)\s+[^>]*)
 		($attr)=
@@ -50,13 +50,14 @@ class FeedWordPressHTML {
 		|
 			\s*((?!/>)($value))
 			([^>]*>)
-		)
+		)".($closing ? "
 		(((?!</($tag)>).)*)
 		(</($tag)>)
+		" : "")."
 		:ix";
 	} /* FeedWordPressHTML::tagWithAttributeRegex () */
 
-	function tagWithAttributeMatch ($matches) {
+	function tagWithAttributeMatch ($matches, $closing = true) {
 		for ($i = 0; $i <= 21; $i++) :
 			if (!isset($matches[$i])) :
 				$matches[$i] = '';
@@ -77,8 +78,8 @@ class FeedWordPressHTML {
 		"before_attribute" => $matches[2],
 		"after_attribute" => $suffix,
 		"open_tag" => $matches[1].$matches[6].$value.$matches[6].$suffix,
-		"content" => $matches[17],
-		"close_tag" => $matches[20],
+		"content" => ($closing ? $matches[17] : NULL),
+		"close_tag" => ($closing ? $matches[20] : NULL),
 		);
 
 	} /* FeedWordPressHTML::tagWithAttributeMatch () */
diff --git a/wp-content/plugins/feedwordpress/feedwordpresshttpauthenticator.class.php b/wp-content/plugins/feedwordpress/feedwordpresshttpauthenticator.class.php
index 7434f1e6250fad1b94527b670d762c81340b8891..0a1bb42dbdcf8ebf8b19530627b3f66098d88b57 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresshttpauthenticator.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresshttpauthenticator.class.php
@@ -2,18 +2,14 @@
 class FeedWordPressHTTPAuthenticator {
 	var $args = array();
 	
-	function FeedWordPressHTTPAuthenticator () {
-		self::__construct();
-	}
-	
 	function __construct () {
-		add_filter('use_curl_transport', array(&$this, 'digest_do_it'), 2, 1000);
+		add_filter('use_curl_transport', array($this, 'digest_do_it'), 2, 1000);
 		foreach (array('fsockopen', 'fopen', 'streams', 'http_extension') as $transport) :
-			add_filter("use_{$transport}_transport", array(&$this, 'digest_dont'), 2, 1000);
+			add_filter("use_{$transport}_transport", array($this, 'digest_dont'), 2, 1000);
 		endforeach;
 		
-		add_filter('pre_http_request', array(&$this, 'pre_http_request'), 10, 3);
-		add_action('http_api_curl', array(&$this, 'set_auth_options'), 1000, 1);
+		add_filter('pre_http_request', array($this, 'pre_http_request'), 10, 3);
+		add_action('http_api_curl', array($this, 'set_auth_options'), 1000, 1);
 	} /* FeedWordPressHTTPAuthenticator::__construct () */
 
 	function methods_available () {
@@ -45,70 +41,74 @@ class FeedWordPressHTTPAuthenticator {
 		));
 		
 		// Ruh roh...
-		if (!is_null($this->args['authentication'])) :
-			switch ($this->args['authentication']) :
-			case '-' :
-				// No HTTP Auth method. Remove this stuff.
-				$this->args['authentication'] = NULL;
-				$this->args['username'] = NULL;
-				$this->args['password'] = NULL;
+		$auth = $this->args['authentication'];
+		if (is_null($auth) or (strlen($auth) == 0)) :
+			$this->args['authentication'] = '-';
+		endif;
+		
+		switch ($this->args['authentication']) :
+		case '-' :
+			// No HTTP Auth method. Remove this stuff.
+			$this->args['authentication'] = NULL;
+			$this->args['username'] = NULL;
+			$this->args['password'] = NULL;
+			break;
+		case 'basic' :
+			if ($this->have_curl($args, $url)) :
+				// Don't need to do anything. http_api_curl hook takes care
+				// of it.
 				break;
-			case 'basic' :
-				if ($this->have_curl($args, $url)) :
-					// Don't need to do anything. http_api_curl hook takes care
-					// of it.
-					break;
-				elseif ($this->have_streams($args, $url)) :
-					// curl has a nice native way to jam in the username and
-					// passwd but streams and fsockopen do not. So we have to
-					// make a recursive call with the credentials in the URL.
-					// Wee ha!
-					$method = $this->args['authentication'];
-					$credentials = $this->args['username'];
-					if (!is_null($this->args['password'])) :
-						$credentials .= ':'.$args['password'];
-					endif;
-					
-					// Remove these so we don't recurse all the way down
-					unset($this->args['authentication']);
-					unset($this->args['username']);
-					unset($this->args['password']);
-					
-					$url = preg_replace('!(https?://)!', '$1'.$credentials.'@', $url);
-					
-					// Subsidiary request
-					$pre = wp_remote_request($url, $this->args);
-					break;
-				endif;
-			case 'digest' :
-				if ($this->have_curl($args, $url)) :
-					// Don't need to do anything. http_api_curl hook takes care
-					// of it.
-					break;
-				endif;
-			default :
-				if (is_callable('WP_Http', '_get_first_available_transport')) :
-					$trans = WP_Http::_get_first_available_transport($args, $url);
-					if (!$trans) :
-						$trans = WP_Http::_get_first_available_transport(array(), $url);
-					endif;
-				elseif (is_callable('WP_Http', '_getTransport')) :
-					$transports = WP_Http::_getTransport($args);
-					$trans = get_class(reset($transports));
-				else :
-					$trans = 'HTTP';
+			elseif ($this->have_streams($args, $url)) :
+				// curl has a nice native way to jam in the username and
+				// passwd but streams and fsockopen do not. So we have to
+				// make a recursive call with the credentials in the URL.
+				// Wee ha!
+				$method = $this->args['authentication'];
+				$credentials = $this->args['username'];
+				if (!is_null($this->args['password'])) :
+					$credentials .= ':'.$args['password'];
 				endif;
 				
-				$pre = new WP_Error('http_request_failed',
-					sprintf(
-						__('%s cannot use %s authentication with the %s transport.'),
-						__CLASS__,
-						$args['authentication'],
-						$trans
-					)
-				);
-			endswitch;
-		endif;
+				// Remove these so we don't recurse all the way down
+				unset($this->args['authentication']);
+				unset($this->args['username']);
+				unset($this->args['password']);
+				
+				$url = preg_replace('!(https?://)!', '$1'.$credentials.'@', $url);
+				
+				// Subsidiary request
+				$pre = wp_remote_request($url, $this->args);
+				break;
+			endif;
+		case 'digest' :
+			if ($this->have_curl($args, $url)) :
+				// Don't need to do anything. http_api_curl hook takes care
+				// of it.
+				break;
+			endif;
+		default :
+			if (is_callable('WP_Http', '_get_first_available_transport')) :
+				$trans = WP_Http::_get_first_available_transport($args, $url);
+				if (!$trans) :
+					$trans = WP_Http::_get_first_available_transport(array(), $url);
+				endif;
+			elseif (is_callable('WP_Http', '_getTransport')) :
+				$transports = WP_Http::_getTransport($args);
+				$trans = get_class(reset($transports));
+			else :
+				$trans = 'HTTP';
+			endif;
+			
+			$pre = new WP_Error('http_request_failed',
+				sprintf(
+					__('%s cannot use %s authentication with the %s transport.'),
+					__CLASS__,
+					$args['authentication'],
+					$trans
+				)
+			);
+		endswitch;
+
 		return $pre;
 	} /* FeedWordPressHTTPAuthenticator::pre_http_request () */
 
diff --git a/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php b/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ff8af497a06b5392fa1a99b13bb4a690a28277a
--- /dev/null
+++ b/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php
@@ -0,0 +1,149 @@
+<?php
+
+class FeedWordPressLocalPost {
+	private $post;
+
+	public function __construct ($p = NULL) {
+		global $post;
+		
+		if (is_null($p)) :
+			$this->post = $post; // current post in loop
+		elseif (is_object($p)) :
+			$this->post = $p;
+		else :
+			$this->post = get_post($p);
+		endif;		
+	}
+	
+	public function id () {
+		return $this->post->ID;
+	}
+	
+	public function meta ($what, $params = array()) {
+
+		// -=-=-= 1. INITIAL SETUP. =-=-=-
+		$params = wp_parse_args($params, array(
+		"single" => true,
+		"default" => NULL,
+		"global" => NULL,
+		"unproxied setting" => NULL,
+		"unproxy" => false,
+		));
+	
+		// This is a little weird, just bear with me here.
+		$results = array();
+		
+		// Has this been left up to the admin setting?
+		if (is_null($params['unproxy'])) :
+			$params['unproxy'] = FeedWordPress::use_aggregator_source_data();
+		endif;
+	
+		// -=-=-= 2. GET DATA FROM THE PROXIMATE OR THE ULTIMATE SOURCE. =-=-=-
+
+		// Now if we are supposed to look for ultimate source data (e.g. from
+		// <atom:source> ... </atom:source> elements), do so here.
+		if ($params['unproxy']) :
+			if (!is_string($params['unproxied setting'])) :
+				// Default pattern for unproxied settings: {$name}_original
+				$params['unproxied setting'] = $what . '_original';
+			endif;
+			
+			// Now see if there's anything in postmeta from our ultimate source.
+			// If so, then we can cut out the middle man here.
+			$results = get_post_meta($this->post->ID, /*key=*/ $params['unproxied setting'], /*single=*/ false);
+		endif;
+
+		// If we weren't looking for ultimate source data, or if there wasn't
+		// any recorded, then grab this from the data for the proximate source.		
+		if (empty($results)) :
+			$results = get_post_meta($this->post->ID, /*key=*/ $what, /*single=*/ false);
+		endif;
+	
+		// -=-=-= 3. DEAL WITH THE RESULTS, IF ANY, OR FALLBACK VALUES. =-=-=-
+		
+		// If we have results now, cool. Just pass them back.
+		if (!empty($results)) :
+			$ret = ($params['single'] ? $results[0] : $results);
+			
+		// If we got no results but we have a fallback global setting, cool. Use
+		// that. Jam it into a singleton array for queries expecting an array of
+		// results instead of a scalar result.
+		elseif (is_string($params['global']) and strlen($params['global']) > 0) :
+			$opt = get_option($params['global'], $params['default']);
+			$ret = ($params['single'] ? $opt : array($opt));
+			
+		// If we got no results and we have no fallback global setting, pass
+		// back a default value for single-result queries, or an empty array for
+		// multiple-result queries.
+		else :
+			$ret = ($params['single'] ? $params['default'] : array());
+		endif;
+		
+		return $ret; 
+	}
+	
+	public function is_syndicated () {
+		return (!is_null($this->feed_id(/*single=*/ false))); 
+	}
+
+	public function syndication_permalink () {
+		return $this->meta('syndication_permalink');
+	}
+
+	public function feed () {
+			return $GLOBALS['feedwordpress']->subscription($this->feed_id());
+	}
+	
+	public function feed_id () {
+		return $this->meta('syndication_feed_id');
+	}
+
+	public function syndication_feed ($original = NULL) {
+		return $this->meta('syndication_feed', array("unproxy" => $original));
+	}
+	
+	public function syndication_feed_guid ($original = NULL) {
+		$ret = $this->meta('syndication_source_id', array("unproxy" => $original));
+		
+		// If this is blank, fall back to the full URL of the feed
+		if (is_null($ret) or strlen(trim($ret))==0) :
+			$ret = get_syndication_feed();
+		endif;
+	
+		return $ret;
+	}
+	
+	public function syndication_source ($original = NULL) {
+		$ret = $this->meta('syndication_source', array("unproxy" => $original));
+		
+		// If this is blank, fall back to a prettified URL for the blog.
+		if (is_null($ret) or strlen(trim($ret)) == 0) :
+			$ret = feedwordpress_display_url($this->syndication_source_link());
+		endif;
+		
+		return $ret;
+	}
+	
+	public function syndication_source_link ($original = NULL) {
+		return $this->meta('syndication_source_uri', array("unproxy" => $original));
+	}
+	
+	public function is_exposed_to_formatting_filters () {
+		
+		return (
+			!$this->is_syndicated()
+			or (
+				'yes' == $this->meta(
+					'_feedwordpress_formatting_filters',
+					array(
+						'global' => 'feedwordpress_formatting_filters',
+						'default' => 'no',
+					)
+				)
+			)
+		);
+		
+	} /* FeedWordPressLocalPost::is_exposed_to_formatting_filters () */
+	
+} /* class FeedWordPressLocalPost */
+
diff --git a/wp-content/plugins/feedwordpress/feedwordpressparsedpostmeta.class.php b/wp-content/plugins/feedwordpress/feedwordpressparsedpostmeta.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..c3c909926711b7ff03c5377107367073d5c18c15
--- /dev/null
+++ b/wp-content/plugins/feedwordpress/feedwordpressparsedpostmeta.class.php
@@ -0,0 +1,308 @@
+<?php
+class FeedWordPressParsedPostMeta {
+	var $s, $ptr, $ptrEOS;
+	var $delims, $delimCount, $delimPtr;
+	var $paren;
+
+	var $parsed = NULL;
+
+	function __construct ($s) {
+		$this->s = $s;
+		$this->reset();
+	}
+
+	function reset () {
+		$this->parsed = NULL;
+		
+		$this->ptr = 0;
+		$this->paren = 0;
+		$this->ptrEOS = strlen($this->s);
+	
+		$this->delimCount['CDATA'] = preg_match_all('/\$/', $this->s, $this->delims['CDATA'], PREG_OFFSET_CAPTURE);
+		$this->delimPtr['CDATA'] = 0;
+
+		$this->delimCount['EXPR'] = preg_match_all('/[()\s]/', $this->s, $this->delims['EXPR'], PREG_OFFSET_CAPTURE);
+		$this->delimPtr['EXPR'] = 0;
+	}
+
+	function look () { return $this->s[$this->ptr]; }
+	function drop () { $this->anchor = $this->ptr; }
+	function take () { return substr($this->s, $this->anchor, ($this->ptr - $this->anchor)); }
+	function EOS () { return ($this->ptr >= $this->ptrEOS); }
+
+	function nextDelim ($which) {
+		$N = $this->delimCount[$which]; $ptr = $this->delimPtr[$which];
+
+		$next = -1;
+		while ( ($ptr < $N) and ($next < $this->ptr) ) :
+			$next = $this->delims[$which][0][$ptr][1];
+			$ptr++;
+		endwhile;
+		$this->delimPtr[$which] = $ptr;
+
+		if ($next < $this->ptr) :
+			$next = $this->ptrEOS;
+		endif;
+		return $next;
+	}
+	
+	function substitute_terms ($post, $piece, $values = NULL) {
+		$terms = array();
+		if ('EXPR'==$piece[0]) :
+			// Parameter stored in $piece[1]
+			$param = $piece[1];
+			if (is_string($param)) :
+				if (!isset($values[$param])) :
+					$values[$param] = $post->query($param);
+				endif;
+				$term = $param;
+				$results = $values[$param];
+			else :
+				list($results, $term, $values) = $this->substitute_terms($post, $piece[1], $values);
+			endif;
+			
+			// Filtering function, if any, stored in $piece[2]
+			if (isset($piece[2])) :
+				$filter = $post->substitution_function(trim(strtolower($piece[2])));
+				if (!is_null($filter)) :
+					foreach ($results as $key => $result) :
+						$results[$key] = $filter($result);
+					endforeach;
+				else :
+					$results = array(
+						"[[ERR: No such function (".$piece[2].")]]",
+					);
+				endif;
+			endif;
+			
+		elseif ('CDATA'==$piece[0]) :
+			// Literal string stored in $piece[1]
+			$results = array($piece[1]);
+			$term = NULL;
+		endif;
+		return array($results, $term, $values);
+	}
+
+	function do_substitutions ($post, $in = NULL, $scratchpad = NULL) {
+		if (is_null($in)) :
+			$in = $this->get();
+		endif;
+		
+		if (count($in) > 0) :
+			$out = array();
+	
+			// Init. results set if not already initialized.
+			if (is_null($scratchpad)) :
+				$scratchpad = array(array('', array()));
+			endif;
+			
+			// Grab the first
+			$piece = array_shift($in);
+
+			foreach ($scratchpad as $key => $scratch) :
+				$line = $scratch[0];
+				$element_values = $scratch[1]; 
+
+				switch ($piece[0]) :
+				case 'CDATA' :
+					$subs = array($piece[1]);
+					$term = NULL;
+					break;
+				case 'EXPR' :
+					list($subs, $term, $element_values) = $this->substitute_terms($post, $piece, $element_values);
+					break;
+				endswitch;
+
+				$constrained_values = $element_values;
+				foreach ($subs as $sub) :
+					
+					if (isset($term)) :
+						$constrained_values[$term] = array($sub);
+					endif;
+				
+					$out[] = array($line . $sub, $constrained_values);
+				endforeach;
+				
+			endforeach;
+			
+			if (count($in) > 0) :
+				$out = $this->do_substitutions($post, $in, $out);
+			endif;
+		else :
+			$out = NULL;
+		endif;
+
+		// Now that we are done, strip out the namespace elements.
+		if (is_array($out)) :
+			foreach ($out as $idx => $line) :
+				if (is_array($line)) :
+					$out[$idx] = $line[0];
+				endif;
+			endforeach;
+		endif;
+		
+		return $out;
+	}
+		
+	function get ($idx = NULL) {
+		$ret = $this->parse();
+		if ($idx) : $ret = $ret[$idx]; endif;
+		
+		return $ret;
+	}
+	
+	function parse () {
+		if (is_null($this->parsed)) :
+			$out = array();
+			
+			$this->reset();
+			while (!$this->EOS()) :
+				switch ($this->look()) :
+				case '$' :
+					$this->ptr++;
+					$out[] = $this->EXPR();
+					break;
+				default :
+					$out[] = $this->CDATA();
+				endswitch;
+			endwhile;
+			
+			$this->parsed = $out;
+		endif;
+		return $this->parsed;
+	}
+
+	function CDATA () {
+		$this->drop();
+		$this->ptr = $this->nextDelim('CDATA');
+		return array(__FUNCTION__, $this->take());
+	} /* FeedWordPressParsedPostMeta::CDATA() */
+
+	function EXPR () {
+		$ret = array(__FUNCTION__);
+		$paren0 = $this->paren;
+		$this->drop();
+		
+		$ptr0 = $this->ptr;
+
+		$complete = false;
+		while (!$this->EOS() and !$complete) :
+			$tok = $this->look();
+			switch ($tok) :
+			case '(' :
+
+				$fun = $this->take();
+
+				// We're at the open paren; skip ahead past that.
+				$this->ptr++;
+
+				// And indent us one level in.
+				$this->paren++;
+				
+				$delta = $this->EXPR();
+				if (isset($delta[2])) :
+					$ret[1] = $delta;
+				else :
+					$ret[1] = $delta[1];
+				endif;
+
+				if (strlen(trim($fun)) > 0) :
+					$ret[2] = trim($fun);
+				endif;
+
+				// We should be stopped on either a close paren or on EOS.
+				$this->ptr++;
+
+				// A top level expression terminates
+				// immediately with the closing of its
+				// parens. Lower-level expressions may
+				// have whitespace wrapper, etc.
+				$complete = ($this->paren <= 0);
+
+				$this->drop();
+				break;
+
+			case ')' :
+
+				if ($this->paren > 0) :
+					$this->paren--;
+
+					$complete = ($this->paren <= $paren0);
+
+					$fun = $this->take();
+					if (strlen(trim($fun)) > 0) :
+						$ret[1] = trim($fun);
+					endif;
+
+					$this->drop();
+				else :
+					$this->ptr++;
+				endif;
+				break;
+			
+			case '$' :
+				if ($ptr0 == $this->ptr) :
+					// This is an escaped literal $
+					$this->ptr++;
+					$ret = array('CDATA', $tok);
+					$this->drop();
+					$complete = true;
+					break;
+				endif;
+
+			default :
+				if (ctype_space($tok) and ($this->paren <= 0)) :
+					// A loose $ should be treated as a literal $
+					if ($ptr0 == $this->ptr) :
+						$ret = array('CDATA', '$');
+						$this->drop();
+					endif;
+					$complete = true;
+				else :
+					$next = $this->nextDelim('EXPR');
+
+					// Skip ahead to the next potentially interesting character.
+					if (!is_null($next)) :
+						$this->ptr = $next;
+					else :
+						$this->ptr = $this->ptrEOS;
+					endif;
+				
+				endif;
+			endswitch;
+		endwhile;
+
+		$var = '';
+		if ($this->anchor < $this->ptr) :
+			$var = trim($this->take());
+		endif;
+		if (strlen($var) > 0) :
+			$ret[1] = $var;
+		endif;
+		return $ret;
+	} /* FeedWordPressParsedPostMeta::EXPR () */
+} /* class FeedWordPressParsedPostMeta */
+
+if (basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__)) :
+	$argv = $_SERVER['argv'];
+	array_shift($argv);
+	$N = reset($argv);
+	if (is_numeric($N)) :
+		array_shift($argv);
+	else :
+		$N = 1;
+	endif;
+
+	$t0 = microtime(/*float=*/ true);
+	for ($i = 0; $i < $N; $i++) :
+		$parse = new FeedWordPressParsedPostMeta(implode(" ", $argv));
+		$voo = ($parse->parse());
+		unset($parse);
+	endfor;
+	$t1 = microtime(/*float=*/ true);
+
+	echo "RESULT: "; var_dump($voo);
+	echo "ELAPSED TIME: "; print number_format(1000.0 * ($t1 - $t0)) . "ms\n";
+	echo "CONSUMED MEMORY: ";  print number_format(memory_get_peak_usage() / 1024) . "KB\n";
+endif;
+
diff --git a/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php b/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
index ead601c558a73075fe0b31037beb2477fbe0ff56..040e74aa8113f1920b63a1190062e51fdb5d1c2c 100644
--- a/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
@@ -5,15 +5,15 @@
 
 class FeedWordPressRPC {
 	function FeedWordPressRPC () {
-		add_filter('xmlrpc_methods', array(&$this, 'xmlrpc_methods'));
+		add_filter('xmlrpc_methods', array($this, 'xmlrpc_methods'));
 	}
 	
 	function xmlrpc_methods ($args = array()) {
-		$args['weblogUpdates.ping'] = array(&$this, 'ping');
-		$args['feedwordpress.subscribe'] = array(&$this, 'subscribe');
-		$args['feedwordpress.deactivate'] = array(&$this, 'deactivate');
-		$args['feedwordpress.delete'] = array(&$this, 'delete');
-		$args['feedwordpress.nuke'] = array(&$this, 'nuke');
+		$args['weblogUpdates.ping'] = array($this, 'ping');
+		$args['feedwordpress.subscribe'] = array($this, 'subscribe');
+		$args['feedwordpress.deactivate'] = array($this, 'deactivate');
+		$args['feedwordpress.delete'] = array($this, 'delete');
+		$args['feedwordpress.nuke'] = array($this, 'nuke');
 		return $args;
 	}
 	
diff --git a/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php b/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
index 3a08b094258922e7cbbfdbdc93d2c5111cb82bed..e60e704e6d655612aa4087220c5842662142598e 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
@@ -82,8 +82,8 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 
 		$update_set = array();
 		if ($fwp_update_invoke != 'get') :
-			if (is_array(FeedWordPress::post('link_ids'))
-			and (FeedWordPress::post('action')==FWP_UPDATE_CHECKED)) :
+			if (is_array(MyPHP::post('link_ids'))
+			and (MyPHP::post('action')==FWP_UPDATE_CHECKED)) :
 				$targets = $wpdb->get_results("
 				SELECT * FROM $wpdb->links
 				WHERE link_id IN (".implode(",",$_POST['link_ids']).")
@@ -95,8 +95,8 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 				else : // This should never happen
 					FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__, __FILE__);
 				endif;
-			elseif (!is_null(FeedWordPress::post('update_uri'))) :
-				$targets = FeedWordPress::post('update_uri');
+			elseif (!is_null(MyPHP::post('update_uri'))) :
+				$targets = MyPHP::post('update_uri');
 				if (!is_array($targets)) :
 					$targets = array($targets);
 				endif;
@@ -340,8 +340,6 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 			return;
 		endif;
 		
-		?>
-		<?php
 		$cont = true;
 		$dispatcher = array(
 			"feedfinder" => 'fwp_feedfinder_page',
@@ -352,8 +350,10 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 			'Unsubscribe' => 'multidelete_page',
 			FWP_RESUB_CHECKED => 'multiundelete_page',
 		);
-		if (isset($_REQUEST['action']) and isset($dispatcher[$_REQUEST['action']])) :
-			$method = $dispatcher[$_REQUEST['action']];
+		
+		$act = MyPHP::request('action');
+		if (isset($dispatcher[$act])) :
+			$method = $dispatcher[$act];
 			if (method_exists($this, $method)) :
 				$cont = $this->{$method}();
 			else :
@@ -384,7 +384,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 			add_meta_box(
 				/*id=*/ 'feedwordpress_feeds_box',
 				/*title=*/ __('Syndicated sources'),
-				/*callback=*/ array(&$this, 'syndicated_sources_box'),
+				/*callback=*/ array($this, 'syndicated_sources_box'),
 				/*page=*/ $this->meta_box_context(),
 				/*context =*/ $this->meta_box_context()
 			);
@@ -431,10 +431,11 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 		
 		// Hey ho, let's go...
 		?>
+		<div style="float: left; background: #F5F5F5; padding-top: 5px; padding-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_html(WP_PLUGIN_URL.'/'.$GLOBALS['fwp_path'].'/feedwordpress.png'); ?>" alt="" /></a></div>
+
 		<p class="info" style="margin-bottom: 0px; border-bottom: 1px dotted black;">Managed by <a href="http://feedwordpress.radgeek.com/">FeedWordPress</a>
 		<?php print FEEDWORDPRESS_VERSION; ?>.</p>
 		<?php if (FEEDWORDPRESS_BLEG) : ?>
-		<div style="float: left; background: white; margin-top: 5px; margin-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_html(WP_PLUGIN_URL.'/'.$GLOBALS['fwp_path'].'/feedwordpress.png'); ?>" alt="" /></a></div>
 		<p class="info" style="margin-top: 0px; font-style: italic; font-size: 75%; color: #666;">If you find this tool useful for your daily work, you can
 		contribute to ongoing support and development with
 		<a href="http://feedwordpress.radgeek.com/donate/">a modest donation</a>.</p>
@@ -488,8 +489,8 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 		  value="Source URL" style="width: 55%;" /></label>
 		
 		  <?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
-		
-		  <input style="vertical-align: middle;" type="image" src="<?php print WP_PLUGIN_URL.'/'.$fwp_path; ?>/plus.png" alt="<?php print FWP_SYNDICATE_NEW; ?>" name="action" value="<?php print FWP_SYNDICATE_NEW; ?>" /></div>
+		  <input type="hidden" name="action" value="<?php print FWP_SYNDICATE_NEW; ?>" />
+		  <input style="vertical-align: middle;" type="image" src="<?php print WP_PLUGIN_URL.'/'.$fwp_path; ?>/plus.png" alt="<?php print FWP_SYNDICATE_NEW; ?>" /></div>
 		  </form>
 		</div> <!-- id="add-single-uri" -->
 		
@@ -733,16 +734,12 @@ regular donation</a>) using an existing PayPal account or any major credit card.
 				// ... and kill them all
 				if (count($post_ids) > 0) :
 					foreach ($post_ids as $post_id) :
-						if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_29)) :
-							// Force scrubbing of deleted post
-							// rather than sending to Trashcan
-							wp_delete_post(
-								/*postid=*/ $post_id,
-								/*force_delete=*/ true
-							);
-						else :
-							wp_delete_post($post_id);
-						endif;
+						// Force scrubbing of deleted post
+						// rather than sending to Trashcan
+						wp_delete_post(
+							/*postid=*/ $post_id,
+							/*force_delete=*/ true
+						);
 					endforeach;
 				endif;
 	
@@ -1144,14 +1141,14 @@ updated to &lt;<a href="<?php echo esc_html($fwp_post['feed']); ?>"><?php echo e
 	endif;
 
 	if (isset($existingLink)) :
-		$auth = FeedWordPress::post('link_rss_auth_method');
-		if (!is_null($auth) and $auth != '-') :
+		$auth = MyPHP::post('link_rss_auth_method');
+		if (!is_null($auth) and (strlen($auth) > 0) and ($auth != '-')) :
 			$existingLink->update_setting('http auth method', $auth);
 			$existingLink->update_setting('http username',
-				FeedWordPress::post('link_rss_username')
+				MyPHP::post('link_rss_username')
 			);
 			$existingLink->update_setting('http password',
-				FeedWordPress::post('link_rss_password')
+				MyPHP::post('link_rss_password')
 			);
 		else :
 			$existingLink->update_setting('http auth method', NULL);
diff --git a/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php b/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
index f20041bda80aa63bc2743fdbd57739db3330bb7c..40c8d7f251a183161af73b139323962bdbcc86d3 100644
--- a/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
+++ b/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
@@ -155,7 +155,8 @@ class MagpieFromSimplePie {
 				endforeach;
 			endforeach;
 		endforeach; endif;
-		return $ret;
+		
+		return apply_filters('feedwordpress_magpiefromsimplepie_processfeeddata', $ret, $data, $this);
 	} /* MagpieFromSimplePie::processFeedData() */
 
 	/**
@@ -183,7 +184,7 @@ class MagpieFromSimplePie {
 			+ $this->handleChildren($data, $path, 'processChannelData')
 			+ $ret;
 
-		return $ret;
+		return apply_filters('feedwordpress_magpiefromsimplepie_processchanneldata', $ret, $data, $path, $this);
         } /* MagpieFromSimplePie::processChannelData() */
 
 	/**
@@ -213,7 +214,7 @@ class MagpieFromSimplePie {
 			+ $this->handleChildren($data, $path, 'processItemData')
 			+ $ret;
 
-		return $ret;
+		return apply_filters('feedwordpress_magpiefromsimplepie_processitemdata', $ret, $data, $path, $this);
 	} /* MagpieFromSimplePie::processItemData() */
 
 	/**
@@ -250,7 +251,8 @@ class MagpieFromSimplePie {
 				endif;
 			endforeach;
 		endforeach; endif;
-		return $ret;
+
+		return apply_filters('feedwordpress_magpiefromsimplepie_handleattributes', $ret, $data, $path, $this);
 	} /* MagpieFromSimplePie::handleAttributes() */
 	
 	var $inImage = false;
@@ -346,7 +348,8 @@ class MagpieFromSimplePie {
 			endforeach; endforeach;
 			
 		endforeach; endif;
-		return $ret;
+
+		return apply_filters('feedwordpress_magpiefromsimplepie_handlechildren', $ret, $data, $path, $method, $this);
 	} /* MagpieFromSimplePie::handleChildren() */
 
 	/**
@@ -386,6 +389,8 @@ class MagpieFromSimplePie {
 	 * @uses FeedTime::timestamp
 	 */
 	function normalize () {
+		do_action('feedwordpress_magpiefromsimplepie_normalize_pre', $this);
+
 		if (!is_null($this->channel)) :
 			// Normalize channel data
 			if ( $this->is_atom() ) :
@@ -497,6 +502,8 @@ class MagpieFromSimplePie {
 				$this->items[$i] = $item;
 			endfor;
 		endif;
+		
+		do_action('feedwordpress_magpiefromsimplepie_normalize_post', $this);
 	} /* MagpieFromSimplePie::normalize() */
 
 	/**
diff --git a/wp-content/plugins/feedwordpress/performance-page.php b/wp-content/plugins/feedwordpress/performance-page.php
index 0762318f3359af73a99a963a4960d2ef7e235f3b..e1928d1fc6472cd2b521f88c8b616c3f9c645208 100644
--- a/wp-content/plugins/feedwordpress/performance-page.php
+++ b/wp-content/plugins/feedwordpress/performance-page.php
@@ -79,9 +79,19 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
 			$feeds = (($N == 1) ? __("feed") : __("feeds"));
 			$this->updated = sprintf(__("Cleared %d cached %s from WordPress database."), $N, $feeds);
 		endif;
+		
+		if (isset($post['optimize_in'])) :
+			update_option('feedwordpress_optimize_in_clauses', true);
+			$this->updated = sprintf(__("Enabled optimizing inefficient IN clauses in SQL queries."));
+		elseif (isset($post['optimize_out'])) :
+			update_option('feedwordpress_optimize_in_clauses', false);
+			$this->updated = sprintf(__("Disabled optimizing inefficient IN clauses in SQL queries."));
+		endif;
 	} /* FeedWordPressPerformancePage::accept_POST () */
 
 	/*static*/ function performance_box ($page, $box = NULL) {
+		$optimize_in = get_option('feedwordpress_optimize_in_clauses', false);
+		
 		// Hey ho, let's go...
 		?>
 <table class="editform" width="100%" cellspacing="2" cellpadding="5">
@@ -106,6 +116,34 @@ table. If you'd like to remove the index for any reason, you can do so here.</p>
 
 <?php endif; ?>
 
+<tr style="vertical-align: top">
+<th width="33%" scope="row">Optimize IN clauses:</th>
+<td width="67%"><?php if (!$optimize_in) : ?>
+<input class="button" type="submit" name="optimize_in" value="Optimize inefficient IN clauses in SQL queries" />
+
+<p><strong>Advanced setting.</strong> As of releases up to 3.3.2, WordPress
+still generates many SQL queries with an extremely inefficient use of the IN
+operator (for example, <code>SELECT user_id, meta_key, meta_value FROM
+wp_usermeta WHERE user_id IN (1)</code>). When there is only one item in the
+set, the IN operator is unnecessary; and inefficient, because it prevents SQL
+from making use of indexes on the table being queried. Activating this setting
+will cause these queries to get rewritten to use a simple equality operator when
+there is only one item in the set (for example, the example query above would be
+rewritten as <code>SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE
+user_id = 1</code>).</p>
+
+<p><strong>Note.</strong> This is an advanced setting, which affects WordPress's
+database queries at a very low level. The change should be harmless, but
+proceed with caution, and only if you are confident in your ability to restore
+your WordPress installation from backups if something important should stop
+working.</p>
+
+<?php else : ?>
+<input class="button" type="submit" name="optimize_out" value="Disable optimizing inefficient IN clauses" />
+<p>You can use this setting to disable any attempts by FeedWordPress to optimize
+or rewrite WordPress's SQL queries.</p>
+<?php endif; ?></td>
+</tr>
 
 </td>
 </tr>
diff --git a/wp-content/plugins/feedwordpress/posts-page.php b/wp-content/plugins/feedwordpress/posts-page.php
index 4d0bf9e7d93cab037819c6d9177a34cf00882691..c7e09ccfd208119db2f58de7063e43cfa867f3b0 100644
--- a/wp-content/plugins/feedwordpress/posts-page.php
+++ b/wp-content/plugins/feedwordpress/posts-page.php
@@ -133,7 +133,6 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
 	 * @uses FeedWordPressPostsPage::these_posts_phrase()
 	 * @uses FeedWordPress::syndicated_status()
 	 * @uses SyndicatedLink::syndicated_status()
-	 * @uses SyndicatedPost::use_api()
 	 */ 
 	/*static*/ function publication_box ($page, $box = NULL) {
 		$thesePosts = $page->these_posts_phrase();
@@ -419,12 +418,16 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
 
 		<?php
 		$i = 0;
-		foreach ($custom_settings as $key => $value) :
+		$testerButton = '<br/><button id="xpath-test-%d"'
+			.'class="xpath-test"'
+			.'>test expression</button>';
+		foreach ($custom_settings as $key => $value) : 
 		?>
 		  <tr style="vertical-align:top">
 		    <th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo esc_html($key); ?>" />
 		    <input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo esc_html($key); ?>" /></th>
-		    <td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo esc_html($value); ?></textarea></td>
+		    <td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo esc_html($value); ?></textarea>
+		    <?php print sprintf($testerButton, $i); ?></td>
 		    <td width="10%"><select name="notes[<?php echo $i; ?>][action]">
 		    <option value="update">save changes</option>
 		    <option value="delete">delete this setting</option>
@@ -438,7 +441,7 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
 
 		  <tr style="vertical-align: top">
 		    <th scope="row"><input type="text" size="10" name="notes[<?php echo $i; ?>][key1]" value="" /></th>
-		    <td><textarea name="notes[<?php echo $i; ?>][value]" rows="2" cols="40"></textarea>
+		    <td><textarea name="notes[<?php echo $i; ?>][value]" rows="2" cols="40"></textarea><?php print sprintf($testerButton, $i); ?>
 		      <p>Enter a text value, or a path to a data element from the syndicated item.<br/>
 		      For data elements, you can use an XPath-like syntax wrapped in <code>$( ... )</code>.<br/>
 		      <code>hello</code> = the text value <code><span style="background-color: #30FFA0;">hello</span></code><br/>
diff --git a/wp-content/plugins/feedwordpress/readme.txt b/wp-content/plugins/feedwordpress/readme.txt
index d4bb3f2b635754a3c01a6d21cafb4780f5524644..e711e099617e5d9254f93a49af40f8a749d4b431 100644
--- a/wp-content/plugins/feedwordpress/readme.txt
+++ b/wp-content/plugins/feedwordpress/readme.txt
@@ -3,15 +3,15 @@ Contributors: Charles Johnson
 Donate link: http://feedwordpress.radgeek.com/
 Tags: syndication, aggregation, feed, atom, rss
 Requires at least: 3.0
-Tested up to: 3.2.1
-Stable tag: 2011.1019
+Tested up to: 3.5.1
+Stable tag: 2013.0503
 
 FeedWordPress syndicates content from feeds you choose into your WordPress weblog. 
 
 == Description ==
 
 * Author: [Charles Johnson](http://radgeek.com/contact)
-* Project URI: <http://projects.radgeek.com/feedwordpress>
+* Project URI: <http://feedwordpress.radgeek.com/>
 * License: GPL 2. See License below for copyright jots and tittles.
 
 FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content
@@ -94,6 +94,120 @@ outs, see the documentation at the [FeedWordPress project homepage][].
 
 == Changelog ==
 
+= 2012.0503 =
+
+*	BUGFIX: Works properly again with WordPress installations that use a
+	MySQL table name prefix other than the default `wp_` prefix.
+	
+*	BUGFIX: Includes a couple of significant PHP 5.4 compatibility fixes.
+	Now that PHP 5.4 is more widely deployed, Diagnostics will now also
+	show PHP version and some other potentially useful troubleshooting
+	information.
+
+*	ADMIN UI: Better indicates your options when deleting a syndicated post
+	so as to let you know whether it will be Trashed (and thus not
+	resyndicated) or Erased (and thus potentially resyndicated)
+	
+*	ADMIN UI: Adds an AJAXy Test Expression button to allow live testing of
+	sample results from expressions in Custom Post Settings.
+
+= 2012.1218 =
+
+*	WORDPRESS VISUAL EDITOR FIXED. There was an unlisted change in the
+	2012.1212 release which had the effect of disabling the WordPress Visual
+	Editor for all posts syndicated by FeedWordPress. Many users reported
+	this as a bug. It was actually a deliberate decision -- a crappy way to
+	try to deal with a crappy situation. (Many users had previously reported
+	a "bug" in which all the paragraph or line breaks seemed to be stripped
+	out of their syndicated posts; the issue turned out to be that the
+	Visual Editor was stripping out `<p>` and `<br/>` tags on the assumption
+	that the resulting post would be sent through standard WordPress
+	formatting filters. But under default settings, posts syndicated by FWP
+	deliberately bypass WordPress formatting filters.) In any case, this
+	version adopts a more flexible compromise. *If* FeedWordPress is set up
+	to bypass WordPress formatting filters (as it is by default), *then*
+	the Visual Editor will be disabled for syndicated posts (since using it
+	would produce incorrect results). If on the other hand FeedWordPress is
+	set up to expose syndicated posts to WordPress formatting filters (as it
+	usually is for those using the Visual Editor to manually edit posts),
+	then the Visual Editor tab will be re-enabled for syndicated posts.
+	
+* 	BUG FIX: PERMALINKS REWRITTEN FOR CUSTOM POST TYPES AS WELL AS NORMAL
+	WORDPRESS POSTS. If you had WordPress set up to syndicate incoming posts
+	to a custom post type (under Syndication > Posts & Links), and asked
+	FeedWordPress to make "permalinks point to the original site", then
+	previous versions of FeedWordPress would fail to do the rewriting --
+	permalinks would only be rewritten to point to the original source for
+	normal WordPress posts, not for custom post types. In 2012.1218 this bug
+	has been fixed: all post types will now have permalinks rewritten unless
+	you request for permalinks to point to the local copy on your aggregator
+	site.
+	
+*	BUG FIX: ELIMINATES "PHP Fatal error: Call to a member function
+	setting() on a non-object...." Some changes to the in-memory caching of
+	information about feed subscriptions could result in a fatal PHP error
+	in cases where you have de-activated one of your subscriptions, but
+	posts from that subscription were still in the archive. This would
+	normally show up through half-completed feeds or half-completed pages
+	that suddenly broke off in the middle, and displayed or logged an error
+	message like: "PHP Fatal error: Call to a member function setting() on a
+	non-object in {...}/wp-content/plugins/feedwordpress/feedwordpress.php
+	on line 615". This bug has been eliminated, so affected feeds and pages
+	should now render correctly, and the error message should no longer
+	appear.
+
+*	BUG FIX: CATEGORY BOXES IN SYNDICATION > CATEGORIES & TAGS. Some minor
+	bugs in the appearance and animation of category checkboxes (for
+	example, the checkbox used to select categories for syndicated posts on
+	the Syndication > Categories & Tags settings page) have been fixed.
+	
+= 2012.1212 =
+
+*	WORDPRESS 3.5 COMPATIBILITY: This release has been tested for compatibility
+	with new releases of WordPress, up to version 3.5, and any documented
+	compatibility issues have been cleared -- in particular, if you were seeing
+	error pages stating that you don't have permission to access the
+	FeedWordPress Syndication page within the WordPress admin interface, then
+	upgrading to this release should fix the problem.
+
+	As always, if you encounter any compatibility problems after upgrading your
+	version of WordPress and your version of FeedWordPress to the most recent
+	versions, please contact me with as detailed a description as possible of
+	the issue you are encountering, the circumstances you're encountering it
+	under, what you expect to see happening, and what is happening instead.
+
+*	PHP 5.4 COMPATIBILITY: This release has been audited to fix potential
+	problems with deprecation notices or fatal errors under recent versions
+	of PHP. In particular, all uses of run-time pass-by-reference have been
+	eliminated from the code; if you were seeing a fatal error reading
+	"Call-time pass-by-reference has been removed ..." then upgrading to
+	this release should fix the problem.
+
+*	CUSTOMIZATION FRAMEWORK: A great deal of work has been done to make the
+	underlying framework more flexible, so that PHP add-ons can be written
+	to adapt FeedWordPress to handle custom XML vocabularies, expiration of
+	posts under specified conditions, and other custom behavior.
+
+*	BUGFIX: MANUALLY EDITED POST SLUGS NOT OVERWRITTEN. Thanks to a report
+	by Chris Fritz, I've identified some code that causes post slugs for the
+	posts generated by FWP to be rewritten with every update, even if the
+	user has manually updated the slug from within the WordPress editing
+	interface. This has been fixed: FWP will continue to generate new slugs
+	for syndicated posts, but when syndicated posts are updated, they will
+	retain the slug that they had at the time of the update; any manual
+	changes to the post slug should be preserved.
+	
+*	USER-AGENT STRING: FeedWordPress now sends a distinctive User-Agent
+	string identifying itself, and noting that it is a feed aggregator.
+
+*	MISCELLANEOUS PERFORMANCE IMPROVEMENTS: A number of changes have been
+	made to try to reduce the intensity and expense in terms of both
+	database performance and web server memory consumption.
+
+*	DIAGNOSTICS IMPROVEMENTS: A number of new and improved diagnostics have
+	been added which should aid in understanding and troubleshooting issues
+	that may arise.
+
 = 2011.1019 =
 
 *	BUGFIX: "THERE ARE NO HTTP TRANSPORTS AVAILABLE" ERROR FIXED: The initial
@@ -1842,7 +1956,8 @@ The FeedWordPress plugin is copyright © 2005-2010 by Charles Johnson. It uses
 code derived or translated from:
 
 -	[wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
--	[MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
+-	[SimplePie][] feed parser by Ryan Parman, Geoffrey Sneddon, Ryan McCue, et al.
+-	[MagpieRSS][] feed parser by [Kellan Elliot-McCrea](kellan@protest.net)
 -	[Ultra-Liberal Feed Finder][] by [Mark Pilgrim](mark@diveintomark.org)
 -	[WordPress Blog Tool and Publishing Platform](http://wordpress.org/)
 
@@ -1858,8 +1973,8 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
   [wp-rss-aggregate.php]: http://laughingmeme.org/archives/002203.html
+  [SimplePie]: http://www.simplepie.org/
   [MagpieRSS]: http://magpierss.sourceforge.net/
-  [HTTP Navigator 2]: http://www.keyvan.net/2004/11/16/http-navigator/
   [Ultra-Liberal Feed Finder]: http://diveintomark.org/projects/feed_finder/
   [GNU General Public License]: http://www.gnu.org/copyleft/gpl.html
 
diff --git a/wp-content/plugins/feedwordpress/syndicatedlink.class.php b/wp-content/plugins/feedwordpress/syndicatedlink.class.php
index 93b809c428bcee2a06604b2e5bdae28990f449df..0e8904044cd85226bc4f52536ec3cb69d85fa45a 100644
--- a/wp-content/plugins/feedwordpress/syndicatedlink.class.php
+++ b/wp-content/plugins/feedwordpress/syndicatedlink.class.php
@@ -34,6 +34,7 @@
 #	the function `get_feed_meta($key)` if this plugin is activated.
 
 require_once(dirname(__FILE__).'/magpiefromsimplepie.class.php');
+require_once(dirname(__FILE__).'/feedwordpressparsedpostmeta.class.php');
 
 class SyndicatedLink {
 	var $id = null;
@@ -49,121 +50,25 @@ class SyndicatedLink {
 			$this->link = $link;
 			$this->id = $link->link_id;
 		else :
-			$this->id = $link;
-			if (function_exists('get_bookmark')) : // WP 2.1+
-				$this->link = get_bookmark($link);
-			else :
-				$this->link = $wpdb->get_row("
-				SELECT * FROM $wpdb->links
-				WHERE (link_id = '".$wpdb->escape($link)."')"
-				);
-			endif;
+			$this->id = $link;			
+			$this->link = get_bookmark($link);
 		endif;
 
 		if (strlen($this->link->link_rss) > 0) :
-			// Read off feed settings from link_notes
-			$notes = explode("\n", $this->link->link_notes);
-			foreach ($notes as $note):
-				$pair = explode(": ", $note, 2);
-				$key = (isset($pair[0]) ? $pair[0] : null);
-				$value = (isset($pair[1]) ? $pair[1] : null);
-				if (!is_null($key) and !is_null($value)) :
-					// Unescape and trim() off the whitespace.
-					// Thanks to Ray Lischner for pointing out the
-					// need to trim off whitespace.
-					$this->settings[$key] = stripcslashes (trim($value));
-				endif;
-			endforeach;
-
-			// "Magic" feed settings
-			$this->settings['link/uri'] = $this->link->link_rss;
-			$this->settings['link/name'] = $this->link->link_name;
-			$this->settings['link/id'] = $this->link->link_id;
-			
-			// `hardcode categories` and `unfamiliar categories` are deprecated in favor of `unfamiliar category`
-			if (
-				isset($this->settings['unfamiliar categories'])
-				and !isset($this->settings['unfamiliar category'])
-			) :
-				$this->settings['unfamiliar category'] = $this->settings['unfamiliar categories'];
-			endif;
-			if (
-				FeedWordPress::affirmative($this->settings, 'hardcode categories')
-				and !isset($this->settings['unfamiliar category'])
-			) :
-				$this->settings['unfamiliar category'] = 'default';
-			endif;
-
-			// Set this up automagically for del.icio.us
-			$bits = parse_url($this->link->link_rss);
-			$tagspacers = array('del.icio.us', 'feeds.delicious.com');
-			if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) : 
-				$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
-			endif;
-
-			// Simple lists
-			foreach ($this->imploded_settings() as $what) :
-				if (isset($this->settings[$what])):
-					$this->settings[$what] = explode(
-						FEEDWORDPRESS_CAT_SEPARATOR,
-						$this->settings[$what]
-					);
-				endif;
-			endforeach;
-
-			if (isset($this->settings['terms'])) :
-				// Look for new format
-				$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
-				
-				if (!is_array($this->settings['terms'])) :
-					// Deal with old format instead. Ugh.
-
-					// Split on two *or more* consecutive breaks
-					// because in the old format, a taxonomy
-					// without any associated terms would
-					// produce tax_name#1\n\n\ntax_name#2\nterm,
-					// and the naive split on the first \n\n
-					// would screw up the tax_name#2 list.
-					//
-					// Props to David Morris for pointing this
-					// out.
-
-					$this->settings['terms'] = preg_split(
-						"/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
-						$this->settings['terms']
-					);
-					$terms = array();
-					foreach ($this->settings['terms'] as $line) :
-						$line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
-						$tax = array_shift($line);
-						$terms[$tax] = $line;
-					endforeach;
-					$this->settings['terms'] = $terms;
-				endif;
-			endif;
-			
-			if (isset($this->settings['map authors'])) :
-				$author_rules = explode("\n\n", $this->settings['map authors']);
-				$ma = array();
-				foreach ($author_rules as $rule) :
-					list($rule_type, $author_name, $author_action) = explode("\n", $rule);
-					
-					// Normalize for case and whitespace
-					$rule_type = strtolower(trim($rule_type));
-					$author_name = strtolower(trim($author_name));
-					$author_action = strtolower(trim($author_action));
-					
-					$ma[$rule_type][$author_name] = $author_action;
-				endforeach;
-				$this->settings['map authors'] = $ma;
-			endif;
+			$this->get_settings_from_notes();
 		endif;
+		
+		add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
 	} /* SyndicatedLink::SyndicatedLink () */
 	
 	function found () {
 		return is_object($this->link) and !is_wp_error($this->link);
 	} /* SyndicatedLink::found () */
 
+	function id () {
+		return (is_object($this->link) ? $this->link->link_id : NULL);
+	}
+	
 	function stale () {
 		global $feedwordpress;
 		
@@ -187,33 +92,53 @@ class SyndicatedLink {
 		return $stale;
 	} /* SyndicatedLink::stale () */
 
-	function poll ($crash_ts = NULL) {
-		global $wpdb;
-
-		$url = $this->uri(array('add_params' => true));
-		FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
-
+	function fetch () {
 		$timeout = $this->setting('fetch timeout', 'feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT);
 
 		$this->simplepie = apply_filters(
 			'syndicated_feed',
-			FeedWordPress::fetch($url, array('timeout' => $timeout)),
+			FeedWordPress::fetch($this, array('timeout' => $timeout)),
 			$this
 		);
-		
+
 		// Filter compatibility mode
 		if (is_wp_error($this->simplepie)) :
 			$this->magpie = $this->simplepie;
 		else :
 			$this->magpie = new MagpieFromSimplePie($this->simplepie, NULL);
 		endif;
+	}
+	function live_posts () {
+		if (!is_object($this->simplepie)) :
+			$this->fetch();
+		endif;
+		
+		if (is_object($this->simplepie) and method_exists($this->simplepie, 'get_items')) :
+			$ret = apply_filters(
+			'syndicated_feed_items',
+			$this->simplepie->get_items(),
+			$this
+			);
+		else :
+			$ret = $this->simplepie;
+		endif;
+		return $ret;
+	}
+	
+	function poll ($crash_ts = NULL) {
+		global $wpdb;
+
+		$url = $this->uri(array('add_params' => true));
+		FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
+
+		$this->fetch();
 
 		$new_count = NULL;
 
-		$resume = FeedWordPress::affirmative($this->settings, 'update/unfinished');
+		$resume = ('yes'==$this->setting('update/unfinished'));
 		if ($resume) :
 			// pick up where we left off
-			$processed = array_map('trim', explode("\n", $this->settings['update/processed']));
+			$processed = array_map('trim', explode("\n", $this->setting('update/processed')));
 		else :
 			// begin at the beginning
 			$processed = array();
@@ -236,26 +161,25 @@ class SyndicatedLink {
 				// Copy over the in-error-since timestamp
 				$theError['since'] = $oldError['since'];
 				
-				// If this is a repeat error, then we should take
-				// a step back before we try to fetch it again.
-				$this->settings['update/last'] = time();
-				$this->settings['update/ttl'] = $this->automatic_ttl();
-				$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
-				$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl_from_error', $this->settings['update/ttl'], $this);
-
-				$this->settings['update/timed'] = 'automatically';
+				// If this is a repeat error, then we should
+				// take a step back before we try to fetch it
+				// again.
+				$this->update_setting('update/last', time(), NULL);
+				$ttl = $this->automatic_ttl();
+				$ttl = apply_filters('syndicated_feed_ttl', $ttl, $this);
+				$ttl = apply_filters('syndicated_feed_ttl_from_error', $ttl, $this);
+				$this->update_setting('update/ttl', $ttl, $this);
+				$this->update_setting('update/timed', 'automatically');
 			endif;
 			
 			do_action('syndicated_feed_error', $theError, $oldError, $this);
 			
-			$this->settings['update/error'] = serialize($theError);
+			$this->update_setting('update/error', serialize($theError));
 			$this->save_settings(/*reload=*/ true);
 
 		elseif (is_object($this->simplepie)) :
 			// Success; clear out error setting, if any.
-			if (isset($this->settings['update/error'])) :
-				unset($this->settings['update/error']);
-			endif;
+			$this->update_setting('update/error', NULL);
 
 			$new_count = array('new' => 0, 'updated' => 0);
 
@@ -282,30 +206,34 @@ class SyndicatedLink {
 					$update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
 				endif;
 			endif;
-	
-			$this->settings = array_merge($this->settings, $this->flatten_array($channel));
 
-			$this->settings['update/last'] = time();
+			$this->merge_settings($channel, 'feed/');
+
+			$this->update_setting('update/last', time());
 			list($ttl, $xml) = $this->ttl(/*return element=*/ true);
 			
 			if (!is_null($ttl)) :
-				$this->settings['update/ttl'] = $ttl;
-				$this->settings['update/xml'] = $xml;
-				$this->settings['update/timed'] = 'feed';
+				$this->update_setting('update/ttl', $ttl);
+				$this->update_setting('update/xml', $xml);
+				$this->update_setting('update/timed', 'feed');
 			else :
 				$ttl = $this->automatic_ttl();
-				$this->settings['update/ttl'] = $ttl;
-				$this->settings['update/xml'] = NULL;
-				$this->settings['update/timed'] = 'automatically';
+				$this->update_setting('update/ttl', $ttl);
+				$this->update_setting('update/xml', NULL);
+				$this->update_setting('update/timed', 'automatically');
 			endif;
-			$this->settings['update/fudge'] = rand(0, ($ttl/3))*60;
-			$this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->setting('update/ttl'), $this);
+			$this->update_setting('update/fudge', rand(0, ($ttl/3))*60);
+			$this->update_setting('update/ttl', apply_filters(
+				'syndicated_feed_ttl',
+				$this->setting('update/ttl'),
+				$this
+			));
 
 			if (!$this->setting('update/hold') != 'ping') :
-				$this->settings['update/hold'] = 'scheduled';
+				$this->update_setting('update/hold', 'scheduled');
 			endif;
 
-			$this->settings['update/unfinished'] = 'yes';
+			$this->update_setting('update/unfinished', 'yes');
 
 			$update[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
 
@@ -322,14 +250,25 @@ class SyndicatedLink {
 			# -- Add new posts from feed and update any updated posts
 			$crashed = false;
 
-			$posts = apply_filters(
-				'syndicated_feed_items',
-				$this->simplepie->get_items(),
-				&$this
-			);
+			$posts = $this->live_posts();
 
 			$this->magpie->originals = $posts;
 
+			// If this is a complete feed, rather than an incremental feed, we
+			// need to prepare to mark everything for presumptive retirement.
+			if ($this->is_incremental()) :
+				$q = new WP_Query(array(
+				'fields' => '_synfrom',
+				'post_status__not' => 'fwpretired',
+				'ignore_sticky_posts' => true,
+				'meta_key' => 'syndication_feed_id',
+				'meta_value' => $this->id,
+				));
+				foreach ($q->posts as $p) :
+					update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1');
+				endforeach;
+			endif;
+			
 			if (is_array($posts)) :
 				foreach ($posts as $key => $item) :
 					$post = new SyndicatedPost($item, $this);
@@ -349,18 +288,51 @@ class SyndicatedLink {
 					unset($post);
 				endforeach;
 			endif;
+			
+			if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) :
+				// Check for use of Atom tombstones. Spec:
+				// <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18>
+				$tombstones = $this->simplepie->get_feed_tags('http://purl.org/atompub/tombstones/1.0', 'deleted-entry');
+				if (count($tombstones) > 0) :
+					foreach ($tombstones as $tombstone) :
+						$ref = NULL;
+						foreach (array('', 'http://purl.org/atompub/tombstones/1.0') as $ns) :
+							if (isset($tombstone['attribs'][$ns])
+							and isset($tombstone['attribs'][$ns]['ref'])) :
+								$ref = $tombstone['attribs'][$ns]['ref'];
+							endif;
+						endforeach;
+						
+						$q = new WP_Query(array(
+						'ignore_sticky_posts' => true,
+						'guid' => $ref,
+						'meta_key' => 'syndication_feed_id',
+						'meta_value' => $this->id, // Only allow a feed to tombstone its own entries.
+						));
+						
+						foreach ($q->posts as $p) :
+							$old_status = $p->post_status;
+							FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.');
+							set_post_field('post_status', 'fwpretired', $p->ID);
+							wp_transition_post_status('fwpretired', $old_status, $p);
+						endforeach;
+						
+					endforeach;
+				endif;
+			endif;
+			
 			$suffix = ($crashed ? 'crashed' : 'completed');
 			do_action('update_syndicated_feed_items', $this->id, $this);
 			do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
 
-			// Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
-			$to_notes = $this->settings;
-
-			$this->settings['update/processed'] = $processed;
+			$this->update_setting('update/processed', $processed);
 			if (!$crashed) :
-				$this->settings['update/unfinished'] = 'no';
+				$this->update_setting('update/unfinished', 'no');
 			endif;
+			$this->update_setting('link/item count', count($posts));
 
+			// Copy back any changes to feed settings made in the
+			// course of updating (e.g. new author rules)
 			$update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
 			
 			// Update the properties of the link from the feed information
@@ -386,6 +358,28 @@ class SyndicatedLink {
 		return $new_count;
 	} /* SyndicatedLink::poll() */
 
+	function process_retirements ($delta) {
+		global $post;
+
+		$q = new WP_Query(array(
+		'fields' => '_synfrom',
+		'post_status__not' => 'fwpretired',
+		'ignore_sticky_posts' => true,
+		'meta_key' => '_feedwordpress_retire_me_'.$this->id,
+		'meta_value' => '1',
+		));
+		if ($q->have_posts()) :
+			foreach ($q->posts as $p) :
+				$old_status = $p->post_status;
+				FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to absence from a non-incremental feed.');
+				set_post_field('post_status', 'fwpretired', $p->ID);
+				wp_transition_post_status('fwpretired', $old_status, $p);
+				delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id);
+			endforeach;
+		endif;
+		return $delta;
+	}
+	
 	/**
 	 * Updates the URL for the feed syndicated by this link.
 	 *
@@ -466,9 +460,11 @@ class SyndicatedLink {
 			$newuser_id = fwp_insert_new_user($newuser_name);
 			if (is_numeric($newuser_id)) :
 				if (is_null($name)) : // Unfamiliar author
-					$this->settings['unfamiliar author'] = $newuser_id;
+					$this->update_setting('unfamiliar author', $newuser_id);
 				else :
-					$this->settings['map authors']['name'][$name] = $newuser_id;
+					$map = $this->setting('map authors');
+					$map['name'][$name] = $newuser_id;
+					$this->update_setting('map authors', $map);
 				endif;
 			else :
 				// TODO: Add some error detection and reporting
@@ -481,6 +477,108 @@ class SyndicatedLink {
 	function imploded_settings () {
 		return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
 	}
+	
+	function get_settings_from_notes () {
+		// Read off feed settings from link_notes
+		$notes = explode("\n", $this->link->link_notes);
+		foreach ($notes as $note):
+			$pair = explode(": ", $note, 2);
+			$key = (isset($pair[0]) ? $pair[0] : null);
+			$value = (isset($pair[1]) ? $pair[1] : null);
+			if (!is_null($key) and !is_null($value)) :
+				// Unescape and trim() off the whitespace.
+				// Thanks to Ray Lischner for pointing out the
+				// need to trim off whitespace.
+				$this->settings[$key] = stripcslashes (trim($value));
+			endif;
+		endforeach;
+
+		// "Magic" feed settings
+		$this->settings['link/uri'] = $this->link->link_rss;
+		$this->settings['link/name'] = $this->link->link_name;
+		$this->settings['link/id'] = $this->link->link_id;
+		
+		// `hardcode categories` and `unfamiliar categories` are
+		// deprecated in favor of `unfamiliar category`
+		if (
+			isset($this->settings['unfamiliar categories'])
+			and !isset($this->settings['unfamiliar category'])
+		) :
+			$this->settings['unfamiliar category'] = $this->settings['unfamiliar categories'];
+		endif;
+		if (
+			FeedWordPress::affirmative($this->settings, 'hardcode categories')
+			and !isset($this->settings['unfamiliar category'])
+		) :
+			$this->settings['unfamiliar category'] = 'default';
+		endif;
+
+		// Set this up automagically for del.icio.us
+		$bits = parse_url($this->link->link_rss);
+		$tagspacers = array('del.icio.us', 'feeds.delicious.com');
+		if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) : 
+			$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
+		endif;
+
+		// Simple lists
+		foreach ($this->imploded_settings() as $what) :
+			if (isset($this->settings[$what])):
+				$this->settings[$what] = explode(
+					FEEDWORDPRESS_CAT_SEPARATOR,
+					$this->settings[$what]
+				);
+			endif;
+		endforeach;
+
+		if (isset($this->settings['terms'])) :
+			// Look for new format
+			$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
+			
+			if (!is_array($this->settings['terms'])) :
+				// Deal with old format instead. Ugh.
+
+				// Split on two *or more* consecutive breaks
+				// because in the old format, a taxonomy
+				// without any associated terms would
+				// produce tax_name#1\n\n\ntax_name#2\nterm,
+				// and the naive split on the first \n\n
+				// would screw up the tax_name#2 list.
+				//
+				// Props to David Morris for pointing this
+				// out.
+
+				$this->settings['terms'] = preg_split(
+					"/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
+					$this->settings['terms']
+				);
+				$terms = array();
+				foreach ($this->settings['terms'] as $line) :
+					$line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
+					$tax = array_shift($line);
+					$terms[$tax] = $line;
+				endforeach;
+				$this->settings['terms'] = $terms;
+			endif;
+		endif;
+
+		if (isset($this->settings['map authors'])) :
+			$author_rules = explode("\n\n", $this->settings['map authors']);
+			$ma = array();
+			foreach ($author_rules as $rule) :
+				list($rule_type, $author_name, $author_action) = explode("\n", $rule);
+				
+				// Normalize for case and whitespace
+				$rule_type = strtolower(trim($rule_type));
+				$author_name = strtolower(trim($author_name));
+				$author_action = strtolower(trim($author_action));
+				
+				$ma[$rule_type][$author_name] = $author_action;
+			endforeach;
+			$this->settings['map authors'] = $ma;
+		endif;
+
+	} /* SyndicatedLink::get_settings_from_notes () */
+	
 	function settings_to_notes () {
 		$to_notes = $this->settings;
 
@@ -593,6 +691,11 @@ class SyndicatedLink {
 		return $ret;
 	} /* SyndicatedLink::setting () */
 
+	function merge_settings ($data, $prefix, $separator = '/') {
+		$dd = $this->flatten_array($data, $prefix, $separator);
+		$this->settings = array_merge($this->settings, $dd);
+	} /* SyndicatedLink::merge_settings () */
+	
 	function update_setting ($name, $value, $default = 'default') {
 		if (!is_null($value) and $value != $default) :
 			$this->settings[$name] = $value;
@@ -601,10 +704,14 @@ class SyndicatedLink {
 		endif;
 	} /* SyndicatedLink::update_setting () */
 	
+	function is_incremental () {
+		return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental'));
+	} /* SyndicatedLink::is_incremental () */
+	
 	function uri ($params = array()) {
-		$params = shortcode_atts(array(
+		$params = wp_parse_args($params, array(
 		'add_params' => false,
-		), $params);
+		));
 		
 		$uri = (is_object($this->link) ? $this->link->link_rss : NULL);
 		if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
@@ -620,11 +727,11 @@ class SyndicatedLink {
 				endforeach;
 				
 				// Are we appending to a URI that already has params?
-				$sep = ((strpos('?', $uri)===false) ? '?' : '&');
+				$sep = ((strpos($uri, "?")===false) ? '?' : '&');
 				
 				// Tack it on
 				$uri .= $sep . implode("&", $q);
-			endif;
+			endif;			
 		endif;
 		
 		return $uri;
@@ -645,15 +752,61 @@ class SyndicatedLink {
 		endif;
 		return $auth;
 	} /* SyndicatedLink::authentication_method () */
+
+	var $postmeta = array();	
+	function postmeta ($params = array()) {
+		$params = wp_parse_args($params, /*defaults=*/ array(
+		"field" => NULL,
+		"parsed" => false,
+		"force" => false,
+		));
+
+		if ($params['force'] or !isset($this->postmeta[/*parsed = */ false])) :
+			// First, get the global settings.
+			$default_custom_settings = get_option('feedwordpress_custom_settings');
+			if ($default_custom_settings and !is_array($default_custom_settings)) :
+				$default_custom_settings = unserialize($default_custom_settings);
+			endif;
+			if (!is_array($default_custom_settings)) :
+				$default_custom_settings = array();
+			endif;
+			
+			// Next, get the settings for this particular feed.
+			$custom_settings = $this->setting('postmeta', NULL, NULL);
+			if ($custom_settings and !is_array($custom_settings)) :
+				$custom_settings = unserialize($custom_settings);
+			endif;
+			if (!is_array($custom_settings)) :
+				$custom_settings = array();
+			endif;
+			
+			$this->postmeta[/*parsed=*/ false] = array_merge($default_custom_settings, $custom_settings);
+			$this->postmeta[/*parsed=*/ true] = array();
+			
+			// Now, run through and parse them all.
+			foreach ($this->postmeta[/*parsed=*/ false] as $key => $meta) :
+				$meta = apply_filters("syndicated_link_post_meta_${key}_pre", $meta, $this);
+				$this->postmeta[/*parsed=*/ false][$key] = $meta;
+				$this->postmeta[/*parsed=*/ true][$key] = new FeedWordPressParsedPostMeta($meta);
+			endforeach;
+		endif;
+
+		$ret = $this->postmeta[!!$params['parsed']];
+		if (is_string($params['field'])) :
+			$ret = $ret[$params['field']];
+		endif;
+		return $ret;
+	} /* SyndicatedLink::postmeta () */
 	
-	function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
+	function property_cascade ($fromFeed, $link_field, $setting, $method) {
 		$value = NULL;
 		if ($fromFeed) :
-			if (isset($this->settings[$setting])) :
-				$value = $this->settings[$setting];
-			elseif (is_object($this->simplepie)
-			and method_exists($this->simplepie, $simplepie_method)) :
-				$value = $this->simplepie->{$simplepie_method}();
+			$value = $this->setting($setting, NULL, NULL, NULL);
+			
+			$s = $this->simplepie;
+			$callable = (is_object($s) and method_exists($s, $method));
+			if (is_null($value) and $callable) :
+				$fallback = $s->{$method}();
 			endif;
 		else :
 			$value = $this->link->{$link_field};
@@ -789,17 +942,13 @@ class SyndicatedLink {
 	} /* SyndicatedLink::flatten_array () */
 
 	function hardcode ($what) {
-		$default = get_option("feedwordpress_hardcode_$what");
-		if ( $default === 'yes' ) :
-			// If the default is to hardcode, then we want the
-			// negation of negative(): TRUE by default and FALSE if
-			// the setting is explicitly "no"
-			$ret = !FeedWordPress::negative($this->settings, "hardcode $what");
+		
+		$ret = $this->setting('hardcode '.$what, 'hardcode_'.$what, NULL);
+		
+		if ('yes' == $ret) :
+			$ret = true;
 		else :
-			// If the default is NOT to hardcode, then we want
-			// affirmative(): FALSE by default and TRUE if the
-			// setting is explicitly "yes"
-			$ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
+			$ret = false;
 		endif;
 		return $ret;
 	} /* SyndicatedLink::hardcode () */
@@ -807,19 +956,8 @@ class SyndicatedLink {
 	function syndicated_status ($what, $default, $fallback = true) {
 		global $wpdb;
 
-		// Use local setting if we have it
-		if ( isset($this->settings["$what status"]) ) :
-			$ret = $this->settings["$what status"];
-		
-		// Or fall back to global default if we can
-		elseif ($fallback) :
-			$ret = FeedWordPress::syndicated_status($what, $default);
-
-		// Or use default value if we can't.
-		else :
-			$ret = $default;
-
-		endif;
+		$g_set = ($fallback ? 'syndicated_' . $what . '_status' : NULL);
+		$ret = $this->setting($what.' status', $g_set, $default);
 
 		return $wpdb->escape(trim(strtolower($ret)));
 	} /* SyndicatedLink:syndicated_status () */
diff --git a/wp-content/plugins/feedwordpress/syndicatedpost.class.php b/wp-content/plugins/feedwordpress/syndicatedpost.class.php
index 2c46841023429f6a99476d16521775364a4c4d3e..aa51a61349016b658a394de08d964e2e3977f902 100644
--- a/wp-content/plugins/feedwordpress/syndicatedpost.class.php
+++ b/wp-content/plugins/feedwordpress/syndicatedpost.class.php
@@ -30,6 +30,7 @@ class SyndicatedPost {
 	
 	var $_freshness = null;
 	var $_wp_id = null;
+	var $_wp_post = null;
 
 	/**
 	 * SyndicatedPost constructor: Given a feed item and the source from
@@ -158,48 +159,16 @@ class SyndicatedPost {
 			// Unique ID (hopefully a unique tag: URI); failing that, the permalink
 			$this->post['guid'] = apply_filters('syndicated_item_guid', $this->guid(), $this);
 
-			// User-supplied custom settings to apply to each post. Do first so that FWP-generated custom settings will overwrite if necessary; thus preventing any munging
-			$default_custom_settings = get_option('feedwordpress_custom_settings');
-			if ($default_custom_settings and !is_array($default_custom_settings)) :
-				$default_custom_settings = unserialize($default_custom_settings);
-			endif;
-			if (!is_array($default_custom_settings)) :
-				$default_custom_settings = array();
-			endif;
-			
-			$custom_settings = (isset($this->link->settings['postmeta']) ? $this->link->settings['postmeta'] : null);
-			if ($custom_settings and !is_array($custom_settings)) :
-				$custom_settings = unserialize($custom_settings);
-			endif;
-			if (!is_array($custom_settings)) :
-				$custom_settings = array();
-			endif;
-			
-			$postMetaIn = array_merge($default_custom_settings, $custom_settings);
+			// User-supplied custom settings to apply to each post.
+			// Do first so that FWP-generated custom settings will
+			// overwrite if necessary; thus preventing any munging.
+			$postMetaIn = $this->link->postmeta(array("parsed" => true));
 			$postMetaOut = array();
-
-			// Big ugly fuckin loop to do any element substitutions
-			// that we may need.
-			foreach ($postMetaIn as $key => $values) :
-				if (is_string($values)) : $values = array($values); endif;
-				
-				$postMetaOut[$key] = array();
-				foreach ($values as $value) :
-					if (preg_match('/\$\( ([^)]+) \)/x', $value, $ref)) :
-						$elements = $this->query($ref[1]);
-						foreach ($elements as $element) :
-							$postMetaOut[$key][] = str_replace(
-								$ref[0],
-								$element,
-								$value
-							);
-						endforeach;
-					else :
-						$postMetaOut[$key][] = $value;	
-					endif;
-				endforeach;
+			
+			foreach ($postMetaIn as $key => $meta) :
+				$postMetaOut[$key] = $meta->do_substitutions($this);
 			endforeach;
-
+			
 			foreach ($postMetaOut as $key => $values) :
 				$this->post['meta'][$key] = array();
 				foreach ($values as $value) :
@@ -380,6 +349,23 @@ class SyndicatedPost {
 	#####################################
 	#### EXTRACT DATA FROM FEED ITEM ####
 	#####################################
+
+	function substitution_function ($name) {
+		$ret = NULL;
+		
+		switch ($name) :
+		// Allowed PHP string functions
+		case 'trim':
+		case 'ltrim':
+		case 'rtrim':
+		case 'strtoupper':
+		case 'strtolower':
+		case 'urlencode':
+		case 'urldecode':
+			$ret = $name;
+		endswitch;
+		return $ret;
+	}
 	
 	/**
 	 * SyndicatedPost::query uses an XPath-like syntax to query arbitrary
@@ -772,8 +758,20 @@ class SyndicatedPost {
 		return $this->_hashes[$id];
 	}
 
-	function update_hash () {
-		return md5(serialize($this->item));
+	function update_hash ($hashed = true) {
+		// Basis for tracking possible changes to item.
+		$hash = array(
+			"title" => $this->entry->get_title(),
+			"link" => $this->permalink(),
+			"content" => $this->content(),
+			"excerpt" => $this->excerpt(),
+		);
+		
+		if ($hashed) :
+			$hash = md5(serialize($hash));
+		endif;
+		
+		return $hash;
 	} /* SyndicatedPost::update_hash() */
 
 	/*static*/ function normalize_guid_prefix () {
@@ -853,56 +851,77 @@ class SyndicatedPost {
 	function author () {
 		$author = array ();
 		
-		if (isset($this->item['author_name'])):
-			$author['name'] = $this->item['author_name'];
-		elseif (isset($this->item['dc']['creator'])):
-			$author['name'] = $this->item['dc']['creator'];
-		elseif (isset($this->item['dc']['contributor'])):
-			$author['name'] = $this->item['dc']['contributor'];
-		elseif (isset($this->feed->channel['dc']['creator'])) :
-			$author['name'] = $this->feed->channel['dc']['creator'];
-		elseif (isset($this->feed->channel['dc']['contributor'])) :
-			$author['name'] = $this->feed->channel['dc']['contributor'];
-		elseif (isset($this->feed->channel['author_name'])) :
-			$author['name'] = $this->feed->channel['author_name'];
-		elseif ($this->feed->is_rss() and isset($this->item['author'])) :
-			// The author element in RSS is allegedly an
-			// e-mail address, but lots of people don't use
-			// it that way. So let's make of it what we can.
-			$author = parse_email_with_realname($this->item['author']);
-			
-			if (!isset($author['name'])) :
-				if (isset($author['email'])) :
-					$author['name'] = $author['email'];
-				else :
-					$author['name'] = $this->feed->channel['title'];
+		$aa = $this->entry->get_authors();
+		if (count($aa) > 0) :
+			$a = reset($aa);
+
+			$author = array(
+			'name' => $a->get_name(),
+			'email' => $a->get_email(),
+			'uri' => $a->get_link(),
+			);
+		endif;
+
+		if (FEEDWORDPRESS_COMPATIBILITY) :
+			// Search through the MagpieRSS elements: Atom, Dublin Core, RSS
+			if (isset($this->item['author_name'])):
+				$author['name'] = $this->item['author_name'];
+			elseif (isset($this->item['dc']['creator'])):
+				$author['name'] = $this->item['dc']['creator'];
+			elseif (isset($this->item['dc']['contributor'])):
+				$author['name'] = $this->item['dc']['contributor'];
+			elseif (isset($this->feed->channel['dc']['creator'])) :
+				$author['name'] = $this->feed->channel['dc']['creator'];
+			elseif (isset($this->feed->channel['dc']['contributor'])) :
+				$author['name'] = $this->feed->channel['dc']['contributor'];
+			elseif (isset($this->feed->channel['author_name'])) :
+				$author['name'] = $this->feed->channel['author_name'];
+			elseif ($this->feed->is_rss() and isset($this->item['author'])) :
+				// The author element in RSS is allegedly an
+				// e-mail address, but lots of people don't use
+				// it that way. So let's make of it what we can.
+				$author = parse_email_with_realname($this->item['author']);
+				
+				if (!isset($author['name'])) :
+					if (isset($author['email'])) :
+						$author['name'] = $author['email'];
+					else :
+						$author['name'] = $this->feed->channel['title'];
+					endif;
 				endif;
 			endif;
-		elseif ($this->link->name()) :
-			$author['name'] = $this->link->name();
-		else :
-			$url = parse_url($this->link->uri());
-			$author['name'] = $url['host'];
 		endif;
 		
-		if (isset($this->item['author_email'])):
-			$author['email'] = $this->item['author_email'];
-		elseif (isset($this->feed->channel['author_email'])) :
-			$author['email'] = $this->feed->channel['author_email'];
+		if (!isset($author['name']) or is_null($author['name'])) :
+			// Nothing found. Try some crappy defaults.
+			if ($this->link->name()) :
+				$author['name'] = $this->link->name();
+			else :
+				$url = parse_url($this->link->uri());
+				$author['name'] = $url['host'];
+			endif;
 		endif;
 		
-		if (isset($this->item['author_uri'])):
-			$author['uri'] = $this->item['author_uri'];
-		elseif (isset($this->item['author_url'])):
-			$author['uri'] = $this->item['author_url'];
-		elseif (isset($this->feed->channel['author_uri'])) :
-			$author['uri'] = $this->item['author_uri'];
-		elseif (isset($this->feed->channel['author_url'])) :
-			$author['uri'] = $this->item['author_url'];
-		elseif (isset($this->feed->channel['link'])) :
-			$author['uri'] = $this->feed->channel['link'];
+		if (FEEDWORDPRESS_COMPATIBILITY) :
+			if (isset($this->item['author_email'])):
+				$author['email'] = $this->item['author_email'];
+			elseif (isset($this->feed->channel['author_email'])) :
+				$author['email'] = $this->feed->channel['author_email'];
+			endif;
+			
+			if (isset($this->item['author_uri'])):
+				$author['uri'] = $this->item['author_uri'];
+			elseif (isset($this->item['author_url'])):
+				$author['uri'] = $this->item['author_url'];
+			elseif (isset($this->feed->channel['author_uri'])) :
+				$author['uri'] = $this->item['author_uri'];
+			elseif (isset($this->feed->channel['author_url'])) :
+				$author['uri'] = $this->item['author_url'];
+			elseif (isset($this->feed->channel['link'])) :
+				$author['uri'] = $this->feed->channel['link'];
+			endif;
 		endif;
-
+		
 		return $author;
 	} /* SyndicatedPost::author() */
 
@@ -1170,7 +1189,7 @@ class SyndicatedPost {
 				$pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
 				$content = preg_replace_callback (
 					$pattern,
-					array(&$obj, 'resolve_single_relative_uri'),
+					array($obj, 'resolve_single_relative_uri'),
 					$content
 				);
 			endforeach;
@@ -1199,7 +1218,7 @@ class SyndicatedPost {
 
 			$content = preg_replace_callback (
 				$pattern,
-				array(&$obj, 'strip_attribute_from_tag'),
+				array($obj, 'strip_attribute_from_tag'),
 				$content
 			);
 		endforeach;
@@ -1270,9 +1289,18 @@ class SyndicatedPost {
 					!is_null($updated_ts)
 					and ($updated_ts > $last_rev_ts)
 				);
-				
-				
-				if (!$updated) :
+
+				$updatedReason = NULL;
+				if ($updated) :
+					$updatedReason = preg_replace(
+						"/\s+/", " ",
+						'has been marked with a new timestamp ('
+						.date('Y-m-d H:i:s', $updated_ts)
+						." > "
+						.date('Y-m-d H:i:s', $last_rev_ts)
+						.')'
+					);
+				else :
 					// Or the hash...
 					$hash = $this->update_hash();
 					$seen = $this->stored_hashes($old_post->ID);
@@ -1281,6 +1309,15 @@ class SyndicatedPost {
 					else :
 						$updated = true; // Can't find syndication meta-data
 					endif;
+					
+					if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) :
+						$updatedReason = ' has a not-yet-seen update hash: '
+						.FeedWordPress::val($hash)
+						.' not in {'
+						.implode(", ", array_map(array('FeedWordPress', 'val'), $seen))
+						.'}. Basis: '
+						.FeedWordPress::val(array_keys($this->update_hash(false)));
+					endif;
 				endif;
 				
 				$frozen = false;
@@ -1289,15 +1326,26 @@ class SyndicatedPost {
 					if (!$frozen) :
 						$frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID);
 						$frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
+						
+						if ($frozen) :
+							$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT '.$updatedReason;
+						endif;
+					else :
+						$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT '.$updatedReason;
 					endif;
 				endif;
 				$updated = ($updated and !$frozen);
 
 				if ($updated) :
 					FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
+					if (!is_null($updatedReason)) :
+						$updatedReason = preg_replace('/\s+/', ' ', $updatedReason);
+						FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item ['.$guid.'] "'.$this->entry->get_title().'" '.$updatedReason);
+					endif;
 					$this->_freshness = 1; // Updated content
 					$this->_wp_id = $old_post->ID;
-					
+					$this->_wp_post = $old_post;
+
 					// We want this to keep a running list of all the
 					// processed update hashes.
 					$this->post['meta']['syndication_item_hash'] = array_merge(
@@ -1427,8 +1475,13 @@ class SyndicatedPost {
 		if (!$this->filtered() and $freshness > 0) :
 			// Filter some individual fields
 			
+			// If there already is a post slug (from syndication or by manual
+			// editing) don't cause WP to overwrite it by sending in a NULL
+			// post_name. Props Chris Fritz 2012-11-28.
+			$post_name = (is_null($this->_wp_post) ? NULL : $this->_wp_post->post_name);			
+
 			// Allow filters to set post slug. Props niska.
-			$post_name = apply_filters('syndicated_post_slug', NULL, $this);
+			$post_name = apply_filters('syndicated_post_slug', $post_name, $this);
 			if (!empty($post_name)) :
 				$this->post['post_name'] = $post_name;
 			endif;
@@ -1446,7 +1499,7 @@ class SyndicatedPost {
 		// Hook in early to make sure these get inserted if at all possible
 		add_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'add_rss_meta'),
+			/*callback=*/ array($this, 'add_rss_meta'),
 			/*priority=*/ -10000, /* very early */
 			/*arguments=*/ 3
 		);
@@ -1469,10 +1522,24 @@ class SyndicatedPost {
 			$ret = $retval[$freshness];
 		endif;
 
+		// If this is a legit, non-filtered post, tag it as found on the feed
+		// regardless of fresh or stale status
+		if (!$this->filtered()) :
+			$key = '_feedwordpress_retire_me_' . $this->link->id;
+			delete_post_meta($this->wp_id(), $key);
+			
+			$status = get_post_field('post_status', $this->wp_id());
+			if ('fwpretired'==$status and $this->link->is_incremental()) :
+				FeedWordPress::diagnostic('syndicated_posts', "Un-retiring previously retired post # ".$this->wp_id()." due to re-appearance on non-incremental feed."); 
+				set_post_field('post_status', $this->post['post_status'], $this->wp_id());
+				wp_transition_post_status($this->post['post_status'], $status, $old_status, $this->post);
+			endif;
+		endif;
+		
 		// Remove add_rss_meta hook
 		remove_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'add_rss_meta'),
+			/*callback=*/ array($this, 'add_rss_meta'),
 			/*priority=*/ -10000, /* very early */
 			/*arguments=*/ 3
 		);
@@ -1509,14 +1576,14 @@ class SyndicatedPost {
 				
 				foreach ($doNotMunge as $field) :
 					$dbpost[$field] = get_post_field($field, $this->wp_id());
-				endforeach;				
+				endforeach;
 			endif;
 			
 			// WP3's wp_insert_post scans current_user_can() for the
 			// tax_input, with no apparent way to override. Ugh.
 			add_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'add_terms'),
+			/*callback=*/ array($this, 'add_terms'),
 			/*priority=*/ -10001, /* very early */
 			/*arguments=*/ 3
 			);
@@ -1525,7 +1592,7 @@ class SyndicatedPost {
 			// post_modified. Ugh.
 			add_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'fix_post_modified_ts'),
+			/*callback=*/ array($this, 'fix_post_modified_ts'),
 			/*priority=*/ -10000, /* very early */
 			/*arguments=*/ 3
 			);
@@ -1539,14 +1606,14 @@ class SyndicatedPost {
 
 			remove_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'add_terms'),
+			/*callback=*/ array($this, 'add_terms'),
 			/*priority=*/ -10001, /* very early */
 			/*arguments=*/ 3
 			);
 
 			remove_action(
 			/*hook=*/ 'transition_post_status',
-			/*callback=*/ array(&$this, 'fix_post_modified_ts'),
+			/*callback=*/ array($this, 'fix_post_modified_ts'),
 			/*priority=*/ -10000, /* very early */
 			/*arguments=*/ 3
 			);
@@ -1554,7 +1621,7 @@ class SyndicatedPost {
 			// Turn off ridiculous fucking kludges #1 and #2
 			remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
 			foreach ($removed as $filter) :
-				add_filter('content_save_pre', $removed);
+				add_filter('content_save_pre', $filter);
 			endforeach;
 			
 			$this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
@@ -2131,20 +2198,5 @@ EOM;
 		return $terms;
 	} // function SyndicatedPost::category_ids ()
 
-	function use_api ($tag) {
-		global $wp_db_version;
-		switch ($tag) :
-		case 'wp_insert_post':
-			// Before 2.2, wp_insert_post does too much of the wrong stuff to use it
-			// In 1.5 it was such a resource hog it would make PHP segfault on big updates
-			$ret = (isset($wp_db_version) and $wp_db_version > FWP_SCHEMA_21);
-			break;
-		case 'post_status_pending':
-			$ret = (isset($wp_db_version) and $wp_db_version > FWP_SCHEMA_23);
-			break;
-		endswitch;
-		return $ret;		
-	} // function SyndicatedPost::use_api ()
-
 } /* class SyndicatedPost */
 
diff --git a/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php b/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
index 90ff6553179a02db09694324663f555c32946d41..fdb046cc537bb8d68da5f39c28bc4e1c18a159e2 100644
--- a/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
+++ b/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
@@ -1,12 +1,15 @@
 <?php
+define('FEEDWORDPRESS_OPTIMIZE_IN_CLAUSES', get_option('feedwordpress_optimize_in_clauses', false));
+
 class SyndicationDataQueries {
 	function SyndicationDataQueries () {
-		add_action('init', array(&$this, 'init'));
-		add_action('parse_query', array(&$this, 'parse_query'), 10, 1);
-		add_filter('posts_search', array(&$this, 'posts_search'), 10, 2);
-		add_filter('posts_where', array(&$this, 'posts_where'), 10, 2);
-		add_filter('posts_fields', array(&$this, 'posts_fields'), 10, 2);
-		add_filter('posts_request', array(&$this, 'posts_request'), 10, 2);
+		add_action('init', array($this, 'init'));
+		add_filter('query', array($this, 'optimize_in_clauses'));
+		add_action('parse_query', array($this, 'parse_query'), 10, 1);
+		add_filter('posts_search', array($this, 'posts_search'), 10, 2);
+		add_filter('posts_where', array($this, 'posts_where'), 10, 2);
+		add_filter('posts_fields', array($this, 'posts_fields'), 10, 2);
+		add_filter('posts_request', array($this, 'posts_request'), 10, 2);
 	}
 
 	function init () {
@@ -14,13 +17,36 @@ class SyndicationDataQueries {
 		$wp->add_query_var('guid');
 	}
 
+	function optimize_in_clauses ($q) {
+		// This is kind of a dicey, low-level thing to do, and Christ,
+		// this is something WordPress should be doing on its own,
+		// so it's disabled by default. But you can enable it in
+		// Performance --> Optimize IN clauses 
+		if (FEEDWORDPRESS_OPTIMIZE_IN_CLAUSES) :
+			if (preg_match_all('/ \s+ IN \s* \((\s*([0-9]+)\s*)\)/x', $q, $r, PREG_OFFSET_CAPTURE)) :
+				$from = 0; $nq = '';
+				foreach ($r[0] as $idx => $ref) :
+					$len = $ref[1] - $from;
+					$nq .= substr($q, $from, $len);
+					$nq .= ' = ' . $r[1][$idx][0];
+					$from = $ref[1] + strlen($ref[0]);
+				endforeach;
+				
+				$q = $nq;
+			endif;
+		endif;
+		
+		return $q;
+	}
+	
 	function parse_query (&$q) {
 		if ($q->get('guid')) :
-			$q->is_single = false;		// Causes nasty side-effects.
+			$q->is_single = false;	// Causes nasty side-effects.
 			$q->is_singular = true;	// Doesn't?
 		endif;
 		
-		if ($q->get('fields') == '_synfresh') :
+		$ff = $q->get('fields');
+		if ($ff == '_synfresh' or $ff == '_synfrom') :
 			$q->query_vars['cache_results'] = false; // Not suitable.
 		endif;
 	} /* SyndicationDataQueries::parse_query () */
@@ -35,7 +61,7 @@ class SyndicationDataQueries {
 		endif;
 		return $sql;
 	}
-	
+
 	function posts_search ($search, &$query) {
 		global $wpdb;
 		if ($guid = $query->get('guid')) :
@@ -67,17 +93,26 @@ class SyndicationDataQueries {
 			// Ugly hack to ensure we ONLY check by guid in syndicated freshness
 			// checks -- for reasons of both performance and correctness. Pitch:
 			$search .= " -- '";
+		elseif ($query->get('fields')=='_synfrom') :
+			$search .= " AND ({$wpdb->postmeta}.meta_key = '".$query->get('meta_key')."' AND {$wpdb->postmeta}.meta_value = '".$query->get('meta_value')."') -- '"; 
 		endif;
 		return $search;
 	} /* SyndicationDataQueries::posts_search () */
 	
 	function posts_where ($where, &$q) {
+		global $wpdb;
+		
 		// Ugly hack to ensure we ONLY check by guid in syndicated freshness
 		// checks -- for reasons of both performance and correctness. Catch:
 		if (strpos($where, " -- '") !== false) :
 			$bits = explode(" -- '", $where, 2);
 			$where = $bits[0];
 		endif;
+		
+		if ($psn = $q->get('post_status__not')) :
+			$where .= " AND ({$wpdb->posts}.post_status <> '".$wpdb->escape($psn)."')"; 
+		endif;
+		
 		return $where;
 	} /* SyndicationDataQueries::post_where () */
 	
@@ -86,7 +121,10 @@ class SyndicationDataQueries {
 		if ($f = $query->get('fields')) :
 			switch ($f) :
 			case '_synfresh' :
-				$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_modified_gmt";
+				$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.post_name";
+				break;
+			case '_synfrom' :
+				$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_title, {$wpdb->postmeta}.meta_value";
 				break;
 			default :
 				// Do nothing.