Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 11890)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -111,6 +111,10 @@
 
 	die('0');
 	break;
+case 'oembed-cache' :
+	$return = ( $wp_embed->cache_oembed( $_GET['post'] ) ) ? '1' : '0';
+	die($return);
+	break;
 default :
 	do_action( 'wp_ajax_' . $_GET['action'] );
 	die('0');
Index: wp-admin/includes/schema.php
===================================================================
--- wp-admin/includes/schema.php	(revision 11890)
+++ wp-admin/includes/schema.php	(working copy)
@@ -305,7 +305,12 @@
 	'widget_rss' => array(),
 
 	// 2.8
-	'timezone_string' => ''
+	'timezone_string' => '',
+
+	// 2.9
+	'embed_autourls' => 0,
+	'embed_size_w' => '',
+	'embed_size_h' => 600,
 	);
 
 	// Set autoload to no for these options
Index: wp-admin/options-media.php
===================================================================
--- wp-admin/options-media.php	(revision 11890)
+++ wp-admin/options-media.php	(working copy)
@@ -44,7 +44,7 @@
 
 <tr valign="top">
 <th scope="row"><?php _e('Medium size') ?></th>
-<td><fieldset><legend class="screen-reader-text"><span><?php _e('Medium size') ?></span></legend>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e('Medium size'); ?></span></legend>
 <label for="medium_size_w"><?php _e('Max Width'); ?></label>
 <input name="medium_size_w" type="text" id="medium_size_w" value="<?php form_option('medium_size_w'); ?>" class="small-text" />
 <label for="medium_size_h"><?php _e('Max Height'); ?></label>
@@ -54,7 +54,7 @@
 
 <tr valign="top">
 <th scope="row"><?php _e('Large size') ?></th>
-<td><fieldset><legend class="screen-reader-text"><span><?php _e('Large size') ?></span></legend>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e('Large size'); ?></span></legend>
 <label for="large_size_w"><?php _e('Max Width'); ?></label>
 <input name="large_size_w" type="text" id="large_size_w" value="<?php form_option('large_size_w'); ?>" class="small-text" />
 <label for="large_size_h"><?php _e('Max Height'); ?></label>
@@ -65,6 +65,35 @@
 <?php do_settings_fields('media', 'default'); ?>
 </table>
 
+<h3><?php _e('Embeds') ?></h3>
+
+<table class="form-table">
+<tr valign="top">
+<th scope="row"><?php _e('Auto-embeds'); ?></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e('Attempt to automatically embed all URLs'); ?></span></legend>
+<label for="embed_autourls"><input name="embed_autourls" type="checkbox" id="embed_autourls" value="1" <?php checked( '1', get_option('embed_autourls') ); ?>/> <?php _e('Attempt to automatically embed all unlinked URLs'); ?></label>
+</fieldset></td>
+</tr>
+
+<tr valign="top">
+<th scope="row"><?php _e('Embed size'); ?></th>
+<td><fieldset><legend class="screen-reader-text"><span><?php _e('Embed size'); ?></span></legend>
+<label for="embed_size_w"><?php _e('Max Width'); ?></label>
+<input name="embed_size_w" type="text" id="embed_size_w" value="<?php
+	$width = get_option('embed_size_w');
+	if ( empty($width) ) {
+		$width = $content_width;
+	}
+	echo esc_attr($width);
+?>" class="small-text" />
+<label for="embed_size_h"><?php _e('Max Height'); ?></label>
+<input name="embed_size_h" type="text" id="embed_size_h" value="<?php form_option('embed_size_h'); ?>" class="small-text" />
+</fieldset></td>
+</tr>
+
+<?php do_settings_fields('media', 'embeds'); ?>
+</table>
+
 <?php do_settings_sections('media'); ?>
 
 <p class="submit">
