diff --git a/sites/all/modules/delicious/delicious.inc b/sites/all/modules/delicious/delicious.inc
new file mode 100644
index 0000000..7fb435f
--- /dev/null
+++ b/sites/all/modules/delicious/delicious.inc
@@ -0,0 +1,258 @@
+<?php
+// $Id$
+// ----------------------------------------------------------------------------
+// REST calls to del.icio.us API
+//
+
+//
+// drupal_http_support etc FROM alastair tse
+//
+function _delicious_make_auth_header($username, $password) {
+  $realm = "del.icio.us API";
+  $user_agent = "drupal.contributions.delicious.module/1.0";
+
+  $auth = 'Basic '. base64_encode($username .':'. $password);
+
+  $headers = array();
+  $headers['User-Agent'] = $user_agent;
+  $headers['Authorization'] = $auth; 
+  return $headers;
+}
+
+//
+// get a page FROM the delicious API
+//
+function _delicious_get_page($page, $user, $pass) {
+  // Force 1 second throttle.
+  static $last_hit;
+  $now = microtime(TRUE);
+  if ($now < $last_hit + 1) {
+    sleep(1);
+  }
+  $last_hit = $now;
+  
+  return drupal_http_request(DELICIOUS_API_URL . $page,
+    _delicious_make_auth_header($user, $pass));
+}
+
+//
+// cron support: update all users who have Delicious Links
+//
+function _delicious_update_user($user) {
+  $resp = _delicious_get_page(DELICIOUS_UPDATE_URL, $user->user, $user->pass);  
+  $code = intval($resp->redirect_code ? $resp->redirect_code : $resp->code);
+  if ($code != 200) {
+    db_query("UPDATE {delicious_user} SET lastcode = %d WHERE uid=%d", $code, $user->uid);
+    return 0;
+  }
+  else if ($resp->error) {
+    watchdog("error", "delicious response: $resp->error");
+  }
+
+  $parser = new _delicious_update_parser();
+  $lastupdate = $parser->parse($resp->data);
+  if ($lastupdate > $user->lastupdate) { 
+    $resp = _delicious_get_page(DELICIOUS_POSTS_URL, $user->user, $user->pass); 
+    $code = intval($resp->redirect_code ? $resp->redirect_code : $resp->code);
+    if ($code != 200) {
+      db_query("UPDATE {delicious_user} SET lastcode = %d WHERE uid=%d", $code, $user->uid);
+      return 0;
+    }
+    $parser = new _delicious_post_parser($user->uid);
+    $parser->parse($resp->data);
+    db_query("UPDATE {delicious_user} SET lastcode = %d, lastupdate = '%s' WHERE uid=%d", $code, $lastupdate, $user->uid);
+    return 1;
+
+  }
+
+  return 0;
+}
+
+// ----------------------------------------------------------------------------
+// XML parsing objects
+//
+// If another object gets created, refactor some of the code into a base object
+// and inherit
+
+//
+// parse the update string
+//
+class _delicious_update_parser {
+
+  function parse($data) {
+    $this->update = 0;
+    $this->xml_parser = xml_parser_create();
+    xml_set_object($this->xml_parser, $this);
+    xml_set_element_handler($this->xml_parser, "start_element", "end_element");
+
+    if (!xml_parse($this->xml_parser, $data)) {
+      watchdog("warning", sprintf("XML error: %s at line %d",
+        xml_error_string(xml_get_error_code($this->xml_parser)),
+        xml_get_current_line_number($this->xml_parser)));
+    }
+
+    xml_parser_free($this->xml_parser);
+    return $this->update;
+  }
+
+  function start_element($parser, $name, $attrs) {
+    if ($name == 'UPDATE') {
+      if ($attrs["TIME"] != '') {
+        $this->update = _delicious_date_parse($attrs["TIME"]);
+      }
+    }
+  }
+
+  function end_element($parser, $name) {
+  }
+
+}
+
+//
+// parse all posts, and write them to the database; delete all unsynced
+// posts for that user.
+//
+class _delicious_post_parser {
+
+  function _delicious_post_parser($uid = 0) {
+    $this->uid = $uid;
+  }
+
+  function parse($data) {
+    // unsync all related records
+    db_query("UPDATE {delicious_link} SET synced=0 WHERE uid=%d", $this->uid);
+    db_query("UPDATE {delicious_tag} SET synced=0 WHERE uid=%d", $this->uid);
+    $this->xml_parser = xml_parser_create();
+    xml_set_object($this->xml_parser, $this);
+    xml_set_element_handler($this->xml_parser, "start_element", "end_element");
+
+    if (!xml_parse($this->xml_parser, $data)) {
+      watchdog("warning", sprintf("XML error: %s at line %d",
+        xml_error_string(xml_get_error_code($this->xml_parser)),
+        xml_get_current_line_number($this->xml_parser)));
+    }
+
+    xml_parser_free($this->xml_parser);
+    // delete all unsynced records
+    db_query("DELETE FROM {delicious_link} WHERE synced=0 and uid=%d", $this->uid);
+    db_query("DELETE FROM {delicious_tag} WHERE synced=0 and uid=%d", $this->uid);
+  }
+
+  function start_element($parser, $name, $attrs) {
+    if ($attrs["DESCRIPTION"] != '') {
+      $desc = $attrs["DESCRIPTION"];
+      $href = $attrs["HREF"];
+      $tags = split(' ', $attrs["TAG"]);
+      if ($attrs["EXTENDED"] != '') {
+        $extended = $attrs["EXTENDED"];
+      }
+      $hash = $attrs["HASH"];
+      $time = _delicious_date_parse($attrs["TIME"]); // yay we gotta parse this don't we?
+
+      $link = array(
+        'desc' => $desc,
+        'href' => $href,
+        'extended' => empty($extended) ? NULL : $extended,
+        'hash' => $hash,
+        'time' => $time,
+        'uid' => $this->uid,
+        'tags' => $tags,
+      );
+
+      $obj = db_fetch_object(db_query("SELECT * FROM {delicious_link} WHERE hash='%s'", $hash));
+      if ($obj) {
+        db_query("UPDATE {delicious_link} SET synced=1, description='%s', extended='%s', href='%s', linktime='%s' WHERE hash='%s'", $desc, $extended, $href, $time, $hash);
+
+        $link['old'] = $obj;
+        $link['lid'] = $obj->lid;
+        module_invoke_all('delicious_link_updated', $link);
+                
+        foreach ($tags as $tag) {
+          $tagobj = db_fetch_object(db_query("SELECT * FROM {delicious_tag} WHERE lid = %d and name = '%s'", $obj->lid, $tag));
+          if ($tagobj) {
+            db_query("UPDATE {delicious_tag} SET synced=1 WHERE lid=%d and name='%s'", $obj->lid, $tag);
+          }
+          else {
+            db_query("INSERT INTO {delicious_tag} (lid, uid, name, synced) VALUES ('%d', '%s', '%s', 1)", $obj->lid, $this->uid, $tag);
+          }
+        }
+      }
+      else {
+        db_query("INSERT INTO {delicious_link} (lid, uid, href, description, extended, linktime, hash, synced) VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', 1)", NULL, $this->uid, $href, $desc, $extended, $time, $hash);
+        $lid = db_last_insert_id("delicious_link", "lid");
+
+        $link['lid'] = $lid;
+        module_invoke_all('delicious_link_insert', $link);
+
+        foreach ($tags as $tag) {
+          db_query("INSERT INTO {delicious_tag} (lid, uid, name, synced) VALUES (%d, %d, '%s', 1)", $lid, $this->uid, $tag);
+        }
+      }
+    }
+  }
+
+  function end_element($parser, $name) {
+  }
+}
+
+// ----------------------------------------------------------------------------
+// smart/crosslinking stuff and general support
+
+//
+// render a link to the node's first term if present for crosslinking
+//
+function _delicious_term_link(&$node) {
+  $terms = taxonomy_node_get_terms($node->nid);
+  $term = array_shift($terms);
+  if (!empty($term->name)) {
+    $tag = strtolower(str_replace(' ', '', $term->name));
+    return DELICIOUS_BASE_URL ."tag/$tag";
+  }
+}
+
+//
+// smart-tagging support
+//
+function _delicious_tag_string($text, $tags, $username) {
+
+  if (!$tags) {
+    return $text;
+  }
+ 
+  // error, it must start with a tag... :-(
+  foreach ($tags as $tag) { 
+    if (!empty($tag) && $tag != ' ') {
+      $path = DELICIOUS_BASE_URL . urlencode($username) .'/'. urlencode($tag);
+      $modulepath = drupal_get_path('module', 'delicious');
+      $delicious_link = "<a href='$path'><img src='/$modulepath/deliciousIcon.gif' class='delicious-icon'></a>";
+
+      $tag = str_replace('/', '\\/', $tag);
+      if (!preg_match('/<.+>/', $text)) {
+        $text = preg_replace('/(\b'. $tag .'\b)/i', '$1'. $delicious_link, $text);
+      }
+      else {
+        $text = preg_replace('/(?<=>)([^<]+)?(\b'. $tag .'\b)/i', '$1$2'. $delicious_link, $text);
+      }
+    }
+  }
+
+  return $text;
+}
+
+//
+// support function for tagged text
+//
+function _delicious_tag_text($text, $name) {
+  $result = db_query("SELECT distinct(name) FROM {delicious_tag}");
+  while ($tag = db_fetch_object($result)) {
+    $tags[] = $tag->name;
+  }
+  return _delicious_tag_string($text, $tags, $name);
+}
+
+// Translate delicious dates into normal dates
+function _delicious_date_parse($date) {
+    $date = str_replace('T', ' ', $date);
+    $date = str_replace('Z', ' ', $date);
+    return strtotime($date);
+}
diff --git a/sites/all/modules/delicious/delicious.install b/sites/all/modules/delicious/delicious.install
index 77d4be5..87f0939 100644
--- a/sites/all/modules/delicious/delicious.install
+++ b/sites/all/modules/delicious/delicious.install
@@ -15,7 +15,7 @@ function delicious_install() {
 function delicious_schema() {
   $schema['delicious_user'] = array(
     'fields' => array(
-      'uid' => array('type' => 'int', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE),
+      'uid' => array('type' => 'int', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE),
       'user' => array('type' => 'varchar', 'length' => '255'),
       'pass' => array('type' => 'varchar', 'length' => '255'),
       'lastupdate' => array('type' => 'varchar', 'length' => '20', 'default' => ''),
@@ -27,8 +27,8 @@ function delicious_schema() {
   );  
   $schema['delicious_link'] = array(
     'fields' => array(
-      'lid' => array('type' => 'serial', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE ),
-      'uid' => array('type' => 'int', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE),
+      'lid' => array('type' => 'serial', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE ),
+      'uid' => array('type' => 'int', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE),
       'href' => array('type' => 'text', 'size' => 'big'),
       'description' => array('type' => 'text', 'size' => 'big'),
       'extended' => array('type' => 'text', 'size' => 'big'),
@@ -47,28 +47,28 @@ function delicious_schema() {
   );
   $schema['delicious_tag'] = array(
     'fields' => array(
-      'lid' => array('type' => 'int', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE),
-      'uid' => array('type' => 'int', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE),
+      'lid' => array('type' => 'int', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE),
+      'uid' => array('type' => 'int', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE),
       'name' => array('type' => 'varchar', 'length' => '255', 'not null' => TRUE),
-      'synced' => array('type' => 'int','size' => 'tiny','length' => '1')
+      'synced' => array('type' => 'int', 'size' => 'tiny', 'length' => '1')
     ),
     'indexes' => array(
       'delicious_tag_synced' => array('synced'),
       'delicious_tag_uid' => array('uid')
     ),
     'unique keys' => array(
-       'delicious_tag_id' => array('lid','name')
+       'delicious_tag_id' => array('lid', 'name')
     )
   );  
   $schema['delicious_block'] = array(
     'fields' => array(
-      'dbid' => array('type' => 'serial', 'length' => '10','unsigned' => TRUE, 'not null' => TRUE),
+      'dbid' => array('type' => 'serial', 'length' => '10', 'unsigned' => TRUE, 'not null' => TRUE),
       'title' => array('type' => 'varchar', 'length' => '255', 'not null' => TRUE),     
-      'users' => array('type' => 'text','size' => 'big'),
-      'tags' => array('type' => 'text','size' => 'big'),      
-      'maxentries' => array('type' => 'int','size' => 'tiny','length' => '2'),
-      'display' => array('type' => 'int','size' => 'tiny','length' => '1'),
-      'orderby' => array('type' => 'int','size' => 'tiny','length' => '1'),
+      'users' => array('type' => 'text', 'size' => 'big'),
+      'tags' => array('type' => 'text', 'size' => 'big'),      
+      'maxentries' => array('type' => 'int', 'size' => 'tiny', 'length' => '2'),
+      'display' => array('type' => 'int', 'size' => 'tiny', 'length' => '1'),
+      'orderby' => array('type' => 'int', 'size' => 'tiny', 'length' => '1'),
     ),
     'primary key' => array('dbid'),
   );
@@ -80,6 +80,7 @@ function delicious_schema() {
  * Implementation of hook_uninstall().
  */
 function delicious_uninstall() {
+  drupal_uninstall_schema('delicious');
   variable_del('delicious_crosslink');
   variable_del('delicious_tagging');
   variable_del('delicious_node_types');
diff --git a/sites/all/modules/delicious/delicious.module b/sites/all/modules/delicious/delicious.module
index d938aba..ee1f2ec 100644
--- a/sites/all/modules/delicious/delicious.module
+++ b/sites/all/modules/delicious/delicious.module
@@ -52,6 +52,7 @@ function delicious_help($section = "admin/help#delicious") {
 //
 // Add a link, if necessary, to the links section of a node
 function delicious_link($type, $node = NULL, $teaser = FALSE) {
+  module_load_include('inc', 'delicious');
   if ($node && user_access('view delicious links') && $type == 'node' && _delicious_nodetype_applicable($node->type) && variable_get('delicious_crosslink', 0)) {
     if ($link = _delicious_term_link($node)) {
       $links = array();
@@ -205,6 +206,7 @@ function delicious_nodeapi(&$node, $op, $arg = 0) {
   switch ($op) {
     // smart-tagging
     case "alter":
+      module_load_include('inc', 'delicious');
       if (user_access('view delicious links') && variable_get("delicious_tagging", 1)) {
         // WARNING: there's not UI for setting this?
         $uname = variable_get("delicious_tag_user", ""); 
@@ -225,6 +227,7 @@ function delicious_nodeapi(&$node, $op, $arg = 0) {
 // _cron() hook
 //
 function delicious_cron() {
+  module_load_include('inc', 'delicious');
   $result = db_query("SELECT DISTINCT(u.uid), u.name, d.user, d.pass, d.lastupdate, d.lastcode FROM {users} u INNER JOIN {delicious_user} d ON u.uid = d.uid");
   while ($u = db_fetch_object($result)) {
     if ($u->lastcode != 403 && $u->lastcode != 401) {
@@ -346,7 +349,8 @@ function delicious_page_tag($tag = "", $uid = "") {
   
   if ($uid) {
   $result = pager_query("SELECT u.name, u.uid, dl.description, dl.href, dl.linktime, dl.extended FROM {delicious_tag} dt LEFT JOIN {delicious_link} dl ON dt.lid = dl.lid LEFT JOIN {users} u ON dl.uid = u.uid WHERE dt.name = '$tag' AND u.uid = '$uid' ORDER BY dl.linktime desc", 20); 
-  } else {
+  }
+  else {
     $result = pager_query("SELECT u.name, u.uid, dl.description, dl.href, dl.linktime, dl.extended FROM {delicious_tag} dt LEFT JOIN {delicious_link} dl ON dt.lid = dl.lid LEFT JOIN {users} u ON dl.uid = u.uid WHERE dt.name = '$tag'  ORDER BY dl.linktime desc", 20);
   }
   //TODO $tag added inside pager_query() to avoid the error "warning: Division by zero " 
@@ -409,7 +413,7 @@ function delicious_page_settings() {
 //
 // render user specific delicious settings form
 //
-function delicious_page_settings_form(&$form_state,$uid) {  
+function delicious_page_settings_form(&$form_state, $uid) {  
   // Check to see if a delicious_user entry exists
   $result = db_query("SELECT * FROM {delicious_user} WHERE uid = %d", $uid);
   $userinfo = db_fetch_object($result);
@@ -485,6 +489,7 @@ function delicious_page_settings_form(&$form_state,$uid) {
 }
 
 function delicious_page_settings_submit($form, &$form_state) {  
+  module_load_include('inc', 'delicious');
   $form_values = $form_state['values'];  
   if ($form_values['op'] == t('Enable')) {
     // create a delicious_user entry
@@ -568,7 +573,7 @@ function delicious_admin_delete($dbid = 0) {
   return drupal_get_form('delicious_confirm_delete_form', $dbid);
 }
 
-function delicious_confirm_delete_form($form_state,$dbid) {
+function delicious_confirm_delete_form($form_state, $dbid) {
   $form['block'] = array('#type' => 'value', '#value' => $dbid);
   return confirm_form(
     $form,
@@ -591,7 +596,7 @@ function delicious_confirm_delete_form_submit($form, &$form_state) {
 //
 // display add/edit block form
 //
-function delicious_block_form(&$form_state,$dbid = 0) {
+function delicious_block_form(&$form_state, $dbid = 0) {
   $block = delicious_load_block($dbid);
 
   $form['title'] = array(
@@ -723,7 +728,13 @@ function delicious_recent($id) {
   $tags = $block->tags ? explode(',', trim($block->tags)) : array();
   $tags = module_invoke_all('delicious', 'tags', $tags);
   if ($tags) {
-    if ($tags['like'] == TRUE) {      unset($tags['like']);      $where .= ' AND ('. implode(' OR ', array_fill(0, count($tags), "dt.name LIKE '%%%s%%'")) .')';    }    else {      $where .= ' AND dt.name IN ('. implode(',', array_fill(0, count($tags), "'%s'")) .')';    }
+    if ($tags['like'] == TRUE) {
+      unset($tags['like']);
+      $where .= ' AND ('. implode(' OR ', array_fill(0, count($tags), "dt.name LIKE '%%%s%%'")) .')';
+    }
+    else {
+      $where .= ' AND dt.name IN ('. implode(',', array_fill(0, count($tags), "'%s'")) .')';
+    }
     $args = array_merge($args, $tags);
   }
 
@@ -827,241 +838,7 @@ function delicious_block_page() {
   return $output;
 }
 
-// ----------------------------------------------------------------------------
-// REST calls to del.icio.us API
-//
-
-//
-// drupal_http_support etc FROM alastair tse
-//
-function _delicious_make_auth_header($username, $password) {
-  $realm = "del.icio.us API";
-  $user_agent = "drupal.contributions.delicious.module/1.0";
-
-  $auth = 'Basic '. base64_encode($username .':'. $password);
-
-  $headers = array();
-  $headers['User-Agent'] = $user_agent;
-  $headers['Authorization'] = $auth; 
-  return $headers;
-}
-
-//
-// get a page FROM the delicious API
-//
-function _delicious_get_page($page, $user, $pass) {
-  // Force 1 second throttle.
-  static $last_hit;
-  $now = microtime(TRUE);
-  if ($now < $last_hit + 1) {
-    sleep(1);
-  }
-  $last_hit = $now;
-  
-  return drupal_http_request(DELICIOUS_API_URL . $page,
-    _delicious_make_auth_header($user, $pass));
-}
-
-//
-// cron support: update all users who have Delicious Links
-//
-function _delicious_update_user($user) {
-  $resp = _delicious_get_page(DELICIOUS_UPDATE_URL, $user->user, $user->pass);  
-  $code = intval($resp->redirect_code ? $resp->redirect_code : $resp->code);
-  if ($code != 200) {
-    db_query("UPDATE {delicious_user} SET lastcode = %d WHERE uid=%d", $code, $user->uid);
-    return 0;
-  }
-  else if ($resp->error) {
-    watchdog("error", "delicious response: $resp->error");
-  }
-
-  $parser = new _delicious_update_parser();
-  $lastupdate = $parser->parse($resp->data);
-  if ($lastupdate > $user->lastupdate) { 
-    $resp = _delicious_get_page(DELICIOUS_POSTS_URL, $user->user, $user->pass); 
-    $code = intval($resp->redirect_code ? $resp->redirect_code : $resp->code);
-    if ($code != 200) {
-      db_query("UPDATE {delicious_user} SET lastcode = %d WHERE uid=%d", $code, $user->uid);
-      return 0;
-    }
-    $parser = new _delicious_post_parser($user->uid);
-    $parser->parse($resp->data);
-    db_query("UPDATE {delicious_user} SET lastcode = %d, lastupdate = '%s' WHERE uid=%d", $code, $lastupdate, $user->uid);
-    return 1;
 
-  }
-
-  return 0;
-}
-
-// ----------------------------------------------------------------------------
-// XML parsing objects
-//
-// If another object gets created, refactor some of the code into a base object
-// and inherit
-
-//
-// parse the update string
-//
-class _delicious_update_parser {
-
-  function parse($data) {
-    $this->update = 0;
-    $this->xml_parser = xml_parser_create();
-    xml_set_object($this->xml_parser, $this);
-    xml_set_element_handler($this->xml_parser, "start_element", "end_element");
-
-    if (!xml_parse($this->xml_parser, $data)) {
-      watchdog("warning", sprintf("XML error: %s at line %d",
-        xml_error_string(xml_get_error_code($this->xml_parser)),
-        xml_get_current_line_number($this->xml_parser)));
-    }
-
-    xml_parser_free($this->xml_parser);
-    return $this->update;
-  }
-
-  function start_element($parser, $name, $attrs) {
-    if ($name == 'UPDATE') {
-      if ($attrs["TIME"] != '') {
-        $this->update = _delicious_date_parse($attrs["TIME"]);
-      }
-    }
-  }
-
-  function end_element($parser, $name) {
-  }
-
-}
-
-//
-// parse all posts, and write them to the database; delete all unsynced
-// posts for that user.
-//
-class _delicious_post_parser {
-
-  function _delicious_post_parser($uid = 0) {
-    $this->uid = $uid;
-  }
-
-  function parse($data) {
-    // unsync all related records
-    db_query("UPDATE {delicious_link} SET synced=0 WHERE uid=%d", $this->uid);
-    db_query("UPDATE {delicious_tag} SET synced=0 WHERE uid=%d", $this->uid);
-    $this->xml_parser = xml_parser_create();
-    xml_set_object($this->xml_parser, $this);
-    xml_set_element_handler($this->xml_parser, "start_element", "end_element");
-
-    if (!xml_parse($this->xml_parser, $data)) {
-      watchdog("warning", sprintf("XML error: %s at line %d",
-        xml_error_string(xml_get_error_code($this->xml_parser)),
-        xml_get_current_line_number($this->xml_parser)));
-    }
-
-    xml_parser_free($this->xml_parser);
-    // delete all unsynced records
-    db_query("DELETE FROM {delicious_link} WHERE synced=0 and uid=%d", $this->uid);
-    db_query("DELETE FROM {delicious_tag} WHERE synced=0 and uid=%d", $this->uid);
-  }
-
-  function start_element($parser, $name, $attrs) {
-    if ($attrs["DESCRIPTION"] != '') {
-      $desc = db_escape_string(utf8_decode($attrs["DESCRIPTION"]));
-      $href = db_escape_string($attrs["HREF"]);
-      $tags = split(' ', $attrs["TAG"]);
-      if ($attrs["EXTENDED"] != '') {
-        $extended = db_escape_string($attrs["EXTENDED"]);
-      }
-      $hash = $attrs["HASH"];
-      $time = _delicious_date_parse($attrs["TIME"]); // yay we gotta parse this don't we?
-
-      $obj = db_fetch_object(db_query("SELECT * FROM {delicious_link} WHERE hash='%s'", $hash));
-      if ($obj) {
-        db_query("UPDATE {delicious_link} SET synced=1, description='%s', extended='%s', href='%s', linktime='%s' WHERE hash='%s'", $desc, $extended, $href, $time, $hash);
-        foreach ($tags as $tag) {
-          $tagobj = db_fetch_object(db_query("SELECT * FROM {delicious_tag} WHERE lid = %d and name = '%s'", $obj->lid, $tag));
-          if ($tagobj) {
-            db_query("UPDATE {delicious_tag} SET synced=1 WHERE lid=%d and name='%s'", $obj->lid, $tag);
-          }
-          else {
-            db_query("INSERT INTO {delicious_tag} (lid, uid, name, synced) VALUES (%d, %s, '%s', 1)", $obj->lid, $this->uid, $tag);
-          }
-        }
-      }
-      else {
-        db_query("INSERT INTO {delicious_link} (lid, uid, href, description, extended, linktime, hash, synced) VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', 1)", NULL, $this->uid, $href, $desc, $extended, $time, $hash);
-        $lid = db_last_insert_id("delicious_link", "lid");
-
-        foreach ($tags as $tag) {
-          db_query("INSERT INTO {delicious_tag} (lid, uid, name, synced) VALUES (%d, %d, '%s', 1)", $lid, $this->uid, $tag);
-        }
-      }
-    }
-  }
-
-  function end_element($parser, $name) {
-  }
-}
-
-// ----------------------------------------------------------------------------
-// smart/crosslinking stuff and general support
-
-//
-// render a link to the node's first term if present for crosslinking
-//
-function _delicious_term_link(&$node) {
-  $terms = taxonomy_node_get_terms($node->nid);
-  $term = array_shift($terms);
-  if (!empty($term->name)) {
-    $tag = strtolower(str_replace(' ', '', $term->name));
-    return DELICIOUS_BASE_URL ."tag/$tag";
-  }
-}
-
-//
-// smart-tagging support
-//
-function _delicious_tag_string($text, $tags, $username) {
-
-  if (!$tags) {
-    return $text;
-  }
- 
-  // error, it must start with a tag... :-(
-  foreach ($tags as $tag) { 
-    if (!empty($tag) && $tag != ' ') {
-      $path = DELICIOUS_BASE_URL . urlencode($username) .'/'. urlencode($tag);
-      $modulepath = drupal_get_path('module', 'delicious');
-      $delicious_link = "<a href='$path'><img src='/$modulepath/deliciousIcon.gif' class='delicious-icon'></a>";
-
-      $tag = str_replace('/', '\\/', $tag);
-      if (!preg_match('/<.+>/', $text)) {
-        $text = preg_replace('/(\b'. $tag .'\b)/i', '$1'. $delicious_link, $text);
-      }
-      else {
-        $text = preg_replace('/(?<=>)([^<]+)?(\b'. $tag .'\b)/i', '$1$2'. $delicious_link, $text);
-      }
-    }
-  }
-
-  return $text;
-}
-
-//
-// support function for tagged text
-//
-function _delicious_tag_text($text, $name) {
-  $result = db_query("SELECT distinct(name) FROM {delicious_tag}");
-  while ($tag = db_fetch_object($result)) {
-    $tags[] = $tag->name;
-  }
-  return _delicious_tag_string($text, $tags, $name);
-}
-
-//
-// General configuration support
-//
 function _delicious_nodetype_applicable($type) {
   $del = variable_get('delicious_node_types', array('blog', 'story', 'page'));
   if (is_array($del)) {
@@ -1069,12 +846,6 @@ function _delicious_nodetype_applicable($type) {
   }
 }
 
-// Translate delicious dates into normal dates
-function _delicious_date_parse($date) {
-    $date = str_replace('T', ' ', $date);
-    $date = str_replace('Z', ' ', $date);
-    return strtotime($date);
-}
 
 //
 // theming function
@@ -1132,11 +903,11 @@ function theme_delicious_tags($tags) {
 }
 
 function theme_delicious_user($uid) {
-	
+
   $module = drupal_get_path('module', 'delicious');
-  drupal_add_css($module . '/delicious.css');
-  drupal_add_js($module . '/delicious.js');
-	
+  drupal_add_css($module .'/delicious.css');
+  drupal_add_js($module .'/delicious.js');
+
   static $num_actuators;
 
   if ($num_actuators) {
@@ -1206,3 +977,11 @@ function theme_delicious_user($uid) {
   return $output;
 }
 
+function delicious_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module', 'delicious') .'/includes',
+  );
+  
+}
+
diff --git a/sites/all/modules/delicious/includes/delicious.views.inc b/sites/all/modules/delicious/includes/delicious.views.inc
new file mode 100644
index 0000000..3447777
--- /dev/null
+++ b/sites/all/modules/delicious/includes/delicious.views.inc
@@ -0,0 +1,218 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Provide views data and handlers for delicious.module
+ */
+
+/**
+ * @defgroup views_delicious_module delicious.module handlers
+ *
+ * Includes the ability to create views of just the delicious data.
+ * @{
+ */
+
+/**
+* Implementation of hook_views_handlers() to register all of the basic handlers
+* views uses.
+*/
+function delicious_views_handlers() {
+ return array(
+   'info' => array(
+     'path' => drupal_get_path('module', 'delicious') .'/includes',
+     ),
+   'handlers' => array(
+     'delicious_views_handler_field_description' => array(
+       'parent' => 'views_handler_field_url',
+     ),
+     'delicious_views_handler_field_tag' => array(
+       'parent' => 'views_handler_field_prerender_list',
+     ),
+   ),
+ );
+}
+
+/**
+ * Implementation of hook_views_data()
+ */
+function delicious_views_data() {
+  // Basic table information.
+
+  $data['delicious_link']['table']['group']  = t('Delicious');
+
+  $data['delicious_link']['table']['base'] = array(
+    'field' => 'lid',
+    'title' => t('Delicious link'),
+    'help' => t('Stores links from Delicious.com.'),
+  );
+
+  $data['delicious_link']['linktime'] = array(
+    'title' => t('Posted time'),
+    'help' => t('The time the link was first posted.'),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+  );
+
+  $data['delicious_link']['href'] = array(
+    'title' => t('Link URL'),
+    'help' => t('The href of the link.'),
+    'field' => array(
+      'handler' => 'views_handler_field_url',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  $data['delicious_link']['description'] = array(
+    'title' => t('Title'),
+    'help' => t('The short description of the link.'),
+    'field' => array(
+      'handler' => 'delicious_views_handler_field_description',
+      'click sortable' => FALSE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+  );
+
+  $data['delicious_link']['extended'] = array(
+    'title' => t('Extended description'),
+    'help' => t('The extended description of the link.'),
+    'field' => array(
+      'handler' => 'views_handler_field_xss',
+      'click sortable' => FALSE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+  );
+
+  $data['delicious_link']['synced'] = array(
+    'title' => t('Sync status'),
+    'help' => t('Whether the post in question has been synced with the copy on Delicious.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_boolean_operator',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+  // Delicious post shard status
+  $data['delicious_link']['shared'] = array(
+    'title' => t('Shared'),
+    'help' => t('Whether the post in question is shared or private.'),
+    'field' => array(
+      'handler' => 'views_handler_field_boolean',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_boolean_operator',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+
+
+
+  $data['delicious_tag']['table']['group']  = t('Delicious');
+
+  $data['delicious_tag']['table']['join'] = array(
+    'delicious_link' => array(
+      'left_field' => 'lid',
+      'field' => 'lid',
+    ),
+  );
+  $data['delicious_tag']['name'] = array(
+    'title' => t('Tag'),
+    'help' => t('A tag associated with the item.'),
+    'field' => array(
+      'handler' => 'delicious_views_handler_field_tag',
+      'click sortable' => FALSE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  $data['delicious_user']['table']['group']  = t('Delicious');
+
+  $data['delicious_user']['table']['join'] = array(
+    'users' => array(
+      'left_field' => 'uid',
+      'field' => 'uid',
+    ),
+    'delicious_link' => array(
+      'left_field' => 'uid',
+      'field' => 'uid',
+    ),
+  );
+
+  // Delicious account description
+  $data['delicious_user']['uid'] = array(
+    'title' => t('User ID'),
+    'help' => t('The UID of the Delicious account.'),
+  );
+
+  // Delicious user name
+  $data['delicious_user']['user'] = array(
+    'title' => t('User name'),
+    'help' => t('The user name of the Delcicious account.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
+  $data['delicious_user']['linktime'] = array(
+    'title' => t('Last updated'),
+    'help' => t("The last time this user's links were retrieved."),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+  );
+
+  return $data;
+}
+
+
+/**
+ * @}
+ */
diff --git a/sites/all/modules/delicious/includes/delicious_views_handler_field_description.inc b/sites/all/modules/delicious/includes/delicious_views_handler_field_description.inc
new file mode 100644
index 0000000..1bbf1db
--- /dev/null
+++ b/sites/all/modules/delicious/includes/delicious_views_handler_field_description.inc
@@ -0,0 +1,27 @@
+<?php 
+// $Id$ 
+/**
+ * Field handler to provide simple renderer that turns a URL into a clickable link.
+ */
+class delicious_views_handler_field_description extends views_handler_field_url {
+  /**
+   * Override init function to provide generic option to link to node.
+   */
+  function init(&$view, &$data) {
+    parent::init($view, $data);
+    if (!empty($data['display_as_link'])) {
+      $this->additional_fields[] = 'href';
+    }
+  }
+
+  function render($values) {
+    $title = check_plain($values->{$this->field_alias});
+    if (!empty($this->options['display_as_link'])) {
+        return l($title, check_url($values->{$this->table_alias .'_href'}), array('html' => TRUE));
+        break;
+    }
+    else {
+      return check_plain($title);
+    }
+  }
+}
\ No newline at end of file
diff --git a/sites/all/modules/delicious/includes/delicious_views_handler_field_tag.inc b/sites/all/modules/delicious/includes/delicious_views_handler_field_tag.inc
new file mode 100644
index 0000000..747a7a5
--- /dev/null
+++ b/sites/all/modules/delicious/includes/delicious_views_handler_field_tag.inc
@@ -0,0 +1,40 @@
+<?php
+// $Id$
+class delicious_views_handler_field_tag extends views_handler_field_prerender_list {
+  function init(&$view, $options) {
+    parent::init($view, $options);
+    $this->additional_fields['lid'] = array('table' => 'delicious_link', 'field' => 'lid');
+  }
+
+  function query() {
+    $this->add_additional_fields();
+  }
+
+  function pre_render($values) {
+    $this->field_alias = $this->aliases['lid'];
+    $this->items = array();
+
+    $lids = array();
+    foreach ($values as $result) {
+      if (!empty($result->{$this->aliases['lid']})) {
+        $lids[] = $result->{$this->aliases['lid']};
+      }
+    }
+
+    $sql = "SELECT dt.name, dt.lid FROM {delicious_tag} dt WHERE dt.lid IN (". implode(", ", $lids) .")";
+    $results = db_query($sql);
+
+    while ($result = db_fetch_array($results)) {
+      $this->items[$result['lid']][] = check_plain($result['name']);
+    }
+  }
+}
+
+
+function delicious_views_data_alter(&$data) {
+  $data['users']['table']['join']['delicious_link'] = array(
+    'left_table' => 'delicious_user_user',
+    'left_field' => 'uid',
+    'field' => 'uid',
+  );
+}
\ No newline at end of file
