Index: includes/flag_handler_relationships.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/includes/Attic/flag_handler_relationships.inc,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 flag_handler_relationships.inc
--- includes/flag_handler_relationships.inc	26 Apr 2009 21:35:12 -0000	1.1.2.9
+++ includes/flag_handler_relationships.inc	28 Sep 2009 06:42:36 -0000
@@ -43,11 +43,16 @@
     if (!$form['flag']['#options']) {
       $form = array(
         'error' => array(
-          '#value' => '<p class="error">' . t('No %type flags exist. You must first <a href="@create-url">create a %type flag</a> before being able to use this relationship type.', array('%type' => $content_type, '@create-url' => url('admin/build/flags'))) . '</p>',
+          '#value' => '<p class="error form-item">' . t('No %type flags exist. You must first <a href="@create-url">create a %type flag</a> before being able to use this relationship type.', array('%type' => $content_type, '@create-url' => url('admin/build/flags'))) . '</p>',
         ),
       );
       $form_state['no flags exist'] = TRUE;
     }
+    if (module_exists('session_api')) {
+      $form['session_warning'] = array(
+        '#value' => '<p class="warning form-item">' . t('<strong>Warning</strong>: Adding this relationship for any flag that contains <strong>anonymous flagging access</strong> will disable page caching for anonymous users when this view is executed. It is recommended to create a dedicated page for views containing anonymous user data.', array('%type' => $content_type, '@create-url' => url('admin/build/flags'))) . '</p>',
+      );
+    }
   }
 
   function options_validate($form, &$form_state) {
@@ -81,6 +86,17 @@
         'value' => '***CURRENT_USER***',
         'numeric' => TRUE,
       );
+      if (array_search(DRUPAL_ANONYMOUS_RID, $flag->roles['flag']) !== FALSE) {
+        // Disable page caching for anonymous users.
+        $GLOBALS['conf']['cache'] = CACHE_DISABLED;
+
+        // Add in the SID from Session API for anonymous users.
+        $this->definition['extra'][] = array(
+          'field' => 'sid',
+          'value' => flag_get_sid(),
+          'numeric' => TRUE,
+        );
+      }
     }
     parent::query();
   }
Index: includes/flag.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/includes/Attic/flag.admin.inc,v
retrieving revision 1.1.4.2.2.6
diff -u -r1.1.4.2.2.6 flag.admin.inc
--- includes/flag.admin.inc	28 Sep 2009 02:05:06 -0000	1.1.4.2.2.6
+++ includes/flag.admin.inc	28 Sep 2009 06:42:36 -0000
@@ -324,19 +324,26 @@
   $form['access']['roles'] = array(
     '#title' => t('Roles that may use this flag'),
     '#access' => empty($flag->locked['roles']),
-    '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking <em>authenticated user</em> will allow access for all logged-in users. Anonymous users may not flag content.'),
+    '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking <em>authenticated user</em> will allow access for all logged-in users.'),
     '#theme' => 'flag_form_roles',
     '#weight' => -2,
   );
+  if (module_exists('session_api')) {
+    $form['access']['roles']['#description'] .= ' ' . t('Support for anonymous users is being provided by <a href="http://drupal.org/project/session_api">Session API</a>.');
+  }
+  else {
+    $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the <a href="http://drupal.org/project/session_api">Session API</a> module is installed.');
+  }
+
   $form['access']['roles']['flag'] = array(
     '#type' => 'checkboxes',
-    '#options' => user_roles(TRUE),
+    '#options' => user_roles(!module_exists('session_api')),
     '#default_value' => $flag->roles['flag'],
     '#parents' => array('roles', 'flag'),
   );
   $form['access']['roles']['unflag'] = array(
     '#type' => 'checkboxes',
-    '#options' => user_roles(TRUE),
+    '#options' => user_roles(!module_exists('session_api')),
     '#default_value' => $flag->roles['unflag'],
     '#parents' => array('roles', 'unflag'),
   );