Index: wp-admin/options.php
===================================================================
--- wp-admin/options.php	(revision 11890)
+++ wp-admin/options.php	(working copy)
@@ -25,7 +25,7 @@
 	'general' => array( 'blogname', 'blogdescription', 'admin_email', 'users_can_register', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'default_role', 'timezone_string' ),
 	'discussion' => array( 'default_pingback_flag', 'default_ping_status', 'default_comment_status', 'comments_notify', 'moderation_notify', 'comment_moderation', 'require_name_email', 'comment_whitelist', 'comment_max_links', 'moderation_keys', 'blacklist_keys', 'show_avatars', 'avatar_rating', 'avatar_default', 'close_comments_for_old_posts', 'close_comments_days_old', 'thread_comments', 'thread_comments_depth', 'page_comments', 'comments_per_page', 'default_comments_page', 'comment_order', 'comment_registration' ),
 	'misc' => array( 'use_linksupdate', 'uploads_use_yearmonth_folders', 'upload_path', 'upload_url_path' ),
-	'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type' ),
+	'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type', 'embed_autourls', 'embed_size_w', 'embed_size_h' ),
 	'privacy' => array( 'blog_public' ),
 	'reading' => array( 'posts_per_page', 'posts_per_rss', 'rss_use_excerpt', 'blog_charset', 'show_on_front', 'page_on_front', 'page_for_posts' ),
 	'writing' => array( 'default_post_edit_rows', 'use_smilies', 'ping_sites', 'mailserver_url', 'mailserver_port', 'mailserver_login', 'mailserver_pass', 'default_category', 'default_email_category', 'use_balanceTags', 'default_link_category', 'enable_app', 'enable_xmlrpc' ),
