diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 818015c..144b430 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -105,6 +105,7 @@ static void remove_client (ECalModel *model, ECalModelClient *client_data);
 enum {
 	TIME_RANGE_CHANGED,
 	ROW_APPENDED,
+	COMPS_DELETED,
 	CAL_VIEW_PROGRESS,
 	CAL_VIEW_DONE,
 	LAST_SIGNAL
@@ -155,6 +156,16 @@ e_cal_model_class_init (ECalModelClass *klass)
 			      NULL, NULL,
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE, 0);
+
+	signals[COMPS_DELETED] =
+		g_signal_new ("comps_deleted",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ECalModelClass, comps_deleted),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1, G_TYPE_POINTER);
+
 	signals[CAL_VIEW_PROGRESS] =
 		g_signal_new ("cal_view_progress",
 			      G_TYPE_FROM_CLASS (klass),
@@ -1427,13 +1438,21 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data
 		while ((comp_data = search_by_id_and_client (priv, client,
 							      id))) {
 			int pos;
+			GSList *list = NULL;
 
 			pos = get_position_in_array (priv->objects, comp_data);
+ 			
+			if (!g_ptr_array_remove (priv->objects, comp_data))
+				continue;
+
+			list = g_slist_append (list, comp_data);
+			g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, list);
+
+			g_slist_free (list);
+			g_object_unref (comp_data);
+
 			e_table_model_pre_change (E_TABLE_MODEL (model));
 			e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
-
- 			if (g_ptr_array_remove (priv->objects, comp_data))
-	 			e_cal_model_free_component_data (comp_data);
  		}
 
 		e_cal_component_free_id (id);
@@ -1469,9 +1488,45 @@ static void
 e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer user_data)
 {
 	ECalModel *model = (ECalModel *) user_data;
+	ECalModelPrivate *priv;
+	GList *l, *list = NULL;
+
+	priv = model->priv;
 
-	/* now re-add all objects */
-	e_cal_view_objects_added_cb (query, objects, model);
+	/*  re-add only the recurrence objects */
+	for (l = objects; l != NULL; l = g_list_next (l)) {
+		if (e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) 
+			g_list_prepend (list, l->data);
+		else {
+			int pos;
+			ECalModelComponent *comp_data;
+			ECalComponentId *id;
+			ECalComponent *comp = e_cal_component_new ();
+			ECal *client = e_cal_view_get_client (query);
+		
+			if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) {
+				g_object_unref (comp);
+				continue;
+			}
+
+			e_table_model_pre_change (E_TABLE_MODEL (model));
+
+			id = e_cal_component_get_id (comp);
+				
+			comp_data = search_by_id_and_client (priv, client, id);
+			icalcomponent_free (comp_data->icalcomp);
+			
+			comp_data->icalcomp = icalcomponent_new_clone (l->data);
+			e_cal_model_set_instance_times (comp_data, priv->zone);
+			
+			pos = get_position_in_array (priv->objects, comp_data);
+			
+			e_table_model_row_changed (E_TABLE_MODEL (model), pos);
+		}
+	}
+
+	e_cal_view_objects_added_cb (query, list, model);
+	g_list_free (list);
 }
 
 static void
@@ -1490,13 +1545,21 @@ e_cal_view_objects_removed_cb (ECalView *query, GList *ids, gpointer user_data)
 
 		/* make sure we remove all objects with this UID */
 		while ((comp_data = search_by_id_and_client (priv, e_cal_view_get_client (query), id))) {
+			GSList *l = NULL;
+
 			pos = get_position_in_array (priv->objects, comp_data);
 
+			if (!g_ptr_array_remove (priv->objects, comp_data))
+				continue;
+
+			l = g_slist_append (l, comp_data);
+			g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, l);
+
+			g_slist_free (l);
+			g_object_unref (comp_data);
+		
 			e_table_model_pre_change (E_TABLE_MODEL (model));
 			e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
-
-			if (g_ptr_array_remove (priv->objects, comp_data))
-				e_cal_model_free_component_data (comp_data);
 		}
 	}
 
@@ -1688,11 +1751,18 @@ remove_client_objects (ECalModel *model, ECalModelClient *client_data)
 		g_return_if_fail (comp_data != NULL);
 
 		if (comp_data->client == client_data->client) {
-			e_table_model_pre_change (E_TABLE_MODEL (model));
-			e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1);
+			GSList *l = NULL;
 
 			g_ptr_array_remove (model->priv->objects, comp_data);
-			e_cal_model_free_component_data (comp_data);
+		
+			l = g_slist_append (l, comp_data);
+			g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, l);
+
+			g_slist_free (l);
+			g_object_unref (comp_data);
+
+			e_table_model_pre_change (E_TABLE_MODEL (model));
+			e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1);
 		}
 	}
 
@@ -1764,11 +1834,34 @@ e_cal_model_remove_all_clients (ECalModel *model)
 	}
 }
 