Index: includes/flag_handler_field_ops.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/includes/Attic/flag_handler_field_ops.inc,v
retrieving revision 1.1.2.5.2.1
diff -u -r1.1.2.5.2.1 flag_handler_field_ops.inc
--- includes/flag_handler_field_ops.inc	14 Sep 2009 11:46:40 -0000	1.1.2.5.2.1
+++ includes/flag_handler_field_ops.inc	28 Sep 2009 06:42:36 -0000
@@ -81,6 +81,11 @@
         'value' => '***CURRENT_USER***',
         'numeric' => TRUE,
       );
+      $join->extra[] = array(
+        'field' => 'sid',
+        'value' => flag_get_sid(),
+        'numeric' => TRUE,
+      );
     }
     $flag_table = $this->query->add_table('flag_content', $parent, $join);
     $this->aliases['is_flagged'] = $this->query->add_field($flag_table, 'content_id');
Index: flag.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.install,v
retrieving revision 1.2.2.32.2.2
diff -u -r1.2.2.32.2.2 flag.install
--- flag.install	28 Sep 2009 02:05:06 -0000	1.2.2.32.2.2
+++ flag.install	28 Sep 2009 06:42:35 -0000
@@ -80,17 +80,44 @@
   $t = get_t();
   if ($phase == 'install') {
     if (!defined('MAINTENANCE_MODE') && _flag_flag_content_installed()) {
-      $requirements['flag_content_clash']['title'] = $t('Flag');
-      $requirements['flag_content_clash']['severity'] = REQUIREMENT_ERROR;
-      $requirements['flag_content_clash']['description'] = _flag_flag_content_message();
+      $requirements['flag_content_clash'] = array(
+        'title' => $t('Flag'),
+        'severity' => REQUIREMENT_ERROR,
+        'description' => _flag_flag_content_message(),
+      );
     }
   }
 
-  if ($phase == 'runtime' && module_exists('translation') && !module_exists('translation_helpers')) {
-    $requirements['flag_translation']['title'] = $t('Flag');
-    $requirements['flag_translation']['severity'] = REQUIREMENT_ERROR;
-    $requirements['flag_translation']['description'] = $t('To have the flag module work with translations, you need to install and enable the <a href="http://drupal.org/project/translation_helpers">Translation helpers</a> module.');
-    $requirements['flag_translation']['value'] = $t('Translation helpers module not found.');
+  if ($phase == 'runtime') {
+    if (module_exists('translation') && !module_exists('translation_helpers')) {
+      $requirements['flag_translation'] = array(
+        'title' => $t('Flag'),
+        'severity' => REQUIREMENT_ERROR,
+        'description' => $t('To have the flag module work with translations, you need to install and enable the <a href="http://drupal.org/project/translation_helpers">Translation helpers</a> module.'),
+        'value' => $t('Translation helpers module not found.'),
+      );
+    }
+    if (module_exists('session_api')) {
+      $flag_path = url('flag') . '/';
+      $robots_string = 'Disallow: ' . $flag_path;
+      if (file_exists('./robots.txt')) {
+        $contents = file_get_contents('./robots.txt');
+        if (strpos($contents, $robots_string) === FALSE) {
+          $robots_error = TRUE;
+        }
+      }
+      else {
+        $robots_error = TRUE;
+      }
+      if ($robots_error) {
+        $requirements['flag_robots'] = array(
+          'title' => $t('Flag robots.txt problem'),
+          'severity' => REQUIREMENT_WARNING,
+          'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exlude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)),
+          'value' => $t('Search engines flagging content'),
+        );
+      }
+    }
   }
   return $requirements;
 }
@@ -196,6 +223,12 @@
         'not null' => TRUE,
         'default' => 0,
       ),
+      'sid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'timestamp' => array(
         'type' => 'int',
         'unsigned' => TRUE,
@@ -206,11 +239,11 @@
     ),
     'primary key' => array('fcid'),
     'unique keys' => array(
-      'fid_content_type_content_id_uid' => array('fid', 'content_type', 'content_id', 'uid'),
+      'fid_content_type_content_id_uid_sid' => array('fid', 'content_type', 'content_id', 'uid', 'sid'),
     ),
     'indexes' => array(
       'content_type_content_id' => array('content_type', 'content_id'),
-      'content_type_uid' => array('content_type', 'uid'),
+      'content_type_uid_sid' => array('content_type', 'uid', 'sid'),
     ),
   );
 
@@ -476,6 +509,26 @@
   return $ret;
 }
 
