diff --git flag.module flag.module
index d626a7a..3b68755 100644
--- flag.module
+++ flag.module
@@ -222,7 +222,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) {
 }
 
 /**
- * Implementation of hook_flag_link().
+ * Default flag_link() implementation.
  *
  * When Flag uses a link type provided by this module, it will call this
  * implementation of hook_flag_link(). It returns a single link's attributes,
@@ -240,9 +240,14 @@ function flag_link($type, $object = NULL, $teaser = FALSE) {
  */
 function flag_flag_link($flag, $action, $content_id) {
   $token = flag_get_token($content_id);
+  $link_types = flag_get_link_types();
+
+  $link = $link_types[$flag->link_type];
+
   return array(
-    'href' => 'flag/'. ($flag->link_type == 'confirm' ? 'confirm/' : '') ."$action/$flag->name/$content_id",
-    'query' => drupal_get_destination() . ($flag->link_type == 'confirm' ? '' : '&token='. $token),
+    'href' => $link['href'] . "/$action/$flag->name/$content_id",
+    'query' => drupal_get_destination() . ($link['token']  ? '&token=' . $token : ''),
+    'attributes' => $link['attributes'],
   );
 }
 
@@ -250,24 +255,31 @@ function flag_flag_link($flag, $action, $content_id) {
  * Implementation of hook_flag_link_types().
  */
 function flag_flag_link_types() {
-  return array(
-    'toggle' => array(
-      'title' => t('JavaScript toggle'),
-      'description' => t('An AJAX request will be made and degrades to type "Normal link" if JavaScript is not available.'),
-    ),
-    'normal' => array(
-      'title' => t('Normal link'),
-      'description' => t('A normal non-JavaScript request will be made and the current page will be reloaded.'),
-    ),
-    'confirm' => array(
-      'title' => t('Confirmation form'),
-      'description' => t('The user will be taken to a confirmation form on a separate page to confirm the flag.'),
-      'options' => array(
-        'flag_confirmation' => '',
-        'unflag_confirmation' => '',
-      ),
+  $items = array();
+
+  $items['toggle'] = array(
+    'title' => t('JavaScript toggle'),
+    'description' => t('An AJAX request will be made and degrades to type "Normal link" if JavaScript is not available.'),
+    'token' => TRUE,
+  );
+
+  $items['normal'] = array(
+    'title' => t('Normal link'),
+    'description' => t('A normal non-JavaScript request will be made and the current page will be reloaded.'),
+    'token' => TRUE,
+  );
+
+  $items['confirm'] = array(
+    'title' => t('Confirmation form'),
+    'description' => t('The user will be taken to a confirmation form on a separate page to confirm the flag.'),
+    'options' => array(
+      'flag_confirmation' => '',
+      'unflag_confirmation' => '',
     ),
+    'href' => 'flag/confirm',
   );
+
+  return $items;
 }
 
 /**
@@ -1096,7 +1108,10 @@ function template_preprocess_flag(&$variables) {
 
   // Generate the link URL.
   $link_type = $flag->get_link_type();
-  $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $content_id);
+  // Use the flag's own link generator, or a default one.
+  $func = function_exists($link_type['module'] . '_flag_link') ? $link_type['module'] . '_flag_link' : 'flag_flag_link';
+  $link = $func($flag, $action, $content_id);
+
   if (isset($link['title']) && empty($link['html'])) {
     $link['title'] = check_plain($link['title']);
   }
@@ -1109,14 +1124,43 @@ function template_preprocess_flag(&$variables) {
 
   // Tell the template file to add JavaScript/CSS if using the toggle link type.
   // Anonymous users always need the JavaScript to maintain their flag state.
+  // If a js callback is provided then load it here.
   if (($flag->link_type == 'toggle' || $user->uid == 0) && $first_time) {
+
+    $variables['flag_js_load'] = $link_type['css'];
     $variables['setup'] = $first_time;
     $first_time = FALSE;
   }
   else {
     $variables['setup'] = FALSE;
+
+    // Load the JS using the provided callback.
+    if (!empty($link_type['js callback file']) && file_exists($link_type['js callback file'])) {
+      include_once $link_type['js callback file'];
+    }
+    if (!empty($link_type['js callback']) && function_exists($link_type['js callback'])) {
+      call_user_func($link_type['js callback']);
+    }
+  }
+
+  $variables['flag_js_load'] = $variables['flag_css_load'] = '';
+
+  if ($variables['setup']) {
+    foreach (array('js', 'css') as $type) {
+        // Load the JS using the provided callback.
+      if (!empty($link_type[$type .' callback file']) && file_exists($link_type[$type .' callback file'])) {
+        include_once $link_type[$type .' callback file'];
+      }
+      if (!empty($link_type[$type . ' callback']) && function_exists($link_type[$type .' callback'])) {
+        call_user_func($link_type[$type . ' callback']);
+      }
+      else {
+        $variables['flag_' . $type . '_load'] = $link_type['js'];
+      }
+    }
   }
 
+
   $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE;
   $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $content_id);
   $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $content_id)));
@@ -1630,6 +1674,13 @@ function flag_get_link_types($reset = FALSE) {
           'title' => '',
           'description' => '',
           'options' => array(),
+          'href' => 'flag',
+          'token' => FALSE,
+          'attributes' => array(),
+          'js' => drupal_get_path('module', 'flag') .'/theme/flag.js',
+          'js callback' => FALSE,
+          'css'=> drupal_get_path('module', 'flag') .'/theme/flag.css',
+          'css callback' => FALSE,
         );
       }
     }
diff --git theme/flag.tpl.php theme/flag.tpl.php
index bef50ec..9bdceb2 100644
--- theme/flag.tpl.php
+++ theme/flag.tpl.php
@@ -12,6 +12,9 @@
  *   following variables don't suffice.
  * - $flag_name_css: The flag name, with all "_" replaced with "-". For use in 'class'
  *   attributes.
+ * - $flag_js_load: Optional; The path to the JS file that needs to be included.
+ * - $flag_css_load: Optional; The path to the CSS file that needs to be 
+ *   included.
  * - $flag_classes: A space-separated list of CSS classes that should be applied to the link.
  *
  * - $action: The action the link is about to carry out, either "flag" or "unflag".
@@ -35,10 +38,12 @@
  * advanced theming you may have to remove all the whitespace.
  */
 
-  if ($setup) {
-    drupal_add_css(drupal_get_path('module', 'flag') .'/theme/flag.css');
-    drupal_add_js(drupal_get_path('module', 'flag') .'/theme/flag.js');
+  if (!empty($flag_css_load)) {
+  	drupal_add_css($flag_css_load);
   }
+  if (!empty($flag_js_load)) {
+    drupal_add_js($flag_js_load);
+  }  
 ?>
 <span class="<?php print $flag_wrapper_classes; ?>">
   <?php if ($link_href): ?>