+static GSList *
+get_objects_as_list (ECalModel *model)
+{
+	gint i;
+	GSList *l = NULL;
+	ECalModelPrivate *priv = model->priv;
+
+	for (i = 0; i < priv->objects->len; i++) {
+		ECalModelComponent *comp_data;
+
+		comp_data = g_ptr_array_index (priv->objects, i);
+		if (comp_data == NULL) {
+			g_warning ("comp_data is null\n");
+			continue;
+		}
+
+		l = g_slist_prepend (l, comp_data);
+	}
+
+	return l;
+}
+
 static void
 redo_queries (ECalModel *model)
 {
 	ECalModelPrivate *priv;
 	GList *l;
+	GSList *sl, *slist;
 	int len;
 
 	priv = model->priv;
@@ -1798,8 +1891,19 @@ redo_queries (ECalModel *model)
 	/* clean up the current contents */
 	e_table_model_pre_change (E_TABLE_MODEL (model));
 	len = priv->objects->len;
+
+	slist = get_objects_as_list (model);
+	g_ptr_array_set_size (priv->objects, 0);
+	g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, slist);
+	
 	e_table_model_rows_deleted (E_TABLE_MODEL (model), 0, len);
-	clear_objects_array (priv);
+	
+	for (sl = slist; sl != NULL; sl = sl->next) {
+		ECalModelComponent *comp_data = sl->data;
+
+		g_object_unref (comp_data);
+	}
+	g_slist_free (slist);
 
 	/* update the query for all clients */
 	for (l = priv->clients; l != NULL; l = l->next) {
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index 405efb4..fd49ce7 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -112,6 +112,7 @@ typedef struct {
 	/* Signals */
 	void (* time_range_changed) (ECalModel *model, time_t start, time_t end);
 	void (* row_appended) (ECalModel *model);
+	void (* comps_deleted) (ECalModel *model, gpointer list);
 	void (* cal_view_progress) (ECalModel *model, const char *message, int progress, ECalSourceType type);
 	void (* cal_view_done) (ECalModel *model, ECalendarStatus status, ECalSourceType type);
 } ECalModelClass;
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index ebf17ef..f1fb84c 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -624,10 +624,10 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data
 }
 
 static void
-model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
+model_comps_deleted_cb (ETableModel *etm, gpointer data, gpointer user_data)
 {
 	EDayView *day_view = E_DAY_VIEW (user_data);
-	int i;
+	GSList *l, *list = data;
 
 	if (!E_CALENDAR_VIEW (day_view)->in_focus) {
 		return;
@@ -635,15 +635,12 @@ model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
 
 	e_day_view_stop_editing_event (day_view);
 
-	for (i = row + count; i > row; i--) {
+	for (l = list; l != NULL; l = g_slist_next (l)) {
+		ECalModelComponent *comp_data = l->data;
 		gint day, event_num;
 		const char *uid = NULL;
 		char *rid = NULL;
-		ECalModelComponent *comp_data;
 
-		comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), i - 1);
-		if (!comp_data)
-			continue;
 
 		uid = icalcomponent_get_uid (comp_data->icalcomp);
 		if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
@@ -656,6 +653,7 @@ model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
 
 		if (e_day_view_find_event_from_uid (day_view, comp_data->client, uid, rid, &day, &event_num))
 			e_day_view_remove_event_cb (day_view, day, event_num, NULL);
+
 		g_free (rid);
 	}
 
@@ -1024,8 +1022,8 @@ init_model (EDayView *day_view, ECalModel *model)
 			  G_CALLBACK (model_cell_changed_cb), day_view);
 	g_signal_connect (G_OBJECT (model), "model_rows_inserted",
 			  G_CALLBACK (model_rows_inserted_cb), day_view);
-	g_signal_connect (G_OBJECT (model), "model_rows_deleted",
-			  G_CALLBACK (model_rows_deleted_cb), day_view);
+	g_signal_connect (G_OBJECT (model), "comps_deleted",
+			  G_CALLBACK (model_comps_deleted_cb), day_view);
 }
 
 /* Turn off the background of the canvas windows. This reduces flicker
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index aa459f8..9e3ea5d 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -401,25 +401,22 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data
 }
 
 static void
-model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
+model_comps_deleted_cb (ETableModel *etm, gpointer data, gpointer user_data)
 {
 	EWeekView *week_view = E_WEEK_VIEW (user_data);
 	int i;
+	GSList *l, *list = data;
 
 	/* FIXME Stop editing? */
 	if (!E_CALENDAR_VIEW (week_view)->in_focus) {
 		return;
 	}
 
-	for (i = row + count; i > row; i--) {
+	for (l = list; l != NULL; l = g_slist_next (l)) {
 		gint event_num;
 		const char *uid;
 		char *rid = NULL;
-		ECalModelComponent *comp_data;
-
-		comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), i - 1);
-		if (!comp_data)
-			continue;
+		ECalModelComponent *comp_data = l->data;
 
 		uid = icalcomponent_get_uid (comp_data->icalcomp);
 		if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
@@ -626,8 +623,8 @@ init_model (EWeekView *week_view, ECalModel *model)
 			  G_CALLBACK (model_cell_changed_cb), week_view);
 	g_signal_connect (G_OBJECT (model), "model_rows_inserted",
 			  G_CALLBACK (model_rows_inserted_cb), week_view);
-	g_signal_connect (G_OBJECT (model), "model_rows_deleted",
-			  G_CALLBACK (model_rows_deleted_cb), week_view);
+	g_signal_connect (G_OBJECT (model), "comps_deleted",
+			  G_CALLBACK (model_comps_deleted_cb), week_view);
 
 }
 
