diff --git a/flag_anon.info b/flag_anon.info
index eeb1a46..19b1a5f 100644
--- a/flag_anon.info
+++ b/flag_anon.info
@@ -1,6 +1,8 @@
 name = Flag anonymous
-description = Provide some display for anon users. It is compatible with Flag 6.x-2.x and upwards, it will not work with Flag 6.x-1.x!
-core = 6.x
+description = Provide a flag display for anonymous users. It is compatible with Flag 7.x-2.x, or better.
+core = 7.x
 dependencies[] = flag
 
 package = Flags
+
+
diff --git a/flag_anon.module b/flag_anon.module
index 3ac5d89..aa377ab 100644
--- a/flag_anon.module
+++ b/flag_anon.module
@@ -1,5 +1,15 @@
 <?php
-
+/**
+ * @file
+ *
+ * Work around flags access handling to allow a message to be shown for anonymous users.
+ *
+ * The module overwrites access to the flag when no action is present in the access check,
+ * this allows us to show the link in views for example. The output is then reset in a preprocess call.
+ *
+ * Since flag module performs a more complex access check in its hook_link implementation this module
+ * provides an alternative hook_link.
+ */
 
 /**
  * Implementation of hook_form_alter().
@@ -22,8 +32,20 @@ function flag_anon_form_alter(&$form, $form_state, $form_id) {
       '#type' => 'textfield',
       '#title' => t('Anonymous link text'),
       '#default_value' => isset($form['#flag']->anon_message) ? $form['#flag']->anon_message : '',
-      '#description' => t('The text displayed when anonymous user views the flag.'),
+      '#description' => t('The text displayed when anonymous user views the flag. For example, "Please [login] to bookmark this post". Use [login] for the login link and [register] for the registration link. Alternatively, use [login-url] and [register-url] for the URLs alone. HTML is allowed.'),
     );
+    $form['#validate'][] = 'flag_anon_flag_form_validate';
+  }
+}
+
+function flag_anon_flag_form_validate($form, &$form_state) {
+  if ($form_state['values']['anon_display']) {
+    if (!empty($form_state['values']['roles']['flag'][DRUPAL_ANONYMOUS_RID])) {
+      form_set_error('anon_display', t("You chose to display a login link for anonymous users, but you also allow anonymous users to use this flag. They don't need to log in to use it."));
+    }
+    elseif (empty($form_state['values']['anon_message'])) {
+      form_set_error('anon_message', t('You must type some text for the anonymous link if you want to display it.'));
+    }
   }
 }
 
@@ -37,22 +59,41 @@ function flag_anon_flag_options_alter(&$options, $flag) {
 }
 
 /**
- * Implementation of hook_link().
+ * Implements hook_flag_access_multiple().
+ *
+ * Grant access to the flag is the user is anonymous. We do this to allow the flag to show
+ * up in Views. We don't really grant access though, flagging action access is determined
+ * via the hook_flag_access which we don't grant.
+ */
+function flag_anon_flag_access_multiple($flag, $content_ids, $account) {
+  if ($flag->anon_display && $account->uid == 0) {
+    foreach ($content_ids as $id => $action) {
+      $access[$id] = TRUE;
+    }
+    return $access;
+  }
+  else {
+    return array();
+  }
+}
+
+/**
+ * Implements hook_link().
+ *
+ * This hook does not exist in Drupal 7, it is called from flag_anon_node_view() and
+ * flag_anon_comment_view() functions.
  */
 function flag_anon_link($type, $object = NULL, $teaser = FALSE) {
-  if (!isset($object) || !flag_fetch_definition($type)) {
+  if (!isset($object) || !flag_fetch_definition('node')) {
     return;
   }
   global $user;
-
   // We only take care of anonymous users.
   if ($user->uid) {
     return;
   }
-
   // Get all possible flags for this content-type.
   $flags = flag_get_flags($type);
-
   foreach ($flags as $flag) {
     if (!$flag->anon_display) {
       // Flag is configured to show for anonymous.
@@ -66,23 +107,137 @@ function flag_anon_link($type, $object = NULL, $teaser = FALSE) {
       // Flag does not apply to this content.
       continue;
     }
-
-    $destination = drupal_get_destination();
-    $links['flag-'. $flag->name] = array(
-      'title' => t($flag->anon_message,
-        array(
-          '!login' => l(t('login'), 'user/login', array(
-            'query' => $destination,
-          )),
-          '!register' => l(t('register'), 'user/register', array(
-            'query' => $destination,
-          ))
-        )),
+    $content_id = $flag->get_content_id($object);
+    $links['flag-anon-'. $flag->name] = array(
+      'title' => $flag->theme('flag', $content_id),
       'html' => TRUE,
     );
   }
-
   if (isset($links)) {
     return $links;
   }
 }
+
+/**
+ * Implements hook_node_view().
+ */
+function flag_anon_node_view($node, $view_mode, $langcode) {
+  $links = flag_anon_link('node', $node, $view_mode == 'teaser');
+  $node->content['links']['flag'] = array(
+    '#theme' => 'links__node__flag',
+    '#links' => $links,
+    '#attributes' => array('class' => array('links', 'inline')),
+  );
+}
+
+/**
+ * Implements hook_comment_view().
+ */
+function flag_anon_comment_view($comment) {
+  $links = flag_anon_link('comment', $comment);
+  $comment->content['links']['flag'] = array(
+    '#theme' => 'links',
+    '#links' => $links,
+    '#attributes' => array('class' => array('links', 'inline')),
+  );
+}
+
+/**
+ * Implements hook_user_view().
+ */
+function flag_anon_user_view($account, $view_mode) {
+  $flags = flag_get_flags('user');
+  $flag_items = array();
+  foreach ($flags as $flag) {
+    if (!$flag->show_on_profile) {
+      // User has no permission to use this flag.
+      continue;
+    }
+    if (!$flag->uses_hook_link(array())){
+      // Flag not set to appear on profile.
+      continue;
+    }
+    $flag_items[$flag->name] = array(
+      '#type' => 'user_profile_item',
+      '#title' => $flag->get_title($account->uid),
+      '#markup' => $flag->theme('flag', $account->uid),
+      '#attributes' => array('class' => array('flag-profile-' . $flag->name)),
+    );
+  }
+  if (!empty($flag_items)) {
+    $account->content['flags'] = $flag_items;
+    $account->content['flags'] += array(
+      '#type' => 'user_profile_category',
+      '#title' => t('Actions'),
+      '#attributes' => array('class' => array('flag-profile')),
+    );
+  }
+}
+
+/**
+ * A utility function for outputting a flag link.
+ *
+ * You should call this function from your template when you want to put the
+ * link on the page yourself. For example, you could call this function from
+ * your 'node.tpl.php':
+ *
+ *   <?php print flag_anon_create_link('bookmarks', $node->nid); ?>
+ *
+ * @param $flag_name
+ *   The "machine readable" name of the flag; e.g. 'bookmarks'.
+ * @param $content_id
+ *   The content ID to check for flagging. This is usually a node ID.
+ */
+function flag_anon_create_link($flag_name, $content_id) {
+  global $user;
+  // In case of authenticated user we fall back to the core create link function.
+  if ($user->uid) {
+    return flag_create_link($flag_name, $content_id);
+  }
+  else {
+    $flag = flag_get_flag($flag_name);
+    if (!$flag) {
+      // Flag does not exist.
+      return;
+    }
+    return $flag->theme('flag', $content_id);
+  }
+}
+
+/**
+ * Since we overwrote the access handling we must overwrite the output as well, to actually respect the real settings.
+ */
+function flag_anon_preprocess_flag(&$variables) {
+  $flag =& $variables['flag'];
+  $action = $variables['action'];
+  $content_id = $variables['content_id'];
+  // We don't need to check for anonymous users having actual access to this flag, since
+  // we excluded that option in the flag configuration validation stage.
+  if ($GLOBALS['user']->uid == 0) {
+    $variables['link_href']= '';
+    $link = _flag_anon_link($flag, $content_id);
+    $variables['link_text'] = $link['title'];
+  }
+}
+
+/**
+ * Helper function to return just the message so that themes can use this.
+ */
+function _flag_anon_link($flag, $content_id) {
+  $link_options = array(
+    'query' => drupal_get_destination(),
+  );
+  $tokens = array(
+    '[login]' => l(t('login'), 'user/login', $link_options),
+    '[login-url]' => check_url(url('user/login', $link_options)),
+    '[register]' => l(t('register'), 'user/register', $link_options),
+    '[register-url]' => check_url(url('user/register', $link_options)),
+  );
+  // Backward compatibility:
+  $tokens['!login'] = $tokens['[login]'];
+  $tokens['!register'] = $tokens['[register]'];
+  return array(
+    'title' => strtr($flag->get_label('anon_message', $content_id), $tokens),
+    'html' => TRUE,
+  );
+}
