diff --git a/includes/rules.state.inc b/includes/rules.state.inc
index 7ecffc4..f643dff 100644
--- a/includes/rules.state.inc
+++ b/includes/rules.state.inc
@@ -216,6 +216,11 @@ class RulesState {
 
     // Actually save!
     $wrapper = $this->save[$selector][0];
+    $entity = $wrapper->value();
+    // Remove the is_new flag for entities that already exist.
+    if ($entity->is_new && $wrapper->getIdentifier()) {
+      unset($entity->is_new);
+    }
     rules_log('Saved %selector of type %type.', array('%selector' => $selector, '%type' => $wrapper->type()));
     $wrapper->save();
 
diff --git a/modules/events.inc b/modules/events.inc
index 0053be1..fcadc34 100644
--- a/modules/events.inc
+++ b/modules/events.inc
@@ -43,9 +43,6 @@ function rules_node_update($node) {
 }
 
 function rules_node_insert($node) {
-  // Make sure the node is not marked as new any more, such that any
-  // sub-sequent saves triggered by rules are updating the node.
-  $node->is_new = FALSE;
   rules_invoke_event('node_insert', $node);
 }
 
@@ -63,9 +60,13 @@ function rules_user_view($account, $view_mode) {
   rules_invoke_event('user_view', $account, $view_mode);
 }
 
-function rules_user_presave(&$edit, $account, $category) {
-  if ($category == 'account') {
-    rules_invoke_event('user_presave', $account);
+/**
+ * We don't want to use hook_user_presave() here because it is called too early
+ * and we would have to mess with the $edit array.
+ */
+function rules_entity_presave($entity, $entity_type) {
+  if ($entity_type == 'user') {
+    rules_invoke_event('user_presave', $entity);
   }
 }
 
diff --git a/modules/user.eval.inc b/modules/user.eval.inc
index cd566be..a6a38e6 100644
--- a/modules/user.eval.inc
+++ b/modules/user.eval.inc
@@ -42,13 +42,18 @@ function rules_condition_user_is_blocked($account) {
  * Action: Adds roles to a particular user.
  */
 function rules_action_user_add_role($account, $roles) {
-  if ($account->uid) {
+  if ($account->uid || $account->is_new) {
     // Get role list (minus the anonymous)
     $role_list = user_roles(TRUE);
 
     foreach ($roles as $rid) {
       $account->roles[$rid] = $role_list[$rid];
     }
+    if ($account->is_new && $account->uid) {
+      // Disable saving for newly created accounts, otherwise we get ugly DB
+      // errors because user_save() also tries to save the roles.
+      return FALSE;
+    }
   }
   else {
     return FALSE;