+/**
+ * Add the sid column and unique index on the flag_content table.
+ */
+function flag_update_6201() {
+  $ret = array();
+
+  // Drop the keys affected by the addition of the SID column.
+  db_drop_unique_key($ret, 'flag_content', 'fid_content_type_content_id_uid');
+  db_drop_index($ret, 'flag_content', 'content_type_uid');
+
+  // Add the column.
+  db_add_field($ret, 'flag_content', 'sid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+
+  // Re-add the removed keys.
+  db_add_unique_key($ret, 'flag_content', 'fid_content_type_content_id_uid_sid', array('fid', 'content_type', 'content_id', 'uid', 'sid'));
+  db_add_index($ret, 'flag_content', 'content_type_uid_sid', array('content_type', 'uid', 'sid'));
+
+  return $ret;
+}
+
 // This is a replacement for update_sql(). The latter doesn't support placeholders.
 function _flag_update_sql($sql) {
   $args = func_get_args();
Index: flag.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.module,v
retrieving revision 1.11.2.72.2.13
diff -u -r1.11.2.72.2.13 flag.module
--- flag.module	28 Sep 2009 02:05:06 -0000	1.11.2.72.2.13
+++ flag.module	28 Sep 2009 06:42:36 -0000
@@ -88,6 +88,10 @@
   if (module_exists('token')) {
     include_once $path .'/includes/flag.token.inc';
   }
+  if (module_exists('session_api')) {
+    // Set the anonymous user SID immediately, in case the user logs in.
+    flag_set_sid();
+  }
 }
 
 /**
@@ -280,14 +284,8 @@
       );
     }
   }
-  elseif (isset($form['type']) && isset($form['#node'])
-      && ($form_id == $form['type']['#value'] .'_node_form')) {
-    if (!$user->uid) {
-      return;
-    }
-
+  elseif (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] .'_node_form')) {
     $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL;
-
     $flags = flag_get_flags('node', $form['type']['#value'], $user);
 
     // Filter out flags which need to be included on the node form.
@@ -407,6 +405,16 @@
  */
 function flag_user($op, &$edit, &$account, $category = NULL) {
   switch ($op) {
+    case 'login':
+      // Migrate anonymous flags to this user's account.
+      if (module_exists('session_api')) {
+        // The @ symbol suppresses errors if the user flags a piece of content
+        // they have already flagged as a logged-in user.
+        @db_query("UPDATE {flag_content} SET uid = %d, sid = 0 WHERE uid = 0 AND sid = %d", $account->uid, flag_get_sid(0));
+        // Delete any remaining flags this user had as an anonymous user.
+        db_query("DELETE FROM {flag_content} WHERE uid = 0 AND sid = %d", flag_get_sid());
+      }
+      break;
     case 'delete':
       // Remove flags by this user.
       $result = db_query("SELECT fc.fid, fc.content_id, c.count FROM {flag_content} fc LEFT JOIN {flag_counts} c ON fc.content_id = c.content_id AND fc.content_type = c.content_type WHERE fc.uid = %d", $account->uid);
@@ -448,6 +456,26 @@
 }
 
 /**
+ * Implementation of hook_session_api_cleanup().
+ *
+ * Clear out anonymous user flaggings during Session API cleanup.
+ */
+function flag_session_api_cleanup($arg = 'run') {
+  // Session API 1.1 version:
+  if ($arg == 'run') {
+    $result = db_query("SELECT fc.sid FROM {flag_content} fc LEFT JOIN {session_api} s ON (fc.sid = s.sid) WHERE fc.sid <> 0 AND s.sid IS NULL");
+    while ($row = db_fetch_object($result)) {
+      db_query("DELETE FROM {flag_content} WHERE sid = %d", $row->sid);
+    }
+  }
+  // Session API 1.2+ version.
+  elseif (is_array($arg)) {
+    $outdated_sids = $arg;
+    db_query('DELETE FROM {flag_content} WHERE sid IN (' . implode(',', $outdated_sids) . ')');
+  }
+}
+
+/**
  * Implementation of hook_node_type().
  */
 function flag_node_type($op, $info) {
@@ -635,10 +663,10 @@
     $result = db_query("SELECT nid, uid FROM {node} WHERE nid IN ($nids) AND type in ($placeholders)", $flag->types);
     while ($row = db_fetch_object($result)) {
       if ($flag->access_author == 'own') {
-        $passed[$row->nid] = $row->uid != $account->uid ? FALSE : $passed[$row->nid];
+        $passed[$row->nid] = $row->uid != $account->uid ? FALSE : NULL;
       }
       elseif ($flag->access_author == 'others') {
-        $passed[$row->nid] = $row->uid == $account->uid ? FALSE : $passed[$row->nid];
+        $passed[$row->nid] = $row->uid == $account->uid ? FALSE : NULL;
       }
     }
     return $passed;
@@ -1159,6 +1187,9 @@
  * @param $uid
  *   Optional. The user ID whose flags we're checking. If none given, the
  *   current user will be used.
+ * @param $sid
+ *   Optional. The user SID (proved by Session API) whose flags we're checking.
+ *   If none given, the current user will be used. SID is 0 for logged in users.
  * @param $reset
  *   Reset the internal cache and execute the SQL query another time.
  *
@@ -1170,7 +1201,7 @@
  *   [nid] => [name] => Object from above.
  *
  */
-function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $reset = FALSE) {
+function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) {
   static $flagged_content;
 
   if ($reset) {
@@ -1181,29 +1212,30 @@
   }
 
   $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid;
+  $sid = !isset($sid) ? flag_get_sid($uid) : $sid;
 
   if (isset($content_id)) {
     if (!isset($flagged_content[$uid][$content_type][$content_id])) {
       $flag_names = _flag_get_flag_names();
-      $flagged_content[$uid][$content_type][$content_id] = array();
-      $result = db_query("SELECT * FROM {flag_content} WHERE content_type = '%s' AND content_id = %d AND (uid = %d OR uid = 0)", $content_type, $content_id, $uid);
+      $flagged_content[$uid][$sid][$content_type][$content_id] = array();
+      $result = db_query("SELECT * FROM {flag_content} WHERE content_type = '%s' AND content_id = %d AND (uid = %d OR uid = 0) AND sid = %s", $content_type, $content_id, $uid, $sid);
       while ($flag_content = db_fetch_object($result)) {
-        $flagged_content[$uid][$content_type][$content_id][$flag_names[$flag_content->fid]] = $flag_content;
+        $flagged_content[$uid][$sid][$content_type][$content_id][$flag_names[$flag_content->fid]] = $flag_content;
       }
     }
-    return $flagged_content[$uid][$content_type][$content_id];
+    return $flagged_content[$uid][$sid][$content_type][$content_id];
   }
 
   else {
-    if (!isset($flagged_content[$uid]['all'][$content_type])) {
+    if (!isset($flagged_content[$uid][$sid]['all'][$content_type])) {
       $flag_names = _flag_get_flag_names();
-      $flagged_content[$uid]['all'][$content_type] = TRUE;
-      $result = db_query("SELECT * FROM {flag_content} WHERE content_type = '%s' AND (uid = %d OR uid = 0)", $content_type, $uid);
+      $flagged_content[$uid][$sid]['all'][$content_type] = TRUE;
+      $result = db_query("SELECT * FROM {flag_content} WHERE content_type = '%s' AND (uid = %d OR uid = 0) AND sid = %s", $content_type, $uid, $sid);
       while ($flag_content = db_fetch_object($result)) {
-        $flagged_content[$uid][$content_type]['all'][$flag_names[$flag_content->fid]][$flag_content->content_id] = $flag_content;
+        $flagged_content[$uid][$sid][$content_type]['all'][$flag_names[$flag_content->fid]][$flag_content->content_id] = $flag_content;
       }
     }
-    return $flagged_content[$uid][$content_type]['all'];
+    return $flagged_content[$uid][$sid][$content_type]['all'];
   }
 
 }
@@ -1298,13 +1330,47 @@
 /**
  * Get a private token used to protect links from spoofing - CSRF.
  */
-function flag_get_token($nid) {
-  return drupal_get_token($nid);
+function flag_get_token($content_id) {
+  // Anonymous users get a less secure token, since it must be the same for all
+  // anonymous users on the entire site to work with page caching.
+  return ($GLOBALS['user']->uid) ? drupal_get_token($content_id) : md5(drupal_get_private_key() . $content_id);
 }
 
 /**
  * Check to see if a token value matches the specified node.
  */
-function flag_check_token($token, $seed) {
-  return drupal_get_token($seed) == $token;
+function flag_check_token($token, $content_id) {
+  return flag_get_token($content_id) == $token;
+}
+
+/**
+ * Set the Session ID for a user. Utilizes the Session API module.
+ *
+ * This function is only called in flag_init(), to set the current user's
+ * SID in case the user logs in during this request.
+ */
+function flag_set_sid($uid = NULL) {
+  static $sids = array();
+
+  if (!isset($uid)) {
+    $uid = $GLOBALS['user']->uid;
+  }
+
+  if (!isset($sids[$uid])) {
+    if (module_exists('session_api') && session_api_available() && $uid == 0) {
+      $sids[$uid] = session_api_get_sid();
+    }
+    else {
+      $sids[$uid] = 0;
+    }
+  }
+
+  return $sids[$uid];
+}
+
+/**
+ * Get the Session ID for a user. Utilizes the Session API module.
+ */
+function flag_get_sid($uid = NULL) {
+  return flag_set_sid($uid);
 }
Index: flag.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.inc,v
retrieving revision 1.1.2.30.2.10
diff -u -r1.1.2.30.2.10 flag.inc
--- flag.inc	28 Sep 2009 03:39:13 -0000	1.1.2.30.2.10
+++ flag.inc	28 Sep 2009 06:42:35 -0000
@@ -399,13 +399,13 @@
       $account = $GLOBALS['user'];
     }
 
-    // Anonymous user can't use this system. For now.
-    if ($account->uid == 0) {
+    // Anonymous user can't use this system unless Session API is installed.
+    if ($account->uid == 0 && !module_exists('session_api')) {
       return FALSE;
     }
 
     $matched_roles = array_intersect($this->roles[$action], array_keys($account->roles));
-    return !empty($matched_roles) || !empty($this->roles[$action]) || $account->uid == 1;
+    return (bool) $matched_roles || $account->uid == 1;
   }
 
   /**
@@ -431,7 +431,9 @@
     }
 
     if (!isset($action)) {
-      $action = $this->is_flagged($content_id, $account->uid) ? 'unflag' : 'flag';
+      $uid = $account->uid;
+      $sid = flag_get_sid($uid);
+      $action = $this->is_flagged($content_id, $uid, $sid) ? 'unflag' : 'flag';
     }
 
     // Base initial access on the user's basic permission to use this flag.
@@ -546,18 +548,19 @@
     // Clear various caches; We don't want code running after us to report
     // wrong counts or false flaggings.
     flag_get_counts(NULL, NULL, TRUE);
-    flag_get_user_flags(NULL, NULL, NULL, TRUE);
+    flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE);
 
     // Perform the flagging or unflagging of this flag.
     $uid = $this->global ? 0 : $account->uid;
-    $flagged = $this->_is_flagged($content_id, $uid);
+    $sid = $this->global ? 0 : flag_get_sid($uid);
+    $flagged = $this->_is_flagged($content_id, $uid, $sid);
     if ($action == 'unflag' && $flagged) {
-      $fcid = $this->_unflag($content_id, $uid);
+      $fcid = $this->_unflag($content_id, $uid, $sid);
       // Let other modules perform actions.
       module_invoke_all('flag', 'unflag', $this, $content_id, $account, $fcid);
     }
     elseif ($action == 'flag' && !$flagged) {
-      $fcid = $this->_flag($content_id, $uid);
+      $fcid = $this->_flag($content_id, $uid, $sid);
       // Let other modules perform actions.
       module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid);
     }
@@ -575,10 +578,12 @@
    *   Optional. The user ID whose flags we're checking. If none given, the
    *   current user will be used.
    */
-  function is_flagged($content_id, $uid = NULL) {
-    $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid;
+  function is_flagged($content_id, $uid = NULL, $sid = NULL) {
+    $uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid);
+    $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid);
+
     // flag_get_user_flags() does caching.
-    $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid);
+    $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid, $sid);
     return isset($user_flags[$this->name]);
   }
 
@@ -594,8 +599,8 @@
    *
    * @private
    */
-  function _is_flagged($content_id, $uid) {
-    return db_result(db_query("SELECT fid FROM {flag_content} WHERE fid = %d AND uid = %d AND content_id = %d", $this->fid, $uid, $content_id));
+  function _is_flagged($content_id, $uid, $sid) { 
+    return db_result(db_query("SELECT fid FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d AND content_id = %d", $this->fid, $uid, $sid, $content_id));
   }
 
   /**
@@ -606,8 +611,8 @@
    *
    * @private
    */
-  function _flag($content_id, $uid) {
-    db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, timestamp) VALUES (%d, '%s', %d, %d, %d)", $this->fid, $this->content_type, $content_id, $uid, time());
+  function _flag($content_id, $uid, $sid) {
+    db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, sid, timestamp) VALUES (%d, '%s', %d, %d, %d, %d)", $this->fid, $this->content_type, $content_id, $uid, $sid, time());
     $fcid = db_last_insert_id('flag_content', 'fcid');
     $this->_update_count($content_id);
     return $fcid;
@@ -621,8 +626,8 @@
    *
    * @private
    */
-  function _unflag($content_id, $uid) {
-    $fcid = db_result(db_query("SELECT fcid FROM {flag_content} WHERE fid = %d AND uid = %d AND content_id = %d", $this->fid, $uid, $content_id));
+  function _unflag($content_id, $uid, $sid) {
+    $fcid = db_result(db_query("SELECT fcid FROM {flag_content} WHERE fid = %d AND content_id = %d AND uid = %d AND sid = %d", $this->fid, $content_id, $uid, $sid));
     if ($fcid) {
       db_query("DELETE FROM {flag_content} WHERE fcid = %d", $fcid);
       $this->_update_count($content_id);
@@ -657,10 +662,10 @@
   /**
    * Returns the number of items a user has flagged.
    *
-   * For global flags, pass '0' as the user ID.
+   * For global flags, pass '0' as the user ID and session ID.
    */
-  function get_user_count($uid) {
-    return db_result(db_query('SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND uid = %d', $this->fid, $uid));
+  function get_user_count($uid, $sid) {
+    return db_result(db_query('SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d', $this->fid, $uid, $sid));
   }
 
   /**
@@ -1070,10 +1075,9 @@
     return parent::flag($action, $content_id, $account, $skip_permission_check);
   }
 
-
-  function is_flagged($content_id, $uid = NULL) {
+  function is_flagged($content_id, $uid = NULL, $sid = NULL) {
     $content_id = $this->get_translation_id($content_id);
-    return parent::is_flagged($content_id, $uid);
+    return parent::is_flagged($content_id, $uid, $sid);
   }
 
   function get_labels_token_types() {
@@ -1423,7 +1427,6 @@
 function _flag_is_drupal_5() {
   return !function_exists('theme_get_registry');
 }
-
 // That's ugly, but duplicating this logic is uglier.
 function _flag_url($path, $fragment = NULL, $absolute = TRUE) {
   return _flag_is_drupal_5()
Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/README.txt,v
retrieving revision 1.1.4.6
diff -u -r1.1.4.6 README.txt
--- README.txt	7 Oct 2008 16:41:26 -0000	1.1.4.6
+++ README.txt	28 Sep 2009 06:42:35 -0000
@@ -45,15 +45,15 @@
 provides many views filters, fields, and sort criteria to make all sorts of
 displays possible relating to the number of times an item has been flagged.
 
-This module was formerly known as Views Bookmark.
+This module was formerly known as Views Bookmark, which was originally was
+written by Earl Miles. Flag was written by Nathan Haug and mystery man Mooffie.
 
-Ongoing development by Nathan Haug and mystery man Mooffie.
-
-Originally written by Earl Miles.
+This module built by robots: http://www.lullabot.com
 
 Recommended Modules
 -------------------
 - Views
+- Session API
 
 Installation
 ------------
@@ -61,6 +61,11 @@
 
 2) Enable the module using Administer -> Modules (/admin/build/modules)
 
+Optional Installation
+---------------------
+1) The ability for anonymous users to flag content is provided by the Session
+   API module, available at http://drupal.org/project/session_api.
+
 Configuration
 -------------
 The configuration for Flag is spread between Views configuration
