Index: flag/flag.module
===================================================================
--- flag/flag.module	(revision 248)
+++ flag/flag.module	(working copy)
@@ -181,8 +181,8 @@ function flag_link($type, $object = NULL, $teaser
   }
   global $user;
 
-  // Anonymous users can't create flags with this system.
-  if (!$user || !$user->uid) {
+  // Anonymous users can't create flags without Session API module.
+  if (!module_exists('session_api') && (!$user || !$user->uid)) {
     return;
   }
 
@@ -251,7 +251,7 @@ function flag_form_alter($form_id, &$form) {
     }
   }
   elseif (($form_id == $form['type']['#value'] .'_node_form')) {
-    if (!$user || !$user->uid) {
+    if (!module_exists('session_api') && (!$user || !$user->uid)) {
       return;
     }
 
@@ -334,7 +334,7 @@ function flag_user($op, &$edit, &$account, $catego
   switch ($op) {
     case 'delete':
       // Remove flags by this user.
-      db_query("DELETE FROM {flag_content} WHERE uid = %d", $account->uid);
+      db_query("DELETE FROM {flag_content} WHERE uid = %d AND sid = %d", $account->uid, flag_get_sid($account));
   }
 }
 
@@ -536,14 +536,14 @@ function flag_form($name = NULL, $type = NULL) {
       '#collapsed' => TRUE,
     );
   }
-
+  $user_roles_available =  module_exists('session_api') ? "" : 1;
   $form['roles'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Roles that may use this flag'),
-    '#options' => user_roles(TRUE),
+    '#options' => user_roles($user_roles_available),
     '#default_value' => isset($flag) ? $flag->roles : array(2),
     '#required' => TRUE,
-    '#description' => t('Checking <em>authenticated user</em> will allow all logged-in users to flag content with this flag. Anonymous users may not flag content.'),
+    '#description' => t('Checking <em>authenticated user</em> will allow all logged-in users to flag content with this flag. You must install the <a href="http://drupal.org/project/session_api">Session API</a> module to enable flagging by <em>anonymous</em> users.'),
   );
 
   $form['global'] = array(
@@ -746,7 +746,7 @@ function flag_page($action = 'flag', $flag_name, $
 /**
  * Action for flagging or unflagging a piece of content.
  */
-function flag($action, $flag_name, $content_type, $content_id, $uid = NULL) {
+function flag($action, $flag_name, $content_type, $content_id, $uid = NULL, $sid = NULL) {
   if (!isset($uid)) {
     global $user;
     $account = $user;
@@ -755,8 +755,9 @@ function flag_page($action = 'flag', $flag_name, $
     $account = user_load(array('uid' => $uid));
   }
 
-  // Anonymous users can't create flags with this system.
-  if (!$account || !$account->uid) {
+  // ensure that session_api is available if its anonymous user.
+  if (!module_exists('session_api') && (!$account || !$account->uid)) {
+    drupal_set_message("You must login to execute that action.",'error');
     return FALSE;
   }
 
@@ -783,12 +784,13 @@ function flag_page($action = 'flag', $flag_name, $
 
   // Perform the flagging or unflagging of this flag.
   $uid = $flag->global ? 0 : $account->uid;
-  $flagged = db_result(db_query("SELECT fid FROM {flag_content} WHERE fid = %d AND uid = %d AND content_type = '%s' AND content_id = %d", $fid, $uid, $content_type, $content_id));
+  $sid = $flag->global ? 0 : flag_get_sid($account);
+  $flagged = db_result(db_query("SELECT fid FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d AND content_type = '%s' AND content_id = %d", $fid, $uid, $sid, $content_type, $content_id));
   if ($flagged && $action == 'unflag') {
-    db_query("DELETE FROM {flag_content} WHERE fid = %d AND uid = %d AND content_type = '%s' AND content_id = %d", $fid, $uid, $content_type, $content_id);
+    db_query("DELETE FROM {flag_content} WHERE fid = %d AND uid = %d AND sid = %d AND content_type = '%s' AND content_id = %d", $fid, $uid, $sid, $content_type, $content_id);
   }
   elseif (!$flagged && $action == 'flag') {
-    db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, timestamp) VALUES (%d, '%s', %d, %d, %d)", $fid, $content_type, $content_id, $uid, time());
+    db_query("INSERT INTO {flag_content} (fid, content_type, content_id, uid, sid, timestamp) VALUES (%d, '%s', %d, %d, %d, %d)", $fid, $content_type, $content_id, $uid, $sid, time());
   }
 
   // Update the flag count for this node.
@@ -800,10 +802,10 @@ function flag_page($action = 'flag', $flag_name, $
 
   // Let other modules perform actions.
   if ($flagged && $action == 'unflag') {
-    module_invoke_all('flag', 'unflag', $flag_name, $content_type, $content_id, $uid);
+    module_invoke_all('flag', 'unflag', $flag_name, $content_type, $content_id, $uid, $sid);
   }
   elseif (!$flagged && $action == 'flag') {
-    module_invoke_all('flag', 'flag', $flag_name, $content_type, $content_id, $uid);
+    module_invoke_all('flag', 'flag', $flag_name, $content_type, $content_id, $uid, $sid);
   }
   return TRUE;
 }
@@ -811,7 +813,7 @@ function flag_page($action = 'flag', $flag_name, $
 /**
  * Implementation of hook_flag(). Trigger actions if any are available.
  */
-function flag_flag($action, $flag_name, $content_type, $content_id, $uid) {
+function flag_flag($action, $flag_name, $content_type, $content_id, $uid, $sid = NULL) {
   if (module_exists('actions')) {
 
     // TODO: Create a real class for flag actions?
@@ -1128,6 +1130,9 @@ function flag_get_flags($content_type = NULL, $con
  * @param $uid
  *   Optional. The user ID whose flags we're checking. If none given, the
  *   current user will be used.
+ * @param $sid
+ *   Optional. The current session ID whose flags we're checking. If none given, the
+ *   current user will be used.
  * @param $reset
  *   Reset the internal cache and execute the SQL query another time.
  *
@@ -1139,32 +1144,39 @@ function flag_get_flags($content_type = NULL, $con
  *   [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;
 
   $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid;
+  if ($uid == 0) {
+    $sid = isset($sid) ? $sid : flag_get_sid();
+  }
+  else {
+    $sid = 0;
+  }
+
   $flags = flag_get_flags($content_type);
 
   if (isset($content_id)) {
-    if (!isset($flagged_content[$uid][$content_type][$content_id]) || $reset) {
-      $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);
+    if (!isset($flagged_content[$uid][$sid][$content_type][$content_id]) || $reset) {
+      $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 = db_fetch_object($result)) {
-        $flagged_content[$uid][$content_type][$content_id][$flags[$flag->fid]->name] = $flag;
+        $flagged_content[$uid][$sid][$content_type][$content_id][$flags[$flag->fid]->name] = $flag;
       }
     }
-    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]) || $reset) {
-      $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);
+    if (!isset($flagged_content[$uid][$sid]['all'][$content_type]) || $reset) {
+      $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 = db_fetch_object($result)) {
-        $flagged_content[$uid][$content_type]['all'][$flags[$flag->fid]->name] = $flag;
+        $flagged_content[$uid][$sid][$content_type]['all'][$flags[$flag->fid]->name] = $flag;
       }
     }
-    return $flagged_content[$uid][$content_type]['all'];
+    return $flagged_content[$uid][$sid][$content_type]['all'];
   }
 
 }
@@ -1186,3 +1198,30 @@ function flag_get_content_flags($content_type, $co
   return $content_flags[$content_type][$content_id]['users'];
 }
 
+/**
+ * Helper method integrates Session API with flags, for anonymous flagging.
+ *
+ * @param $user
+ *   Optional.  The user object for whom to get the Session API. If none 
+ *   specified will use the current user.
+ *
+ * @return $sid
+ *   The integer Session ID from Session API for the specified user. If no
+ *   user is specified, will use the session for the current website user.
+ *   NOTE: SID for flag usage is always 0 for logged in users, and always an
+ *   integer for anonymous users.
+ */
+function flag_get_sid(&$user = NULL) {
+  if (empty($user)) {
+    global $user;
+  }
+  if (!empty($user->uid)) {
+    if ($user->uid != 0) {
+      return 0;
+    }
+  }
+  if (module_exists('session_api')) {
+    return session_api_get_sid();
+  }
+  return 0;
+}
Index: flag/flag.views.inc
===================================================================
--- flag/flag.views.inc	(revision 248)
+++ flag/flag.views.inc	(working copy)
@@ -10,6 +10,7 @@
  * Implementation of hook_views_tables
  */
 function flag_views_tables() {
+  global $user;
   $flags = flag_get_flags();
   foreach ($flags as $flag) {
     // Localize the flag title:
@@ -172,7 +173,8 @@ function flag_views_tables() {
         ),
         'extra' => array(
           'fid' => $flag->fid,
-          'uid' => $flag->global ? 0 : '***CURRENT_USER***',
+          'uid' => $flag->global ? 0 : $user->uid,
+          'sid' => $flag->global ? 0 : flag_get_sid($user),
           // Note: since this is a LEFT JOIN, we also get records where
           // uid is empty; that is, nodes which haven't been flagged.
           // This is intentional, as we want to display the Ops field
@@ -236,13 +238,15 @@ function flag_query_handler_ops($field, $fieldinfo
  */
 function flag_filter_handler_uid($op, $filter, $filterinfo, &$query) {
   // Load the views flag to check if it's global.
+  global $user;
   $flag = flag_get_flag(NULL, $filterinfo['fid']);
 
   $tn = $query->add_table($filterinfo['table']);
   $tname = $query->get_table_name($filterinfo['table'], $tn);
   $query->add_where("$tname.uid $filter[operator] NULL");
   if ($filter['value'] == '***CURRENT_USER***' && !$flag->global) {
-    $query->add_where("$tname.uid = ***CURRENT_USER***");
+    $query->add_where("$tname.uid = %d", $user->uid);
+    $query->add_where("$tname.sid = %d", flag_get_sid());
   }
 }
 
@@ -388,6 +392,13 @@ function flag_views_default_views() {
         'options' => '',
         'value' => '***CURRENT_USER***',
       ),
+      array(
+        'tablename' => "flag_content_". $flag->name,
+        'field' => 'sid',
+        'operator' => 'IS NOT',
+        'options' => '',
+        'value' => flag_get_sid(),
+      ),
     );
     $view->requires = array('node', 'users');
 
Index: flag/flag.install
===================================================================
--- flag/flag.install	(revision 248)
+++ flag/flag.install	(working copy)
@@ -142,3 +142,25 @@ function flag_uninstall() {
   drupal_set_message(t('Flag has been uninstalled.'));
 }
 
+/**
+ * Adds support for Anonymous flagging using the sid from Session API.
+ */
+function flag_update_5001() {
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("ALTER TABLE {flag_content} ADD COLUMN sid int(10) unsigned NOT NULL default 0 AFTER uid");
+      $ret[] = update_sql("ALTER TABLE {flag_content} DROP PRIMARY KEY");
+      $ret[] = update_sql("ALTER TABLE {flag_content} ADD PRIMARY KEY (fid, content_type, content_id, uid, sid)");
+      $ret[] = update_sql("DROP INDEX {flag_content}_content_type_uid_idx ON {flag_content}");
+      $ret[] = update_sql("CREATE INDEX {flag_content}_content_type_uid_idx ON {flag_content} (content_type, uid, sid)");
+      $success = TRUE;
+      break;
+    case 'pgsql':
+      db_add_column($ret, 'flag_content', 'sid', 'int', array('default' => 0, 'not null' => TRUE, 'after' => 'uid'));
+      $ret[] = update_sql("DROP INDEX {flag_content}_content_type_uid_idx on {flag_content} RESTRICT");
+      $ret[] = update_sql("CREATE INDEX {flag_content}_content_type_uid_idx ON {flag_content} (content_type, uid, sid)");
+      break;
+  }
+  return $ret;
+}
