diff -urpN contrib/emaudio/changelog.txt contrib/emaudio/changelog.txt
--- contrib/emaudio/changelog.txt	2008-12-09 16:13:48.000000000 -0600
+++ contrib/emaudio/changelog.txt	2008-11-19 21:49:34.000000000 -0600
@@ -1,8 +1,4 @@
-/* $Id: changelog.txt,v 1.1.4.12 2008/12/09 22:13:48 alexua Exp $ */
-
-December 2008
-=============
- * #337997 - Got emaudio up and running (alexua and moonray)
+/* $Id: changelog.txt,v 1.1.4.11 2008/11/20 03:49:34 aaron Exp $ */
 
 November 2008
 =============
diff -urpN contrib/emaudio/emaudio.info contrib/emaudio/emaudio.info
--- contrib/emaudio/emaudio.info	2008-12-09 16:13:48.000000000 -0600
+++ contrib/emaudio/emaudio.info	2008-10-08 11:39:08.000000000 -0600
@@ -1,7 +1,7 @@
-; $Id: emaudio.info,v 1.1.4.7 2008/12/09 22:13:48 alexua Exp $
+; $Id: emaudio.info,v 1.1.4.6 2008/10/08 17:39:08 alexua Exp $
 
 name = Embedded Audio Field
 description = Defines a field type for displaying third party music, podcasts, and other audio, such as podOmatic and Odeo.
-core = 6.x
+core = 5.x
 dependencies[] = emfield
 package = CCK
diff -urpN contrib/emaudio/emaudio.install contrib/emaudio/emaudio.install
--- contrib/emaudio/emaudio.install	2008-12-09 17:31:28.000000000 -0600
+++ contrib/emaudio/emaudio.install	2008-07-25 05:45:50.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: emaudio.install,v 1.1.4.7 2008/12/09 23:31:28 alexua Exp $
+// $Id: emaudio.install,v 1.1.4.6 2008/07/25 11:45:50 alexua Exp $
 
 /**
  * @file
@@ -10,7 +10,6 @@
  * Implementation of hook_install().
  */
 function emaudio_install() {
-  drupal_load('module', 'content');
   content_notify('install', 'emaudio');
 }
 