Index: wp-includes/class-oembed.php
===================================================================
--- wp-includes/class-oembed.php	(revision 0)
+++ wp-includes/class-oembed.php	(revision 0)
@@ -0,0 +1,174 @@
+<?php
+
+class WP_oEmbed {
+	var $providers = array();
+
+	function WP_oEmbed() {
+		return $this->__construct();
+	}
+
+	function __construct() {
+		// List out some popular sites, mainly ones that don't have discovery tags in their <head>
+		$this->providers = apply_filters( 'oembed_providers', array(
+			'http://*.flickr.com/*'       => 'http://www.flickr.com/services/oembed/',
+			'http://*.viddler.com/*'      => 'http://lab.viddler.com/services/oembed/',
+			'http://qik.com/*'            => 'http://qik.com/api/oembed.{format}',
+			'http://*.revision3.com/*'    => 'http://revision3.com/api/oembed/',
+			'http://www.hulu.com/watch/*' => 'http://www.hulu.com/api/oembed.{format}',
+			//'http://www.vimeo.com/*'      => 'http://www.vimeo.com/api/oembed.{format}', // Discovery tag supported, leave it commented to use as a discovery test
+
+			//'http://*.youtube.com/watch*' => 'http://oohembed.com/oohembed/',
+		) );
+	}
+
+	// Pass a URL, returns false or HTML result
+	function getHTML( $url, $args = '' ) {
+		$provider = false;
+
+		foreach ( $this->providers as $scheme => $providerurl ) { // Needs a better variable name
+
+			// Turn the asterisk-type provider URLs into regex
+			$regex = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $scheme ) ) ) . '#i';
+
+			if ( preg_match( $regex, $url ) ) {
+				$provider = str_replace( '{format}', 'json', $providerurl ); // JSON is easier to deal with than XML
+				break;
+			}
+		}
+
+		if ( !$provider )
+			$provider = $this->discover( $url );
+
+		if ( !$provider || false === $data = $this->fetch( $provider, $url, $args ) )
+			return false;
+
+		return apply_filters( 'oembed_output', $this->data2html( $data, $url ), $url, $args );
+	}
+
+	// Pass a URL, returns the oEmbed provider URL(s) if it can find them in the <head>
+	function discover( $url ) {
+		$providers = array();
+
+		// Fetch URL content
+		if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) {
+
+			// <link> types that contain oEmbed provider URLs
+			$linktypes = apply_filters( 'oembed_linktypes', array(
+				'application/json+oembed' => 'json',
+				'text/xml+oembed' => 'xml',
+				'application/xml+oembed' => 'xml', // Incorrect, but used by at least Vimeo
+			) );
+
+			// Strip <body>
+			$html = substr( $html, 0, stripos( $html, '</head>' ) );
+
+			// Do a quick check
+			$tagfound = false;
+			foreach ( $linktypes as $linktype => $format ) {
+				if ( stripos($html, $linktype) ) {
+					$tagfound = true;
+					break;
+				}
+			}
+
+			if ( $tagfound && preg_match_all( '/<link([^<>]+)>/i', $html, $links ) ) {
+				foreach ( $links[1] as $link ) {
+					$atts = shortcode_parse_atts( $link );
+
+					if ( !empty($atts['type']) && !empty($linktypes[$atts['type']]) && !empty($atts['href']) ) {
+						$providers[$linktypes[$atts['type']]] = $atts['href'];
+
+						// Stop here if it's JSON (that's all we need)
+						if ( 'json' == $linktypes[$atts['type']] )
+							break;
+					}
+				}
+			}
+		}
+
+		// JSON is preferred to XML
+		if ( !empty($providers['json']) )
+			return $providers['json'];
+		elseif ( !empty($providers['xml']) )
+			return $providers['xml'];
+		else
+			return false;
+	}
+
+	// Connects to an oEmbed provider and returns the result
+	function fetch( $provider, $url, $args = '' ) {
+		$args = wp_parse_args( $args, wp_embed_defaults() );
+
+		$provider = add_query_arg( 'format', 'json', $provider ); // JSON is easier to deal with than XML
+
+		$provider = add_query_arg( 'maxwidth', $args['width'], $provider );
+		$provider = add_query_arg( 'maxheight', $args['height'], $provider );
+		$provider = add_query_arg( 'url', urlencode($url), $provider );
+
+		if ( !$result = wp_remote_retrieve_body( wp_remote_get( $provider ) ) )
+			return false;
+
+		$data = false;
+
+		// JSON?
+		// Example: http://vimeo.com/api/oembed.json?url=http%3A%2F%2Fvimeo.com%2F240975
+		if ( $data = json_decode($result) ) {
+			return $data;
+		}
+
+		// Must be XML. Start out with the super-easy PHP5 functions.
+		// Example: http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F240975
+		elseif ( function_exists('simplexml_load_string') ) {
+			libxml_use_internal_errors('true');
+
+			$data = simplexml_load_string($result);
+
+			if ( is_object($data) )
+				return $data;
+		}
+
+		// Still must be XML, but no PHP5 support. Use PHP4 (ugh).
+		// Example: http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F240975
+		else {
+			// Code me!
+		}
+
+		return false;
+	}
+
+	// Takes a data set and returns the HTML
+	function data2html( $data, $url ) {
+		if ( !is_object($data) || empty($data->type) )
+			return false;
+
+		switch ( $data->type ) {
+			case 'photo':
+				if ( empty($data->url) || empty($data->width) || empty($data->height) )
+					return false;
+
+				$title = ( !empty($data->title) ) ? $data->title : '';
+				return '<img src="' . esc_attr( clean_url( $data->url ) ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" />';
+
+			case 'video':
+			case 'rich':
+				if ( is_feed() )
+					return 'CODE ME';
+				else
+					return ( !empty($data->html) ) ? $data->html : false;
+
+			case 'link':
+				return ( !empty($data->title) ) ? '<a href="' . clean_url($url) . '">' . esc_html($data->title) . '</a>' : false;
+		}
+
+		return false;
+	}
+}
+
+function &_wp_oembed_get_object() {
+	static $oembed;
+
+	if ( is_null($oembed) )
+		$oembed = new WP_oEmbed();
+
+	return $oembed;
+}
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 11890)
+++ wp-includes/formatting.php	(working copy)
@@ -1267,6 +1267,10 @@
 	return $ret;
 }
 
