diff --git a/wp-content/plugins/feedwordpress/admin-ui.php b/wp-content/plugins/feedwordpress/admin-ui.php
index 478db9f09522484ce6c67e878a254fa7f65747ff..f0c4ef39736419fe8148ae5d53a6b8a1796fb45e 100644
--- a/wp-content/plugins/feedwordpress/admin-ui.php
+++ b/wp-content/plugins/feedwordpress/admin-ui.php
@@ -28,7 +28,7 @@ class FeedWordPressAdminPage {
 		$slug = preg_replace('/FeedWordPress(.*)Page/', '$1', get_class($this));
 		return strtolower($slug);
 	}
-	
+
 	function pagename ($context = NULL) {
 		if (is_null($context)) :
 			$context = 'default';
@@ -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 () {
@@ -58,22 +58,25 @@ class FeedWordPressAdminPage {
 
 		add_action('feedwordpress_check_feed', 'update_feeds_mention');
 		add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
-		
+
 		print '<div class="updated">';
 		print "<ul>";
 		$uri = $this->link->uri();
+		$displayUrl = $uri;
+		
+		// check for effects of an effective-url filter
+		$effectiveUrl = $link->uri(array('fetch' => true));
+		if ($uri != $effectiveUrl) : $displayUrl .= ' | ' . $effectiveUrl; endif;
+
 		$delta = $feedwordpress->update($uri);
 		print "</ul>";
 
 		if (!is_null($delta)) :
-			$mesg = array();
-			if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
-			if (isset($delta['updated'])) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
-			echo "<p><strong>Update complete.</strong>".implode(' and', $mesg)."</p>";
+			echo "<p><strong>Update complete.</strong>".fwp_update_set_results_message($delta)."</p>";
 			echo "\n"; flush();
 		else :
-			$uri = esc_html($uri);
-			echo "<p><strong>Error:</strong> There was a problem updating <a href=\"$uri\">$uri</a></p>\n";
+			$effectiveUrl  = esc_html($effectiveUrl);
+			echo "<p><strong>Error:</strong> There was a problem updating <a href=\"$effectiveUrl\">$displayUrl</a></p>\n";
 		endif;
 		print "</div>\n";
 		remove_action('feedwordpress_check_feed', 'update_feeds_mention');
@@ -87,7 +90,7 @@ class FeedWordPressAdminPage {
 			// Save settings
 			$this->link->save_settings(/*reload=*/ true);
 			$this->updated = true;
-			
+
 			// Reset, reload
 			$link_id = $this->link->id;
 			unset($this->link);
@@ -118,7 +121,7 @@ class FeedWordPressAdminPage {
 		endif;
 
 		if ($this->for_feed_settings()) : // Check feed-specific setting first; fall back to global
-			if (!$params['fallback']) : $global_name = NULL; endif; 
+			if (!$params['fallback']) : $global_name = NULL; endif;
 			$ret = $this->link->setting($feed_name, $global_name, $fallback_value, $params['default']);
 		else : // Check global setting
 			$ret = get_option($global_name, $fallback_value);
@@ -134,7 +137,7 @@ class FeedWordPressAdminPage {
 			$feed_name = $names['feed'];
 			$global_name = 'feedwordpress_'.$names['global'];
 		endif;
-		
+
 		if ($this->for_feed_settings()) : // Update feed-specific setting
 			$this->link->update_setting($feed_name, $value, $default);
 		else : // Update global setting
@@ -148,7 +151,7 @@ class FeedWordPressAdminPage {
 	function update_requested_in ($post) {
 		return (isset($post['update']) and (strlen($post['update']) > 0));
 	}
-	
+
 	/*static*/ function submitted_link_id () {
 		global $fwp_post;
 
@@ -166,7 +169,7 @@ class FeedWordPressAdminPage {
 				$link_id = MyPHP::request('save_link_id');
 			endif;
 		endforeach;
-		
+
 		if (is_null($link_id) and isset($_REQUEST['link_id'])) :
 			$link_id = MyPHP::request('link_id');
 		endif;
@@ -212,7 +215,7 @@ class FeedWordPressAdminPage {
 	function meta_box_context () {
 		return $this->context;
 	} /* FeedWordPressAdminPage::meta_box_context () */
-	
+
 	/**
 	 * Outputs JavaScript to fix AJAX toggles settings.
 	 *
@@ -252,7 +255,7 @@ class FeedWordPressAdminPage {
 			$link_id = NULL;
 			if (is_object($link)) :
 				if (method_exists($link, 'found')) :
-					// Is this a SyndicatedLink object?					
+					// Is this a SyndicatedLink object?
 					if ($link->found()) :
 						$link_id = $link->link->link_id;
 					endif;
@@ -284,14 +287,14 @@ class FeedWordPressAdminPage {
 			'subscription' => $this->link,
 		));
 		$sub = $params['subscription'];
-		
+
 		$links = array(
 			"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 & Tags'),
 		);
-		
+
 		$link_id = NULL;
 		if (is_object($sub)) :
 			if (method_exists($sub, 'found')) :
@@ -302,40 +305,40 @@ class FeedWordPressAdminPage {
 				$link_id = $sub->link_id;
 			endif;
 		endif;
-		
+
 		print $params['before']; $first = true;
 		foreach ($links as $label => $link) :
 			if (!$first) :	print $params['between']; endif;
-			
+
 			if (isset($link['url'])) : MyPHP::url($link['url'], array("link_id" => $link_id));
 			else : $url = $this->admin_page_href($link['page'], array(), $sub);
 			endif;
 			$url = esc_html($url);
-			
+
 			if ($link['page']==basename($this->filename)) :
 				print "<strong>";
 			else :
 				print "<a href=\"${url}\">";
 			endif;
-			
+
 			if ($params['long']) : print esc_html(__($link['long']));
 			else : print esc_html(__($label));
 			endif;
-			
+
 			if ($link['page']==basename($this->filename)) :
 				print "</strong>";
 			else :
 				print "</a>";
 			endif;
-			
+
 			$first = false;
 		endforeach;
 		print $params['after'];
 	} /* FeedWordPressAdminPage::display_feed_settings_page_links */
-	
+
 	function display_feed_select_dropdown() {
 		$links = FeedWordPress::syndicated_links();
-		
+
 		?>
 		<div id="fwpfs-container"><ul class="subsubsub">
 		<li><select name="link_id" class="fwpfs" style="max-width: 20.0em;">
@@ -353,14 +356,14 @@ class FeedWordPressAdminPage {
 			'after' => '</li>',
 			'subscription' => $this->link,
 		));
-		
+
 		if ($this->for_feed_settings()) :
 		?>
 		<li><input class="button" type="submit" name="update" value="Update Now" /></li>
 		<?php
 		endif;
 		?>
-		</ul>		
+		</ul>
 		</div>
 		<?php
 	} /* FeedWordPressAdminPage::display_feed_select_dropdown() */
@@ -385,7 +388,7 @@ class FeedWordPressAdminPage {
 				$this->mesg = $this->updated;
 			endif;
 		endif;
-		
+
 		if (!is_null($this->mesg)) :
 			?>
 			<div class="updated">
@@ -408,12 +411,12 @@ class FeedWordPressAdminPage {
 		<?php
 		endif;
 	} /* FeedWordPressAdminPage::display_settings_scope_message () */
-	
+
 	/*static*/ function has_link () { return true; }
 
 	function form_action ($filename = NULL) {
 		global $fwp_path;
-		
+
 		if (is_null($filename)) :
 			$filename = basename($this->filename);
 		endif;
@@ -451,7 +454,7 @@ class FeedWordPressAdminPage {
 			$this->pagename('settings-update'),
 			$this->update_message()
 		);
-		
+
 		$this->open_sheet($this->pagename('open-sheet'));
 		?>
 		<div id="post-body">
@@ -464,7 +467,7 @@ class FeedWordPressAdminPage {
 				$id = 'feedwordpress_'.$method;
 				$title = $row;
 			endif;
-	
+
 			add_meta_box(
 				/*id=*/ $id,
 				/*title=*/ $title,
@@ -493,7 +496,7 @@ class FeedWordPressAdminPage {
 		$this->ajax_interface_js();
 		?>
 		</script>
-		
+
 		<?php
 		add_action(
 			FeedWordPressCompatibility::bottom_script_hook($this->filename),
@@ -535,14 +538,14 @@ class FeedWordPressAdminPage {
 		endif;
 		?>
 		</div>
-		
+
 		<div id="poststuff">
 		<?php
 	} /* FeedWordPressAdminPage::open_sheet () */
-	
+
 	function close_sheet () {
 		?>
-		
+
 		</div> <!-- id="poststuff" -->
 		<?php
 		if (!is_null($this->dispatch)) :
@@ -551,51 +554,51 @@ class FeedWordPressAdminPage {
 		endif;
 		?>
 		</div> <!-- class="wrap" -->
-		
+
 		<?php
 	} /* FeedWordPressAdminPage::close_sheet () */
-	
+
 	function setting_radio_control ($localName, $globalName, $options, $params = array()) {
 		global $fwp_path;
-		
+
 		if (isset($params['filename'])) : $filename = $params['filename'];
 		else : $filename = basename($this->filename);
 		endif;
-		
+
 		if (isset($params['site-wide-url'])) : $href = $params['site-wide-url'];
 		else : 	$href = $this->admin_page_href($filename);
 		endif;
-		
+
 		if (isset($params['setting-default'])) : $settingDefault = $params['setting-default'];
 		else : $settingDefault = NULL;
 		endif;
-		
+
 		if (isset($params['global-setting-default'])) : $globalSettingDefault = $params['global-setting-default'];
 		else : $globalSettingDefault = $settingDefault;
 		endif;
 
-		$globalSetting = get_option('feedwordpress_'.$globalName, $globalSettingDefault); 
+		$globalSetting = get_option('feedwordpress_'.$globalName, $globalSettingDefault);
 		if ($this->for_feed_settings()) :
 			$setting = $this->link->setting($localName, NULL, $settingDefault);
 		else :
 			$setting = $globalSetting;
 		endif;
-		
+
 		if (isset($params['offer-site-wide'])) : $offerSiteWide = $params['offer-site-wide'];
 		else : $offerSiteWide = $this->for_feed_settings();
 		endif;
-		
+
 		// This allows us to provide an alternative set of human-readable
 		// labels for each potential value. For use in Currently: line.
 		if (isset($params['labels'])) : $labels = $params['labels'];
 		elseif (is_callable($options)) : $labels = NULL;
 		else : $labels = $options;
 		endif;
-		
+
 		if (isset($params['input-name'])) : $inputName = $params['input-name'];
 		else : $inputName = $globalName;
 		endif;
-		
+
 		if (isset($params['default-input-id'])) : $defaultInputId = $params['default-input-id'];
 		else : $defaultInputId = NULL;
 		endif;
@@ -604,7 +607,7 @@ class FeedWordPressAdminPage {
 		elseif (!is_null($defaultInputId)) : $defaultInputIdNo = $defaultInputId.'-no';
 		else : $defaultInputIdNo = NULL;
 		endif;
-		
+
 		// This allows us to either include the site-default setting as
 		// one of the options within the radio box, or else as a simple
 		// yes/no toggle that controls whether or not to check another
@@ -622,7 +625,7 @@ class FeedWordPressAdminPage {
 				: 'site-default'
 			);
 		endif;
-		
+
 		$settingDefaulted = (is_null($setting) or ($settingDefault === $setting));
 
 		if (!is_callable($options)) :
@@ -630,7 +633,7 @@ class FeedWordPressAdminPage {
 			if ($settingDefaulted) :
 				$checked[$defaultInputValue] = ' checked="checked"';
 			endif;
-			
+
 			foreach ($options as $value => $label) :
 				if ($setting == $value) :
 					$checked[$value] = ' checked="checked"';
@@ -647,7 +650,7 @@ class FeedWordPressAdminPage {
 		else :
 			$defaulted['yes'] = (isset($checked[$defaultInputValue]) ? $checked[$defaultInputValue] : '');
 		endif;
-		
+
 		if (isset($params['defaulted'])) :
 			$defaulted['yes'] = ($params['defaulted'] ? ' checked="checked"' : '');
 			$defaulted['no'] = ($params['defaulted'] ? '' : ' checked="checked"');
@@ -674,7 +677,7 @@ class FeedWordPressAdminPage {
 				print $labels[$globalSetting];
 			endif;  ?></strong> (<a href="<?php print $href; ?>">change</a>)</span></li>
 			</ul></td>
-			
+
 			<td class="equals second inactive">
 			<?php if ($defaultInputName != $inputName) : ?>
 				<ul class="options">
@@ -686,7 +689,7 @@ class FeedWordPressAdminPage {
 				<?php _e('Do something different with this feed.'); ?></label>
 			<?php endif;
 		endif;
-		
+
 		// Let's spit out the controls here.
 		if (is_callable($options)) :
 			// Method call to print out options list
@@ -703,7 +706,7 @@ class FeedWordPressAdminPage {
 			</ul> <!-- class="options" -->
 			<?php
 		endif;
-		
+
 		if ($offerSiteWide) :
 			if ($defaultInputName != $inputName) :
 				// Close the <li> and <ul class="options"> we opened above
@@ -712,7 +715,7 @@ class FeedWordPressAdminPage {
 				</ul> <!-- class="options" -->
 			<?php
 			endif;
-			
+
 			// Close off the twofer table that we opened up above.
 			?>
 			</td></tr>
@@ -721,7 +724,7 @@ class FeedWordPressAdminPage {
 			<?php
 		endif;
 	} /* FeedWordPressAdminPage::setting_radio_control () */
-	
+
 	function save_button ($caption = NULL) {
 		if (is_null($caption)) : $caption = __('Save Changes'); endif;
 		?>
@@ -732,6 +735,18 @@ class FeedWordPressAdminPage {
 	}
 } /* class FeedWordPressAdminPage */
 
+function fwp_update_set_results_message ($delta, $joiner = ';') {
+	$mesg = array();
+	if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
+	if (isset($delta['updated']) and ($delta['updated'] != 0)) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
+	if (isset($delta['stored']) and ($delta['stored'] != 0)) : $mesg[] = ' '.$delta['stored'].' alternate versions of existing posts were stored for reference'; endif;
+
+	if (!is_null($joiner)) :
+		$mesg = implode($joiner, $mesg);
+	endif;
+	return $mesg;
+} /* function fwp_update_set_results_message () */
+
 function fwp_authors_single_submit ($link = NULL) {
 ?>
 <div class="submitbox" id="submitlink">
@@ -772,13 +787,13 @@ function fwp_tags_box ($tags, $object, $params = array()) {
 	'id' => NULL,
 	'box_title' => __('Post Tags'),
 	));
-	
+
 	if (!is_array($tags)) : $tags = array(); endif;
-	
+
 	$tax_name = $params['taxonomy'];
 	$taxonomy = get_taxonomy($params['taxonomy']);
 	$disabled = (!current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '');
-	
+
 	$desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
 
 	if (is_null($params['textarea_name'])) :
@@ -793,11 +808,11 @@ function fwp_tags_box ($tags, $object, $params = array()) {
 	if (is_null($params['input_name'])) :
 		$params['input_name'] = "newtag[$tax_name]";
 	endif;
-	
+
 	if (is_null($params['id'])) :
 		$params['id'] = $tax_name;
 	endif;
-	
+
 	print $desc;
 	$helps = __('Separate tags with commas.');
 	$box['title'] = __('Tags');
@@ -807,7 +822,7 @@ function fwp_tags_box ($tags, $object, $params = array()) {
 	<div class="nojs-tags hide-if-js">
     <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
 	<textarea name="<?php echo $params['textarea_name']; ?>" class="the-tags" id="<?php echo $params['textarea_id']; ?>"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
-	
+
 	<?php if ( current_user_can($taxonomy->cap->assign_terms) ) :?>
 	<div class="ajaxtag hide-if-no-js">
 		<label class="screen-reader-text" for="<?php echo $params['input_id']; ?>"><?php echo $params['box_title']; ?></label>
@@ -818,7 +833,7 @@ function fwp_tags_box ($tags, $object, $params = array()) {
 	<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
 	<?php endif; ?>
 	</div>
-	
+
 	<div class="tagchecklist"></div>
 </div>
 <?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
@@ -869,7 +884,7 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
     <p id="<?php print $idPrefix; ?><?php print $taxonomy; ?>-add" class="category-add wp-hidden-child">
 	<?php
 	$newcat = 'new'.$taxonomy;
-	
+
 	?>
     <label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>"><?php _e('Add New Category'); ?></label>
     <input
@@ -877,7 +892,7 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
     	class="new<?php print $taxonomy; ?> form-required form-input-tip"
     	aria-required="true"
     	tabindex="3"
-    	type="text" name="<?php print $newcat; ?>" 
+    	type="text" name="<?php print $newcat; ?>"
     	value="<?php _e( 'New category name' ); ?>"
     />
     <label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>-parent"><?php _e('Parent Category:'); ?></label>
@@ -926,7 +941,7 @@ function fwp_author_list () {
 	global $wpdb;
 	$ret = array();
 
-	$users = get_users_of_blog();
+	$users = get_users();
 	if (is_array($users)) :
 		foreach ($users as $user) :
 			$id = (int) $user->ID;
@@ -940,9 +955,9 @@ function fwp_author_list () {
 }
 
 class FeedWordPressSettingsUI {
-	function is_admin () {
+	static function is_admin () {
 		global $fwp_path;
-		
+
 		$admin_page = false; // Innocent until proven guilty
 		if (isset($_REQUEST['page'])) :
 			$admin_page = (
@@ -952,18 +967,18 @@ class FeedWordPressSettingsUI {
 		endif;
 		return $admin_page;
 	}
-	
-	function admin_scripts () {
+
+	static function admin_scripts () {
 		global $fwp_path;
-	
+
 		wp_enqueue_script('post'); // for magic tag and category boxes
 		wp_enqueue_script('admin-forms'); // for checkbox selection
-	
+
 		wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
 		wp_enqueue_script('feedwordpress-elements');
 	}
 
-	function admin_styles () {
+	static function admin_styles () {
 		?>
 		<style type="text/css">
 		#feedwordpress-admin-feeds .link-rss-params-remove .x, .feedwordpress-admin .remove-it .x {
@@ -985,7 +1000,7 @@ class FeedWordPressSettingsUI {
 			background-position:0 top;
 			background-repeat:repeat-x;
 		}
-		
+
 		.update-results {
 			max-width: 100%;
 			overflow: auto;
@@ -994,8 +1009,8 @@ class FeedWordPressSettingsUI {
 		</style>
 		<?php
 	} /* FeedWordPressSettingsUI::admin_styles () */
-	
-	/*static*/ function ajax_nonce_fields () {
+
+	static function ajax_nonce_fields () {
 		if (function_exists('wp_nonce_field')) :
 			echo "<form style='display: none' method='get' action=''>\n<p>\n";
 			wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
@@ -1004,24 +1019,24 @@ class FeedWordPressSettingsUI {
 		endif;
 	} /* FeedWordPressSettingsUI::ajax_nonce_fields () */
 
-	/*static*/ function fix_toggles_js ($context) {
+	static function fix_toggles_js ($context) {
 	?>
 		<script type="text/javascript">
-			jQuery(document).ready( function($) {	
+			jQuery(document).ready( function($) {
 			// In case someone got here first...
 			$('.postbox h3, .postbox .handlediv').unbind('click');
 			$('.postbox h3 a').unbind('click');
 			$('.hide-postbox-tog').unbind('click');
 			$('.columns-prefs input[type="radio"]').unbind('click');
 			$('.meta-box-sortables').sortable('destroy');
-				
+
 			postboxes.add_postbox_toggles('<?php print $context; ?>');
 			} );
 		</script>
 	<?php
 	} /* FeedWordPressSettingsUI::fix_toggles_js () */
-	
-	function magic_input_tip_js ($id) {
+
+	static function magic_input_tip_js ($id) {
 			if (!preg_match('/^[.#]/', $id)) :
 				$id = '#'.$id;
 			endif;
@@ -1038,7 +1053,7 @@ class FeedWordPressSettingsUI {
 				inputBox.blur(function() {
 					if ( this.value == '' )
 						jQuery(this).val( this.defaultValue ).addClass( 'form-input-tip' );
-				});			
+				});
 			} );
 			</script>
 		<?php
@@ -1056,10 +1071,10 @@ function fwp_insert_new_user ($newuser_name) {
 		$userdata['user_nicename'] = apply_filters('pre_user_nicename', sanitize_title($newuser_name));
 		$userdata['display_name'] = $newuser_name;
 		$userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
-		
+
 		$blahUrl = get_bloginfo('url'); $url = parse_url($blahUrl);
 		$userdata['user_email'] = substr(md5(uniqid(microtime())), 0, 6).'@'.$url['host'];
-		
+
 		$newuser_id = wp_insert_user($userdata);
 		$ret = $newuser_id; // Either a numeric ID or a WP_Error object
 	else :
@@ -1081,7 +1096,7 @@ function fwp_add_meta_box ($id, $title, $callback, $page, $context = 'advanced',
 
 function fwp_do_meta_boxes($page, $context, $object) {
 	$ret = do_meta_boxes($page, $context, $object);
-		
+
 	// Avoid JavaScript error from WordPress 2.5 bug
 ?>
 	<div style="display: none">
@@ -1096,7 +1111,7 @@ function fwp_remove_meta_box($id, $page, $context) {
 } /* function fwp_remove_meta_box() */
 
 function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible = 'Y') {
-	
+
 	$subscribed = ('Y' == strtoupper($visible));
 	if ($subscribed or (count($links) > 0)) :
 	?>
@@ -1112,7 +1127,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 
 	<tbody>
 <?php
-		$alt_row = true; 
+		$alt_row = true;
 		if (count($links) > 0):
 			foreach ($links as $link):
 				$trClass = array();
@@ -1130,7 +1145,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 				if (is_null($sLink->setting('update/error'))) :
 					$errorsSince = '';
 					if (!is_null($sLink->setting('link/item count'))) :
-						$N = $sLink->setting('link/item count');	
+						$N = $sLink->setting('link/item count');
 						$fileSizeLines[] = sprintf((($N==1) ? __('%d item') : __('%d items')), $N);
 					endif;
 
@@ -1141,7 +1156,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 					$trClass[] = 'feed-error';
 
 					$theError = unserialize($sLink->setting('update/error'));
-					
+
 					$errorsSince = "<div class=\"returning-errors\">"
 						."<p><strong>Returning errors</strong> since "
 						.fwp_time_elapsed($theError['since'])
@@ -1155,7 +1170,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 				endif;
 
 				$nextUpdate = "<div style='max-width: 30.0em; font-size: 0.9em;'><div style='font-style:italic;'>";
-				
+
 				$ttl = $sLink->setting('update/ttl');
 				if (is_numeric($ttl)) :
 					$next = $sLink->setting('update/last') + $sLink->setting('update/fudge') + ((int) $ttl * 60);
@@ -1178,7 +1193,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 						else :
 							$lastUpdated .= gmdate('F j', $next + (get_option('gmt_offset') * 3600));
 						endif;
-						
+
 						$nextUpdate .= "Scheduled to be checked for updates every ".$ttl." minute".(($ttl!=1)?"s":"")."</div><div style='size:0.9em; margin-top: 0.5em'>	This update schedule was requested by the feed provider";
 						if ($sLink->setting('update/xml')) :
 							$nextUpdate .= " using a standard <code style=\"font-size: inherit; padding: 0; background: transparent\">&lt;".$sLink->setting('update/xml')."&gt;</code> element";
@@ -1194,11 +1209,11 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
 				if (count($fileSizeLines) > 0) :
 					$fileSize = '<div>'.implode(" / ", $fileSizeLines)."</div>";
 				endif;
-				
+
 				unset($sLink);
-				
+
 				$alt_row = !$alt_row;
-				
+
 				if ($alt_row) :
 					$trClass[] = 'alternate';
 				endif;
diff --git a/wp-content/plugins/feedwordpress/btc-qr-64px.png b/wp-content/plugins/feedwordpress/btc-qr-64px.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d23ec44dce6efcd150118b0bac951842c0b2734
Binary files /dev/null and b/wp-content/plugins/feedwordpress/btc-qr-64px.png differ
diff --git a/wp-content/plugins/feedwordpress/categories-page.php b/wp-content/plugins/feedwordpress/categories-page.php
index 3eb5515d5cffc45f49589aefaf6551f3bcae4524..a24c680b9d6f449d3eb8000fe04fa02e49bae8ef 100644
--- a/wp-content/plugins/feedwordpress/categories-page.php
+++ b/wp-content/plugins/feedwordpress/categories-page.php
@@ -6,7 +6,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 		if (is_numeric($link) and -1 == $link) :
 			$link = $this->submitted_link();
 		endif;
-		
+
 		FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
 		$this->dispatch = 'feedwordpress_admin_page_categories';
 		$this->pagenames = array(
@@ -16,7 +16,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 		);
 		$this->filename = __FILE__;
 	}
-	
+
 	function unfamiliar_category_label ($name) {
 		if (preg_match('/^create:(.*)$/', $name, $refs)) :
 			$tax = get_taxonomy($refs[1]);
@@ -24,11 +24,11 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 		endif;
 		return $name;
 	}
-	
-	
+
+
 	function feed_categories_box ($page, $box = NULL) {
 		$link = $page->link;
-		
+
 		$globalPostType = get_option('feedwordpress_syndicated_post_type', 'post');
 		if ($this->for_feed_settings()) :
 			$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
@@ -42,7 +42,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 		$tagLikeTaxonomies = array();
 		foreach ($taxonomies as $tax) :
 			$taxonomy = get_taxonomy($tax);
-			
+
 			if (!$taxonomy->hierarchical) :
 				$tagLikeTaxonomies[] = $tax;
 			endif;
@@ -62,12 +62,12 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 				);
 			endforeach;
 		endforeach;
-		
+
 		foreach ($unmatched as $what => $um) :
 			$unmatched[$what]['null'] = array('label' => __('Don\'t create any matching terms'));
 			$unmatchedRadio[$what]['null'] = '';
 		endforeach;
-		
+
 		$globalUnmatched = array(
 			'category' => FeedWordPress::on_unfamiliar('category'),
 			'post_tag' => FeedWordPress::on_unfamiliar('post_tag'),
@@ -77,21 +77,21 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 			if ($value=='tag') : $value = 'create:post_tag'; endif;
 			$globalUnmatched[$what] = $value;
 		endforeach;
-		
+
 		$globalMatch['cats'] = get_option('feedwordpress_match_cats', $taxonomies);
 		$globalMatch['tags'] = get_option('feedwordpress_match_tags', $tagLikeTaxonomies);
 		$globalMatch['filter'] = get_option('feedwordpress_match_filter', array());
-		
+
 		$globalMatchLabels = array();
 		$nothingDoing = array('cats' => "won't try to match", 'tags' => "won't try to match", "filter" => "won't filter");
-		
+
 		foreach ($globalMatch as $what => $domain) :
 			$labels = array(); $domain = array_filter($domain, 'remove_dummy_zero');
 			foreach ($domain as $tax) :
 				$tax = get_taxonomy($tax);
 				$labels[] = $tax->labels->name;
 			endforeach;
-			
+
 			if (count($labels) > 0) :
 				$globalMatchLabels[$what] = implode(", ", $labels);
 			else :
@@ -126,30 +126,30 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 					$unmatchedDefault[$what] = $opts[0];
 					$unmatchedColumns[$what] = array();
 				endif;
-				
+
 				$ucKey[$what] = $link->setting("unfamiliar $what", NULL, NULL);
 			endforeach;
-			
+
 			$match['cats'] = $this->link->setting('match/cats', NULL, NULL);
 			$match['tags'] = $this->link->setting('match/tags', NULL, NULL);
 			$match['filter'] = $this->link->setting('match/filter', NULL, NULL);
 		else :
 			foreach ($unmatched as $what => $um) :
-				$ucKey[$what] = FeedWordPress::on_unfamiliar($what); 
+				$ucKey[$what] = FeedWordPress::on_unfamiliar($what);
 			endforeach;
 
 			$match = $globalMatch;
 		endif;
-		
+
 		foreach ($ucKey as $what => $uck) :
 			if ($uck == 'tag') : $uck = 'create:post_tag'; endif;
 			if ($uck == 'create') : $uck = 'create:category'; endif;
-			
+
 			if (!is_string($uck)) :
 				$uck = $unmatchedDefault[$what];
 			endif;
 			$ucKey[$what] = $uck;
-			
+
 			if (!array_key_exists($uck, $unmatchedRadio[$what])) :
 				$obsoleteLi = array(
 					$uck => array(
@@ -159,12 +159,12 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 				$unmatched[$what] = array_merge($obsoleteLi, $unmatched[$what]);
 				$unmatchedRadio[$what][$uck] = ' disabled="disabled"';
 			endif;
-			
+
 			$unmatchedRadio[$what][$uck] .= ' checked="checked"';
-			
+
 			$unmatchedColumns[$what][] = $unmatched[$what];
 		endforeach;
-		
+
 		$defaulted = array();
 		foreach ($match as $what => $set) :
 			$defaulted[$what] = false;
@@ -175,7 +175,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
 					$match[$what] = $globalMatch[$what];
 				endif;
 			endif;
-			
+
 			if (!$defaulted[$what] or $this->for_feed_settings()) :
 				foreach ($set as $against) :
 					if (array_key_exists($against, $matchUl[$what])) :
@@ -350,7 +350,7 @@ least one local <strong><?php $l = $li['labels']; print $l->singular_name; ?></s
 <?php if ($page->for_feed_settings()) : ?>
 <tr>
 <th scope="row">Multiple categories:</th>
-<td> 
+<td>
 <input type="text" size="20" id="cat_split" name="cat_split" value="<?php if (isset($link->settings['cat_split'])) : echo htmlspecialchars($link->settings['cat_split']); endif; ?>" />
 <p class="setting-description">Enter a <a href="http://us.php.net/manual/en/reference.pcre.pattern.syntax.php">Perl-compatible regular expression</a> here if the feed provides multiple
 categories in a single category element. The regular expression should match
@@ -376,9 +376,11 @@ blank.</p></td>
 			'post_tag' => 'tags',
 		);
 	}
-	
+
 	function categories_box ($page, $box = NULL) {
 		$link = $page->link;
+		$dummy = null;
+		$syndicatedlink = new SyndicatedLink($dummy);
 
 		if ($this->for_feed_settings()) :
 			$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
@@ -417,7 +419,7 @@ blank.</p></td>
 				$add_global_categories = $link->setting("add/$tax", NULL, 'yes');
 				$checked = array('yes' => '', 'no' => '');
 				$checked[$add_global_categories] = ' checked="checked"';
-				
+
 				if (isset($setting_map[$tax])) :
 					$setting = $setting_map[$tax];
 					$cats = $link->setting($setting, NULL, NULL);
@@ -430,7 +432,7 @@ blank.</p></td>
 			else :
 				$cats = $globalCats;
 			endif;
-			
+
 			if ($page->for_feed_settings()) :
 			?>
 			<table class="twofer">
@@ -439,17 +441,17 @@ blank.</p></td>
 			<td class="primary">
 			<?php
 			endif;
-			
-			$dogs = SyndicatedPost::category_ids($cats, /*unfamiliar=*/ NULL, /*taxonomies=*/ array($tax));
+
+			$dogs = $syndicatedlink->category_ids(/*post=*/ NULL, $cats, /*unfamiliar=*/ NULL, /*taxonomies=*/ array($tax));
 			
 			if ($taxonomy->hierarchical) : // Use a category-style checkbox
 				fwp_category_box($dogs, 'all '.$page->these_posts_phrase(), /*tags=*/ array(), /*params=*/ array('taxonomy' => $tax));
 			else : // Use a tag-style edit box
 				fwp_tags_box($cats, 'all '.$page->these_posts_phrase(), /*params=*/ array('taxonomy' => $tax));
 			endif;
-			
-			$globalDogs = SyndicatedPost::category_ids($globalCats, /*unfamiliar=*/ 'create:'.$tax, /*taxonomies=*/ array($tax));
-	
+
+			$globalDogs = $syndicatedlink->category_ids(/*post=*/ NULL, $globalCats, /*unfamiliar=*/ 'create:'.$tax, /*taxonomies=*/ array($tax));
+
 			$siteWideHref = $this->admin_page_href(basename(__FILE__));
 
 			if ($page->for_feed_settings()) :
@@ -472,7 +474,7 @@ blank.</p></td>
 			Should <?php print $page->these_posts_phrase(); ?> be assigned
 			these <?php print $taxonomy->labels->name; ?> from the <a href="<?php print esc_html($siteWideHref); ?>">site-wide settings</a>, in
 			addition to the feed-specific <?php print $taxonomy->labels->name; ?> you set up here?</p>
-			
+
 			<ul class="settings">
 			<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="yes" <?php print $checked['yes']; ?> /> Yes. Place <?php print $page->these_posts_phrase(); ?> under all these categories.</label></p></li>
 			<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="no" <?php print $checked['no']; ?> /> No. Only use the categories I set up on the left. Do not use the global defaults for <?php print $page->these_posts_phrase(); ?></label></p></li>
@@ -493,7 +495,7 @@ blank.</p></td>
 		</table>
 		<?php
 	} /* FeedWordPressCategoriesPage::categories_box () */
-	
+
 	function save_settings ($post) {
 		if (isset($post['match_categories'])) :
 			foreach ($post['match_categories'] as $what => $set) :
@@ -504,7 +506,7 @@ blank.</p></td>
 				and $post['match_default'][$what]=='yes') :
 					$set = NULL; // Defaulted!
 				endif;
-				
+
 				$this->update_setting("match/$what", $set, NULL);
 			endforeach;
 		endif;
@@ -512,9 +514,9 @@ blank.</p></td>
 		$settingMap = $this->term_setting_map();
 
 		$saveTerms = array(); $separateSaveTerms = array('category' => array(), 'post_tag' => array());
-		
+
 		if (!isset($post['tax_input'])) : $post['tax_input'] = array(); endif;
-		
+
 		// Merge in data from older-notation category check boxes
 		if (isset($post['post_category'])) :
 			// Just merging in for processing below.
@@ -537,7 +539,7 @@ blank.</p></td>
 				$saveTerms[$tax] = explode(",", $terms);
 			endif;
 			$saveTerms[$tax] = array_map('trim', $saveTerms[$tax]);
-			
+
 			if (isset($optionMap[$tax])) :
 				$separateSaveTerms[$tax] = $saveTerms[$tax];
 				unset($saveTerms[$tax]);
@@ -546,10 +548,10 @@ blank.</p></td>
 
 		if (isset($post['post_category'])) :
 			foreach ($post['post_category'] as $cat) :
-				$separateSaveTerms['category'][] = '{category#'.$cat.'}'; 
+				$separateSaveTerms['category'][] = '{category#'.$cat.'}';
 			endforeach;
 		endif;
-		
+
 		// Unmatched categories and tags
 		foreach (array('category', 'post_tag') as $what) :
 			if (isset($post["unfamiliar_{$what}"])) :
@@ -560,7 +562,7 @@ blank.</p></td>
 				);
 			endif;
 		endforeach;
-		
+
 		// Categories and Tags
 		foreach ($separateSaveTerms as $tax => $terms) :
 			if ($this->for_feed_settings()) :
@@ -573,7 +575,7 @@ blank.</p></td>
 				endif;
 			endif;
 		endforeach;
-		
+
 		// Other terms
 		$this->update_setting(array('feed'=>'terms', 'global'=>'syndication_terms'), $saveTerms, array());
 
@@ -582,7 +584,7 @@ blank.</p></td>
 			if (isset($post['cat_split'])) :
 				$this->link->update_setting('cat_split', trim($post['cat_split']), '');
 			endif;
-			
+
 			// Treat global terms (cats, tags, etc.) as additional,
 			// or as defaults to be overridden and replaced?
 			if (isset($post['add_global'])) :
@@ -593,18 +595,18 @@ blank.</p></td>
 		endif;
 		parent::save_settings($post);
 	} /* FeedWordPressCategoriesPage::save_settings() */
-	
+
 	function display () {
 		////////////////////////////////////////////////
 		// Display settings boxes //////////////////////
 		////////////////////////////////////////////////
-	
+
 		$this->boxes_by_methods = array(
 			'feed_categories_box' => __('Feed Categories & Tags'),
 			'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
 		);
 
-		parent::display();	
+		parent::display();
 	}
 }
 
diff --git a/wp-content/plugins/feedwordpress/compatability.php b/wp-content/plugins/feedwordpress/compatability.php
index d108a02b7b331fd234703a50def300d1c24b9824..e0e3f36e47ac12b679ee16c4c65c9f8508d2ff2a 100644
--- a/wp-content/plugins/feedwordpress/compatability.php
+++ b/wp-content/plugins/feedwordpress/compatability.php
@@ -15,9 +15,9 @@ class FeedWordPressCompatibility {
 	 * @return bool TRUE if within the range of versions, FALSE if too low
 	 * 	or too high.
 	 */
-	/*static*/ function test_version ($floor, $ceiling = null) {
+	static function test_version ($floor, $ceiling = null) {
 		global $wp_db_version;
-		
+
 		$ver = (isset($wp_db_version) ? $wp_db_version : 0);
 		$good = ($ver >= $floor);
 		if (!is_null($ceiling)) :
@@ -26,7 +26,7 @@ class FeedWordPressCompatibility {
 		return $good;
 	} /* FeedWordPressCompatibility::test_version() */
 
-	/*static*/ function insert_link_category ($name) {
+	static function insert_link_category ($name) {
 		global $wpdb;
 
 		// WordPress 2.3+ term/taxonomy API
@@ -45,12 +45,12 @@ class FeedWordPressCompatibility {
 		else :
 			$cat_id = $term;
 		endif;
-	
+
 		// Return newly-created category ID
 		return $cat_id;
 	} /* FeedWordPressCompatibility::insert_link_category () */
 
-	/*static*/ function link_category_id ($value, $key = 'cat_name') {
+	static function link_category_id ($value, $key = 'cat_name') {
 		global $wpdb;
 
 		$cat_id = NULL;
@@ -65,11 +65,11 @@ class FeedWordPressCompatibility {
 		else :
 			$cat_id = $the_term;
 		endif;
-		
+
 		return $cat_id;
 	} /* FeedWordPressCompatibility::link_category_id () */
 
-	/*static*/ function validate_http_request ($action = -1, $capability = null) {
+	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') :
 			// Limit post by user capabilities
@@ -87,15 +87,15 @@ class FeedWordPressCompatibility {
 			endif;
 		endif;
 	} /* FeedWordPressCompatibility::validate_http_request() */
-	
-	/*static*/ function stamp_nonce ($action = -1) {
+
+	static function stamp_nonce ($action = -1) {
 		// stamp form with hidden fields for a nonce in WP 2.0.3 & later
 		if (function_exists('wp_nonce_field')) :
 			wp_nonce_field($action);
 		endif;
 	} /* FeedWordPressCompatibility::stamp_nonce() */
-	
-	/*static*/ function bottom_script_hook ($filename) {
+
+	static function bottom_script_hook ($filename) {
 		global $fwp_path;
 
 		$hook = 'admin_footer-'.$fwp_path.'/'.basename($filename);
@@ -125,11 +125,11 @@ if (!function_exists('set_post_field')) {
 	 * Included under terms of GPL from WordPress Ticket #10946 <http://core.trac.wordpress.org/attachment/ticket/10946/post.php.diff>
 	 */
 	function set_post_field ($field, $value, $post_id) {
-		global $wpdb; 
+		global $wpdb;
 
 		$post_id = absint($post_id);
 		// sigh ... when FWP is active, I need to avoid avoid_kses_munge
-		// $value = sanitize_post_field($field, $value, $post_id, 'db'); 
+		// $value = sanitize_post_field($field, $value, $post_id, 'db');
 		return $wpdb->update($wpdb->posts, array($field => $value), array('ID' => $post_id));
 	} /* function set_post_field () */
 
@@ -145,10 +145,10 @@ function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selec
 		$prefix = (isset($params['prefix']) ? $params['prefix'] : '');
 		$taxonomy = (isset($params['taxonomy']) ? $params['taxonomy'] : 'category');
 	endif;
-	
+
 	$walker = new FeedWordPress_Walker_Category_Checklist($params);
 	$walker->set_prefix($prefix);
-	$walker->set_taxonomy($taxonomy); 
+	$walker->set_taxonomy($taxonomy);
 	wp_terms_checklist(/*post_id=*/ $post_id, array(
 		'taxonomy' => $taxonomy,
 		'descendents_and_self' => $descendents_and_self,
diff --git a/wp-content/plugins/feedwordpress/diagnostics-page.php b/wp-content/plugins/feedwordpress/diagnostics-page.php
index 2c12b8e02dea1d0392b8114fe17a92f602577cf6..46c397502585c3bc6cb250cd9aa52462485d100e 100644
--- a/wp-content/plugins/feedwordpress/diagnostics-page.php
+++ b/wp-content/plugins/feedwordpress/diagnostics-page.php
@@ -7,7 +7,7 @@ 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);
 	}
@@ -17,15 +17,15 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 	function display () {
 		global $wpdb, $wp_db_version, $fwp_path;
 		global $fwp_post;
-		
+
 		if (FeedWordPress::needs_upgrade()) :
 			fwp_upgrade_page();
 			return;
 		endif;
-	
+
 		// If this is a POST, validate source and user credentials
 		FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_diagnostics', /*capability=*/ 'manage_options');
-	
+
 		if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
 			$this->accept_POST($fwp_post);
 			do_action('feedwordpress_admin_page_diagnostics_save', $fwp_post, $this);
@@ -47,7 +47,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 			'updates_box' => __('Updates'),
 			'tests_box' => __('Diagnostic Tests'),
 		);
-	
+
 		foreach ($boxes_by_methods as $method => $title) :
 			add_meta_box(
 				/*id=*/ 'feedwordpress_'.$method,
@@ -76,13 +76,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		or isset($post['feedwordpress_diagnostics_do'])) :
 			update_option('feedwordpress_debug', $post['feedwordpress_debug']);
 			update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
-			
+
 			if (!isset($post['diagnostics_output'])
 			or !is_array($post['diagnostics_output'])) :
 				$post['diagnostics_output'] = array();
 			endif;
 			update_option('feedwordpress_diagnostics_output', $post['diagnostics_output']);
-	
+
 			if (!isset($post['diagnostics_show'])
 			or !is_array($post['diagnostics_show'])) :
 				$post['diagnostics_show'] = array();
@@ -95,7 +95,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 			else :
 				delete_option('feedwordpress_diagnostics_persistent_errors_hours');
 			endif;
-			
+
 			if (in_array('email', $post['diagnostics_output'])) :
 				$ded = $post['diagnostics_email_destination'];
 				if ('mailto'==$ded) :
@@ -106,18 +106,18 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 			else :
 				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) {
+	static function info_box ($page, $box = NULL) {
 		global $feedwordpress;
 		global $wp_version;
 		$link_category_id = FeedWordPress::link_category_id();
@@ -147,7 +147,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		</ul>
 		</td>
 		</tr>
-		
+
 		<tr>
 		<th scope="row">Link Category:</th>
 		<td><?php if (!is_wp_error($link_category_id)) :
@@ -168,13 +168,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		<?php $data = $link_category_id->get_error_data(); if (!empty($data)) : ?>
 		<tr>
 		<th scope="row">Auxiliary Data:</th>
-		<td><pre><?php print esc_html(FeedWordPress::val($link_category_id->get_error_data())); ?></pre></td>
+		<td><pre><?php print esc_html(MyPHP::val($link_category_id->get_error_data())); ?></pre></td>
 		</tr>
 		<?php endif; ?>
 		</table>
 		<?php endif; ?></td>
 		</tr>
-		
+
 		<tr>
 		<th scope="row"><?php _e('Secret Key:'); ?></th>
 		<td><input type="text" name="feedwordpress_secret_key" value="<?php print esc_attr($feedwordpress->secret_key()); ?>" />
@@ -186,13 +186,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 
 		<?php
 	} /* FeedWordPressDiagnosticsPage::info_box () */
-	
-	function diagnostics_box ($page, $box = NULL) {
+
+	static function diagnostics_box ($page, $box = NULL) {
 		$settings = array();
 		$settings['debug'] = (get_option('feedwordpress_debug')=='yes');
 
 		$diagnostics_output = get_option('feedwordpress_diagnostics_output', array());
-		
+
 		$users = fwp_author_list();
 
 		$ded = get_option('feedwordpress_diagnostics_email_destination', 'admins');
@@ -202,7 +202,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
 		else :
 			$ded_addy = NULL;
 		endif;
-		
+
 		// Hey ho, let's go...
 		?>
 <table class="edit-form">
@@ -255,16 +255,16 @@ testing but absolutely inappropriate for a production server.</p>
 			'mailto',
 			'inline'
 		);
-	} );	
+	} );
 </script>
 		<?php
 	} /* FeedWordPressDiagnosticsPage::diagnostics_box () */
-	
-	/*static*/ function updates_box ($page, $box = NULL) {
+
+	static function updates_box ($page, $box = NULL) {
 		$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
 		$fields = apply_filters('feedwordpress_diagnostics', array(
 			'Update Diagnostics' => array(
-				'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule', 
+				'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
 				'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',
@@ -276,15 +276,17 @@ testing but absolutely inappropriate for a production server.</p>
 			'Syndicated Post Details' => array(
 				'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
 				'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
+				'syndicated_posts:categories' => 'as categories, tags, and other terms are added on the post',
 				'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', 
+				'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:categories:test' => 'as FeedWordPress checks for the familiarity of feed categories and tags',
 				'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
 			),
 		), $page);
-		
+
 		foreach ($fields as $section => $items) :
 			foreach ($items as $key => $label) :
 				$checked[$key] = '';
@@ -317,8 +319,8 @@ testing but absolutely inappropriate for a production server.</p>
 </table>
 		<?php
 	} /* FeedWordPressDiagnosticsPage::updates_box () */
-	
-	function tests_box ($page, $box = NULL) {
+
+	static function tests_box ($page, $box = NULL) {
 ?>
 <script type="text/javascript">
 function clone_http_test_args_keyvalue_prototype () {
@@ -327,7 +329,7 @@ function clone_http_test_args_keyvalue_prototype () {
 	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');	
+	newRow.appendTo('#http-test-args');
 	return false;
 }
 </script>
@@ -354,7 +356,7 @@ function clone_http_test_args_keyvalue_prototype () {
 	<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">
@@ -370,10 +372,10 @@ function clone_http_test_args_keyvalue_prototype () {
 	} /* FeedWordPressDiagnosticsPage::tests_box () */
 
 	var $test_html;
-	function do_http_test ($post) {
+	static 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) :
@@ -384,21 +386,21 @@ function clone_http_test_args_keyvalue_prototype () {
 						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')) :	
+							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);
@@ -408,10 +410,10 @@ function clone_http_test_args_keyvalue_prototype () {
 				break;
 			endswitch;
 			
-			$this->test_html['http_test'] = esc_html(FeedWordPress::val($out));
+			$this->test_html['http_test'] = esc_html(MyPHP::val($out));
 		endif;
 	} /* FeedWordPressDiagnosticsPage::do_http_test () */
-	
+
 } /* class FeedWordPressDiagnosticsPage */
 
 	$diagnosticsPage = new FeedWordPressDiagnosticsPage;
diff --git a/wp-content/plugins/feedwordpress/externals/myphp/myphp.class.php b/wp-content/plugins/feedwordpress/externals/myphp/myphp.class.php
index 9d37e54b51d840012eb26cd6bd9c02efde46a7da..250572e1eed1889474299f328c873f4fa7a44327 100644
--- a/wp-content/plugins/feedwordpress/externals/myphp/myphp.class.php
+++ b/wp-content/plugins/feedwordpress/externals/myphp/myphp.class.php
@@ -1,7 +1,23 @@
 <?php
+/**
+ * MyPHP: handy general utility functions, for things that PHP should do, but
+ * doesn't do (yet).
+ * 
+ * @package MyPHP
+ * @version 2014.0805
+ */
 if (!class_exists('MyPHP')) :
 	class MyPHP {
-		// For dealing with HTTP GET/POST parameters sent to us as input
+		/**
+		 * MyPHP::param: For dealing with HTTP GET/POST parameters sent
+		 * to us as input.
+		 *
+		 * @param string $key The name of the GET/POST parameter
+		 * @param mixed $default Default to return if parameter is unset
+		 * @param string $type 'GET', 'POST' or 'REQUEST' (=both GET and POST)
+		 * @return mixed The value of the named parameter, or the fallback
+		 *    in $default if there is no value set for that param name.
+		 */
 		static public function param ($key, $default = NULL, $type = 'REQUEST') {
 			// PHP 5.4 introduces "just-in-time" initialization of
 			// $GLOBALS. Which seems to me largely to defeat the
@@ -26,14 +42,40 @@ if (!class_exists('MyPHP')) :
 			return $ret;
 		} /* MyPHP::param () */
 		
+		/**
+		 * MyPHP::post: For dealing with HTTP POST parameters sent as input
+		 *
+		 * @param string $key The name of the POST parameter
+		 * @param mixed $default Default to return if parameter is unset
+		 * @return mixed The value of the named parameter, or the fallback
+		 *    in $default if there is no value set for that param name.
+		 */
 		static function post ($key, $default = NULL) {
 			return self::param($key, $default, 'POST');
 		} /*MyPHP::post () */
 		
+		/**
+		 * MyPHP::post: For dealing with HTTP GET parameters sent as input
+		 *
+		 * @param string $key The name of the GET parameter
+		 * @param mixed $default Default to return if parameter is unset
+		 * @return mixed The value of the named parameter, or the fallback
+		 *    in $default if there is no value set for that param name.
+		 */
 		static function get ($key, $default = NULL) {
 			return self::param($key, $default, "GET");
 		} /* MyPHP::get () */
 		
+		/**
+		 * MyPHP::request: For dealing with HTTP GET/POST parameters
+		 * sent as input. This method checks both GET parameters and POST
+		 * parameters and will return values from either.
+		 *
+		 * @param string $key The name of the GET/POST parameter
+		 * @param mixed $default Default to return if parameter is unset
+		 * @return mixed The value of the named parameter, or the fallback
+		 *    in $default if there is no value set for that param name.
+		 */
 		static function request ($key, $default = NULL) {
 			return self::param($key, $default, "REQUEST");
 		} /* MyPHP::request () */
@@ -82,7 +124,26 @@ if (!class_exists('MyPHP')) :
 			endforeach;
 			return implode("&", $getQuery);
 		} /* MyPHP::to_http_post () */
-	}
+		
+		/**
+		 * MyPHP::val(): Captures the output of var_dump() to a string,
+		 * with some optional filtering removing newlines and replacing 
+		 * them with spaces) applied.
+		 *
+		 * @param mixed $v Value to dump to a string representation
+		 * @param bool $no_newlines Whether to filter out newline chars
+		 *
+		 * @return string
+		 */
+		 static function val ($v, $no_newlines = false) {
+		 	 ob_start();
+		 	 var_dump($v);
+		 	 $out = ob_get_contents(); ob_end_clean();
+		
+		 	 if ($no_newlines) :
+		 	 	$out = preg_replace('/\s+/', " ", $out);
+		 	 endif;
+		 	 return $out;
+		 } /* MyPHP::val () */
+	} /* class MyPHP */
 endif;
-
-
diff --git a/wp-content/plugins/feedwordpress/feeds-page.php b/wp-content/plugins/feedwordpress/feeds-page.php
index a87360669e51df957d36f83c3d5d71e2d68a5e5d..c1e755d941216a2af92f89a1548dae6fd57725b1 100644
--- a/wp-content/plugins/feedwordpress/feeds-page.php
+++ b/wp-content/plugins/feedwordpress/feeds-page.php
@@ -901,7 +901,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 					$feed_version = '';
 				endif;
 				?>
-					<form<?php print $form_class; ?> action="<?php $this->form_action('syndication.php'); ?>" method="post">
+					<form<?php print $form_class; ?> action="<?php print $this->form_action('syndication.php'); ?>" method="post">
 					<div class="inside"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?>
 
 					<?php
@@ -1034,7 +1034,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 						
 						print "<h4>".__("HTTP Transport").":</h4>\n";
 						print "<ol>\n";
-						print "<li>".FeedWordPress::val($transport)."</li>\n";
+						print "<li>".MyPHP::val($transport)."</li>\n";
 						print "</ol>\n";
 					endif;
 					
@@ -1069,9 +1069,9 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
 		$alt = $params['alt'];
 		
 		?>
-		<form action="<?php $this->form_action(); ?>" method="post">
+		<form action="<?php print $this->form_action('syndication.php'); ?>" method="post">
 		<div class="inside"><?php
-			FeedWordPressCompatibility::stamp_nonce($this->dispatch);
+			FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds');
 		?>
 		<fieldset class="alt"
 		<?php if (!$alt): ?>style="margin: 1.0em 3.0em; font-size: smaller;"<?php endif; ?>>
diff --git a/wp-content/plugins/feedwordpress/feedwordpie.class.php b/wp-content/plugins/feedwordpress/feedwordpie.class.php
index 49bf11195d081bfc21f1865a3be7c7ef5848a472..55cad62884bc6524f09411293bdb52e39582480a 100644
--- a/wp-content/plugins/feedwordpress/feedwordpie.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpie.class.php
@@ -10,7 +10,7 @@ class FeedWordPie extends SimplePie {
 
 			// Get URL with relevant parameters attached.
 			// Credentials will be handled further down.
-			$new_url = $url->uri(array('add_params' => true));
+			$new_url = $url->uri(array('add_params' => true, 'fetch' => true));
 			
 			// Store for reference.
 			$this->subscription = $url->id();
@@ -43,10 +43,12 @@ class FeedWordPie extends SimplePie {
 	}
 	
 	function get_feed_tags ($namespace, $tag) {
+		$tags = parent::get_feed_tags($namespace, $tag);
+		
 		// Allow filters to filter SimplePie handling
 		return apply_filters(
 			'feedwordpie_get_feed_tags',
-			parent::get_feed_tags($namespace, $tag),
+			$tags,
 			$namespace,
 			$tag,
 			$this
diff --git a/wp-content/plugins/feedwordpress/feedwordpress-elements.css b/wp-content/plugins/feedwordpress/feedwordpress-elements.css
index 11fcf2903d0e8a4e1a9941a3ae32abe37dfcfea5..447a3180787f036bbfac7d1448668fb41bb1df7b 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress-elements.css
+++ b/wp-content/plugins/feedwordpress/feedwordpress-elements.css
@@ -330,7 +330,7 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
 }
 #feedwordpress-admin-syndication .update-form.with-donation {
 	margin-right: 50%;
-	min-height: 255px;
+	min-height: 355px;
 }
 #feedwordpress-admin-syndication .donation-form,
 #feedwordpress-admin-syndication .donation-thanks {
@@ -468,4 +468,6 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
 	padding: 10px;
 }
 
-
+.hovered-component .hover-on { display: none; }
+.hovered-component:hover .hover-on { display: inline; }
+.hovered-component:hover .hover-on.pop-over { display: block; position: absolute; }
diff --git a/wp-content/plugins/feedwordpress/feedwordpress-walker-category-checklist.class.php b/wp-content/plugins/feedwordpress/feedwordpress-walker-category-checklist.class.php
index e78a2099510c9cc199f55d2b2f9c133784b279c6..ea7e39e4a49b0015bd3f65950974efddff63c380 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress-walker-category-checklist.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress-walker-category-checklist.class.php
@@ -15,12 +15,12 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
 	var $checkbox_name = NULL;
 	function FeedWordPress_Walker_Category_Checklist ($params = array()) {
 		$this->set_taxonomy('category');
-		
+
 		if (isset($params['checkbox_name'])) :
 			$this->checkbox_name = $params['checkbox_name'];
 		endif;
 	}
-	
+
 	function set_prefix ($prefix) {
 		$this->prefix = $prefix;
 	}
@@ -28,11 +28,11 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
 		$this->taxonomy = $taxonomy;
 	}
 
-	function start_el (&$output, $category, $depth, $args) {
+	function start_el( &$output, $category, $depth = 0, $args = array(), $current_object_id = 0 ) {
 		extract($args);
                if ( empty($taxonomy) ) :
 			$taxonomy = 'category';
-		endif; 
+		endif;
 
 		if (!is_null($this->checkbox_name)) :
 			$name = $this->checkbox_name;
@@ -41,7 +41,7 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
 		else :
 			$name = 'tax_input['.$taxonomy.']';
 		endif;
-		
+
 		$unit = array();
 		if (strlen($this->prefix) > 0) :
 			$unit[] = $this->prefix;
diff --git a/wp-content/plugins/feedwordpress/feedwordpress.php b/wp-content/plugins/feedwordpress/feedwordpress.php
index 75506b80843dc819d7baa46503fa5b138fb2ac31..98c2feb4a1d31209ea53890b3521c136fc2403a8 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: 2013.0504
+Version: 2014.0805
 Author: Charles Johnson
 Author URI: http://radgeek.com/
 License: GPL
@@ -11,7 +11,7 @@ License: GPL
 
 /**
  * @package FeedWordPress
- * @version 2013.0504
+ * @version 2014.0805
  */
 
 # This uses code derived from:
@@ -27,17 +27,18 @@ License: GPL
 # USAGE: once FeedWordPress is installed, you manage just about everything from
 # 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 
+# 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', '2013.0504');
+define ('FEEDWORDPRESS_VERSION', '2014.0805');
 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
 
 if (!defined('FEEDWORDPRESS_BLEG')) :
 	define ('FEEDWORDPRESS_BLEG', true);
 endif;
+define('FEEDWORDPRESS_BLEG_BTC', '1FN3Q4VSR4jV7unRjaknVQVe5ky88ktPHS');
 
 // Defaults
 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
@@ -70,9 +71,9 @@ if (FEEDWORDPRESS_DEBUG) :
 	// Help us to pick out errors, if any.
 	ini_set('error_reporting', E_ALL & ~E_NOTICE);
 	ini_set('display_errors', true);
-	
+
 	 // When testing we don't want cache issues to interfere. But this is
-	 // a VERY BAD SETTING for a production server. Webmasters will eat your 
+	 // a VERY BAD SETTING for a production server. Webmasters will eat your
 	 // face for breakfast if you use it, and the baby Jesus will cry. So
 	 // make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
 	 // used for more than testing purposes!
@@ -101,11 +102,11 @@ if (!function_exists('wp_insert_user')) :
 	require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
 endif;
 
-$dir = dirname(__FILE__); 
+$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             
+require_once("${dir}/compatability.php"); // Legacy API
 require_once("${dir}/syndicatedpost.class.php");
 require_once("${dir}/syndicatedlink.class.php");
 require_once("${dir}/feedwordpresshtml.class.php");
@@ -141,7 +142,8 @@ else : // Something went wrong. Let's just guess.
 	$fwp_path = 'feedwordpress';
 endif;
 
-if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
+$feedwordpress = new FeedWordPress;
+if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
 
 	# Syndicated items are generally received in output-ready (X)HTML and
 	# should not be folded, crumpled, mutilated, or spindled by WordPress
@@ -158,18 +160,18 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 
 	add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
 	add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
-	
+
 	add_action('atom_entry', 'feedwordpress_item_feed_data');
-	
+
 	# 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');
 	add_filter('the_permalink_rss', 'syndication_permalink_escaped');
-	
+
 	add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
 
 	# WTF? By default, wp_insert_link runs incoming link_url and link_rss
@@ -178,17 +180,17 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 	# happens to fuck up any URI with a & to separate GET parameters.
 	remove_filter('pre_link_rss', 'wp_filter_kses');
 	remove_filter('pre_link_url', 'wp_filter_kses');
-	
+
 	# Admin menu
-	add_action('admin_init', array('feedwordpress', 'admin_init'));
+	add_action('admin_init', array($feedwordpress, 'admin_init'));
 	add_action('admin_menu', 'fwp_add_pages');
 	add_action('admin_notices', 'fwp_check_debug');
 
 	add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
 	add_action('save_post', 'feedwordpress_save_post_edit_controls');
 
-	add_action('admin_footer', array('FeedWordPress', 'admin_footer'));
-	
+	add_action('admin_footer', array($feedwordpress, 'admin_footer'));
+
 	# Inbound XML-RPC update methods
 	$feedwordpressRPC = new FeedWordPressRPC;
 
@@ -206,24 +208,25 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
 
 	add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
 	add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
-	
-	$feedwordpress = new FeedWordPress;
 
 	# Cron-less auto-update. Hooray!
 	$autoUpdateHook = $feedwordpress->automatic_update_hook();
 	if (!is_null($autoUpdateHook)) :
 		add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
 	endif;
-	
+
 	add_action('init', array($feedwordpress, 'init'));
 	add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
+	add_action('shutdown', array($feedwordpress, 'feedwordpress_cleanup'));
 	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'));
+	add_action('plugins_loaded', array($feedwordpress, 'admin_api'));
+	add_action('all_admin_notices', array($feedwordpress, 'all_admin_notices'));
+
 else :
 	# Hook in the menus, which will just point to the upgrade interface
 	add_action('admin_menu', 'fwp_add_pages');
@@ -238,6 +241,10 @@ class FeedWordPressDiagnostic {
 		$wpError = $error['object'];
 		$url = $link->uri();
 		
+		// check for effects of an effective-url filter
+		$effectiveUrl = $link->uri(array('fetch' => true));
+		if ($url != $effectiveUrl) : $url .= ' | ' . $effectiveUrl; endif;
+
 		$mesgs = $wpError->get_error_messages();
 		foreach ($mesgs as $mesg) :
 			$mesg = esc_html($mesg);
@@ -245,7 +252,7 @@ class FeedWordPressDiagnostic {
 				'updated_feeds:errors',
 				"Feed Error: [${url}] update returned error: $mesg"
 			);
-			
+
 			$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
 			$span = ($error['ts'] - $error['since']);
 
@@ -311,8 +318,8 @@ function debug_out_feedwordpress_footer () {
  * displaying a post.
  *
  * @param int $id The post to check for syndicated status. Defaults to the current post in a Loop context.
- * @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise 
- */ 
+ * @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise
+ */
 function is_syndicated ($id = NULL) {
 	$p = new FeedWordPressLocalPost($id);
 	return $p->is_syndicated();
@@ -320,12 +327,12 @@ function is_syndicated ($id = NULL) {
 
 function feedwordpress_display_url ($url, $before = 60, $after = 0) {
 	$bits = parse_url($url);
-	
+
 	// Strip out crufty subdomains
 	if (isset($bits['host'])) :
   		$bits['host'] = preg_replace('/^www[0-9]*\./i', '', $bits['host']);
   	endif;
-  
+
   	// Reassemble bit-by-bit with minimum of crufty elements
 	$url = (isset($bits['user'])?$bits['user'].'@':'')
 		.(isset($bits['host'])?$bits['host']:'')
@@ -334,7 +341,7 @@ function feedwordpress_display_url ($url, $before = 60, $after = 0) {
 		.(isset($bits['query'])?'?'.$bits['query']:'');
 
 	if (strlen($url) > ($before+$after)) :
-		$url = substr($url, 0, $before).'…'.substr($url, 0 - $after, $after);
+		$url = substr($url, 0, $before).'.'.substr($url, 0 - $after, $after);
 	endif;
 
 	return $url;
@@ -433,7 +440,7 @@ function the_syndication_permalink ($id = NULL) {
  */
 function get_local_permalink ($id = NULL) {
 	global $feedwordpress_the_original_permalink;
-	
+
 	// get permalink, and thus activate filter and force global to be filled
 	// with original URL.
 	$url = get_permalink($id);
@@ -476,7 +483,7 @@ function feedwordpress_preserve_syndicated_content ($text) {
 
 function feedwordpress_restore_syndicated_content ($text) {
 	global $feedwordpress_the_syndicated_content;
-	
+
 	if ( !is_null($feedwordpress_the_syndicated_content) ) :
 		$text = $feedwordpress_the_syndicated_content;
 	endif;
@@ -531,7 +538,7 @@ function feedwordpress_item_feed_data () {
 function syndication_permalink ($permalink = '', $post = null, $leavename = false, $sample = false) {
 	global $id;
 	global $feedwordpress_the_original_permalink;
-	
+
 	// Save the local permalink in case we need to retrieve it later.
 	$feedwordpress_the_original_permalink = $permalink;
 
@@ -581,11 +588,11 @@ function syndication_permalink_escaped ($permalink) {
 		$permalink = esc_html($permalink);
 	endif;
 	return $permalink;
-} /* function syndication_permalink_escaped() */ 
+} /* function syndication_permalink_escaped() */
 
 /**
  * syndication_comments_feed_link: Escape XML special characters in comments
- * feed links 
+ * feed links
  *
  * @param string $link
  * @return string
@@ -602,7 +609,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 (
@@ -611,14 +618,14 @@ function syndication_comments_feed_link ($link) {
 				and (strlen($commentFeeds[0]) > 0)
 			) :
 				$replacement = $commentFeeds[0];
-				
+
 				// This is a foreign link; WordPress can't vouch for its not
 				// having any entities that need to be &-escaped. So we'll do it
 				// here.
 				$replacement = esc_html($replacement);
 			endif;
 		endif;
-		
+
 		if (is_null($replacement)) :
 			// Q: How can we get the proper feed format, since the
 			// format is, stupidly, not passed to the filter?
@@ -642,7 +649,7 @@ function syndication_comments_feed_link ($link) {
 				// comments feed link is never munged by FWP.
 			endif;
 		endif;
-		
+
 		if (!is_null($replacement)) : $link = $replacement; endif;
 	endif;
 	return $link;
@@ -654,11 +661,11 @@ 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');
-	
+
 	add_menu_page(
 		'Syndicated Sites', 'Syndication',
 		$menu_cap,
@@ -708,7 +715,7 @@ 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 () */
@@ -779,7 +786,7 @@ function fwp_publish_post_hook ($post_id) {
 			do_action('xmlrpc_publish_post', $post_id);
 		if ( defined('APP_REQUEST') )
 			do_action('app_publish_post', $post_id);
-		
+
 		if ( defined('WP_IMPORTING') )
 			return;
 
@@ -797,18 +804,29 @@ function fwp_publish_post_hook ($post_id) {
 		global $inspectPostMeta;
 
 		// Put in Manual Editing checkbox
-		add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
+		add_action('add_meta_boxes', 'feedwordpress_post_add_meta_boxes', 10, 2);
 		
 		add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
-		
+
 		if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
 			$inspectPostMeta = new InspectPostMeta;
 		endif;
-	} // function FeedWordPress::postEditControls
-	
+	} // function feedwordpress_add_post_edit_controls ()
+
+	function feedwordpress_post_add_meta_boxes ($post_type, $post) {
+		add_meta_box(
+			'feedwordpress-post-controls',
+			__('Syndication'),
+			'feedwordpress_post_edit_controls',
+			$post_type,
+			'side',
+			'high'
+		);
+	}
+
 	function feedwordpress_post_edit_controls () {
 		global $post;
-		
+
 		$frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
 		$frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
 
@@ -817,47 +835,71 @@ function fwp_publish_post_hook ($post_id) {
 		<p>This is a syndicated post, which originally appeared at
 		<cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
 		<a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
+
+		<?php do_action('feedwordpress_post_edit_controls_pre', $post); ?>
 		
 		<p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
 		<label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
 		If set, FeedWordPress will not overwrite the changes you make manually
 		to this post, if the syndicated content is updated on the
 		feed.</label></p>
+
+		<?php do_action('feedwordpress_post_edit_controls', $post); ?>
+
 		<?php
 		else :
 		?>
 		<p>This post was created locally at this website.</p>
 		<?php
 		endif;
-	} // function feedwordpress_post_edit_controls () */
+	} /* function feedwordpress_post_edit_controls () */
 
 	function feedwordpress_save_post_edit_controls ( $post_id ) {
 		global $post;
-		
 		if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
 			return $post_id;
 		endif;
-	
+
 		// Verify if this is an auto save routine. If it is our form has
 		// not been submitted, so we don't want to do anything.
 		if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
 			return $post_id;
 		endif;
+
+		// The data in $_POST is for applying only to the post actually
+		// in the edit window, i.e. $post
+		if ($post_id != $post->ID) :
+			return $post_id;		
+		endif;
 		
 		// Check permissions
-		if ( !current_user_can( 'edit_'.$_POST['post_type'], $post_id) ) :
+		$cap[0] = 'edit_post';
+		$cap[1] = 'edit_' . $_POST['post_type'];
+		if (
+			!current_user_can( $cap[0], $post_id )
+			and !current_user_can( $cap[1], $post_id )
+		) :
 			return $post_id;
 		endif;
 		
 		// OK, we're golden. Now let's save some data.
 		if (isset($_POST['freeze_updates'])) :
+
 			update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
 			$ret = $_POST['freeze_updates'];
+			
+			// If you make manual edits through the WordPress editing
+			// UI then they should be run through normal WP formatting
+			// filters.
+			update_post_meta($post_id, '_feedwordpress_formatting_filters', 'yes');
+
 		else :
 			delete_post_meta($post_id, '_syndication_freeze_updates');
 			$ret = NULL;
 		endif;
-		
+
+		do_action('feedwordpress_save_edit_controls', $post_id);
+
 		return $ret;
 	} // function feedwordpress_save_edit_controls
 
@@ -902,16 +944,19 @@ class FeedWordPress {
 	var $feeds = NULL;
 	var $feedurls = NULL;
 	var $httpauth = NULL;
-	
-	# function FeedWordPress (): Contructor; retrieve a list of feeds 
-	function FeedWordPress () {
+
+	/**
+	 * FeedWordPress::__construct (): Construct FeedWordPress singleton object
+	 * and retrieves a list of feeds for later reference.
+	 */
+	public function __construct () {
 		$this->feeds = array ();
 		$this->feedurls  = array();
 		$links = FeedWordPress::syndicated_links();
 		if ($links): foreach ($links as $link):
 			$id = intval($link->link_id);
 			$url = $link->link_rss;
-			
+
 			// Store for later reference.
 			$this->feeds[$id] = $id;
 			if (strlen($url) > 0) :
@@ -919,20 +964,37 @@ class FeedWordPress {
 			endif;
 		endforeach; endif;
 
+		add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
+
 		$this->httpauth = new FeedWordPressHTTPAuthenticator;
-	} // FeedWordPress::FeedWordPress ()
+	} /* FeedWordPress::__construct () */
 
-	function subscribed ($id) {
+	/**
+	 * FeedWordPress::subscribed (): Check whether a feed is currently in the
+	 * subscription list for FeedWordPress.
+	 *
+	 * @param mixed $id Numeric ID of a WordPress link object or URL of a feed
+	 * @return bool TRUE if currently subscribed; FALSE otherwise.
+	 */
+	public function subscribed ($id) {
 		return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
 	} /* FeedWordPress::subscribed () */
-	
-	function subscription ($which) {
+
+	/**
+	 * FeedWordPress::subscription (): Get the SyndicatedLink object for a
+	 * given URL or numeric ID, if we have either an active subscription to
+	 * it; or a de-activated subscription.
+	 *
+	 * @param mixed $which Numeric ID for a WordPress link object or string URL for a feed
+	 * @return mixed SyndicatedLink object if subscription is found; NULL if not
+	 */
+	public 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;
@@ -950,10 +1012,10 @@ class FeedWordPress {
 			$this->feeds[$which] = $link;
 			$sub = $link;
 		endif;
-		
+
 		return $sub;
 	} /* FeedWordPress::subscription () */
-	
+
 	# function update (): polls for updates on one or more Contributor feeds
 	#
 	# Arguments:
@@ -999,17 +1061,17 @@ class FeedWordPress {
 	#      (between 30 minutes and 2 hours).
 	#
 	# *    New posts from the polled feed are added to the WordPress store.
-	# 
+	#
 	# *    Updates to existing posts since the last poll are mirrored in the
 	#      WordPress store.
 	#
-	function update ($uri = null, $crash_ts = null) {
+	public function update ($uri = null, $crash_ts = null) {
 		global $wpdb;
 
 		if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
 			return NULL;
 		endif;
-		
+
 		if (!is_null($uri) and $uri != '*') :
 			$uri = trim($uri);
 		else : // Update all
@@ -1028,7 +1090,7 @@ class FeedWordPress {
 		if (is_null($crash_ts)) :
 			$crash_ts = $this->crash_ts();
 		endif;
-		
+
 		// Randomize order for load balancing purposes
 		$feed_set = array_keys($this->feeds);
 		shuffle($feed_set);
@@ -1045,8 +1107,8 @@ 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_id) :
@@ -1057,13 +1119,13 @@ class FeedWordPress {
 			if (
 				// Over time limit?
 				(!is_null($crash_ts) and (time() > $crash_ts))
-				
+
 				// Over feed count?
-				or ($remaining == 0) 
+				or ($remaining == 0)
 			) :
 				break;
 			endif;
-			
+
 			$pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
 
 			if (!is_null($uri)) : // A site-specific ping always updates
@@ -1072,8 +1134,10 @@ class FeedWordPress {
 				$timely = $feed->stale();
 			endif;
 
-			if ($pinged_that and is_null($delta)) :		// If at least one feed was hit for updating...
-				$delta = array('new' => 0, 'updated' => 0);	// ... don't return error condition 
+			// If at least one feed was hit for updating...
+			if ($pinged_that and is_null($delta)) :
+				// ... don't return error condition
+				$delta = array('new' => 0, 'updated' => 0, 'stored' => 0);
 			endif;
 
 			if ($pinged_that and $timely) :
@@ -1085,18 +1149,18 @@ class FeedWordPress {
 				do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
 
 				if (is_array($added)) : // Success
-					if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
-					if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
+					foreach ($added as $key => $count) :
+						$delta[$key] += $added[$key];
+					endforeach;
 				endif;
 			endif;
 		endforeach;
 
 		do_action('feedwordpress_update_complete', $delta);
-
 		return $delta;
-	}
+	} /* FeedWordPress::update () */
 
-	function crash_ts ($default = NULL) {
+	public function crash_ts ($default = NULL) {
 		$crash_dt = (int) get_option('feedwordpress_update_time_limit', 0);
 		if ($crash_dt > 0) :
 			$crash_ts = time() + $crash_dt;
@@ -1104,32 +1168,23 @@ class FeedWordPress {
 			$crash_ts = $default;
 		endif;
 		return $crash_ts;
-	}
-	
-	function secret_key () {
+	} /* FeedWordPress::crash_ts () */
+
+	public function secret_key () {
 		$secret = get_option('feedwordpress_secret_key', false);
 		if (!$secret) : // Generate random key.
 			$secret = substr(md5(uniqid(microtime())), 0, 6);
 			update_option('feedwordpress_secret_key', $secret);
 		endif;
 		return $secret;
-	}
-	
-	function has_secret () {
-		return ($this->by_request('feedwordpress_key', $this->secret_key()));
-	}
+	} /* FeedWordPress::secret_key () */
+
+	public function has_secret () {
+		return (MyPHP::request('feedwordpress_key')==$this->secret_key());
+	} /* FeedWordPress::has_secret () */
 
-	// Utility function so I don't have to repeat myself w/ 1,000,003 isset()'s
-	function by_request ($param, $eq = NULL) {
-		$match = false;
-		if (isset($_REQUEST[$param])) :
-			$match = (is_null($eq) ? $_REQUEST[$param] : ($eq==$_REQUEST[$param]));
-		endif;
-		return $match;
-	}
-	
 	var $update_hooked = NULL;
-	function automatic_update_hook ($params = array()) {
+	public function automatic_update_hook ($params = array()) {
 		$params = wp_parse_args($params, array( // Defaults
 			'setting only' => false,
 		));
@@ -1140,51 +1195,53 @@ class FeedWordPress {
 		if (
 			!$params['setting only']
 			and $this->has_secret()
-			and $this->by_request('automatic_update')
+			and MyPHP::request('automatic_update')
 		) :
-			$hook = $_REQUEST['automatic_update'];
+			$hook = MyPHP::request('automatic_update');
 			$method = 'URL parameter';
 		endif;
-		
+
 		$exact = $hook; // Before munging
-		
+
 		if (!!$hook) :
 			if ($hook != 'init') : // Constrain values.
 				$hook = 'shutdown';
 			endif;
 		endif;
-		
+
 		if ($hook) :
 			$this->update_hooked = "Initiating an AUTOMATIC CHECK FOR UPDATES ON PAGE LOAD ".$hook." due to ".$method." = ".trim($this->val($exact));
 		endif;
-		
-		return $hook; 
-	}
-	function last_update_all () {
+
+		return $hook;
+	} /* FeedWordPress::automatic_update_hook () */
+
+	public function last_update_all () {
 		$last = get_option('feedwordpress_last_update_all');
-		if ($this->has_secret() and $this->by_request('automatic_update')) :
+		if ($this->has_secret() and MyPHP::request('automatic_update')) :
 			$last = 1; // A long, long time ago.
-		elseif ($this->has_secret() and $this->by_request('last_update_all')) :
-			$last = $_REQUEST['last_update_all'];
+		elseif ($this->has_secret() and MyPHP::request('last_update_all')) :
+			$last = MyPHP::request('last_update_all');
 		endif;
 		return $last;
-	}
-	function force_update_all () {
-		return ($this->has_secret() and $this->by_request('force_update_feeds'));
-	}
-	
-	function stale () {
+	} /* FeedWordPress::last_update_all () */
+
+	public function force_update_all () {
+		return ($this->has_secret() and MyPHP::request('force_update_feeds'));
+	} /* FeedWordPress::force_update_all () */
+
+	public function stale () {
 		if (!is_null($this->automatic_update_hook())) :
 			// Do our best to avoid possible simultaneous
 			// updates by getting up-to-the-minute settings.
-			
+
 			$last = $this->last_update_all();
-		
+
 			// If we haven't updated all yet, give it a time window
 			if (false === $last) :
 				$ret = false;
 				update_option('feedwordpress_last_update_all', time());
-			
+
 			// Otherwise, check against freshness interval
 			elseif (is_numeric($last)) : // Expect a timestamp
 				$freshness = get_option('feedwordpress_freshness');
@@ -1192,7 +1249,7 @@ class FeedWordPress {
 					$freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
 				endif;
 				$ret = ( (time() - $last) > $freshness );
-			
+
 			// This should never happen.
 			else :
 				FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__, __FILE__);
@@ -1202,7 +1259,7 @@ class FeedWordPress {
 			$ret = false;
 		endif;
 		return $ret;
-	} // FeedWordPress::stale()
+	} /* 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
@@ -1211,34 +1268,200 @@ class FeedWordPress {
 		if (!intval(get_option('link_manager_enabled', false))) :
 			update_option('link_manager_enabled', true);
 		endif;
+		
+		if (defined('FEEDWORDPRESS_PREPARE_TO_ZAP') and FEEDWORDPRESS_PREPARE_TO_ZAP) :
+			$post_id = FEEDWORDPRESS_PREPARE_TO_ZAP;
+			$sendback = wp_get_referer();
+			if (
+				! $sendback
+				or strpos( $sendback, 'post.php' ) !== false
+				or strpos( $sendback, 'post-new.php' ) !== false
+			) :
+				if ( 'attachment' == $post_type ) :
+					$sendback = admin_url( 'upload.php' );
+				else :
+					$sendback = admin_url( 'edit.php' );
+					$sendback .= ( ! empty( $post_type ) ) ? '?post_type=' . $post_type : '';
+				endif;
+			else :
+				$sendback = remove_query_arg( array('trashed', 'untrashed', 'deleted', 'zapped', 'unzapped', 'ids'), $sendback );
+			endif;
+
+			// Make sure we have a post corresponding to this ID.
+			$post = $post_type = $post_type_object = null;
+			if ( $post_id ) :
+				$post = get_post( $post_id );
+			endif;
+
+			if ( $post ) :
+				$post_type = $post->post_type;
+			endif;
+			$p = get_post($post_id);
+
+			if ( ! $post ) :
+				wp_die( __( 'The item you are trying to zap no longer exists.' ) );
+			endif;
+			
+			if ( ! current_user_can( 'delete_post', $post_id ) ) :
+				wp_die( __( 'You are not allowed to zap this item.' ) );
+			endif;
+			
+			if ( $user_id = wp_check_post_lock( $post_id ) ) :
+				$user = get_userdata( $user_id );
+				wp_die( sprintf( __( 'You cannot retire this item. %s is currently editing.' ), $user->display_name ) );
+			endif;
+		
+			if (MyPHP::request('fwp_post_delete')=='zap') :
+				FeedWordPress::diagnostic('syndicated_posts', 'Zapping existing post # '.$p->ID.' "'.$p->post_title.'" due to user request.');
+				
+				$old_status = $post->post_status;
+				
+				set_post_field('post_status', 'fwpzapped', $post_id);
+				wp_transition_post_status('fwpzapped', $old_status, $post);
+
+				# Set up the post to have its content blanked on
+				# next update if you do not undo the zapping.
+				add_post_meta($post_id, '_feedwordpress_zapped_blank_me', 1, /*unique=*/ true);
+				add_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', $old_status, /*unique=*/ true);
+				
+				wp_redirect( add_query_arg( array('zapped' => 1, 'ids' => $post_id), $sendback ) );
+
+			else :
+				$old_status = get_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', /*single=*/ true);
+				
+				set_post_field('post_status', $old_status, $post_id);
+				wp_transition_post_status($old_status, 'fwpzapped', $post);
+				
+				# O.K., make sure this post does not get blanked
+				delete_post_meta($post_id, '_feedwordpress_zapped_blank_me');
+				delete_post_meta($post_id, '_feedwordpress_zapped_blank_old_status');
+
+				wp_redirect( add_query_arg( array('unzapped' => 1, 'ids' => $post_id), $sendback ) );
+
+			endif;
+				
+			// Intercept, don't pass on.
+			exit;
+		endif;
 	} /* FeedWordPress::admin_init() */
 
-	function admin_api () {
+	public 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);
+			
+		elseif (MyPHP::request('fwp_post_delete')=='zap' OR MyPHP::request('fwp_post_delete') == 'unzap') :
+			// 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, get ready to intercept the call a little
+			// further down the line.
+			
+			define('FEEDWORDPRESS_PREPARE_TO_ZAP', $post_id);
+			
+		endif;
+
+	} /* FeedWordPress::admin_api () */
+
+	public function all_admin_notices () {
+		if (MyPHP::request('zapped')) :
+			$n = intval(MyPHP::request('zapped'));
+?>
+<div id="message" class="updated"><p><?php print $n; ?> syndicated item<?php print ($n!=1?'s':''); ?> zapped. <strong>These items will not be re-syndicated.</strong> If this was a mistake, you must <strong>immediately</strong> Un-Zap them in the Zapped items section to avoid losing the data.</p></div>
+<?php
+		endif;
+		
+		if (MyPHP::request('unzapped')) :
+			$n = intval(MyPHP::request('unzapped'));
+?>
+<div id="message" class="updated"><p><?php print $n; ?> syndicated item<?php print ($n!=1?'s':'') ?> un-zapped and restored to normal.</p></div>
+<?php
 		endif;
+	} /* FeedWordPress::all_admin_notices () */
+	
+	public function process_retirements ($delta) {
+		update_option('feedwordpress_process_zaps', 1);
 
+		return $delta;
 	}
+	
+	public function feedwordpress_cleanup () {
+		if (get_option('feedwordpress_process_zaps', null)) :
+			$q = new WP_Query(array(
+			'fields' => '_synfrom',
+			'post_status' => 'fwpzapped',
+			'ignore_sticky_posts' => true,
+			'meta_key' => '_feedwordpress_zapped_blank_me',
+			'meta_value' => 1,
+			));
+			
+			if ($q->have_posts()) :
+				foreach ($q->posts as $p) :
 
-	function init () {
+					$post_id = $p->ID;
+					$revisions = wp_get_post_revisions($post_id, array("check_enabled" => false));
+				
+					# Now nuke the content of the post & its revisions
+					set_post_field('post_content', '', $post_id);
+					set_post_field('post_excerpt', '', $post_id);
+				
+					foreach ($revisions as $rev) :
+						set_post_field('post_content', '', $rev->ID);
+						set_post_field('post_excerpt', '', $rev->ID);
+					endforeach;
+					
+					# Un-tag it for blanking.
+					delete_post_meta($p->ID, '_feedwordpress_zapped_blank_me');
+	
+					# Don't remove old_status indicator. A later
+					# update from the feed may cause us to once
+					# again have some content so we can un-zap.
+				
+				endforeach;
+			endif;
+			
+			$q = new WP_Query(array(
+			'fields' => '_synfrom',
+			'post_status' => 'fwpzapped',
+			'ignore_sticky_posts' => true,
+			'meta_key' => '_feedwordpress_zapped_blank_me',
+			'meta_value' => 2,
+			));
+	
+			if ($q->have_posts()) :
+				foreach ($q->posts as $p) :
+					update_post_meta($p->ID, '_feedwordpress_zapped_blank_me', 1);
+				endforeach;
+			endif;
+	
+			update_option('feedwordpress_process_zaps', 0);
+		endif;
+	} /* FeedWordPress::feedwordpress_cleanup () */
+	
+	public function init () {
 		global $fwp_path;
-		
+
 		// If this is a FeedWordPress admin page, queue up scripts for AJAX
 		// functions that FWP uses. If it is a display page or a non-FWP admin
 		// page, don't.
@@ -1246,19 +1469,21 @@ class FeedWordPress {
 		if (FeedWordPressSettingsUI::is_admin()) :
 			// For JavaScript that needs to be generated dynamically
 			add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
-		
+
 			// For CSS that needs to be generated dynamically.
 			add_action('admin_print_styles', array('FeedWordPressSettingsUI', 'admin_styles'));
-		
+
 			wp_enqueue_style('dashboard');
 			wp_enqueue_style('feedwordpress-elements');
-		
+
 			/*if (function_exists('wp_admin_css')) :
 				wp_admin_css('css/dashboard');
 			endif;*/
 		endif;
 
-		// This is a special post status for hiding posts that have expired
+		// These are a special post statuses for hiding posts that have
+		// expired from the feed or been marked for permanent zapping by
+		// the FWP admin.
 		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>'),
@@ -1268,6 +1493,15 @@ class FeedWordPress {
 		'show_in_admin_all_list' => false,
 		'show_in_admin_status_list' => true,
 		));
+		register_post_status('fwpzapped',  array(
+		'label' => _x('Zapped', 'post'),
+		'label_count' => _n_noop('Zapped <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'),
@@ -1277,15 +1511,15 @@ class FeedWordPress {
 		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 () {
+
+	public function fwp_feeds () {
 		$feeds = array();
 		$feed_ids = $this->feeds;
-		
+
 		foreach ($feed_ids as $id) :
 			$sub = $this->subscription($id);
 			$feeds[] = array(
@@ -1295,18 +1529,18 @@ class FeedWordPress {
 			);
 		endforeach;
 
-		header("Content-Type: application/json");	
+		header("Content-Type: application/json");
 		echo json_encode($feeds);
 		exit;
-	}
+	} /* FeedWordPress::fwp_feeds () */
 
-	function fwp_feedcontents () {
+	public 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;
@@ -1315,7 +1549,7 @@ class FeedWordPress {
 
 			foreach ($posts as $post) :
 				$p = new SyndicatedPost($post, $feed);
-				
+
 				$result[] = array(
 					"post_title" => $p->entry->get_title(),
 					"post_link" => $p->permalink(),
@@ -1324,42 +1558,42 @@ class FeedWordPress {
 				);
 			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 () {
+
+	public 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(),
@@ -1374,24 +1608,27 @@ class FeedWordPress {
 			"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 () {
+
+	public function redirect_retired () {
 		global $wp_query;
 		if (is_singular()) :
-			if ('fwpretired'==$wp_query->post->post_status) :
+			if (
+				'fwpretired'==$wp_query->post->post_status
+				or 'fwpzapped'==$wp_query->post->post_status
+			) :
 				do_action('feedwordpress_redirect_retired', $wp_query->post);
-				
+
 				if (!($template = get_404_template())) :
 					$template = get_index_template();
 				endif;
@@ -1402,48 +1639,73 @@ class FeedWordPress {
 				exit;
 			endif;
 		endif;
-	}
-	
-	function row_actions ($actions, $post) {
+	} /* FeedWordPress::redirect_retired () */
+
+	public 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"));
+			$eraseLink = MyPHP::url($link, array("fwp_post_delete" => "nuke"));
+
+			$caption = apply_filters('feedwordpress_ui_erase_link_caption', __('Erase the record of this post (will be re-syndicated if it still appears on the feed).'));
+			$linktext = apply_filters('feedwordpress_ui_erase_link_text', __('Erase/Resyndicate'));
 			
-			$caption = 'Erase the record of this post (will be re-syndicated if it still appears on the feed).';
-			$linktext = 'Erase/Resyndicate';
+			$retireClass = NULL;
+			if ($post->post_status == 'fwpzapped') :
+				if (count(get_post_meta($post->ID, '_feedwordpress_zapped_blank_me')) > 0) :
+					$retireCap = 'Un-Zap this syndicated post (so it will appear on the site again)';
+					$retireText = 'Un-Zap &amp; Restore';
+					$retireLink = MyPHP::url($link, array("fwp_post_delete" => "unzap"));
+				else :
+					// No Un-Zap link for posts that have
+					// been blanked. You'll just have to
+					// Erase and hope you can resyndicate...
+					$retireLink = NULL;
+				endif;
+			else :
+				$retireCap = apply_filters('feedwordpress_ui_zap_link_caption', __('Zap this syndicated post (so it will not be re-syndicated if it still appears on the feed).'));
+				$retireText = apply_filters('feedwordpress_ui_zap_link_text', __('Zap/Don&#8217;t Resyndicate'));
+				$retireLink = MyPHP::url($link, array("fwp_post_delete" => "zap"));
+				$retireClass = 'submitdelete';
+			endif;
 			
 			$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>";
-					
+					#$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' ) . "</a>";
+
 					// Placeholder.
+					if (!is_null($retireLink)) :
+						$links['zap trash'] = '';
+					endif;
 					$links['delete'] = '';
 				endif;
 			endforeach;
-			
-			$links['delete'] = '<a class="submitdelete" title="'.esc_attr(__($caption)).'" href="' . $link . '">' . __($linktext) . '</a>';
+
+			if (!is_null($retireLink)) :
+				$links['zap trash'] = '<a class="'.esc_attr($retireClass).'" title="'.esc_attr(__($retireCap)).'" href="' . $retireLink . '">' . __($retireText) . '</a>';
+			endif;
+			$links['delete'] = '<a class="submitdelete" title="'.esc_attr(__($caption)).'" href="' . $eraseLink . '">' . __($linktext) . '</a>';
 
 			$actions = $links;
 		endif;
 		return $actions;
-	}
-	
-	function dashboard_setup () {
+	} /* FeedWordPress::row_actions () */
+
+	public function dashboard_setup () {
 		$see_it = FeedWordPress::menu_cap();
-		
+
 		if (current_user_can($see_it)) :
 			// Get the stylesheet
 			wp_enqueue_style('feedwordpress-elements');
-	
+
 			$widget_id = 'feedwordpress_dashboard';
 			$widget_name = __('Syndicated Sources');
 			$column = 'side';
 			$priority = 'core';
-	
+
 			// I would love to use wp_add_dashboard_widget() here and save
 			// myself some trouble. But WP 3 does not yet have any way to
 			// push a dashboard widget onto the side, or to give it a default
@@ -1457,57 +1719,57 @@ class FeedWordPress {
 				/*priority=*/ $priority
 			);
 			/*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
 			// know of any better way to reorder the boxen.
 			//
 			// Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
-			
+
 			// Globalize the metaboxes array, this holds all the widgets for wp-admin
 			global $wp_meta_boxes;
-	
-			// Get the regular dashboard widgets array 
+
+			// Get the regular dashboard widgets array
 			// (which has our new widget already but at the end)
-	
+
 			$normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
-		
+
 			// Backup and delete our new dashbaord widget from the end of the array
 			if (isset($normal_dashboard[$widget_id])) :
 				$backup = array();
 				$backup[$widget_id] = $normal_dashboard[$widget_id];
 				unset($normal_dashboard[$widget_id]);
-	
+
 				// Merge the two arrays together so our widget is at the
 				// beginning
 				$sorted_dashboard = array_merge($backup, $normal_dashboard);
-	
-				// Save the sorted array back into the original metaboxes 
+
+				// Save the sorted array back into the original metaboxes
 				$wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
 			endif;
 		endif;
 	} /* FeedWordPress::dashboard_setup () */
-	
-	function dashboard () {
+
+	public function dashboard () {
 		$syndicationPage = new FeedWordPressSyndicationPage(dirname(__FILE__).'/syndication.php');
 		$syndicationPage->dashboard_box($syndicationPage);
 	} /* FeedWordPress::dashboard () */
 
-	function user_can_richedit ($rich_edit) {
+	public 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;
+			# $rich_edit = false;
 		endif;
-		
+
 		return $rich_edit;
 
 	} /* FeedWordPress::user_can_richedit () */
-	
-	function update_magic_url () {
+
+	public function update_magic_url () {
 		global $wpdb;
 
 		// Explicit update request in the HTTP request (e.g. from a cron job)
@@ -1515,7 +1777,7 @@ class FeedWordPress {
 			$this->update_hooked = "Initiating a CRON JOB CHECK-IN ON UPDATE SCHEDULE due to URL parameter = ".trim($this->val($_REQUEST['update_feedwordpress']));
 
 			$this->update($this->update_requested_url());
-			
+
 			if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
 				$mysqlTime = 0.0;
 				$byTime = array();
@@ -1523,58 +1785,58 @@ class FeedWordPress {
 					$time = $query[1] * 1000000.0;
 					$mysqlTime += $query[1];
 					if (!isset($byTime[$time])) : $byTime[$time] = array(); endif;
-					$byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];   
+					$byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
 				endforeach;
 				krsort($byTime);
-	       
+
 				foreach ($byTime as $time => $querySet) :
 					foreach ($querySet as $query) :
 						print "[".(sprintf('%4.4f', $time/1000.0)) . "ms] $query\n";
 					endforeach;
 				endforeach;
-				echo $this->log_prefix()."$wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
+				echo self::log_prefix()."$wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
 			endif;
-	
+
 			debug_out_feedwordpress_footer();
-	
+
 			// Magic URL should return nothing but a 200 OK header packet
 			// when successful.
 			exit;
 		endif;
 	} /* FeedWordPress::magic_update_url () */
 
-	function clear_cache_magic_url () {
+	public function clear_cache_magic_url () {
 		if ($this->clear_cache_requested()) :
 			$this->clear_cache();
 		endif;
 	} /* FeedWordPress::clear_cache_magic_url() */
-	
-	function clear_cache_requested () {
+
+	public function clear_cache_requested () {
 		return MyPHP::request('clear_cache');
 	} /* FeedWordPress::clear_cache_requested() */
 
-	function update_requested () {
-		return FeedWordPress::by_request('update_feedwordpress');
-	} // FeedWordPress::update_requested()
+	public function update_requested () {
+		return MyPHP::request('update_feedwordpress');
+	} /* FeedWordPress::update_requested() */
 
-	function update_requested_url () {
+	public function update_requested_url () {
 		$ret = null;
-		
+
 		if (($_REQUEST['update_feedwordpress']=='*')
 		or (preg_match('|^http://.*|i', $_REQUEST['update_feedwordpress']))) :
 			$ret = $_REQUEST['update_feedwordpress'];
 		endif;
 
 		return $ret;
-	} // FeedWordPress::update_requested_url()
+	} /* FeedWordPress::update_requested_url() */
 
-	function auto_update () {
+	public function auto_update () {
 		if ($this->stale()) :
 			$this->update();
 		endif;
 	} /* FeedWordPress::auto_update () */
 
-	function find_link ($uri, $field = 'link_rss') {
+	public static function find_link ($uri, $field = 'link_rss') {
 		global $wpdb;
 
 		$unslashed = untrailingslashit($uri);
@@ -1583,11 +1845,40 @@ class FeedWordPress {
 		SELECT link_id FROM $wpdb->links WHERE $field IN ('%s', '%s')
 		LIMIT 1", $unslashed, $slashed
 		));
-		
+
 		return $link_id;
 	} /* FeedWordPress::find_link () */
 
-	function syndicate_link ($name, $uri, $rss) {
+	/**
+	 * FeedWordPress:syndicate_link(): add or update a feed subscription
+	 *
+	 * Add a new subscription to, or update an existing subscription in,
+	 * FWP's list of subscribed feeds.
+	 *
+	 * Postcondition: If $rss is the URL of a feed not yet on FWP's list of
+	 * subscribed feeds, then a new subscription will be added, using $name
+	 * as its initial title and $uri as its initial homepage URL (normally
+	 * these will be updated with new values taken from the feed, the first
+	 * time the new feed is checked for syndicated content, unless feed
+	 * settings prevent this). If $rss is the URL of a feed that is already
+	 * on FWP's list of subscribed feeds, then that feed will be updated to
+	 * use the title provided in $name and the homepage URL in $uri
+	 *
+	 * @param string $name The human-readable title of the feed (for example, "Rad Geek People's Daily")
+	 * @param string $uri The URI for the human-readable homepage associated with the feed (for example, <http://radgeek.com/>)
+	 * @param string $rss The URI for the feed itself (for example, <http://radgeek.com/feed/>)
+	 *
+	 * @return mixed Returns an int with the numeric ID of the new
+	 *   subscription's wp_links record if successful or a WP_Error object
+	 *   if wp_insert_link() failed.
+	 *
+	 * @uses FeedWordPress::link_category_id()
+	 * @uses FeedWordPress::find_link()
+	 * @uses is_wp_error()
+	 * @uses wp_insert_link()
+	 *
+	 */
+	public static function syndicate_link ($name, $uri, $rss) {
 		// Get the category ID#
 		$cat_id = FeedWordPress::link_category_id();
 		if (!is_wp_error($cat_id)) :
@@ -1598,21 +1889,21 @@ class FeedWordPress {
 
 		// WordPress gets cranky if there's no homepage URI
 		if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
-		
+
 		// Check if this feed URL is already being syndicated.
-		$link_id = wp_insert_link(array(
+		$link_id = wp_insert_link(/*linkdata=*/ array(
 		"link_id" => FeedWordPress::find_link($rss), // insert if nothing was found; else update
 		"link_rss" => $rss,
 		"link_name" => $name,
 		"link_url" => $uri,
 		"link_category" => $link_category,
 		"link_visible" => 'Y', // reactivate if inactivated
-		));
+		), /*wp_error=*/ true);
 
 		return $link_id;
 	} /* function FeedWordPress::syndicate_link() */
 
-	/*static*/ function syndicated_status ($what, $default) {
+	static function syndicated_status ($what, $default) {
 		$ret = get_option("feedwordpress_syndicated_{$what}_status");
 		if (!$ret) :
 			$ret = $default;
@@ -1620,17 +1911,17 @@ class FeedWordPress {
 		return $ret;
 	} /* FeedWordPress::syndicated_status() */
 
-	function on_unfamiliar ($what = 'author') {
+	public static function on_unfamiliar ($what = 'author') {
 		switch ($what) :
 		case 'category' : $suffix = ':category'; break;
 		case 'post_tag' : $suffix = ':post_tag'; break;
 		default: $suffix = '';
 		endswitch;
-		
+
 		return get_option('feedwordpress_unfamiliar_'.$what, 'create'.$suffix);
 	} // function FeedWordPress::on_unfamiliar()
 
-	function null_email_set () {
+	public static function null_email_set () {
 		$base = get_option('feedwordpress_null_email_set');
 
 		if ($base===false) :
@@ -1644,16 +1935,16 @@ class FeedWordPress {
 
 	} /* FeedWordPress::null_email_set () */
 
-	function is_null_email ($email) {
+	public static function is_null_email ($email) {
 		$ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
 		$ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
 		return $ret;
 	} /* FeedWordPress::is_null_email () */
 
-	function use_aggregator_source_data () {
+	public static function use_aggregator_source_data () {
 		$ret = get_option('feedwordpress_use_aggregator_source_data');
 		return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
-	}
+	} /* FeedWordPress::use_aggregator_source_data () */
 
 	/**
 	 * FeedWordPress::munge_permalinks: check whether or not FeedWordPress
@@ -1662,11 +1953,11 @@ class FeedWordPress {
 	 *
 	 * @return bool TRUE if FeedWordPress SHOULD rewrite permalinks; FALSE otherwise
 	 */
-	/*static*/ function munge_permalinks () {
+	static function munge_permalinks () {
 		return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
 	} /* FeedWordPress::munge_permalinks() */
 
-	function syndicated_links ($args = array()) {
+	public static function syndicated_links ($args = array()) {
 		$contributors = FeedWordPress::link_category_id();
 		if (!is_wp_error($contributors)) :
 			$links = get_bookmarks(array_merge(
@@ -1678,13 +1969,13 @@ class FeedWordPress {
 		endif;
 
 		return $links;
-	} // function FeedWordPress::syndicated_links()
+	} /* FeedWordPress::syndicated_links() */
 
-	function link_category_id () {
+	public static function link_category_id () {
 		global $wpdb, $wp_db_version;
 
 		$cat_id = get_option('feedwordpress_cat_id');
-		
+
 		// If we don't yet have the category ID stored, search by name
 		if (!$cat_id) :
 			$cat_id = FeedWordPressCompatibility::link_category_id(DEFAULT_SYNDICATION_CATEGORY);
@@ -1698,7 +1989,7 @@ class FeedWordPress {
 		else :
 			$cat_id = FeedWordPressCompatibility::link_category_id((int) $cat_id, 'cat_id');
 		endif;
-		
+
 		// If we could not find an appropriate link category,
 		// make a new one for ourselves.
 		if (!$cat_id) :
@@ -1710,45 +2001,35 @@ class FeedWordPress {
 		endif;
 
 		return $cat_id;
-	} // function FeedWordPress::link_category_id()
+	} /* FeedWordPress::link_category_id() */
 
 	# Upgrades and maintenance...
-	function needs_upgrade () {
+	static function needs_upgrade () {
+
 		global $wpdb;
-		$fwp_db_version = get_option('feedwordpress_version');
+		$fwp_db_version = get_option('feedwordpress_version', NULL);
 		$ret = false; // innocent until proven guilty
-		if (!$fwp_db_version or $fwp_db_version < FEEDWORDPRESS_VERSION) :
-			// This is an older version or a fresh install. Does it
-			// require a database upgrade or database initialization?
-			if ($fwp_db_version <= 0.96) :
-				// Yes. Check to see whether this is a fresh install or an upgrade.
-				$syn = $wpdb->get_col("
-				SELECT post_id
-				FROM $wpdb->postmeta
-				WHERE meta_key = 'syndication_feed'
-				");
-				if (count($syn) > 0) : // contains at least one syndicated post
-					$ret = true;
-				else : // fresh install; brand it as ours
-					update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
-				endif;
-			elseif ($fwp_db_version < 2009.0707) :
-				// We need to clear out any busted AJAX crap
-				$wpdb->query("
-				DELETE FROM $wpdb->usermeta
-				WHERE LOCATE('feedwordpress', meta_key)
-				AND LOCATE('box', meta_key);
-				");
+		if (is_null($fwp_db_version) or ($fwp_db_version < FEEDWORDPRESS_VERSION)) :
 
+			// This is an older version or a fresh install. Does it require a database
+			// upgrade or database initialization?
+
+			if (is_null($fwp_db_version)) :
+
+				// Fresh install; brand it as ours. Or possibly a version of FWP
+				// from before 0.96. But I'm no longer supporting upgrade paths
+				// for versions from the previous decade. Sorry.
 				update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
+
 			elseif ($fwp_db_version < 2010.0814) :
+
 				// Change in terminology.
 				if (get_option('feedwordpress_unfamiliar_category', 'create')=='default') :
 					update_option('feedwordpress_unfamiliar_category', 'null');
 				endif;
 				foreach (FeedWordPress::syndicated_links() as $link) :
 					$sub = new SyndicatedLink($link);
-					
+
 					$remap_uf = array(
 						'default' => 'null',
 						'filter' => 'null',
@@ -1765,34 +2046,38 @@ class FeedWordPress {
 							endif;
 						endforeach;
 					endif;
-					
+
 					if (isset($sub->settings['add global categories'])) :
 						$sub->settings['add/category'] = $sub->settings['add global categories'];
 						unset($sub->settings['add global categories']);
 					endif;
-					
+
 					$sub->save_settings(/*reload=*/ true);
 				endforeach;
 				update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
+
 			else :
-				// No. Just brand it with the new version.
+
+				// No upgrade needed. Just brand it with the new version.
 				update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
+
 			endif;
+
 		endif;
 		return $ret;
-	}
+	} /* FeedWordPress::needs_upgrade () */
 
-	function upgrade_database ($from = NULL) {
+	static function upgrade_database ($from = NULL) {
 		global $wpdb;
 
 		if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
 
 		switch ($from) :
 		case 0.96:
-			 // Dropping legacy upgrade code. If anyone is still
-			 // using 0.96 and just now decided to upgrade, well, I'm
-			 // sorry about that. You'll just have to cope with a few
-			 // duplicate posts.
+			// Dropping legacy upgrade code. If anyone is still
+			// using 0.96 and just now decided to upgrade, well, I'm
+			// sorry about that. You'll just have to cope with a few
+			// duplicate posts.
 
 			// Mark the upgrade as successful.
 			update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
@@ -1800,9 +2085,9 @@ class FeedWordPress {
 		echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
 	} /* FeedWordPress::upgrade_database() */
 
-	function has_guid_index () {
+	public static function has_guid_index () {
 		global $wpdb;
-		
+
 		$found = false; // Guilty until proven innocent.
 
 		$results = $wpdb->get_results("
@@ -1818,41 +2103,42 @@ class FeedWordPress {
 		endif;
 		return $found;
 	} /* FeedWordPress::has_guid_index () */
-	
-	function create_guid_index () {
+
+	public static function create_guid_index () {
 		global $wpdb;
-		
+
 		$wpdb->query("
 		CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
 		");
 	} /* FeedWordPress::create_guid_index () */
-	
-	function remove_guid_index () {
+
+	public static function remove_guid_index () {
 		global $wpdb;
-		
+
 		$wpdb->query("
 		DROP INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}
 		");
 	}
 
-	/*static*/ function fetch_timeout () {
+	static function fetch_timeout () {
 		return apply_filters(
 			'feedwordpress_fetch_timeout',
 			intval(get_option('feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT))
 		);
 	}
-	
-	/*static*/ function fetch ($url, $params = array()) {
+
+	static function fetch ($url, $params = array()) {
 		if (is_wp_error($url)) :
 			// Let's bounce.
 			return $url;
 		endif;
-		
+
 		$force_feed = true; // Default
 
-		// Allow user to change default feed-fetch timeout with a global setting. Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html>			'timeout' => 
+		// Allow user to change default feed-fetch timeout with a global setting.
+		// Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html>
 		$timeout = FeedWordPress::fetch_timeout();
- 		
+
 		if (!is_array($params)) :
 			$force_feed = $params;
 		else : // Parameter array
@@ -1860,11 +2146,11 @@ class FeedWordPress {
 			'force_feed' => $force_feed,
 			'timeout' => $timeout
 			), $params);
-			
+
 			extract($args);
 		endif;
 		$timeout = intval($timeout);
-		
+
 		$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');
@@ -1876,7 +2162,7 @@ class FeedWordPress {
 		$feed->set_feed_url($url);
 		$feed->set_cache_class($cache_class);
 		$feed->set_timeout($timeout);
-		
+
 		$feed->set_content_type_sniffer_class($sniffer_class);
 		$feed->set_file_class($file_class);
 		$feed->set_parser_class($parser_class);
@@ -1885,7 +2171,7 @@ class FeedWordPress {
 		$feed->set_cache_duration(FeedWordPress::cache_duration($params));
 		$feed->init();
 		$feed->handle_content_type();
-		
+
 		if ($feed->error()) :
 			$ret = new WP_Error('simplepie-error', $feed->error());
 		else :
@@ -1893,10 +2179,10 @@ class FeedWordPress {
 		endif;
 		return $ret;
 	} /* FeedWordPress::fetch () */
-	
-	function clear_cache () {
+
+	public function clear_cache () {
 		global $wpdb;
-		
+
 		// Just in case, clear out any old MagpieRSS cache records.
 		$magpies = $wpdb->query("
 		DELETE FROM {$wpdb->options}
@@ -1919,11 +2205,11 @@ class FeedWordPress {
 		return ($magpies + $simplepies);
 	} /* FeedWordPress::clear_cache () */
 
-	function cache_duration ($params = array()) {
+	static public function cache_duration ($params = array()) {
 		$params = wp_parse_args($params, array(
 		"cache" => true,
 		));
-		
+
 		$duration = NULL;
 		if (!$params['cache']) :
 			$duration = 0;
@@ -1932,7 +2218,8 @@ class FeedWordPress {
 		endif;
 		return $duration;
 	}
-	function cache_lifetime ($duration) {
+
+	static public function cache_lifetime ($duration) {
 		// Check for explicit setting of a lifetime duration
 		if (defined('FEEDWORDPRESS_CACHE_LIFETIME')) :
 			$duration = FEEDWORDPRESS_CACHE_LIFETIME;
@@ -1941,32 +2228,32 @@ class FeedWordPress {
 		elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
 			$duration = FEEDWORDPRESS_CACHE_AGE;
 		endif;
-		
+
 		// Fall back to WordPress default
 		return $duration;
 	} /* FeedWordPress::cache_lifetime () */
 
 	# Utility functions for handling text settings
-	function negative ($f, $setting) {
+	static function negative ($f, $setting) {
 		$nego = array ('n', 'no', 'f', 'false');
 		return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
-	}
+	} /* FeedWordPress::negative () */
 
-	function affirmative ($f, $setting) {
+	static function affirmative ($f, $setting) {
 		$affirmo = array ('y', 'yes', 't', 'true', 1);
 		return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
-	}
+	} /* FeedWordPress::affirmative () */
 
 	# Internal debugging functions
-	function critical_bug ($varname, $var, $line, $file = NULL) {
+	static function critical_bug ($varname, $var, $line, $file = NULL) {
 		global $wp_version;
-		
+
 		if (!is_null($file)) :
 			$location = "line # ${line} of ".basename($file);
 		else :
 			$location = "line # ${line}";
 		endif;
-		
+
 		print '<p><strong>Critical error:</strong> There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
 		print "\n<plaintext>";
 		print "Triggered at ${location}\n";
@@ -1976,31 +2263,24 @@ class FeedWordPress {
 		print "Error data:    ";
 		print  $varname.": "; var_dump($var); echo "\n";
 		die;
-	}
-	
-	function noncritical_bug ($varname, $var, $line, $file = NULL) {
+	} /* FeedWordPress::critical_bug () */
+
+	static function noncritical_bug ($varname, $var, $line, $file = NULL) {
 		if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
 			FeedWordPress::critical_bug($varname, $var, $line, $file);
 		endif;
-	}
-	
-	function val ($v, $no_newlines = false) {
-		ob_start();
-		var_dump($v);
-		$out = ob_get_contents(); ob_end_clean();
-		
-		if ($no_newlines) :
-			$out = preg_replace('/\s+/', " ", $out);
-		endif;
-		return $out;
+	} /* FeedWordPress::noncritical_bug () */
+
+	static function val ($v, $no_newlines = false) {
+		return MyPHP::val($v, $no_newlines);
 	} /* FeedWordPress::val () */
 
-	function diagnostic_on ($level) {
+	static function diagnostic_on ($level) {
 		$show = get_option('feedwordpress_diagnostics_show', array());
 		return (in_array($level, $show));
 	} /* FeedWordPress::diagnostic_on () */
 
-	function diagnostic ($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) {
+	static function diagnostic ($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) {
 		global $feedwordpress_admin_footer;
 
 		$output = get_option('feedwordpress_diagnostics_output', array());
@@ -2013,7 +2293,7 @@ class FeedWordPress {
 				switch ($method) :
 				case 'echo' :
 					if (!FeedWordPress::update_requested()) :
-						echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>";
+						echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>\n";
 					endif;
 					break;
 				case 'echo_in_cronjob' :
@@ -2028,7 +2308,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);
@@ -2038,56 +2318,58 @@ class FeedWordPress {
 						$hook = md5($level."\n".$persist);
 						$line = array("Since" => $since, "Message" => $out, "Most Recent" => $mostRecent);
 					endif;
-					
+
 					if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
 					if (!isset($dlog['mesg'][$sect])) : $dlog['mesg'][$sect] = array(); endif;
-					
+
 					$dlog['mesg'][$sect][$hook] = $line;
 				endswitch;
 			endforeach;
 		endif;
-		
-		update_option('feedwordpress_diagnostics_log', $dlog);		
+
+		update_option('feedwordpress_diagnostics_log', $dlog);
 	} /* FeedWordPress::diagnostic () */
-	
-	function email_diagnostics_override () {
+
+	public function email_diagnostics_override () {
 		return ($this->has_secret() and isset($_REQUEST['feedwordpress_email_diagnostics']) and !!$_REQUEST['feedwordpress_email_diagnostics']);
-	}
-	function has_emailed_diagnostics ($dlog) {
+	} /* FeedWordPress::email_diagnostics_override () */
+
+	public function has_emailed_diagnostics ($dlog) {
 		$ret = false;
 		if ($this->email_diagnostics_override()
 		or (isset($dlog['schedule']) and isset($dlog['schedule']['last']))) :
 			$ret = true;
 		endif;
 		return $ret;
-	}
-	function ready_to_email_diagnostics ($dlog) {
+	} /* FeedWordPress::has_emailed_diagnostics () */
+
+	public function ready_to_email_diagnostics ($dlog) {
 		$ret = false;
 		if ($this->email_diagnostics_override()
 		or (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq']))) :
 			$ret = true;
 		endif;
 		return $ret;
-	}
-	
-	function email_diagnostic_log ($params = array()) {
+	} /* FeedWordPress::ready_to_email_diagnostics () */
+
+	public 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)) :
 			if ($this->ready_to_email_diagnostics($dlog)) :
 				// No news is good news; only send if
 				// there are some messages to send.
 				$body = NULL;
 				if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
-				
+
 				foreach ($dlog['mesg'] as $sect => $mesgs) :
 					if (count($mesgs) > 0) :
 						if (is_null($body)) : $body = ''; endif;
-						
+
 						$paradigm = reset($mesgs);
 						$body .= "<h2>".ucfirst($sect)." issues</h2>\n"
 							."<table>\n"
@@ -2097,7 +2379,7 @@ class FeedWordPress {
 						endforeach;
 						$body .= "</tr></thead>\n"
 							."<tbody>\n";
-						
+
 						foreach ($mesgs as $line) :
 							$body .= "<tr>\n";
 							foreach ($line as $col => $cell) :
@@ -2109,11 +2391,11 @@ class FeedWordPress {
 							endforeach;
 							$body .= "</tr>\n";
 						endforeach;
-						
+
 						$body .= "</tbody>\n</table>\n\n";
 					endif;
 				endforeach;
-				
+
 				$body = apply_filters('feedwordpress_diagnostic_email_body', $body, $dlog);
 				if (!is_null($body)) :
 					$home = feedwordpress_display_url(get_bloginfo('url'));
@@ -2148,12 +2430,12 @@ EOMAIL;
 					// e-mail address
 					if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
 						$recipients = array($ref[1]);
-						
+
 					// userid
 					elseif (preg_match('/^user:(.*)$/', $ded, $ref)) :
 						$userdata = get_userdata((int) $ref[1]);
 						$recipients = array($userdata->user_email);
-					
+
 					// admins
 					else :
 						$recipients = FeedWordPressDiagnostic::admin_emails();
@@ -2176,17 +2458,17 @@ EOMAIL;
 					endif;
 					$head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
 
-					foreach ($recipients as $email) :						
+					foreach ($recipients as $email) :
 						add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
 						wp_mail($email, $subj, $body, $head);
 						remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
 					endforeach;
 				endif;
-				
+
 				// Clear the logs
 				$dlog['mesg']['persistent'] = array();
 				$dlog['mesg']['occurrent'] = array();
-				
+
 				// Set schedule for next update
 				$dlog['schedule']['last'] = time();
 			endif;
@@ -2196,22 +2478,22 @@ EOMAIL;
 				'last' => time(),
 			);
 		endif;
-		
+
 		update_option('feedwordpress_diagnostics_log', $dlog);
 	} /* FeedWordPress::email_diagnostic_log () */
-	
-	function allow_html_mail () {
+
+	static function allow_html_mail () {
 		return 'text/html';
 	} /* FeedWordPress::allow_html_mail () */
 
-	function admin_footer () {
+	static function admin_footer () {
 		global $feedwordpress_admin_footer;
 		foreach ($feedwordpress_admin_footer as $line) :
 			echo '<div><pre>'.$line.'</pre></div>';
 		endforeach;
 	} /* FeedWordPress::admin_footer () */
-	
-	function log_prefix ($date = false) {
+
+	static function log_prefix ($date = false) {
 		$home = get_bloginfo('url');
 		$prefix = '['.feedwordpress_display_url($home).'] [feedwordpress] ';
 		if ($date) :
@@ -2219,8 +2501,8 @@ EOMAIL;
 		endif;
 		return $prefix;
 	} /* FeedWordPress::log_prefix () */
-	
-	function menu_cap ($sub = false) {
+
+	static function menu_cap ($sub = false) {
 		if ($sub) :
 			$cap = apply_filters('feedwordpress_menu_settings_capacity', 'manage_options');
 		else :
@@ -2228,26 +2510,29 @@ EOMAIL;
 		endif;
 		return $cap;
 	} /* FeedWordPress::menu_cap () */
-	
-	function path ($filename = '') {
+
+	static function path ($filename = '') {
 		global $fwp_path;
-		
+
 		$path = $fwp_path;
 		if (strlen($filename) > 0) :
 			$path .= '/'.$filename;
 		endif;
 		return $path;
-	}
-	
+	} /* FeedWordPress::path () */
+
 	// These are superceded by MyPHP::param/post/get/request, but kept
 	// here for backward compatibility.
-	function param ($key, $type = 'REQUEST', $default = NULL) {
+
+	static function param ($key, $type = 'REQUEST', $default = NULL) {
 		return MyPHP::param($key, $default, $type);
-	}
-	function post ($key, $default = NULL) {
+	} /* FeedWordPress::param () */
+
+	static function post ($key, $default = NULL) {
 		return MyPHP::post($key, $default);
-	}
-} // class FeedWordPress
+	} /* FeedWordPress::post () */
+
+} /* class FeedWordPress */
 
 $feedwordpress_admin_footer = array();
 
diff --git a/wp-content/plugins/feedwordpress/feedwordpress_file.class.php b/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
index 542e3962b6a64050279ade7af2a4d289a79d6e1e..e3eadccba5b1feba9e41c6f0f8752216376afd03 100644
--- a/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpress_file.class.php
@@ -5,10 +5,6 @@ $fwp_credentials = NULL;
 
 class FeedWordPress_File extends WP_SimplePie_File {
 	function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
-		self::__construct($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
-	}
-	
-	function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
 		global $feedwordpress;
 		global $wp_version;
 
@@ -16,7 +12,7 @@ class FeedWordPress_File extends WP_SimplePie_File {
 		if ($feedwordpress->subscribed($url)) :
 			$source = $feedwordpress->subscription($url);
 		endif;
-		
+
 		$this->url = $url;
 		$this->timeout = $timeout;
 		$this->redirects = $redirects;
@@ -24,13 +20,13 @@ class FeedWordPress_File extends WP_SimplePie_File {
 		$this->useragent = $useragent;
 
 		$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
-		
+
 		global $wpdb;
 		global $fwp_credentials;
-		
+
 		if ( preg_match('/^http(s)?:\/\//i', $url) ) :
 			$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
-	
+
 			if ( !empty($this->headers) )
 				$args['headers'] = $this->headers;
 
@@ -62,12 +58,12 @@ class FeedWordPress_File extends WP_SimplePie_File {
 				$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)));
+			FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] &#8668; ".esc_html(MyPHP::val($args)));
 			$res = wp_remote_request($url, $args);
-			FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] &#8669; ".esc_html(FeedWordPress::val($res)));
+			FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] &#8669; ".esc_html(MyPHP::val($res)));
 
 			if ( is_wp_error($res) ) {
 				$this->error = 'WP HTTP Error: ' . $res->get_error_message();
@@ -77,13 +73,13 @@ class FeedWordPress_File extends WP_SimplePie_File {
 				$this->body = wp_remote_retrieve_body( $res );
 				$this->status_code = wp_remote_retrieve_response_code( $res );
 			}
-			
+
 			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
diff --git a/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php b/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
index 91cb5ed9030abc99343c134beca4d324c5d9934f..d484a31ed8aeaf77d579fd2c9acf7138508e1396 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresshtml.class.php
@@ -1,6 +1,6 @@
-<?php 
+<?php
 class FeedWordPressHTML {
-	function attributeRegex ($tag, $attr) {
+	static function attributeRegex ($tag, $attr) {
 		return ":(
 		(<($tag)\s+[^>]*)
 		($attr)=
@@ -16,7 +16,7 @@ class FeedWordPressHTML {
 		:ix";
 	} /* function FeedWordPressHTML::attributeRegex () */
 
-	function attributeMatch ($matches) {
+	static function attributeMatch ($matches) {
 		for ($i = 0; $i <= 12; $i++) :
 			if (!isset($matches[$i])) :
 				$matches[$i] = '';
@@ -38,7 +38,7 @@ class FeedWordPressHTML {
 		);
 	} /* function FeedWordPressHTML::attributeMatch () */
 
-	function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
+	static function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
 		return ":(
 		(<($tag)\s+[^>]*)
 		($attr)=
@@ -57,7 +57,7 @@ class FeedWordPressHTML {
 		:ix";
 	} /* FeedWordPressHTML::tagWithAttributeRegex () */
 
-	function tagWithAttributeMatch ($matches, $closing = true) {
+	static function tagWithAttributeMatch ($matches, $closing = true) {
 		for ($i = 0; $i <= 21; $i++) :
 			if (!isset($matches[$i])) :
 				$matches[$i] = '';
diff --git a/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php b/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php
index 94cc928088d8279e9e428b9b77937cdcd664fac7..743f65122a7f1bab75f65eb626b6894d0c74d875 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresslocalpost.class.php
@@ -1,8 +1,9 @@
 <?php
 
 class FeedWordPressLocalPost {
-	private $post;
-
+	public $post;
+	public $link;
+	
 	public function __construct ($p = NULL) {
 		global $post;
 		
@@ -92,7 +93,8 @@ class FeedWordPressLocalPost {
 
 	public function feed () {
 		global $feedwordpress;
-		return $feedwordpress->subscription($this->feed_id());
+		$this->link = $feedwordpress->subscription($this->feed_id());
+		return $this->link;
 	}
 	
 	public function feed_id () {
@@ -146,5 +148,41 @@ class FeedWordPressLocalPost {
 		
 	} /* FeedWordPressLocalPost::is_exposed_to_formatting_filters () */
 	
+
+	public function content () {
+		return apply_filters('the_content', $this->post->post_content, $this->post->ID);
+	}
+	
+	public function title () {
+		return apply_filters('the_title', $this->post->post_title, $this->post->ID);
+	}
+
+	public function guid () {
+		return apply_filters('get_the_guid', $this->post->guid);
+	}
+	
+	public function get_categories () {
+		$terms = wp_get_object_terms(
+			$this->post->ID,
+			get_taxonomies(array(
+				'public' => true,
+			), 'names'),
+			'all'
+		);
+		$rootUrl = get_bloginfo('url');
+
+		$cats = array();
+		foreach ($terms as $term) :
+			$taxUrl = MyPHP::url($rootUrl, array("taxonomy" => $term->taxonomy));
+			//array("taxonomy" => $term->taxonomy ));
+			$cats[] = new SimplePie_Category(
+				/*term=*/ $term->slug,
+				/*scheme=*/ $taxUrl,
+				/*label=*/ $term->name
+			);
+		endforeach;
+		return $cats;
+	}
+	
 } /* class FeedWordPressLocalPost */
 
diff --git a/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php b/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
index 040e74aa8113f1920b63a1190062e51fdb5d1c2c..9a58854c4bc26180120c6a0dcad41ca24e842ea4 100644
--- a/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpressrpc.class.php
@@ -24,11 +24,8 @@ class FeedWordPressRPC {
 		if (is_null($delta)):
 			return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
 		else:
-			$mesg = array();
-			if (isset($delta['new'])) { $mesg[] = ' '.$delta['new'].' new posts were syndicated'; }
-			if (isset($delta['updated'])) { $mesg[] = ' '.$delta['updated'].' existing posts were updated'; }
-	
-			return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
+		$mesg = array();
+			return array('flerror' => false, 'message' => "Thanks for the ping.".fwp_update_set_results_message($delta));
 		endif;
 	}
 	
diff --git a/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php b/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
index 301e644bfeffd51c047c9fac1b696c4db614505d..f4afb13453bf68c4bf049c2f7cbb7272389c4f07 100644
--- a/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
+++ b/wp-content/plugins/feedwordpress/feedwordpresssyndicationpage.class.php
@@ -649,17 +649,48 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
 
 	function bleg_box ($page, $box = NULL) {
 		?>
+<script type="text/javascript">
+/* <![CDATA[ */
+    (function() {
+        var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
+        s.type = 'text/javascript';
+        s.async = true;
+        s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
+        t.parentNode.insertBefore(s, t);
+    })();
+/* ]]> */</script>
+
 <div class="donation-form">
-<h4>Keep FeedWordPress improving</h4>
+<h4>Consider a Donation to FeedWordPress</h4>
 <form action="https://www.paypal.com/cgi-bin/webscr" accept-charset="UTF-8" method="post"><div>
 <p><a href="http://feedwordpress.radgeek.com/">FeedWordPress</a> makes syndication
 simple and empowers you to stream content from all over the web into your
-WordPress hub. That's got to be worth a few lattes. If you're finding FWP useful,
+WordPress hub. If you&#8217;re finding FWP useful,
 <a href="http://feedwordpress.radgeek.com/donate/">a modest gift</a>
 is the best way to support steady progress on development, enhancements,
 support, and documentation.</p>
-<div class="donate">
-<input type="hidden" name="business" value="commerce@radgeek.com"  />
+
+<div class="donate" style="vertical-align: middle">
+
+<div id="flattr-paypal">
+
+<div style="display: inline-block; vertical-align: middle; ">
+<a class="FlattrButton" style="display:none;"   href="http://feedwordpress.radgeek.com/"></a>
+<noscript>
+<a href="http://flattr.com/thing/1380856/FeedWordPress" target="_blank"><img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a>
+</noscript>
+<div>via Flattr</div>
+
+</div> <!-- style="display: inline-block" -->
+
+<div class="hovered-component" style="display: inline-block; vertical-align: bottom">
+<a href="bitcoin:<?php print esc_attr(FEEDWORDPRESS_BLEG_BTC); ?>"><img src="<?php print esc_url(WP_PLUGIN_URL.'/'.FeedWordPress::path('btc-qr-64px.png')); ?>" alt="Donate" /></a>
+<div><a href="bitcoin:<?php print esc_attr(FEEDWORDPRESS_BLEG_BTC); ?>">via bitcoin<span class="hover-on pop-over" style="background-color: #ddffdd; padding: 5px; color: black; border-radius: 5px;">bitcoin:<?php print esc_html(FEEDWORDPRESS_BLEG_BTC); ?></span></a></div>
+</div>
+
+<div style="display: inline-block; vertical-align: bottom">
+<input type="image" name="submit" src="<?php print esc_url(WP_PLUGIN_URL.'/'.FeedWordPress::path('paypal-donation-64px.png')); ?>" alt="Donate through PayPal" />
+<input type="hidden" name="business" value="distro.to.feedback@radgeek.com"  />
 <input type="hidden" name="cmd" value="_xclick"  />
 <input type="hidden" name="item_name" value="FeedWordPress donation"  />
 <input type="hidden" name="no_shipping" value="1"  />
@@ -667,9 +698,14 @@ support, and documentation.</p>
 <input type="hidden" name="currency_code" value="USD" />
 <input type="hidden" name="notify_url" value="http://feedwordpress.radgeek.com/ipn/donation"  />
 <input type="hidden" name="custom" value="1"  />
-<input type="image" name="submit" src="https://www.paypal.com/en_GB/i/btn/btn_donate_SM.gif" alt="Donate through PayPal" />
-</div>
-</div></form>
+<div>via PayPal</div>
+</div> <!-- style="display: inline-block" -->
+
+</div> <!-- id="flattr-paypal" -->
+</div> <!-- class="donate" -->
+
+</div> <!-- class="donation-form" -->
+</form>
 
 <p>You can make a gift online (or
 <a href="http://feedwordpress.radgeek.com/donation">set up an automatic
@@ -1023,10 +1059,7 @@ function fwp_dashboard_update_if_requested ($object) {
 		echo "</ul>\n";
 
 		if (!is_null($tdelta)) :
-			$mesg = array();
-			if (isset($delta['new'])) : $mesg[] = ' '.$tdelta['new'].' new posts were syndicated'; endif;
-			if (isset($delta['updated'])) : $mesg[] = ' '.$tdelta['updated'].' existing posts were updated'; endif;
-			echo "<p>Update complete.".implode(' and', $mesg)."</p>";
+			echo "<p><strong>Update complete.</strong>".fwp_update_set_results_message($delta)."</p>";
 			echo "\n"; flush();
 		endif;
 		echo "</div> <!-- class=\"updated\" -->\n";
diff --git a/wp-content/plugins/feedwordpress/inspectpostmeta.class.php b/wp-content/plugins/feedwordpress/inspectpostmeta.class.php
index a53f4e2565d93d8f47d29badff9a3f5eb97f9aca..e43081c78e2dfe4012decb98d6ef7a97d0101b4b 100644
--- a/wp-content/plugins/feedwordpress/inspectpostmeta.class.php
+++ b/wp-content/plugins/feedwordpress/inspectpostmeta.class.php
@@ -9,19 +9,15 @@
 
 class InspectPostMeta {
 	function InspectPostMeta ($in_hook = true) {
-		if (!$in_hook) :
-			add_action('admin_menu', array($this, 'add_meta_box'));
-		else :
-			$this->add_meta_box();
-		endif;
+		add_action('add_meta_boxes', array($this, 'add_meta_boxes'), 10, 2);
 	}
 	
-	function add_meta_box () {
+	function add_meta_boxes ($post_type, $post) {
 		add_meta_box(
 			/*id=*/ 'inspect_post_guid_box',
 			/*title=*/ 'Post GUID and Meta Data',
 			/*callback=*/ array($this, 'meta_box'),
-			/*page=*/ 'post',
+			/*page=*/ $post_type,
 			/*context=*/ 'normal',
 			/*priority=*/ 'default'
 		);
diff --git a/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php b/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
index 40c8d7f251a183161af73b139323962bdbcc86d3..0cebcf08e2450f9831785414253ecbafa6edb056 100644
--- a/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
+++ b/wp-content/plugins/feedwordpress/magpiefromsimplepie.class.php
@@ -89,7 +89,7 @@ class MagpieFromSimplePie {
 		endif;
 
 		$this->normalize();
-
+		
 		// In case anyone goes poking around our private members (uh...)
 		$this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
 		$this->feed_version = $this->feed_version();
diff --git a/wp-content/plugins/feedwordpress/magpiemocklink.class.php b/wp-content/plugins/feedwordpress/magpiemocklink.class.php
index 49bcd453b0555d3c19fcb099a4e7faa3f0bb5f99..b666812559ad66b11ea53202e637f9145cfe25a1 100644
--- a/wp-content/plugins/feedwordpress/magpiemocklink.class.php
+++ b/wp-content/plugins/feedwordpress/magpiemocklink.class.php
@@ -6,7 +6,7 @@ class MagpieMockLink extends SyndicatedLink {
 
 	function MagpieMockLink ($rss, $url) {
 		$this->link = $rss;
-		
+
 		if (is_array($rss) and isset($rss['simplepie']) and isset($rss['magpie'])) :
 			$this->simplepie = $rss['simplepie'];
 			$this->magpie = $rss['magpie'];
@@ -18,7 +18,7 @@ class MagpieMockLink extends SyndicatedLink {
 		$this->id = -1;
 		$this->settings = array(
 			'unfamiliar category' => 'default',
-			
+
 		);
 	} /* function MagpieMockLink::MagpieMockLink () */
 
@@ -30,14 +30,14 @@ class MagpieMockLink extends SyndicatedLink {
 		$this->link = $this->magpie;
 	} /* function MagpieMockLink::poll () */
 
-	function uri () {
+	function uri ($params = array()) {
 		return $this->url;
 	} /* function MagpieMockLink::uri() */
 
-	function homepage () {
+	function homepage ($fromFeed = true) {
 		return (!is_wp_error($this->simplepie) ? $this->simplepie->get_link() : null);
 	} /* function MagpieMockLink::homepage () */
-	
+
 	function save_settings ($reload = false) {
 		// NOOP.
 	}
diff --git a/wp-content/plugins/feedwordpress/paypal-donation-64px.png b/wp-content/plugins/feedwordpress/paypal-donation-64px.png
new file mode 100644
index 0000000000000000000000000000000000000000..a792109a48639dfd225c2df8f1e6a8e513d80ecf
Binary files /dev/null and b/wp-content/plugins/feedwordpress/paypal-donation-64px.png differ
diff --git a/wp-content/plugins/feedwordpress/performance-page.php b/wp-content/plugins/feedwordpress/performance-page.php
index 5f7be90f108efcf207f91c8513277ac9e7d2c243..24e608bcd4e67908cca62ec3890a45df487c324d 100644
--- a/wp-content/plugins/feedwordpress/performance-page.php
+++ b/wp-content/plugins/feedwordpress/performance-page.php
@@ -14,15 +14,15 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
 	function display () {
 		global $wpdb, $wp_db_version, $fwp_path;
 		global $fwp_post;
-		
+
 		if (FeedWordPress::needs_upgrade()) :
 			fwp_upgrade_page();
 			return;
 		endif;
-	
+
 		// If this is a POST, validate source and user credentials
 		FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_performance', /*capability=*/ 'manage_options');
-	
+
 		if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
 			$this->accept_POST($fwp_post);
 			do_action('feedwordpress_admin_page_performance_save', $fwp_post, $this);
@@ -41,7 +41,7 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
 		$boxes_by_methods = array(
 			'performance_box' => __('Performance'),
 		);
-	
+
 		foreach ($boxes_by_methods as $method => $title) :
 			add_meta_box(
 				/*id=*/ 'feedwordpress_'.$method,
@@ -79,19 +79,11 @@ 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);
-		
+	static function performance_box ($page, $box = NULL) {
+
 		// Hey ho, let's go...
 		?>
 <table class="editform" width="100%" cellspacing="2" cellpadding="5">
@@ -116,33 +108,6 @@ 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>
diff --git a/wp-content/plugins/feedwordpress/readme.txt b/wp-content/plugins/feedwordpress/readme.txt
index 96abc75bd6e20b2bf1640f85461477fd029fd20b..6dc09b3e000573db62f27cceb7298cccf00fb5d4 100644
--- a/wp-content/plugins/feedwordpress/readme.txt
+++ b/wp-content/plugins/feedwordpress/readme.txt
@@ -3,8 +3,8 @@ Contributors: Charles Johnson
 Donate link: http://feedwordpress.radgeek.com/
 Tags: syndication, aggregation, feed, atom, rss
 Requires at least: 3.0
-Tested up to: 3.5.1
-Stable tag: 2013.0504
+Tested up to: 3.9.1
+Stable tag: 2014.0805
 
 FeedWordPress syndicates content from feeds you choose into your WordPress weblog. 
 
@@ -94,12 +94,46 @@ outs, see the documentation at the [FeedWordPress project homepage][].
 
 == Changelog ==
 
-= 2012.0504 =
+= 2014.0805 =
+
+
+*	FILTERS AND ADD-ONS: A number of new hooks for filters and add-ons to
+	further customize the behavior of FWP have been added.
+
+* 	COMPATIBILITY/BUGFIX: Many users saw odd characters, especially "n,"
+	appearing in posts in versions of WordPress from 3.6 on, due to a change
+	in when the API expects HTML data for posts to be slashed and when it
+	does not. This has been fixed, so that the junk characters should no
+	longer appear, regardless of your version of WordPress.
+
+*	BUGFIX: A bug preventing FWP from saving categories assigned under
+	Syndication > Categories & Tags has been fixed.
+	
+*	BUGFIX: Post-editing related metaboxes should now show up when you edit
+	items of any post type, including custom types, not only normal WordPress
+	posts.
+	
+*	BUGFIX: A bug in the admin UI that caused the "Alternative Feeds" /
+	"Find Feeds" box to throw a permissions error has been fixed.
+	
+*	BUGFIX: A bug preventing proper mapping of categories and other terms in
+	2013.0504 has been fixed.
+	
+*	BUGFIX: A number of small fixes contributed through Github by Flynsarmy
+	should eliminate PHP warnings for many users on several methods that are
+	called as static methods within FeedWordPress.
 
+= 2013.0504 =
+	
 *	BUGFIX: PHP 5.4 compatibility -- includes some more extensive fixes to
 	compatibility issues with PHP 5.4's handling of global variables
 
-*	MODULE REORGANIZATION: Should ensures that all needed submodules will be
+*	DIAGNOSTICS: New diagnostics settings added to help track behavior of
+	terms (categories, post tags, etc.) for syndicated posts.
+
+= 2012.0504 =
+
+*	MODULE REORGANIZATION: Should ensure that all needed submodules will be
 	properly included regardless of whether you are installing from github,
 	from SVN, or from the WordPress plugins page. If you've been getting
 	fatal errors about required modules not being found, this release should
diff --git a/wp-content/plugins/feedwordpress/syndicatedlink.class.php b/wp-content/plugins/feedwordpress/syndicatedlink.class.php
index 0e8904044cd85226bc4f52536ec3cb69d85fa45a..b34de0c4bad863114f518ccbd5f8d07d636ae03e 100644
--- a/wp-content/plugins/feedwordpress/syndicatedlink.class.php
+++ b/wp-content/plugins/feedwordpress/syndicatedlink.class.php
@@ -25,7 +25,7 @@
 #	backslashes (so, for example, a newline becomes "\n").
 #
 #	The value of `cats` is used as a newline-separated list of
-#	default categories for any post coming from a particular feed. 
+#	default categories for any post coming from a particular feed.
 #	(In the example above, any posts from this feed will be placed
 #	in the "computers" and "web" categories--*in addition to* any
 #	categories that may already be applied to the posts.)
@@ -40,7 +40,7 @@ class SyndicatedLink {
 	var $id = null;
 	var $link = null;
 	var $settings = array ();
-	var $simplepie = null;
+	public $simplepie = null;
 	var $magpie = null;
 
 	function SyndicatedLink ($link) {
@@ -50,17 +50,17 @@ class SyndicatedLink {
 			$this->link = $link;
 			$this->id = $link->link_id;
 		else :
-			$this->id = $link;			
+			$this->id = $link;
 			$this->link = get_bookmark($link);
 		endif;
 
 		if (strlen($this->link->link_rss) > 0) :
 			$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 () */
@@ -68,10 +68,10 @@ class SyndicatedLink {
 	function id () {
 		return (is_object($this->link) ? $this->link->link_id : NULL);
 	}
-	
+
 	function stale () {
 		global $feedwordpress;
-		
+
 		$stale = true;
 		if ($this->setting('update/hold')=='ping') :
 			$stale = false; // don't update on any timed updates; pings only
@@ -112,7 +112,7 @@ class SyndicatedLink {
 		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',
@@ -124,11 +124,11 @@ class SyndicatedLink {
 		endif;
 		return $ret;
 	}
-	
+
 	function poll ($crash_ts = NULL) {
 		global $wpdb;
 
-		$url = $this->uri(array('add_params' => true));
+		$url = $this->uri(array('add_params' => true, 'fetch' => true));
 		FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
 
 		$this->fetch();
@@ -160,7 +160,7 @@ class SyndicatedLink {
 			if (!is_null($oldError)) :
 				// 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.
@@ -171,9 +171,9 @@ class SyndicatedLink {
 				$this->update_setting('update/ttl', $ttl, $this);
 				$this->update_setting('update/timed', 'automatically');
 			endif;
-			
+
 			do_action('syndicated_feed_error', $theError, $oldError, $this);
-			
+
 			$this->update_setting('update/error', serialize($theError));
 			$this->save_settings(/*reload=*/ true);
 
@@ -189,21 +189,21 @@ class SyndicatedLink {
 			if (!isset($channel['id'])) :
 				$channel['id'] = $this->link->link_rss;
 			endif;
-	
+
 			$update = array();
 			if (!$this->hardcode('url') and isset($channel['link'])) :
-				$update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
+				$update[] = "link_url = '".esc_sql($channel['link'])."'";
 			endif;
-	
+
 			if (!$this->hardcode('name') and isset($channel['title'])) :
-				$update[] = "link_name = '".$wpdb->escape($channel['title'])."'";
+				$update[] = "link_name = '".esc_sql($channel['title'])."'";
 			endif;
-	
+
 			if (!$this->hardcode('description')) :
 				if (isset($channel['tagline'])) :
-					$update[] = "link_description = '".$wpdb->escape($channel['tagline'])."'";
+					$update[] = "link_description = '".esc_sql($channel['tagline'])."'";
 				elseif (isset($channel['description'])) :
-					$update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
+					$update[] = "link_description = '".esc_sql($channel['description'])."'";
 				endif;
 			endif;
 
@@ -211,7 +211,7 @@ class SyndicatedLink {
 
 			$this->update_setting('update/last', time());
 			list($ttl, $xml) = $this->ttl(/*return element=*/ true);
-			
+
 			if (!is_null($ttl)) :
 				$this->update_setting('update/ttl', $ttl);
 				$this->update_setting('update/xml', $xml);
@@ -235,10 +235,10 @@ class SyndicatedLink {
 
 			$this->update_setting('update/unfinished', 'yes');
 
-			$update[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
+			$update[] = "link_notes = '".esc_sql($this->settings_to_notes())."'";
 
 			$update_set = implode(',', $update);
-			
+
 			// Update the properties of the link from the feed information
 			$result = $wpdb->query("
 				UPDATE $wpdb->links
@@ -251,12 +251,12 @@ class SyndicatedLink {
 			$crashed = false;
 
 			$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()) :
+			if ($this->is_non_incremental()) :
 				$q = new WP_Query(array(
 				'fields' => '_synfrom',
 				'post_status__not' => 'fwpretired',
@@ -268,7 +268,7 @@ class SyndicatedLink {
 					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);
@@ -288,7 +288,7 @@ 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>
@@ -302,25 +302,25 @@ class SyndicatedLink {
 								$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);
@@ -333,28 +333,28 @@ class SyndicatedLink {
 
 			// 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_set = "link_notes = '".esc_sql($this->settings_to_notes())."'";
+
 			// Update the properties of the link from the feed information
 			$result = $wpdb->query("
 			UPDATE $wpdb->links
 			SET $update_set
 			WHERE link_id='$this->id'
 			");
-			
+
 			do_action("update_syndicated_feed_completed", $this->id, $this);
 		endif;
-		
+
 		// All done; let's clean up.
 		$this->magpie = NULL;
-		
+
 		// Avoid circular-reference memory leak in PHP < 5.3.
 		// Cf. <http://simplepie.org/wiki/faq/i_m_getting_memory_leaks>
 		if (method_exists($this->simplepie, '__destruct')) :
 			$this->simplepie->__destruct();
 		endif;
 		$this->simplepie = NULL;
-		
+
 		return $new_count;
 	} /* SyndicatedLink::poll() */
 
@@ -377,9 +377,10 @@ class SyndicatedLink {
 				delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id);
 			endforeach;
 		endif;
+
 		return $delta;
 	}
-	
+
 	/**
 	 * Updates the URL for the feed syndicated by this link.
 	 *
@@ -394,50 +395,50 @@ class SyndicatedLink {
 			$result = $wpdb->query("
 			UPDATE $wpdb->links
 			SET
-				link_rss = '".$wpdb->escape($url)."'
-			WHERE link_id = '".$wpdb->escape($this->id)."'
+				link_rss = '".esc_sql($url)."'
+			WHERE link_id = '".esc_sql($this->id)."'
 			");
-			
+
 			$ret = ($result ? true : false);
 		else :
 			$ret = false;
 		endif;
 		return $ret;
 	} /* SyndicatedLink::set_uri () */
-	
+
 	function deactivate () {
 		global $wpdb;
-		
+
 		$wpdb->query($wpdb->prepare("
 		UPDATE $wpdb->links SET link_visible = 'N' WHERE link_id = %d
 		", (int) $this->id));
 	} /* SyndicatedLink::deactivate () */
-	
+
 	function delete () {
 		global $wpdb;
-		
+
 		$wpdb->query($wpdb->prepare("
 		DELETE FROM $wpdb->postmeta WHERE meta_key='syndication_feed_id'
 		AND meta_value = '%s'
 		", $this->id));
-		
+
 		$wpdb->query($wpdb->prepare("
 		DELETE FROM $wpdb->links WHERE link_id = %d
 		", (int) $this->id));
-		
+
 		$this->id = NULL;
 	} /* SyndicatedLink::delete () */
-	
+
 	function nuke () {
 		global $wpdb;
-		
+
 		// Make a list of the items syndicated from this feed...
 		$post_ids = $wpdb->get_col($wpdb->prepare("
 		SELECT post_id FROM $wpdb->postmeta
 		WHERE meta_key = 'syndication_feed_id'
 		AND meta_value = '%s'
 		", $this->id));
-	
+
 		// ... and kill them all
 		if (count($post_ids) > 0) :
 			foreach ($post_ids as $post_id) :
@@ -449,10 +450,10 @@ class SyndicatedLink {
 				);
 			endforeach;
 		endif;
-		
+
 		$this->delete();
 	} /* SyndicatedLink::nuke () */
-	
+
 	function map_name_to_new_user ($name, $newuser_name) {
 		global $wpdb;
 
@@ -477,7 +478,7 @@ 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);
@@ -497,7 +498,7 @@ class SyndicatedLink {
 		$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 (
@@ -516,7 +517,7 @@ class SyndicatedLink {
 		// 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)) : 
+		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;
 
@@ -533,7 +534,7 @@ class SyndicatedLink {
 		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.
 
@@ -566,19 +567,19 @@ class SyndicatedLink {
 			$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;
 
@@ -601,12 +602,12 @@ class SyndicatedLink {
 				);
 			endif;
 		endforeach;
-		
+
 		if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
 			// Serialize it.
 			$to_notes['terms'] = serialize($to_notes['terms']);
 		endif;
-		
+
 		// Collapse the author mapping rule structure back into a flat string
 		if (isset($to_notes['map authors'])) :
 			$ma = array();
@@ -630,11 +631,11 @@ class SyndicatedLink {
 
 		// Save channel-level meta-data
 		foreach (array('link_name', 'link_description', 'link_url') as $what) :
-			$alter[] = "{$what} = '".$wpdb->escape($this->link->{$what})."'";
+			$alter[] = "{$what} = '".esc_sql($this->link->{$what})."'";
 		endforeach;
 
 		// Save settings to the notes field
-		$alter[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
+		$alter[] = "link_notes = '".esc_sql($this->settings_to_notes())."'";
 
 		// Update the properties of the link from settings changes, etc.
 		$update_set = implode(", ", $alter);
@@ -644,7 +645,7 @@ class SyndicatedLink {
 		SET $update_set
 		WHERE link_id='$this->id'
 		");
-		
+
 		if ($reload) :
 			// force reload of link information from DB
 			if (function_exists('clean_bookmark_cache')) :
@@ -667,7 +668,7 @@ class SyndicatedLink {
 		if (isset($this->settings[$name])) :
 			$ret = $this->settings[$name];
 		endif;
-		
+
 		$no_value = (
 			is_null($ret)
 			or (is_string($ret) and strtolower($ret)==$default)
@@ -676,8 +677,13 @@ class SyndicatedLink {
 		if ($no_value and !is_null($fallback_global)) :
 			// Avoid duplication of this correction
 			$fallback_global = preg_replace('/^feedwordpress_/', '', $fallback_global);
-			
-			$ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
+
+			// Occasionally we'll get an array back. Convert it to a string
+			if ( is_array($fallback_global) && sizeof($fallback_global) )
+				$fallback_global = reset($fallback_global);
+
+			if ( !empty($fallback_global) )
+				$ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
 		endif;
 
 		$no_value = (
@@ -695,7 +701,7 @@ class SyndicatedLink {
 		$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;
@@ -703,48 +709,55 @@ class SyndicatedLink {
 			unset($this->settings[$name]);
 		endif;
 	} /* SyndicatedLink::update_setting () */
-	
-	function is_incremental () {
+
+	function is_non_incremental () {
 		return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental'));
-	} /* SyndicatedLink::is_incremental () */
-	
+	} /* SyndicatedLink::is_non_incremental () */
+
 	function uri ($params = array()) {
 		$params = wp_parse_args($params, array(
 		'add_params' => false,
+		'fetch' => false,
 		));
-		
-		$uri = (is_object($this->link) ? $this->link->link_rss : NULL);
+
+		$link_rss = (is_object($this->link) ? $this->link->link_rss : NULL); 
+
+		$uri = $link_rss;
 		if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
 			$qp = maybe_unserialize($this->setting('query parameters', array()));
-			
+
 			// For high-tech HTTP feed request kung fu
 			$qp = apply_filters('syndicated_feed_parameters', $qp, $uri, $this);
-			
+
 			$q = array();
 			if (is_array($qp) and count($qp) > 0) :
 				foreach ($qp as $pair) :
 					$q[] = urlencode($pair[0]).'='.urlencode($pair[1]);
 				endforeach;
-				
+
 				// Are we appending to a URI that already has params?
 				$sep = ((strpos($uri, "?")===false) ? '?' : '&');
-				
+
 				// Tack it on
 				$uri .= $sep . implode("&", $q);
-			endif;			
+			endif;
 		endif;
-		
+
+		// Do we have any filters that apply here?
+		$uri = apply_filters('syndicated_link_uri', $uri, $link_rss, $qp, $params, $this);
+
+		// Return the filtered link URI.		
 		return $uri;
 	} /* SyndicatedLink::uri () */
 
 	function username () {
 		return $this->setting('http username', 'http_username', NULL);
 	} /* SyndicatedLink::username () */
-	
+
 	function password () {
 		return $this->setting('http password', 'http_password', NULL);
 	} /* SyndicatedLink::password () */
-	
+
 	function authentication_method () {
 		$auth = $this->setting('http auth method', NULL);
 		if (('-' == $auth) or (strlen($auth)==0)) :
@@ -753,7 +766,7 @@ class SyndicatedLink {
 		return $auth;
 	} /* SyndicatedLink::authentication_method () */
 
-	var $postmeta = array();	
+	var $postmeta = array();
 	function postmeta ($params = array()) {
 		$params = wp_parse_args($params, /*defaults=*/ array(
 		"field" => NULL,
@@ -770,7 +783,7 @@ class SyndicatedLink {
 			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)) :
@@ -779,10 +792,10 @@ class SyndicatedLink {
 			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);
@@ -797,12 +810,12 @@ class SyndicatedLink {
 		endif;
 		return $ret;
 	} /* SyndicatedLink::postmeta () */
-	
+
 	function property_cascade ($fromFeed, $link_field, $setting, $method) {
 		$value = NULL;
 		if ($fromFeed) :
 			$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) :
@@ -813,7 +826,7 @@ class SyndicatedLink {
 		endif;
 		return $value;
 	} /* SyndicatedLink::property_cascade () */
-	
+
 	function homepage ($fromFeed = true) {
 		return $this->property_cascade($fromFeed, 'link_url', 'feed/link', 'get_link');
 	} /* SyndicatedLink::homepage () */
@@ -824,17 +837,18 @@ class SyndicatedLink {
 
 	function guid () {
 		$ret = $this->setting('feed/id', NULL, $this->uri());
-		
+
 		// If we can get it live from the feed, do so.
 		if (is_object($this->simplepie)) :
 			$search = array(
+				array('', 'id'),
 				array(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'),
 				array(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'),
 				array(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'),
 				array(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'),
 				array(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'),
 			);
-			
+
 			foreach ($search as $pair) :
 				if ($id_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
 					$ret = $id_tags[0]['data'];
@@ -848,6 +862,60 @@ class SyndicatedLink {
 		return $ret;
 	}
 
+	function links ($params = array()) {
+		$params = wp_parse_args($params, array(
+		"rel" => NULL,
+		));
+		
+		$fLinks = array();
+		$search = array(
+			array('', 'link'),
+			array(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'),
+			array(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'),
+		);
+		
+		foreach ($search as $pair) :
+			if ($link_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
+				$fLinks = array_merge($fLinks, $link_tags);
+			endif;
+			if ($link_tags = $this->simplepie->get_channel_tags($pair[0], $pair[1])) :
+				$fLinks = array_merge($fLinks, $link_tags);
+			endif;
+		endforeach;
+		
+		$ret = array();
+		foreach ($fLinks as $link) :
+			$filter = false;
+			if (!is_null($params['rel'])) :
+				$filter = true;
+
+				if (isset($link['attribs'])) :
+					// Get a list of NSes from the search
+					foreach ($search as $pair) :
+						$ns = $pair[0];
+						
+						if (isset($link['attribs'][$ns])
+						and isset($link['attribs'][$ns]['rel'])
+						) :
+							$rel = strtolower(trim($link['attribs'][$ns]['rel']));
+							$fRel = strtolower(trim($params['rel']));
+					
+							if ($rel == $fRel) :
+								$filter = false;
+							endif;
+						endif;
+					endforeach;
+				endif;
+			endif;
+			
+			if (!$filter) :
+				$ret[] = $link;
+			endif;
+		endforeach;
+
+		return $ret;
+	}
+	
 	function ttl ($return_element = false) {
 		if (is_object($this->magpie)) :
 			$channel = $this->magpie->channel;
@@ -859,7 +927,7 @@ class SyndicatedLink {
 			// "ttl stands for time to live. It's a number of
 			// minutes that indicates how long a channel can be
 			// cached before refreshing from the source."
-			// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>	
+			// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
 			$xml = 'rss:ttl';
 			$ret = $channel['ttl'];
 		elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
@@ -878,8 +946,8 @@ class SyndicatedLink {
 			if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
 			else : $period = 'daily';
 			endif;
-			
-			// "sy:updateFrequency: Used to describe the frequency 
+
+			// "sy:updateFrequency: Used to describe the frequency
 			// of updates in relation to the update period. A
 			// positive integer indicates how many times in that
 			// period the channel is updated. ... If omitted a value
@@ -887,17 +955,17 @@ class SyndicatedLink {
 			if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
 			else : $freq = 1;
 			endif;
-			
+
 			$xml = 'sy:updateFrequency';
 			$ret = (int) ($period_minutes[$period] / $freq);
 		else :
 			$xml = NULL;
 			$ret = NULL;
 		endif;
-		
+
 		if ('yes'==$this->setting('update/minimum', 'update_minimum', 'no')) :
 			$min = (int) $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
-			
+
 			if ($min > $ret) :
 				$ret = NULL;
 			endif;
@@ -942,9 +1010,9 @@ class SyndicatedLink {
 	} /* SyndicatedLink::flatten_array () */
 
 	function hardcode ($what) {
-		
+
 		$ret = $this->setting('hardcode '.$what, 'hardcode_'.$what, NULL);
-		
+
 		if ('yes' == $ret) :
 			$ret = true;
 		else :
@@ -959,13 +1027,119 @@ class SyndicatedLink {
 		$g_set = ($fallback ? 'syndicated_' . $what . '_status' : NULL);
 		$ret = $this->setting($what.' status', $g_set, $default);
 
-		return $wpdb->escape(trim(strtolower($ret)));
+		return esc_sql(trim(strtolower($ret)));
 	} /* SyndicatedLink:syndicated_status () */
-	
+
 	function taxonomies () {
 		$post_type = $this->setting('syndicated post type', 'syndicated_post_type', 'post');
 		return get_object_taxonomies(array('object_type' => $post_type), 'names');
 	} /* SyndicatedLink::taxonomies () */
-	
+
+	/**
+	 * category_ids: look up (and create) category ids from a list of
+	 * categories
+	 *
+	 * @param array $cats
+	 * @param string $unfamiliar_category
+	 * @param array|null $taxonomies
+	 * @return array
+	 */
+	function category_ids ($post, $cats, $unfamiliar_category = 'create', $taxonomies = NULL, $params = array()) {
+		$singleton = (isset($params['singleton']) ? $params['singleton'] : true);
+		$allowFilters = (isset($params['filters']) ? $params['filters'] : false);
+
+		$catTax = 'category';
+
+		if (is_null($taxonomies)) :
+			$taxonomies = array('category');
+		endif;
+
+		// We need to normalize whitespace because (1) trailing
+		// whitespace can cause PHP and MySQL not to see eye to eye on
+		// VARCHAR comparisons for some versions of MySQL (cf.
+		// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
+		// because I doubt most people want to make a semantic
+		// distinction between 'Computers' and 'Computers  '
+		$cats = array_map('trim', $cats);
+
+		$terms = array();
+		foreach ($taxonomies as $tax) :
+			$terms[$tax] = array();
+		endforeach;
+
+		foreach ($cats as $cat_name) :
+			if (strlen(trim($cat_name)) < 1) :
+				continue;
+			endif;
+
+			$oTerm = new SyndicatedPostTerm($cat_name, $taxonomies, $post);
+
+			if ($oTerm->is_familiar()) :
+
+				$tax = $oTerm->taxonomy();
+				if (!isset($terms[$tax])) :
+					$terms[$tax] = array();
+				endif;
+				$terms[$tax][] = $oTerm->id();
+
+			else :
+
+				if ('tag'==$unfamiliar_category) :
+					$unfamiliar_category = 'create:post_tag';
+				endif;
+
+				if (preg_match('/^create(:(.*))?$/i', $unfamiliar_category, $ref)) :
+					$tax = $catTax; // Default
+
+					if (isset($ref[2])
+					and strlen($ref[2]) > 2) :
+						$tax = $ref[2];
+					endif;
+
+					$inserted = $oTerm->insert($tax);
+					if (!is_null($inserted)) :
+						if (!isset($terms[$tax])) :
+							$terms[$tax] = array();
+						endif;
+						$terms[$tax][] = $inserted;
+					else :
+
+					endif; // !is_null($inserted)
+				endif; // preg_match(...)
+
+			endif; /* ($oTerm->is_familiar()) */
+		endforeach;
+
+		$filtersOn = $allowFilters;
+		if ($allowFilters) :
+			$filters = array_filter(
+				$this->setting('match/filter', 'match_filter', array()),
+				'remove_dummy_zero'
+			);
+			$filtersOn = ($filtersOn and is_array($filters) and (count($filters) > 0));
+		endif;
+
+		// Check for filter conditions
+		foreach ($terms as $tax => $term_ids) :
+			if ($filtersOn
+			and (count($term_ids)==0)
+			and in_array($tax, $filters)) :
+				$terms = NULL; // Drop the post
+				break;
+			else :
+				$terms[$tax] = array_unique($term_ids);
+			endif;
+		endforeach;
+
+		if ($singleton and count($terms)==1) : // If we only searched one, just return the term IDs
+			$terms = end($terms);
+		endif;
+
+		FeedWordPress::diagnostic(
+			'syndicated_posts:categories',
+			'Category: MAPPED term names '.json_encode($cats).' to IDs: '.json_encode($terms)
+		);
+		return $terms;
+	} /* SyndicatedLink::category_ids () */
 } // class SyndicatedLink
 
diff --git a/wp-content/plugins/feedwordpress/syndicatedpost.class.php b/wp-content/plugins/feedwordpress/syndicatedpost.class.php
index aa51a61349016b658a394de08d964e2e3977f902..e713b76fbb3fe91fa2c60549a775ca159f2a2659 100644
--- a/wp-content/plugins/feedwordpress/syndicatedpost.class.php
+++ b/wp-content/plugins/feedwordpress/syndicatedpost.class.php
@@ -1,5 +1,6 @@
 <?php
 require_once(dirname(__FILE__).'/feedtime.class.php');
+require_once(dirname(__FILE__).'/syndicatedpostterm.class.php');
 
 /**
  * class SyndicatedPost: FeedWordPress uses to manage the conversion of
@@ -10,7 +11,7 @@ require_once(dirname(__FILE__).'/feedtime.class.php');
  * different feed formats, which may be useful to FeedWordPress users
  * who make use of feed data in PHP add-ons and filters.
  *
- * @version 2011.0831
+ * @version 2013.0525
  */
 class SyndicatedPost {
 	var $item = null;	// MagpieRSS representation
@@ -19,7 +20,7 @@ class SyndicatedPost {
 	var $link = null;
 	var $feed = null;
 	var $feedmeta = null;
-	
+
 	var $xmlns = array ();
 
 	var $post = array ();
@@ -27,7 +28,7 @@ class SyndicatedPost {
 	var $named = array ();
 	var $preset_terms = array ();
 	var $feed_terms = array ();
-	
+
 	var $_freshness = null;
 	var $_wp_id = null;
 	var $_wp_post = null;
@@ -44,6 +45,9 @@ class SyndicatedPost {
 	function SyndicatedPost ($item, &$source) {
 		global $wpdb;
 
+		if ( empty($item) && empty($source) )
+			return;
+
 		if (is_array($item)
 		and isset($item['simplepie'])
 		and isset($item['magpie'])) :
@@ -52,11 +56,11 @@ class SyndicatedPost {
 			$item = $item['magpie'];
 		elseif (is_a($item, 'SimplePie_Item')) :
 			$this->entry = $item;
-			
+
 			// convert to Magpie for compat purposes
 			$mp = new MagpieFromSimplePie($source->simplepie, $this->entry);
 			$this->item = $mp->get_item();
-			
+
 			// done with conversion object
 			$mp = NULL; unset($mp);
 		else :
@@ -76,9 +80,9 @@ class SyndicatedPost {
 			if (!isset($this->xmlns['reverse'][$ns])) :
 				$this->xmlns['reverse'][$ns] = array();
 			endif;
-			$this->xmlns['reverse'][$ns][] = $url; 
+			$this->xmlns['reverse'][$ns][] = $url;
 		endforeach;
-		
+
 		// Fucking SimplePie.
 		$this->xmlns['reverse']['rss'][] = '';
 
@@ -100,7 +104,7 @@ class SyndicatedPost {
 		// Trigger global syndicated_item filter.
 		$changed = apply_filters('syndicated_item', $this->item, $this);
 		$this->item = $changed;
-		
+
 		// Allow for feed-specific syndicated_item filters.
 		$changed = apply_filters(
 			"syndicated_item_".$source->uri(),
@@ -108,12 +112,12 @@ class SyndicatedPost {
 			$this
 		);
 		$this->item = $changed;
-		
+
 		# Filters can halt further processing by returning NULL
 		if (is_null($this->item)) :
 			$this->post = NULL;
 		else :
-			# Note that nothing is run through $wpdb->escape() here.
+			# Note that nothing is run through esc_sql() here.
 			# That's deliberate. The escaping is done at the point
 			# of insertion, not here, to avoid double-escaping and
 			# to avoid screwing with syndicated_post filters
@@ -130,7 +134,7 @@ class SyndicatedPost {
 			// This just gives us an alphanumeric name for the author.
 			// We look up (or create) the numeric ID for the author
 			// in SyndicatedPost::add().
-
+			
 			$this->post['post_content'] = apply_filters(
 				'syndicated_item_content',
 				$this->content(), $this
@@ -164,18 +168,18 @@ class SyndicatedPost {
 			// overwrite if necessary; thus preventing any munging.
 			$postMetaIn = $this->link->postmeta(array("parsed" => true));
 			$postMetaOut = array();
-			
+
 			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) :
 					$this->post['meta'][$key][] = apply_filters("syndicated_post_meta_{$key}", $value, $this);
 				endforeach;
 			endforeach;
-			
+
 			// RSS 2.0 / Atom 1.0 enclosure support
 			$enclosures = $this->entry->get_enclosures();
 			if (is_array($enclosures)) : foreach ($enclosures as $enclosure) :
@@ -187,7 +191,7 @@ class SyndicatedPost {
 
 			// In case you want to point back to the blog this was
 			// syndicated from.
-			
+
 			$sourcemeta['syndication_source'] = apply_filters(
 				'syndicated_item_source_title',
 				$this->link->name(),
@@ -203,7 +207,7 @@ class SyndicatedPost {
 				$this->link->guid(),
 				$this
 			);
-			
+
 			// Make use of atom:source data, if present in an aggregated feed
 			$entry_source = $this->source();
 			if (!is_null($entry_source)) :
@@ -213,7 +217,7 @@ class SyndicatedPost {
 						elseif ($what=='feed') : $key = 'syndication_feed';
 						else : $key = "syndication_source_${what}";
 						endif;
-						
+
 						$sourcemeta["${key}_original"] = apply_filters(
 							'syndicated_item_original_source_'.$what,
 							$value,
@@ -222,7 +226,7 @@ class SyndicatedPost {
 					endif;
 				endforeach;
 			endif;
-			
+
 			foreach ($sourcemeta as $meta_key => $value) :
 				if (!is_null($value)) :
 					$this->post['meta'][$meta_key] = $value;
@@ -230,7 +234,7 @@ class SyndicatedPost {
 			endforeach;
 
 			// Store information on human-readable and machine-readable comment URIs
-			
+
 			// Human-readable comment URI
 			$commentLink = apply_filters('syndicated_item_comments', $this->comment_link(), $this);
 			if (!is_null($commentLink)) : $this->post['meta']['rss:comments'] = $commentLink; endif;
@@ -273,14 +277,14 @@ class SyndicatedPost {
 				$cats = array_merge($cats, $fc);
 			endif;
 			$this->preset_terms['category'] = $cats;
-			
+
 			// Now add categories from the post, if we have 'em
 			$cats = array();
 			$post_cats = $this->entry->get_categories();
 			if (is_array($post_cats)) : foreach ($post_cats as $cat) :
 				$cat_name = $cat->get_term();
 				if (!$cat_name) : $cat_name = $cat->get_label(); endif;
-				
+
 				if ($this->link->setting('cat_split', NULL, NULL)) :
 					$pcre = "\007".$this->feedmeta['cat_split']."\007";
 					$cats = array_merge(
@@ -298,24 +302,24 @@ class SyndicatedPost {
 			endforeach; endif;
 
 			$this->feed_terms['category'] = apply_filters('syndicated_item_categories', $cats, $this);
-			
+
 			// Tags: start with default tags, if any
 			$tags = array();
 			if ('no' != $this->link->setting('add/post_tag', NULL, 'yes')) :
 				$ft = get_option("feedwordpress_syndication_tags", NULL);
 				$tags = (is_null($ft) ? array() : explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft));
 			endif;
-			
+
 			$ft = $this->link->setting('tags', NULL, array());
 			if (is_array($ft)) :
 				$tags = array_merge($tags, $ft);
 			endif;
 			$this->preset_terms['post_tag'] = $tags;
-			
+
 			// Scan post for /a[@rel='tag'] and use as tags if present
 			$tags = $this->inline_tags();
 			$this->feed_terms['post_tag'] = apply_filters('syndicated_item_tags', $tags, $this);
-			
+
 			$taxonomies = $this->link->taxonomies();
 			$feedTerms = $this->link->setting('terms', NULL, array());
 			$globalTerms = get_option('feedwordpress_syndication_terms', array());
@@ -324,14 +328,14 @@ class SyndicatedPost {
 			foreach ($taxonomies as $tax) :
 				if (!isset($specials[$tax])) :
 					$terms = array();
-				
+
 					// See if we should get the globals
 					if ('no' != $this->link->setting("add/$tax", NULL, 'yes')) :
 						if (isset($globalTerms[$tax])) :
 							$terms = $globalTerms[$tax];
 						endif;
 					endif;
-					
+
 					// Now merge in the locals
 					if (isset($feedTerms[$tax])) :
 						$terms = array_merge($terms, $feedTerms[$tax]);
@@ -352,7 +356,7 @@ class SyndicatedPost {
 
 	function substitution_function ($name) {
 		$ret = NULL;
-		
+
 		switch ($name) :
 		// Allowed PHP string functions
 		case 'trim':
@@ -366,7 +370,7 @@ class SyndicatedPost {
 		endswitch;
 		return $ret;
 	}
-	
+
 	/**
 	 * SyndicatedPost::query uses an XPath-like syntax to query arbitrary
 	 * elements within the syndicated item.
@@ -383,9 +387,9 @@ class SyndicatedPost {
 	 	foreach ($match as $ref) :
 	 	 	$urlHash[md5($ref[1])] = $ref[1];
 		endforeach;
-	
+
 		foreach ($urlHash as $hash => $url) :
-			$path = str_replace('{'.$url.'}', '{#'.$hash.'}', $path); 
+			$path = str_replace('{'.$url.'}', '{#'.$hash.'}', $path);
 		endforeach;
 
 		$path = explode('/', $path);
@@ -406,7 +410,7 @@ class SyndicatedPost {
 		while (strlen($node)==0 and !is_null($node)) :
 			$node = array_shift($path);
 		endwhile;
-		
+
 		switch ($node) :
 		case 'feed' :
 		case 'channel' :
@@ -440,7 +444,7 @@ class SyndicatedPost {
 									$addenda = $elements[$element];
 									$contexts = $elements[$element];
 								endif;
-								
+
 								foreach ($addenda as $index => $addendum) :
 									$context = $contexts[$index];
 
@@ -450,15 +454,15 @@ class SyndicatedPost {
 									endif;
 								endforeach;
 							endif;
-						endforeach;						
+						endforeach;
 					endif;
 				endforeach;
-		
+
 				$data = $matches;
 			endif;
 			$node = array_shift($path);
 		endwhile;
-	
+
 		$matches = array();
 		foreach ($data as $datum) :
 			if (is_string($datum)) :
@@ -487,7 +491,7 @@ class SyndicatedPost {
 				'http://backend.userland.com/RSS2',
 				SIMPLEPIE_NAMESPACE_RSS_20,
 		);
-		
+
 		$matches = array();
 		foreach ($rss as $ns) :
 			$data = $this->link->simplepie->get_feed_tags($ns, 'channel');
@@ -514,7 +518,7 @@ class SyndicatedPost {
 		else :
 			$defaultNS = SIMPLEPIE_NAMESPACE_RSS_20;
 		endif;
-		return $defaultNS;	
+		return $defaultNS;
 	} /* SyndicatedPost::xpath_default_namespace() */
 
 	function xpath_name_and_axis ($node) {
@@ -549,20 +553,20 @@ class SyndicatedPost {
 			$ns = array($ref[1]);
 		elseif (strpos($node, ':') !== FALSE) :
 			list($xmlns, $element) = explode(':', $node, 2);
-			
+
 			if (isset($this->xmlns['reverse'][$xmlns])) :
 				$ns = $this->xmlns['reverse'][$xmlns];
 			else :
 				$ns = array($xmlns);
 			endif;
-			
+
 			// Fucking SimplePie. For attributes in default xmlns.
 			$defaultNS = $this->xpath_default_namespace();
 			if (isset($this->xmlns['forward'][$defaultNS])
 			and ($xmlns==$this->xmlns['forward'][$defaultNS])) :
 				$ns[] = '';
 			endif;
-			
+
 			if (isset($datum['xmlns'])) :
 				if (isset($datum['xmlns'][$xmlns])) :
 					$ns[] = $datum['xmlns'][$xmlns];
@@ -576,18 +580,60 @@ class SyndicatedPost {
 		return array_unique($ns);
 	} /* SyndicatedPost::xpath_possible_namespaces() */
 
-	function content () {
+	function get_categories ($params = array()) {
+		return $this->entry->get_categories();
+	}
+	
+	function title ($params = array()) {
+		return $this->entry->get_title();
+	} /* SyndicatedPost::title () */
+	
+	function content ($params = array()) {
+		$params = wp_parse_args($params, array(
+		"full only" => false, 
+		));
+		
 		$content = NULL;
+		
+		// FIXME: This is one of the main places in the code still using
+		// the outmoded SimplePie - to - Magpie construction. We could
+		// replace using SimplePie_Item::get_tags() here. (Or if really
+		// ambitious we could attempt to just use
+		// SimplePie_Item::get_content() with content-only set to TRUE
+		// and some sanitization in effect. -CJ 1jul14
+		
+		// atom:content, standard method of providing full HTML content
+		// in Atom feeds.
 		if (isset($this->item['atom_content'])) :
 			$content = $this->item['atom_content'];
+		elseif (isset($this->item['atom']['atom_content'])) :
+			$content = $this->item['atom']['atom_content'];
+		
+		// Some exotics: back in the day, before widespread convergence
+		// on content:encoding, some RSS feeds took advantage of XML
+		// namespaces to use an inline xhtml:body or xhtml:div element
+		// for full-content HTML. (E.g. Sam Ruby's feed, IIRC.)
 		elseif (isset($this->item['xhtml']['body'])) :
 			$content = $this->item['xhtml']['body'];
 		elseif (isset($this->item['xhtml']['div'])) :
 			$content = $this->item['xhtml']['div'];
+		
+		// content:encoded, most common method of providing full HTML in
+		// RSS 2.0 feeds.
 		elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
 			$content = $this->item['content']['encoded'];
-		elseif (isset($this->item['description'])) :
-			$content = $this->item['description'];
+		
+		// Fall back on elements that sometimes may contain full HTML
+		// but sometimes not.
+		elseif (!$params['full only']) :
+		
+			// description element is sometimes used for full HTML
+			// sometimes for summary text in RSS. (By the letter of
+			// the standard, it should just be for summary text.)
+			if (isset($this->item['description'])) :
+				$content = $this->item['description'];
+			endif;
+			
 		endif;
 		return $content;
 	} /* SyndicatedPost::content() */
@@ -595,13 +641,13 @@ class SyndicatedPost {
 	function excerpt () {
 		# Identify and sanitize excerpt: atom:summary, or rss:description
 		$excerpt = $this->entry->get_description();
-			
+
 		# Many RSS feeds use rss:description, inadvisably, to
 		# carry the entire post (typically with escaped HTML).
 		# If that's what happened, we don't want the full
 		# content for the excerpt.
 		$content = $this->content();
-		
+
 		// Ignore whitespace, case, and tag cruft.
 		$theExcerpt = preg_replace('/\s+/', '', strtolower(strip_tags($excerpt)));
 		$theContent = preg_replace('/\s+/', '', strtolower(strip_tags($content)));
@@ -628,7 +674,7 @@ class SyndicatedPost {
 	function created ($params = array()) {
 		$unfiltered = false; $default = NULL;
 		extract($params);
-		
+
 		$date = '';
 		if (isset($this->item['dc']['created'])) :
 			$date = $this->item['dc']['created'];
@@ -653,7 +699,7 @@ class SyndicatedPost {
 		else : // New style
 			extract($params);
 		endif;
-		
+
 		$date = '';
 		$ts = null;
 
@@ -672,14 +718,14 @@ class SyndicatedPost {
 		elseif (isset($this->item['pubdate'])):				// RSS 2.0
 			$date = $this->item['pubdate'];
 		endif;
-		
+
 		if (strlen($date) > 0) :
 			$time = new FeedTime($date);
 			$ts = $time->timestamp();
 		elseif ($fallback) :						// Fall back to <updated> / <modified> if present
 			$ts = $this->updated(/*fallback=*/ false, /*default=*/ $default);
 		endif;
-		
+
 		# If everything failed, then default to the current time.
 		if (is_null($ts)) :
 			if (-1 == $default) :
@@ -688,7 +734,7 @@ class SyndicatedPost {
 				$ts = $default;
 			endif;
 		endif;
-		
+
 		if (!$unfiltered) :
 			$ts = apply_filters('syndicated_item_published', $ts, $this);
 		endif;
@@ -718,14 +764,14 @@ class SyndicatedPost {
 		elseif (isset($this->item['updated'])):			// Atom 1.0
 			$date = $this->item['updated'];
 		endif;
-		
+
 		if (strlen($date) > 0) :
 			$time = new FeedTime($date);
 			$ts = $time->timestamp();
 		elseif ($fallback) :						// Fall back to issued / dc:date
 			$ts = $this->published(/*fallback=*/ false, /*default=*/ $default);
 		endif;
-		
+
 		# If everything failed, then default to the current time.
 		if (is_null($ts)) :
 			if (-1 == $default) :
@@ -766,19 +812,19 @@ class SyndicatedPost {
 			"content" => $this->content(),
 			"excerpt" => $this->excerpt(),
 		);
-		
+
 		if ($hashed) :
 			$hash = md5(serialize($hash));
 		endif;
-		
+
 		return $hash;
 	} /* SyndicatedPost::update_hash() */
 
-	/*static*/ function normalize_guid_prefix () {
+	static function normalize_guid_prefix () {
 		return trailingslashit(get_bloginfo('url')).'?guid=';
 	}
-	
-	/*static*/ function normalize_guid ($guid) {
+
+	static function normalize_guid ($guid) {
 		$guid = trim($guid);
 		if (preg_match('/^[0-9a-z]{32}$/i', $guid)) : // MD5
 			$guid = SyndicatedPost::normalize_guid_prefix().strtolower($guid);
@@ -788,7 +834,7 @@ class SyndicatedPost {
 		$guid = trim($guid);
 		return $guid;
 	} /* SyndicatedPost::normalize_guid() */
-	
+
 	function guid () {
 		$guid = null;
 		if (isset($this->item['id'])):						// Atom 0.3 / 1.0
@@ -800,12 +846,12 @@ class SyndicatedPost {
 		elseif (isset($this->item['dc']['identifier'])) :	// yeah, right
 			$guid = $this->item['dc']['identifier'];
 		endif;
-		
+
 		// Un-set or too long to use as-is. Generate a tag: URI.
 		if (is_null($guid) or strlen($guid) > 250) :
 			// In case we need to check this again
 			$original_guid = $guid;
-			
+
 			// The feed does not seem to have provided us with a
 			// usable unique identifier, so we'll have to cobble
 			// together a tag: URI that might work for us. The base
@@ -823,7 +869,7 @@ class SyndicatedPost {
 			// are hashed down into a nice, manageable tag: URI.
 			if (!is_null($original_guid)) :
 				$guid .= ',2010-12-03:id.'.md5($original_guid);
-			
+
 			// If we have a date of creation, then we can use that
 			// to uniquely identify the item. (On the other hand, if
 			// the feed producer was consicentious enough to
@@ -831,7 +877,7 @@ class SyndicatedPost {
 			// conscientious enough to generate unique identifiers.)
 			elseif (!is_null($this->created())) :
 				$guid .= '://post.'.date('YmdHis', $this->created());
-			
+
 			// Otherwise, use both the URI of the item, *and* the
 			// item's title. We have to use both because titles are
 			// often not unique, and sometimes links aren't unique
@@ -847,10 +893,10 @@ class SyndicatedPost {
 		endif;
 		return $guid;
 	} /* SyndicatedPost::guid() */
-	
+
 	function author () {
 		$author = array ();
-		
+
 		$aa = $this->entry->get_authors();
 		if (count($aa) > 0) :
 			$a = reset($aa);
@@ -881,7 +927,7 @@ class SyndicatedPost {
 				// 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'];
@@ -891,7 +937,7 @@ class SyndicatedPost {
 				endif;
 			endif;
 		endif;
-		
+
 		if (!isset($author['name']) or is_null($author['name'])) :
 			// Nothing found. Try some crappy defaults.
 			if ($this->link->name()) :
@@ -901,14 +947,14 @@ class SyndicatedPost {
 				$author['name'] = $url['host'];
 			endif;
 		endif;
-		
+
 		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'])):
@@ -921,7 +967,7 @@ class SyndicatedPost {
 				$author['uri'] = $this->feed->channel['link'];
 			endif;
 		endif;
-		
+
 		return $author;
 	} /* SyndicatedPost::author() */
 
@@ -945,7 +991,7 @@ class SyndicatedPost {
 		endif;
 		return $tags;
 	}
-	
+
 	/**
 	 * SyndicatedPost::isTaggedAs: Test whether a feed item is
 	 * tagged / categorized with a given string. Case and leading and
@@ -953,7 +999,7 @@ class SyndicatedPost {
 	 *
 	 * @param string $tag Tag to check for
 	 *
-	 * @return bool Whether or not at least one of the categories / tags on 
+	 * @return bool Whether or not at least one of the categories / tags on
 	 *	$this->item is set to $tag (modulo case and leading and trailing
 	 * 	whitespace)
 	 */
@@ -968,7 +1014,7 @@ class SyndicatedPost {
 		// on this item is stored under index "category#".
 		if (isset($this->item['category#'])) :
 			$numberOfCategories = (int) $this->item['category#'];
-		
+
 		// We REALLY shouldn't have the old and busted MagpieRSS, but in
 		// case we do, it doesn't support multiple categories, but there
 		// might still be a single value under the "category" index.
@@ -1027,7 +1073,7 @@ class SyndicatedPost {
 				endif;
 			endfor;
 		endif;
-		return $enclosures;		
+		return $enclosures;
 	} /* SyndicatedPost::enclosures() */
 
 	function source ($what = NULL) {
@@ -1038,7 +1084,7 @@ class SyndicatedPost {
 			$ret['title'] = $source->get_title();
 			$ret['uri'] = $source->get_link();
 			$ret['feed'] = $source->get_link(0, 'self');
-			
+
 			if ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) :
 				$ret['id'] = $id_tags[0]['data'];
 			elseif ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) :
@@ -1051,16 +1097,16 @@ class SyndicatedPost {
 				$ret['id'] = $id_tags[0]['data'];
 			endif;
 		endif;
-		
+
 		if (!is_null($what) and is_scalar($what)) :
 			$ret = $ret[$what];
 		endif;
 		return $ret;
 	}
-	
+
 	function comment_link () {
 		$url = null;
-		
+
 		// RSS 2.0 has a standard <comments> element:
 		// "<comments> is an optional sub-element of <item>. If present,
 		// it is the url of the comments page for the item."
@@ -1073,13 +1119,13 @@ class SyndicatedPost {
 		// element with @rel="replies" and @type="text/html".
 		// Unfortunately, SimplePie_Item::get_links() allows us to filter
 		// by the value of @rel, but not by the value of @type. *sigh*
-		
+
 		// Try Atom 1.0 first
 		$linkElements = $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link');
-		
+
 		// Fall back and try Atom 0.3
 		if (is_null($linkElements)) : $linkElements =  $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'); endif;
-		
+
 		// Now loop through the elements, screening by @rel and @type
 		if (is_array($linkElements)) : foreach ($linkElements as $link) :
 			$rel = (isset($link['attribs']['']['rel']) ? $link['attribs']['']['rel'] : 'alternate');
@@ -1170,9 +1216,9 @@ class SyndicatedPost {
 		return $tag['prefix'] . $url . $tag['suffix'];
 	} /* function SyndicatedPost::resolve_single_relative_uri() */
 
-	function resolve_relative_uris ($content, $obj) {
+	static function resolve_relative_uris ($content, $obj) {
 		$set = $obj->link->setting('resolve relative', 'resolve_relative', 'yes');
-		if ($set and $set != 'no') : 
+		if ($set and $set != 'no') :
 			// Fallback: if we don't have anything better, use the
 			// item link from the feed
 			$obj->_base = $obj->permalink(); // Reset the base for resolving relative URIs
@@ -1194,7 +1240,7 @@ class SyndicatedPost {
 				);
 			endforeach;
 		endif;
-		
+
 		return $content;
 	} /* function SyndicatedPost::resolve_relative_uris () */
 
@@ -1209,7 +1255,7 @@ class SyndicatedPost {
 		return $tag['before_attribute'].$tag['after_attribute'];
 	}
 
-	function sanitize_content ($content, $obj) {
+	static function sanitize_content ($content, $obj) {
 		# This kind of sucks. I intend to replace it with
 		# lib_filter sometime soon.
 		foreach ($obj->strip_attrs as $pair):
@@ -1246,50 +1292,69 @@ class SyndicatedPost {
 	 * still up-to-date.
 	 *
 	 * @return int A status code representing the freshness of the post
+	 *	-1 = post already syndicated; has a revision that needs to be stored, but not updated to
 	 *	0 = post already syndicated; no update needed
 	 *	1 = post already syndicated, but needs to be updated to latest
 	 *	2 = post has not yet been syndicated; needs to be created
 	 */
-	function freshness () {
+	function freshness ($format = 'number') {
 		global $wpdb;
 
 		if ($this->filtered()) : // This should never happen.
 			FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
 		endif;
-		
+
 		if (is_null($this->_freshness)) : // Not yet checked and cached.
 			$guid = $this->post['guid'];
-			$eguid = $wpdb->escape($this->post['guid']);
+			$eguid = esc_sql($this->post['guid']);
 
 			$q = new WP_Query(array(
 				'fields' => '_synfresh', // id, guid, post_modified_gmt
 				'ignore_sticky_posts' => true,
 				'guid' => $guid,
 			));
-			
+
 			$old_post = NULL;
 			if ($q->have_posts()) :
 				while ($q->have_posts()) : $q->the_post();
 					$old_post = $q->post;
 				endwhile;
 			endif;
-			
+
 			if (is_null($old_post)) : // No post with this guid
 				FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is a NEW POST.');
 				$this->_wp_id = NULL;
 				$this->_freshness = 2; // New content
 			else :
-				preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $old_post->post_modified_gmt, $backref);
+				// Presume there is nothing new until we find
+				// something new.
+				$updated = false;
+				$live = false;
+				
+				// Pull the list of existing revisions to get
+				// timestamps.
+				$revisions = wp_get_post_revisions($old_post->ID);
+				foreach ($revisions as $rev) :
+					$revisions_ts[] = mysql2date('G', $rev->post_modified_gmt); 
+				endforeach;
 
-				$last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
+				$revisions_ts[] = mysql2date('G', $old_post->post_modified_gmt);
+				$last_rev_ts = end($revisions_ts);
 				$updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
 				
-				// Check timestamps...
-				$updated = (
-					!is_null($updated_ts)
-					and ($updated_ts > $last_rev_ts)
-				);
+				// If we have an explicit updated timestamp,
+				// check that against existing stamps.
+				if (!is_null($updated_ts)) :
+					$updated = !in_array($updated_ts, $revisions_ts);
+
+					// If this a newer revision, make it go
+					// live. If an older one, just record
+					// the contents.
+					$live = ($updated and ($updated_ts > $last_rev_ts));
+				endif;
 
+				// This is a revision we haven't seen before, judging by the date.
+				
 				$updatedReason = NULL;
 				if ($updated) :
 					$updatedReason = preg_replace(
@@ -1300,6 +1365,9 @@ class SyndicatedPost {
 						.date('Y-m-d H:i:s', $last_rev_ts)
 						.')'
 					);
+
+				// The date does not indicate a new revision, so
+				// let's check the hash.
 				else :
 					// Or the hash...
 					$hash = $this->update_hash();
@@ -1309,24 +1377,31 @@ class SyndicatedPost {
 					else :
 						$updated = true; // Can't find syndication meta-data
 					endif;
-					
+
 					if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) :
+						// In the absence of definitive
+						// timestamp information, we
+						// just have to assume that a
+						// hash we haven't seen before
+						// is a newer version.
+						$live = true;
+
 						$updatedReason = ' has a not-yet-seen update hash: '
-						.FeedWordPress::val($hash)
+						.MyPHP::val($hash)
 						.' not in {'
 						.implode(", ", array_map(array('FeedWordPress', 'val'), $seen))
 						.'}. Basis: '
-						.FeedWordPress::val(array_keys($this->update_hash(false)));
+						.MyPHP::val(array_keys($this->update_hash(false)));
 					endif;
 				endif;
-				
+
 				$frozen = false;
 				if ($updated) : // Ignore if the post is frozen
 					$frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
 					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;
@@ -1334,7 +1409,7 @@ class SyndicatedPost {
 						$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT '.$updatedReason;
 					endif;
 				endif;
-				$updated = ($updated and !$frozen);
+				$live = ($live and !$frozen);
 
 				if ($updated) :
 					FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
@@ -1342,7 +1417,9 @@ class SyndicatedPost {
 						$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->_freshness = apply_filters('syndicated_item_freshness', ($live ? 1 : -1), $updated, $frozen, $updated_ts, $last_rev_ts, $this);
+
 					$this->_wp_id = $old_post->ID;
 					$this->_wp_post = $old_post;
 
@@ -1359,9 +1436,88 @@ class SyndicatedPost {
 				endif;
 			endif;
 		endif;
-		return $this->_freshness;
+		
+		switch ($format) :
+		case 'status' :
+			switch ($this->_freshness) :
+			case -1:
+				$ret = 'stored';
+				break;
+			case 0:
+				$ret = NULL;
+				break;
+			case 1:
+				$ret = 'updated';
+				break;
+			case 2:
+			default:
+				$ret = 'new';
+				break;
+			endswitch;
+			break;
+		case 'number' :
+		default :
+			$ret = $this->_freshness;
+		endswitch;
+		
+		
+		return $ret;
+	} /* SyndicatedPost::freshness () */
+	
+	function has_fresh_content () {
+		return ( ! $this->filtered() and $this->freshness() != 0 );
+	} /* SyndicatedPost::has_fresh_content () */
+	
+	function this_revision_needs_original_post ($freshness = NULL) {
+		if (is_null($freshness)) :
+			$freshness = $this->freshness();
+		endif;
+		return ( $freshness >= 2 );
 	}
-
+	
+	function this_revision_is_current ($freshness = NULL) {
+		if (is_null($freshness)) :
+			$freshness = $this->freshness();
+		endif;
+		return ( $freshness >= 1 );
+	} /* SyndicatedPost::this_revision_is_current () */
+	
+	function fresh_content_is_update () {
+		return ($this->freshness() < 2);
+	} /* SyndicatedPost::fresh_content_is_update () */
+	
+	function fresh_storage_diagnostic () {
+		$ret = NULL;
+		switch ($this->freshness()) :
+		case -1 :
+			$ret = 'Storing alternate revision of existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"';
+			break;
+		case 1 :
+			$ret = 'Updating existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"';
+			break;
+		case 2 :
+		default :
+			$ret = 'Inserting new post "'.$this->post['post_title'].'"';
+			break;			
+		endswitch;
+		return $ret;
+	} /* SyndicatedPost::fresh_storage_diagnostic() */
+	
+	function fresh_storage_hook () {
+		$ret = NULL;
+		switch ($this->freshness()) :
+		case -1 :
+		case 1 :
+			$ret = 'update_syndicated_item';
+			break;
+		case 2 :
+		default :
+			$ret = 'post_syndicated_item';
+			break;
+		endswitch;
+		return $ret;
+	} /* SyndicatedPost::fresh_storage_hook () */
+	
 	#################################################
 	#### INTERNAL STORAGE AND MANAGEMENT METHODS ####
 	#################################################
@@ -1370,7 +1526,7 @@ class SyndicatedPost {
 		if ($this->filtered()) : // This should never happen.
 			FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
 		endif;
-		
+
 		if (is_null($this->_wp_id) and is_null($this->_freshness)) :
 			$fresh = $this->freshness(); // sets WP DB id in the process
 		endif;
@@ -1383,9 +1539,9 @@ class SyndicatedPost {
 		if ($this->filtered()) : // This should never happen.
 			FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
 		endif;
-		
+
 		$freshness = $this->freshness();
-		if ($freshness > 0) :
+		if ($this->has_fresh_content()) :
 			# -- Look up, or create, numeric ID for author
 			$this->post['post_author'] = $this->author_id (
 				$this->link->setting('unfamiliar author', 'unfamiliar_author', 'create')
@@ -1396,8 +1552,10 @@ class SyndicatedPost {
 				$this->post = NULL;
 			endif;
 		endif;
-		
-		if (!$this->filtered() and $freshness > 0) :
+
+		// We have to check again in case post has been filtered during
+		// the author_id lookup
+		if ($this->has_fresh_content()) :
 			$consider = array(
 				'category' => array('abbr' => 'cats', 'domain' => array('category', 'post_tag')),
 				'post_tag' => array('abbr' => 'tags', 'domain' => array('post_tag')),
@@ -1408,10 +1566,10 @@ class SyndicatedPost {
 				if (!is_null($this->post)) : // Not filtered out yet
 					# -- Look up, or create, numeric ID for categories
 					$taxonomies = $this->link->setting("match/".$taxes['abbr'], 'match_'.$taxes['abbr'], $taxes['domain']);
-	
+
 					// Eliminate dummy variables
 					$taxonomies = array_filter($taxonomies, 'remove_dummy_zero');
-	
+
 					$terms = $this->category_ids (
 						$this->feed_terms[$what],
 						$this->link->setting("unfamiliar {$what}", "unfamiliar_{$what}", 'create:'.$what),
@@ -1421,7 +1579,7 @@ class SyndicatedPost {
 						  'filters' => true,
 						)
 					);
-					
+
 					if (is_null($terms) or is_null($termSet)) :
 						// filtered out -- no matches
 					else :
@@ -1457,7 +1615,7 @@ class SyndicatedPost {
 					if (!isset($this->post['tax_input'][$tax])) :
 						$this->post['tax_input'][$tax] = array();
 					endif;
-					
+
 					$this->post['tax_input'][$tax] = array_merge (
 						$this->post['tax_input'][$tax],
 						$this->category_ids (
@@ -1471,23 +1629,25 @@ class SyndicatedPost {
 				endforeach;
 			endif;
 		endif;
-		
-		if (!$this->filtered() and $freshness > 0) :
+
+		// We have to check again in case the post has been filtered
+		// during the category/tags/taxonomy terms lookup
+		if ($this->has_fresh_content()) :
 			// 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);			
+			$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', $post_name, $this);
 			if (!empty($post_name)) :
 				$this->post['post_name'] = $post_name;
 			endif;
-			
+
 			$this->post = apply_filters('syndicated_post', $this->post, $this);
-			
+
 			// Allow for feed-specific syndicated_post filters.
 			$this->post = apply_filters(
 				"syndicated_post_".$this->link->uri(),
@@ -1495,7 +1655,7 @@ class SyndicatedPost {
 				$this
 			);
 		endif;
-		
+
 		// Hook in early to make sure these get inserted if at all possible
 		add_action(
 			/*hook=*/ 'transition_post_status',
@@ -1503,39 +1663,42 @@ class SyndicatedPost {
 			/*priority=*/ -10000, /* very early */
 			/*arguments=*/ 3
 		);
-
-		$retval = array(1 => 'updated', 2 => 'new');
 		
 		$ret = false;
-		if (!$this->filtered() and isset($retval[$freshness])) :			
-			$diag = array(
-				1 => 'Updating existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"',
-				2 => 'Inserting new post "'.$this->post['post_title'].'"',
-			);
-			FeedWordPress::diagnostic('syndicated_posts', $diag[$freshness]);
-
-			$this->insert_post(/*update=*/ ($freshness == 1));
+		if ($this->has_fresh_content()) :
+			$diag = $this->fresh_storage_diagnostic();
+			if (!is_null($diag)) :
+				FeedWordPress::diagnostic('syndicated_posts', $diag);
+			endif;
 			
-			$hook = array(	1 => 'update_syndicated_item', 2 => 'post_syndicated_item' );
-			do_action($hook[$freshness], $this->wp_id(), $this);
+			$this->insert_post(/*update=*/ $this->fresh_content_is_update(), $this->freshness());
 
-			$ret = $retval[$freshness];
+			$hook = $this->fresh_storage_hook();
+			if (!is_null($hook)) :
+				do_action($hook, $this->wp_id(), $this);
+			endif;
+			
+			$ret = $this->freshness('status');
 		endif;
 
-		// If this is a legit, non-filtered post, tag it as found on the feed
-		// regardless of fresh or stale status
+		// 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."); 
+			if ('fwpretired'==$status and $this->link->is_non_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);
+				wp_transition_post_status($this->post['post_status'], $status, $this->post);
+			elseif ('fwpzapped'==$status) :
+				// Set this new revision up to be
+				// blanked on the next update.
+				add_post_meta($this->wp_id(), '_feedwordpress_zapped_blank_me', 2, /*single=*/ true);
 			endif;
 		endif;
-		
+
 		// Remove add_rss_meta hook
 		remove_action(
 			/*hook=*/ 'transition_post_status',
@@ -1546,17 +1709,18 @@ class SyndicatedPost {
 
 		return $ret;
 	} /* function SyndicatedPost::store () */
-	
-	function insert_post ($update = false) {
+
+	function insert_post ($update = false, $freshness = 2) {
 		global $wpdb;
 
 		$dbpost = $this->normalize_post(/*new=*/ true);
+
 		if (!is_null($dbpost)) :
 			$dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
-	
+
 			// This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
 			add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
-				
+
 			// Kludge to prevent kses filters from stripping the
 			// content of posts when updating without a logged in
 			// user who has `unfiltered_html` capability.
@@ -1568,17 +1732,17 @@ class SyndicatedPost {
 					$removed[] = $munger;
 				endif;
 			endforeach;
-			
+
 			if ($update and function_exists('get_post_field')) :
 				// Don't munge status fields that the user may
 				// have reset manually
 				$doNotMunge = array('post_status', 'comment_status', 'ping_status');
-				
+
 				foreach ($doNotMunge as $field) :
 					$dbpost[$field] = get_post_field($field, $this->wp_id());
 				endforeach;
 			endif;
-			
+
 			// WP3's wp_insert_post scans current_user_can() for the
 			// tax_input, with no apparent way to override. Ugh.
 			add_action(
@@ -1587,7 +1751,7 @@ class SyndicatedPost {
 			/*priority=*/ -10001, /* very early */
 			/*arguments=*/ 3
 			);
-			
+
 			// WP3 appears to override whatever you give it for
 			// post_modified. Ugh.
 			add_action(
@@ -1601,8 +1765,44 @@ class SyndicatedPost {
 				$this->post['ID'] = $this->wp_id();
 				$dbpost['ID'] = $this->post['ID'];
 			endif;
+
+			// O.K., is this a new post? If so, we need to create
+			// the basic post record before we do anything else.
+			if ($this->this_revision_needs_original_post()) :
+				// *sigh*, for handling inconsistent slash expectations < 3.6
+				$sdbpost = $this->db_sanitize_post($dbpost);
+				
+				// Go ahead and insert the first post record to
+				// anchor the revision history.
+				$this->_wp_id = wp_insert_post($sdbpost, /*return wp_error=*/ true);
+				
+				$dbpost['ID'] = $this->_wp_id;
+			endif;
+			
+			// Now that we've made sure the original exists, insert
+			// this version here as a revision.
+			$revision_id = _wp_put_post_revision($dbpost, /*autosave=*/ false);
+
+			if (!$this->this_revision_needs_original_post()) :
 			
-			$this->_wp_id = wp_insert_post($dbpost, /*return wp_error=*/ true);
+				if ($this->this_revision_is_current()) :
+
+					wp_restore_post_revision($revision_id);
+
+				else :
+
+					// If we do not activate this revision, then the
+					// add_rss_meta will not be called, which is
+					// more or less as it should be, but that means
+					// we have to actively record this revision's
+					// update hash from here.
+					$postId = $this->post['ID'];
+					$key = 'syndication_item_hash';
+					$hash = $this->update_hash();
+					FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".FeedWordPress::val($hash, /*no newlines=*/ true));
+					add_post_meta(	$postId, $key, $hash, /*unique=*/ false );
+				endif;
+			endif;
 
 			remove_action(
 			/*hook=*/ 'transition_post_status',
@@ -1623,17 +1823,17 @@ class SyndicatedPost {
 			foreach ($removed as $filter) :
 				add_filter('content_save_pre', $filter);
 			endforeach;
-			
+
 			$this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
 		endif;
 	} /* function SyndicatedPost::insert_post () */
-	
+
 	function insert_new () {
-		$this->insert_post(/*update=*/ false);
+		$this->insert_post(/*update=*/ false, 1);
 	} /* SyndicatedPost::insert_new() */
 
 	function update_existing () {
-		$this->insert_post(/*update=*/ true);
+		$this->insert_post(/*update=*/ true, 2);
 	} /* SyndicatedPost::update_existing() */
 
 	/**
@@ -1660,7 +1860,7 @@ class SyndicatedPost {
 				$feed_url = parse_url($this->post['meta']['syndication_feed']);
 				$source_title = $feed_url['host'];
 			endif;
-			
+
 			$out['post_title'] = $source_title
 				.' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
 			// FIXME: Option for what to fill a blank title with...
@@ -1669,18 +1869,29 @@ class SyndicatedPost {
 		// Normalize the guid if necessary.
 		$out['guid'] = SyndicatedPost::normalize_guid($out['guid']);
 
-		// Why the fuck doesn't wp_insert_post already do this?
-		foreach ($out as $key => $value) :
-			if (is_string($value)) :
-				$out[$key] = $wpdb->escape($value);
-			else :
-				$out[$key] = $value;
-			endif;
-		endforeach;
-
 		return $out;
 	}
 
+	function db_sanitize_post ($out) {
+		// < 3.6. Core API, including wp_insert_post(), will expect
+		// properly slashed data. If wp_slash() exists, then this is
+		// after the big change-over, and wp_insert_post() etc. will
+		// expect *un*-slashed data.
+		if (!function_exists('wp_slash')) :
+		
+			foreach ($out as $key => $value) :
+				if (is_string($value)) :
+					$out[$key] = esc_sql($value);
+				else :
+					$out[$key] = $value;
+				endif;
+			endforeach;
+
+		endif;
+
+		return $out;
+	}
+	
 	/**
 	 * SyndicatedPost::validate_post_id()
 	 *
@@ -1702,8 +1913,9 @@ class SyndicatedPost {
 			// notice if we are in debug mode.
 			$mesg = "Failed to $verb item [$guid]. WordPress API returned no valid post ID.\n"
 				."\t\tID = ".serialize($this->_wp_id)."\n"
-				."\t\tURL = ".FeedWordPress::val($url)
-				."\t\tFeed = ".FeedWordPress::val($feed); 
+				."\t\tURL = ".MyPHP::val($url)
+				."\t\tFeed = ".MyPHP::val($feed); 
+
 			FeedWordPress::diagnostic('updated_feeds:errors', "WordPress API error: $mesg");
 			FeedWordPress::diagnostic('feed_items:rejected', $mesg);
 
@@ -1711,9 +1923,9 @@ class SyndicatedPost {
 The WordPress API returned an invalid post ID
 			   when FeedWordPress tried to $verb item $guid
 			   [URL: $url]
-			   from the feed at $feed 
+			   from the feed at $feed
 
-$ns::_wp_id 
+$ns::_wp_id
 EOM;
 			FeedWordPress::noncritical_bug(
 				/*message=*/ $mesg,
@@ -1725,16 +1937,16 @@ EOM;
 			);
 		endif;
 	} /* SyndicatedPost::validate_post_id() */
-	
+
 	/**
-	 * SyndicatedPost::fix_revision_meta() - Fixes the way WP 2.6+ fucks up
-	 * meta-data (authorship, etc.) when storing revisions of an updated
-	 * syndicated post.
+	 * SyndicatedPost::fix_revision_meta() - Ensures that we get the meta
+	 * data (authorship, guid, etc.) that we want when storing revisions of
+	 * a syndicated post.
 	 *
-	 * In their infinite wisdom, the WordPress coders have made it completely
-	 * impossible for a plugin that uses wp_insert_post() to set certain
-	 * meta-data (such as the author) when you store an old revision of an
-	 * updated post. Instead, it uses the WordPress defaults (= currently
+	 * In their infinite wisdom, the WordPress coders seem to have made it
+	 * completely impossible for a plugin that uses wp_insert_post() to set
+	 * certain meta-data (such as the author) when you store an old revision
+	 * of an updated post. Instead, it uses the WordPress defaults (= cur.
 	 * active user ID if the process is running with a user logged in, or
 	 * = #0 if there is no user logged in). This results in bogus authorship
 	 * data for revisions that are syndicated from off the feed, unless we
@@ -1745,17 +1957,22 @@ EOM;
 	 */
 	function fix_revision_meta ($revision_id) {
 		global $wpdb;
-		
+
 		$post_author = (int) $this->post['post_author'];
-		
+
 		$revision_id = (int) $revision_id;
-		$wpdb->query("
-		UPDATE $wpdb->posts
-		SET post_author={$this->post['post_author']}
-		WHERE post_type = 'revision' AND ID='$revision_id'
-		");
+		
+		// Let's fix the author.
+		set_post_field('post_author', $this->post['post_author'], $revision_id);
+		
+		// Let's fix the GUID to a dummy URL with the update hash.
+		set_post_field('guid', 'http://feedwordpress.radgeek.com/?rev='.$this->update_hash(), $revision_id);
+
+		// Let's fire an event for add-ons and filters
+		do_action('syndicated_post_fix_revision_meta', $revision_id, $this);
+		
 	} /* SyndicatedPost::fix_revision_meta () */
-	 
+
 	/**
 	 * SyndicatedPost::add_terms() -- if FeedWordPress is processing an
 	 * automatic update, that generally means that wp_insert_post() is being
@@ -1774,18 +1991,35 @@ EOM;
 	 * @param object $post The database record for the post just inserted.
 	 */
 	function add_terms ($new_status, $old_status, $post) {
+
 		if ($new_status!='inherit') : // Bail if we are creating a revision.
 			if ( is_array($this->post) and isset($this->post['tax_input']) and is_array($this->post['tax_input']) ) :
 				foreach ($this->post['tax_input'] as $taxonomy => $terms) :
 					if (is_array($terms)) :
 						$terms = array_filter($terms); // strip out empties
 					endif;
-					wp_set_post_terms($post->ID, $terms, $taxonomy);
+
+					$res = wp_set_post_terms(
+						/*post_id=*/ $post->ID,
+						/*terms=*/ $terms,
+						/*taxonomy=*/ $taxonomy
+					);
+
+					FeedWordPress::diagnostic(
+						'syndicated_posts:categories',
+						'Category: post('.json_encode($post->ID).') '.$taxonomy
+						.' := '
+						.json_encode($terms)
+						.' / result: '
+						.json_encode($res)
+					);
+
 				endforeach;
 			endif;
 		endif;
+
 	} /* SyndicatedPost::add_terms () */
-	
+
 	/**
 	 * SyndicatedPost::fix_post_modified_ts() -- We would like to set
 	 * post_modified and post_modified_gmt to reflect the value of
@@ -1810,7 +2044,7 @@ EOM;
 			), /*where=*/ array('ID' => $post->ID) );
 		endif;
 	} /* SyndicatedPost::fix_post_modified_ts () */
-	
+
 	/**
 	 * SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
 	 * using the space for custom keys. The set of keys and values to add is
@@ -1833,7 +2067,7 @@ EOM;
 
 			if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
 				$postId = $post->ID;
-				
+
 				// Aggregated posts should NOT send out pingbacks.
 				// WordPress 2.1-2.2 claim you can tell them not to
 				// using $post_pingback, but they don't listen, so we
@@ -1842,21 +2076,21 @@ EOM;
 				DELETE FROM $wpdb->postmeta
 				WHERE post_id='$postId' AND meta_key='_pingme'
 				");
-	
+
 				foreach ( $this->post['meta'] as $key => $values ) :
-					$eKey = $wpdb->escape($key);
-	
+					$eKey = esc_sql($key);
+
 					// If this is an update, clear out the old
 					// values to avoid duplication.
 					$result = $wpdb->query("
 					DELETE FROM $wpdb->postmeta
 					WHERE post_id='$postId' AND meta_key='$eKey'
 					");
-					
+
 					// Allow for either a single value or an array
 					if (!is_array($values)) $values = array($values);
 					foreach ( $values as $value ) :
-					FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".FeedWordPress::val($value, /*no newlines=*/ true));
+					FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".MyPHP::val($value, /*no newlines=*/ true));
 						add_post_meta($postId, $key, $value, /*unique=*/ false);
 					endforeach;
 				endforeach;
@@ -1881,7 +2115,7 @@ EOM;
 		$source = $this->source();
 		$forbidden = apply_filters('feedwordpress_forbidden_author_names',
 			array('admin', 'administrator', 'www', 'root'));
-		
+
 		// Prepare the list of candidates to try for author name: name from
 		// feed, original source title (if any), immediate source title live
 		// from feed, subscription title, prettied version of feed homepage URL,
@@ -1896,10 +2130,10 @@ EOM;
 		if (strlen($this->link->homepage()) > 0) : $candidates[] = feedwordpress_display_url($this->link->homepage()); endif;
 		$candidates[] = feedwordpress_display_url($this->link->uri());
 		$candidates[] = 'unknown author';
-		
+
 		// Pick the first one that works from the list, screening against empty
 		// or forbidden names.
-		
+
 		$author = NULL;
 		while (is_null($author) and ($candidate = each($candidates))) :
 			if (!is_null($candidate['value'])
@@ -1908,11 +2142,11 @@ EOM;
 				$author = $candidate['value'];
 			endif;
 		endwhile;
-		
+
 		$email = (isset($a['email']) ? $a['email'] : NULL);
 		$authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
 
-		
+
 		$hostUrl = $this->link->homepage();
 		if (is_null($hostUrl) or (strlen($hostUrl) < 0)) :
 			$hostUrl = $this->link->uri();
@@ -1939,7 +2173,7 @@ EOM;
 			// Uniqueness will be guaranteed below if necessary.
 
 			$url = parse_url($hostUrl);
-			
+
 			$login = sanitize_user($url['host'], /*strict=*/ true);
 			if (strlen($login) < 1) :
 				// This isn't working. Frak it.
@@ -1952,11 +2186,11 @@ EOM;
 		$nice_author = sanitize_title($author);
 		$nice_author = apply_filters('pre_user_nicename', $nice_author);
 
-		$reg_author = $wpdb->escape(preg_quote($author));
-		$author = $wpdb->escape($author);
-		$email = $wpdb->escape($email);
-		$test_email = $wpdb->escape($test_email);
-		$authorUrl = $wpdb->escape($authorUrl);
+		$reg_author = esc_sql(preg_quote($author));
+		$author = esc_sql($author);
+		$email = esc_sql($email);
+		$test_email = esc_sql($test_email);
+		$authorUrl = esc_sql($authorUrl);
 
 		// Check for an existing author rule....
 		if (isset($this->link->settings['map authors']['name']['*'])) :
@@ -1974,7 +2208,7 @@ EOM;
 		// User name is filtered out
 		elseif ('filter' == $author_rule) :
 			$id = NULL;
-		
+
 		else :
 			// Check the database for an existing author record that might fit
 
@@ -1987,7 +2221,7 @@ EOM;
 				LENGTH(TRIM(LCASE(user_email))) > 0
 				AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
 			)");
-	
+
 			// If that fails, look for aliases in the user meta data table
 			if (is_null($id)) :
 				$id = $wpdb->get_var(
@@ -2032,7 +2266,7 @@ EOM;
 					if (isset($parts[1])) : $userdata['last_name'] = $parts[1]; endif;
 					$userdata['display_name'] = $author;
 					$userdata['role'] = 'contributor';
-					
+
 					do { // Keep trying until you get it right. Or until PHP crashes, I guess.
 						$id = wp_insert_user($userdata);
 						if (is_wp_error($id)) :
@@ -2046,10 +2280,10 @@ EOM;
 							case 'existing_user_email' :
 								// No disassemble!
 								$parts = explode('@', $userdata['user_email'], 2);
-								
+
 								// Add a random disambiguator as a gmail-style username extension
 								$parts[0] .= '+'.substr(md5(uniqid(microtime())), 0, 6);
-								
+
 								// Reassemble
 								$userdata['user_email'] = $parts[0].'@'.$parts[1];
 								break;
@@ -2066,7 +2300,7 @@ EOM;
 
 		if ($id) :
 			$this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
-			
+
 			// Multisite: Check whether the author has been recorded
 			// on *this* blog before. If not, put her down as a
 			// Contributor for *this* blog.
@@ -2075,128 +2309,21 @@ EOM;
 				$user->add_role('contributor');
 			endif;
 		endif;
-		return $id;	
+		return $id;
 	} /* function SyndicatedPost::author_id () */
 
 	/**
-	 * category_ids: look up (and create) category ids from a list of categories
+	 * category_ids: look up (and create) category ids from a list of
+	 * categories
 	 *
 	 * @param array $cats
 	 * @param string $unfamiliar_category
 	 * @param array|null $taxonomies
 	 * @return array
-	 */ 
+	 */
 	function category_ids ($cats, $unfamiliar_category = 'create', $taxonomies = NULL, $params = array()) {
-		$singleton = (isset($params['singleton']) ? $params['singleton'] : true);
-		$allowFilters = (isset($params['filters']) ? $params['filters'] : false);
-		
-		$catTax = 'category';
-
-		if (is_null($taxonomies)) :
-			$taxonomies = array('category');
-		endif;
-
-		// We need to normalize whitespace because (1) trailing
-		// whitespace can cause PHP and MySQL not to see eye to eye on
-		// VARCHAR comparisons for some versions of MySQL (cf.
-		// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
-		// because I doubt most people want to make a semantic
-		// distinction between 'Computers' and 'Computers  '
-		$cats = array_map('trim', $cats);
-
-		$terms = array();
-		foreach ($taxonomies as $tax) :
-			$terms[$tax] = array();
-		endforeach;
-		
-		foreach ($cats as $cat_name) :
-			if (preg_match('/^{([^#}]*)#([0-9]+)}$/', $cat_name, $backref)) :
-				$cat_id = (int) $backref[2];
-				$tax = $backref[1];
-				if (strlen($tax) < 1) :
-					$tax = $catTax;
-				endif;
-
-				$term = term_exists($cat_id, $tax);
-				if (!is_wp_error($term) and !!$term) :
-					if (!isset($terms[$tax])) :
-						$terms[$tax] = array();
-					endif;
-					$terms[$tax][] = $cat_id;
-				endif;
-			elseif (strlen($cat_name) > 0) :
-				$familiar = false;
-				foreach ($taxonomies as $tax) :
-					if ($tax!='category' or strtolower($cat_name)!='uncategorized') :
-						$term = term_exists($cat_name, $tax);
-						if (!is_wp_error($term) and !!$term) :
-							$familiar = true;
-	
-							if (is_array($term)) :
-								$term_id = (int) $term['term_id'];
-							else :
-								$term_id = (int) $term;
-							endif;
-							
-							if (!isset($terms[$tax])) :
-								$terms[$tax] = array();
-							endif;
-							$terms[$tax][] = $term_id;
-							break; // We're done here.
-						endif;
-					endif;
-				endforeach;
-				
-				if (!$familiar) :
-					if ('tag'==$unfamiliar_category) :
-						$unfamiliar_category = 'create:post_tag';
-					endif;
-					
-					if (preg_match('/^create(:(.*))?$/i', $unfamiliar_category, $ref)) :
-						$tax = $catTax; // Default
-						if (isset($ref[2]) and strlen($ref[2]) > 2) :
-							$tax = $ref[2];
-						endif;
-						$term = wp_insert_term($cat_name, $tax);
-						if (is_wp_error($term)) :
-							FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__, __FILE__);
-						else :
-							if (!isset($terms[$tax])) :
-								$terms[$tax] = array();
-							endif;
-							$terms[$tax][] = (int) $term['term_id'];
-						endif;
-					endif;
-				endif;
-			endif;
-		endforeach;
-
-		$filtersOn = $allowFilters;
-		if ($allowFilters) :
-			$filters = array_filter(
-				$this->link->setting('match/filter', 'match_filter', array()),
-				'remove_dummy_zero'
-			);
-			$filtersOn = ($filtersOn and is_array($filters) and (count($filters) > 0));
-		endif;
-		
-		// Check for filter conditions
-		foreach ($terms as $tax => $term_ids) :
-			if ($filtersOn
-			and (count($term_ids)==0)
-			and in_array($tax, $filters)) :
-				$terms = NULL; // Drop the post
-				break;
-			else :
-				$terms[$tax] = array_unique($term_ids);
-			endif;
-		endforeach;
-
-		if ($singleton and count($terms)==1) : // If we only searched one, just return the term IDs
-			$terms = end($terms);
-		endif;
-		return $terms;
-	} // function SyndicatedPost::category_ids ()
+		return $this->link->category_ids($this, $cats, $unfamiliar_category, $taxonomies, $params);
+	} /* SyndicatedPost::category_ids () */
 
 } /* class SyndicatedPost */
 
diff --git a/wp-content/plugins/feedwordpress/syndicatedpostterm.class.php b/wp-content/plugins/feedwordpress/syndicatedpostterm.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..01f61a95709a65f9dd7abc97f5b26039d805de7b
--- /dev/null
+++ b/wp-content/plugins/feedwordpress/syndicatedpostterm.class.php
@@ -0,0 +1,215 @@
+<?php
+class SyndicatedPostTerm {
+	private $term, $tax, $exists, $exists_in, $post;
+	
+	public function __construct ($term, $taxonomies, $post) {
+		$catTax = 'category';
+		
+		$this->post = $post;
+
+		// Default to these
+		$this->term = NULL;
+		$this->tax = NULL;
+		$this->exists = NULL;
+		$this->exists_in = NULL;
+		
+		if (preg_match('/^{([^#}]*)#([0-9]+)}$/', $term, $backref)) :
+			$cat_id = (int) $backref[2];
+			$tax = $backref[1];
+			if (strlen($tax) < 1) :
+				$tax = $catTax;
+			endif;
+
+			$aTerm = get_term($cat_id, $tax);
+			if (!is_wp_error($aTerm) and !!$aTerm) :
+				$this->exists = (array) $aTerm;
+				$this->exists_in = $this->exists['taxonomy'];
+				
+				$this->term = $this->exists['name'];
+				$this->tax = array($this->exists['taxonomy']);
+			endif;
+			
+		else :
+			$this->term = $term;
+			$this->tax = $taxonomies;
+
+			// Leave exists/exists_in empty until we search()
+			
+		endif;
+		
+		if (is_null($this->tax)) :
+			$this->tax = array($catTax);
+		endif;
+	} /* SyndicatedPostTerm constructor */
+	
+	public function is_familiar () {
+		$ex = $this->exists;
+		if (is_null($this->exists)) :
+			$ex = $this->search();
+		endif;
+
+		FeedWordPress::diagnostic(
+			'syndicated_posts:categories',
+			'Assigned category '.json_encode($this->term)
+			  .' by feed; checking '.json_encode($this->tax)
+			  . ' with result: '.json_encode($ex) 
+		);
+		return (!is_wp_error($ex) and !!$ex);
+	} /* SyndicatedPostTerm::familiar () */
+	
+	protected function search () {
+		
+		// Either this is a numbered term code, which supplies the ID
+		// and the taxonomy explicitly (e.g.: {category#2}; in which
+		// case we have set $this->tax to a unit array containing only
+		// the correct taxonomy, or else we have a term name and an
+		// ordered array of taxonomies to search for that term name. In
+		// either case, loop through and check each pair of term
+
+		foreach ($this->tax as $tax) :
+			
+			if (!$this->is_forbidden_in($tax)) :
+				
+				$found = $this->fetch_record_in($tax); 
+				if ($found) :
+					// When TRUE, the term has been found
+					// and is now stored in $this->exists
+					
+					// Save the taxonomy we found this in.
+					$this->exists_in = $tax;
+					
+					break;
+				endif;
+				
+			endif;
+			
+		endforeach;
+
+		FeedWordPress::diagnostic(
+			'syndicated_posts:categories:test',
+			'CHECKED familiarity of term '
+			  .json_encode($this->term)
+			  .' across '.json_encode($this->tax)
+			  . ' with result: '.json_encode($record) 
+		);
+		
+		return $this->exists;
+
+	} /* SyndicatedPostTerm::search () */
+	
+	protected function fetch_record_in ($tax) {
+		$record = term_exists($this->term, $tax);
+		
+		FeedWordPress::diagnostic(
+			'syndicated_posts:categories:test',
+			'CHECK existence of '.$tax.': '
+			  .json_encode($this->term)
+			  .' with result: '.json_encode($record) 
+		);
+		
+		$found = (!is_wp_error($record) and !!$record);
+		
+		if ($found) :
+			$this->exists = $record;
+		endif;
+		
+		return $found;
+	} /* SyndicatedPostTerm::fetch_record_in() */
+
+	public function is_forbidden_in ($tax = NULL) {
+		$forbid = false; // Innocent until proven guilty.
+		
+		$term = $this->term;
+		if (is_null($tax) and (count($this->tax) > 0)) :
+			$tax = $this->tax[0];
+		endif;
+		
+		if ($tax=='category' and strtolower($term)=='uncategorized') :
+			$forbid = true;
+		endif;
+		
+		// Run it through a filter.
+		return apply_filters('syndicated_post_forbidden_term', $forbid, $term, $tax, $this->post);
+	} /* SyndicatedPostTerm::is_forbidden_in () */
+
+	public function taxonomy () {
+		if (is_null($this->exists_in)) :
+			$this->search();
+		endif;
+		
+		return $this->exists_in;
+	} /* SyndicatedPostTerm::taxonomy () */
+	
+	public function id () {
+		$term_id = NULL;
+		
+		if (is_null($this->exists)) :
+			$this->search();
+		endif;
+		
+		$term = $this->exists;
+		if (is_array($term) or is_object($term)) :
+			
+			// For hash tables of any sort, use the term_id member
+			$term = (array) $term;
+			$term_id = intval($term['term_id']);
+			
+		elseif (is_numeric($term)) :
+		
+			// For a straight numeric response, just return number
+			$term_id = intval($term);
+			
+		endif;
+		
+		return $term_id;
+	} /* SyndicatedPostTerm::id () */
+
+	public function insert ($tax = NULL) {
+		$ret = NULL;
+		
+		if (is_null($tax)) :
+			if (count($this->tax) > 0) :
+				$tax = $this->tax[0];
+			endif;
+		endif;
+		
+		if (!$this->is_forbidden_in($tax)) :
+			$aTerm = wp_insert_term($this->term, $tax);
+			if (is_wp_error($aTerm)) :
+			
+				// If debug mode is ON, this will halt us here.
+				FeedWordPress::noncritical_bug(
+					'term insertion problem', array(
+						'term' => $this->term,
+						'result' => $aTerm,
+						'post' => $post, 
+						'this' => $this
+					), __LINE__, __FILE__
+				);
+			
+				// Otherwise, we'll continue & return NULL...
+				
+			else :
+				$this->exists = $aTerm;
+				$this->exists_in = $tax;
+				
+				$ret = $this->id();
+			endif;
+			
+			FeedWordPress::diagnostic(
+				'syndicated_posts:categories',
+				'CREATED unfamiliar '.$tax.': '.json_encode($this->term).' with result: '.json_encode($aTerm) 
+			);
+		else :
+			FeedWordPress::diagnostic(
+				'syndicated_posts:categories',
+				'Category: DID NOT CREATE unfamiliar '.$tax.': '.json_encode($this->term).':'
+				.' that '.$tax.' name is filtered out.'
+			);
+		endif;
+		
+		return $ret;
+	} /* SyndicatedPostTerm::insert () */
+
+} /* class SyndicatedPostTerm */
+
diff --git a/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php b/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
index fdb046cc537bb8d68da5f39c28bc4e1c18a159e2..d61784bdc95564085e136575733d4fffb7c685e9 100644
--- a/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
+++ b/wp-content/plugins/feedwordpress/syndicationdataqueries.class.php
@@ -1,10 +1,8 @@
 <?php
-define('FEEDWORDPRESS_OPTIMIZE_IN_CLAUSES', get_option('feedwordpress_optimize_in_clauses', false));
 
 class SyndicationDataQueries {
 	function SyndicationDataQueries () {
 		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);
@@ -17,44 +15,22 @@ 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_singular = true;	// Doesn't?
 		endif;
-		
+
 		$ff = $q->get('fields');
 		if ($ff == '_synfresh' or $ff == '_synfrom') :
 			$q->query_vars['cache_results'] = false; // Not suitable.
 		endif;
 	} /* SyndicationDataQueries::parse_query () */
-	
+
 	function pre_get_posts (&$q) {
-		// 
+		//
 	}
-	
+
 	function posts_request ($sql, &$query) {
 		if ($query->get('fields') == '_synfresh') :
 			FeedWordPress::diagnostic('feed_items:freshness:sql', "SQL: ".$sql);
@@ -67,7 +43,7 @@ class SyndicationDataQueries {
 		if ($guid = $query->get('guid')) :
 			if (strlen(trim($guid)) > 0) :
 				$seek = array($guid);
-				
+
 				// MD5 hashes
 				if (preg_match('/^[0-9a-f]{32}$/i', $guid)) :
 					$seek[] = SyndicatedPost::normalize_guid_prefix().$guid;
@@ -79,43 +55,43 @@ class SyndicationDataQueries {
 				if ($guid != $nGuid) :
 					$seek[] = $nGuid;
 				endif;
-				
+
 				// Escape to prevent frak-ups, injections, etc.
 				$seek = array_map('esc_sql', $seek);
-				
+
 				// Assemble
 				$guidMatch = "(guid = '".implode("') OR (guid = '", $seek)."')";
 				$search .= " AND ($guidMatch)";
 			endif;
 		endif;
-		
+
 		if ($query->get('fields')=='_synfresh') :
 			// 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')."') -- '"; 
+			$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)."')"; 
+			$where .= " AND ({$wpdb->posts}.post_status <> '".esc_sql($psn)."')";
 		endif;
-		
+
 		return $where;
 	} /* SyndicationDataQueries::post_where () */
-	
+
 	function posts_fields ($fields, &$query) {
 		global $wpdb;
 		if ($f = $query->get('fields')) :