Index: itip-formatter.c
===================================================================
--- itip-formatter.c	(revision 36291)
+++ itip-formatter.c	(working copy)
@@ -107,6 +107,7 @@
 	guint progress_info_id;
 
 	gboolean delete_message;
+	gboolean is_meeting;
 
 };
 
@@ -641,9 +642,29 @@
 	d(printf ("Decreasing itip formatter search count to %d\n", fd->count));
 
 	if (fd->count == 0) {
+		gboolean rsvp_enabled = FALSE;
+
 		itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id);
 		pitip->progress_info_id = 0;
+		
+		/*
+		 * Only allow replies if backend doesn't do that automatically.
+		 * Replies only make sense for meetings with an organizer.
+		 */
+		if (!e_cal_get_save_schedules (ecal) &&
+		    pitip->is_meeting) {
+			rsvp_enabled = TRUE;
+		}
+		itip_view_set_rsvp (ITIP_VIEW (pitip->view), rsvp_enabled);
 
+		/*
+		 * TODO: The default value should be taken from the
+		 * RSVP=TRUE|FALSE of the original meeting invitation.
+		 * Instead we always enable it when replies are
+		 * enabled.
+		 */
+		itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), rsvp_enabled);
+
 		if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method ==  ICAL_METHOD_REQUEST)
 		    && !pitip->current_ecal) {
 			/* Reuse already declared one or rename? */
@@ -677,11 +698,6 @@
 			itip_view_set_source_list (ITIP_VIEW (pitip->view), pitip->source_lists[pitip->type]);
 			g_signal_connect (pitip->view, "source_selected", G_CALLBACK (source_selected_cb), pitip);
 
-			/* The only method that RSVP makes sense for is REQUEST */
-			/* FIXME Default to the suggestion for RSVP for my attendee */
-			itip_view_set_rsvp (ITIP_VIEW (pitip->view), pitip->method == ICAL_METHOD_REQUEST ? TRUE : FALSE);
-			itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), pitip->method == ICAL_METHOD_REQUEST ? TRUE : FALSE);
-
 			if (source) {
 				itip_view_set_source (ITIP_VIEW (pitip->view), source);
 
@@ -1423,6 +1439,15 @@
 	switch (icalcomponent_isa (pitip->ical_comp)) {
 	case ICAL_VEVENT_COMPONENT:
 		pitip->type = E_CAL_SOURCE_TYPE_EVENT;
+		/*
+		 * Treat any event which contains attendees as a meeting.
+		 * A meeting at least contains the organizer. Also
+		 * treat each meeting request like a meeting (which it
+		 * should be...) because that's what previous versions
+		 * of Evolution did.
+		 */
+		pitip->is_meeting = pitip->method == ICAL_METHOD_REQUEST ||
+			icalcomponent_get_first_property (pitip->ical_comp, ICAL_ATTENDEE_PROPERTY) != NULL;
 		break;
 	case ICAL_VTODO_COMPONENT:
 		pitip->type = E_CAL_SOURCE_TYPE_TODO;
@@ -1867,6 +1892,11 @@
 	uri = mail_tools_folder_to_url (folder);
 
 	res = !(folder->folder_flags & CAMEL_FOLDER_IS_TRASH) &&
+		/*
+		 * TODO Bugzilla #346146: test is too broad. The sent folder might
+		 * be the same as some other folder with incoming invitations;
+		 * in such a setup meetings cannot be accepted in the inbox!
+		 */
 	      !em_utils_folder_is_sent (folder, uri) &&
 	      !em_utils_folder_is_outbox (folder, uri) &&
 	      !em_utils_folder_is_drafts (folder, uri);
@@ -1921,10 +1951,17 @@
 	} else {
 		switch (info->method) {
 		case ICAL_METHOD_PUBLISH:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_PUBLISH);
-			break;
 		case ICAL_METHOD_REQUEST:
-			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REQUEST);
+			/*
+			 * Treat meeting request (sent by organizer directly) and
+			 * published evend (forwarded by organizer or attendee) alike:
+			 * if the event is a meeting, then show "accept/tentative/decline"
+			 * choice. Otherwise only show "accept".
+			 */
+			itip_view_set_mode (ITIP_VIEW (info->view),
+					    info->is_meeting ?
+					    ITIP_VIEW_MODE_REQUEST :
+					    ITIP_VIEW_MODE_PUBLISH);
 			break;
 		case ICAL_METHOD_REPLY:
 			itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REPLY);
@@ -2249,6 +2286,7 @@
 
 	gconf = gconf_client_get_default ();
 	puri->delete_message = gconf_client_get_bool (gconf, GCONF_KEY_DELETE, NULL);
+	puri->is_meeting = FALSE;
 	puri->folder = ((EMFormat *) target->format)->folder;
 	puri->uid = g_strdup (((EMFormat *) target->format)->uid);
 	puri->msg = ((EMFormat *) target->format)->message;