+function make_link($url) {
+	return apply_filters( 'make_link', '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a>' );
+}
+
 /**
  * Adds rel nofollow string to all HTML A elements in content.
  *
@@ -2352,6 +2356,8 @@
 		case 'medium_size_h':
 		case 'large_size_w':
 		case 'large_size_h':
+		case 'embed_size_w':
+		case 'embed_size_h':
 		case 'default_post_edit_rows':
 		case 'mailserver_port':
 		case 'comment_max_links':
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 11890)
+++ wp-includes/media.php	(working copy)
@@ -933,3 +933,321 @@
 
 	return false;
 }
+
+
+
+
+
+
+/*
+
+	EMBED TODO:
+
+	* oEmbed PHP4 XML
+	* Videos in feeds? It's currently just a link (handlers manually; WP_Embed class aborts before oEmbed).
+		Note that <object> and <embed> breaks feed validation last I looked, but perhaps we don't care?
+	* Phpdoc
+	* Auto-embed: Possible to modify regex to ignore inside of <a> tags? The hack that's currently used isn't that robust.
+	* Add more default handlers (the WP.com ones perhaps?)
+	* Should the stuff be wrapped in a div/span for styling purposes? Maybe leave it to a filter?
+	* Add a bunch more filters (oEmbed output, handler outputs, etc.). Add common filter to all output too. Suggestions welcome!
+
+*/
+
+
+// Embed class
+class WP_Embed {
+	var $handlers = array();
+	var $post_ID;
+	var $usecache = true;
+	var $linkifunknown = true;
+	var $autoembedcontent;
+
+	// PHP4 constructor
+	function WP_Embed() {
+		return $this->__construct();
+	}
+
+	// PHP5 constructor
+	function __construct() {
+		// After a post is saved, cache oEmbed items via AJAX
+		add_action( 'edit_form_advanced', array(&$this, 'maybe_run_ajax_cache') );
+
+		// Hack to get the [embed] shortcode to run before wpautop()
+		add_filter( 'the_content', array(&$this, 'runshortcode'), 9 );
+
+		// Attempts to embed all URLs in a post
+		if ( get_option('embed_autourls') )
+			add_filter( 'the_content', array(&$this, 'autoembed'), 12 );
+	}
+
+	// Run do_shortcode() with only the [embed] shortcode active
+	// This is so it can be run earlier than normal so the output can go through wpautop()
+	function runshortcode( $content ) {
+		global $shortcode_tags;
+
+		// Backup current registered shortcodes and clear them all out
+		$orig_shortcode_tags = $shortcode_tags;
+		remove_all_shortcodes();
+
+		add_shortcode( 'embed', array(&$this, 'shortcode') );
+
+		// Do the shortcode (only the [embed] one is registered)
+		$content = do_shortcode( $content );
+
+		// Put the original shortcodes back
+		$shortcode_tags = $orig_shortcode_tags;
+
+		return $content;
+	}
+
+	// If a post was saved, then cache oEmbed results via AJAX
+	function maybe_run_ajax_cache() {
+		global $post_ID;
+
+		if ( empty($post_ID) || empty($_GET['message']) || 1 != $_GET['message'] )
+			return;
+
+?>
+<script type="text/javascript">
+/* <![CDATA[ */
+	jQuery(document).ready(function($){
+		$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post_ID ); ?>");
+	});
+/* ]]> */
+</script>
+<?php
+	}
+
+	// Register an internal handler for WP_Embed::shortcode()
+	// wp_embed_register_handler() is a wrapper for this, so call that instead
+	// This should only be used for sites that don't support oEmbed
+	function register_handler( $id, $regex, $callback, $priority = 10 ) {
+		$this->handlers[$priority][$id] = array(
+			'regex'    => $regex,
+			'callback' => $callback,
+		);
+	}
+
+	// Remove a previously registered internal handler
+	// wp_embed_unregister_handler() is a wrapper for this, so call that instead
+	function unregister_handler( $id, $priority = 10 ) {
+		if ( isset($this->handlers[$priority][$id]) )
+			unset($this->handlers[$priority][$id]);
+	}
+
+	// [embed] shortcode handler
+	function shortcode( $attr, $url = '' ) {
+		global $post, $_wp_using_ext_object_cache;
+
+		if ( empty($url) )
+			return '';
+
+		$rawattr = $attr;
+		$attr = wp_parse_args( $attr, wp_embed_defaults() );
+
+		// Look for known internal handlers
+		ksort( $this->handlers );
+		foreach ( $this->handlers as $priority => $handlers ) {
+			foreach ( $handlers as $id => $handler ) {
+				if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
+					if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) )
+						return $return;
+				}
+			}
+		}
+
+		if ( is_feed() )
+			return $this->make_link( $url );
+
+		// Unknown URL format. Let oEmbed have a go.
+		if ( current_user_can('unfiltered_html') ) {
+			$post_ID = ( !empty($post->ID) ) ? $post->ID : null;
+			if ( !empty($this->post_ID) ) // Potentially set by WP_Embed::cache_oembed()
+				$post_ID = $this->post_ID;
+
+			// Check for a cached result (stored in the post meta)
+			if ( $post_ID ) {
+				$cachekey = '_oembed_' . md5( $url . implode( '|', $attr ) );
+
+				if ( $this->usecache ) {
+					$cache = ( $_wp_using_ext_object_cache ) ? wp_cache_get( "{$post_ID}_{$cachekey}", 'oembed' ) : get_post_meta( $post_ID, $cachekey, true );
+
+					// Failures are cached
+					if ( '{{unknown}}' === $cache )
+						return $this->make_link( $url );
+
+					if ( !empty($cache) )
+						return $cache;
+				}
+			}
+
+			$html = wp_oembed_get( $url, $attr );
+
+			// Cache the result
+			if ( $post_ID ) {
+				$cache = ( $html ) ? $html : '{{unknown}}';
+
+				if ( $_wp_using_ext_object_cache )
+					wp_cache_set( "{$post_ID}_{$cachekey}", $cache, 'oembed' );
+				else
+					update_post_meta( $post_ID, $cachekey, $cache );
+			}
+
+			if ( $html )
+				return $html;
+		}
+
+		// Still unknown
+		return $this->make_link( $url );
+	}
+
+	// Cache all oEmbed results for the given post ID to it's post meta
+	function cache_oembed( $post_ID ) {
+		$post = get_post( $post_ID );
+
+		// post_type check is incase of "save_post" usage
+		if ( empty($post->ID) || !in_array( $post->post_type, array( 'post', 'page' ) ) )
+			return;
+
+		// Dump existing caches
+		$post_metas = get_post_custom_keys( $post->ID );
+		foreach( $post_metas as $post_meta_key ) {
+			if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) )
+				delete_post_meta( $post->ID, $post_meta_key );
+		}
+
+		// Trigger a caching
+		if ( !empty($post->post_content) ) {
+			$this->post_ID = $post->ID;
+			$this->usecache = false;
+
+			$content = $this->runshortcode( $post->post_content );
+			if ( get_option('embed_autourls') )
+				$this->autoembed( $content );
+
+			$this->usecache = true;
+		}
+	}
+
+	// Helper function that conditionally makes a HTML link for the passed URL
+	function make_link( $url ) {
+		return ( $this->linkifunknown ) ? make_link($url) : $url;
+	}
+
+	// With help from WP_Emebed::_autoembed(), this attempts to convert all URLs in a post into embeds
+	function autoembed( $content ) {
+		// Stolen from make_clickable()
+		$content = ' ' . $content;
+		$this->autoembedcontent = $content;
+		$content = preg_replace_callback( '#(?<=[\s>])(\()?([\w]+?://(?:[\w\\x80-\\xff\#$%&~/\-=?@\[\](+]|[.,;:](?![\s<])|(?(1)\)(?![\s<])|\)))+)#is', array(&$this, '_autoembed'), $content );
+		$this->autoembedcontent = null;
+		return trim( $content );
+	}
+
+	// A helper function for WP_Embed::autoembed() that converts a URL into an embed
+	function _autoembed( $match ) {
+		$return = $match[0];
+
+		// If the match was not directly before </a> (i.e. it's not the click text of a link),
+		// then process it using the shortcode handler
+		if ( !strpos( $this->autoembedcontent, $match[0] . '</a>' ) ) { // This isn't perfect, ex: the URL is in the content twice
+			$oldval = $this->linkifunknown;
+			$this->linkifunknown = false;
+			$return = $this->shortcode( array(), $match[2] );
+			$this->linkifunknown = $oldval;
+		}
+
+		return $match[1] . $return;
+	}
+}
+$wp_embed = new WP_Embed();
+
+
+// Wrapper to register a new hander for a URL format inside [embed]
+function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) {
+	global $wp_embed;
+	return $wp_embed->register_handler( $id, $regex, $callback, $priority );
+}
+
+// Wrapper to unregister a new hander for a URL format inside [embed]
+function wp_embed_unregister_handler( $id, $priority = 10 ) {
+	global $wp_embed;
+	return $wp_embed->unregister_handler( $id, $priority );
+}
+
+// A helper function to return some default attributes for embeds
+function wp_embed_defaults() {
+	if ( !empty($GLOBALS['content_width']) )
+		$theme_width = (int) $GLOBALS['content_width'];
+
+	if ( !($width = get_option('embed_size_w')) && !empty($theme_width) )
+		$width = $theme_width;
+
+	if ( !$width )
+		$width = 500;
+
+	return apply_filters( 'embed_defaults', array(
+		'width' => $width,
+		'height' => 700,
+	) );
+}
+
+// Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height
+function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) {
+	return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height );
+}
+
+// Wrapper to load the WP_oEmbed class and use it to get some HTML
+function wp_oembed_get( $url, $args = '' ) {
+	require_once( 'class-oembed.php' );
+	$oembed_object = _wp_oembed_get_object();
+	return $oembed_object->getHTML( $url, $args );
+}
+
+
+// YouTube internal handler (no oEmbed support)
+wp_embed_register_handler( 'youtube', '#http://(www.youtube|youtube|[A-Za-z]{2}.youtube)\.com/(watch\?v=|w/\?v=|\?v=)([\w-]+)(.*?)#i', 'wp_embed_handler_youtube' );
+function wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) {
+	if ( is_feed() )
+		return "<a href='" . get_permalink() . "'><img src='http://img.youtube.com/vi/{$matches[3]}/0.jpg' alt='" . __('YouTube') . "' /></a>";
+
+	// If the user supplied a fixed width AND height, use it
+	if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) {
+		$width  = (int) $rawattr['width'];
+		$height = (int) $rawattr['height'];
+	} else {
+		list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] );
+	}
+
+	return apply_filters( 'embed_youtube', "<object width='$width' height='$height'><param name='movie' value='http://www.youtube.com/v/{$matches[3]}&amp;hl=en&amp;fs=1'></param><param name='allowFullScreen' value='true'></param><param name='allowscriptaccess' value='always'></param><embed src='http://www.youtube.com/v/{$matches[3]}&amp;hl=en&amp;fs=1' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' width='$width' height='$height'></embed></object>", $matches, $attr, $url, $rawattr );
+}
+
+
+// PollDaddy internal handler (no oEmbed support)
+wp_embed_register_handler( 'polldaddy', '#http://answers.polldaddy.com/poll/(\d+)(.*?)#i', 'wp_embed_handler_polldaddy' );
+function wp_embed_handler_polldaddy( $matches, $attr, $url, $rawattr ) {
+	if ( is_feed() )
+		return make_link($url);
+
+	return apply_filters( 'embed_polldaddy', '<script type="text/javascript" src="http://s3.polldaddy.com/p/' . esc_attr($matches[1]) . '"></script>', $matches, $attr, $url, $rawattr );
+}
+
+
+// DailyMotion internal handler (no oEmbed support)
+// Example: http://www.dailymotion.com/video/x4cqyl_ferrari-p45-owner-exclusive-intervi_auto
+wp_embed_register_handler( 'dailymotion', '#http://(www.dailymotion|dailymotion)\.com/(.+)/([0-9a-zA-Z]+)\_(.*?)#i', 'wp_embed_handler_dailymotion' );
+function wp_embed_handler_dailymotion( $matches, $attr, $url, $rawattr ) {
+	if ( is_feed() )
+		return make_link($url);
+
+	// If the user supplied a fixed width AND height, use it
+	if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) {
+		$width  = (int) $rawattr['width'];
+		$height = (int) $rawattr['height'];
+	} else {
+		list( $width, $height ) = wp_expand_dimensions( 480, 291, $attr['width'], $attr['height'] );
+	}
+
+	return apply_filters( 'embed_dailymotion', "<object width='$width' height='$height' classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000'><param name='movie' value='http://www.dailymotion.com/swf/{$matches[3]}&amp;related=0'></param><param name='allowFullScreen' value='true'></param><param name='allowScriptAccess' value='always'></param><embed src='http://www.dailymotion.com/swf/{$matches[3]}&amp;related=0' type='application/x-shockwave-flash' width='$width' height='$height' allowFullScreen='true' allowScriptAccess='always'></embed></object>", $matches, $attr, $url, $rawattr );;
+}
