diff --git user_badges.module user_badges.module
index e54b167..9f1378c 100644
--- user_badges.module
+++ user_badges.module
@@ -717,8 +717,19 @@ function user_badges_user_save($edit, $uid, $quiet = TRUE) {
  * @return bool with query success
  */
 function user_badges_user_add_badge($uid, $bid, $type = NULL) {
-  user_badges_user_remove_badge($uid, $bid, $type);
-  return db_query('INSERT INTO {user_badges_user} (uid, bid, type) VALUES (%d, %d, \'%s\')', $uid, $bid, $type);
+  // Integrate rule action
+  if (module_exists('rules')) {
+    $arguments = array('user' => user_load($uid), 'userbadge' => user_badges_get_badge($bid));
+    rules_invoke_event('user_badges_badge_given', $arguments);
+  }
+  // add the badge only it wasn't yet assigned
+  $badges = user_badges_get_badges($uid);
+  if (!isset($badges[$bid])) {
+    return db_query('INSERT INTO {user_badges_user} (uid, bid, type) VALUES (%d, %d, \'%s\')', $uid, $bid, $type);
+  }
+  else {
+    return TRUE;
+  }
 }
 
 
@@ -732,12 +743,22 @@ function user_badges_user_add_badge($uid, $bid, $type = NULL) {
  * @return bool with query success
  */
 function user_badges_user_remove_badge($uid, $bid, $type = NULL) {
-  if (is_null($type)) {
-    return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d', $uid, $bid);
+  // Integrate rule action
+  if (module_exists('rules')) {
+    $arguments = array('user' => user_load($uid), 'userbadge' => user_badges_get_badge($bid));
+    rules_invoke_event('user_badges_badge_removed', $arguments);
   }
-  else {
-    return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d AND type=\'%s\'', $uid, $bid, $type);
+  // remove the badge only if it's already assigned
+  $badges = user_badges_get_badges($uid);
+  if (isset($badges[$bid])) {
+    if (is_null($type)) {
+      return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d', $uid, $bid);
+    }
+    else {
+      return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d AND type=\'%s\'', $uid, $bid, $type);
+    }
   }
+  return TRUE;
 }
 
 
@@ -1094,7 +1115,7 @@ function user_badges_add_badge_action(&$account, $context = array()) {
   $badges = user_badges_get_badges('all');
 
   foreach ($context['badges'] as $bid) {
-    $success = (boolean) user_badges_user_add_badge($uid, $bid, 'uid');
+    $success = (boolean) user_badges_user_add_badge($uid, $bid, 'user');
     if ($success) {
       watchdog('action', 'Added user badge %badge to user %name.', array('%name' => check_plain($user->name), '%badge' => check_plain($badges[$bid]->name)));
     }
@@ -1152,7 +1173,7 @@ function user_badges_remove_badge_action(&$account, $context = array()) {
   $badges = user_badges_get_badges('all');
 
   foreach ($context['badges'] as $bid) {
-    $success = (boolean) user_badges_user_remove_badge($uid, $bid, 'uid');
+    $success = (boolean) user_badges_user_remove_badge($uid, $bid, 'user');
     if ($success) {
       watchdog('action', 'Removed user badge %badge to user %name.', array('%name' => check_plain($user->name), '%badge' => check_plain($badges[$bid]->name)));
     }
@@ -1195,23 +1216,25 @@ function user_badges_remove_badge_action_submit($form, $form_state) {
  * Implements hook_token_values().
  */
 function user_badges_token_values($type, $object = NULL) {
+  $tokens = array();
   if ($type == 'userbadge') {
     $badge = $object;
     $tokens['userbadge-name'] = $badge->name;
     $tokens['userbadge-bid'] = $badge->bid;
-    return $tokens;
   }
+  return $tokens;
 }
 
 /**
  * Implements hook_token_list().
  */
 function user_badges_token_list($type = 'all') {
-  if ($type == 'userbadge' || $type == 'all') {
+  $tokens = array();
+  if ($type == 'userbadge') {
     $tokens['userbadge']['userbadge-name'] = t("The badge name");
     $tokens['userbadge']['userbadge-bid'] = t("The badge id number (bid)");
-    return $tokens;
   }
+  return $tokens;
 }
 
 
diff --git user_badges.rules.inc user_badges.rules.inc
new file mode 100644
index 0000000..d9e0709
--- /dev/null
+++ user_badges.rules.inc
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * @file
+ * Provide better integration into the rules module
+ */
+
+/**
+ * Implementation of hook_rules_event_info().
+ */
+function user_badges_rules_event_info() {
+  return array(
+    'user_badges_badge_given' => array(
+      'label' => t('User was given a badge'),
+      'arguments' => array(
+        'user' => array('type' => 'user', 'label' => t('User who was given a badge')),
+        'userbadge' => array('type' => 'userbadge', 'label' => t('The given Badge')),
+      ),
+      'module' => 'User Badges',
+    ),
+    'user_badges_badge_removed' => array(
+      'label' => t('User was removed a badge'),
+      'arguments' => array(
+        'user' => array('type' => 'user', 'label' => t('User who was removed a badge')),
+        'userbadge' => array('type' => 'userbadge', 'label' => t('The removed Badge')),
+      ),
+      'module' => 'User Badges',
+    ),
+  );
+}
+
+/**
+ * Implementation of hook_rules_condition_info().
+ */
+function user_badges_rules_condition_info() {
+  return array(
+    'user_badges_has_badge' => array(
+      'label' => t('User has badge'),
+      'arguments' => array(
+        'account' => array('type' => 'user', 'label' => t('User')),
+      ),
+      'module' => 'User Badges',
+    ),
+  );
+}
+
+/**
+ * Configuration form for user_badges_has_badge condition
+ */
+function user_badges_has_badge_form($settings = array(), &$form) {
+  $form['badges'] = array('#tree' => TRUE);
+  $badges = user_badges_get_badges('all');
+  $settings['badges'] = is_array($settings['badges']) ? $settings['badges'] : array();
+
+  $form['settings']['operator'] = array(
+    '#type' => 'select',
+    '#title' => t('Operator'),
+    '#options' => array(
+      'any' => t('Has one of'),
+      'all' => t('Has all of'),
+    ),
+    '#default_value' => $settings['operator'],
+  );
+  foreach ($badges as $badge) {
+    $form['settings']['badges'][$badge->bid] = array(
+      '#type' => 'checkbox',
+      '#title' => theme('user_badge', $badge),
+      '#return_value' => 1,
+      '#default_value' => $settings['badges'][$badge->bid],
+      '#description' => check_plain($badge->name),
+    );
+  }
+
+  return $form;
+}
+
+/**
+ * Test the user_badges_has_badge condition
+ */
+function user_badges_has_badge($account, $settings) {
+  $badges = user_badges_get_badges($account->uid);
+  $result = $settings['operator'] == 'all' ? TRUE : FALSE;
+  foreach ($settings['badges'] as $bid => $on) {
+    if (!$on) {
+      continue;
+    }
+    $has_badge = isset($badges[$bid]);
+    if ($settings['operator'] == 'all') {
+      $result = $result && $has_badge;
+    }
+    else {
+      $result = $result || $has_badge;
+    }
+  }
+  return $result;
+}
+
+/**
+ * Implementation of hook_rules_data_type_info().
+ */
+function user_badges_data_type_info() {
+  return array(
+    'userbadge' => array(
+      'label' => t('User Badge'),
+      'class' => 'rules_data_type_badge',
+      'savable' => FALSE,
+      'identifiable' => TRUE,
+      'module' => 'User Badges',
+    ),
+  );
+}
+
+/**
+* Defines the rules user badge data type.
+*/
+class rules_data_type_badge extends rules_data_type {
+  function load($bid) {
+    return user_badges_get_badge($bid);
+  }
+
+  function get_identifier() {
+    $badge = &$this->get();
+    return $badge->bid;
+  }
+}
\ No newline at end of file
