diff -urp /users/wmostrey/Desktop/flag.old/flag.inc flag/flag.inc
--- /users/wmostrey/Desktop/flag.old/flag.inc	2008-10-04 02:20:35.000000000 +0200
+++ flag/flag.inc	2008-10-08 15:38:53.000000000 +0200
@@ -649,8 +649,11 @@ class flag_flag {
   /**
    * Saves an existing flag to the database. Better use save().
    */
+  /**
+   * Saves an existing flag to the database. Better use save().
+   */
   function update() {
-    db_query("UPDATE {flags} SET name = '%s', title = '%s', flag_short = '%s', flag_long = '%s', flag_message = '%s', unflag_short = '%s', unflag_long = '%s', unflag_message = '%s', roles = '%s', global = %d, options = '%s' WHERE fid = %d", $this->name, $this->title, $this->flag_short, $this->flag_long, $this->flag_message, $this->unflag_short, $this->unflag_long, $this->unflag_message, implode(',', $this->roles), $this->global, $this->get_serialized_options(), $this->fid);
+    db_query("UPDATE {flags} SET name = '%s', title = '%s', flag_short = '%s', flag_long = '%s', flag_message = '%s', unflag_short = '%s', unflag_long = '%s', unflag_message = '%s', roles = '%s', global = %d, options = '%s', i18n = %d WHERE fid = %d", $this->name, $this->title, $this->flag_short, $this->flag_long, $this->flag_message, $this->unflag_short, $this->unflag_long, $this->unflag_message, implode(',', $this->roles), $this->global, $this->get_serialized_options(), $this->i18n, $this->fid);
     db_query("DELETE FROM {flag_types} WHERE fid = %d", $this->fid);
     foreach ($this->types as $type) {
       db_query("INSERT INTO {flag_types} (fid, type) VALUES (%d, '%s')", $this->fid, $type);
@@ -663,7 +666,7 @@ class flag_flag {
   function insert() {
     if (function_exists('db_last_insert_id')) {
       // Drupal 6. We have a 'serial' primary key.
-      db_query("INSERT INTO {flags} (content_type, name, title, flag_short, flag_long, flag_message, unflag_short, unflag_long, unflag_message, roles, global, options) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s')", $this->content_type, $this->name, $this->title, $this->flag_short, $this->flag_long, $this->flag_message, $this->unflag_short, $this->unflag_long, $this->unflag_message, implode(',', $this->roles), $this->global, $this->get_serialized_options());
+      db_query("INSERT INTO {flags} (content_type, name, title, flag_short, flag_long, flag_message, unflag_short, unflag_long, unflag_message, roles, global, options, i18n) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d)", $this->content_type, $this->name, $this->title, $this->flag_short, $this->flag_long, $this->flag_message, $this->unflag_short, $this->unflag_long, $this->unflag_message, implode(',', $this->roles), $this->global, $this->get_serialized_options(), $this->i18n);
       $this->fid = db_last_insert_id('flags', 'fid');
     }
     else {
diff -urp /users/wmostrey/Desktop/flag.old/flag.install flag/flag.install
--- /users/wmostrey/Desktop/flag.old/flag.install	2008-09-30 05:08:49.000000000 +0200
+++ flag/flag.install	2008-10-08 15:38:19.000000000 +0200
@@ -361,6 +361,17 @@ function flag_update_6000() {
   return $ret;
 }
 
+function flag_update_6001() {
+  $ret = array();
+  db_add_field($ret, 'flags', 'i18n', array(
+    'type' => 'int',
+     'size' => 'tiny',
+     'not null' => FALSE,
+     'default' => 0,
+    ));
+  return $ret;
+}
+
 // This is a replacement for update_sql(). The latter doesn't support placeholders.
 function _flag_update_sql($sql) {
   $args = func_get_args();
diff -urp /users/wmostrey/Desktop/flag.old/flag.module flag/flag.module
--- /users/wmostrey/Desktop/flag.old/flag.module	2008-10-03 17:32:07.000000000 +0200
+++ flag/flag.module	2008-10-08 15:44:43.000000000 +0200
@@ -239,6 +239,24 @@ function flag_form_alter(&$form, &$form_
 }
 
 /**
+* Return the node field to be used for flagging.
+*/
+function _flag_translation_get_field($flag) {
+  return $flag->i18n == 'source' ? 'tnid' : 'nid';
+}
+
+/**
+* Return the node ID field to be used for flagging.
+*
+* If the flag type is set to use the source translation for flagging, the {node}.tnid
+* value will be returned if set. Otherwise, the {node}.nid value will be returned.
+*/
+function _flag_translation_get_value($flag, $node) {
+  $field = _flag_translation_get_field($flag);
+  return (isset($node->$field) && !empty($node->$field)) ? $node->$field : $node->nid;
+}
+
+/**
  * Implementation of hook_nodeapi().
  */
 function flag_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
@@ -251,21 +269,22 @@ function flag_nodeapi(&$node, $op, $teas
       if (isset($node->flag)) {
         foreach ($node->flag as $name => $state) {
           $flag = flag_get_flag($name);
+          $id = _flag_translation_get_value($flag, $node);
           // Flagging may trigger actions. We want actions to get the current
           // node, not a stale database-loaded one:
           if (!$remembered) {
-            $flag->remember_content($node->nid, $node);
+            $flag->remember_content($id, $node);
             // Actions may modify a node, and we don't want to overwrite this
             // modification:
             $remembered = TRUE;
           }
-          flag($state ? 'flag' : 'unflag', $name, $node->nid);
+          flag($state ? 'flag' : 'unflag', $name, $id);
         }
       }
       break;
     case 'delete':
-      db_query("DELETE FROM {flag_content} WHERE content_type = 'node' AND content_id = %d", $node->nid);
-      db_query("DELETE FROM {flag_counts} WHERE content_type = 'node' AND content_id = %d", $node->nid);
+      db_query("DELETE FROM {flag_content} WHERE content_type = 'node' AND content_id = %d", $id);
+      db_query("DELETE FROM {flag_counts} WHERE content_type = 'node' AND content_id = %d", $id);
       break;
   }
 }
@@ -337,6 +356,7 @@ function flag_admin_page() {
       empty($flag->roles) ? '<em>' . t('No roles') . '</em>' : implode(', ', $roles),
       $flag->types ? implode(', ', $flag->types) : '-',
       $flag->global ? t('Yes') : t('No'),
+      $flag->i18n ? t('Yes') : t('No'),
       $ops,
     );
   }
@@ -346,7 +366,7 @@ function flag_admin_page() {
     );
   }
 
-  $output .= theme('table', array(t('Flag'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')), $rows);
+  $output .= theme('table', array(t('Flag'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Internationzalized?'), t('Operations')), $rows);
 
   if (!module_exists('views')) {
     $output .= '<p>' . t('The <a href="@views-url">Views</a> module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '</p>';