@@ -18,7 +17,6 @@ function emaudio_install() {
  * Implementation of hook_uninstall().
  */
 function emaudio_uninstall() {
-  drupal_load('module', 'content');
   content_notify('uninstall', 'emaudio');
 }
 
@@ -26,7 +24,6 @@ function emaudio_uninstall() {
  * Implementation of hook_enable().
  */
 function emaudio_enable() {
-  drupal_load('module', 'content');
   content_notify('enable', 'emaudio');
 }
 
@@ -34,7 +31,6 @@ function emaudio_enable() {
  * Implementation of hook_disable().
  */
 function emaudio_disable() {
-  drupal_load('module', 'content');
   content_notify('disable', 'emaudio');
 }
 
diff -urpN contrib/emaudio/providers/CVS/Entries contrib/emaudio/providers/CVS/Entries
--- contrib/emaudio/providers/CVS/Entries	2008-12-15 19:01:25.310000000 -0600
+++ contrib/emaudio/providers/CVS/Entries	2008-12-03 19:56:17.468055200 -0600
@@ -1,4 +1,4 @@
-/odeo.inc/1.1.4.6/Tue Dec  9 22:13:49 2008//TDRUPAL-6--1
-/podcastalley.inc/1.1.4.6/Tue Dec  9 22:13:49 2008//TDRUPAL-6--1
-/podomatic.inc/1.1.4.8/Tue Dec  9 22:13:49 2008//TDRUPAL-6--1
+/odeo.inc/1.1.4.5/Wed Oct  8 17:39:08 2008//TDRUPAL-6--1
+/podcastalley.inc/1.1.4.5/Wed Oct  8 17:39:08 2008//TDRUPAL-6--1
+/podomatic.inc/1.1.4.7/Sat Oct 11 19:05:26 2008//TDRUPAL-6--1
 D
diff -urpN contrib/emaudio/providers/odeo.inc contrib/emaudio/providers/odeo.inc
--- contrib/emaudio/providers/odeo.inc	2008-12-09 16:13:49.000000000 -0600
+++ contrib/emaudio/providers/odeo.inc	2008-10-08 11:39:08.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: odeo.inc,v 1.1.4.6 2008/12/09 22:13:49 alexua Exp $
+// $Id: odeo.inc,v 1.1.4.5 2008/10/08 17:39:08 alexua Exp $
 
 /**
  * @file
@@ -166,15 +166,3 @@ function emaudio_odeo_preview($embed, $w
 
   return $output;
 }
-
-/**
- * Implementation of hook_emfield_subtheme.
- */
-function emaudio_odeo_emfield_subtheme() {
-  return array (
-    'emaudio_odeo_flash'  => array(
-            'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
-            'file' => 'providers/odeo.inc'
-        )
-    );
-}
diff -urpN contrib/emaudio/providers/podcastalley.inc contrib/emaudio/providers/podcastalley.inc
--- contrib/emaudio/providers/podcastalley.inc	2008-12-09 16:13:49.000000000 -0600
+++ contrib/emaudio/providers/podcastalley.inc	2008-10-08 11:39:08.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: podcastalley.inc,v 1.1.4.6 2008/12/09 22:13:49 alexua Exp $
+// $Id: podcastalley.inc,v 1.1.4.5 2008/10/08 17:39:08 alexua Exp $
 
 /**
  * @file
@@ -165,15 +165,3 @@ function emaudio_podcastalley_preview($e
 
   return $output;
 }
-
-/**
- * Implementation of hook_emfield_subtheme.
- */
-function emaudio_podcastalley_emfield_subtheme() {
-  return array (
-    'emaudio_podcastalley_flash'  => array(
-            'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
-            'file' => 'providers/podcastalley.inc'
-        )
-    );
-}
\ No newline at end of file
diff -urpN contrib/emaudio/providers/podomatic.inc contrib/emaudio/providers/podomatic.inc
--- contrib/emaudio/providers/podomatic.inc	2008-12-09 16:13:49.000000000 -0600
+++ contrib/emaudio/providers/podomatic.inc	2008-10-11 13:05:26.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: podomatic.inc,v 1.1.4.8 2008/12/09 22:13:49 alexua Exp $
+// $Id: podomatic.inc,v 1.1.4.7 2008/10/11 19:05:26 alexua Exp $
 
 /**
  * @file
@@ -83,17 +83,15 @@ function emaudio_podomatic_embedded_link
  * the embedded flash displaying the podomatic audio
  */
  
-function theme_emaudio_podomatic_flash($embed, $width, $height, $autoplay) {
+function theme_emaudio_podomatic_flash($code, $width, $height, $field, $item, $autoplay, $flv, $thumbnail, $options = array()) {
   // <object width="320" height="315"><param name="movie" value="http://www.podOmatic.com/flash/flashcatcher.swf"></param><embed type="application/x-shockwave-flash" src="http://www.podOmatic.com/flash/flashcatcher.swf" width="320" height="315" flashvars="playlist_url=http://funkylondon.podOmatic.com/xspf.xspf" ></embed></object><br /><a href="http://www.podOmatic.com/podcast/embed/funkylondon" style="text-decoration: none"><font size="1" face="Verdana, Arial, Helvetica, sans-serif" color="#0033ff"><strong>Click here to get your own player.</strong></font></a><br><br>
 
-   if ($embed) {
-   /*    
-    if ($autoplay) {
+  if ($code) {
+/*    if ($autoplay) {
       $autoplay_value = '&autostart=1';
-    }
-	*/
-    $output .= "
-    <object type=\"application/x-shockwave-flash\" height=\"$height\" width=\"$width\" data=\"http://www.podOmatic.com/flash/flashcatcher.swf\" id=\"audioPlayback\">
+    }*/
+    $output .= 
+    '<object type=\"application/x-shockwave-flash\" height=\"$height\" width=\"$width\" data=\"http://www.podOmatic.com/flash/flashcatcher.swf\" id=\"audioPlayback\">
       <param name=\"movie\" value=\"http://www.podOmatic.com/flash/flashcatcher.swf\">
       <param name=\"allowScriptAcess\" value=\"sameDomain\">
       <param name=\"quality\" value=\"best\">
@@ -102,8 +100,7 @@ function theme_emaudio_podomatic_flash($
       <param name=\"salign\" value=\"TL\">
       <param name=\"FlashVars\" value=\"playlist_url=http://". $embed .".podOmatic.com/xspf.xspf\" />
       <param name=\"wmode\" value=\"transparent\" />
-    </object>
-	\n";
+    </object>\n';
   }
   return $output;
 }
@@ -168,11 +165,12 @@ function emaudio_podomatic_preview($embe
 /**
  * Implementation of hook_emfield_subtheme.
  */
-function emaudio_podomatic_emfield_subtheme() {
+function emaudio_podomatic_subtheme() {
   return array (
     'emaudio_podomatic_flash'  => array(
             'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
             'file' => 'providers/podomatic.inc'
         )
     );
-}
\ No newline at end of file
+}
+
diff -urpN contrib/emfield_generic/README.txt contrib/emfield_generic/README.txt
--- contrib/emfield_generic/README.txt	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/README.txt	2008-11-23 12:00:42.000000000 -0600
@@ -0,0 +1,18 @@
+/* $Id: $ */
+
+/***********/
+ Embedded Generic Field
+/***********/
+
+Author:enzo - Eduardo Garcia
+Development Began 2008-10-21
+
+Requires: Drupal 6, Content (CCK), emfield
+Optional: Views
+
+This extensible module will create a field for node content types that can be used to display video,audio or images
+from various third party providers. When entering the content, the user will simply paste the URL or embed code
+of the video,audio or image and the module will automatically determine which content provider is being used. When displaying
+the video,audio or image the proper embedding format will be used.
+
+Questions can be directed to enzo@anexusit.com 
diff -urpN contrib/emfield_generic/changelog.txt contrib/emfield_generic/changelog.txt
--- contrib/emfield_generic/changelog.txt	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/changelog.txt	2008-11-23 12:00:44.000000000 -0600
@@ -0,0 +1,180 @@
+/* $Id: changelog.txt,v 1.1.2.7 2008/11/12 17:54:43 aaron Exp $ */
+
+November 2008
+-------------
+ * #333365/chrono325: Allow Emvideo to play Google Video links from RSS feeds (aaron/chrono325).
+
+September 2008
+--------------
+ * Comment some code in upgrade to d6 that might cause a complaint (aaron).
+ * Begin upgrade from d5 to d6 (aaron).
+ * Add drupal_load('module', 'content'); to install/uninstall process (aaron).
+ * Placeholder function to upgrade from video_cck (aaron).
+
+August 2008
+-----------
+ * Add support for swfobject to youtube, taking swfobject_api into account (aaron).
+#297760 - BenKewell fixed thickbox theming issues
+
+2008-07-18
+----------
+Changed name from video_cck to emvideo to comply with new naming standards.
+
+2008-06-23
+----------
+ * Add TODO for thumbnails for spike.tv (aaron).
+ * Add placeholder ifilm.inc to help with updates after ifilm-spike switch (aaron).
+ * Move ifilm.inc to spike.inc (aaron).
+
+2008-06-22
+----------
+ * Move theme functions to video_cck.theme.inc (aaron).
+ * Implement hook_theme (aaron).
+
+2008-05-30
+widget info
+'callbacks' => array('tables' => CONTENT_CALLBACK_DEFAULT, 'arguments' => CONTENT_CALLBACK_DEFAULT, ),
+allow w/h (and other) overrides to thumbnails and other formatters
+case 'database columns': return module_invoke('emfield', 'field_columns', $field);
+content_notify in .install files
+
+2008-05-29
+implement hook_content_is_empty
+
+2008-05-23
+#261999 - chirale fixed XHTML validation errors in YouTube.inc
+
+2008-05-10
+#208963 - robomalo + darrenmUK  added Vimeo support
+#249255 - ekes added MRSS support to multiple files
+#170799 - ekes added support for google video URLs from '.com.au', 'co.uk' etc.
+#199189 - vsnguyen + Rysk added support for Veoh
+#253389 - Rysk updated Veoh support + added providers guba and imeem
+
+2008-04-30
+change 'thumbnail' text on widget settings form
+
+2008-04-29
+dailymotion thumbnails
+
+2008-04-07
+support for blip.tv's new player
+added $options=array() to themes for future expansion of options
+
+2008-03-14
+#216796/jhedstrom - extended brightcove support
+ifilm.inc was changed to spike.inc to reflect the change in site name and url, and the provider file was fixed.
+
+2008-03-21
+add support for last.fm videos
+
+2008-02-22
+#217339/fjen fix myspace thumbnails
+myspace now is also myspacetv.com
+fix myspace to use object instead of embed
+
+2008-02-17
+removed goleft support -- no user contributed videos, and no thumbnails.
+add provider views handlers
+
+2008-02-16
+#178299/dalin - modified patch to allow filter by video present
+
+2008-02-09
+#211529 - MrKatz fixed the revver url
+
+2008-02-07
+support for goleft.tv
+
+2008-01-06
+grab random youtube thumbnail
+#200435/jhedstrom - default thumbnail when video thumbnail not available
+
+2008-01-04
+remove bliptv debugging printout on node submission
+dailymotion autoplay support
+added dailymotion support
+#181095:alley youtube thumbnails w/o api or requests
+#177593:anonymous5190 parse new google embed code
+add <param name=\"wmode\" value=\"transparent\" /> to youtube & google
+integrate with colorpicker module; add border options for youtube
+#201855;jhedstrom add color options for youtube player
+#184980 cache youtube thumbnails (cache was accidentally left off while debugging)
+#173780;alexua - fix 'Cannot find server or DNS Error' in ie6 for youtube
+add support for emthumb, so that custom thumbnails may be stored and displayed for videos
+
+2007-12-07
+change url for brightcove to .tv
+
+2007-10-17
+#179454 fix youtube's new &rel=1 url structure
+
+2007-09-12
+better support for blip.tv's rss (allow overriding type given)
+
+2007-09-06
+added rss support for blip.tv
+added data versioning to allow nodes to save more data, but respect older nodes
+
+2007-07-27
+ignore case when matching video url's
+don't show 'show video' on thumbnails if no embed code value
+
+2007-06-27
+clean old variables during install, sorry, new update again.
+fix install -- change ncck to emfield
+
+2007-06-19
+add update code to change variables and remove old menu item
+require dependency on ncck
+
+2007-06-09
+fixed embed pasting for blip.tv
+added support for blip.tv
+added serialized data array for extra provider-specific node-level data
+added thumbnail width/height
+
+2007-06-07
+created 'supported features' sections of settings page
+added support for 'related videos' for youtube
+
+2007-06-05
+add 'embed code' filter for views -- note: run update.php to see it
+increase maxlength on embed textfield for better embed code support
+added support for ifilm
+
+2007-06-03
+began support for autoplay (starting with youtube)
+added support for sevenload
+
+2007-04-25
+added support for brightcove videos. thanks, recidive!
+
+2007-04-12
+text link for thumbnail when thumbnail not available
+link thumbnails to node view
+fix youtube thumbnails
+
+2007-04-04
+some code documentation
+
+2007-03-24
+simplified api
+added video link hook to api
+
+2007-03-23
+begin bliptv, but waiting on email re. api
+add google, metacafe, myspace, revver, jumpcut
+change structure to use .inc files for 3rd party providers
+describe api in readme
+
+2007-03-22
+fix bug w/ blank video when no embed code entered
+call youtube api to fetch thumbnails
+parse video code from the YouTube video URL
+
+2007-03-14
+branch to video_cck for more generic video integration
+
+2007-02-23
+began development for YouTube integration; release as youtube_cck
diff -urpN contrib/emfield_generic/emaudio.theme.inc contrib/emfield_generic/emaudio.theme.inc
--- contrib/emfield_generic/emaudio.theme.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emaudio.theme.inc	2008-11-23 16:36:06.000000000 -0600
@@ -0,0 +1,109 @@
+<?php
+// $Id: emaudio.theme.inc,v 1.1.2.4 2008/11/20 03:49:34 aaron Exp $
+
+/**
+ * @file
+ * This defines the various theme functions for Embedded Audio Field (emaudio).
+ */
+
+function theme_emaudio_audio_embed($field, $item, $formatter, $node, $options = array()) {
+  /*
+    Note you can use this in node.tpl.php, substituting the proper field type:
+    $field_type = 'field_audio';
+    $system_types = _content_type_info();
+    $field = $system_types['fields'][$field_type];
+    $field['widget'] = $system_types['content types'][$node->type]['fields'][$field_type]['widget'];
+    print theme('emaudio_audio_embed', $field, $node->{$field_type}[0], 'emaudio_embed', $node);
+   */
+  if ($item['value'] && $item['provider']) {
+    $output = drupal_get_form('emaudio_embed_form', $field, $item, $formatter, $node, $options);
+  }
+
+  return $output;
+}
+
+function theme_emaudio_audio_thumbnail($field, $item, $formatter, $node, $no_link = FALSE, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    // If we've set $options['thumbnail_url'], then we'll just use that.
+    // Otherwise, if we have emthumb installed, then give it a chance to override our thumbnail
+    $thumbnail_url = $options['thumbnail_url'] ? $options['thumbnail_url'] : module_invoke('emthumb', 'thumbnail_url', $item);
+
+    // if we don't have a custom thumbnail, then see if the provider gives us a thumbnail
+    $thumbnail_url = $thumbnail_url ? $thumbnail_url : _emfield_generic_include_invoke('emfield_generic', 'emaudio', $item['provider'], 'thumbnail', $field, $item, $formatter, $node, $width, $height, $options);
+
+    // If we still don't have a thumbnail, then apply a default thumbnail, if it exists.
+    if (!$thumbnail_url) {
+      $default_thumbnail_url = $field['widget']['thumbnail_default_path'] ? $field['widget']['thumbnail_default_path'] : variable_get('emaudio_default_thumbnail_path', NULL);
+
+      if ($default_thumbnail_url) {
+        $thumbnail_url = base_path() . $default_thumbnail_url;
+      }
+    }
+  }
+  else {
+    // Seems to be an unknown audio. Apply a default thumbnail, if it exists.
+    if (!$thumbnail_url) {
+      $default_thumbnail_url = $field['widget']['thumbnail_default_path'] ? $field['widget']['thumbnail_default_path'] : variable_get('emaudio_default_thumbnail_path', NULL);
+      if ($default_thumbnail_url) {
+        $thumbnail_url = base_path() . $default_thumbnail_url;
+      }
+    }
+  }
+
+  $link_url = isset($options['link_url']) ? $options['link_url'] : 'node/'. $node->nid;
+  $link_title = isset($options['link_title']) ? $options['link_title'] : t('See audio');
+  $image_title = isset($options['image_title']) ? $options['image_title'] : $link_title;
+  $image_alt = isset($options['image_alt']) ? $options['image_alt'] : $link_title;
+
+  if ($thumbnail_url) {
+    $width = isset($options['width']) ? $options['width'] : NULL;
+    $width = isset($width) ? $width : ($field['widget']['thumbnail_width'] ? $field['widget']['thumbnail_width'] : variable_get('emaudio_default_thumbnail_width', EMAUDIO_DEFAULT_THUMBNAIL_WIDTH));
+    $height = isset($options['height']) ? $options['height'] : NULL;
+    $height = isset($height) ? $height : ($field['widget']['thumbnail_height'] ? $field['widget']['thumbnail_height'] : variable_get('emaudio_default_thumbnail_height', emaudio_DEFAULT_THUMBNAIL_HEIGHT));
+    if ($no_link) { //thickbox requires the thumbnail returned without the link
+      $output = '<img src="'. $thumbnail_url .'" width="'. $width  .'" height="'. $height  .'" alt="'. $image_alt .'" title="'. $image_title .'" />';
+    }
+    else {
+      $output = l('<img src="'. $thumbnail_url .'" width="'. $width  .'" height="'. $height  .'" alt="'. $image_alt .'" title="'. $image_title .'" />', $link_url, array('html'=> true));
+    }
+  }
+  else {
+     // if all else fails, then just print a 'see audio' link.
+    if ($no_link) {
+      $output = ''; //thickbox won't work without a thumbnail
+    }
+    else {
+      $output = l($link_title, $link_url);
+    }
+  }
+
+  return $output;
+}
+
+function theme_emaudio_audio_audio($field, $item, $formatter, $node, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    $embed = $item['value'];
+    $width = isset($options['width']) ? $options['width'] : (isset($field['widget']['audio_width']) ? $field['widget']['audio_width'] : variable_get('emaudio_default_audio_width', EMAUDIO_DEFAULT_AUDIO_WIDTH));
+    $height = isset($options['height']) ? $options['height'] : (isset($field['widget']['audio_height']) ? $field['widget']['audio_height'] : variable_get('emaudio_default_audio_height', EMAUDIO_DEFAULT_AUDIO_HEIGHT));
+    $autoplay = isset($options['autoplay']) ? $options['autoplay'] : $field['widget']['audio_autoplay'];
+    $output = _emfield_generic_include_invoke('emfield_generic', 'emaudio', $item['provider'], 'audio', $embed, $width, $height, $field, $item, $autoplay, $options);
+  }
+
+  return $output;
+}
+
+function theme_emaudio_default($field, $item, $formatter, $node, $options = array()) {
+  return theme('emaudio_audio_audio', $field, $item, $formatter, $node, $options);
+}
+
+function theme_emaudio_audio_preview($field, $item, $formatter, $node, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    $embed = $item['value'];
+    $width = isset($options['width']) ? $options['width'] : (isset($field['widget']['audio_width']) ? $field['widget']['audio_width'] : variable_get('emaudio_default_audio_width', EMAUDIO_DEFAULT_PREVIEW_WIDTH));
+    $height = isset($options['height']) ? $options['height'] : (isset($field['widget']['audio_height']) ? $field['widget']['audio_height'] : variable_get('emaudio_default_audio_height', EMAUDIO_DEFAULT_PREVIEW_HEIGHT));
+    $autoplay = isset($options['autoplay']) ? $options['autoplay'] : $field['widget']['audio_autoplay'];
+    $output = _emfield_generic_include_invoke('emfield_generic', 'emaudio', $item['provider'], 'preview', $embed, $width, $height, $field, $item, $autoplay, $options);
+  }
+
+  return $output;
+}
\ No newline at end of file
diff -urpN contrib/emfield_generic/emfield_generic.info contrib/emfield_generic/emfield_generic.info
--- contrib/emfield_generic/emfield_generic.info	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emfield_generic.info	2008-11-23 12:00:42.000000000 -0600
@@ -0,0 +1,15 @@
+; $Id: emvideo.info,v 1.1.2.2 2008/07/25 11:45:51 alexua Exp $
+
+name = Embedded Generic Field
+description = Defines a field type for displaying third party providers for video,audio or images.
+
+core = 6.x
+dependencies[] = emfield
+package = CCK
+
+;
+version = "6.x-1.x-dev"
+core = "6.x"
+project = "emfield"
+datestamp = ""
+
diff -urpN contrib/emfield_generic/emfield_generic.install contrib/emfield_generic/emfield_generic.install
--- contrib/emfield_generic/emfield_generic.install	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emfield_generic.install	2008-11-27 09:53:44.000000000 -0600
@@ -0,0 +1,75 @@
+<?php
+// $Id: emvideo.install,v 1.1.2.7 2008/10/08 17:39:09 alexua Exp $
+
+/**
+ * @file
+ * Installation, configuration, and removal of the emvideo module.
+ */
+
+/**
+ * Implementation of hook_install().
+ */
+function emfield_generic_install() {
+  // Build any necessary tables.
+  drupal_load('module', 'content');
+  content_notify('install', 'emfield_generic');
+
+  //Set global variables
+  $providers = drupal_system_listing("\.inc", drupal_get_path('module', 'emfield_generic') ."/providers/", 'name', 0);
+  foreach($providers as $provider)
+  	variable_set('emfield_emfield_generic_allow_'. $provider->name,TRUE);    
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function emfield_generic_uninstall() {
+
+  //Delete global variables
+  $providers = drupal_system_listing("\.inc", drupal_get_path('module', 'emfield_generic') ."/providers/", 'name', 0);
+
+  foreach($providers as $provider)
+  	variable_del('emfield_emfield_generic_allow_'. $provider->name);  
+   	
+  drupal_load('module', 'content');
+  content_notify('uninstall', 'emfield_generic');
+
+}
+
+/**
+ * Implementation of hook_enable().
+ */
+function emfield_generic_enable() {
+  drupal_load('module', 'content');
+  content_notify('enable', 'emfield_generic');
+}
+
+/**
+ * Implementation of hook_disable().
+ */
+function emfield_generic_disable() {
+  drupal_load('module', 'content');
+  content_notify('disable', 'emfield_generic');
+}
+
+/**
+ *  Implementation of hook_requirements().
+ */
+function emfield_generic_requirements($phase) {
+  $requirements = array();
+  // Ensure translations don't break at install time
+  $t = get_t();
+
+  if ($phase == 'install') {
+    if (drupal_get_installed_schema_version('content') < 6000) {
+      drupal_set_message($t("Some updates are still pending. Please return to !update and run the remaining updates.", array('!update' => l($t(), 'update.php', array('query' => 'op=selection')))), 'warning');
+      $requirements['cck'] = array(
+        'title' => $t('CCK'),
+        'description' => $t('Updates for content.module need to be run first.<br/>Please re-run the update script.'),
+        'severity' => REQUIREMENT_ERROR,
+      );
+    }
+  }
+
+  return $requirements;
+}
diff -urpN contrib/emfield_generic/emfield_generic.module contrib/emfield_generic/emfield_generic.module
--- contrib/emfield_generic/emfield_generic.module	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emfield_generic.module	2008-11-25 17:52:20.000000000 -0600
@@ -0,0 +1,1024 @@
+<?php
+// $Id: emvideo.module,v 1.1.2.8 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ * Embedded Video module is a handler for 3rd party files.
+ */
+//Audio Variables
+define('EMAUDIO_DEFAULT_AUDIO_WIDTH', 425);
+define('EMAUDIO_DEFAULT_AUDIO_HEIGHT', 350);
+define('EMAUDIO_DEFAULT_PREVIEW_WIDTH', 425);
+define('EMAUDIO_DEFAULT_PREVIEW_HEIGHT', 350);
+define('EMAUDIO_DEFAULT_THUMBNAIL_WIDTH', 120);
+define('EMAUDIO_DEFAULT_THUMBNAIL_HEIGHT', 90);
+define('EMAUDIO_DEFAULT_THUMBNAIL_PATH', '');
+
+//Image Variables
+define('EMIMAGE_LINK_NONE', 0);
+define('EMIMAGE_LINK_CONTENT', 'node');
+define('EMIMAGE_LINK_PROVIDER', 'provider');
+define('EMIMAGE_DEFAULT_FULL_WIDTH', 500);
+define('EMIMAGE_DEFAULT_FULL_HEIGHT', 800);
+define('EMIMAGE_DEFAULT_FULL_LINK', EMIMAGE_LINK_PROVIDER);
+define('EMIMAGE_DEFAULT_PREVIEW_WIDTH', 240);
+define('EMIMAGE_DEFAULT_PREVIEW_HEIGHT', 360);
+define('EMIMAGE_DEFAULT_PREVIEW_LINK', EMIMAGE_LINK_CONTENT);
+define('EMIMAGE_DEFAULT_THUMBNAIL_WIDTH', 100);
+define('EMIMAGE_DEFAULT_THUMBNAIL_HEIGHT', 180);
+define('EMIMAGE_DEFAULT_THUMBNAIL_LINK', EMIMAGE_LINK_CONTENT);
+
+//Video Variables
+define('EMVIDEO_DEFAULT_VIDEO_WIDTH', 425);
+define('EMVIDEO_DEFAULT_VIDEO_HEIGHT', 350);
+define('EMVIDEO_DEFAULT_PREVIEW_WIDTH', 425);
+define('EMVIDEO_DEFAULT_PREVIEW_HEIGHT', 350);
+define('EMVIDEO_DEFAULT_THUMBNAIL_WIDTH', 120);
+define('EMVIDEO_DEFAULT_THUMBNAIL_HEIGHT', 90);
+
+
+/**
+ * Implementation of hook_menu().
+ */
+function emfield_generic_menu() {
+  $items = array();
+  if (module_exists('thickbox')) {
+    $items['emfield_generic/thickbox'] = array(
+      'page callback' => 'emfield_generic_thickbox',
+      'access arguments' => array('access content'),
+      'type' => MENU_CALLBACK,
+    );
+  }
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_emfield_info().
+ */
+function emfield_generic_emfield_info() {
+  $name = t('Embedded Generic Field');
+  return array(
+    '#name' => $name,
+    '#settings_description' => t('The following settings configure content with any fields controlled by @name.', array('@name' => $name)),
+  );
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function emfield_generic_theme() {
+	$themes_emaudio = array(
+    'emaudio_audio_embed' => array(
+       'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+       'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_audio_flash' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_audio_thumbnail' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_audio_audio' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_audio_preview' => array(
+      'arguments'	=> array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_default' => array(
+      'arguments'	=> array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_audio_embed' => array(
+      'arguments' => array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_audio_thumbnail' => array(
+      'arguments' => array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_audio_audio' => array(
+      'arguments' => array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_audio_preview' => array(
+      'arguments'	=> array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_audio_flash' => array(
+      'arguments'	=> array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+    'emaudio_formatter_default' => array(
+      'arguments'	=> array('element' => NULL),
+      'file' => 'emaudio.theme.inc'
+    ),
+  );
+  
+  $themes_emimage = array(
+    'emimage_image' => array(
+        'arguments' => array(
+          'field' => NULL, 
+          'item' => NULL, 
+          'formatter' => NULL, 
+          'node' => NULL, 
+          'code' => NULL, 
+          'width' => NULL, 
+          'height' => NULL, 
+          'title' => NULL, 
+          'link' => NULL
+        ),
+	'file' => 'emimage.theme.inc',
+    ),
+    'emimage_image_embed' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL),
+	  'file' => 'emimage.theme.inc',
+    ),
+    'emimage_image_image' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL,
+        'code' => NULL,
+        'width' => NULL,
+        'height' => NULL,
+        'title' => '',
+        'link' => NULL),
+	  'file' => 'emimage.theme.inc',
+	),
+    'emimage_image_thumbnail' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL),
+	  'file' => 'emimage.theme.inc',    
+	),
+    'emimage_image_full' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL),
+	  'file' => 'emimage.theme.inc',
+    ),
+    'emimage_image_preview' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL),
+	  'file' => 'emimage.theme.inc',
+    ),
+    'emimage_default' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+        'node' => NULL),
+	  'file' => 'emimage.theme.inc',
+		
+    ),
+    'emimage_formatter_image_image' => array(
+        'arguments' => array('element' => NULL),
+		'file' => 'emimage.theme.inc',
+    ),
+    'emimage_formatter_image_thumbnail' => array(
+        'arguments' => array('element' => NULL),
+		'file' => 'emimage.theme.inc',
+    ),
+    'emimage_formatter_image_embed' => array(
+        'arguments' => array('element' => NULL),
+		'file' => 'emimage.theme.inc',
+    ),
+    'emimage_formatter_image_preview' => array(
+        'arguments' => array('element' => NULL),
+		'file' => 'emimage.theme.inc',
+    ),
+    'emimage_formatter_default' => array(
+        'arguments' => array('element' => NULL),
+		'file' => 'emimage.theme.inc',
+    )
+  );  
+  	
+  $themes_emvideo = array(
+    'emvideo_video_embed' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_video_thumbnail' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'no_link' => FALSE, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_video_video' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_default' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_video_preview' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_thickbox' => array(
+      'arguments' => array('field' => NULL, 'item' => NULL, 'formatter' => NULL, 'node' => NULL, 'options' => array()),
+      'file' => 'emvideo.theme.inc',
+    ),
+    'emvideo_formatter_video_video' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+    'emvideo_formatter_video_thumbnail' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+    'emvideo_formatter_video_embed' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+    'emvideo_formatter_video_preview' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+    'emvideo_formatter_default' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+	'emvideo_formatter_thickbox' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emvideo.theme.inc'
+    ),
+  );
+  
+  $themes_emfield_generic = array(
+    'emfield_generic_formatter_video_video' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+    'emfield_generic_formatter_video_thumbnail' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+    'emfield_generic_formatter_video_embed' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+    'emfield_generic_formatter_video_preview' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+    'emfield_generic_formatter_default' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+    'emfield_generic_formatter_video_flash' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),    
+	'emfield_generic_formatter_thickbox' => array(
+        'arguments' => array('element' => NULL),
+        'file' => 'emfield_generic.theme.inc'
+    ),
+  );
+  
+  $themes = array_merge($themes_emaudio,$themes_emimage,$themes_emvideo,$themes_emfield_generic);
+  
+  $themes += module_invoke('emfield', 'provider_themes', 'emfield_generic');
+  
+  return $themes;
+  
+}
+
+/**
+ * Implementation of hook_emfield_settings().
+ *
+ * This would be to add any extra settings (besides providers) to the emfield
+ * settings configuration page. Video CCK doesn't require anything at the moment.
+ */
+function emfield_generic_emfield_settings() {
+  $form = array();
+
+  return $form;
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function emfield_generic_field_info() {
+  $fields = array(
+    'emfield_generic' => array(
+      'label' => t('Generic Embedded Field'),
+      'description' => t('Automatically parse and display a third party sources from its URL or embed code.'),
+      'callbacks' => array(
+        'tables' => CONTENT_CALLBACK_DEFAULT,
+        'arguments' => CONTENT_CALLBACK_DEFAULT,
+      ),
+    ),
+  );
+
+  return $fields;
+}
+
+/**
+ *  Implementation of hook_field_settings
+ */
+function emfield_generic_field_settings($op, $field) {
+  switch ($op) {
+    case 'database columns':
+      return module_invoke('emfield', 'field_columns', $field);    
+  }
+}
+
+/**
+ * Implementation of hook_content_is_empty().
+ */
+function emfield_generic_content_is_empty($item, $field) {
+  return module_invoke('emfield', 'emfield_content_is_empty', $item, $field);
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function emfield_generic_field($op, &$node, $field, &$items, $teaser, $page) {
+  if (module_hook('emfield', 'emfield_field')) {
+    return emfield_emfield_field($op, $node, $field, $items, $teaser, $page, 'emfield_generic');
+  }
+}
+
+/**
+ * Implementation of hook_field_formatter_info()
+ */
+function emfield_generic_field_formatter_info() {
+  $types = array('emfield_generic', );
+  $formats = array(
+    'default' => array(
+      'label' => t('Default'),
+      'field types' => $types,
+    ));
+    
+  $formats_audio = array(
+    'audio_audio' => array(
+      'label' => t('Full Size Audio Player'),
+      'field types' => $types,
+    ),
+    'emaudio_preview' => array(
+      'label' => t('Preview Size Audio Player'),
+      'field types' => $types,
+    ),
+    'emaudio_thumbnail' => array(
+      'label' => t('Audio Image Thumbnail'),
+      'field types' => $types,
+    ),
+    'emaudio_embed' => array(
+      'label' => t('Audio Embed Code'),
+      'field types' => $types,
+    ),
+  );    
+    
+  $formats_image = array(
+    'image_full' => array(
+      'label' => t('Image Full Size Image'),
+      'field types' => $types,
+    ),
+    'image_preview' => array(
+      'label' => t('Image Preview Size Image'),
+      'field types' => $types,
+    ),
+    'image_thumbnail' => array(
+      'label' => t('Image Thumbnail'),
+      'field types' => $types,
+    ),
+    'image_embed' => array(
+      'label' => t('Image Embed Code'),
+      'field types' => $types,
+    ),
+  );  
+  
+  $formats_video = array(
+    'video_video' => array(
+      'label' => t('Full Size Video'),
+      'field types' => $types,
+    ),
+    'video_preview' => array(
+      'label' => t('Preview Video'),
+      'field types' => $types,
+    ),
+    'video_thumbnail' => array(
+      'label' => t('Video Image Thumbnail'),
+      'field types' => $types,
+    ),
+    'video_embed' => array(
+      'label' => t('Video Embed Code'),
+      'field types' => $types,
+    ),
+  );
+
+  $formats = array_merge($formats,$formats_audio,$formats_image,$formats_video);
+  
+  // Add thickbox formatter if thickbox module exists.
+  if (module_exists('thickbox')) {
+    $formats['thickbox'] = array(
+      'label' => t('Thickbox: Image Thumbnail -> Full Size Video'),
+      'field types' => $types,
+      );
+  }
+
+  return $formats;
+}
+
+/**
+ * Implementation of hook_field_formatter().
+ */
+function emfield_generic_field_formatter($field, $item, $formatter, $node) {
+  $types = array("emaudio","emimage","emvideo");
+  foreach($types as $type){	
+	  $files = _emfield_generic_system_list('emfield_generic', $type,$item['provider'],FALSE);
+	  
+	  if(!empty($files))
+	  	$item['type'] = $type;
+  }
+  return module_invoke('emfield', 'emfield_field_formatter', $field, $item, $formatter, $node, 'emfield_generic');
+}
+
+/** Widgets **/
+
+/**
+ * Implementation of hook_widget_info
+ */
+function emfield_generic_widget_info() {
+  return array(
+    'emfield_generic_textfields' => array(
+      'label' => '3rd Party files',
+      'field types' => array('emfield_generic'),
+      'multiple values' => CONTENT_HANDLE_CORE,
+      'callbacks' => array(
+        'default value' => CONTENT_CALLBACK_DEFAULT,
+        ),
+    ),
+  );
+}
+
+function _emfield_generic_system_list($module, $type,$provider = NULL, $load = TRUE) {
+  $override_files = module_invoke_all('emfield_providers', $module, $provider);
+  $files = drupal_system_listing("$provider\.inc", drupal_get_path('module', $module) ."/providers/" . $type , 'name', 0);
+  $files = array_merge($files, $override_files);
+
+  ksort($files);
+
+  if ($load) {
+    foreach ($files as $file) {
+      emfield_include_list($file);
+    }
+  }
+
+  return $files;
+}
+
+/**
+ * Invoke hook in a particular include.
+ *
+ * @param $module
+ *  the helper module
+ * @param $provider
+ *   The name of the provider (without the .inc extension).
+ * @param $hook
+ *   The name of the hook (e.g. "settings", "thumbnail", etc.).
+ * @param ...
+ *   Arguments to pass to the hook implementation.
+ * @return
+ *   The return value of the hook implementation.
+ */
+function _emfield_generic_include_invoke() {
+  $args     = func_get_args();
+  $module = array_shift($args);
+  $type = array_shift($args);
+  $provider  = array_shift($args);
+  $hook     = array_shift($args);
+  $function = $type .'_'. $provider .'_'. $hook;
+  _emfield_generic_system_list($module, $type,$provider);  
+  return emfield_include_hook($type, $provider, $hook) ? call_user_func_array($function, $args) : NULL;
+}
+
+
+function _emfield_generic_widget_settings($op, $widget, $type) {
+  switch ($op) {
+    case 'form':
+      // Make sure to register the new type as supported by this module.
+      emfield_implement_types(FALSE);
+
+      $form = array();
+      $options = array();
+      $providers = _emfield_generic_system_list($module = "emfield_generic",$type);
+ 	
+      global $conf;
+      foreach ($providers as $provider) {
+      	if (variable_get('emfield_'. $module . '_allow_'. $provider->name, FALSE)) {
+          $info = _emfield_generic_include_invoke("emfield_generic", $type,$provider->name, 'info');
+          $options[$provider->name] = $info['name'];
+        }
+      }
+      $type_str = substr($type,2);
+      $form_options = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Providers ' . $type_str),
+        '#default_value' => empty($widget['providers_' . $type_str]) ? array() : $widget['providers_' . $type_str],
+        '#options' => $options,
+      );     
+
+      /*foreach (module_implements('emfield_widget_settings_extra') as $module) {
+        $form[$module] = module_invoke($module, 'emfield_widget_settings_extra', 'form', $widget);
+      }*/
+
+      return $form_options;
+
+    case 'save':
+      $columns = array('providers'); //, 'helper_module', );
+      foreach (module_implements('emfield_widget_settings_extra') as $module) {
+        $columns = array_merge($columns, module_invoke($module, 'emfield_widget_settings_extra', 'save', $widget));
+      }
+
+      return $columns;
+  }
+}
+
+function emfield_generic_widget_settings($op, $widget) {
+  switch ($op) {
+    case 'form':
+      if ($widget['type'] == 'emfield_generic_textfields') {
+      
+      $form['provider_list'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Providers Supported'),
+        '#description' => t('Select which third party providers you wish to allow for this content type from the list below. If no checkboxes are checked, then all providers will be supported. When a user submits new content, the URL they enter will be matched to the provider, assuming that provider is allowed here.'),
+        '#collapsible' => TRUE,
+        '#collapsed' => FALSE,
+      );
+      	//Audio Section
+        $form['provider_list']['providers_audio'] = (array)_emfield_generic_widget_settings('form', $widget, 'emaudio');
+        $width = variable_get('emaudio_default_audio_width', EMAUDIO_DEFAULT_AUDIO_WIDTH);
+        $height = variable_get('emaudio_default_audio_height', EMAUDIO_DEFAULT_AUDIO_HEIGHT);
+        $form['audio'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Audio Display Settings'),
+          '#description' => t('These settings control how this audio player is displayed in its full size, which defaults to @widthx@height.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['audio']['audio_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Audio display width'),
+          '#default_value' => empty($widget['audio_width']) ? $width : $widget['audio_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the audio. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['audio']['audio_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Audio display height'),
+          '#default_value' => empty($widget['audio_height']) ? $height : $widget['audio_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the audio. It defaults to @height.', array('@height' => $height)),
+        );
+        $form['audio']['audio_autoplay'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Autoplay'),
+          '#default_value' => empty($widget['audio_autoplay']) ? '' : $widget['audio_autoplay'],
+          '#description' => t('If supported by the provider, checking this box will cause the audio player to automatically begin after it loads when in its full size.'),
+        );
+
+        $width = variable_get('emaudio_default_preview_width', EMAUDIO_DEFAULT_PREVIEW_WIDTH);
+        $height = variable_get('emaudio_default_preview_height', EMAUDIO_DEFAULT_PREVIEW_HEIGHT);
+        $form['audio_preview'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Audio Preview Settings'),
+          '#description' => t('These settings control how this audio is displayed in its preview size, which defaults to @widthx@height.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['audio_preview']['audio_preview_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Audio preview width'),
+          '#default_value' => empty($widget['audio_preview_width']) ? $width : $widget['audio_preview_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the preview audio. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['audio_preview']['audio_preview_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Audio preview height'),
+          '#default_value' => empty($widget['audio_preview_height']) ? $height : $widget['audio_preview_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the preview audio. It defaults to @height.', array('@height' => $height)),
+        );
+        $form['audio_preview']['audio_preview_autoplay'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Autoplay'),
+          '#default_value' => empty($widget['preview_autoplay']) ? '' : $widget['preview_autoplay'],
+          '#description' => t('If supported by the provider, checking this box will cause the audio player to automatically begin after it loads when in its preview size.'),
+        );
+
+        $width = variable_get('emaudio_default_thumbnail_width', EMAUDIO_DEFAULT_THUMBNAIL_WIDTH);
+        $height = variable_get('emaudio_default_thumbnail_height', EMAUDIO_DEFAULT_THUMBNAIL_HEIGHT);
+        $form['audio_tn'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Audio Thumbnail'),
+          '#description' => t('When displayed as a thumbnail, these settings control the image returned. Note that not all 3rd party audio content providers offer thumbnails, and others may require an API key or other requirements. More information from the <a href="@settings">settings page</a>. The default size for thumbnails is @widthx@height.', array('@settings' => url('admin/content/emfield'), '@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['audio_tn']['audio_thumbnail_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Audio width'),
+          '#default_value' => empty($widget['audio_thumbnail_width']) ? $width : $widget['audio_thumbnail_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the thumbnail. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['audio_tn']['audio_thumbnail_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Thumbnail height'),
+          '#default_value' => empty($widget['audio_thumbnail_height']) ? $height : $widget['audio_thumbnail_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the thumbnail. It defaults to @height.', array('@height' => $height)),
+        );
+        if (!module_exists('emthumb')) {
+          $tn_desc = ' '. t('You may be interested in activating the Embedded Media Thumbnails module as well, which will allow you to specify custom thumbnails on a per-node basis.');
+        }
+		$default_path = variable_get('emaudio_default_thumbnail_path', EMAUDIO_DEFAULT_THUMBNAIL_PATH);
+        $form['audio_tn']['audio_thumbnail_default_path'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Default thumbnail path'),
+          '#default_value' => empty($widget['audio_thumbnail_default_path']) ? $default_path : $widget['audio_thumbnail_default_path'],
+          '#description' => t("Path to a local default thumbnail image for cases when a thumbnail can't be found. For example, you might have a default thumbnail at %files.", array('%files' => 'files/thumbnail.png')) . $tn_desc,
+        );
+        
+        //Image Section
+        $form['provider_list']['providers_image'] = (array)_emfield_generic_widget_settings('form', $widget, 'emimage');
+		$link_options = array(
+          EMIMAGE_LINK_NONE => t('No link'),
+          EMIMAGE_LINK_CONTENT => t('Link to content'),
+          EMIMAGE_LINK_PROVIDER => t('Link to provider'),
+        );
+        $width = variable_get('emimage_default_full_width', EMIMAGE_DEFAULT_FULL_WIDTH);
+        $height = variable_get('emimage_default_full_height', EMIMAGE_DEFAULT_FULL_HEIGHT);
+        $form['image_full'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Image Full size display settings'),
+          '#description' => t('These settings control how this image is displayed in its full size, which defaults to @widthx@height. Note that if one of the dimensions is 0, then the image will be resized to be no larger than the other dimension.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['image_full']['full_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Full size display width'),
+          '#default_value' => empty($widget['full_width']) ? $width : $widget['full_width'],
+          '#required' => true,
+          '#description' => t('The width of the image. It defaults to @width. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@width' => $width)),
+        );
+        $form['image_full']['full_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Full size display height'),
+          '#default_value' => empty($widget['full_height']) ? $height : $widget['full_height'],
+          '#required' => true,
+          '#description' => t('The height of the image. It defaults to @height. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@height' => $height)),
+        );
+		$full_link = variable_get('emimage_default_full_link', EMIMAGE_DEFAULT_FULL_LINK);
+        $form['image_full']['full_link'] = array(
+          '#type' => 'select',
+          '#title' => t('Full size link'),
+          '#description' => t("Where the image will link when displayed in its full size. 'Content' links to the content page, 'provider' links to the provider's image page, and 'none' displays the image with no link."),
+          '#options' => $link_options,
+          '#default_value' => empty($widget['full_link']) ? $full_link : $widget['full_link'],
+        );
+
+        $width = variable_get('emimage_default_preview_width', EMIMAGE_DEFAULT_PREVIEW_WIDTH);
+        $height = variable_get('emimage_default_preview_height', EMIMAGE_DEFAULT_PREVIEW_HEIGHT);
+        $form['image_preview'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Image Preview Settings'),
+          '#description' => t('These settings control how this image is displayed in its preview size, which defaults to @widthx@height. Note that if one of the dimensions is 0, then the image will be resized to be no larger than the other dimension.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => true,
+          '#collapsed' => TRUE,
+        );
+        $form['image_preview']['image_preview_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Image preview width'),
+          '#default_value' => empty($widget['image_preview_width']) ? $width : $widget['image_preview_width'],
+          '#required' => true,
+          '#description' => t('The width of the image preview. It defaults to @width. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@width' => $width)),
+        );
+        $form['image_preview']['image_preview_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Image preview height'),
+          '#default_value' => empty($widget['image_preview_height']) ? $height : $widget['image_preview_height'],
+          '#required' => true,
+          '#description' => t('The height of the image preview. It defaults to @height. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@height' => $height)),
+        );
+		$full_link = variable_get('emimage_default_preview_link', EMIMAGE_DEFAULT_PREVIEW_LINK);
+        $form['image_preview']['preview_link'] = array(
+          '#type' => 'select',
+          '#title' => t('Preview size link'),
+          '#description' => t("Where the image will link when displayed in its preview size. 'Content' links to the content page, 'provider' links to the provider's image page, and 'none' displays the image with no link."),
+          '#options' => $link_options,
+          '#default_value' => empty($widget['full_link']) ? $full_link : $widget['full_link'],
+        );
+        $width = variable_get('emimage_default_thumbnail_width', EMIMAGE_DEFAULT_THUMBNAIL_WIDTH);
+        $height = variable_get('emimage_default_thumbnail_height', EMIMAGE_DEFAULT_THUMBNAIL_HEIGHT);
+        $form['image_tn'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Image Thumbnail'),
+          '#description' => t('When displayed as a thumbnail, these settings control the image returned. The default size for thumbnails is @widthx@height. Note that if one of the dimensions is 0, then the image will be resized to be no larger than the other dimension.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['image_tn']['image_thumbnail_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Image thumbnail width'),
+          '#default_value' => empty($widget['image_thumbnail_width']) ? $width : $widget['image_thumbnail_width'],
+          '#required' => true,
+          '#description' => t('The width of the image thumbnail. It defaults to @width. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@width' => $width)),
+        );
+        $form['image_tn']['image_thumbnail_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Image thumbnail height'),
+          '#default_value' => empty($widget['image_thumbnail_height']) ? $height : $widget['image_thumbnail_height'],
+          '#required' => true,
+          '#description' => t('The height of the image thumbnail. It defaults to @height. Set it to 0 if you want to leave the image at its original aspect ratio.', array('@height' => $height)),
+        );
+		$thumb_link = variable_get('emimage_default_thumbnail_link', EMIMAGE_DEFAULT_THUMBNAIL_LINK);
+        $form['image_tn']['image_thumbnail_link'] = array(
+          '#type' => 'select',
+          '#title' => t('Image thumbnail link'),
+          '#description' => t("Where the image will link when displayed as a thumbnail. 'Content' links to the content page, 'provider' links to the provider's image page, and 'none' displays the image with no link."),
+          '#options' => $link_options,
+          '#default_value' => empty($widget['image_thumbnail_link']) ? $thumb_link : $widget['image_thumbnail_link'],
+        );
+                
+        //Video Section
+        $form['provider_list']['providers_video'] = (array)_emfield_generic_widget_settings('form', $widget, 'emvideo');
+        
+        $width = variable_get('emvideo_default_video_width', EMVIDEO_DEFAULT_VIDEO_WIDTH);
+        $height = variable_get('emvideo_default_video_height', EMVIDEO_DEFAULT_VIDEO_HEIGHT);
+        
+        $form['video'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Video Display Settings'),
+          '#description' => t('These settings control how this video is displayed in its full size, which defaults to @widthx@height.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['video']['video_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Video display width'),
+          '#default_value' => empty($widget['video_width']) ? $width : $widget['video_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the video. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['video']['video_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Video display height'),
+          '#default_value' => empty($widget['video_height']) ? $height : $widget['video_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the video. It defaults to @height.', array('@height' => $height)),
+        );
+        $form['video']['video_autoplay'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Autoplay'),
+          '#default_value' => empty($widget['video_autoplay']) ? '' : $widget['video_autoplay'],
+          '#description' => t('If supported by the provider, checking this box will cause the video to automatically begin after the video loads when in its full size.'),
+        );
+
+        $width = variable_get('emvideo_default_preview_width', EMVIDEO_DEFAULT_PREVIEW_WIDTH);
+        $height = variable_get('emvideo_default_preview_height', EMVIDEO_DEFAULT_PREVIEW_HEIGHT);
+        $form['video_preview'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Video Preview Settings'),
+          '#description' => t('These settings control how this video is displayed in its preview size, which defaults to @widthx@height.', array('@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['video_preview']['video_preview_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Video preview width'),
+          '#default_value' => empty($widget['video_preview_width']) ? $width : $widget['video_preview_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the preview video. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['video_preview']['video_preview_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Video preview height'),
+          '#default_value' => empty($widget['video_preview_height']) ? $height : $widget['video_preview_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the preview video. It defaults to @height.', array('@height' => $height)),
+        );
+        $form['video_preview']['vieo_preview_autoplay'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Autoplay'),
+          '#default_value' => empty($widget['video_preview_autoplay']) ? '' : $widget['video_preview_autoplay'],
+          '#description' => t('If supported by the provider, checking this box will cause the video to automatically begin after the video loads when in its preview size.'),
+        );
+
+        $width = variable_get('emvideo_default_thumbnail_width', EMVIDEO_DEFAULT_THUMBNAIL_WIDTH);
+        $height = variable_get('emvideo_default_thumbnail_height', EMVIDEO_DEFAULT_THUMBNAIL_HEIGHT);
+        $form['video_tn'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Video Thumbnail'),
+          '#description' => t('When displayed as a thumbnail, these settings control the image returned. Note that not all 3rd party files content providers offer thumbnails, and others may require an API key or other requirements. More information from the <a href="@settings">settings page</a>. The default size for thumbnails is @widthx@height.', array('@settings' => url('admin/content/emfield'), '@width' => $width, '@height' => $height)),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['video_tn']['video_thumbnail_width'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Thumbnail width'),
+          '#default_value' => empty($widget['video_thumbnail_width']) ? $width : $widget['video_thumbnail_width'],
+          '#required' => TRUE,
+          '#description' => t('The width of the thumbnail. It defaults to @width.', array('@width' => $width)),
+        );
+        $form['video_tn']['video_thumbnail_height'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Thumbnail height'),
+          '#default_value' => empty($widget['video_thumbnail_height']) ? $height : $widget['video_thumbnail_height'],
+          '#required' => TRUE,
+          '#description' => t('The height of the thumbnail. It defaults to @height.', array('@height' => $height)),
+        );
+        if (!module_exists('emthumb')) {
+          $tn_desc = ' '. t('You may be interested in activating the Embedded Media Thumbnails module as well, which will allow you to specify custom thumbnails on a per-node basis.');
+        }
+		$default_path = variable_get('emfield_generic_default_thumbnail_path', '');
+        $form['video_tn']['video_thumbnail_default_path'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Default thumbnail path'),
+          '#default_value' => empty($widget['video_thumbnail_default_path']) ? $default_path : $widget['video_thumbnail_default_path'],
+          '#description' => t("Path to a local default thumbnail image for cases when a thumbnail can't be found. For example, you might have a default thumbnail at %files.", array('%files' => 'files/thumbnail.png')) . $tn_desc,
+        );
+      }
+      return $form;
+
+    case 'validate':
+      if ($widget['type'] == 'emfield_generic') {
+      	
+      	//Audio Section
+        if (!is_numeric($widget['audio_width']) || intval($widget['audio_width']) != $widget['audio_width'] || $widget['audio_width'] < 1) {
+          form_set_error('audio_width', t('"Audio width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['audio_height']) || intval($widget['audio_height']) != $widget['audio_height'] || $widget['audio_height'] < 1) {
+          form_set_error('audio_height', t('"Audio height" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['audio_preview_width']) || intval($widget['audio_preview_width']) != $widget['audio_preview_width'] || $widget['audio_preview_width'] < 1) {
+          form_set_error('audio_preview_width', t('"Audio Preview width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['audio_preview_height']) || intval($widget['audio_preview_height']) != $widget['audio_preview_height'] || $widget['audio_preview_height'] < 1) {
+          form_set_error('audio_preview_height', t('"Audio Preview height" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['audio_thumbnail_width']) || intval($widget['audio_thumbnail_width']) != $widget['audio_thumbnail_width'] || $widget['audio_thumbnail_width'] < 1) {
+          form_set_error('audio_thumbnail_width', t('"Audio Thumbnail width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['audio_thumbnail_height']) || intval($widget['audio_thumbnail_height']) != $widget['audio_thumbnail_height'] || $widget['audio_thumbnail_height'] < 1) {
+          form_set_error('audio_thumbnail_height', t('"Audio Thumbnail height" must be a positive integer.'));
+        }      	
+      	
+      	//Image Section
+      	if (!is_numeric($widget['full_width']) || intval($widget['full_width']) != $widget['full_width'] || $widget['full_width'] < 0) {
+          form_set_error('full_width', t('"Image Full size width" must be an integer.'));
+        }
+        if (!is_numeric($widget['full_height']) || intval($widget['full_height']) != $widget['full_height'] || $widget['full_height'] < 0) {
+          form_set_error('full_height', t('"Image Full size height" must be an integer.'));
+        }
+        if (!is_numeric($widget['image_preview_width']) || intval($widget['image_preview_width']) != $widget['image_preview_width'] || $widget['image_preview_width'] < 0) {
+          form_set_error('image_preview_width', t('"Image Preview width" must be an integer.'));
+        }
+        if (!is_numeric($widget['image_preview_height']) || intval($widget['image_preview_height']) != $widget['image_preview_height'] || $widget['image_preview_height'] < 0) {
+          form_set_error('image_preview_height', t('"Image Preview height" must be an integer.'));
+        }
+        if (!is_numeric($widget['image_thumbnail_width']) || intval($widget['image_thumbnail_width']) != $widget['image_thumbnail_width'] || $widget['image_thumbnail_width'] < 0) {
+          form_set_error('image_thumbnail_width', t('"Image Thumbnail width" must be an integer.'));
+        }
+        if (!is_numeric($widget['image_thumbnail_height']) || intval($widget['image_thumbnail_height']) != $widget['image_thumbnail_height'] || $widget['image_thumbnail_height'] < 0) {
+          form_set_error('image_thumbnail_height', t('"Image Thumbnail height" must be an integer.'));
+        }
+        
+      	//Video Section
+        if (!is_numeric($widget['video_width']) || intval($widget['video_width']) != $widget['video_width'] || $widget['video_width'] < 1) {
+          form_set_error('video_width', t('"Video width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['video_height']) || intval($widget['video_height']) != $widget['video_height'] || $widget['video_height'] < 1) {
+          form_set_error('video_height', t('"Video height" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['video_preview_width']) || intval($widget['video_preview_width']) != $widget['video_preview_width'] || $widget['video_preview_width'] < 1) {
+          form_set_error('video_preview_width', t('"Video Preview width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['video_preview_height']) || intval($widget['video_preview_height']) != $widget['video_preview_height'] || $widget['video_preview_height'] < 1) {
+          form_set_error('video_preview_height', t('"Video Preview height" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['video_thumbnail_width']) || intval($widget['video_thumbnail_width']) != $widget['video_thumbnail_width'] || $widget['video_thumbnail_width'] < 1) {
+          form_set_error('video_thumbnail_width', t('"Video Thumbnail width" must be a positive integer.'));
+        }
+        if (!is_numeric($widget['video_thumbnail_height']) || intval($widget['video_thumbnail_height']) != $widget['video_thumbnail_height'] || $widget['video_thumbnail_height'] < 1) {
+          form_set_error('video_thumbnail_height', t('"Video Thumbnail height" must be a positive integer.'));
+        }
+      }
+      break;
+
+    case 'save':
+      if ($widget['widget_type'] == 'emfield_generic_textfields') {
+      	$columns_audio = array('audio_width', 'audio_height', 'audio_autoplay', 'audio_preview_width', 'audio_preview_height', 'audio_preview_autoplay', 'audio_thumbnail_width', 'audio_thumbnail_height', 'audio_thumbnail_default_path', );
+      	$columns_image = array('full_width', 'full_height', 'full_link', 'image_preview_width', 'image_preview_height', 'image_preview_link', 'image_thumbnail_width', 'image_thumbnail_height', 'image_thumbnail_link', );
+        $columns_video = array('video_width', 'video_height', 'video_autoplay', 'video_preview_width', 'video_preview_height', 'video_preview_autoplay', 'videio_thumbnail_width', 'video_thumbnail_height', 'video_thumbnail_default_path', );
+        $providers = array('providers_audio','providers_image','providers_video');
+        $columns = array_merge($columns_audio,$columns_image,$columns_video,$providers);
+        //$columns = array_merge($columns_audio,$columns_image,$columns_video, module_invoke('emfield', 'emfield_widget_settings', 'save', $widget, 'emfield_generic'));        
+        return $columns;
+      }
+      break;
+  }
+}
+
+/**
+ * Return a list of providers allowed for a specific field. honor general setting and cck field settings
+ */
+function _emfield_generic_allowed_providers($field, $module,$type) {
+  $allowed_providers = _emfield_generic_system_list($module,$type);
+  $providers = "providers_" . substr($type,2);
+  
+  foreach ($allowed_providers as $provider) {
+  	if (!variable_get('emfield_'. $module . '_allow_'. $provider->name, FALSE) || !$field['widget'][$providers][$provider->name]) {
+      unset($allowed_providers[$provider->name]);
+    }
+  }
+  return $allowed_providers;
+}
+
+/**
+ * Implementation of hook_widget()
+ */
+function emfield_generic_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+  if (module_hook('emfield', 'emfield_widget')) {
+    return emfield_emfield_widget($form, $form_state, $field, $items, $delta, 'emfield_generic');
+  }
+}
+
+function emfield_generic_embed_form($field, $item, $formatter, $node, $options = array()) {
+  $embed = $item['value'];
+  $width = $options['width'] ? $options['width'] : $field['widget']['video_width'];
+  $height = $options['height'] ? $options['height'] : $field['widget']['video_height'];
+  $autoplay = $options['autoplay'] ? $options['autoplay'] : $field['widget']['video_autoplay'];
+  $title = $options['title'] ? $options['title'] : t('Embed Code');
+  $description = $options['description'] ? $options['description'] : t('To embed this video on your own site, simply copy and paste the html code from this text area.');
+  $text = module_invoke('emfield', 'include_invoke', 'emfield_generic', $item['provider'], 'video', $embed, $width, $height, $field, $item, $autoplay);
+  $form = array();
+  $form['emfield_generic_embed'] = array(
+    '#type' => 'textarea',
+    '#title' => $title,
+    '#description' => $description,
+    '#default_value' => $text,
+  );
+
+  return $form;
+}
+
+/**
+ * Providers may supply an enclosure for rss feeds. This expects something in a
+ * file format, so would be an object in the format of $file->filepath,
+ * $file->filesize, and $file->filemime.
+ * Calls the providers hook emfield_generic_PROVIDER_RSS($item, $teaser).
+ */
+function emfield_generic_emfield_rss($node, $items = array(), $teaser = NULL) {
+  $rss_data = array();
+  foreach ($items as $item) {
+    // note only the first $item will get an RSS enclosure, other items may have media: data in the feed however
+    if ($item['value'] && $item['provider']) {
+      $rss_data[] = module_invoke('emfield', 'include_invoke', 'emfield_generic', $item['provider'], 'rss', $item, $teaser);
+    }
+  }
+
+  return $rss_data;
+}
+
+function emfield_generic_handler_arg_provider($op, &$query, $argtype, $arg = '') {
+  return _emfield_handler_arg_provider($op, $query, $argtype, $arg, 'emfield_generic');
+}
+
+/**
+ * Page callback for video-cck/thickbox.
+ * This will display our video in a modal window defined by the thickbox module.
+ * As it's a direct callback, it displays no HTML other than the video.
+ */
+function emfield_generic_thickbox($nid, $width, $height, $field_name) {
+  $field = array();
+  $field['widget']['video_width'] = $width;
+  $field['widget']['video_height'] = $height;
+  $field['widget']['video_autoplay'] = 1;
+  $field['field_name'] = $field_name;
+  $node = node_load($nid);
+  $items = $node->$field_name;
+  $item = $items[0];
+  print theme('emfield_generic_video_video', $field, $item, 'video_video', $node);
+}
diff -urpN contrib/emfield_generic/emfield_generic.theme.inc contrib/emfield_generic/emfield_generic.theme.inc
--- contrib/emfield_generic/emfield_generic.theme.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emfield_generic.theme.inc	2008-11-23 16:32:20.000000000 -0600
@@ -0,0 +1,97 @@
+<?php
+// $Id:  $
+
+/**
+ * @file
+ * This defines the various theme functions for Embedded Generic Field.
+ */
+//Audio Section
+function theme_emfield_generic_formatter_audio_flash($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+function theme_emfield_generic_formatter_audio_embed($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_audio_thumbnail($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_audio_preview($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_audio_audio($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+
+//Image Section
+function theme_emfield_generic_formatter_image_image($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_image_embed($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_image_preview($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_image_thumbnail($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_image_embed($field, $item, $formatter, $node) {
+  if ($item['value'] && $item['provider']) {
+    $output = drupal_get_form('emimage_embed_form', $field, $item, $formatter, $node);
+  }
+  return $output;
+}
+
+
+//Video Section
+function theme_emfield_generic_formatter_video_video($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_video_embed($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_video_preview($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_video_thumbnail($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+function theme_emfield_generic_formatter_video_flash($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+function theme_emfield_generic_formatter_thickbox($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
+
+//General section
+function theme_emfield_generic_formatter_default($element) {
+  $field = content_fields($element['#field_name'], $element['#type_name']);
+  return module_invoke('emfield_generic', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
+}
diff -urpN contrib/emfield_generic/emimage.theme.inc contrib/emfield_generic/emimage.theme.inc
--- contrib/emfield_generic/emimage.theme.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emimage.theme.inc	2008-11-23 16:35:02.000000000 -0600
@@ -0,0 +1,92 @@
+<?php
+
+
+function theme_emimage_image($field, $item, $formatter, $node, $code, $width, $height, $title = '', $link = NULL) {
+  $url = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'image_url', $code, $width, $height, $formatter, $field, $item, $node);
+  $attributes = array();
+  if ($width) {
+    $attributes['width'] = $width;
+  }
+  if ($height) {
+    $attributes['height'] = $height;
+  }
+  if ($item['class']){
+      $attributes['class'] = $item['class'];
+  }
+  else if ($item['provider']) {
+      $attributes['class'] = $item['provider'];
+  }
+  $output = theme('image', $url, $title, $title, $attributes, false);
+  
+  if ($link) {
+    $output = l($output, $link, array('html' => true));
+  }
+  return $output;
+}
+
+function theme_emimage_image_thumbnail($field, $item, $formatter, $node) {
+  if ($item['value'] && $item['provider']) {
+    $code = $item['value'];
+    $width = $field['widget']['thumbnail_width'] === '' ? variable_get('emimage_default_full_width', EMIMAGE_DEFAULT_FULL_WIDTH) : $field['widget']['thumbnail_width'];
+    $height = $field['widget']['thumbnail_height'] === '' ? variable_get('emimage_default_full_height', EMIMAGE_DEFAULT_FULL_HEIGHT) : $field['widget']['thumbnail_height'];
+    $link = $field['widget']['thumbnail_link'] ? $field['widget']['thumbnail_link'] : variable_get('emimage_default_thumbnail_link', EMIMAGE_DEFAULT_THUMBNAIL_LINK);
+    if ($link == EMIMAGE_LINK_CONTENT) {
+      $link = 'node/'. $node->nid;
+    }
+    else if ($link == EMIMAGE_LINK_PROVIDER) {
+      $link = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'embedded_link', $code, $item['data']);
+    }
+    else {
+      $link = NULL;
+    }
+    $title = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'image_title', $code, $item['data']);
+    $output = theme('emimage_image', $field, $item, $formatter, $node, $code, $width, $height, $title, $link);
+  }
+  return $output;
+}
+
+function theme_emimage_image_full($field, $item, $formatter, $node) {
+  if ($item['value'] && $item['provider']) {
+    $code = $item['value'];
+    $width = $field['widget']['full_width'] === '' ? variable_get('emimage_default_full_width', EMIMAGE_DEFAULT_FULL_WIDTH) : $field['widget']['full_width'];
+    $height = $field['widget']['full_height'] === '' ? variable_get('emimage_default_full_height', EMIMAGE_DEFAULT_FULL_HEIGHT) : $field['widget']['full_height'];
+    $link = $field['widget']['full_link'] ? $field['widget']['full_link'] : variable_get('emimage_default_full_link', EMIMAGE_DEFAULT_FULL_LINK);
+    if ($link == EMIMAGE_LINK_CONTENT) {
+      $link = 'node/'. $node->nid;
+    }
+    else if ($link == EMIMAGE_LINK_PROVIDER) {
+      $link = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'embedded_link', $code, $item['data']);
+    }
+    else {
+      $link = NULL;
+    }
+    $title = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'image_title', $code, $item['data']);
+    $output = theme('emimage_image', $field, $item, $formatter, $node, $code, $width, $height, $title, $link);
+  }
+  return $output;
+}
+
+function theme_emimage_default($field, $item, $formatter, $node) {
+  return theme('emimage_image_full', $field, $item, $formatter, $node);
+}
+
+function theme_emimage_image_preview($field, $item, $formatter, $node) {
+  if ($item['value'] && $item['provider']) {
+    $code = $item['value'];
+    $width = $field['widget']['preview_width'] === '' ? variable_get('emimage_default_preview_width', EMIMAGE_DEFAULT_PREVIEW_WIDTH) : $field['widget']['preview_width'];
+    $height = $field['widget']['preview_height'] === '' ? variable_get('emimage_default_preview_height', EMIMAGE_DEFAULT_PREVIEW_HEIGHT) : $field['widget']['preview_height'];
+    $link = $field['widget']['preview_link'] ? $field['widget']['preview_link'] : variable_get('emimage_default_preview_link', EMIMAGE_DEFAULT_PREVIEW_LINK);
+    if ($link == EMIMAGE_LINK_CONTENT) {
+      $link = 'node/'. $node->nid;
+    }
+    else if ($link == EMIMAGE_LINK_PROVIDER) {
+      $link = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'embedded_link', $code, $item['data']);
+    }
+    else {
+      $link = NULL;
+    }
+    $title = _emfield_generic_include_invoke('emfield_generic', 'emimage', $item['provider'], 'image_title', $code, $item['data']);
+    $output = theme('emimage_image', $field, $item, $formatter, $node, $code, $width, $height, $title, $link);
+  }
+  return $output;
+}
\ No newline at end of file
diff -urpN contrib/emfield_generic/emvideo.theme.inc contrib/emfield_generic/emvideo.theme.inc
--- contrib/emfield_generic/emvideo.theme.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/emvideo.theme.inc	2008-11-23 16:03:18.000000000 -0600
@@ -0,0 +1,162 @@
+<?php
+// $Id: emvideo.theme.inc,v 1.1.2.9 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ * This defines the various theme functions for Embedded Video Field (emvideo).
+ */
+
+/**
+ * Formatter for emvideo_video_embed.
+ * This will return the 'embed code', typically used to embed media in an
+ * external site or blog.
+ */
+function theme_emvideo_video_embed($field, $item, $formatter, $node, $options = array()) {
+  /*
+    Note you can use this in node.tpl.php, substituting the proper field type:
+    $field_type = 'field_video';
+    $system_types = _content_type_info();
+    $field = $system_types['fields'][$field_type];
+    $field['widget'] = $system_types['content types'][$node->type]['fields'][$field_type]['widget'];
+    print theme('emvideo_video_embed', $field, $node->{$field_type}[0], 'emvideo_embed', $node);
+
+    or you can set $field to NULL and just use the options array
+   */
+  if ($item['value'] && $item['provider']) {
+    $output = drupal_get_form('emvideo_embed_form', $field, $item, $formatter, $node, $options);
+  }
+
+  return $output;
+}
+
+/**
+ * This will return a provided thumbnail image for a video.
+ *
+ * @param $field
+ *   This is the field providing settings for the video thumbnail.
+ * @param $item
+ *   This is the data returned by the field. It requires at the least to be an array with 'value' and 'provider'.
+ *   $item['value'] will be the video code, and $item['provider'] will be the provider, such as youtube.
+ * @param $formatter
+ *   This is the formatter for the view. This will nearly always be video_thumbnail.
+ * @param $node
+ *   This is the node object containing the field.
+ * @param $no_link
+ *   Optional. If FALSE, then we provide a link to the node.
+ *   (In retrospect, this should have been $link, defaulting to TRUE.
+ *   TODO: fix? problem though is that this goes deeper up the tree.)
+ * @param $options
+ *   Optional array. This is to pass optional overrides. currently:
+ *     $options['width'] and $options['height'], if provided, will override any field settings for the thumbnail w/h.
+ *     $options['link_url'], if provided, will cause the thumbnail link to go to another URL other than node/nid. $no_link must be FALSE.
+ *     $options['link_title'], if provided, will set the title of the link when no image is provided. otherwise, it defaults to 'See video'.
+ *     $options['image_title'], if provided, will set the title attribute of the href link, defaulting to $options['link_title'].
+ *     $options['image_alt'], if provided, will set the alt attribute of the href link, defaulting to $options['link_title'].
+ *     $options['thumbnail_url'], if provided, will completely override the thumbnail image entirely.
+ */
+function theme_emvideo_video_thumbnail($field, $item, $formatter, $node, $no_link = FALSE, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    // If we've set $options['thumbnail_url'], then we'll just use that.
+    // Otherwise, if we have emthumb installed, then give it a chance to override our thumbnail
+    $thumbnail_url = $options['thumbnail_url'] ? $options['thumbnail_url'] : module_invoke('emthumb', 'thumbnail_url', $item);
+
+    // if we don't have a custom thumbnail, then see if the provider gives us a thumbnail
+    $thumbnail_url = $thumbnail_url ? $thumbnail_url : _emfield_generic_include_invoke('emfield_generic', 'emvideo', $item['provider'], 'thumbnail', $field, $item, $formatter, $node, $width, $height, $options);
+
+    // If we still don't have a thumbnail, then apply a default thumbnail, if it exists.
+    if (!$thumbnail_url) {
+      $default_thumbnail_url = $field['widget']['thumbnail_default_path'] ? $field['widget']['thumbnail_default_path'] : variable_get('emvideo_default_thumbnail_path', NULL);
+
+      if ($default_thumbnail_url) {
+        $thumbnail_url = base_path() . $default_thumbnail_url;
+      }
+    }
+  }
+  else {
+    // Seems to be an unknown video. Apply a default thumbnail, if it exists.
+    if (!$thumbnail_url) {
+      $default_thumbnail_url = $field['widget']['thumbnail_default_path'] ? $field['widget']['thumbnail_default_path'] : variable_get('emvideo_default_thumbnail_path', NULL);
+      if ($default_thumbnail_url) {
+        $thumbnail_url = base_path() . $default_thumbnail_url;
+      }
+    }
+  }
+
+  $link_url = isset($options['link_url']) ? $options['link_url'] : 'node/'. $node->nid;
+  $link_title = isset($options['link_title']) ? $options['link_title'] : t('See video');
+  $image_title = isset($options['image_title']) ? $options['image_title'] : $link_title;
+  $image_alt = isset($options['image_alt']) ? $options['image_alt'] : $link_title;
+
+  if ($thumbnail_url) {
+    $width = isset($options['width']) ? $options['width'] : NULL;
+    $width = isset($width) ? $width : ($field['widget']['thumbnail_width'] ? $field['widget']['thumbnail_width'] : variable_get('emvideo_default_thumbnail_width', EMVIDEO_DEFAULT_THUMBNAIL_WIDTH));
+    $height = isset($options['height']) ? $options['height'] : NULL;
+    $height = isset($height) ? $height : ($field['widget']['thumbnail_height'] ? $field['widget']['thumbnail_height'] : variable_get('emvideo_default_thumbnail_height', EMVIDEO_DEFAULT_THUMBNAIL_HEIGHT));
+    if ($no_link) { //thickbox requires the thumbnail returned without the link
+      $output = '<img src="'. $thumbnail_url .'" width="'. $width  .'" height="'. $height  .'" alt="'. $image_alt .'" title="'. $image_title .'" />';
+    }
+    else {
+      $output = l('<img src="'. $thumbnail_url .'" width="'. $width  .'" height="'. $height  .'" alt="'. $image_alt .'" title="'. $image_title .'" />', $link_url, array('html'=> TRUE));
+    }
+  }
+  else {
+     // if all else fails, then just print a 'see video' link.
+    if ($no_link) {
+      $output = ''; //thickbox won't work without a thumbnail
+    }
+    else {
+      $output = l($link_title, $link_url);
+    }
+  }
+
+  return $output;
+}
+
+function theme_emvideo_video_video($field, $item, $formatter, $node, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    $embed = $item['value'];
+    $width = $options['width'] ? $options['width'] : ($field['widget']['video_width'] ? $field['widget']['video_width'] : variable_get('emvideo_default_video_width', EMVIDEO_DEFAULT_VIDEO_WIDTH));
+    $height = $options['height'] ? $options['height'] : ($field['widget']['video_height'] ? $field['widget']['video_height'] : variable_get('emvideo_default_video_height', EMVIDEO_DEFAULT_VIDEO_HEIGHT));
+    $autoplay = $options['autoplay'] ? $options['autoplay'] : $field['widget']['video_autoplay'];
+    $output = _emfield_generic_include_invoke('emfield_generic','emvideo',$item['provider'], 'video', $embed, $width, $height, $field, $item, $autoplay, $options); 
+    
+  }
+
+  return $output;
+}
+
+function theme_emvideo_default($field, $item, $formatter, $node, $options = array()) {
+  return theme('emvideo_video_video', $field, $item, $formatter, $node, $options);
+}
+
+function theme_emvideo_video_preview($field, $item, $formatter, $node, $options = array()) {
+  if ($item['value'] && $item['provider']) {
+    $embed = $item['value'];
+    $width = $options['width'] ? $options['width'] : ($field['widget']['preview_width'] ? $field['widget']['preview_width'] : variable_get('emvideo_default_preview_width', EMVIDEO_DEFAULT_PREVIEW_WIDTH));
+    $height = $options['height'] ? $options['height'] : ($field['widget']['preview_height'] ? $field['widget']['preview_height'] : variable_get('emvideo_default_preview_height', EMVIDEO_DEFAULT_PREVIEW_HEIGHT));
+    $autoplay = $options['autoplay'] ? $options['autoplay'] : $field['widget']['preview_autoplay'];
+    $output = _emfield_generic_include_invoke('emfield_generic','emvideo', $item['provider'], 'preview', $embed, $width, $height, $field, $item, $autoplay, $options);
+  }
+
+  return $output;
+}
+
+function theme_emvideo_thickbox($field, $item, $formatter, $node, $options = array()) {
+  $thumbnail = theme('emvideo_video_thumbnail', $field, $item, 'video_thumbnail', $node, TRUE, $options);
+
+  $destination = 'emvideo/thickbox/'. $node->nid .'/'. $field['widget']['video_width'] .'/'. $field['widget']['video_height'] .'/'. $field['field_name'];
+  $options = array(
+    'attributes' => array(
+      'title' => $title,
+      'class' => 'thickbox',
+      'rel' => $field['type_name'],
+    ),
+    'query' => NULL,
+    'fragment' => NULL,
+    'absolute' => FALSE,
+    'html' => TRUE,
+  );
+  $output = l($thumbnail, $destination, $options);
+
+  return $output;
+}
\ No newline at end of file
diff -urpN contrib/emfield_generic/providers/emaudio/odeo.inc contrib/emfield_generic/providers/emaudio/odeo.inc
--- contrib/emfield_generic/providers/emaudio/odeo.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emaudio/odeo.inc	2008-11-23 12:00:44.000000000 -0600
@@ -0,0 +1,168 @@
+<?php
+// $Id: odeo.inc,v 1.1.4.5 2008/10/08 17:39:08 alexua Exp $
+
+/**
+ * @file
+ * This include processes Odeo audio files for use by emaudio.module.
+ */
+
+define('EMAUDIO_ODEO_MAIN_URL', 'http://odeo.com/');
+/**
+ * Implementation of hook emaudio_odeo_info().
+ *
+ * This returns information relevant to a specific 3rd party audio provider.
+ *
+ * @return
+ *   An array of strings requested by various admin and other forms.
+ *   'name' => The translated name of the provider.
+ *   'url' => The url to the main page for the provider.
+ *   'settings_description' => A description of the provider that will be posted in the admin settings form.
+ *   'supported_features' => An array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emaudio_odeo_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+  return array(
+    'provider' => 'odeo',
+    'name' => t('odeo'),
+    'url' => EMAUDIO_ODEO_MAIN_URL,
+    'settings_description' => t('These settings specifically affect audio podcasts displayed from <a href="@odeo" target="_blank">odeo</a>.', array('@odeo' => EMAUDIO_ODEO_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * Implementation of hook emaudio_odeo_settings().
+ *
+ * This should return a subform to be added to the emaudio_settings() admin settings page.
+ * Note that a form field will already be provided, at $form['odeo'] (such as $form['podomatic']).
+ * So if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emaudio_odeo_settings() {
+  $form = array();
+
+  return $form;
+}
+
+/**
+ * Implementation of hook emaudio_odeo_extract().
+ *
+ * This is called to extract the video code from a pasted URL or embed code.
+ *
+ * @param $embed
+ *   An optional string with the pasted URL or embed code.
+ * @return
+ *   Either an array of regex expressions to be tested, or a string with the
+ *   audio code to be used. If the hook tests the code itself, it should return
+ *   either the string of the audio code (if matched), or an empty array.
+ *   Otherwise, the calling function will handle testing the embed code against
+ *   each regex string in the returned array.
+ */
+function emaudio_odeo_extract($embed = '') {
+  return array(
+    '@odeo\.com/audio/([0-9]+)/@i',
+    '@href="http://odeo.com/audio/([0-9]+)/@i',
+  );
+}
+
+/**
+ * The embedded flash displaying the odeo audio.
+ *
+ * Default width is 322, height is 54.
+ */
+function theme_emaudio_odeo_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    /*
+    if ($autoplay) {
+      $autoplay_value = '&autostart=1';
+    }
+    */
+
+    $output .= "
+      <object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,47,0\"width=\"$width\" height=\"$height\" id=\"wimpy\" align=\"center\">
+      <param name=\"quality\" value=\"high\" />
+      <param name=\"width\" value=\"$width\" />
+      <param name=\"height\" value=\"$height\" />
+      <param name=\"name\" value=\"odeo_player_black\" />
+      <param name=\"allowScriptAccess\" value=\"always\" />
+      <param name=\"wmode\" value=\"transparent\" />
+      <embed src=\"http://odeo.com/flash/audio_player_black.swf\"
+      quality=\"high\" width=\"322\" height=\"54\"
+      name=\"odeo_player_black\" align=\"middle\"
+      allowScriptAccess=\"always\" wmode=\"transparent\"
+      type=\"application/x-shockwave-flash\" flashvars=\"type=audio&id=". $embed ."\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />
+      </object>
+    \n";
+  }
+
+  return $output;
+}
+
+/**
+ * Implementation of hook emaudio_odeo_thumbnail().
+ *
+ * Returns the external url for a thumbnail of a specific audio.
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things.
+ *
+ * @param $field
+ *   The field of the requesting node.
+ * @param $item
+ *   The actual content of the field from the requesting node.
+ * @return
+ *   A URL pointing to the thumbnail.
+ */
+function emaudio_odeo_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return $tn;
+}
+
+/**
+ * Implementation of hook emaudio_odeo_audio().
+ *
+ * This actually displays the full/normal-sized video we want, usually on the default page view.
+ *
+ * @param $embed
+ *   The video code for the audio to embed.
+ * @param $width
+ *   The width to display the audio.
+ * @param $height
+ *   The height to display the audio.
+ * @param $field
+ *   The field info from the requesting node.
+ * @param $item
+ *   The actual content from the field.
+ * @return
+ *   The html of the embedded audio.
+ */
+function emaudio_odeo_audio($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_odeo_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
+
+/**
+ * Implementation of hook emaudio_odeo_preview().
+ *
+ * This actually displays the preview-sized video we want, commonly for the teaser.
+ *
+ * @param $embed
+ *   The video code for the audio to embed.
+ * @param $width
+ *   The width to display the audio.
+ * @param $height
+ *   The height to display the audio.
+ * @param $field
+ *   The field info from the requesting node.
+ * @param $item
+ *   The actual content from the field.
+ * @return
+ *   The html of the embedded audio.
+ */
+function emaudio_odeo_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_odeo_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
diff -urpN contrib/emfield_generic/providers/emaudio/podcastalley.inc contrib/emfield_generic/providers/emaudio/podcastalley.inc
--- contrib/emfield_generic/providers/emaudio/podcastalley.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emaudio/podcastalley.inc	2008-11-23 12:00:44.000000000 -0600
@@ -0,0 +1,167 @@
+<?php
+// $Id: podcastalley.inc,v 1.1.4.5 2008/10/08 17:39:08 alexua Exp $
+
+/**
+ * @file
+ * This include processes Podcastalley audio files for use by emaudio.module.
+ */
+
+define('EMAUDIO_PODCASTALLEY_MAIN_URL', 'http://www.podcastalley.com');
+/**
+ * Implementation of hook emaudio_podcastalley_info().
+ *
+ * This returns information relevant to a specific 3rd party audio provider.
+ *
+ * @return
+ *   An array of strings requested by various admin and other forms.
+ *   'name' => The translated name of the provider.
+ *   'url' => The url to the main page for the provider.
+ *   'settings_description' => A description of the provider that will be posted in the admin settings form.
+ *   'supported_features' => An array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emaudio_podcastalley_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+
+  return array(
+    'provider' => 'Podcast Alley',
+    'name' => t('Podcast Alley'),
+    'url' => EMAUDIO_PODCASTALLEY_MAIN_URL,
+    'settings_description' => t('These settings specifically affect audio podcasts displayed from <a href="@podcastalley" target="_blank">Podcast Alley</a>.', array('@podcastalley' => EMAUDIO_PODCASTALLEY_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * Implementation of hook emaudio_podcastalley_settings().
+ *
+ * This should return a subform to be added to the emaudio_settings() admin settings page.
+ * Note that a form field will already be provided, at $form['podcastalley'].
+ * So if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emaudio_podcastalley_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * Implementation of hook emaudio_podcastalley_extract().
+ *
+ * This is called to extract the video code from a pasted URL or embed code.
+ *
+ * @param $embed
+ *   An optional string with the pasted URL or embed code.
+ * @return
+ *   Either an array of regex expressions to be tested, or a string with the
+ *   audio code to be used. If the hook tests the code itself, it should return
+ *   either the string of the audio code (if matched), or an empty array.
+ *   Otherwise, the calling function will handle testing the embed code against
+ *   each regex string in the returned array.
+ */
+function emaudio_podcastalley_extract($embed = '') {
+  // http://www.podcastalley.com/podcast_details.php?pod_id=929#
+  return array(
+      '@podcastalley\.com/podcast_details\.php\?pod_id=([0-9]+)@i'
+  );
+}
+
+/**
+ * The embedded flash displaying the podcastalley audio.
+ *
+ * Default width is 419, height is 202.
+ */
+function theme_emaudio_podcastalley_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    /*
+    if ($autoplay) {
+      $autoplay_value = '&autostart=1';
+    }
+    */
+    $output .= "
+        <object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,47,0\"width=\"$width\" height=\"$height\" id=\"wimpy\" align=\"center\">
+      <param name=\"allowScriptAccess\" value=\"sameDomain\" />
+      <param name=\"movie\" value=\"http://www.podcastalley.com/player/wimpy.swf?wimpyApp=http://www.podcastalley.com/player/playlist.php?pod_id=". $embed ."&u=1.xml&wimpySkin=http://www.podcastalley.com/player/paskin.xml&wW=419&wH=202&forceXMLplaylist=yes&defaultVisualExt=jpg&theVolume=100&bufferAudio=0&infoDisplayTime=3&iTextStyle=scroller&startPlayingOnload=yes&popUpHelp=no\" />
+
+      <param name=\"loop\" value=\"false\" />
+      <param name=\"menu\" value=\"false\" />
+      <param name=\"quality\" value=\"high\" />
+      <param name=\"scale\" value=\"noscale\" />
+      <param name=\"salign\" value=\"lt\" />
+      <param name=\"bgcolor\" value=\"#000000\" />
+      <embed src=\"http://www.podcastalley.com/player/wimpy.swf?wimpyApp=http://www.podcastalley.com/player/playlist.php?pod_id=". $embed ."&u=1.xml&wimpySkin=http://www.podcastalley.com/player/paskin.xml&wW=419&wH=202&forceXMLplaylist=yes&defaultVisualExt=jpg&theVolume=100&bufferAudio=0&infoDisplayTime=3&iTextStyle=scroller&startPlayingOnload=yes&popUpHelp=no\" loop=\"false\" menu=\"false\" quality=\"high\" width=\"419\" height=\"202\" scale=\"noscale\" salign=\"lt\" name=\"wimpy\" align=\"center\" bgcolor=\"#000000\" allowScriptAccess=\"sameDomain\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />
+    </object>
+    \n";
+  }
+
+  return $output;
+}
+
+/**
+ * Implementation of hook emaudio_podcastalley_thumbnail.
+ *
+ * Returns the external url for a thumbnail of a specific audio.
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things.
+ *
+ * @param $field
+ *   The field of the requesting node.
+ * @param $item
+ *   The actual content of the field from the requesting node.
+ * @return
+ *   A URL pointing to the thumbnail.
+ */
+function emaudio_podcastalley_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return $tn;
+}
+
+/**
+ * Implementation of hook emaudio_podcastalley_audio().
+ *
+ * This actually displays the full/normal-sized video we want,
+ * usually on the default page view.
+ *
+ * @param $embed
+ *   The video code for the audio to embed.
+ * @param $width
+ *   The width to display the audio.
+ * @param $height
+ *   The height to display the audio.
+ * @param $field
+ *   The field info from the requesting node.
+ * @param $item
+ *   The actual content from the field.
+ * @return
+ *   The html of the embedded audio.
+ */
+function emaudio_podcastalley_audio($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_podcastalley_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
+
+/**
+ * Implementation of hook emaudio_podcastalley_preview().
+ *
+ * This actually displays the preview-sized video we want, commonly for the teaser.
+ *
+ * @param $embed
+ *   The video code for the audio to embed.
+ * @param $width
+ *   The width to display the audio.
+ * @param $height
+ *   The height to display the audio.
+ * @param $field
+ *   The field info from the requesting node.
+ * @param $item
+ *   The actual content from the field.
+ * @return
+ *   The html of the embedded audio.
+ */
+function emaudio_podcastalley_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_podcastalley_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
diff -urpN contrib/emfield_generic/providers/emaudio/podomatic.inc contrib/emfield_generic/providers/emaudio/podomatic.inc
--- contrib/emfield_generic/providers/emaudio/podomatic.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emaudio/podomatic.inc	2008-11-23 12:00:44.000000000 -0600
@@ -0,0 +1,176 @@
+<?php
+// $Id: podomatic.inc,v 1.1.4.7 2008/10/11 19:05:26 alexua Exp $
+
+/**
+ * @file
+ * This include processes Podomatic audio files for use by emaudio.module.
+ */
+
+define('EMAUDIO_PODOMATIC_MAIN_URL', 'http://www.podomatic.com/');
+
+/**
+ * hook emaudio_PROVIDER_info
+ * this returns information relevant to a specific 3rd party audio provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emaudio_podomatic_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+  return array(
+    'provider' => 'podomatic',
+    'name' => t('podOmatic'),
+    'url' => EMAUDIO_PODOMATIC_MAIN_URL,
+    'settings_description' => t('These settings specifically affect audio podcasts displayed from <a href="@podomatic" target="_blank">podOmatic</a>.', array('@podomatic' => EMAUDIO_PODOMATIC_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emaudio_PROVIDER_settings
+ * this should return a subform to be added to the emaudio_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['podomatic'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emaudio_podomatic_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * hook emaudio_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the audio code to be used
+ *   if the hook tests the code itself, it should return either the string of the audio code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emaudio_podomatic_extract($embed = '') {
+  // http://www.podomatic.com/podcast/embed/funkylondon
+  // <object width="320" height="315"><param name="movie" value="http://www.podOmatic.com/flash/flashcatcher.swf"></param><embed type="application/x-shockwave-flash" src="http://www.podOmatic.com/flash/flashcatcher.swf" width="320" height="315" flashvars="playlist_url=http://funkylondon.podOmatic.com/xspf.xspf" ></embed></object><br /><a href="http://www.podOmatic.com/podcast/embed/funkylondon" style="text-decoration: none"><font size="1" face="Verdana, Arial, Helvetica, sans-serif" color="#0033ff"><strong>Click here to get your own player.</strong></font></a><br><br>
+  // http://funkylondon.podomatic.com
+  return array(
+    '@podomatic\.com/podcast/embed/([^"\&]+)@i',
+    '@playlist_url\=http://([^\.]+)\.podOmatic\.com@i',
+    '@http://([^\.]+)\.podomatic\.com@i',
+  );
+}
+
+/**
+ * hook emaudio_PROVIDER_embedded_link($audio_code)
+ * returns a link to view the audio at the provider's site
+ *  @param $audio_code
+ *    the string containing the audio to watch
+ *  @return
+ *    a string containing the URL to view the audio at the original provider's site
+ */
+function emaudio_podomatic_embedded_link($audio_code) {
+  return 'http://www.podomatic.com/podcast/embed/'. $audio_code;
+}
+
+/**
+ * hook theme_emaudio_PROVIDER_flash
+ * the embedded flash displaying the podomatic audio
+ */
+ 
+function theme_emaudio_podomatic_flash($code, $width, $height, $field, $item, $autoplay, $flv, $thumbnail, $options = array()) {
+  // <object width="320" height="315"><param name="movie" value="http://www.podOmatic.com/flash/flashcatcher.swf"></param><embed type="application/x-shockwave-flash" src="http://www.podOmatic.com/flash/flashcatcher.swf" width="320" height="315" flashvars="playlist_url=http://funkylondon.podOmatic.com/xspf.xspf" ></embed></object><br /><a href="http://www.podOmatic.com/podcast/embed/funkylondon" style="text-decoration: none"><font size="1" face="Verdana, Arial, Helvetica, sans-serif" color="#0033ff"><strong>Click here to get your own player.</strong></font></a><br><br>
+
+  if ($code) {
+/*    if ($autoplay) {
+      $autoplay_value = '&autostart=1';
+    }*/
+    $output .= 
+    '<object type=\"application/x-shockwave-flash\" height=\"$height\" width=\"$width\" data=\"http://www.podOmatic.com/flash/flashcatcher.swf\" id=\"audioPlayback\">
+      <param name=\"movie\" value=\"http://www.podOmatic.com/flash/flashcatcher.swf\">
+      <param name=\"allowScriptAcess\" value=\"sameDomain\">
+      <param name=\"quality\" value=\"best\">
+      <param name=\"bgcolor\" value=\"#FFFFFF\">
+      <param name=\"scale\" value=\"noScale\">
+      <param name=\"salign\" value=\"TL\">
+      <param name=\"FlashVars\" value=\"playlist_url=http://". $embed .".podOmatic.com/xspf.xspf\" />
+      <param name=\"wmode\" value=\"transparent\" />
+    </object>\n';
+  }
+  return $output;
+}
+
+/**
+ * hook emaudio_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific audio
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emaudio_podomatic_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return $tn;
+}
+
+/**
+ * hook emaudio_PROVIDER_audio
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the audio to embed
+ *  @param $width
+ *    the width to display the audio
+ *  @param $height
+ *    the height to display the audio
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded audio
+ */
+function emaudio_podomatic_audio($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_podomatic_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emaudio_PROVIDER_preview
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the audio to embed
+ *  @param $width
+ *    the width to display the audio
+ *  @param $height
+ *    the height to display the audio
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded audio
+ */
+function emaudio_podomatic_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emaudio_podomatic_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emaudio_podomatic_subtheme() {
+  return array (
+    'emaudio_podomatic_flash'  => array(
+            'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+            'file' => 'providers/podomatic.inc'
+        )
+    );
+}
+
diff -urpN contrib/emfield_generic/providers/emimage/flickr.inc contrib/emfield_generic/providers/emimage/flickr.inc
--- contrib/emfield_generic/providers/emimage/flickr.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emimage/flickr.inc	2008-11-27 10:09:28.000000000 -0600
@@ -0,0 +1,240 @@
+<?php
+// $Id: flickr.inc,v 1.1.2.5 2008/11/12 18:46:18 aaron Exp $
+
+/**
+ * @file
+ * This include processes flickr.com image files for use by emfield.module.
+ */
+
+define('EMIMAGE_FLICKR_MAIN_URL', 'http://www.flickr.com/');
+define('EMIMAGE_FLICKR_API_INFO', 'http://flickr.com/services/api');
+define('EMIMAGE_FLICKR_API_APPLICATION_URL', 'http://www.flickr.com/services/api/keys');
+define('EMIMAGE_FLICKR_REST_ENDPOINT', 'http://api.flickr.com/services/rest/');
+
+/**
+ * hook emimage_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+
+function emimage_flickr_info() {
+  $features = array(
+    array(t('Import photosets'), t('Yes'), t('If you have the Embedded Media Import module activated, you may allow @name photosets to be imported into content.', array('@name' => $name))),
+  );
+  return array(
+    'provider' => 'flickr',
+    'name' => t('Flickr'),
+    'url' => EMIMAGE_FLICKR_MAIN_URL,
+    'settings_description' => t('These settings specifically affect images displayed from <a href="@flickr" target="_blank">Flickr</a>.', array('@flickr' => EMIMAGE_FLICKR_MAIN_URL)),
+    'supported_features' => $features,
+    'import_sets_word' => t('photosets'),
+  );
+}
+
+/**
+ *  This allows flickr photosets to be imported into nodes
+ */
+function emimage_flickr_import($url, $limit = 0, $page = 0) {
+  $codes = array();
+
+  // http://www.flickr.com/photos/nikkiana/sets/72157601948647678/
+  if (preg_match('@flickr\.com/photos/([^/]*)/([^/]*)/([^/]*)/@i', $url, $matches)) {
+    $page++;  // flickr starts current page at 1
+    $codes['#matches'] = $matches;
+    $args = array('photoset_id' => $matches[3]);
+    if ($limit) {
+      $args['per_page'] = $limit;
+    }
+    $args['page'] = $page;
+    $xml = emimage_flickr_request('flickr.photosets.getPhotos', $args);
+//    print_r($xml);
+    $codes['#pages'] = $xml['photoset']['pages'];
+    $codes['#page'] = $xml['photoset']['page'] - 1;
+    $codes['#total'] = $xml['photoset']['total'];
+    $codes['#per_page'] = $xml['photoset']['per_page'];
+    $codes['#set'] = array();
+    foreach ($xml['photoset']['photo'] as $photo) {
+      $data = emimage_flickr_data(NULL, array('value' => $photo['id']));
+      $codes['#set'][] = array(
+        '#code' => $photo['id'],
+        '#title' => $photo['title'],
+        '#link' => emimage_flickr_embedded_link($photo['id'], $xml['photoset']['owner']),
+        '#thumb' => emimage_flickr_image_url($photo['id'], 100, 100, NULL, NULL, NULL),
+        '#body' => $data['description'],
+        '#tags' => $data['tags'],
+//         '#body' => emimage_flickr_description($photo['id']),
+//         '#tags' => emimage_flickr_tags($photo['id']),
+      );
+    }
+/*
+    $data['owner'] = $xml['photo']['owner']['nsid'];
+    $data['title'] = $xml['photo']['title']['_content'];*/
+  }
+// print_r($codes);
+  return $codes;
+}
+
+/**
+ * hook emimage_PROVIDER_settings
+ * this should return a subform to be added to the emimage_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['flickr'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emimage_flickr_settings() {
+  $form['flickr']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Flickr API'),
+    '#description' => t('You will first need to apply for an API Developer Key from the <a href="@flickr" target="_blank">Flickr Developer Profile page</a>.', array('@flickr' => EMIMAGE_FLICKR_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => (variable_get('emimage_flickr_api_key', '') != ''),
+  );
+  $form['flickr']['api']['emimage_flickr_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Flickr API Key'),
+    '#default_value' => variable_get('emimage_flickr_api_key', ''),
+    '#description' => t('Please enter your Flickr Developer Key here.'),
+  );
+  $form['flickr']['api']['emimage_flickr_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Flickr API Secret'),
+    '#default_value' => variable_get('emimage_flickr_api_secret', ''),
+    '#description' => t('If you have a secret for the Flickr API, enter it here.'),
+  );
+  return $form;
+}
+
+
+/**
+ * this is a wrapper for emimage_request_xml that includes flickr's api key
+ */
+function emimage_flickr_request($method, $args = array(), $cached = TRUE) {
+  // display an error if we don't have an api key yet
+  emimage_flickr_error_check();
+
+  $args['api_key'] = trim(variable_get('emimage_flickr_api_key', ''));
+  if ($secret = trim(variable_get('emimage_flickr_api_secret', ''))) {
+    $args['secret'] = md5($secret . $arghash);
+  }
+  $args['method'] = $method;
+  $args['format'] = 'php_serial';
+
+  $xml = module_invoke('emfield', 'request_xml', 'flickr', EMIMAGE_FLICKR_REST_ENDPOINT, $args, $cached, FALSE, FALSE, TRUE);
+  return $xml;
+}
+
+function emimage_flickr_data($field, $item) {
+  $data = array();
+
+  // use the page id, since we'll have that in most cases (except in embed pastes, which gets parsed during extraction)
+  // we use this to get an rss feed w/ all the info for the video. interesting reading ;)
+  $xml = emimage_flickr_request('flickr.photos.getInfo', array('photo_id' => $item['value']));
+
+  $data['owner'] = $xml['photo']['owner']['nsid'];
+  $data['title'] = $xml['photo']['title']['_content'];
+  $data['description'] = $xml['photo']['description']['_content'];
+  $data['tags'] = array();
+  if (is_array($xml['photo']['tags']['tag'])) {
+    foreach ($xml['photo']['tags']['tag'] as $tag) {
+      $data['tags'][] = $tag['raw'];
+    }
+  }
+  return $data;
+}
+
+/**
+ *  This will log an error if we don't have a key yet. In addition, if the user is an admin, we'll display an error.
+ */
+function emimage_flickr_error_check() {
+  static $checked;
+  if (!$checked && (variable_get('emimage_flickr_api_key', '') == '')) {
+    global $user;
+    $error = t('You do not yet have a Flickr API key set. You will need to <a href="@apply" target="_blank">apply for a Flickr API key</a> and enter your key at the <a href="@settings">settings administration page</a> before Flickr images may be displayed.', array('@apply' => EMIMAGE_FLICKR_API_APPLICATION_URL, '@settings' => url('admin/content/emfield')));
+    if (user_access('administer site configuration')) {
+      drupal_set_message($error, 'error');
+    }
+    watchdog('Embedded Media Field', '!error', array('!error' => $error));
+  }
+  $checked = TRUE;
+}
+
+function emimage_flickr_extract($embed = '') {
+  // http://flickr.com/photos/96898796@N00/194727976/
+  return array('@flickr\.com/photos/[^/]*/(\d+)@i');
+}
+
+/**
+ * hook emimage_PROVIDER_embedded_link($code)
+ * returns a link to view the content at the provider's site
+ *  @param $code
+ *    the string containing the content to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emimage_flickr_embedded_link($code, $data = array()) {
+  if ($data['owner']) {
+    $owner = $data['owner'];
+  }
+  else {
+    $xml = emimage_flickr_request('flickr.photos.getInfo', array('photo_id' => $code));
+    $owner = $xml['photo']['owner']['nsid'];
+  }
+  return 'http://www.flickr.com/photos/'. $owner .'/'. $code;
+}
+
+/**
+ *  Implements emimage_PROVIDER_image_url.
+ *
+ *  @param $code
+ *    The provider code of the image.
+ *  @param $width
+ *  @param $height
+ *    The dimensions of the photo to display.
+ *  @return
+ *    The url directly to the image to display.
+ */
+function emimage_flickr_image_url($code, $width, $height, $formatter = NULL, $field = NULL, $item = NULL, $node = NULL) {
+  if ($code) {
+    $size = _emimage_flickr_guess_size($width, $height);
+    $getsize = emimage_flickr_request('flickr.photos.getSizes', array('photo_id' => $code));
+    $url = $getsize['sizes']['size'][$size]['source'];
+  }
+  return $url;
+}
+
+/**
+ *  Implements emimage_PROVIDER_image_title.
+ *
+ *  @param $code
+ *    The provider code of the image.
+ *  @param $data
+ *    Any stored data for the image, which may already have the title.
+ *  @return
+ *    The title as the 3rd party provider knows it, if accessible to us. otherwise, ''.
+ */
+function emimage_flickr_image_title($code, $data) {
+  if ($data['title']) {
+    return $data['title'];
+  }
+  $photo = emimage_flickr_request('flickr.photos.getInfo', array('photo_id' => $code));
+  return $photo['photo']['title']['_content'] ? $photo['photo']['title']['_content'] : '';
+}
+
+/**
+ *  Helper function for emimage_flickr_image_url.
+ *  This will return the appropriate array key for the image size we wish.
+ */
+function _emimage_flickr_guess_size($width, $height) {
+  $max = max($width, $height);
+  foreach (array('0' => 75, '1' => 100, '2' => 240, '3' => 500, '4' => 1024) as $size => $value) {
+    if ($max <= $value) {
+      return $size;
+    }
+  }
+  return '5';
+}
diff -urpN contrib/emfield_generic/providers/emimage/imageshack.inc contrib/emfield_generic/providers/emimage/imageshack.inc
--- contrib/emfield_generic/providers/emimage/imageshack.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emimage/imageshack.inc	2008-11-23 12:00:46.000000000 -0600
@@ -0,0 +1,123 @@
+<?php
+// $Id: imageshack.inc,v 1.1.2.4 2008/10/08 17:39:09 alexua Exp $
+
+/**
+ * @file
+ * This include processes imageshack.com image files for use by emfield.module.
+ */
+
+define('EMIMAGE_IMAGESHACK_MAIN_URL', 'http://www.imageshack.us/');
+
+/**
+ * hook emimage_PROVIDER_info
+ * this returns information relevant to a specific 3rd party image provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+
+function emimage_imageshack_info() {
+  $features = array();
+  return array(
+    'provider' => 'imageshack',
+    'name' => t('ImageShack'),
+    'url' => EMIMAGE_IMAGESHACK_MAIN_URL,
+    'settings_description' => t('These settings specifically affect images displayed from <a href="@imageshack" target="_blank">ImageShack</a>.', array('@imageshack' => EMIMAGE_IMAGESHACK_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emimage_imageshack_data($field, $item) {
+  $data = array();
+
+  $url = stristr($item['embed'], 'my.php?image=')? _emimage_imageshack_scrape_image_url($item['embed']) : $item['embed'];
+  if (preg_match('!([^/.:@]+)\.imageshack\.us/([^/]+)/([^/]+)/(.+)$!i', $url, $matches)) {
+    $data = array(
+      'server' => $matches[1],
+      'a1' => $matches[2],
+      'a2' => $matches[3],
+      'file' => $matches[4],
+      'title' => '',
+    );
+  }
+  return $data;
+}
+
+function emimage_imageshack_extract($embed = '') {
+  // http://img255.imageshack.us/my.php?image=dscn0036ky1.jpg
+  // http://img255.imageshack.us/img255/7682/dscn0036ky1.jpg
+  if (preg_match('!([^/.:@]+)\.imageshack\.us/(([^/]+)/([^/]+)/|my.php\?image=)?(.+)$!i', $embed, $matches)) {
+    return $matches[5];
+  }
+
+  return array();
+}
+
+/**
+ * hook emimage_PROVIDER_embedded_link($code)
+ * returns a link to view the content at the provider's site
+ *  @param $code
+ *    the string containing the content to watch
+ *  @return
+ *    a string containing the URL to view the image at the original provider's site
+ */
+function emimage_imageshack_embedded_link($code, $data) {
+  return "http://{$data['server']}.imageshack.us/my.php?image={$code}";
+}
+
+/**
+ *  implement emimage_PROVIDER_image_url
+ *
+ *  @param $code
+ *    the code of the image
+ *  @param $data
+ *    any stored data for the image, which may already have the title
+ *  @return
+ *    the url directly to the image to display
+ */
+function emimage_imageshack_image_url($code, $data) {
+  if (func_num_args() == 7) {
+    $arg = func_get_arg(5);
+    $code = &$arg['data']['file'];
+    $data = &$arg['data'];
+  }
+  return "http://{$data['server']}.imageshack.us/{$data['a1']}/{$data['a2']}/{$code}";
+}
+
+/**
+ *  implement emimage_PROVIDER_image_title
+ *
+ *  @param $code
+ *    the code of the image
+ *  @param $data
+ *    any stored data for the image, which may already have the title
+ *  @return
+ *    the title as the 3rd party provider knows it, if accessible to us. otherwise, ''
+ */
+function emimage_imageshack_image_title($code, $data) {
+  return ''; // Not provided by on ImageShack.
+}
+
+/**
+ * Scrape the actual image URL from the ImageShack page.
+ *
+ * @param String $url
+ *   ImageShack page.
+ * @return String
+ *   ImageShack image URL.
+ */
+function _emimage_imageshack_scrape_image_url($url) {
+  static $urls;
+  if (isset($urls[$url])) {
+    return $urls[$url];
+  }
+
+  $html = file_get_contents($url);
+  if (preg_match('!<img id="thepic" .+? src="(.+?)"!is', $html, $matches)) {
+    return $urls[$url] = $matches[1];
+  }
+}
diff -urpN contrib/emfield_generic/providers/emimage/photobucket.inc contrib/emfield_generic/providers/emimage/photobucket.inc
--- contrib/emfield_generic/providers/emimage/photobucket.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emimage/photobucket.inc	2008-11-23 12:00:46.000000000 -0600
@@ -0,0 +1,124 @@
+<?php
+// $Id: photobucket.inc,v 1.1.2.4 2008/10/08 17:39:09 alexua Exp $
+
+/**
+ * @file
+ * This include processes photobucket.com image files for use by emfield.module.
+ */
+
+define('EMIMAGE_PHOTOBUCKET_MAIN_URL', 'http://www.photobucket.com/');
+
+/**
+ * hook emimage_PROVIDER_info
+ * this returns information relevant to a specific 3rd party image provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+
+function emimage_photobucket_info() {
+  $features = array();
+  return array(
+    'provider' => 'photobucket',
+    'name' => t('Photobucket'),
+    'url' => EMIMAGE_PHOTOBUCKET_MAIN_URL,
+    'settings_description' => t('These settings specifically affect images displayed from <a href="@photobucket" target="_blank">Photobucket</a>.', array('@photobucket' => EMIMAGE_PHOTOBUCKET_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emimage_photobucket_data($field, $item) {
+  $data = array();
+
+  if (preg_match('![si]([^/.:@]+)\.photobucket\.com/albums/([^/]+)/([^/]+)/(\?action=view&current=)?(.+)$!i', $item['embed'], $matches)) {
+    $data = array(
+      'server' => $matches[1],
+      'album' => $matches[2],
+      'owner' => $matches[3],
+      'file' => $matches[5],
+    );
+    $data['title'] = emimage_photobucket_image_title($data['file'], $data);
+  }
+  return $data;
+}
+
+function emimage_photobucket_extract($embed = '') {
+  // http://s201.photobucket.com/albums/aa274/layoutqueenie/?action=view&current=baileys_in_gardens.jpg
+  // http://i201.photobucket.com/albums/aa274/layoutqueenie/baileys_in_gardens.jpg
+  if (preg_match('![si]([^/.:@]+)\.photobucket\.com/albums/([^/]+)/([^/]+)/(\?action=view&current=)?(.+)$!i', $embed, $matches)) {
+    return $matches[5];
+  }
+  return array();
+}
+
+/**
+ * hook emimage_PROVIDER_embedded_link($code)
+ * returns a link to view the content at the provider's site
+ *  @param $code
+ *    the string containing the content to watch
+ *  @return
+ *    a string containing the URL to view the image at the original provider's site
+ */
+function emimage_photobucket_embedded_link($code, $data) {
+  return "http://s{$data['server']}.photobucket.com/albums/{$data['album']}/{$data['owner']}/?action=view&current={$code}";
+}
+
+/**
+ *  implement emimage_PROVIDER_image_url
+ *
+ *  @param $code
+ *    the code of the image
+ *  @param $data
+ *    any stored data for the image, which may already have the title
+ *  @return
+ *    the url directly to the image to display
+ */
+function emimage_photobucket_image_url($code, $data) {
+  if (func_num_args() == 7) {
+    $arg = func_get_arg(5);
+    $code = &$arg['data']['file'];
+    $data = &$arg['data'];
+  }
+
+  return "http://i{$data['server']}.photobucket.com/albums/{$data['album']}/{$data['owner']}/{$code}";
+}
+
+/**
+ *  implement emimage_PROVIDER_image_title
+ *
+ *  @param $code
+ *    the code of the image
+ *  @param $data
+ *    any stored data for the image, which may already have the title
+ *  @return
+ *    the title as the 3rd party provider knows it, if accessible to us. otherwise, ''
+ */
+function emimage_photobucket_image_title($code, $data) {
+  if ($data['title']) {
+    return $data['title'];
+  }
+  $url = emimage_photobucket_embedded_link($code, $data);
+  return _emimage_photobucket_scrape_image_title($url);
+}
+
+/**
+ * Visit the image URL and scrape the image title from HTML.
+ *
+ * @param String $url
+ *   Image URL.
+ * @return String
+ *   Image title.
+ */
+function _emimage_photobucket_scrape_image_title($url) {
+  static $title;
+  if (isset($title[$url])) {
+    return $title[$url];
+  }
+
+  $html = file_get_contents($url);
+  return $title[$url] = preg_match('@<span id="photoTitle">(.+?)</span>@is', $html, $matches)? $matches[1] : '';
+}
diff -urpN contrib/emfield_generic/providers/emimage/picasa.inc contrib/emfield_generic/providers/emimage/picasa.inc
--- contrib/emfield_generic/providers/emimage/picasa.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emimage/picasa.inc	2008-11-23 12:00:46.000000000 -0600
@@ -0,0 +1,161 @@
+<?php
+// $Id: picasa.inc,v 1.1.2.4 2008/10/08 17:39:09 alexua Exp $
+
+/**
+ * @file
+ * This include processes picasa.com image files for use by emfield.module.
+ */
+
+define('EMIMAGE_PICASA_MAIN_URL', 'http://picasaweb.google.com/');
+define('EMIMAGE_PICASA_API_INFO', 'http://code.google.com/apis/picasaweb/gdata.html');
+define('EMIMAGE_PICASA_REST_ENDPOINT', 'http://picasaweb.google.com/data/feed/api/user/');
+
+/**
+ * hook emimage_PROVIDER_info
+ * this returns information relevant to a specific 3rd party image provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+
+function emimage_picasa_info() {
+  $features = array(
+    array(t('Import photosets'), t('No'), ''),
+  );
+  return array(
+    'provider' => 'picasa',
+    'name' => t('Picasa'),
+    'url' => EMIMAGE_PICASA_MAIN_URL,
+    'settings_description' => t('These settings specifically affect images displayed from <a href="@picasa" target="_blank">Picasa</a>.', array('@picasa' => EMIMAGE_PICASA_MAIN_URL)),
+    'supported_features' => $features,
+    'import_sets_word' => t('photosets'),
+  );
+}
+
+/**
+ * This is a wrapper for image_cck_request_xml.
+ */
+function emimage_picasa_request($data = array(), $kind = '', $cached = TRUE) {
+  $args['kind'] = $kind;
+  $xml =  module_invoke('emfield', 'request_xml', 'picasa', EMIMAGE_PICASA_REST_ENDPOINT ."{$data['userid']}/album/{$data['album']}/photoid/{$data['photoid']}", $args, $cached, FALSE, ":{$data['userid']}:{$data['album']}?{$data['photoid']}");
+
+  return $xml;
+}
+
+function emimage_picasa_data($field, $item) {
+  $data = array();
+  if (preg_match('!picasaweb\.google\.com/([^/]*)/([^/]*)/photo\#(.*)!i', $item['embed'], $matches)) {
+    $data = array(
+      'userid' => $matches[1],
+      'album' => $matches[2],
+      'photoid' => $matches[3],
+    );
+  }
+  // use the page id, since we'll have that in most cases (except in embed pastes, which gets parsed during extraction)
+  // we use this to get an rss feed w/ all the info for the image. interesting reading ;)
+  $xml = emimage_picasa_request($data, 'tag');
+
+  $data['title'] = $xml['MEDIA:GROUP']['MEDIA:DESCRIPTION'][0];
+  $data['original'] = $xml['MEDIA:GROUP']['MEDIA:CONTENT'][1][URL];
+  $data['small'] = $xml['MEDIA:GROUP']['MEDIA:THUMBNAIL'][1][URL];
+  $data['medium'] = $xml['MEDIA:GROUP']['MEDIA:THUMBNAIL'][3][URL];
+  $data['large'] =  $xml['MEDIA:GROUP']['MEDIA:THUMBNAIL'][5][URL];
+  $data['width'] = $xml['MEDIA:GROUP']['MEDIA:THUMBNAIL'][5][WIDTH];
+  $data['height'] = $xml['MEDIA:GROUP']['MEDIA:THUMBNAIL'][5][HEIGHT];
+
+  return $data;
+}
+
+function emimage_picasa_extract($embed = '') {
+  // http://picasaweb.google.com/kaos777/YearlyKos/photo#5119063656501095090
+  if (preg_match('!picasaweb\.google\.com/([^/]*)/([^/]*)/photo\#(.*)!i', $embed, $matches)) {
+    return $matches[3];
+  }
+
+  return array();
+}
+
+/**
+ * hook emimage_PROVIDER_embedded_link($code)
+ * returns a link to view the content at the provider's site
+ *  @param $code
+ *    the string containing the content to watch
+ *  @return
+ *    a string containing the URL to view the image at the original provider's site
+ */
+function emimage_picasa_embedded_link($code, $data) {
+  $userid = $data['userid'];
+  $album= $data['album'];
+  $photoid= $data['photoid'];
+
+  return "http://picasaweb.google.com/$userid/$album/photo#$photoid";
+}
+
+/**
+ * Implement emimage_PROVIDER_image_url.
+ *
+ * @param $code
+ *   the code of the image
+ * @param $data
+ *   any stored data for the image, which may already have the url of the image to display
+ * @return
+ *   the url directly to emfield for the image to display
+ */
+function emimage_picasa_image_url($code, $width, $height, $formatter, $field, $item, $node) {
+  if (func_num_args() == 7) {
+    $arg = func_get_arg(5);
+    $code = &$arg['data']['original'];
+    $data = &$arg['data'];
+    $size = _emimage_picasa_guess_size($width, $height);
+  }
+  //http://lh5.google.com/kaos777/RwqRRgxcKrI/AAAAAAAAAB0/pl5FboT6x2M/IMG_0468.JPG
+  if (preg_match ('!([^/]*)\.ggpht\.com/([^/]*)/([^/]*)/([^/]*)/([^/]*)/(.*)!i', $code, $matches)) {
+    $info = array(
+     'server' => $matches[1],
+     'userid' => $matches[2],
+     's1' => $matches[3],
+     's2' => $matches[4],
+     's3' => $matches[5],
+     'image'  => $matches[6],
+    );
+  }
+
+  return "http://{$info['server']}.google.com/{$info['userid']}/{$info['s1']}/{$info['s2']}/{$info['s3']}/s$size/{$info['image']}";
+}
+
+/**
+ * Implement emimage_PROVIDER_image_title.
+ *
+ * @param $code
+ *   The code of the image.
+ * @param $data
+ *   Any stored data for the image, which may already have the title.
+ * @return
+ *   The title as the 3rd party provider knows it, if accessible to us. otherwise, ''.
+ */
+function emimage_picasa_image_title($code, $data) {
+  if (func_num_args() == 7) {
+    $arg = func_get_arg(5);
+    $code = &$arg['data']['title'];
+    $data = &$arg['data'];
+    $title = $code;
+  }
+
+  return "$title";
+}
+
+function _emimage_picasa_guess_size($width, $height) {
+  $max = max($width, $height);
+  foreach (array('144' => 144, '288' => 288, '400' => 400, '800' => 800) as $size => $value) {
+    if ($max <= $value) {
+      return $size;
+    }
+  }
+
+  // we would use the original size if we could, but we can't since google won't serve it
+  return '800';
+}
diff -urpN contrib/emfield_generic/providers/emvideo/bliptv.inc contrib/emfield_generic/providers/emvideo/bliptv.inc
--- contrib/emfield_generic/providers/emvideo/bliptv.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/bliptv.inc	2008-11-23 15:19:00.000000000 -0600
@@ -0,0 +1,316 @@
+<?php
+// $Id: bliptv.inc,v 1.1.2.8 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes blip.tv media files for use by emfield.module.
+ */
+
+define('EMVIDEO_BLIPTV_MAIN_URL', 'http://blip.tv/');
+define('EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE', 'flv');
+
+function emvideo_bliptv_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS attachment'), t('Yes'), t('When displaying in an RSS feed, these videos will be attached to the feed. (The feed reader or aggregator must support enclosure tags.)')),
+    array(t('Thumbnails'), t('Yes'), ''),
+  );
+  return array(
+    'provider' => 'bliptv',
+    'name' => t('Blip.tv'),
+    'url' => EMVIDEO_BLIPTV_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">Blip.tv</a>.', array('@provider' => EMVIDEO_BLIPTV_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_bliptv_settings() {
+  $tags = array('none' => t('No video'), 'flv' => t('Flash Video'), 'override' => t('Override tag'), 'web' => t('Web'), 'Web High Resolution' => t('Web High Resolution'), 'Portable (iPod)' => t('Portable (iPod)'), 'Portable (other)' => t('Portable (other)'), 'Television' => t('Television'), 'HDTV' => t('HDTV'), 'Cell Phone' => t('Cell Phone'), 'Source' => t('Source'));
+  $formats = array('none' => t('No video'), 'flv' => t('Flash video (flv)'), 'mov' => t('Quicktime Movie (mov)'), 'mp3' => t('MP3'), 'm4a' => t('m4a'), 'mpg' => t('MPEG'), 'mp4' => t('mp4'), 'm4v' => t('m4v'), 'wmv' => t('Windows Media (wmv)'));
+
+  $form = array();
+  $form['video_formats'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Video formats'),
+    '#description' => t("Blip.TV allows users to upload videos of various formats, sizes, and qualities. These options will allow the administrator to choose the default video formats to display. Blip.TV uses 'tags' to determine this, such as 'Web' for a standard web resolution, and 'HDTV' for a high definition. If you select a tag, then the video format provided by Blip.TV for that tag will be displayed. If you select 'Override tag', then you may specify that the first available video of the given format will be displayed instead, which may or may not have your desired resolution. If a tag or format is not available for a specific video, the module will display the Flash video format instead, which is always present."),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+  $form['video_formats']['rss'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('RSS'),
+    '#description' => t("This will determine the preferred video format for RSS feeds."),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+
+  $form['video_formats']['rss']['emvideo_bliptv_rss_tag'] = array(
+    '#type' => 'select',
+    '#title' => t('RSS full page tag'),
+    '#description' => t("When RSS feeds are displayed, and this tag is available for a video, then the clip for that tag will be displayed as an enclosure tag in the feed. Select 'Override tag' if you wish to control the format displayed. Select 'No video' if you do not wish a video to be displayed in RSS feeds."),
+    '#options' => $tags,
+    '#default_value' => variable_get('emvideo_bliptv_rss_tag', array(EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE => EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE)),
+  );
+  $form['video_formats']['rss']['emvideo_bliptv_rss_format'] = array(
+    '#type' => 'select',
+    '#title' => t('RSS full page format override'),
+    '#description' => t("When RSS feeds are displayed, and the 'Override tag' option is selected above, then this format will be displayed as an enclosure tag in the feed."),
+    '#options' => $formats,
+    '#default_value' => variable_get('emvideo_bliptv_rss_format', array(EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE => EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE)),
+  );
+  return $form;
+}
+
+function emvideo_bliptv_data($field, $item) {
+  $data = array();
+
+  // we added new data fields to keep from having to reload the api/rss
+  // because the data is only stored on update/insert, however, we have to know which data type we're using
+  // this will just be an integer, increased when we make a change to data
+  $data['emvideo_bliptv_data_version'] = 2;
+
+  // use the page id, since we'll have that in most cases (except in embed pastes, which gets parsed during extraction)
+  // we use this to get an rss feed w/ all the info for the video. interesting reading ;)
+  // some of our data we'll get from the api, like available files
+  $rss = emvideo_bliptv_request($item['value'], TRUE, 'rss');
+  $api = emvideo_bliptv_request($item['value'], TRUE, 'api');
+
+  // special handling for show/feature pages
+  // TODO: this is disabled for now.
+//   if (empty($rss) && empty($api) && preg_match('@http\://([^\.]+)\.blip\.tv/@i', $item['embed'], $matches)) {
+//     $show_rss = emvideo_bliptv_request($item['value'], TRUE, 'rss', TRUE);
+//     $data['thumbnail']['url'] = $rss['IMAGE']['URL'][0];
+//     $data['flv'] = array();
+//     $data['showpage'] = "http://{$item['value']}.blip.tv/";
+//     $data['is_show'] = TRUE;
+//     return $data;
+//   }
+
+  $data['is_show'] = FALSE;
+
+  // get our thumbnail url
+  $data['thumbnail']['url'] = $rss['ITEM']['MEDIA:THUMBNAIL'][1]['URL'];
+  // this gets sent to the player
+  foreach ((array)$api['MEDIA']['LINK'] as $x => $link) {
+    $x--;
+    $video_type = '';
+    switch ($link['TYPE']) {
+      case 'video/x-flv':
+        $video_type = 'flv';
+        break;
+      case 'video/x-m4v':
+        $video_type = 'm4v';
+        break;
+      case 'video/quicktime':
+        $video_type = 'mov';
+        break;
+    }
+    if ($video_type) {
+      $video_info = array();
+      $video_info['url'] = $link['HREF'];
+      $video_info['width'] = $api['MEDIA']['WIDTH'][$x];
+      $video_info['height'] = $api['MEDIA']['HEIGHT'][$x];
+      $video_info['duration'] = $api['MEDIA']['DURATION'][$x];
+      $video_info['size'] = $api['MEDIA']['SIZE'][$x];
+      $video_info['mime'] = $link['TYPE'];
+      $video_info['embed_code'] = $rss['ITEM']['BLIP:EMBEDLOOKUP'];
+
+      // we only store the last video of a particular type, for instance if two roles use .mov
+      $data[$video_type] = $video_info;
+
+      // however, we store the whole thing under role, so the information is still saved
+      // but our arrays may be out of synch...
+      $y = $x + 1;
+      if ($api['MEDIA']['ROLE'][$y]) {
+        $data[$video_type]['role'] = $api['MEDIA']['ROLE'][$y];
+        $data[$api['MEDIA']['ROLE'][$y]] = $video_info;
+        $data[$api['MEDIA']['ROLE'][$y]]['role'] = $api['MEDIA']['ROLE'][$y];
+      }
+    }
+  }
+  if (!$data['flv']) {
+    $data['flv'] = array();
+  }
+  if (!$data['flv']['url']) {
+    $data['flv']['url'] = $rss['ITEM']['ENCLOSURE'][1]['URL'];
+  }
+  $data['title'] = $api['en']['TITLE'][0] ? $api['en']['TITLE'][0] : $rss['2.0']['CHANNEL']['TITLE'][0];
+  $data['description'] = $api['en']['DESCRIPTION'][0] ? $api['en']['DESCRIPTION'][0] : $rss['ITEM']['BLIP:PUREDESCRIPTION'][0];
+  $data['blip_user']['uid'] = $api['CREATEDBY']['UID'][0] ? $api['CREATEDBY']['UID'][0] : $rss['ITEM']['BLIP:USERID'][0];
+  $data['blip_user']['username'] = $api['CREATEDBY']['LOGIN'][0] ? $api['CREATEDBY']['LOGIN'][0] : $rss['ITEM']['BLIP:USER'][0];
+  $data['blip_user']['url'] = $api['CREATEDBY']['LINKS']['LINK'][1] ? $api['CREATEDBY']['LINKS']['LINK'][1] : 'http://blip.tv/users/view/'. $data['blip_user']['username'];
+
+  $data['showpage'] = $rss['ITEM']['BLIP:SHOWPAGE'][0];
+  $data['embed_code'] = $rss['ITEM']['BLIP:EMBEDLOOKUP'];
+
+  // this is the code actually used by the player, even though it's different than for the page
+  if ($rss['ITEM']['BLIP:POSTS_ID'][0]) {
+    $data['post_id'] = $rss['ITEM']['BLIP:POSTS_ID'][0];
+  }	
+  return $data;
+}
+
+function emvideo_bliptv_request($code, $cacheable = TRUE, $skin = 'rss', $show = FALSE) {
+  $args = array();
+  $file = $show ? "http://$code.blip.tv/file/?skin=" . $skin : "http://blip.tv/file/$code?skin=" . $skin;
+  return module_invoke('emfield', 'request_xml', 'bliptv', $file, $args, $cacheable, FALSE, $code .':'. $skin . ($show ? ':show' : ':post'));
+}
+
+function emvideo_bliptv_extract($embed) {
+  return array(
+    '@blip\.tv/rss/flash/([^"\&\?]+)@i',
+    '@blip\.tv/file/view/([^"\&\?]+)@i',
+    '@blip\.tv/file/([^"\&\?]+)@i',
+    '@blip\.tv/play/([^"\&\?]+)@i',
+
+    // test handling for featured shows. disabled for now.
+//     '@http\://([^\.]+)\.blip\.tv/@i',
+  );
+}
+
+function emvideo_bliptv_video_link($video_code) {
+  return 'http://blip.tv/file/'. $video_code;
+}
+
+function _emvideo_bliptv_get_video_info_from_preferred_tag($data, $var) {
+  $preferred_tags = (array)variable_get($var, array(EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE => EMVIDEO_BLIPTV_DEFAULT_RSS_TYPE));
+
+  foreach ($preferred_tags as $test_tag) {
+    // if we override the tag with a type, then break so it can be handled
+    if ($test_tag == 'override') {
+      $video_info = 'override';
+      break;
+    }
+
+    // if we have a clip of that format type, then return it
+    if ($data[$test_tag]['url']) {
+      $video_info = $data[$test_tag];
+      break;
+    }
+  }
+
+  return $video_info;
+}
+
+/**
+ *  Providers may supply an enclosure for rss feeds. This expects something in a file format, so would be an object
+ *  in the format of $file->filepath, $file->filesize, and $file->filemime. calls the providers hook emvideo_PROVIDER_rss.
+ */
+function emvideo_bliptv_rss($item, $teaser = NULL) {
+  if ($item['value']) {
+    if ($item['data']['emvideo_bliptv_data_version'] >= 1) {
+      $data = $item['data'];
+    }
+    else {
+      $data = emvideo_bliptv_data(NULL, $item);
+    }
+
+    // get the preferred type for the rss feed
+    $var = 'emvideo_bliptv_rss_tag';
+    $video_info = _emvideo_bliptv_get_video_info_from_preferred_tag($data, $var);
+
+    // grab the preferred filetype rather than tag, so .mov rather than 'web'
+    if ($video_info == 'override') {
+      $var = 'emvideo_bliptv_rss_format';
+      $video_info = _emvideo_bliptv_get_video_info_from_preferred_tag($data, $var);
+    }
+
+    // default to flv if there's no available clip format
+    if (is_null($video_info) || ($video_info == 'override') && $video_info != 'none') {
+      $video_info = $data['flv'];
+    }
+
+    if (is_array($video_info)) {
+      // Begin building file object.
+
+      $file = array();
+      // Create temporary name/path for newly uploaded files.
+      $file['filepath'] = $video_info['url'];
+      $file['filesize'] = $video_info['size'];
+      $file['filemime'] = $video_info['mime'];
+
+      // additional data for Y! MRSS
+      $file['thumbnail']['filepath'] = $data['thumbnail']['url'];
+      $file['width'] = ($video_info['width']) ? $video_info['width'] : 0;
+      $file['height'] = ($video_info['height']) ? $video_info['height'] : 0;
+      $file['duration'] = ($video_info['duration']) ? $video_info['duration'] : FALSE;
+      // @todo media:credit role="author" ...
+
+
+
+    }
+  }
+}
+
+function theme_emvideo_bliptv_flash($code, $width, $height, $field, $item, $autoplay, $flv, $thumbnail, $options = array()) {
+  static $count;
+  if ($code) {
+    $count++;
+    $id = isset($options['id']) ? $options['id'] : "emfield_videocck_player_bliptv_$count";
+    $autoplay = $autoplay ? 'autoStart=true' : 'autoStart=false';
+
+    $rss = $item['data']['showpage'] ? "&amp;feedurl={$item['data']['showpage']}/rss" : '';
+    $post_id = $item['data']['post_id'];
+    // if/when we allow featured shows to be embedded, this will handle that.
+//     $file = $item['data']['is_show'] ? "http://$code.blip.tv/rss/flash/" : 'http://blip.tv/rss/flash/'. $item['data']['post_id'];
+    $embed_code = $item['data']['flv']['embed_code']['0'];
+    $file = 'http://blip.tv/rss/flash/'. $item['data']['post_id'];
+    $embed_file = 'http://blip.tv/scripts/flash/showplayer.swf?enablejs=true'. $rss .'&amp;file='. $file .'&amp;showplayerpath=http://blip.tv/scripts/flash/showplayer.swf';
+
+   // If you want strict html you may want to use the following  code instead of the one blip provides 
+   // $output .= '<object type="application/x-shockwave-flash" data="'. $embed_file .'" width="'. $width .'" height="'. $height .'" allowfullscreen="true" id="'. $id .'"><param name="movie" value="'. $embed_file .'" /><param name="quality" value="best" /><embed src="'. $embed_file .'" quality="best" width="'. $width .'" height="'. $height .'" name="'. $id .'" type="application/x-shockwave-flash"></embed></object>'; 
+   
+   $output .= '<embed src="http://blip.tv/play/'. $embed_code .'" type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'" allowscriptaccess="always" allowfullscreen="true"></embed>';
+  }
+  
+  return $output;
+}
+
+function emvideo_bliptv_thumbnail($field, $item, $formatter, $node, $width, $height, $options = array()) {
+  if ($item['data']['emvideo_bliptv_data_version'] >= 1) {
+    $tn = $item['data']['thumbnail']['url'];
+  }
+  else {
+    $tn = $item['data']['thumbnail'];
+  }
+  return $tn;
+}
+
+function emvideo_bliptv_video($code, $width, $height, $field, $item, $autoplay, $options = array()) {
+  if ($item['data']['emvideo_bliptv_data_version'] >= 1) {
+    $flv = $item['data']['flv']['url'];
+    $thumbnail = $item['data']['thumbnail']['url'];
+  }
+  else {
+    $flv = $item['data']['flv'];
+    $thumbnail = $item['data']['thumbnail'];
+  }
+
+  $output = theme('emvideo_bliptv_flash', $code, $width, $height, $field, $item, $autoplay, $flv, $thumbnail);
+  return $output;
+}
+
+function emvideo_bliptv_preview($code, $width, $height, $field, $item, $autoplay, $options = array()) {
+  if ($item['data']['emvideo_bliptv_data_version'] >= 1) {
+    $flv = $item['data']['flv']['url'];
+    $thumbnail = $item['data']['thumbnail']['url'];
+  }
+  else {
+    $flv = $item['data']['flv'];
+    $thumbnail = $item['data']['thumbnail'];
+  }
+  $output = theme('emvideo_bliptv_flash', $code, $width, $height, $field, $item, $autoplay, $flv, $thumbnail);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_bliptv_emfield_subtheme() {
+  return array(
+    'emvideo_bliptv_flash' => array(
+      'arguments' => array('code' => NULL, 'width' => NULL, 'height' => NULL, 'field' => NULL, 'item' => NULL, 'autoplay' => NULL, 'flv' => NULL, 'thumbnail' => NULL, 'options' => NULL),
+      'file' => 'providers/emvideo/bliptv.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/brightcove.inc contrib/emfield_generic/providers/emvideo/brightcove.inc
--- contrib/emfield_generic/providers/emvideo/brightcove.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/brightcove.inc	2008-11-23 15:19:48.000000000 -0600
@@ -0,0 +1,161 @@
+<?php
+// $Id: brightcove.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes brightcove media files for use by emfield.module.
+ */
+
+define('EMVIDEO_BRIGHTCOVE_MAIN_URL', 'http://www.brightcove.tv/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ */
+function emvideo_brightcove_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), ''),
+  );
+  return array(
+    'provider' => 'brightcove',
+    'name' => t('Brightcove'),
+    'url' => EMVIDEO_BRIGHTCOVE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@brightcove" target="_blank">Brightcove</a>.', array('@brightcove' => EMVIDEO_BRIGHTCOVE_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['brightcove'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_brightcove_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_brightcove_extract($embed = '') {
+  return array(
+    //<embed src='http://www.brightcove.tv/playerswf' bgcolor='#FFFFFF' flashVars='allowFullScreen=true&initVideoId=1155177265&servicesURL=http://www.brightcove.tv&viewerSecureGatewayURL=https://www.brightcove.tv&cdnURL=http://admin.brightcove.com&autoStart=false' base='http://admin.brightcove.com' name='bcPlayer' width='425' height='350' allowFullScreen='true' allowScriptAccess='always' seamlesstabbing='false' type='application/x-shockwave-flash' swLiveConnect='true' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'></embed>
+
+    '@brightcove\.tv/playerswf\' bgcolor\=\'\#FFFFFF\' flashVars\=\'initVideoId\=([^\&]*)\&@i',
+
+    // was:
+    // &initVideoId=753308735&
+    // '@\&initVideoId=([^\&]*)\&@',
+
+    // http://www.brightcove.tv/title.jsp?title=753308735
+    '@brightcove\.tv/title\.jsp\?title=(.*)@i',
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_video_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_brightcove_video_link($video_code) {
+  return 'http://www.brightcove.tv/title.jsp?title='. $video_code;
+}
+
+/**
+ * the embedded flash displaying the brightcove video
+ */
+function theme_emvideo_brightcove_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autostart = $autoplay ? 'autoStart=true' : 'autoStart=false';
+    $output .= "<embed src='http://www.brightcove.tv/playerswf' bgcolor='#FFFFFF' flashVars='initVideoId=$embed&amp;servicesURL=http://www.brightcove.tv&amp;viewerSecureGatewayURL=https://www.brightcove.tv&amp;cdnURL=http://admin.brightcove.com&amp;$autostart' base='http://admin.brightcove.com' name='bcPlayer' width='$width' height='$height' allowFullScreen='true' allowScriptAccess='always' seamlesstabbing='false' type='application/x-shockwave-flash' swLiveConnect='true' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'></embed>";
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_brightcove_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return '';
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_brightcove_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_brightcove_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_brightcove_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_brightcove_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_brightcove_emfield_subtheme() {
+  return array(
+    'emvideo_brightcove_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/brightcove.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/dailymotion.inc contrib/emfield_generic/providers/emvideo/dailymotion.inc
--- contrib/emfield_generic/providers/emvideo/dailymotion.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/dailymotion.inc	2008-11-23 15:19:58.000000000 -0600
@@ -0,0 +1,182 @@
+<?php
+// $Id: dailymotion.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes dailymotion media files for use by emfield.module.
+ */
+
+define('EMVIDEO_DAILYMOTION_MAIN_URL', 'http://www.dailymotion.com/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_dailymotion_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+  return array(
+    'provider' => 'dailymotion',
+    'name' => t('Dailymotion'),
+    'url' => EMVIDEO_DAILYMOTION_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@dailymotion" target="_blank">Dailymotion</a>.', array('@dailymotion' => EMVIDEO_DAILYMOTION_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['dailymotion'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_dailymotion_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_dailymotion_extract($embed = '') {
+  // http://www.dailymotion.com/us/cluster/news/featured/video/x3xk8v_primary-smackdown-obama-girl-return_fun
+  // http://www.dailymotion.com/barelypolitical/video/x3xk8v_primary-smackdown-obama-girl-return_fun
+  // http://www.dailymotion.com/barelypolitical/video/x3xk8v
+  // <div><object width="420" height="252"><param name="movie" value="http://www.dailymotion.com/swf/x3xk8v" /></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.dailymotion.com/swf/x3xk8v" type="application/x-shockwave-flash" width="420" height="252" allowFullScreen="true" allowScriptAccess="always"></embed></object><br /><b><a href="http://www.dailymotion.com/video/x3xk8v_primary-smackdown-obama-girl-return_fun">Primary Smackdown: Obama Girl Returns</a></b><br /><i>Uploaded by <a href="http://www.dailymotion.com/BarelyPolitical">BarelyPolitical</a></i></div>
+  // <div><object width="420" height="252"><param name="movie" value="http://www.dailymotion.com/swf/x3xk8v"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.dailymotion.com/swf/x3xk8v" type="application/x-shockwave-flash" width="420" height="252" allowFullScreen="true" allowScriptAccess="always"></embed></object><br /><b><a href="http://www.dailymotion.com/video/x3xk8v_primary-smackdown-obama-girl-return_fun">Primary Smackdown: Obama Girl Returns</a></b><br /><i>Uploaded by <a href="http://www.dailymotion.com/BarelyPolitical">BarelyPolitical</a></i></div>
+//   if (preg_match('@dailymotion\.com@i', $embed, $matches)) {
+//     if (preg_match('@/([^/_]+)_@i', $embed, $matches)) {
+//       return $matches[0];
+//     }
+//   }
+  if (preg_match('@dailymotion\.com/swf/([^"\&]+)@i', $embed, $matches)) {
+    return $matches[1];
+  }
+  if (preg_match('@dailymotion\.com@i', $embed, $matches)) {
+    if (preg_match('@/([^/_]+)_@i', $embed, $matches)) {
+      return $matches[1];
+    }
+  }
+  return array();
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_dailymotion_embedded_link($video_code) {
+  return 'http://www.dailymotion.com/swf/'. $video_code;
+}
+
+/**
+ * the embedded flash displaying the dailymotion video
+ */
+function theme_emvideo_dailymotion_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    if ($autoplay) {
+      $autoplay_value = '&amp;autoStart=1';
+    }
+    $output .= "    <object type=\"application/x-shockwave-flash\" height=\"$height\" width=\"$width\" data=\"http://www.dailymotion.com/swf/$embed". $autoplay_value ."\" id=\"VideoPlayback\">
+      <param name=\"movie\" value=\"http://www.dailymotion.com/swf/$embed". $autoplay_value ."\" />
+      <param name=\"allowScriptAcess\" value=\"always\" />
+      <param name=\"allowFullScreen\" value=\"true\" />
+      <param name=\"quality\" value=\"best\" />
+      <param name=\"bgcolor\" value=\"#FFFFFF\" />
+      <param name=\"scale\" value=\"noScale\" />
+      <param name=\"salign\" value=\"TL\" />
+      <param name=\"FlashVars\" value=\"playerMode=embedded$autoplay_value\" />
+      <param name=\"wmode\" value=\"transparent\" />
+    </object>\n";
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_dailymotion_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return 'http://www.dailymotion.com/thumbnail/160x120/video/'. $item['value'];
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_dailymotion_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_dailymotion_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_dailymotion_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_dailymotion_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_dailymotion_emfield_subtheme() {
+  return array(
+    'emvideo_dailymotion_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/dailymotion.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/google.inc contrib/emfield_generic/providers/emvideo/google.inc
--- contrib/emfield_generic/providers/emvideo/google.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/google.inc	2008-11-23 15:20:18.000000000 -0600
@@ -0,0 +1,198 @@
+<?php
+// $Id: google.inc,v 1.1.2.8 2008/11/12 17:54:43 aaron Exp $
+
+/**
+ * @file
+ *   This include processes Google.com media files for use by emfield.module
+ */
+
+define('EMVIDEO_GOOGLE_MAIN_URL', 'http://video.google.com/');
+define('EMVIDEO_GOOGLE_XML', 'http://video.google.com/videofeed');
+define('EMVIDEO_GOOGLE_DOMAIN_DEFAULT', 'com');
+
+function emvideo_google_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('Yes'), ''),
+    array(t('Thumbnails'), t('Yes'), ''),
+  );
+  return array(
+    'provider' => 'google',
+    'name' => t('Google'),
+    'url' => EMVIDEO_GOOGLE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@google" target="_blank">Google</a>.', array('@google' => EMVIDEO_GOOGLE_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_google_settings() {
+  $form = array();
+  $form['emvideo_google_domain'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Google video domain'),
+    '#default_value' => variable_get('emvideo_google_domain', EMVIDEO_GOOGLE_DOMAIN_DEFAULT),
+    '#description' => t('Google hosts their videos on various servers throughout the world. By default, videos from Google will be displayed from the United States, at their google.<b><em>com</em></b> servers. If you wish to display the video from another Google server, please enter the domain here, without the initial dot. For instance, you might enter <b><em>it</em></b> for the Italian Google servers at google.it, or <b><em>ca</em></b> for their Canadian servers.'),
+  );
+  return $form;
+}
+
+function emvideo_google_extract($embed) {
+  return array(
+    '@http://video\.google(?:\.[a-z]{2,4})+/videoplay(?:\?|%3F)docid(?:=|%3D)([^\&]*)\&@i',
+    '@http://video\.google(?:\.[a-z]{2,4})+/videoplay(?:\?|%3F)docid(?:=|%3D)([^\&]*)\&@i',
+    '@http://video\.google(?:\.[a-z]{2,4})+/videoplay\?docid=(.*)@i',
+    '@http://video\.google(?:\.[a-z]{2,4})+/googleplayer\.swf\?docId=(-?\d*)@i',
+    '@http://video\.google(?:\.[a-z]{2,4})+/url\?docid=([^\&]*)\&@i',
+  );
+}
+
+function emvideo_google_request($embed, $cacheable = TRUE) {
+  $args = array('docid' => $embed);
+  return module_invoke('emfield', 'request_xml', 'google', EMVIDEO_GOOGLE_XML, $args, $cacheable);
+}
+
+function emvideo_google_video_link($video_code) {
+  return 'http://video.google.'. variable_get('emvideo_google_domain', EMVIDEO_GOOGLE_DOMAIN_DEFAULT) .'/videoplay?docid='. $video_code;
+}
+
+function theme_emvideo_google_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autoplay = $autoplay ? '&amp;autoPlay=true' : '';
+    // this will be executed by not Internet Explorer browsers
+    $output = '<!--[if !IE]> <-->
+  <object type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'"
+  data="http://video.google.'. variable_get('emvideo_google_domain', EMVIDEO_GOOGLE_DOMAIN_DEFAULT) .'/googleplayer.swf?docId='. check_plain($embed) . $autoplay .'">
+  <!--> <![endif]-->'."\n";
+
+    // this will be executed by Internet Explorer
+    $output .= '<!--[if IE]>
+  <object type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'"
+  classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">
+  <![endif]-->'."\n";
+
+    // params will be passed to both IE or not IE browsers
+    $output .= '<param name="movie" value="http://video.google.'. variable_get('emvideo_google_domain', EMVIDEO_GOOGLE_DOMAIN_DEFAULT) .'/googleplayer.swf?docId='. check_plain($embed) . $autoplay .'" />'."\n";
+    // following a list of params simply copied from old embed tag params. I don't know if this are really needed.
+    $output .= '<param name="quality" value="best" />
+    <param name="bgcolor" value="#ffffff" />
+    <param name="allowScriptAccess" value="sameDomain" />
+    <param name="scale" value="noScale" />
+    <param name="wmode" value="transparent" />
+    <param name="salign" value="TL" />
+    <param name="FlashVars" value="playerMode=embedded" />
+    <p>'. t('Your browser is not able to display this multimedia content.') .'</p>
+  </object>';
+  }
+  return $output;
+}
+
+/**
+ * hook emfield_PROVIDER_data
+ *
+ * provides an array to be serialised and made available with $item elsewhere
+ */
+function emvideo_google_data($field, $item) {
+  $data = array();
+  // create some 'field' version control
+  //$data['emvideo_google_version'] = 1;
+
+  $rss = emvideo_google_request($item['value']);
+
+  if (
+    is_array($rss['ITEM']) &&
+    is_array($rss['ITEM']['MEDIA:GROUP']) &&
+    is_array($rss['ITEM']['MEDIA:GROUP']['MEDIA:CONTENT']) &&
+    is_array($rss['ITEM']['MEDIA:GROUP']['MEDIA:CONTENT'][1])
+  ) {
+    $video = $rss['ITEM']['MEDIA:GROUP']['MEDIA:CONTENT'][1];
+    $data['filepath'] = $video['URL'];
+    $data['filemime'] = $video['TYPE'];
+    $data['medium'] = $video['MEDIUM'];
+    $data['expression'] = $video['EXPRESSION'];
+    $data['duration'] = $video['DURATION'];
+    $data['width'] = $video['WIDTH'];
+    $data['height'] = $video['HEIGHT'];
+  }
+
+  if (is_array($rss['MEDIA:GROUP'])) {
+    if (is_array($rss['MEDIA:GROUP']['MEDIA:THUMBNAIL']) && is_array($rss['MEDIA:GROUP']['MEDIA:THUMBNAIL'][1])) {
+      $thumbnail = $rss['MEDIA:GROUP']['MEDIA:THUMBNAIL'][1];
+      $data['thumbnail']['filepath'] = $thumbnail['URL'];
+      $data['thumbnail']['width'] = $thumbnail['WIDTH'];
+      $data['thumbnail']['height'] = $thumbnail['HEIGHT'];
+    }
+    if (is_array($rss['MEDIA:GROUP']['MEDIA:PLAYER']) && is_array($rss['MEDIA:GROUP']['MEDIA:PLAYER'][1])) {
+      $data['player']['filepath'] = $rss['MEDIA:GROUP']['MEDIA:PLAYER'][1]['URL'];
+    }
+  }
+
+  if ($data['thumbnail']['filepath'] == '') {
+    // for whatever reason the thumbnail failed try the old method
+    // we'll parse it from the description, where it's repeated.
+    $desc = $rss['ITEM']['DESCRIPTION'][0];
+    $regex = '@<img src="([^"]*)"@';
+    if (preg_match($regex, $desc, $matches)) {
+      $data['thumbnail']['filepath'] = $matches[1];
+    }
+  }
+
+  // google rss doesn't actually have <embeded> media, just MRSS, and no size
+  // so not actually really really necessary or really useful but for completeness
+  $play = 'http://video.google.'. variable_get('emvideo_google_domain', EMVIDEO_GOOGLE_DOMAIN_DEFAULT) .'/googleplayer.swf?docId='. check_plain($item['embed']);
+  $response = emfield_request_header('google', $play, FALSE, FALSE);
+
+  if ($response->code == 200) {
+    $data['filesize'] = $response->headers['Content-Length'];
+  }
+
+  return $data;
+}
+
+function emvideo_google_rss($item, $teaser) {
+  if ($item['value']) {
+    if ($item['data']['emvideo_google_data_version'] >= 1000000) {
+      $data = $item['data'];
+    }
+    else {
+      $data = emvideo_google_data(NULL, $item);
+    }
+
+    return $data;
+  }
+}
+
+function emvideo_google_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  if ($item['data']['emvideo_google_data_version'] >= 1) {
+    $data = $item['data'];
+  }
+  else {
+    $data = emvideo_google_data($field, $item);
+  }
+
+  return $data['thumbnail']['filepath'];
+
+  return NULL;
+}
+
+function emvideo_google_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_google_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_google_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_google_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_google_emfield_subtheme() {
+  return array(
+    'emvideo_google_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/google.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/guba.inc contrib/emfield_generic/providers/emvideo/guba.inc
--- contrib/emfield_generic/providers/emvideo/guba.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/guba.inc	2008-11-23 15:20:26.000000000 -0600
@@ -0,0 +1,98 @@
+<?php
+// $Id: guba.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   Provide support for the Guba provider to the emfield.module.
+ */
+
+define('EMVIDEO_GUBA_MAIN_URL', 'http://www.guba.com/');
+define('EMVIDEO_GUBA_API_INFO', 'http://www.guba.com/restApiDoc/restReference.html');
+define('EMVIDEO_GUBA_API_APPLICATION_URL', 'http://www.guba.com/developers.html');
+
+function emvideo_guba_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Show related videos'), t('No'), t('This is embedded in the video itself when enabled; currently not available with other providers. Set the feature above.')),
+    array(t('Thumbnails'), t('Yes'), t('May not currently resize thumbnails. Must have an API key for thumbnails at the moment, although research is underway to determine an alternative to this. Set your API key above.')),
+  );
+  return array(
+    'provider' => 'guba',
+    'name' => t('GUBA'),
+    'url' => EMVIDEO_GUBA_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@guba" target="_blank">GUBA</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@guba' => EMVIDEO_GUBA_MAIN_URL, '@api' => EMVIDEO_GUBA_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_guba_settings() {
+  $form['guba']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('GUBA API'),
+    '#description' => t('If you wish to be able to display GUBA thumbnails automatically, you will first need to apply for an API Developer Key from the <a href="@guba" target="_blank">GUBA Developer Profile page</a>. Note that you do not need this key to display GUBA videos themselves.', array('@guba' => EMVIDEO_GUBA_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['guba']['api']['emvideo_guba_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('GUBA API Key'),
+    '#default_value' => variable_get('emvideo_guba_api_key', ''),
+    '#description' => t('Please enter your GUBA Developer Key here.'),
+  );
+  $form['guba']['api']['emvideo_guba_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('GUBA API Secret'),
+    '#default_value' => variable_get('emvideo_guba_api_secret', ''),
+    '#description' => t('If you have a secret for the GUBA API, enter it here.'),
+  );
+  return $form;
+}
+
+
+function emvideo_guba_request($method, $args = array(), $cached = TRUE) {
+  //$args = array('docid' => $embed);
+  return module_invoke('emfield', 'request_xml', 'guba', "http://www.guba.com/rest/video/". $method ."/details", $args, $cacheable);
+}
+
+function emvideo_guba_extract($embed = '') {
+  return array(
+    '@http://www\.guba\.com/watch/([^"\?]+)@i',
+    '@http://www\.guba\.com/f/root\.swf\?video_url=http://free\.guba\.com/uploaditem/([^"\?/]*)@i',
+  );
+}
+
+function emvideo_guba_embedded_link($video_code) {
+  return 'http://www.guba.com/watch/'. $video_code;
+}
+
+function theme_emvideo_guba_flash($embed, $width, $height, $autoplay) {
+  $autoplay = $autoplay ? '&amp;autoPlay=TRUE' : '&amp;autoPlay=FALSE';
+  $output .= '<embed src="http://www.guba.com/f/root.swf?video_url=http://free.guba.com/uploaditem/'. $embed .'/flash.flv&amp;isEmbeddedPlayer=FALSE'. $autoplay .'" quality="best" bgcolor="#FFFFFF" menu="TRUE" width="'. $width .'" height="'. $height .'" name="root" id="root" align="middle" scaleMode="noScale" allowScriptAccess="always" allowFullScreen="TRUE" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
+  return $output;
+}
+
+function emvideo_guba_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $thumbid = $item['value'];
+  $thm = 'http://img.guba.com/public/video/f/58/'. $thumbid .'-m.jpg';
+  return $thm;
+}
+
+function emvideo_guba_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_guba_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_guba_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_guba_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_guba_emfield_subtheme() {
+  return array(
+    'emvideo_guba_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/guba.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/imeem.inc contrib/emfield_generic/providers/emvideo/imeem.inc
--- contrib/emfield_generic/providers/emvideo/imeem.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/imeem.inc	2008-11-23 15:20:34.000000000 -0600
@@ -0,0 +1,103 @@
+<?php
+// $Id: imeem.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
+
+define('EMVIDEO_IMEEM_MAIN_URL', 'http://www.imeem.com/');
+define('EMVIDEO_IMEEM_API_INFO', 'http://www.imeem.com/developers/documentation/');
+define('EMVIDEO_IMEEM_API_APPLICATION_URL', 'http://www.imeem.com/developers/');
+define('EMVIDEO_IMEEM_XML', 'http://www.imeem.com/api/xml/mediaGetInfo?&amp;mediaIds=');
+
+function emvideo_imeem_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Show related videos'), t('No'), t('This is embedded in the video itself when enabled; currently not available with other providers. Set the feature above.')),
+    array(t('Thumbnails'), t('Yes'), t('May not currently resize thumbnails. Must have an API key for thumbnails at the moment, although research is underway to determine an alternative to this. Set your API key above.')),
+  );
+  return array(
+    'provider' => 'imeem',
+    'name' => t('IMEEM'),
+    'url' => EMVIDEO_IMEEM_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@imeem" target="_blank">IMEEM</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@imeem' => EMVIDEO_IMEEM_MAIN_URL, '@api' => EMVIDEO_IMEEM_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_imeem_settings() {
+  $form['imeem']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('IMEEM API'),
+    '#description' => t('If you wish to be able to display IMEEM thumbnails automatically, you will first need to apply for an API Developer Key from the <a href="@imeem" target="_blank">IMEEM Developer Profile page</a>. Note that you do not need this key to display IMEEM videos themselves.', array('@imeem' => EMVIDEO_IMEEM_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['imeem']['api']['emvideo_imeem_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('IMEEM API Key'),
+    '#default_value' => variable_get('emvideo_imeem_api_key', ''),
+    '#description' => t('Please enter your IMEEM Developer Key here.'),
+  );
+  $form['imeem']['api']['emvideo_imeem_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('IMEEM API Secret'),
+    '#default_value' => variable_get('emvideo_imeem_api_secret', ''),
+    '#description' => t('If you have a secret for the IMEEM API, enter it here.'),
+  );
+  return $form;
+}
+
+function emvideo_imeem_request($embed, $cacheable = TRUE) {
+  $args = array('docid' => $embed);
+  return module_invoke('emfield', 'request_xml', 'imeem', EMVIDEO_IMEEM_XML . $embed .'&amp;version=1.0', $args, $cacheable);
+}
+
+function emvideo_imeem_extract($embed = '') {
+  return array(
+    '@http://media\.imeem\.com/[a-z]{1,2}/([^"\?/]+)/@i',
+  );
+}
+
+function emvideo_imeem_embedded_link($video_code) {
+  return 'http://www.imeem.com/v/'. $video_code;
+}
+
+function theme_emvideo_imeem_flash($embed, $width, $height, $autoplay) {
+  $autoplay = $autoplay ? '/aus=true' : '/aus=false';
+  $colors = 'backColor=666666&amp;primaryColor=cccccc&amp;secondaryColor=333333&amp;linkColor=cccccc';
+
+  $output .= '<object width="'. $width .'" height="'. $height .'">';
+  $output .= '<param name="movie" value="http://media.imeem.com/v/'. $embed . $autoplay .'/pv=2"></param>';
+  $output .= '<param name="allowFullScreen" value="true"></param>';
+  $output .= '<param name="wmode" value="transparent"></param>';
+  $output .= '<param name="FlashVars" value="'. $colors .'"></param>';
+  $output .= '<embed src="http://media.imeem.com/v/'. $embed . $autoplay .'/pv=2" type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'" allowFullScreen="true" wmode="transparent" FlashVars="'. $colors .'"></embed>';
+  $output .= '</object>';
+  return $output;
+}
+
+function emvideo_imeem_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $xml = emvideo_imeem_request($item['value']);
+  $tmpthm = $xml['ITEM']['ICONURL'][0];
+  $imgmax = $xml['ITEM']['DURATION'][0];
+  $formatnum = str_pad(rand(0, $imgmax) .'.jpg', 9, "0", STR_PAD_LEFT);;
+  $thm = str_replace('00010.jpg', $formatnum, $tmpthm);
+  return $thm;
+}
+
+function emvideo_imeem_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_imeem_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_imeem_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_imeem_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_imeem_emfield_subtheme() {
+  return array(
+    'emvideo_imeem_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/imeem.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/jumpcut.inc contrib/emfield_generic/providers/emvideo/jumpcut.inc
--- contrib/emfield_generic/providers/emvideo/jumpcut.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/jumpcut.inc	2008-11-23 15:20:44.000000000 -0600
@@ -0,0 +1,73 @@
+<?php
+// $Id: jumpcut.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes jumpcut media files for use by emfield.module.
+ */
+
+define('EMVIDEO_JUMPCUT_MAIN_URL', 'http://jumpcut.com/');
+
+function emvideo_jumpcut_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), ''),
+  );
+  return array(
+    'provider' => 'jumpcut',
+    'name' => t('JumpCut'),
+    'url' => EMVIDEO_JUMPCUT_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">JumpCut</a>.', array('@provider' => EMVIDEO_JUMPCUT_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_jumpcut_settings() {
+  $form = array();
+  return $form;
+}
+
+function emvideo_jumpcut_extract($embed) {
+  return array(
+    '@jumpcut\.com/view\?id=(.*)@i',
+    '@jumpcut\.com/view\?id=([^\&]*)\&@i',
+  );
+}
+
+function emvideo_jumpcut_video_link($video_code) {
+  return 'http://jumpcut.com/view?id='. $video_code;
+}
+
+function theme_emvideo_jumpcut_flash($embed, $width, $height) {
+  if ($embed) {
+    $output .= '<embed src="http://jumpcut.com/media/flash/jump.swf?id='. $embed .'&amp;asset_type=movie&amp;asset_id='. $embed .'&eb=1" width="'. $width .'" height="'. $height .'" type="application/x-shockwave-flash"></embed>';
+  }
+  return $output;
+}
+
+function emvideo_jumpcut_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return '';
+}
+
+function emvideo_jumpcut_video($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_jumpcut_flash', $embed, $width, $height);
+  return $output;
+}
+
+function emvideo_jumpcut_preview($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_jumpcut_flash', $embed, $width, $height);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_jumpcut_emfield_subtheme() {
+  return array(
+    'emvideo_jumpcut_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL),
+      'file' => 'providers/emvideo/jumpcut.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/lastfm.inc contrib/emfield_generic/providers/emvideo/lastfm.inc
--- contrib/emfield_generic/providers/emvideo/lastfm.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/lastfm.inc	2008-11-23 15:21:04.000000000 -0600
@@ -0,0 +1,178 @@
+<?php
+// $Id: lastfm.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   Provide support for Last.fm to the emfield.module.
+ */
+
+define('EMVIDEO_LASTFM_MAIN_URL', 'http://www.lastfm.com/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_lastfm_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+  return array(
+    'provider' => 'lastfm',
+    'name' => t('Last.fm'),
+    'url' => EMVIDEO_LASTFM_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@lastfm" target="_blank">Last.fm</a>.', array('@lastfm' => EMVIDEO_LASTFM_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['lastfm'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_lastfm_settings() {
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_lastfm_extract($embed = '') {
+  // http://www.last.fm/music/The+Shins/+videos/2794412
+  // <object width="340" height="289" id="player" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" align="middle"> <param name="movie" value="http://cdn.last.fm/videoplayer/33/VideoPlayer.swf" /> <param name="menu" value="false" /> <param name="quality" value="high" /> <param name="bgcolor" value="#000000" /> <param name="allowFullScreen" value="true" /> <param name="flashvars" value="embed=true&creator=The+Shins&title=Phantom+Limb&uniqueName=2794412&albumArt=http://cdn.last.fm/coverart/130x130/3243014.jpg&album=Wincing+the+Night+Away&duration=&image=http://userserve-ak.last.fm/serve/image:320/2794412.jpg&FSSupport=true" /> <embed src="http://cdn.last.fm/videoplayer/33/VideoPlayer.swf" menu="false" quality="high" bgcolor="#000000" width="340" height="289" name="player" align="middle" allowFullScreen="true" flashvars="embed=true&creator=The+Shins&title=Phantom+Limb&uniqueName=2794412&albumArt=http://cdn.last.fm/coverart/130x130/3243014.jpg&album=Wincing+the+Night+Away&duration=&image=http://userserve-ak.last.fm/serve/image:320/2794412.jpg&FSSupport=true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object>
+
+  // thumb:
+  // http://userserve-ak.last.fm/serve/image:160/2794412.jpg
+
+  // src="http://www.lastfm.com/v/nvbQQnvxXDk"
+  // http://lastfm.com/watch?v=nvbQQnvxXDk
+  // http://www.lastfm.com/watch?v=YzFCA-xUc8w&feature=dir
+  if (preg_match('@cdn.last.fm@i', $embed, $matches)) {
+    if (preg_match('@uniqueName=([0-9]+)@i', $embed, $matches)) {
+      return $matches[1];
+    }
+  }
+  else if (preg_match('@last\.fm@i', $embed, $matches)) {
+    if (preg_match('@([0-9]+)@i', $embed, $matches)) {
+      return $matches[1];
+    }
+  }
+  return array(
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_lastfm_embedded_link($video_code) {
+  return '';
+}
+
+/**
+ * the embedded flash displaying the lastfm video
+ */
+function theme_emvideo_lastfm_flash($embed, $width, $height, $autoplay) {
+  static $count;
+  if ($embed) {
+    // set css id count
+    $count++;
+    $output .= '<object width="'. $width .'" height="'. $height .'" id="emfield-videocck-player-lastfm-'. $count .'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" align="middle"> <param name="movie" value="http://cdn.last.fm/videoplayer/33/VideoPlayer.swf" /> <param name="menu" value="false" /> <param name="quality" value="high" /> <param name="bgcolor" value="#000000" /> <param name="allowFullScreen" value="true" /> <param name="flashvars" value="embed=true&amp;creator=&amp;title=&amp;uniqueName='. $embed .'&amp;albumArt=&amp;album=&amp;duration=&amp;image=http://userserve-ak.last.fm/serve/image:320/'. $embed .'.jpg&amp;FSSupport=true" /> <embed src="http://cdn.last.fm/videoplayer/33/VideoPlayer.swf" menu="false" quality="high" bgcolor="#000000" width="'. $width .'" height="'. $height .'" name="player" align="middle" allowFullScreen="true" flashvars="embed=true&amp;creator=&amp;title=&amp;uniqueName='. $embed .'&amp;albumArt=&amp;album=&amp;duration=&amp;image=http://userserve-ak.last.fm/serve/image:320/'. $embed .'.jpg&amp;FSSupport=true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object>';
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_lastfm_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $lastfm_id = $item['value'];
+
+  // if we have a large thumbnail size, then get the larger version available.
+  if ($width >= 320) {
+    $tn = "http://userserve-ak.last.fm/serve/image:320/$lastfm_id.jpg";
+  } 
+  else {
+    $tn = "http://userserve-ak.last.fm/serve/image:160/$lastfm_id.jpg";
+  }
+  return $tn;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_lastfm_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_lastfm_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_lastfm_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_lastfm_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_lastfm_emfield_subtheme() {
+  return array(
+    'emvideo_lastfm_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/lastfm.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/livevideo.inc contrib/emfield_generic/providers/emvideo/livevideo.inc
--- contrib/emfield_generic/providers/emvideo/livevideo.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/livevideo.inc	2008-11-23 15:21:14.000000000 -0600
@@ -0,0 +1,197 @@
+<?php
+// $Id: livevideo.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes livevideo media files for use by emfield.module.
+ */
+
+define('EMVIDEO_LIVEVIDEO_MAIN_URL', 'http://www.livevideo.com/');
+define('EMVIDEO_LIVEVIDEO_API_INFO', 'http://www.livevideo.com/api/default.aspx');
+define('EMVIDEO_LIVEVIDEO_API_APPLICATION_URL', 'http://www.livevideo.com/profile/admin/editdeveloperprofile.aspx');
+define('EMVIDEO_LIVEVIDEO_REST_ENDPOINT', 'http://www.livevideo.com/api/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_livevideo_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('Yes'), ''),
+  );
+
+  return array(
+    'provider' => 'livevideo',
+    'name' => t('Live Video'),
+    'url' => EMVIDEO_LIVEVIDEO_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@livevideo" target="_blank">Live Video</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@livevideo' => EMVIDEO_LIVEVIDEO_MAIN_URL, '@api' => EMVIDEO_LIVEVIDEO_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['livevideo'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_livevideo_settings() {
+  $form['livevideo']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Live Video API'),
+    '#description' => t('If you wish to be able to display Live Video thumbnails automatically, you will first need to apply for an API Developer Key from the <a href="@livevideo" target="_blank">Live Video Developer Profile page</a>. Note that you do not need this key to display Live Video videos themselves.', array('@livevideo' => EMVIDEO_LIVEVIDEO_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['livevideo']['api']['emvideo_livevideo_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Live Video API Key'),
+    '#default_value' => variable_get('emvideo_livevideo_api_key', ''),
+    '#description' => t('Please enter your Live Video Developer Key here.'),
+  );
+
+  return $form;
+}
+
+/**
+ * this is a wrapper for emvideo_request_xml that includes livevideo's api key
+ */
+function emvideo_livevideo_request($method, $args = array(), $cached = TRUE) {
+  $args['developerId'] = trim(variable_get('emvideo_livevideo_api_key', ''));
+  $request = module_invoke('emfield', 'request_xml', 'livevideo', EMVIDEO_LIVEVIDEO_REST_ENDPOINT . $method, $args, $cached);
+
+  return $request;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_livevideo_extract($embed = '') {
+  // <div><embed src="http://www.livevideo.com/flvplayer/embed/591C1350DD174FE0B10C4DCFC88981DA" type="application/x-shockwave-flash" quality="high" WIDTH="445" HEIGHT="369" wmode="transparent"></embed><br/><a href="http://www.livevideo.com/video/embedLink/591C1350DD174FE0B10C4DCFC88981DA/236172/mascot-bloopers-video.aspx">Mascot Bloopers Video</a></div>
+  // http://www.livevideo.com/video/591C1350DD174FE0B10C4DCFC88981DA/mascot-bloopers-video.aspx
+  // NOTE: the order of the following matters very much in this case...
+  return array(
+    '@livevideo\.com/flvplayer/embed/([^\"]*)\"@i',
+    '@livevideo\.com/video/([^/]*)/@i',
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_livevideo_embedded_link($video_code) {
+  $method = 'GetVideoDetails.ashx';
+  $args = array('videoId' => $video_code);
+  $request = emvideo_livevideo_request($method, $args);
+  $url = $request['VIDEODETAILS']['VIEWURL'][0];
+  return $url;
+}
+
+/**
+ * the embedded flash displaying the livevideo video
+ */
+function theme_emvideo_livevideo_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autostart = $autoplay ? '&amp;autoStart=1' : '';
+    $output .= '<embed src="http://www.livevideo.com/flvplayer/embed/'. $embed . $autostart .'" type="application/x-shockwave-flash" quality="high" WIDTH="'. $width .'" HEIGHT="'. $height .'" wmode="transparent"></embed>';
+  }
+
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_livevideo_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $method = 'GetVideoDetails.ashx';
+  $args = array('videoId' => $item['value']);
+  $request = emvideo_livevideo_request($method, $args);
+  $tn = $request['VIDEODETAILS']['DEFAULTTHUMBNAIL'][0];
+
+  return $tn;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_livevideo_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_livevideo_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_livevideo_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_livevideo_flash', $embed, $width, $height, $autoplay);
+
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_livevideo_emfield_subtheme() {
+  return array(
+    'emvideo_livevideo_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/livevideo.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/metacafe.inc contrib/emfield_generic/providers/emvideo/metacafe.inc
--- contrib/emfield_generic/providers/emvideo/metacafe.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/metacafe.inc	2008-11-23 15:21:24.000000000 -0600
@@ -0,0 +1,87 @@
+<?php
+// $Id: metacafe.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes metacafe.com media files for use by emfield.module.
+ */
+
+define('EMVIDEO_METACAFE_MAIN_URL', 'http://www.metacafe.com/');
+
+function emvideo_metacafe_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('Yes'), ''),
+  );
+  return array(
+    'provider' => 'metacafe',
+    'name' => t('MetaCafe'),
+    'url' => EMVIDEO_METACAFE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">MetaCafe</a>.', array('@provider' => EMVIDEO_METACAFE_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_metacafe_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ *  we're going to handle our own matches, unless someone can come up with a regex that will match this better
+ */
+function emvideo_metacafe_extract($embed) {
+  // http://www.metacafe.com/watch/479957/gorilla_prank/
+  if ($embed && preg_match('@metacafe\.com/watch/(.[^/]*)/(.[^/]*)/@i', $embed, $matches)) {
+    return $matches[1] .'/'. $matches[2];
+  }
+  else if ($embed && preg_match('@metacafe\.com/watch/(.[^/]*)/(.*)@i', $embed, $matches)) {
+    return $matches[1] .'/'. $matches[2];
+  }
+  // <embed src="http://www.metacafe.com/fplayer/479957/gorilla_prank.swf" width="400" height="345" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed><br><font size = 1><a href="http://www.metacafe.com/watch/479957/gorilla_prank/">Gorilla Prank</a> - <a href='http://www.metacafe.com/'>Celebrity bloopers here</a></font>
+  else if ($embed && preg_match('@metacafe\.com/fplayer/(.[^/]*)/(.[^\.]*)\.@i', $embed, $matches)) {
+    return $matches[1] .'/'. $matches[2];
+  }
+
+  return FALSE;
+}
+
+function emvideo_metacafe_video_link($video_code) {
+  return 'http://www.metacafe.com/watch/'. $video_code .'/';
+}
+
+function theme_emvideo_metacafe_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autoplay = $autoplay ? '?playerVars=autoPlay=yes' : '';
+    $output .= '<embed src="http://www.metacafe.com/fplayer/'. $embed .'.swf'. $autoplay .'" width="'. $width .'" height="'. $height .'" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed>';
+  }
+  return $output;
+}
+
+function emvideo_metacafe_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $picturelink=substr($item['value'], 0, 6);
+  return 'http://www.metacafe.com/thumb/'. $picturelink .'.jpg';
+}
+
+function emvideo_metacafe_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_metacafe_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_metacafe_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_metacafe_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_metacafe_emfield_subtheme() {
+  return array(
+    'emvideo_metacafe_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/metacafe.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/myspace.inc contrib/emfield_generic/providers/emvideo/myspace.inc
--- contrib/emfield_generic/providers/emvideo/myspace.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/myspace.inc	2008-11-23 15:21:34.000000000 -0600
@@ -0,0 +1,125 @@
+<?php
+// $Id: myspace.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes myspace.com media files for use by emfield.module.
+ */
+
+define('EMVIDEO_MYSPACE_MAIN_URL', 'http://vids.myspace.com/index.cfm?fuseaction=vids.videos');
+
+function emvideo_myspace_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('Yes'), ''),
+  );
+  return array(
+    'provider' => 'myspace',
+    'name' => t('MySpace'),
+    'url' => EMVIDEO_MYSPACE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">MySpace</a>.', array('@provider' => EMVIDEO_MYSPACE_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_myspace_settings() {
+  $form = array();
+  return $form;
+}
+
+function emvideo_myspace_request($code, $cacheable = TRUE) {
+  $args = array();
+  return module_invoke('emfield', 'request_xml', 'myspace', "http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid=$code", $args, $cacheable);
+}
+
+/**
+ *  this scrapes the thumbnail from the video page and caches it
+ */
+function _emvideo_myspace_scrape_thumbnail($video, $cached = TRUE) {
+  if (!$cached || !$cache = cache_get('myspace:thumbnail:'. $video, 'cache')) {
+    $vidid = drupal_substr($video, 0, 10);
+
+    if ($str = file_get_contents("http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid=$vidid")) {
+      // grab videos channel-id first
+      $channel_id = preg_replace('/.*tvchanid=([0-9]+);.*/si', '\1', $str);
+
+      if (is_numeric($channel_id)) {
+        // now from channel-page grab videos thumbnail
+        $str2 = file_get_contents("http://vids.myspace.com/index.cfm?fuseaction=vids.viewVideos&amp;channelid=$channel_id");
+
+        if ($str2) {
+          $picturelink = preg_replace('@.*href="[^"]+'. $vidid .'"[^>]+><img[^>]+src="([^"]+)".*@si', '\1',  $str2);
+
+          if ($picturelink) {
+            $thumbnail = $picturelink;
+            cache_set('myspace:thumbnail:'. $video, $thumbnail, 'cache', time() + 3600);
+          }
+        }
+      }
+    }
+  }
+  else {
+    $thumbnail = $cache->data;
+  }
+
+  return $thumbnail;
+}
+
+function emvideo_myspace_extract($embed) {
+  // <a href="http://myspacetv.com/index.cfm?fuseaction=vids.individual&videoid=14686340">What's That Floating In The Water Part 1</a><br><embed src="http://lads.myspace.com/videos/vplayer.swf" flashvars="m=14686340&v=2&type=video" type="application/x-shockwave-flash" width="430" height="346"></embed><br><a href="http://myspacetv.com/index.cfm?fuseaction=vids.addToProfileConfirm&videoid=14686340&title=What's That Floating In The Water Part 1">Add to My Profile</a> | <a href="http://myspacetv.com/index.cfm?fuseaction=vids.home">More Videos</a>
+  return array(
+    '@src="myspace\.com/index.cfm\?fuseaction=vids\.individual&amp;videoid=([^&"]+)@i',
+    '@myspace\.com/index\.cfm\?fuseaction=vids\.individual&amp;videoid=([^&"]+)@i',
+    '@src="myspacetv\.com/index.cfm\?fuseaction=vids\.individual&amp;videoid=([^&"]+)"@i',
+    '@myspacetv\.com/index\.cfm\?fuseaction=vids\.individual&amp;videoid=([^&"]+)@i',
+  );
+}
+
+function emvideo_myspace_video_link($video_code) {
+  return 'http://vids.myspace.com/index.cfm?fuseaction=vids.individual&amp;videoid='. $video_code;
+}
+
+function theme_emvideo_myspace_flash($embed, $width, $height) {
+  static $count = 0;
+  if ($embed) {
+    $output .= "    <object type=\"application/x-shockwave-flash\" height=\"$height\" width=\"$width\" data=\"http://lads.myspace.com/videos/vplayer.swf\" id=\"emfield-video-myspace-$count\" >
+      <param name=\"movie\" value=\"http://lads.myspace.com/videos/vplayer.swf\" />
+      <param name=\"allowScriptAcess\" value=\"sameDomain\"/>
+      <param name=\"quality\" value=\"best\"/>
+      <param name=\"bgcolor\" value=\"#FFFFFF\"/>
+      <param name=\"scale\" value=\"noScale\"/>
+      <param name=\"salign\" value=\"TL\"/>
+      <param name=\"FlashVars\" value=\"m=$embed&amp;type=video\" />
+      <param name=\"wmode\" value=\"transparent\" />
+    </object>\n";
+  }
+  $count++;
+  return $output;
+}
+
+function emvideo_myspace_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return _emvideo_myspace_scrape_thumbnail($item['value']);
+}
+
+function emvideo_myspace_video($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_myspace_flash', $embed, $width, $height);
+  return $output;
+}
+
+function emvideo_myspace_preview($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_myspace_flash', $embed, $width, $height);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_myspace_emfield_subtheme() {
+  return array(
+    'emvideo_myspace_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/myspace.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/revver.inc contrib/emfield_generic/providers/emvideo/revver.inc
--- contrib/emfield_generic/providers/emvideo/revver.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/revver.inc	2008-11-23 15:21:44.000000000 -0600
@@ -0,0 +1,90 @@
+<?php
+// $Id: revver.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes revver.com media files for use by emfield.module.
+ */
+
+define('EMVIDEO_REVVER_MAIN_URL', 'http://one.revver.com/revver');
+define('EMVIDEO_REVVER_AFFILIATE_PROGRAM_URL', 'http://one.revver.com/revver/go/faq#makingmoney1');
+
+function emvideo_revver_info() {
+  $features = array(
+    array(t('Affliate program'), t('Yes'), t('Not currently supported by other providers. Set affiliate ID above.')),
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('Yes'), t('May not currently resize thumbnails, but this will be easy to add. Meanwhile, you can override theme_emvideo_revver_thumbnail if you have a pressing need for this and know how to theme.')),
+  );
+  return array(
+    'provider' => 'revver',
+    'name' => t('Revver'),
+    'url' => EMVIDEO_REVVER_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">Revver</a>.', array('@provider' => EMVIDEO_REVVER_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_revver_settings() {
+  $form = array();
+  $form['revver']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Revver affiliate program'),
+    '#description' => t('You may share ad revenue if you publish Revver videos through their <a href="@program" target="_blank">Affiliate Program</a>.', array('@program' => EMVIDEO_REVVER_AFFILIATE_PROGRAM_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['revver']['api']['emvideo_revver_affiliate_id'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Revver associate key'),
+    '#default_value' => variable_get('emvideo_revver_affiliate_id', '0'),
+    '#description' => t('If you have a Revver Affiliate ID, you may enter it here. This is not required for viewing videos, but will give you proper credit when doing so. You can find your Affiliate ID by examining the URL of a video while logged into their site.'),
+  );
+  return $form;
+}
+
+function emvideo_revver_extract($embed) {
+  return array(
+    '@revver\.com/video/([^/]*)/@i',
+    '@revver\.com/video/(.*)@i',
+    '@revver\.com/player/1\.0/player\.js\?mediaId\:([^;]*);@i',
+  );
+}
+
+function emvideo_revver_video_link($video_code) {
+  return 'http://one.revver.com/video/'. $video_code;
+}
+
+function theme_emvideo_revver_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autoplay = $autoplay ? ';flashvars:autoStart=true;' : '';
+    $output .= '<script src="http://flash.revver.com/player/1.0/player.js?mediaId:'. $embed .';affiliateId:'. check_plain(variable_get('emvideo_revver_affiliate_id', '0')) .';height:'. $height .';width:'. $width . $autoplay .';" type="text/javascript"></script>';
+  }
+  return $output;
+}
+
+function emvideo_revver_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return 'http://frame.revver.com/frame/'. $width .'x'. $height .'/'. check_plain($item['value']) .'.jpg';
+}
+
+function emvideo_revver_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_revver_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_revver_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_revver_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_revver_emfield_subtheme() {
+  return array(
+    'emvideo_revver_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/revver.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/sevenload.inc contrib/emfield_generic/providers/emvideo/sevenload.inc
--- contrib/emfield_generic/providers/emvideo/sevenload.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/sevenload.inc	2008-11-23 15:21:54.000000000 -0600
@@ -0,0 +1,144 @@
+<?php
+// $Id: sevenload.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes Sevenload media files for use by emfield.module.
+ */
+
+define('EMVIDEO_SEVENLOAD_MAIN_URL', 'http://www.sevenload.com/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ */
+function emvideo_sevenload_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), ''),
+  );
+  return array(
+    'provider' => 'sevenload',
+    'name' => t('Sevenload'),
+    'url' => EMVIDEO_SEVENLOAD_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">Sevenload</a>.', array('@provider' => EMVIDEO_SEVENLOAD_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['youtube'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_sevenload_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_sevenload_extract($embed = '') {
+  // src="http://de.sevenload.com/pl/zuh5KMt"
+  // http://de.sevenload.com/videos/zuh5KMt/Die-Zeit-rennt
+  // hint: de.sevenload.com can also be en.sevenload.com and probably other languages later
+  return array(
+    '@sevenload\.com/pl/([^"]*)"@i',
+    '@sevenload\.com/videos/(.*)/(.*)@i',
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_video_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_sevenload_video_link($video_code) {
+  return 'http://www.sevenload.com/videos/'. $video_code;
+}
+
+function emvideo_sevenload_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return '';
+}
+
+/**
+ * the embedded flash displaying the Sevenload video
+ */
+function theme_emvideo_sevenload_flash($embed, $width, $height) {
+  if ($embed) {
+    $output .= "<object height=\"$height\" width=\"$width\"><param name=\"FlashVars\" value=\"slxml=en.sevenload.com\" /><param name=\"movie\" value=\"http://en.sevenload.com/pl/$embed/options/swf\" /><embed src=\"http://de.sevenload.com/pl/$embed/options/swf\" type=\"application/x-shockwave-flash\" width=\"$width\" height=\"$height\" FlashVars=\"slxml=en.sevenload.com\"></embed></object>";
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_sevenload_video($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_sevenload_flash', $embed, $width, $height);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_sevenload_preview($embed, $width, $height, $field, $item) {
+  $output = theme('emvideo_sevenload_flash', $embed, $width, $height);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_sevenload_emfield_subtheme() {
+  return array(
+    'emvideo_sevenload_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL),
+      'file' => 'providers/emvideo/sevenload.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/spike.inc contrib/emfield_generic/providers/emvideo/spike.inc
--- contrib/emfield_generic/providers/emvideo/spike.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/spike.inc	2008-11-23 15:22:04.000000000 -0600
@@ -0,0 +1,88 @@
+<?php
+// $Id: spike.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes Spike media files for use by emfield.module.
+ */
+
+define('EMVIDEO_SPIKE_MAIN_URL', 'http://www.spike.com/');
+
+function emvideo_spike_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), t('In the works...')),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('In the works...'), ''),
+  );
+  return array(
+    'provider' => 'spike tv',
+    'name' => t('Spike TV'),
+    'url' => EMVIDEO_SPIKE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@spike" target="_blank">Spike TV</a>.', array('@spike' => EMVIDEO_SPIKE_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_spike_settings() {
+  $form = array();
+  return $form;
+}
+
+function emvideo_spike_extract($embed) {
+  return array(
+    // http://www.spike.com/video/2836119/collection/19459/channel/comedy
+    // <embed width="448" height="365" src="http://www.spike.com/efp" quality="high" bgcolor="000000" name="efp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="flvbaseclip=2836119&"> </embed> <h1><a href="http://www.spike.com/video/2836119">"I Lost It" with Tom Cruize and Jesus</a></h1><span>Posted Mar 25, 2007</span><p>What happens when Jesus, Abe Lincoln, Tom Cruise, Dustin Hoffman, Buddha and Einstein play a friendly game of poker?</p>
+    '@spike\.com/efp"(?:.*)flvbaseclip=([^&]+)@i',
+    '@spike\.com/video/([^/&"\?]*)@i',
+  );
+}
+
+function emvideo_spike_request($embed, $cacheable = TRUE) {
+  return NULL;
+}
+
+function emvideo_spike_video_link($video_code) {
+  return 'http://www.spike.com/video/'. $video_code;
+}
+
+function theme_emvideo_spike_flash($embed, $width, $height, $autoplay) {
+  // TODO: figure out autoplay...
+  //<embed width="448" height="365" src="http://www.spike.com/efp" quality="high" bgcolor="000000" name="efp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="flvbaseclip=2952560&"> </embed>
+  if ($embed) {
+    $autoplay = $autoplay ? ' autoplay="true"' : '';
+    $output = '<embed width="'. $width .'" height="'. $height .'" src="http://www.spike.com/efp" quality="high" bgcolor="000000" name="efp" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="flvbaseclip='. $embed .'"> </embed>';
+  }
+
+  return $output;
+}
+
+/**
+ *  TODO: Is this correct? Using ifilmpro for thumbnails.
+ */
+function emvideo_spike_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $picturelink = drupal_substr($item['value'], 0, 7);
+
+  return 'http://img1.ifilmpro.com/resize/image/stills/films/resize/istd/'. $picturelink .'.jpg?width='. $width;
+}
+
+function emvideo_spike_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_spike_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_spike_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_spike_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_spike_emfield_subtheme() {
+  return array(
+    'emvideo_spike_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/spike.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/tudou.inc contrib/emfield_generic/providers/emvideo/tudou.inc
--- contrib/emfield_generic/providers/emvideo/tudou.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/tudou.inc	2008-11-23 15:22:14.000000000 -0600
@@ -0,0 +1,159 @@
+<?php
+// $Id: tudou.inc,v 1.1.2.3 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   Provide support for the Tudou provider to the emfield.module.
+ */
+
+define('EMVIDEO_TUDOU_MAIN_URL', 'http://www.tudou.com/');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_tudou_info() {
+  $features = array(
+    array(t('Autoplay'), t('No'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Thumbnails'), t('No'), t('')),
+  );
+  return array(
+    'provider' => 'tudou',
+    'name' => t('Tudou'),
+    'url' => EMVIDEO_TUDOU_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@tudou" target="_blank">Tudou</a>.', array('@tudou' => EMVIDEO_TUDOU_MAIN_URL)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['tudou'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_tudou_settings() {
+  $form = array();
+  return $form;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_tudou_extract($embed = '') {
+  // http://www.tudou.com/programs/view/uprLNXyEGpc/
+  // <object width="400" height="300"><param name="movie" value="http://www.tudou.com/v/uprLNXyEGpc"></param><param name="allowScriptAccess" value="always"></param><param name="wmode" value="transparent"></param><embed src="http://www.tudou.com/v/uprLNXyEGpc" type="application/x-shockwave-flash" width="400" height="300" allowFullScreen="true" wmode="transparent" allowScriptAccess="always"></embed></object>
+  return array(
+    '@tudou\.com/programs/view/([^"\&/]+)@i',
+    '@value="http\://www\.tudou\.com/v/([^"\&/]+)@i'
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_tudou_embedded_link($video_code) {
+  return 'http://www.tudou.com/programs/view/'. $video_code;
+}
+
+/**
+ * the embedded flash displaying the tudou video
+ */
+function theme_emvideo_tudou_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $output .= "
+      <object width=\"$width\" height=\"$height\">
+        <param name=\"movie\" value=\"http://www.tudou.com/v/$embed\"></param>
+        <param name=\"allowScriptAccess\" value=\"always\"></param>
+        <param name=\"wmode\" value=\"transparent\"></param>
+        <embed src=\"http://www.tudou.com/v/$embed\" type=\"application/x-shockwave-flash\" width=\"$width\" height=\"$height\" allowFullScreen=\"true\" wmode=\"transparent\" allowScriptAccess=\"always\"></embed>
+        </object>
+    ";
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_tudou_thumbnail($field, $item, $formatter, $node, $width, $height) {
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_tudou_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_tudou_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_tudou_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_tudou_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_tudou_emfield_subtheme() {
+  return array(
+    'emvideo_tudou_flash' => array(
+      'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+      'file' => 'providers/emvideo/tudou.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/veoh.inc contrib/emfield_generic/providers/emvideo/veoh.inc
--- contrib/emfield_generic/providers/emvideo/veoh.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/veoh.inc	2008-11-23 15:22:24.000000000 -0600
@@ -0,0 +1,129 @@
+<?php
+// $Id: veoh.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   Provide support for the Veoh provider to the emfield.module.
+ */
+
+define('EMVIDEO_VEOH_MAIN_URL', 'http://www.veoh.com/');
+define('EMVIDEO_VEOH_API_INFO', 'http://www.veoh.com/restApiDoc/restReference.html');
+define('EMVIDEO_VEOH_API_APPLICATION_URL', 'http://www.veoh.com/developers.html');
+define('EMVIDEO_VEOH_XML', 'http://www.veoh.com/rest/video/');
+
+function emvideo_veoh_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('No'), ''),
+    array(t('Show related videos'), t('No'), t('This is embedded in the video itself when enabled; currently not available with other providers. Set the feature above.')),
+    array(t('Thumbnails'), t('Yes'), t('May not currently resize thumbnails. Must have an API key for thumbnails at the moment, although research is underway to determine an alternative to this. Set your API key above.')),
+  );
+  return array(
+    'provider' => 'veoh',
+    'name' => t('Veoh'),
+    'url' => EMVIDEO_VEOH_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@veoh" target="_blank">Veoh</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@veoh' => EMVIDEO_VEOH_MAIN_URL, '@api' => EMVIDEO_VEOH_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+function emvideo_veoh_settings() {
+  $form['veoh']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Veoh API'),
+    '#description' => t('If you wish to be able to display Veoh thumbnails automatically, you will first need to apply for an API Developer Key from the <a href="@veoh" target="_blank">Veoh Developer Profile page</a>. Note that you do not need this key to display Veoh videos themselves.', array('@veoh' => EMVIDEO_VEOH_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['veoh']['api']['emvideo_veoh_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Veoh API Key'),
+    '#default_value' => variable_get('emvideo_veoh_api_key', ''),
+    '#description' => t('Please enter your Veoh Developer Key here.'),
+  );
+  $form['veoh']['api']['emvideo_veoh_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Veoh API Secret'),
+    '#default_value' => variable_get('emvideo_veoh_api_secret', ''),
+    '#description' => t('If you have a secret for the Veoh API, enter it here.'),
+  );
+  return $form;
+}
+
+
+function emvideo_veoh_request($embed, $cacheable = TRUE) {
+  $args = array('docid' => $embed);
+  return module_invoke('emfield', 'request_xml', 'veoh', EMVIDEO_VEOH_XML . $embed .'/details', $args, $cacheable);
+}
+
+function emvideo_veoh_extract($embed = '') {
+  return array(
+    '@http://www\.veoh\.com/videos/([^"\?]+)@i',
+    '@http://www\.veoh\.com/videodetails2\.swf\?permalinkId=([^"\&]*)@i',
+  );
+}
+
+function emvideo_veoh_embedded_link($video_code) {
+  return 'http://www.veoh.com/videos/'. $video_code;
+}
+
+function theme_emvideo_veoh_flash($embed, $width, $height, $autoplay) {
+  if ($embed) {
+    $autoplay = $autoplay ? '&amp;videoAutoPlay=1' : '&amp;videoAutoPlay=0';
+
+    $output .= '<embed src="http://www.veoh.com/videodetails2.swf?permalinkId='. $embed .'&amp;id=9183600&amp;player=videodetailsembedded'. $autoplay .'" allowFullScreen="true" width="'. $width .'" height="'. $height .'" bgcolor="#FFFFFF" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
+  }
+  return $output;
+}
+
+function emvideo_veoh_check_thumbnail($thumbnail_check) {
+  if ($thumbnail_status=@fopen($thumbnail_check, "r")) {
+    fclose($thumbnail_status);
+    return $thumbnail_status;
+  }
+  return NULL;
+}
+
+function emvideo_veoh_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $thumbid = $item['value'];
+  //$xml = emvideo_veoh_request($item['value']);
+  //print_r($xml);
+  // make the thumb index zero to follow their standard web tag format.
+
+  // - Rysk
+  $thumbnail = 'http://p-images.veoh.com/thumb.out?imageId=thumb-'. $thumbid .'-'. rand(0, 30) .'.jpg';
+  if (emvideo_veoh_check_thumbnail($thumbnail) != NULL) {
+    return $thumbnail;
+  } 
+  else {
+    $url = 'http://www.veoh.com/rest/video/'. $thumbid .'/details';
+    $content = file_get_contents($url);
+    if ($content) {
+      print '(start)<br>';
+      print $content;
+      print '(end)<br>';
+      $start = strpos($content, 'fullMedResImagePath="')+21;
+      $end = strpos($content, '"', $start);
+      $thumbnail = substr($content, $start, $end-$start);
+    }
+    return $thumbnail;
+  }
+}
+
+function emvideo_veoh_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_veoh_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+function emvideo_veoh_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_veoh_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+function emvideo_veoh_emfield_subtheme() {
+  return array(
+  'emvideo_veoh_flash' => array(
+  'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+  'file' => 'providers/emvideo/veoh.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/vimeo.inc contrib/emfield_generic/providers/emvideo/vimeo.inc
--- contrib/emfield_generic/providers/emvideo/vimeo.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/vimeo.inc	2008-11-23 15:22:34.000000000 -0600
@@ -0,0 +1,236 @@
+<?php
+// $Id: vimeo.inc,v 1.1.2.3 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   Provide support for the Vimeo provider to the emfield.module.
+ */
+
+define('EMVIDEO_VIMEO_MAIN_URL', 'http://www.vimeo.com/');
+define('EMVIDEO_VIMEO_API_INFO', 'http://vimeo.com/api');
+define('EMVIDEO_VIMEO_COLOR_DEFAULT', '#01AAEA');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_vimeo_info() {
+  $features = array(
+    array(t('Custom player color'), t('Yes'), t("You may customize the player's skin by choosing your own color.")),
+    array(t('Thumbnails'), t('Yes'), t('You may select the size of thumbnail to request from Vimeo.')),
+    array(t('Full screen mode'), t('Yes'), t('You may customize the player to enable or disable full screen playback. Full screen mode is enabled by default.')),
+  );
+  return array(
+    'provider' => 'vimeo',
+    'name' => t('Vimeo'),
+    'url' => EMVIDEO_VIMEO_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@provider" target="_blank">Vimeo</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@provider' => EMVIDEO_VIMEO_MAIN_URL, '@api' => EMVIDEO_VIMEO_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['vimeo'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_vimeo_settings() {
+  $form['vimeo']['color'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Embedded video player color'),
+    '#description' => t('If allowed, this color, in hexidecimal form (#RRGGBB), will be used to change the skin of the Vimeo player.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['vimeo']['color']['emvideo_vimeo_color_override'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Override player color'),
+    '#default_value' => variable_get('emvideo_vimeo_color_override', FALSE),
+  );
+  $form['vimeo']['color']['emvideo_vimeo_color'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Color'),
+    '#default_value' => variable_get('emvideo_vimeo_color', EMVIDEO_VIMEO_COLOR_DEFAULT),
+  );
+  $form['vimeo']['player_options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Embedded video player options'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['vimeo']['player_options']['emvideo_vimeo_on_screen_info'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('On-screen info'),
+    '#default_value' => variable_get('emvideo_vimeo_on_screen_info', array('portrait', 'title', 'byline')),
+  '#options' => array(
+      'portrait' => t("Show video author's portrait"),
+      'title' => t('Show video title'),
+      'byline' => t('Show byline'),
+    ),
+    '#description' => t('Provide additional video information on the Vimeo player.'),
+  );
+  $form['vimeo']['player_options']['emvideo_vimeo_full_screen'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Allow fullscreen'),
+  '#default_value' => variable_get('emvideo_vimeo_full_screen', 1),
+  '#description' => t('Allow users to view video using the entire computer screen.'),
+  );
+  $form['vimeo']['emvideo_vimeo_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Vimeo API Key'),
+    '#default_value' => variable_get('emvideo_vimeo_api_key', ''),
+  );
+  $form['vimeo']['emvideo_vimeo_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Vimeo API Shared Secret'),
+    '#default_value' => variable_get('emvideo_vimeo_api_secret', ''),
+  );
+  $form['vimeo']['emvideo_vimeo_thumb_size'] = array(
+    '#type' => 'select',
+    '#title' => t('Vimeo Thumbnail Size'),
+    '#options' => array('96' => '96', '100' => '100', '160' => '160', '200' => '200', '460' => '460'),
+    '#default_value' => variable_get('emvideo_vimeo_thumb_size', '160'),
+  );
+  return $form;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_vimeo_extract($embed = '') {
+  // http://vimeo.com/123456
+  // http://www.vimeo.com/123456
+  return array(
+    '@vimeo\.com/([^\"\&]+)@i',
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_vimeo_embedded_link($video_code) {
+  return 'http://www.vimeo.com/'. $video_code;
+}
+
+function emvideo_vimeo_convert_color($color = NULL) {
+  if ($color{0} == '#') {
+    return substr($color, 1);
+  }
+  return $color;
+}
+
+/**
+ * the embedded flash displaying the Vimeo video
+ */
+function theme_emvideo_vimeo_flash($embed, $width, $height, $autoplay) {
+  $output = '';
+  if ($embed) {
+  $fullscreen = variable_get('emvideo_vimeo_full_screen', 1);
+  $on_screen_info = variable_get('emvideo_vimeo_on_screen_info', array('portrait', 'title', 'byline'));
+  $show_portrait = $on_screen_info['portrait'] ? 1 : 0;
+  $show_title = $on_screen_info['title'] ? 1 : 0;
+  $show_byline = $on_screen_info['byline'] ? 1 : 0;
+    if (variable_get('emvideo_vimeo_color_override', FALSE)) {
+      $color = emvideo_vimeo_convert_color(variable_get('emvideo_vimeo_color', EMVIDEO_VIMEO_COLOR_DEFAULT));
+    }
+    $output = '<object type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'" data="http://www.vimeo.com/moogaloop.swf?clip_id='. $embed .'&amp;server=www.vimeo.com&amp;fullscreen='. $fullscreen .'&amp;show_title='. $show_title .'&amp;show_byline='. $show_byline .'&amp;show_portrait='. $show_portrait .'&amp;color='. $color .'">';
+    $output .= '<param name="quality" value="best" />';
+    $output .= '<param name="allowfullscreen" value="'. ($fullscreen ? 'true' : 'false') .'" />';
+    $output .= '<param name="scale" value="showAll" />';
+    $output .= '<param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id='. $embed .'&amp;server=www.vimeo.com&amp;fullscreen='. $fullscreen .'&amp;show_title='. $show_title .'&amp;show_byline='. $show_byline .'&amp;show_portrait='. $show_portrait .'&amp;color='. $color .'" /></object>';
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_vimeo_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_vimeo_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_vimeo_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_vimeo_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_vimeo_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $vimeo_id = (substr($item['value'], -1, 1)=='/') ? substr($item['value'], 0, -1) : $item['value'];
+  $vimeo_signature = variable_get('emvideo_vimeo_api_secret', '') .'api_key'. variable_get('emvideo_vimeo_api_key', '') .'method'.'vimeo.videos.getThumbnailUrl'.'size'. variable_get('emvideo_vimeo_thumb_size', '160') .'video_id'. $vimeo_id;
+  $vimeo_apicall = 'http://www.vimeo.com/api/rest?'.'api_key='. variable_get('emvideo_vimeo_api_key', '') .'&method='.'vimeo.videos.getThumbnailUrl'.'&size='. variable_get('emvideo_vimeo_thumb_size', '160') .'&video_id='. $vimeo_id .'&api_sig='. md5($vimeo_signature);
+  $api_file = file_get_contents($vimeo_apicall);
+  $data = array();
+  preg_match("#<thumbnail .*>(.*)</thumbnail>#i", $api_file, $data);
+  return $data[1];
+}
+
+function emvideo_vimeo_emfield_subtheme() {
+  return array(
+  'emvideo_vimeo_flash' => array(
+  'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+  'file' => 'providers/emvideo/brightcove.inc'
+    )
+  );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/youtube.inc contrib/emfield_generic/providers/emvideo/youtube.inc
--- contrib/emfield_generic/providers/emvideo/youtube.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/youtube.inc	2008-11-23 15:22:44.000000000 -0600
@@ -0,0 +1,379 @@
+<?php
+// $Id: youtube.inc,v 1.1.2.12 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ *   This include processes youtube.com media files for use by emfield.module.
+ */
+
+define('EMVIDEO_YOUTUBE_MAIN_URL', 'http://www.youtube.com/');
+define('EMVIDEO_YOUTUBE_API_INFO', 'http://youtube.com/dev');
+define('EMVIDEO_YOUTUBE_API_APPLICATION_URL', 'http://www.youtube.com/my_profile_dev');
+define('EMVIDEO_YOUTUBE_REST_ENDPOINT', 'http://www.youtube.com/api2_rest');
+define('EMVIDEO_YOUTUBE_COLOR1_DEFAULT', '#FFFFFF');
+define('EMVIDEO_YOUTUBE_COLOR2_DEFAULT', '#CCCCCC');
+
+/**
+ * hook emvideo_PROVIDER_info
+ * this returns information relevant to a specific 3rd party video provider
+ * @return
+ *   an array of strings requested by various admin and other forms
+ *   'name' => the translated name of the provider
+ *   'url' => the url to the main page for the provider
+ *   'settings_description' => a description of the provider that will be posted in the admin settings form
+ *   'supported_features' => an array of rows describing the state of certain supported features by the provider.
+ *      These will be rendered in a table, with the columns being 'Feature', 'Supported', 'Notes'.
+ */
+function emvideo_youtube_info() {
+  $features = array(
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS Attachment'), t('Yes'), ''),
+    array(t('Show related videos'), t('Yes'), t('This is embedded in the video itself when enabled; currently not available with other providers. Set the feature above.')),
+    array(t('Thumbnails'), t('Yes'), t('')),
+    array(t('Custom player colors'), t('Yes'), t("You may customize the player's skin by choosing your own colors, and/or border in that setting field set.")),
+  );
+  return array(
+    'provider' => 'youtube',
+    'name' => t('YouTube'),
+    'url' => EMVIDEO_YOUTUBE_MAIN_URL,
+    'settings_description' => t('These settings specifically affect videos displayed from <a href="@youtube" target="_blank">YouTube</a>. You can learn more about its <a href="@api" target="_blank">API</a> here.', array('@youtube' => EMVIDEO_YOUTUBE_MAIN_URL, '@api' => EMVIDEO_YOUTUBE_API_INFO)),
+    'supported_features' => $features,
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_settings
+ * this should return a subform to be added to the emvideo_settings() admin settings page.
+ * note that a form field will already be provided, at $form['PROVIDER'] (such as $form['youtube'])
+ * so if you want specific provider settings within that field, you can add the elements to that form field.
+ */
+function emvideo_youtube_settings() {
+  $form['youtube']['emvideo_youtube_show_related_videos'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show related videos'),
+    '#default_value' => variable_get('emvideo_youtube_show_related_videos', 0),
+    '#description' => t('If checked, then when playing a video from YouTube, users may hover over the video to see thumbnails & links to related videos.'),
+  );
+  $form['youtube']['api'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('YouTube API'),
+    '#description' => t('The API is no longer required. However, there may be future features requiring it (such as the ability to display otherwise private videos). You will first need to apply for an API Developer Key from the <a href="@youtube" target="_blank">YouTube Developer Profile page</a>. Note that you do not need this key to display YouTube videos or their thumbnails.', array('@youtube' => EMVIDEO_YOUTUBE_API_APPLICATION_URL)),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['youtube']['api']['emvideo_youtube_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('YouTube API Key'),
+    '#default_value' => variable_get('emvideo_youtube_api_key', ''),
+    '#description' => t('Please enter your YouTube Developer Key here.'),
+  );
+  $form['youtube']['api']['emvideo_youtube_api_secret'] = array(
+    '#type' => 'textfield',
+    '#title' => t('YouTube API Secret'),
+    '#default_value' => variable_get('emvideo_youtube_api_secret', ''),
+    '#description' => t('If you have a secret for the YouTube API, enter it here.'),
+  );
+  $form['youtube']['colors'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Embedded Video Player Colors'),
+    '#description' => t('If allowed, these two colors, in hexidecimal form (#RRGGBB), will be used to skin the YouTube player.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['youtube']['colors']['emvideo_youtube_show_colors'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Override player colors'),
+    '#default_value' => variable_get('emvideo_youtube_show_colors', FALSE),
+  );
+  $form['youtube']['colors']['emvideo_youtube_show_border'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Display border around player'),
+    '#default_value' => variable_get('emvideo_youtube_show_border', FALSE),
+  );
+  $form['youtube']['colors']['emvideo_youtube_colors_color1'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Color 1'),
+    '#default_value' => variable_get('emvideo_youtube_colors_color1', EMVIDEO_YOUTUBE_COLOR1_DEFAULT),
+  );
+  $form['youtube']['colors']['emvideo_youtube_colors_color2'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Color 2'),
+    '#default_value' => variable_get('emvideo_youtube_colors_color2', EMVIDEO_YOUTUBE_COLOR2_DEFAULT),
+  );
+  if (module_exists('colorpicker')) {
+    $form['youtube']['colors']['emvideo_youtube_colors_color1']['#type'] = 'colorpicker_textfield';
+    $form['youtube']['colors']['emvideo_youtube_colors_color1']['#colorpicker'] = 'colorpicker_1';
+    $form['youtube']['colors']['emvideo_youtube_colors_color2']['#type'] = 'colorpicker_textfield';
+    $form['youtube']['colors']['emvideo_youtube_colors_color2']['#colorpicker'] = 'colorpicker_2';
+    $form['youtube']['colors']['colorpicker_1'] = array(
+      '#type' => 'colorpicker',
+      '#title' => t('Color 1 picker'),
+      '#description' => t('Click in this textfield to start picking your color'),
+    );
+    $form['youtube']['colors']['colorpicker_2'] = array(
+      '#type' => 'colorpicker',
+      '#title' => t('Color 2 picker'),
+      '#description' => t('Click in this textfield to start picking your color'),
+    );
+  }
+  else {
+    $form['youtube']['colors']['#description'] .= ' '. t('The <a href="@colorpicker">Colorpicker module</a>, if active, gives an easy way to select these colors.', array('@colorpicker' => 'http://drupal.org/project/colorpicker'));
+  }
+  return $form;
+}
+
+/**
+ * hook emfield_PROVIDER_data
+ *
+ * provides an array to be serialised and made available with $item elsewhere
+ */
+function emvideo_youtube_data($field, $item) {
+  $data = array();
+  // create some 'field' version control
+  $data['emvideo_youtube_version'] = 1;
+
+  // be nice to make this an array for changing media:thumbnail?
+  $data['thumbnail']['url'] = 'http://img.youtube.com/vi/'. $item['value'] .'/0.jpg';
+
+  // gather info about the item
+  // RSS / MRSS feeds with the item would have enough info
+  // alternative try getting the minimum from an http get
+  $url = 'http://youtube.com/v/'. $item['value'];
+  $response = emfield_request_header('youtube', $url);
+
+  if ($response->code == 200) {
+    // probably shouldn't give the 303 path
+    $data['flash']['url'] = $url;
+    $data['flash']['size'] = $response->headers['Content-Length'];
+    $data['flash']['mime'] = $response->headers['Content-Type'];
+  }
+
+  return $data;
+}
+
+/**
+ *
+ */
+function emvideo_youtube_rss($item, $teaser = NULL) {
+  if ($item['value']) {
+    if ($item['data']['emvideo_youtube_data_version'] >= 1) {
+      $data = $item['data'];
+    }
+    else {
+      $data = emvideo_youtube_data(NULL, $item);
+    }
+
+    $file = array();
+    if (is_array($data['flash'])) {
+      $file['filepath'] = $data['flash']['url'];
+      $file['filesize'] = $data['flash']['size'];
+      $file['filemime'] = $data['flash']['mime'];
+    }
+    $file['thumbnail']['filepath'] = $data['thumbnail']['url'];
+
+    return $file;
+  }
+}
+
+/**
+ * this is a wrapper for emvideo_request_xml that includes youtube's api key
+ */
+function emvideo_youtube_request($method, $args = array(), $cached = TRUE) {
+  $args['dev_id'] = trim(variable_get('emvideo_youtube_api_key', ''));
+  $args['method'] = $method;
+
+  // if we've got a secret sign the arguments
+  // TODO: doesn't seem to matter
+//  if ($secret = trim(variable_get('emvideo_youtube_api_secret', ''))) {
+//    $args['api_sig'] = md5($secret . $arghash);
+//  }
+
+  $request = module_invoke('emfield', 'request_xml', 'youtube', EMVIDEO_YOUTUBE_REST_ENDPOINT, $args, $cached);
+  return $request;
+}
+
+/**
+ * hook emvideo_PROVIDER_extract
+ * this is called to extract the video code from a pasted URL or embed code.
+ * @param $embed
+ *   an optional string with the pasted URL or embed code
+ * @return
+ *   either an array of regex expressions to be tested, or a string with the video code to be used
+ *   if the hook tests the code itself, it should return either the string of the video code (if matched), or an empty array.
+ *   otherwise, the calling function will handle testing the embed code against each regex string in the returned array.
+ */
+function emvideo_youtube_extract($embed = '') {
+  // src="http://www.youtube.com/v/nvbQQnvxXDk"
+  // http://youtube.com/watch?v=nvbQQnvxXDk
+  // http://www.youtube.com/watch?v=YzFCA-xUc8w&feature=dir
+  return array(
+    '@youtube\.com/v/([^"\&]+)@i',
+    '@youtube\.com/watch\?v=([^"\&]+)@i',
+     '@youtube\.com/\?v=([^"\&]+)@i',
+  );
+}
+
+/**
+ * hook emvideo_PROVIDER_embedded_link($video_code)
+ * returns a link to view the video at the provider's site
+ *  @param $video_code
+ *    the string containing the video to watch
+ *  @return
+ *    a string containing the URL to view the video at the original provider's site
+ */
+function emvideo_youtube_embedded_link($video_code) {
+  return 'http://www.youtube.com/watch?v='. $video_code;
+}
+
+function emvideo_youtube_convert_color($color = NULL) {
+  if ($color{0} == '#') {
+    return drupal_substr($color, 1);
+  }
+
+  return $color;
+}
+
+/**
+ * The embedded flash displaying the youtube video.
+ */
+function theme_emvideo_youtube_flash($embed, $width, $height, $autoplay, $options = array()) {
+  static $count;
+  if ($embed) {
+    $related = isset($options['related']) ? $options['related'] : variable_get('emvideo_youtube_show_related_videos', 0);
+    $related = "rel=$related";
+    $autoplay = isset($options['autoplay']) ? $options['autoplay'] : $autoplay;
+    $autoplay_value = $autoplay ? '&autoplay=1' : '';
+    $show_colors = isset($options['show_colors']) ? $options['show_colors'] : variable_get('emvideo_youtube_show_colors', FALSE);
+    if ($show_colors) {
+      $color1 = isset($options['color1']) ? $options['color1'] : variable_get('emvideo_youtube_colors_color1', emvideo_YOUTUBE_COLOR1_DEFAULT);
+      $color2 = isset($options['color2']) ? $options['color2'] : variable_get('emvideo_youtube_colors_color2', emvideo_YOUTUBE_COLOR2_DEFAULT);
+      $colors='&color1=0x'. emvideo_youtube_convert_color($color1) .'&color2=0x'. emvideo_youtube_convert_color($color2);
+    }
+    $border = isset($options['border']) ? $options['border'] : variable_get('emvideo_youtube_show_border', FALSE);
+    $border = $border ? '&border=1' : '';
+    $enablejsapi = isset($options['enablejsapi']) ? $options['enablejsapi'] : variable_get('emvideo_youtube_enablejsapi', TRUE);
+    $enablejsapi = $enablejsapi ? '&enablejsapi=1&playerapiid=ytplayer' : '';
+    $id = isset($options['id']) ? $options['id'] : 'video-cck-youtube-flash-'. (++$count);
+    $div_id = isset($options['div_id']) ? $options['div_id'] : 'video-cck-youtube-flash-wrapper-'. $count;
+    $url = "http://www.youtube.com/v/$embed&amp;$related$autoplay_value$colors$border$enablejsap";
+    if (variable_get('emfield_swfobject', FALSE) && (module_exists('swfobject_api') || variable_get('emfield_swfobject_location', ''))) {
+      if (module_exists('swfobject_api')) {
+        $params['width'] = $width;
+        $params['height'] = $height;
+        $params['div_id'] = $id;
+        $output .= theme('swfobject_api', $url, $params, $vars, $id);
+      }
+      else {
+        drupal_add_js(variable_get('emfield_swfobject_location', ''));
+        $output .= <<<FLASH
+          <div id="$div_id">
+            Sorry, you need to install flash to see this content.
+          </div>
+          <script language="JavaScript" type="text/javascript">
+            var so = new SWFObject("$url", "$id", "$width", "$height", "7");
+            so.write("$div_id");
+          </script>
+FLASH;
+      }
+    }
+    else {
+      $output .= <<<FLASH
+        <div id="$div_id"><object type="application/x-shockwave-flash" height="$height" width="$width" data="$url" id="$id">
+          <param name="movie" value="$url" />
+          <param name="allowScriptAcess" value="sameDomain"/>
+          <param name="quality" value="best"/>
+          <param name="bgcolor" value="#FFFFFF"/>
+          <param name="scale" value="noScale"/>
+          <param name="salign" value="TL"/>
+          <param name="FlashVars" value="playerMode=embedded" />
+          <param name="wmode" value="transparent" />
+        </object></div>
+FLASH;
+    }
+  }
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_thumbnail
+ * returns the external url for a thumbnail of a specific video
+ * TODO: make the args: ($embed, $field, $item), with $field/$item provided if we need it, but otherwise simplifying things
+ *  @param $field
+ *    the field of the requesting node
+ *  @param $item
+ *    the actual content of the field from the requesting node
+ *  @return
+ *    a URL pointing to the thumbnail
+ */
+function emvideo_youtube_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  $youtube_id = $item['value'];
+  // Old code to grab thumbnail via API.
+//$request = emvideo_youtube_request('youtube.videos.get_details', array('video_id' => $youtube_id));
+//$tn = $request['THUMBNAIL_URL'][0];
+
+  // if we have a large thumbnail size, then get the larger version available.
+  if ($width > 130 || $height > 97) {
+    $tn = "http://img.youtube.com/vi/$youtube_id/0.jpg";
+  }
+  else {
+    // youtube offers 3 thumbnails. select one randomly.
+    $rand = rand(0, 2) + 1;
+    $tn = "http://img.youtube.com/vi/$youtube_id/$rand.jpg";
+  }
+
+  return $tn;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the full/normal-sized video we want, usually on the default page view
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_youtube_video($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_youtube_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * hook emvideo_PROVIDER_video
+ * this actually displays the preview-sized video we want, commonly for the teaser
+ *  @param $embed
+ *    the video code for the video to embed
+ *  @param $width
+ *    the width to display the video
+ *  @param $height
+ *    the height to display the video
+ *  @param $field
+ *    the field info from the requesting node
+ *  @param $item
+ *    the actual content from the field
+ *  @return
+ *    the html of the embedded video
+ */
+function emvideo_youtube_preview($embed, $width, $height, $field, $item, $autoplay) {
+  $output = theme('emvideo_youtube_flash', $embed, $width, $height, $autoplay);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_youtube_emfield_subtheme() {
+    return array(
+        'emvideo_youtube_flash'  => array(
+            'arguments' => array('embed' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL),
+            'file' => 'providers/emvideo/youtube.inc'
+        )
+    );
+}
diff -urpN contrib/emfield_generic/providers/emvideo/zzz_custom_url.inc contrib/emfield_generic/providers/emvideo/zzz_custom_url.inc
--- contrib/emfield_generic/providers/emvideo/zzz_custom_url.inc	1969-12-31 18:00:00.000000000 -0600
+++ contrib/emfield_generic/providers/emvideo/zzz_custom_url.inc	2008-11-23 15:22:52.000000000 -0600
@@ -0,0 +1,164 @@
+<?php
+// $Id: zzz_custom_url.inc,v 1.1.2.9 2008/10/21 17:14:56 alexua Exp $
+
+/**
+ * @file
+ *   This is an include file used by emfield.module.
+ */
+
+function _emvideo_zzz_custom_url_default_types() {
+  return array('wmv', 'wma', 'swf', 'flv', 'mov', 'rm', 'mp4');
+}
+
+function emvideo_zzz_custom_url_info() {
+  $name = t('Custom URL');
+  $features = array(
+    array(t('Thumbnails'), t('No'), ''),
+    array(t('Autoplay'), t('Yes'), ''),
+    array(t('RSS attachment'), t('No'), ''),
+  );
+  return array(
+    'provider' => 'zzz_custom_url',
+    'name' => $name,
+    'url' => '',
+    'settings_description' => t('These settings specifically affect videos displayed from custom URLs. When a field uses a URL it determines to be a link directly to a video file, it will embed that file into the content.'),
+    'supported_features' => $features,
+    'weight' => 9,
+  );
+}
+
+function emvideo_zzz_custom_url_settings() {
+  $options = array(
+    'wmv' => t('Windows Media (wmv)'),
+    'wma' => t('Windows Media (wma)'),
+    'swf' => t('Flash (swf)'),
+    'flv' => t('Flash Video (flv)'),
+    'mov' => t('Quicktime (mov)'),
+    'mp4' => t('Quicktime (mp4)'),
+    'rm' => t('Real Media (rm)'),
+  );
+  $form = array();
+  $form['emvideo_zzz_custom_url_supported_types'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Supported Types'),
+    '#options' => $options,
+    '#default_value' => variable_get('emvideo_zzz_custom_url_supported_types', _emvideo_zzz_custom_url_default_types()),
+    '#description' => t('Select the video types you wish to support. When a custom url with that type is entered into an embedded video field, it will be parsed and displayed appropriately. If a type is not supported, then it will be ignored.'),
+  );
+  return $form;
+}
+
+function _emvideo_zzz_custom_url_implode_types() {
+  return implode('|', variable_get('emvideo_zzz_custom_url_supported_types', _emvideo_zzz_custom_url_default_types()));
+}
+
+function emvideo_zzz_custom_url_extract($embed = '') {
+  $types = _emvideo_zzz_custom_url_implode_types();
+  $baseurl = preg_quote(url(null, array('absolute' => TRUE)), '@');
+
+  return array(
+    '@' . $baseurl . '(.*' . '\.(?:' . $types . ')' . '(\?.*)?)@i',
+    '@(.*\.(?:'. $types .')(\?.*)?)@i'
+  );
+}
+
+function emvideo_zzz_custom_url_data($field, $item) {
+  $data = array();
+  // adding the version control
+  $data['emvideo_zzz_custom_url_data_version'] = 1;
+
+  // attempt to get info from headers
+  $response = emfield_request_header('zzz_custom_url', $item['embed']);
+
+  if ($response->code == 200) {
+    $data['url'] = $item['embed'];
+    $data['size'] = $response->headers['Content-Length'];
+    $data['mime'] = $response->headers['Content-Type'];
+  }
+  // @todo replace ['type'] with converted mime info if available
+  $types = _emvideo_zzz_custom_url_implode_types();
+  $regex = '@\.('. $types .')@i';
+  if (preg_match($regex, $item['embed'], $matches)) {
+    $data['type'] = $matches[1];
+  }
+  return $data;
+}
+
+/**
+ * hook emfield_PROVIDER_rss
+ */
+function emvideo_zzz_custom_url_rss($item, $teaser = NULL) {
+  if ($item['value']) {
+    if ($item['data']['emvideo_zzz_custom_url_data_version'] >= 1) {
+      $data = $item['data'];
+    }
+    else {
+      $data = emvideo_zzz_custom_url_data(NULL, $item);
+    }
+
+    $file = array();
+    if ($data['size'] > 0) {
+      $file['filepath'] = $data['url'];
+      $file['filesize'] = $data['size'];
+      $file['filemime'] = $data['mime'];
+    }
+
+    return $file;
+  }
+}
+
+
+function emvideo_zzz_custom_url_embedded_link($video_code) {
+  return $video_code;
+}
+
+function theme_emvideo_zzz_custom_url_embedded_video($type, $url, $width, $height, $autoplay = FALSE, $field = NULL, $item = NULL) {
+  if ($url) {
+    switch ($type) {
+      case 'wmv':
+      case 'wma':
+        $autostart = $autoplay ? '1' : '0';
+        return '<embed src="'. $url .'" width="'. $width .'" height="'. $height .'" autostart="'. $autostart .'" showcontrols="1" type="application/x-mplayer2" pluginspage="http://www.microsoft.com/windows/windowsmedia/download/"> </embed>';
+      case 'mov':
+      case 'mp4':
+        $autostart = $autoplay ? 'true' : 'false';
+        return '<embed src="'. $url .'" width="'. $width .'" height="'. $height .'" autoplay="'. $autostart .'" controller="true" type="video/quicktime" scale="tofit" pluginspage="http://www.apple.com/quicktime/download/"> </embed>';
+      case 'rm':
+        $autostart = $autoplay ? 'true' : 'false';
+        return '<embed type="audio/x-pn-realaudio-plugin" src="'. $url .'" width="'. $width .'" height="'. $height .'" autostart="'. $autostart .'" controls="imagewindow" nojava="true" console="c1183760810807" pluginspage="http://www.real.com/"></embed><br /><embed type="audio/x-pn-realaudio-plugin" src="'. $url .'" width="'. $width .'" height="26" autostart="'. $autostart .'" nojava="true" controls="ControlPanel" console="c1183760810807"> </embed>';
+      case 'swf':
+        return '<embed src="'. $url .'" width="'. $width .'" height="'. $height .'" quality="high" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
+      case 'flv':
+        $autostart = $autoplay ? 'true' : 'false';
+        return '<embed src="http://freevideocoding.com/flvplayer.swf?file='. $url .'&amp;autoStart='. $autostart .'" width="'. $width .'" height="'. $height .'" quality="high" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>';
+    }
+  }
+}
+
+function emvideo_zzz_custom_url_thumbnail($field, $item, $formatter, $node, $width, $height) {
+  return '';
+}
+
+function emvideo_zzz_custom_url_video($code, $width, $height, $field, $item, $autoplay) {
+  $type = $item['data']['type'];
+  $output = theme('emvideo_zzz_custom_url_embedded_video', $type, $code, $width, $height, $autoplay, $field, $item);
+  return $output;
+}
+
+function emvideo_zzz_custom_url_preview($code, $width, $height, $field, $item, $autoplay) {
+  $type = $item['data']['type'];
+  $output = theme('emvideo_zzz_custom_url_embedded_video', $type, $code, $width, $height, $autoplay, $field, $item);
+  return $output;
+}
+
+/**
+ * Implementation of hook_emfield_subtheme.
+ */
+function emvideo_zzz_custom_url_emfield_subtheme() {
+  return array(
+    'emvideo_zzz_custom_url_embedded_video' => array(
+      'arguments' => array('type' => NULL, 'url' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => FALSE, 'field' => NULL, 'item' => NULL),
+      'file' => 'providers/emvideo/zzz_custom_url.inc'
+    )
+  );
+}
diff -urpN contrib/emimage/CVS/Entries contrib/emimage/CVS/Entries
--- contrib/emimage/CVS/Entries	2008-12-15 19:01:25.505000000 -0600
+++ contrib/emimage/CVS/Entries	2008-12-03 19:56:18.197055200 -0600
@@ -1,7 +1,7 @@
 /README.txt/1.1.2.1/Fri Jul 18 20:22:44 2008//TDRUPAL-6--1
 /changelog.txt/1.1.2.4/Wed Nov 12 18:46:17 2008//TDRUPAL-6--1
 /emimage.info/1.1.2.3/Sun Sep 14 20:07:59 2008//TDRUPAL-6--1
-/emimage.install/1.1.2.4/Tue Dec  9 23:31:28 2008//TDRUPAL-6--1
+/emimage.install/1.1.2.3/Fri Jul 25 11:45:51 2008//TDRUPAL-6--1
 /emimage.module/1.1.2.6/Wed Oct  8 17:39:08 2008//TDRUPAL-6--1
 /emimage.theme.inc/1.1.2.1/Sun Sep 14 20:07:59 2008//TDRUPAL-6--1
 D
diff -urpN contrib/emimage/emimage.install contrib/emimage/emimage.install
--- contrib/emimage/emimage.install	2008-12-09 17:31:28.000000000 -0600
+++ contrib/emimage/emimage.install	2008-07-25 05:45:51.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: emimage.install,v 1.1.2.4 2008/12/09 23:31:28 alexua Exp $
+// $Id: emimage.install,v 1.1.2.3 2008/07/25 11:45:51 alexua Exp $
 
 /**
  * @file
@@ -10,7 +10,6 @@
  * Implementation of hook_install().
  */
 function emimage_install() {
-  drupal_load('module', 'content');
   content_notify('install', 'emimage');
 }
 
@@ -18,7 +17,6 @@ function emimage_install() {
  * Implementation of hook_uninstall().
  */
 function emimage_uninstall() {
-  drupal_load('module', 'content');
   content_notify('uninstall', 'emimage');
 }
 
@@ -26,7 +24,6 @@ function emimage_uninstall() {
  * Implementation of hook_enable().
  */
 function emimage_enable() {
-  drupal_load('module', 'content');
   content_notify('enable', 'emimage');
 }
 
@@ -34,7 +31,6 @@ function emimage_enable() {
  * Implementation of hook_disable().
  */
 function emimage_disable() {
-  drupal_load('module', 'content');
   content_notify('disable', 'emimage');
 }
 
diff -urpN contrib/emvideo/CVS/Entries contrib/emvideo/CVS/Entries
--- contrib/emvideo/CVS/Entries	2008-12-15 19:01:26.612000000 -0600
+++ contrib/emvideo/CVS/Entries	2008-12-03 19:56:19.774055200 -0600
@@ -1,7 +1,7 @@
 /README.txt/1.1.2.1/Fri Jul 18 20:22:44 2008//TDRUPAL-6--1
-/changelog.txt/1.1.2.8/Tue Dec  9 23:31:28 2008//TDRUPAL-6--1
+/changelog.txt/1.1.2.7/Wed Nov 12 17:54:43 2008//TDRUPAL-6--1
 /emvideo.info/1.1.2.2/Fri Jul 25 11:45:51 2008//TDRUPAL-6--1
 /emvideo.install/1.1.2.7/Wed Oct  8 17:39:09 2008//TDRUPAL-6--1
-/emvideo.module/1.1.2.9/Tue Dec  9 23:31:28 2008//TDRUPAL-6--1
-/emvideo.theme.inc/1.1.2.10/Tue Dec  9 23:31:28 2008//TDRUPAL-6--1
+/emvideo.module/1.1.2.8/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/emvideo.theme.inc/1.1.2.9/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
 D
diff -urpN contrib/emvideo/changelog.txt contrib/emvideo/changelog.txt
--- contrib/emvideo/changelog.txt	2008-12-09 17:31:28.000000000 -0600
+++ contrib/emvideo/changelog.txt	2008-11-12 11:54:43.000000000 -0600
@@ -1,15 +1,4 @@
-/* $Id: changelog.txt,v 1.1.2.8 2008/12/09 23:31:28 alexua Exp $ */
-
-December 2008
--------------
- * 195783 - solomongifford noted that Vimeo needed transparent mode
- * 327052 - dalin made improvements to theme_emvideo_zzz_custom_url_embedded_video()
- * 334944 - fixed small problem with Veoh provider
- * 334535 - Gyt added multivideo support for thickbox
- * 307187 - grendzy added fullscreen support for YouTube
- * 339025 - moonray changed emvideo_PROVIDER_video() hook to allow for more info being passed
- * 332673 - Jody Lynn fixed a fatal error in the google.inc file
- * 330176 - beeradb and arron fixed problem with trailing slashes in blip.tv urls
+/* $Id: changelog.txt,v 1.1.2.7 2008/11/12 17:54:43 aaron Exp $ */
 
 November 2008
 -------------
diff -urpN contrib/emvideo/emvideo.module contrib/emvideo/emvideo.module
--- contrib/emvideo/emvideo.module	2008-12-09 17:31:28.000000000 -0600
+++ contrib/emvideo/emvideo.module	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: emvideo.module,v 1.1.2.9 2008/12/09 23:31:28 alexua Exp $
+// $Id: emvideo.module,v 1.1.2.8 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -418,10 +418,6 @@ function emvideo_thickbox($nid, $width, 
   $field['field_name'] = $field_name;
   $node = node_load($nid);
   $items = $node->$field_name;
-  foreach ((array)$items as $thisitem){
-    if ($thisitem['value']==$item_value) { 
-	 $item = $thisitem;
-	 }
-    }
+  $item = $items[0];
   print theme('emvideo_video_video', $field, $item, 'video_video', $node);
 }
diff -urpN contrib/emvideo/emvideo.theme.inc contrib/emvideo/emvideo.theme.inc
--- contrib/emvideo/emvideo.theme.inc	2008-12-09 17:31:28.000000000 -0600
+++ contrib/emvideo/emvideo.theme.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: emvideo.theme.inc,v 1.1.2.10 2008/12/09 23:31:28 alexua Exp $
+// $Id: emvideo.theme.inc,v 1.1.2.9 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -118,7 +118,7 @@ function theme_emvideo_video_video($fiel
     $width = $options['width'] ? $options['width'] : ($field['widget']['video_width'] ? $field['widget']['video_width'] : variable_get('emvideo_default_video_width', EMVIDEO_DEFAULT_VIDEO_WIDTH));
     $height = $options['height'] ? $options['height'] : ($field['widget']['video_height'] ? $field['widget']['video_height'] : variable_get('emvideo_default_video_height', EMVIDEO_DEFAULT_VIDEO_HEIGHT));
     $autoplay = $options['autoplay'] ? $options['autoplay'] : $field['widget']['video_autoplay'];
-    $output = module_invoke('emfield', 'include_invoke', 'emvideo', $item['provider'], 'video', $embed, $width, $height, $field, $item, $node, $autoplay, $options);
+    $output = module_invoke('emfield', 'include_invoke', 'emvideo', $item['provider'], 'video', $embed, $width, $height, $field, $item, $autoplay, $options);
   }
 
   return $output;
@@ -134,7 +134,7 @@ function theme_emvideo_video_preview($fi
     $width = $options['width'] ? $options['width'] : ($field['widget']['preview_width'] ? $field['widget']['preview_width'] : variable_get('emvideo_default_preview_width', EMVIDEO_DEFAULT_PREVIEW_WIDTH));
     $height = $options['height'] ? $options['height'] : ($field['widget']['preview_height'] ? $field['widget']['preview_height'] : variable_get('emvideo_default_preview_height', EMVIDEO_DEFAULT_PREVIEW_HEIGHT));
     $autoplay = $options['autoplay'] ? $options['autoplay'] : $field['widget']['preview_autoplay'];
-    $output = module_invoke('emfield', 'include_invoke', 'emvideo', $item['provider'], 'preview', $embed, $width, $height, $field, $item, $node, $autoplay, $options);
+    $output = module_invoke('emfield', 'include_invoke', 'emvideo', $item['provider'], 'preview', $embed, $width, $height, $field, $item, $autoplay, $options);
   }
 
   return $output;
@@ -142,7 +142,8 @@ function theme_emvideo_video_preview($fi
 
 function theme_emvideo_thickbox($field, $item, $formatter, $node, $options = array()) {
   $thumbnail = theme('emvideo_video_thumbnail', $field, $item, 'video_thumbnail', $node, TRUE, $options);
-  $destination = 'emvideo/thickbox/'. $node->nid .'/'. $field['widget']['video_width'] .'/'. $field['widget']['video_height'] .'/'. $field['field_name'] .'/'. $item['value'];
+
+  $destination = 'emvideo/thickbox/'. $node->nid .'/'. $field['widget']['video_width'] .'/'. $field['widget']['video_height'] .'/'. $field['field_name'];
   $options = array(
     'attributes' => array(
       'title' => $title,
@@ -191,4 +192,4 @@ function theme_emvideo_formatter_video_f
 function theme_emvideo_formatter_thickbox($element) {
   $field = content_fields($element['#field_name'], $element['#type_name']);
   return module_invoke('emvideo', 'field_formatter', $field, $element['#item'], $element['#formatter'], $element['#node']);
-}
+}
\ No newline at end of file
diff -urpN contrib/emvideo/providers/CVS/Entries contrib/emvideo/providers/CVS/Entries
--- contrib/emvideo/providers/CVS/Entries	2008-12-15 19:01:27.697000000 -0600
+++ contrib/emvideo/providers/CVS/Entries	2008-12-03 19:56:21.275055200 -0600
@@ -1,20 +1,20 @@
-/bliptv.inc/1.1.2.9/Tue Dec  9 22:29:47 2008//TDRUPAL-6--1
-/brightcove.inc/1.1.2.8/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/dailymotion.inc/1.1.2.8/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/google.inc/1.1.2.10/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/guba.inc/1.1.2.5/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/imeem.inc/1.1.2.5/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
+/bliptv.inc/1.1.2.8/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/brightcove.inc/1.1.2.7/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/dailymotion.inc/1.1.2.7/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/google.inc/1.1.2.8/Wed Nov 12 17:54:43 2008//TDRUPAL-6--1
+/guba.inc/1.1.2.4/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/imeem.inc/1.1.2.4/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
 /jumpcut.inc/1.1.2.7/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
-/lastfm.inc/1.1.2.5/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/livevideo.inc/1.1.2.8/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/metacafe.inc/1.1.2.7/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
+/lastfm.inc/1.1.2.4/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/livevideo.inc/1.1.2.7/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/metacafe.inc/1.1.2.6/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
 /myspace.inc/1.1.2.7/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
-/revver.inc/1.1.2.7/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
+/revver.inc/1.1.2.6/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
 /sevenload.inc/1.1.2.6/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
-/spike.inc/1.1.2.7/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/tudou.inc/1.1.2.4/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/veoh.inc/1.1.2.5/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/vimeo.inc/1.1.2.4/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/youtube.inc/1.1.2.13/Tue Dec  9 23:31:29 2008//TDRUPAL-6--1
-/zzz_custom_url.inc/1.1.2.11/Wed Dec 10 01:40:23 2008//TDRUPAL-6--1
+/spike.inc/1.1.2.6/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/tudou.inc/1.1.2.3/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/veoh.inc/1.1.2.4/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/vimeo.inc/1.1.2.3/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/youtube.inc/1.1.2.12/Sat Oct 11 18:29:21 2008//TDRUPAL-6--1
+/zzz_custom_url.inc/1.1.2.9/Tue Oct 21 17:14:56 2008//TDRUPAL-6--1
 D
diff -urpN contrib/emvideo/providers/bliptv.inc contrib/emvideo/providers/bliptv.inc
--- contrib/emvideo/providers/bliptv.inc	2008-12-09 16:29:47.000000000 -0600
+++ contrib/emvideo/providers/bliptv.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: bliptv.inc,v 1.1.2.9 2008/12/09 22:29:47 alexua Exp $
+// $Id: bliptv.inc,v 1.1.2.8 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -158,10 +158,13 @@ function emvideo_bliptv_request($code, $
 
 function emvideo_bliptv_extract($embed) {
   return array(
-    '@blip\.tv/rss/flash/([^"\&\?/]+)@i',
-    '@blip\.tv/file/view/([^"\&\?/]+)@i',
-    '@blip\.tv/file/([^"\&\?/]+)@i',
-    '@blip\.tv/play/([^"\&\?/]+)@i',
+    '@blip\.tv/rss/flash/([^"\&\?]+)@i',
+    '@blip\.tv/file/view/([^"\&\?]+)@i',
+    '@blip\.tv/file/([^"\&\?]+)@i',
+    '@blip\.tv/play/([^"\&\?]+)@i',
+
+    // test handling for featured shows. disabled for now.
+//     '@http\://([^\.]+)\.blip\.tv/@i',
   );
 }
 
diff -urpN contrib/emvideo/providers/brightcove.inc contrib/emvideo/providers/brightcove.inc
--- contrib/emvideo/providers/brightcove.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/brightcove.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: brightcove.inc,v 1.1.2.8 2008/12/09 23:31:29 alexua Exp $
+// $Id: brightcove.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -122,7 +122,7 @@ function emvideo_brightcove_thumbnail($f
  *  @return
  *    the html of the embedded video
  */
-function emvideo_brightcove_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_brightcove_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_brightcove_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/dailymotion.inc contrib/emvideo/providers/dailymotion.inc
--- contrib/emvideo/providers/dailymotion.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/dailymotion.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: dailymotion.inc,v 1.1.2.8 2008/12/09 23:31:29 alexua Exp $
+// $Id: dailymotion.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -143,7 +143,7 @@ function emvideo_dailymotion_thumbnail($
  *  @return
  *    the html of the embedded video
  */
-function emvideo_dailymotion_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_dailymotion_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_dailymotion_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/google.inc contrib/emvideo/providers/google.inc
--- contrib/emvideo/providers/google.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/google.inc	2008-11-12 11:54:43.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: google.inc,v 1.1.2.10 2008/12/09 23:31:29 alexua Exp $
+// $Id: google.inc,v 1.1.2.8 2008/11/12 17:54:43 aaron Exp $
 
 /**
  * @file
@@ -127,7 +127,7 @@ function emvideo_google_data($field, $it
     }
   }
 
-  if ($data['thumbnail']['filepath'] == '' && is_array($rss['ITEM'])) {
+  if ($data['thumbnail']['filepath'] == '') {
     // for whatever reason the thumbnail failed try the old method
     // we'll parse it from the description, where it's repeated.
     $desc = $rss['ITEM']['DESCRIPTION'][0];
@@ -175,7 +175,7 @@ function emvideo_google_thumbnail($field
   return NULL;
 }
 
-function emvideo_google_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_google_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_google_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/guba.inc contrib/emvideo/providers/guba.inc
--- contrib/emvideo/providers/guba.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/guba.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: guba.inc,v 1.1.2.5 2008/12/09 23:31:29 alexua Exp $
+// $Id: guba.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -78,7 +78,7 @@ function emvideo_guba_thumbnail($field, 
   return $thm;
 }
 
-function emvideo_guba_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_guba_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_guba_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/imeem.inc contrib/emvideo/providers/imeem.inc
--- contrib/emvideo/providers/imeem.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/imeem.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: imeem.inc,v 1.1.2.5 2008/12/09 23:31:29 alexua Exp $
+// $Id: imeem.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
 
 define('EMVIDEO_IMEEM_MAIN_URL', 'http://www.imeem.com/');
 define('EMVIDEO_IMEEM_API_INFO', 'http://www.imeem.com/developers/documentation/');
@@ -83,7 +83,7 @@ function emvideo_imeem_thumbnail($field,
   return $thm;
 }
 
-function emvideo_imeem_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_imeem_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_imeem_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/lastfm.inc contrib/emvideo/providers/lastfm.inc
--- contrib/emvideo/providers/lastfm.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/lastfm.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: lastfm.inc,v 1.1.2.5 2008/12/09 23:31:29 alexua Exp $
+// $Id: lastfm.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -142,7 +142,7 @@ function emvideo_lastfm_thumbnail($field
  *  @return
  *    the html of the embedded video
  */
-function emvideo_lastfm_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_lastfm_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_lastfm_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/livevideo.inc contrib/emvideo/providers/livevideo.inc
--- contrib/emvideo/providers/livevideo.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/livevideo.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: livevideo.inc,v 1.1.2.8 2008/12/09 23:31:29 alexua Exp $
+// $Id: livevideo.inc,v 1.1.2.7 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -156,7 +156,7 @@ function emvideo_livevideo_thumbnail($fi
  *  @return
  *    the html of the embedded video
  */
-function emvideo_livevideo_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_livevideo_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_livevideo_flash', $embed, $width, $height, $autoplay);
 
   return $output;
diff -urpN contrib/emvideo/providers/metacafe.inc contrib/emvideo/providers/metacafe.inc
--- contrib/emvideo/providers/metacafe.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/metacafe.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: metacafe.inc,v 1.1.2.7 2008/12/09 23:31:29 alexua Exp $
+// $Id: metacafe.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -64,7 +64,7 @@ function emvideo_metacafe_thumbnail($fie
   return 'http://www.metacafe.com/thumb/'. $picturelink .'.jpg';
 }
 
-function emvideo_metacafe_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_metacafe_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_metacafe_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/revver.inc contrib/emvideo/providers/revver.inc
--- contrib/emvideo/providers/revver.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/revver.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: revver.inc,v 1.1.2.7 2008/12/09 23:31:29 alexua Exp $
+// $Id: revver.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -67,7 +67,7 @@ function emvideo_revver_thumbnail($field
   return 'http://frame.revver.com/frame/'. $width .'x'. $height .'/'. check_plain($item['value']) .'.jpg';
 }
 
-function emvideo_revver_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_revver_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_revver_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/spike.inc contrib/emvideo/providers/spike.inc
--- contrib/emvideo/providers/spike.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/spike.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: spike.inc,v 1.1.2.7 2008/12/09 23:31:29 alexua Exp $
+// $Id: spike.inc,v 1.1.2.6 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -65,7 +65,7 @@ function emvideo_spike_thumbnail($field,
   return 'http://img1.ifilmpro.com/resize/image/stills/films/resize/istd/'. $picturelink .'.jpg?width='. $width;
 }
 
-function emvideo_spike_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_spike_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_spike_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/tudou.inc contrib/emvideo/providers/tudou.inc
--- contrib/emvideo/providers/tudou.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/tudou.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: tudou.inc,v 1.1.2.4 2008/12/09 23:31:29 alexua Exp $
+// $Id: tudou.inc,v 1.1.2.3 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -123,7 +123,7 @@ function emvideo_tudou_thumbnail($field,
  *  @return
  *    the html of the embedded video
  */
-function emvideo_tudou_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_tudou_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_tudou_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/veoh.inc contrib/emvideo/providers/veoh.inc
--- contrib/emvideo/providers/veoh.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/veoh.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: veoh.inc,v 1.1.2.5 2008/12/09 23:31:29 alexua Exp $
+// $Id: veoh.inc,v 1.1.2.4 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -99,6 +99,9 @@ function emvideo_veoh_thumbnail($field, 
     $url = 'http://www.veoh.com/rest/video/'. $thumbid .'/details';
     $content = file_get_contents($url);
     if ($content) {
+      print '(start)<br>';
+      print $content;
+      print '(end)<br>';
       $start = strpos($content, 'fullMedResImagePath="')+21;
       $end = strpos($content, '"', $start);
       $thumbnail = substr($content, $start, $end-$start);
@@ -107,7 +110,7 @@ function emvideo_veoh_thumbnail($field, 
   }
 }
 
-function emvideo_veoh_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_veoh_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_veoh_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/vimeo.inc contrib/emvideo/providers/vimeo.inc
--- contrib/emvideo/providers/vimeo.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/vimeo.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: vimeo.inc,v 1.1.2.4 2008/12/09 23:31:29 alexua Exp $
+// $Id: vimeo.inc,v 1.1.2.3 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -155,7 +155,6 @@ function theme_emvideo_vimeo_flash($embe
     }
     $output = '<object type="application/x-shockwave-flash" width="'. $width .'" height="'. $height .'" data="http://www.vimeo.com/moogaloop.swf?clip_id='. $embed .'&amp;server=www.vimeo.com&amp;fullscreen='. $fullscreen .'&amp;show_title='. $show_title .'&amp;show_byline='. $show_byline .'&amp;show_portrait='. $show_portrait .'&amp;color='. $color .'">';
     $output .= '<param name="quality" value="best" />';
-	$output .= '<param name="wmode" value="transparent" />';
     $output .= '<param name="allowfullscreen" value="'. ($fullscreen ? 'true' : 'false') .'" />';
     $output .= '<param name="scale" value="showAll" />';
     $output .= '<param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id='. $embed .'&amp;server=www.vimeo.com&amp;fullscreen='. $fullscreen .'&amp;show_title='. $show_title .'&amp;show_byline='. $show_byline .'&amp;show_portrait='. $show_portrait .'&amp;color='. $color .'" /></object>';
@@ -179,7 +178,7 @@ function theme_emvideo_vimeo_flash($embe
  *  @return
  *    the html of the embedded video
  */
-function emvideo_vimeo_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_vimeo_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_vimeo_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/youtube.inc contrib/emvideo/providers/youtube.inc
--- contrib/emvideo/providers/youtube.inc	2008-12-09 17:31:29.000000000 -0600
+++ contrib/emvideo/providers/youtube.inc	2008-10-11 12:29:21.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: youtube.inc,v 1.1.2.13 2008/12/09 23:31:29 alexua Exp $
+// $Id: youtube.inc,v 1.1.2.12 2008/10/11 18:29:21 alexua Exp $
 
 /**
  * @file
@@ -31,7 +31,6 @@ function emvideo_youtube_info() {
     array(t('Show related videos'), t('Yes'), t('This is embedded in the video itself when enabled; currently not available with other providers. Set the feature above.')),
     array(t('Thumbnails'), t('Yes'), t('')),
     array(t('Custom player colors'), t('Yes'), t("You may customize the player's skin by choosing your own colors, and/or border in that setting field set.")),
-    array(t('Full screen mode'), t('Yes'), t('You may customize the player to enable or disable full screen playback. Full screen mode is enabled by default.')),
   );
   return array(
     'provider' => 'youtube',
@@ -101,19 +100,6 @@ function emvideo_youtube_settings() {
     '#title' => t('Color 2'),
     '#default_value' => variable_get('emvideo_youtube_colors_color2', EMVIDEO_YOUTUBE_COLOR2_DEFAULT),
   );
-  $form['youtube']['player_options'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Embedded video player options'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['youtube']['player_options']['emvideo_youtube_full_screen'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Allow fullscreen'),
-    '#default_value' => variable_get('emvideo_youtube_full_screen', 1),
-    '#description' => t('Allow users to view video using the entire computer screen.'),
-  );
-
   if (module_exists('colorpicker')) {
     $form['youtube']['colors']['emvideo_youtube_colors_color1']['#type'] = 'colorpicker_textfield';
     $form['youtube']['colors']['emvideo_youtube_colors_color1']['#colorpicker'] = 'colorpicker_1';
@@ -253,9 +239,6 @@ function emvideo_youtube_convert_color($
 function theme_emvideo_youtube_flash($embed, $width, $height, $autoplay, $options = array()) {
   static $count;
   if ($embed) {
-    $fullscreen = variable_get('emvideo_youtube_full_screen', 1);
-    $fullscreen_value = $fullscreen ? "true" : "false";
-    $fs = $fullscreen ? "&amp;fs=$fullscreen" : "";
     $related = isset($options['related']) ? $options['related'] : variable_get('emvideo_youtube_show_related_videos', 0);
     $related = "rel=$related";
     $autoplay = isset($options['autoplay']) ? $options['autoplay'] : $autoplay;
@@ -272,13 +255,12 @@ function theme_emvideo_youtube_flash($em
     $enablejsapi = $enablejsapi ? '&enablejsapi=1&playerapiid=ytplayer' : '';
     $id = isset($options['id']) ? $options['id'] : 'video-cck-youtube-flash-'. (++$count);
     $div_id = isset($options['div_id']) ? $options['div_id'] : 'video-cck-youtube-flash-wrapper-'. $count;
-    $url = "http://www.youtube.com/v/$embed&amp;$related$autoplay_value$colors$border$enablejsap$fs";
+    $url = "http://www.youtube.com/v/$embed&amp;$related$autoplay_value$colors$border$enablejsap";
     if (variable_get('emfield_swfobject', FALSE) && (module_exists('swfobject_api') || variable_get('emfield_swfobject_location', ''))) {
       if (module_exists('swfobject_api')) {
         $params['width'] = $width;
         $params['height'] = $height;
         $params['div_id'] = $id;
-        $params['allowFullScreen'] = $fullscreen_value;
         $output .= theme('swfobject_api', $url, $params, $vars, $id);
       }
       else {
@@ -296,11 +278,10 @@ FLASH;
     }
     else {
       $output .= <<<FLASH
-        <div id="$div_id"><object type="application/x-shockwave-flash" height="$height" width="$width" data="$url" id="$id" allowFullScreen="$fullscreen_value">
+        <div id="$div_id"><object type="application/x-shockwave-flash" height="$height" width="$width" data="$url" id="$id">
           <param name="movie" value="$url" />
           <param name="allowScriptAcess" value="sameDomain"/>
           <param name="quality" value="best"/>
-          <param name="allowFullScreen" value="$fullscreen_value"/>
           <param name="bgcolor" value="#FFFFFF"/>
           <param name="scale" value="noScale"/>
           <param name="salign" value="TL"/>
@@ -359,7 +340,7 @@ function emvideo_youtube_thumbnail($fiel
  *  @return
  *    the html of the embedded video
  */
-function emvideo_youtube_video($embed, $width, $height, $field, $item, &$node, $autoplay) {
+function emvideo_youtube_video($embed, $width, $height, $field, $item, $autoplay) {
   $output = theme('emvideo_youtube_flash', $embed, $width, $height, $autoplay);
   return $output;
 }
diff -urpN contrib/emvideo/providers/zzz_custom_url.inc contrib/emvideo/providers/zzz_custom_url.inc
--- contrib/emvideo/providers/zzz_custom_url.inc	2008-12-09 19:40:23.000000000 -0600
+++ contrib/emvideo/providers/zzz_custom_url.inc	2008-10-21 11:14:56.000000000 -0600
@@ -1,5 +1,5 @@
 <?php
-// $Id: zzz_custom_url.inc,v 1.1.2.11 2008/12/10 01:40:23 alexua Exp $
+// $Id: zzz_custom_url.inc,v 1.1.2.9 2008/10/21 17:14:56 alexua Exp $
 
 /**
  * @file
diff -urpN emfield.admin.inc emfield.admin.inc
--- emfield.admin.inc	2008-12-15 13:21:17.000000000 -0600
+++ emfield.admin.inc	2008-11-27 10:13:28.000000000 -0600
@@ -1,194 +1,230 @@
-<?php
-// $Id: emfield.admin.inc,v 1.1.2.8 2008/12/15 19:21:17 aaron Exp $
-
-/**
- * @file
- * The administrative settings page.
- */
-
-/**
- * Callback for admin/content/emfield.
- */
-function emfield_settings() {
-  if (!module_exists('emvideo') && !module_exists('emimage') && !module_exists('emaudio')) {
-    drupal_set_message(t('The Embedded Media Field module does nothing on its own. You should also install the Embedded Video Field, Embedded Image Field, and/or Embedded Audio Field modules from the <a href="@modules">modules administration page</a>. (If you do not see them listed there, under the CCK section, you may need to <a href="@download">download the module</a> from its project page. They are all in the same package.)', array('@download' => 'http://drupal.org/project/emfield', '@modules' => url('admin/build/modules'))), 'error');
-  }
-  $form = array();
-  $form['general'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('General Settings'),
-    '#description' => t('These features will be generally available for use by related modules as needed.'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-
-  if (module_exists('swfobject_api')) {
-    $swfobject_desc = t('As you have the <a href="@swfobject_api" target="_blank">SWFObject API</a> module installed, Embedded Media Field will use those settings, assuming you have configured them properly. Visit its <a href="@settings">settings page</a> for more information.', array('@swfobject_api' => 'http://drupal.org/project/swfobject_api', '@settings' => url('admin/settings/swfobject_api')));
-  }
-  else {
-    $swfobject_desc = t('If you have the swfobject.js file installed on your system, you can make it available to Embedded Media Field and its related modules by entering the information here. You can download and find out more about <a href="@here" target="_blank">SWFObject here</a>. You may also choose to install the <a href="@swfobject_api" target="_blank">SWFObject API</a> module, which will integrate automatically with this module..', array('@here' => 'http://code.google.com/p/swfobject/', '@swfobject_api' => 'http://drupal.org/project/swfobject_api'));
-  }
-  $form['general']['swfobject'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('SWF Object'),
-    '#description' => $swfobject_desc,
-    '#collapsible' => TRUE,
-  );
-  $form['general']['swfobject']['emfield_swfobject'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use SWFObject'),
-    '#default_value' => variable_get('emfield_swfobject', FALSE),
-    '#description' => t('When checked, then Embedded Media Field will use the SWFObject javascript library when it is able.'),
-  );
-
-  if (!module_exists('swfobject_api')) {
-    $form['general']['swfobject']['emfield_swfobject_location'] = array(
-      '#type' => 'textfield',
-      '#title' => t('SWFObject location'),
-      '#default_value' => variable_get('emfield_swfobject_location', ''),
-      '#description' => t('Enter the path to the swfobject.js file, relative to the web root, without the preceding slash (/).'),
-    );
-  }
-  $header = array(t('Feature'), t('Supported'), t('Notes'));
-
-  foreach (module_implements('emfield_info', TRUE) as $module) {
-    $emfield_info = module_invoke($module, 'emfield_info');
-    $providers = emfield_system_list($module);
-    $form[$module] = array(
-      '#type' => 'fieldset',
-      '#title' => t('@neighborhood', array('@neighborhood' => $emfield_info['#name'])),
-      '#description' => $emfield_info['#settings_description'],
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form[$module]['providers'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Providers'),
-      '#description' => t('The following settings determine what providers are allowed, and what provider-specific options, if any, are set.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => FALSE,
-    );
-    foreach ($providers as $provider) {
-      $info = emfield_include_invoke($module, $provider->name, 'info');
-      $form[$module]['providers'][$provider->name] = array(
-        '#type' => 'fieldset',
-        '#title' => t('@provider configuration', array('@provider' => $info['name'])),
-        '#description' => $info['settings_description'],
-        '#collapsible' => TRUE,
-        '#collapsed' => TRUE,
-      );
-      if (is_array($info['supported_features']) && !empty($info['supported_features'])) {
-        $form[$module]['providers'][$provider->name]['supported_features'] = array(
-          '#type' => 'fieldset',
-          '#title' => t('Supported features'),
-          '#description' => t('This is a list of the current state of support for the following features by %provider:', array('%provider' => $info['name'])),
-          '#collapsible' => TRUE,
-          '#collapsed' => TRUE,
-          '#weight' => 7,
-        );
-        $form[$module]['providers'][$provider->name]['supported_features']['features'] = array(
-          '#type' => 'markup',
-          '#value' => theme('table', $header, $info['supported_features']),
-        );
-      }
-      $form[$module]['providers'][$provider->name]['emfield_'. $module .'_allow_'. $provider->name] = array( '#type' => 'checkbox',
-        '#title' => t('Allow content from %provider', array('%provider' => $info['name'])),
-        '#description' => t('If checked, then content types may be created that allow content to be provided by %provider.', array('%provider' => $info['name'])),
-        '#weight' => -10,
-        '#default_value' => variable_get('emfield_'. $module .'_allow_'. $provider->name, TRUE),
-      );
-      $form[$module]['providers'][$provider->name][] = emfield_include_invoke($module, $provider->name, 'settings');
-    }
-    $form[$module] = array_merge($form[$module], module_invoke($module, 'emfield_settings'));
-  }
-
-  $form = system_settings_form($form);
-
-  // Custom valiation callback so we can validate the SWFObject path.
-  $form['#validate'][] = 'emfield_settings_validate';
-
-  return $form;
-}
-
-/**
- *  Validation for emfield_settings form, callback for /admin/content/emfield.
- *  Ensure we have a valid SWFObject path.
- */
-function emfield_settings_validate($form, $form_state) {
-  if ($form_state['values']['emfield_swfobject'] && $form_state['values']['emfield_swfobject_location']) {
-    if (!file_exists($form_state['values']['emfield_swfobject_location'])) {
-      form_set_error('emfield_swfobject_location', t('The SWFObject %file file was not found at that location. Please specify a valid location.', array('%file' => $form_state['values']['emfield_swfobject_location'])));
-    }
-  }
-}
-
-/**
- * Menu callback settings form.
- * If job_queue module is installed, admins can reload embedded media data in bulk
- */
-function emfield_settings_jobqueue() {
-	$form = array();
-  $form['job_queue'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Reload Embedded Media Data'),
-    '#description' => t('You can reload the embedded media data on all nodes on your site if necessary.  This action will be queued to run on cron via the job queue module.'),
-	  '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-  );
-  $types = content_types();
-  $options = array();
-  foreach ($types as $type) {
-	  foreach ($type['fields'] as $field) {
-      if (module_hook($field['type'], 'emfield_info')) {
-	      $options[$type['type']] = $type['name'];
-	    }
-	  }
-  }
-  if (count($options)) {
-    $form['job_queue']['types'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Types to reload'),
-      '#options' => $options,
-      '#description' => t('Choose the content types to reload'),
-    );
-
-    $form['job_queue']['submit'] = array(
-	    '#type' => 'submit',
-	    '#value' => t('Submit'),
-	  );
-  }
-
-  return $form;
-}
-
-/**
- * For each selected content type, add all of its nodes to the job queue for reloading.
- */
-function emfield_settings_jobqueue_submit($form, &$form_state) {
-	foreach($form_state['values']['types'] as $type => $value) {
-		if ($value) {
-	    $result = db_query("SELECT nid FROM {node} WHERE type = '%s'", $type);
-	    while ($nid = db_result($result)) {
-		    job_queue_add('emfield_reload', 'refresh emfield info', array($nid), drupal_get_path('module', 'emfield') .'/emfield.admin.inc', TRUE);
-	    }
-			drupal_set_message(t('The %type nodes have been queued to reload emfield data upon cron.', array('%type' => $type)));
-		}
-	}
-}
-
-/**
- *  This reloads and saves the data for a single node.
- */
-function emfield_reload($nid) {
-  if ($node = node_load($nid)) {
-    $type = content_types($node->type);
-    foreach ($type['fields'] as $field) {
-      if (module_hook($field['type'], 'emfield_info')) {
-        $items = $node->{$field['field_name']};
-        emfield_emfield_field('submit', $node, $field, $items, FALSE, FALSE, $field['type']);
-        $node->{$field['field_name']} = $items;
-        node_save($node);
-      }
-    }
-  }
+<?php
+// $Id: emfield.admin.inc,v 1.1.2.6 2008/11/12 18:14:37 aaron Exp $
+
+/**
+ * @file
+ * The administrative settings page.
+ */
+
+/**
+ * Callback for admin/content/emfield.
+ */
+function emfield_settings() {
+  if (!module_exists('emvideo') && !module_exists('emimage') && !module_exists('emaudio') && !module_exists('emfield_generic')) {
+    drupal_set_message(t('The Embedded Media Field module does nothing on its own. You should also install the Embedded Video Field, Embedded Image Field, and/or Embedded Audio Field modules from the <a href="@modules">modules administration page</a>. (If you do not see them listed there, under the CCK section, you may need to <a href="@download">download the module</a> from its project page. They are all in the same package.)', array('@download' => 'http://drupal.org/project/emfield', '@modules' => url('admin/build/modules'))), 'error');
+  }
+  $form = array();
+  $form['general'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('General Settings'),
+    '#description' => t('These features will be generally available for use by related modules as needed.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+
+  if (module_exists('swfobject_api')) {
+    $swfobject_desc = t('As you have the <a href="@swfobject_api" target="_blank">SWFObject API</a> module installed, Embedded Media Field will use those settings, assuming you have configured them properly. Visit its <a href="@settings">settings page</a> for more information.', array('@swfobject_api' => 'http://drupal.org/project/swfobject_api', '@settings' => url('admin/settings/swfobject_api')));
+  }
+  else {
+    $swfobject_desc = t('If you have the swfobject.js file installed on your system, you can make it available to Embedded Media Field and its related modules by entering the information here. You can download and find out more about <a href="@here" target="_blank">SWFObject here</a>. You may also choose to install the <a href="@swfobject_api" target="_blank">SWFObject API</a> module, which will integrate automatically with this module..', array('@here' => 'http://code.google.com/p/swfobject/', '@swfobject_api' => 'http://drupal.org/project/swfobject_api'));
+  }
+  $form['general']['swfobject'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('SWF Object'),
+    '#description' => $swfobject_desc,
+    '#collapsible' => TRUE,
+  );
+  $form['general']['swfobject']['emfield_swfobject'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use SWFObject'),
+    '#default_value' => variable_get('emfield_swfobject', FALSE),
+    '#description' => t('When checked, then Embedded Media Field will use the SWFObject javascript library when it is able.'),
+  );
+
+  if (!module_exists('swfobject_api')) {
+    $form['general']['swfobject']['emfield_swfobject_location'] = array(
+      '#type' => 'textfield',
+      '#title' => t('SWFObject location'),
+      '#default_value' => variable_get('emfield_swfobject_location', ''),
+      '#description' => t('Enter the relative path to the swfobject.js file, without the preceding slash (/).'),
+    );
+  }
+  $header = array(t('Feature'), t('Supported'), t('Notes'));
+
+  foreach (module_implements('emfield_info', TRUE) as $module) {
+    $emfield_info = module_invoke($module, 'emfield_info');
+
+    $form[$module] = array(
+      '#type' => 'fieldset',
+      '#title' => t('@neighborhood', array('@neighborhood' => $emfield_info['#name'])),
+      '#description' => $emfield_info['#settings_description'],
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+    
+    if($module == "emfield_generic"){
+    	$types = array("emaudio","emimage","emvideo");
+    	foreach($types as $type){
+    		$providers = _emfield_generic_system_list($module,$type);
+    		
+		   $form[$module]['providers_' . $type] = array(
+		      '#type' => 'fieldset',
+		      '#title' => t('Providers ' . substr($type,2)),
+		      '#description' => t('The following settings determine what providers are allowed, and what provider-specific options, if any, are set.'),
+		      '#collapsible' => TRUE,
+		      '#collapsed' => TRUE,
+		    );    		
+    	
+	    foreach ($providers as $provider) {    
+		    
+	      $info = _emfield_generic_include_invoke($module,$type,$provider->name, 'info');	
+	      $form[$module]['providers_' . $type][$provider->name] = array(
+	        '#type' => 'fieldset',
+	        '#title' => t('@provider configuration', array('@provider' => $info['name'])),
+	        '#description' => $info['settings_description'],
+	        '#collapsible' => TRUE,
+	        '#collapsed' => TRUE,
+	      );
+	      if (is_array($info['supported_features']) && !empty($info['supported_features'])) {
+	        $form[$module]['providers_' . $type][$provider->name]['supported_features'] = array(
+	          '#type' => 'fieldset',
+	          '#title' => t('Supported features'),
+	          '#description' => t('This is a list of the current state of support for the following features by %provider:', array('%provider' => $info['name'])),
+	          '#collapsible' => TRUE,
+	          '#collapsed' => TRUE,
+	          '#weight' => 7,
+	        );
+	        $form[$module]['providers_' . $type][$provider->name]['supported_features']['features'] = array(
+	          '#type' => 'markup',
+	          '#value' => theme('table', $header, $info['supported_features']),
+	        );
+	      }
+	      $form[$module]['providers_' . $type][$provider->name]['emfield_'. $module .'_allow_'. $provider->name] = array( '#type' => 'checkbox',
+	        '#title' => t('Allow content from %provider', array('%provider' => $info['name'])),
+	        '#description' => t('If checked, then content types may be created that allow content to be provided by %provider.', array('%provider' => $info['name'])),
+	        '#weight' => -10,
+	        '#default_value' => variable_get('emfield_'. $module .'_allow_'. $provider->name, TRUE),
+	      );
+	      $form[$module]['providers_' . $type][$provider->name][] = _emfield_generic_include_invoke($module, $type,$provider->name, 'settings');
+	    }
+	    $form[$module] = array_merge($form[$module], module_invoke($module, 'emfield_settings'));    	
+      }
+    }
+    else {
+    	
+	    $form[$module]['providers'] = array(
+	      '#type' => 'fieldset',
+	      '#title' => t('Providers'),
+	      '#description' => t('The following settings determine what providers are allowed, and what provider-specific options, if any, are set.'),
+	      '#collapsible' => TRUE,
+	      '#collapsed' => FALSE,
+	    );    	
+	    $providers = emfield_system_list($module);
+	    foreach ($providers as $provider) {
+	      $info = emfield_include_invoke($module, $provider->name, 'info');
+	      $form[$module]['providers'][$provider->name] = array(
+	        '#type' => 'fieldset',
+	        '#title' => t('@provider configuration', array('@provider' => $info['name'])),
+	        '#description' => $info['settings_description'],
+	        '#collapsible' => TRUE,
+	        '#collapsed' => TRUE,
+	      );
+	      if (is_array($info['supported_features']) && !empty($info['supported_features'])) {
+	        $form[$module]['providers'][$provider->name]['supported_features'] = array(
+	          '#type' => 'fieldset',
+	          '#title' => t('Supported features'),
+	          '#description' => t('This is a list of the current state of support for the following features by %provider:', array('%provider' => $info['name'])),
+	          '#collapsible' => TRUE,
+	          '#collapsed' => TRUE,
+	          '#weight' => 7,
+	        );
+	        $form[$module]['providers'][$provider->name]['supported_features']['features'] = array(
+	          '#type' => 'markup',
+	          '#value' => theme('table', $header, $info['supported_features']),
+	        );
+	      }
+	      $form[$module]['providers'][$provider->name]['emfield_'. $module .'_allow_'. $provider->name] = array( '#type' => 'checkbox',
+	        '#title' => t('Allow content from %provider', array('%provider' => $info['name'])),
+	        '#description' => t('If checked, then content types may be created that allow content to be provided by %provider.', array('%provider' => $info['name'])),
+	        '#weight' => -10,
+	        '#default_value' => variable_get('emfield_'. $module .'_allow_'. $provider->name, TRUE),
+	      );
+	      $form[$module]['providers'][$provider->name][] = emfield_include_invoke($module, $provider->name, 'settings');
+	    }
+	    $form[$module] = array_merge($form[$module], module_invoke($module, 'emfield_settings'));
+   } 
+  }
+
+  return system_settings_form($form);
+}
+
+/**
+ * Menu callback settings form.
+ * If job_queue module is installed, admins can reload embedded media data in bulk
+ */
+function emfield_settings_jobqueue() {
+	$form = array();
+  $form['job_queue'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Reload Embedded Media Data'),
+    '#description' => t('You can reload the embedded media data on all nodes on your site if necessary.  This action will be queued to run on cron via the job queue module.'),
+	  '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+  );
+  $types = content_types();
+  $options = array();
+  foreach ($types as $type) {
+	  foreach ($type['fields'] as $field) {
+      if (module_hook($field['type'], 'emfield_info')) {
+	      $options[$type['type']] = $type['name'];
+	    }
+	  }
+  }
+  if (count($options)) {
+    $form['job_queue']['types'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Types to reload'),
+      '#options' => $options,
+      '#description' => t('Choose the content types to reload'),
+    );	
+
+    $form['job_queue']['submit'] = array(
+	    '#type' => 'submit',
+	    '#value' => t('Submit'),
+	  );
+  }
+  
+  return $form;
+}
+
+/**
+ * For each selected content type, add all of its nodes to the job queue for reloading.
+ */
+function emfield_settings_jobqueue_submit($form, &$form_state) {
+	foreach($form_state['values']['types'] as $type => $value) {
+		if ($value) {
+	    $result = db_query("SELECT nid FROM {node} WHERE type = '%s'", $type);
+	    while ($nid = db_result($result)) {
+		    job_queue_add('emfield_reload', 'refresh emfield info', array($nid), drupal_get_path('module', 'emfield') .'/emfield.admin.inc', TRUE);
+	    }	
+			drupal_set_message(t('The %type nodes have been queued to reload emfield data upon cron.', array('%type' => $type)));
+		}
+	}
+}
+
+/**
+ *  This reloads and saves the data for a single node.
+ */
+function emfield_reload($nid) {
+  if ($node = node_load($nid)) {
+    $type = content_types($node->type);
+    foreach ($type['fields'] as $field) {
+      if (module_hook($field['type'], 'emfield_info')) {
+        $items = $node->{$field['field_name']};
+        emfield_emfield_field('submit', $node, $field, $items, FALSE, FALSE, $field['type']);
+        $node->{$field['field_name']} = $items;
+        node_save($node);
+      }
+    }
+  }
 }
\ No newline at end of file
diff -urpN emfield.cck.inc emfield.cck.inc
--- emfield.cck.inc	2008-12-09 17:31:29.000000000 -0600
+++ emfield.cck.inc	2008-11-24 23:22:44.000000000 -0600
@@ -1,215 +1,245 @@
-<?php
-// $Id: emfield.cck.inc,v 1.1.2.10 2008/12/09 23:31:29 alexua Exp $
-
-/**
- * @file
- * Helper functions to implement our various cck-required functions, such as hook_field and hook_widget.
- */
-
-/**
- *  helper function to consistently define field columns
- */
-function _emfield_field_columns($field) {
-  $columns = array(
-    // poorly named. but this contains the original URL or embed code pre-parsing, as entered by the user/editor.
-    'embed' => array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
-    // this contains the code used by the provider to identify the media
-    'value' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
-    // this is the actual provider used; matches up with the specific provider.inc file
-    'provider' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
-    // an array for any extra data required by this media, such as unique thumbnail requirements or rss feed data
-    'data' => array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'not null' => FALSE, 'sortable' => FALSE),
-  );
-  // allow other modules to add new columns
-  // TODO: couldn't we just use module_invoke_all here? also make sure those modules do their magic on enable/disable
-  // finally, is this actually used? seems extraneous with the data array (unless we're using views magic for them)
-  foreach (module_implements('emfield_field_columns_extra') as $module) {
-    $extra = module_invoke($module, 'emfield_field_columns_extra', $field);
-    if (is_array($extra) && !empty($extra)) {
-      $columns = array_merge($columns, $extra);
-    }
-  }
-
-  return $columns;
-}
-
-/**
- * Implementation of hook_emfield_field().
- * 
- * This private function is returned directly by emfield_emfield_field().
- */
-function _emfield_emfield_field($op, &$node, $field, &$items, $teaser, $page, $module) {
-  switch ($op) {
-    // TODO: Nothing to validate at the moment. We need to have different provider api's have a chance to validate.
-    case 'validate':
-      foreach ($items as $delta => $item) {
-        $error_field = $field['multiple'] ? $field['field_name'] .']['. $delta .'][embed' : $field['field_name'];
-        _emfield_field_validate_id($field, $item, $error_field, $module, $delta);
-      }
-      break;
-
-    case 'presave':
-      foreach ($items as $delta => $item) {
-        $list = _emfield_field_submit_id($field, $item, $module);
-        $items[$delta]['provider'] = $list['provider'];
-        $items[$delta]['value'] = $list['value'];
-        $items[$delta]['data'] = $list['data'];
-      }
-      break;
-
-    case 'load':
-      // We need to unserialize the 'data' column manually.
-      $field_name = $field['field_name'];
-      foreach ($items as $delta => $item) {
-        $data = (array)unserialize($items[$delta]['data']);
-        $items[$delta]['data'] = $data;
-        $node->{$field_name}[$delta]['data'] = $data;
-      }
-
-      $return = array();
-      $return[$field_name] = $items;
-      break;
-      
-    case 'delete':
-      break;
-  }
-  // Allow modules (such as emthumb) to alter our data.
-  foreach (module_implements('emfield_field_extra') as $module) {
-    $args = array($op, &$node, $field, &$items, $teaser, $page, $module);
-    $ret = call_user_func_array($module .'_emfield_field_extra', $args);
-    if (is_array($return) && is_array($ret)) {
-      $return = array_merge($return, $ret);
-    }
-  }
-  if (in_array($op, array('insert', 'update'))) {
-    // we need to manually serialize the 'data' array
-    foreach ($items as $delta => $item) {
-      $items[$delta]['data'] = serialize($items[$delta]['data']);
-    }
-  }
-  if (isset($return)) { 
-  return $return;
-  }
-}
-
-function _emfield_emfield_widget_settings($op, $widget, $module) {
-  switch ($op) {
-    case 'form':
-      // Make sure to register the new type as supported by this module.
-      emfield_implement_types(FALSE);
-
-      $form = array();
-      $options = array();
-      $providers = emfield_system_list($module);
-      foreach ($providers as $provider) {
-        if (variable_get('emfield_allow_'. $module .'_'. $provider->name, TRUE)) {
-          $info = emfield_include_invoke($module, $provider->name, 'info');
-          $options[$provider->name] = $info['name'];
-        }
-      }
-      $form['provider_list'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Providers Supported'),
-        '#description' => t('Select which third party providers you wish to allow for this content type from the list below. If no checkboxes are checked, then all providers will be supported. When a user submits new content, the URL they enter will be matched to the provider, assuming that provider is allowed here.'),
-        '#collapsible' => TRUE,
-        '#collapsed' => FALSE,
-      );
-      $form['provider_list']['providers'] = array(
-        '#type' => 'checkboxes',
-        '#title' => t('Providers'),
-        '#default_value' => empty($widget['providers']) ? array() : $widget['providers'],
-        '#options' => $options,
-      );
-
-      foreach (module_implements('emfield_widget_settings_extra') as $module) {
-        $form[$module] = module_invoke($module, 'emfield_widget_settings_extra', 'form', $widget);
-      }
-
-      return $form;
-
-    case 'save':
-      $columns = array('providers'); //, 'helper_module', );
-      foreach (module_implements('emfield_widget_settings_extra') as $module) {
-        $columns = array_merge($columns, module_invoke($module, 'emfield_widget_settings_extra', 'save', $widget));
-      }
-
-      return $columns;
-  }
-}
-
-
-/**
- * This creates default widget handling for all the Embedded Media Fields.
- * Helper modules are expected to call this function to create the widget,
- * which will include a list of all providers as well as handle data parsing.
- */
-function _emfield_emfield_widget(&$form, &$form_state, $field, $items, $delta = 0, $module) { //($op, &$node, $field, &$node_field, $module) {
-  // Our form element will need to be processed as a tree, collapsing any children elements.
-  $tree = array('#tree' => TRUE);
-
-  $providers = emfield_allowed_providers($field, $module);
-  $urls = array();
-  $additional_form_elements = array();
-
-  foreach ($providers as $provider) {
-    // Only list providers allowed for this field. Honor global settings first.
-    if (variable_get('emfield_allow_'. $module .'_'. $provider->name, TRUE)) {
-      // Get the provider info.
-      $info = emfield_include_invoke($module, $provider->name, 'info');
-      // Grab the provider's URL.
-      $urls[] = l($info['name'], $info['url'], array('target' => '_blank'));
-      // Allow the module to add any additional elements to the form, based on individual provider needs.
-      $additional_element = emfield_include_invoke($module, $provider->name, 'form', $field, $items[$delta]);
-      if ($additional_element) {
-        $additional_form_elements[$provider->name] = $additional_element;
-      }
-    }
-  }
-
-  // Set the widget description, but allow the field to override this.
-  if (!(empty($field['widget']['description']))) {
-    $textfield_description = $field['widget']['description'];
-  }
-  else {
-    $textfield_description = t('Enter the URL or Embed Code here. The embedded third party content will be parsed and displayed appropriately from this.');
-  }
-
-  // Add a list of all supported third party providers.
-  $textfield_description .= '<br />'. t('The following services are provided: !urls', array('!urls' => implode(', ', $urls)));
-  // Get the value of our data, if it's been set for this node.
-  $value = isset($items[$delta]['embed']) ? $items[$delta]['embed'] : '';
-  $tree['embed'] = array(
-    '#type' => 'textfield',
-    '#title' => t($field['widget']['label']),
-    '#description' => $textfield_description,
-    '#default_value' => $value,
-    '#required' => $field['required'],
-    '#maxlength' => 2048,
-  );
-
-  $tree['value'] = array(
-    '#type' => 'value',
-    '#value' => $value,
-  );
-
-  if (!empty($additional_form_elements)) {
-    foreach ($additional_form_elements as $key => $element) {
-      $tree[$key] = $element;
-    }
-  }
-
-  if ($value) {
-    $info = emfield_include_invoke($module, $items[$delta]['provider'], 'info');
-    $tree['value_markup'] = array(
-      '#type' => 'item',
-      '#value' => t('(@provider ID: !value)', array('@provider' => $info['provider'], '!value' => l($value, emfield_include_invoke($module, $info['provider'], 'embedded_link', $value, $items[$delta]['data']), array('target' => '_blank')))),
-    );
-  }
-
-  // Allow other modules, such as Embedded Media Thumbnail, to add additional elements to the widget.
-  foreach (module_implements('emfield_widget_extra') as $module_extra) {
-    $tree[$module_extra] = module_invoke($module_extra, 'emfield_widget_extra', 'form', $form, $field, $items[$delta]);
-  }
-
-  return $tree;
-}
+<?php
+// $Id: emfield.cck.inc,v 1.1.2.9 2008/10/11 18:29:21 alexua Exp $
+
+/**
+ * @file
+ * Helper functions to implement our various cck-required functions, such as hook_field and hook_widget.
+ */
+
+/**
+ *  helper function to consistently define field columns
+ */
+function _emfield_field_columns($field) {
+  $columns = array(
+    // poorly named. but this contains the original URL or embed code pre-parsing, as entered by the user/editor.
+    'embed' => array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
+    // this contains the code used by the provider to identify the media
+    'value' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
+    // this is the actual provider used; matches up with the specific provider.inc file
+    'provider' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'not null' => FALSE, 'sortable' => TRUE),
+    // an array for any extra data required by this media, such as unique thumbnail requirements or rss feed data
+    'data' => array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'not null' => FALSE, 'sortable' => FALSE),
+  );
+  // allow other modules to add new columns
+  // TODO: couldn't we just use module_invoke_all here? also make sure those modules do their magic on enable/disable
+  // finally, is this actually used? seems extraneous with the data array (unless we're using views magic for them)
+  foreach (module_implements('emfield_field_columns_extra') as $module) {
+    $extra = module_invoke($module, 'emfield_field_columns_extra', $field);
+    if (is_array($extra) && !empty($extra)) {
+      $columns = array_merge($columns, $extra);
+    }
+  }
+
+  return $columns;
+}
+
+/**
+ * Implementation of hook_emfield_field().
+ * 
+ * This private function is returned directly by emfield_emfield_field().
+ */
+function _emfield_emfield_field($op, &$node, $field, &$items, $teaser, $page, $module) {
+  switch ($op) {
+    // TODO: Nothing to validate at the moment. We need to have different provider api's have a chance to validate.
+    case 'validate':
+      foreach ($items as $delta => $item) {
+        $error_field = $field['multiple'] ? $field['field_name'] .']['. $delta .'][embed' : $field['field_name'];
+        _emfield_field_validate_id($field, $item, $error_field, $module, $delta);
+      }
+      break;
+
+    case 'presave':
+      foreach ($items as $delta => $item) {
+        $list = _emfield_field_submit_id($field, $item, $module);
+        $items[$delta]['provider'] = $list['provider'];
+        $items[$delta]['value'] = $list['value'];
+        $items[$delta]['data'] = $list['data'];
+      }
+      break;
+
+    case 'load':
+      // We need to unserialize the 'data' column manually.
+      $field_name = $field['field_name'];
+      foreach ($items as $delta => $item) {
+        $data = (array)unserialize($items[$delta]['data']);
+        $items[$delta]['data'] = $data;
+        $node->{$field_name}[$delta]['data'] = $data;
+      }
+
+      $return = array();
+      $return[$field_name] = $items;
+      break;
+      
+    case 'delete':
+      break;
+  }
+  // Allow modules (such as emthumb) to alter our data.
+  foreach (module_implements('emfield_field_extra') as $module) {
+    $args = array($op, &$node, $field, &$items, $teaser, $page, $module);
+    $ret = call_user_func_array($module .'_emfield_field_extra', $args);
+    if (is_array($return) && is_array($ret)) {
+      $return = array_merge($return, $ret);
+    }
+  }
+  if (in_array($op, array('insert', 'update'))) {
+    // we need to manually serialize the 'data' array
+    foreach ($items as $delta => $item) {
+      $items[$delta]['data'] = serialize($items[$delta]['data']);
+    }
+  }
+  if (isset($return)) { 
+  return $return;
+  }
+}
+
+function _emfield_emfield_widget_settings($op, $widget, $module) {
+  switch ($op) {
+    case 'form':
+      // Make sure to register the new type as supported by this module.
+      emfield_implement_types(FALSE);
+
+      $form = array();
+      $options = array();
+      $providers = emfield_system_list($module);
+      foreach ($providers as $provider) {
+        if (variable_get('emfield_'. $module . '_allow_'. $provider->name, FALSE)) {
+          $info = emfield_include_invoke($module, $provider->name, 'info');
+          $options[$provider->name] = $info['name'];
+        }
+      }
+      $form['provider_list'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Providers Supported'),
+        '#description' => t('Select which third party providers you wish to allow for this content type from the list below. If no checkboxes are checked, then all providers will be supported. When a user submits new content, the URL they enter will be matched to the provider, assuming that provider is allowed here.'),
+        '#collapsible' => TRUE,
+        '#collapsed' => FALSE,
+      );
+      $form['provider_list']['providers'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Providers'),
+        '#default_value' => empty($widget['providers']) ? array() : $widget['providers'],
+        '#options' => $options,
+      );
+
+      foreach (module_implements('emfield_widget_settings_extra') as $module) {
+        $form[$module] = module_invoke($module, 'emfield_widget_settings_extra', 'form', $widget);
+      }
+
+      return $form;
+
+    case 'save':
+      $columns = array('providers'); //, 'helper_module', );
+      foreach (module_implements('emfield_widget_settings_extra') as $module) {
+        $columns = array_merge($columns, module_invoke($module, 'emfield_widget_settings_extra', 'save', $widget));
+      }
+
+      return $columns;
+  }
+}
+
+
+/**
+ * This creates default widget handling for all the Embedded Media Fields.
+ * Helper modules are expected to call this function to create the widget,
+ * which will include a list of all providers as well as handle data parsing.
+ */
+function _emfield_emfield_widget(&$form, &$form_state, $field, $items, $delta = 0, $module) { //($op, &$node, $field, &$node_field, $module) {
+  // Our form element will need to be processed as a tree, collapsing any children elements.
+  $tree = array('#tree' => TRUE);
+
+  $urls = array();
+  if($module == "emfield_generic"){
+  	$types = array("emaudio","emimage","emvideo");
+  	$widget = $field['widget'];
+    foreach($types as $type){
+    	$type_str = substr($type,2);
+    	
+    	$providers = _emfield_generic_system_list($module,$type);
+ 		   
+	    foreach ($providers as $provider) {    
+		//Only list providers allowed for this field. Honor global settings first. and local cck field settings
+
+	    if (variable_get('emfield_'. $module . '_allow_'. $provider->name, FALSE) && $widget['providers_' . $type_str][$provider->name]) {
+	      //Get the provider info.	  
+	      $function = "_emfield_generic_include_invoke";
+	      $args = array($module,$type,$provider->name, 'info');
+	      $info = call_user_func_array($function, $args);
+	      // Grab the provider's URL.
+	      $urls[] = l($info['name'], $info['url'], array('target' => '_blank'));
+	      // Allow the module to add any additional elements to the form, based on individual provider needs.
+	      $additional_element = emfield_include_invoke($module, $provider->name, 'form');
+	      if ($additional_element) {
+	        $additional_form_elements[$provider->name] = $additional_element;
+	      }	      	      
+	     }
+	    }  	    	
+    }
+  }
+  else
+  {
+	  $providers = emfield_allowed_providers($field, $module);
+	  $additional_form_elements = array();
+	
+	  foreach ($providers as $provider) {
+	    // Only list providers allowed for this field. Honor global settings first.
+	  	if (variable_get('emfield_'. $module .'_allow_'. $provider->name, TRUE)) {
+	      // Get the provider info.
+	      $info = emfield_include_invoke($module, $provider->name, 'info');
+	      // Grab the provider's URL.
+	      $urls[] = l($info['name'], $info['url'], array('target' => '_blank'));
+	      // Allow the module to add any additional elements to the form, based on individual provider needs.
+	      $additional_element = emfield_include_invoke($module, $provider->name, 'form');
+	      if ($additional_element) {
+	        $additional_form_elements[$provider->name] = $additional_element;
+	      }
+	    }
+	  }
+  }
+
+  // Set the widget description, but allow the field to override this.
+  if (!(empty($field['widget']['description']))) {
+    $textfield_description = $field['widget']['description'];
+  }
+  else {
+    $textfield_description = t('Enter the URL or Embed Code here. The embedded third party content will be parsed and displayed appropriately from this.');
+  }
+
+  // Add a list of all supported third party providers.
+  $textfield_description .= '<br />'. t('The following services are provided: !urls', array('!urls' => implode(', ', $urls)));
+  // Get the value of our data, if it's been set for this node.
+  $value = isset($items[$delta]['embed']) ? $items[$delta]['embed'] : '';
+  $tree['embed'] = array(
+    '#type' => 'textfield',
+    '#title' => t($field['widget']['label']),
+    '#description' => $textfield_description,
+    '#default_value' => $value,
+    '#required' => $field['required'],
+    '#maxlength' => 2048,
+  );
+
+  $tree['value'] = array(
+    '#type' => 'value',
+    '#value' => $value,
+  );
+
+  if (!empty($additional_form_elements)) {
+    foreach ($additional_form_elements as $key => $element) {
+      $tree[$key] = $element;
+    }
+  }
+
+  if ($value) {
+    $info = emfield_include_invoke($module, $items[$delta]['provider'], 'info');
+    $tree['value_markup'] = array(
+      '#type' => 'item',
+      '#value' => t('(@provider ID: !value)', array('@provider' => $info['provider'], '!value' => l($value, emfield_include_invoke($module, $info['provider'], 'embedded_link', $value, $items[$delta]['data']), array('target' => '_blank')))),
+    );
+  }
+
+  // Allow other modules, such as Embedded Media Thumbnail, to add additional elements to the widget.
+  foreach (module_implements('emfield_widget_extra') as $module_extra) {
+    $tree[$module_extra] = module_invoke($module_extra, 'emfield_widget_extra', 'form', $form, $field, $items[$delta]);
+  }
+
+  return $tree;
+}
diff -urpN emfield.module emfield.module
--- emfield.module	2008-11-12 12:14:37.000000000 -0600
+++ emfield.module	2008-11-25 17:56:22.000000000 -0600
@@ -140,27 +140,51 @@ function emfield_implement_types($cached
  * @return
  *   Either an empty array (if no match), or an array of 'provider' and 'value'.
  */
-function emfield_parse_embed($field, $embed = '', $module) {
-  $providers = emfield_allowed_providers($field, $module);
-  foreach ($providers as $provider) {
-    $success = emfield_include_invoke($module, $provider->name, 'extract', $embed, $field);
-
-    // We've been given an array of regex strings, so try to find a match.
-    if (is_array($success)) {
-      foreach ($success as $regex) {
-        $matches = NULL;
-        if (preg_match($regex, $embed, $matches)) {
-          return array('provider' => $provider->name, 'value' => $matches[1]);
-        }
-      }
-    }
-    // the invoked include module did its own parsing and found a match
-    else if ($success) {
-      return array('provider' => $provider->name, 'value' => $success);
-    }
+function emfield_parse_embed($field, $embed = '', $module) {
+  if($module == 'emfield_generic'){
+  	$types = array("emaudio","emimage","emvideo");
+    	foreach($types as $type){
+	  	  $providers =  _emfield_generic_allowed_providers($field, $module,$type);
+    	  foreach ($providers as $provider) {
+		    $success = _emfield_generic_include_invoke($module, $type, $provider->name, 'extract', $embed, $field);	
+		    // We've been given an array of regex strings, so try to find a match.
+		    if (is_array($success)) {
+		      foreach ($success as $regex) {
+		        $matches = NULL;
+		        if (preg_match($regex, $embed, $matches)) {	
+		          return array('provider' => $provider->name, 'value' => $matches[1],'type'=> $type);
+		        }
+		      }
+		    }
+		    // the invoked include module did its own parsing and found a match
+		    else if ($success) {		     
+		      return array('provider' => $provider->name, 'value' => $success,'type' => $type);
+		    }
+		  }  		  		
+    	}
+    	  return array('provider' => '', 'value' => '');
+  }
+  else {
+	  $providers = emfield_allowed_providers($field, $module);
+	  foreach ($providers as $provider) {
+	    $success = emfield_include_invoke($module, $provider->name, 'extract', $embed, $field);
+	
+	    // We've been given an array of regex strings, so try to find a match.
+	    if (is_array($success)) {
+	      foreach ($success as $regex) {
+	        $matches = NULL;
+	        if (preg_match($regex, $embed, $matches)) {
+	          return array('provider' => $provider->name, 'value' => $matches[1]);
+	        }
+	      }
+	    }
+	    // the invoked include module did its own parsing and found a match
+	    else if ($success) {
+	      return array('provider' => $provider->name, 'value' => $success);
+	    }
+	  }
   }
-
-  // We found no match.
+  // We found no match.
   return array();
 }
 
@@ -170,9 +194,11 @@ function emfield_parse_embed($field, $em
 function _emfield_field_validate_id($field, $item, $error_field, $module, $delta = 0) {
   // Load the provider info.
   $item = _emfield_field_submit_id($field, $item, $module, $error_field);
-  // Ensure we have proper provider info.
+  // Ensure we have proper provider info.
+  //dpr($item);
+  //exit;
   if ($item['embed'] && !$item['value']) {
-    form_set_error($error_field, t('You have specified an invalid media URL or embed code.'));
+    form_set_error($error_field, t('You have specified an invalid media URL or embed code or doesn\'t exist a provider for your entry.'));
   }
 
   return $item;
@@ -183,9 +209,15 @@ function _emfield_field_validate_id($fie
  *  This also allows you to grab directly from the URL to display the content from field 'provider'.
  */
 function _emfield_field_submit_id($field, $item, $module) {
-  $item = array_merge($item, emfield_parse_embed($field, $item['embed'], $module));
-  $item['data'] = (array)emfield_include_invoke($module, $item['provider'], 'data', $field, $item);
-
+  $item = array_merge($item, emfield_parse_embed($field, $item['embed'], $module));
+  if($module == "emfield_generic"){
+   	$item['data'] = (array) _emfield_generic_include_invoke($module, $item['type'],$item['provider'], 'data', $field, $item);
+   }
+  else {
+  	$item['data'] = (array)emfield_include_invoke($module, $item['provider'], 'data', $field, $item);
+  }	
+  /*dpr($item);
+  exit;*/
   return $item;
 }
 
@@ -197,8 +229,8 @@ function emfield_emfield_field_formatter
   // If we're coming from a preview, we need to extract our new embedded value.
   if (isset($node->in_preview)) {
     $item = emfield_parse_embed($field, $item['embed'], $module);
-  }
-
+  }
+  
   // If we have no value, then return an empty string.
   if (!isset($item['value'])) {
     return '';
@@ -216,9 +248,13 @@ function emfield_emfield_field_formatter
   }
 
   // The individual modules actually define the theme for the formatter.
-  $output = '';
-  $output .= theme($module .'_'. $formatter, $field, $item, $formatter, $node);
-
+  $output = '';
+  if(empty($item['type'])){
+  	$output .= theme($module .'_'. $formatter, $field, $item, $formatter, $node);
+  } else {
+  		$output .= theme($item['type'] . '_'. $formatter, $field, $item, $formatter, $node);
+  }
+  //dpr($item);
   return $output;
 }
 
@@ -482,8 +518,10 @@ function emfield_set_error($error) {
 function emfield_system_list($module, $provider = NULL, $load = TRUE) {
   $override_files = module_invoke_all('emfield_providers', $module, $provider);
   $files = drupal_system_listing("$provider\.inc", drupal_get_path('module', $module) ."/providers", 'name', 0);
-  $files = array_merge($files, $override_files);
-
+  $files = array_merge($files, $override_files);
+  /*print "<pre>";
+  debug_print_backtrace();
+  print "</pre>";*/
   ksort($files);
 
   if ($load) {
@@ -654,17 +692,40 @@ function _emfield_handler_arg_provider($
 
 function emfield_provider_themes($module, $provider = NULL) {
   $themes = array();
-  
-  if ($provider && $subthemes = emfield_include_invoke($module, $provider, 'subtheme')) {
-    $themes = $subthemes;
-  }
-  $providers = module_invoke('emfield', 'system_list', $module);
-  
-  foreach ($providers as $provider) {
-    if ($subthemes = emfield_include_invoke($module, $provider->name, 'emfield_subtheme')) {
-        $themes += $subthemes;
-    }
+      
+  	if($module == 'emfield_generic'){
+
+		$types = array("emaudio","emimage","emvideo");
+  		
+	   if($provider){
+	   		foreach($types as $type){
+		   		if ($subthemes = _emfield_include_invoke($module, $type, $provider, 'subtheme')) {
+			    	$themes = $subthemes;
+		 		}
+	   		}	
+	   }
+
+	    foreach($types as $type){
+	    	$providers = _emfield_generic_system_list($module,$type);
+	   		foreach ($providers as $provider) {
+			    if ($subthemes = _emfield_generic_include_invoke($module,$type,$provider->name, 'emfield_subtheme')) {
+			        $themes += $subthemes;
+			    }
+	  		}
+	    }  	
+  }
+  else {	
+  	
+  	   if ($provider && $subthemes = emfield_include_invoke($module, $provider, 'subtheme')) {
+	    $themes = $subthemes;
+ 		}
+	  $providers = module_invoke('emfield', 'system_list', $module);
+	  
+	  foreach ($providers as $provider) {
+	    if ($subthemes = emfield_include_invoke($module, $provider->name, 'emfield_subtheme')) {
+	        $themes += $subthemes;
+	    }
+	  }
   }
-  
   return $themes;
 }
