ecb_ews_save_component_sync (ECalMetaBackend *meta_backend,
			     gboolean overwrite_existing,
			     EConflictResolution conflict_resolution,
			     const GSList *instances,
			     const gchar *extra,
			     gchar **out_new_uid,
			     gchar **out_new_extra,
			     GCancellable *cancellable,
			     GError **error)
{
	ECalBackendEws *cbews;
	ECalCache *cal_cache;
	ECalComponent *master = NULL;
	EwsFolderId *fid;
	GSList *link;
	const gchar *uid = NULL;
	gboolean success = TRUE;

	g_return_val_if_fail (E_IS_CAL_BACKEND_EWS (meta_backend), FALSE);

	cbews = E_CAL_BACKEND_EWS (meta_backend);

	for (link = (GSList *) instances; link && !master; link = g_slist_next (link)) {
		master = link->data;

		if (!master)
			continue;

		if (e_cal_component_is_instance (master))
			master = NULL;
	}

	if (!master) {
		g_propagate_error (error, EDC_ERROR (InvalidObject));
		return FALSE;
	}

	cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
	g_return_val_if_fail (cal_cache != NULL, FALSE);

	g_rec_mutex_lock (&cbews->priv->cnc_lock);

	e_cal_component_get_uid (master, &uid);
	fid = e_ews_folder_id_new (cbews->priv->folder_id, NULL, FALSE);

	if (overwrite_existing) {
		GSList *existing = NULL, *changed_instances = NULL, *removed_instances = NULL;

		success = uid && e_cal_cache_get_components_by_uid (cal_cache, uid, &existing, cancellable, error) && existing;

		if (success) {
			GSList *link;

			/* This is for offline changes, where the component in the cache
			   is already modified, while the original, the one on the server,
			   is different. Using the cached component in this case generates
			   empty UpdateItem request and nothing is saved. */
			for (link = existing; link; link = g_slist_next (link)) {
				ECalComponent *comp = link->data;

				comp = ecb_ews_restore_original_comp (comp);
				if (comp) {
					g_object_unref (link->data);
					link->data = comp;
				}
			}
		}

		if (success)
			ecb_ews_filter_out_unchanged_instances (instances, existing, &changed_instances, &removed_instances);

		if (success) {
			GHashTable *removed_indexes;

			removed_indexes = g_hash_table_new (g_direct_hash, g_direct_equal);

			for (link = changed_instances; link && success; link = g_slist_next (link)) {
				ChangeData *cd = link->data;

				if (!cd)
					continue;

				success = ecb_ews_modify_item_sync (cbews, removed_indexes,
					e_cal_component_get_icalcomponent (cd->old_component ? cd->old_component : master),
					e_cal_component_get_icalcomponent (cd->new_component),
					cancellable, error);
			}

			for (link = removed_instances; link && success; link = g_slist_next (link)) {
				ECalComponent *comp = link->data;
				ECalComponentId *id = NULL;

				if (!comp)
					continue;

				id = e_cal_component_get_id (comp);

				if (id) {
					success = ecb_ews_remove_item_sync (cbews, cal_cache, removed_indexes, id->uid, id->rid, cancellable, error);
					e_cal_component_free_id (id);
				}
			}

			g_hash_table_destroy (removed_indexes);
		}

		if (success)
			ecb_ews_extract_item_id (master, out_new_uid, NULL);

		g_slist_free_full (existing, g_object_unref);
		g_slist_free_full (changed_instances, change_data_free);
		g_slist_free_full (removed_instances, g_object_unref);
	} else {
		GHashTable *removed_indexes;
		EwsCalendarConvertData convert_data = { 0 };
		EEwsItem *item = NULL;
		EwsId *ews_id = NULL;
		const gchar *send_meeting_invitations;
		icalcomponent *icalcomp;
		icalproperty *prop;
		GSList *items = NULL;

		icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (master));

		e_ews_clean_icalcomponent (icalcomp);

		if (!e_ews_connection_satisfies_server_version (cbews->priv->cnc, E_EWS_EXCHANGE_2010))
			ecb_ews_pick_all_tzids_out (cbews, icalcomp);

		/*
		 * In case we are creating a meeting with attendees and attachments.
		 * We have to preform 3 steps in order to allow attendees to receive attachments in their invite mails.
		 * 1. create meeting and do not send invites
		 * 2. create attachments
		 * 3. dummy update meeting and send invites to all
		 */
		if (e_cal_component_has_attendees (master)) {
			if (e_cal_component_has_attachments (master))
				send_meeting_invitations = "SendToNone";
			else
				send_meeting_invitations = "SendToAllAndSaveCopy";
		} else {
			/* In case of appointment we have to set SendMeetingInvites to SendToNone */
			send_meeting_invitations = "SendToNone";
		}

		convert_data.connection = cbews->priv->cnc;
		convert_data.timezone_cache = E_TIMEZONE_CACHE (cbews);
		convert_data.icalcomp = icalcomp;
		convert_data.default_zone = icaltimezone_get_utc_timezone ();

		success = e_ews_connection_create_items_sync (cbews->priv->cnc, EWS_PRIORITY_MEDIUM, "SaveOnly", send_meeting_invitations,
			fid, e_cal_backend_ews_convert_calcomp_to_xml, &convert_data,
			&items, cancellable, error);

		if (success && items) {
			item = items->data;
			if (item) {
				g_object_ref (item);

				ews_id = e_ews_id_copy (e_ews_item_get_id (item));
			}
		}

		if (success && item && e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_EVENT) {
			EEwsAdditionalProps *add_props;
			GSList *items, *items_req = NULL;

			add_props = e_ews_additional_props_new ();
			add_props->field_uri = g_strdup ("calendar:UID");

			items = g_slist_append (NULL, ews_id->id);

			/* get calender uid from server*/
			success = e_ews_connection_get_items_sync (cbews->priv->cnc, EWS_PRIORITY_MEDIUM,
				items, "IdOnly", add_props, FALSE, NULL, E_EWS_BODY_TYPE_TEXT,
				&items_req, NULL, NULL, cancellable, error) && items_req != NULL;

			e_ews_additional_props_free (add_props);

			if (success) {
				g_clear_object (&item);

				item = items_req->data;

				e_ews_id_free (ews_id);
				ews_id = NULL;

				if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) {
					g_propagate_error (error, g_error_copy (e_ews_item_get_error (item)));
					item = NULL;
					success = FALSE;
				} else {
					item = g_object_ref (item);
					ews_id = e_ews_id_copy (e_ews_item_get_id (item));
				}
			}

			g_slist_free_full (items_req, g_object_unref);
			g_slist_free (items);
		}

		/* attachments */
		if (success && e_cal_component_has_attachments (master) > 0) {
			GSList *info_attachments = NULL;

			g_warn_if_fail (ews_id != NULL);

			if (ews_id && ecb_ews_extract_attachments (icalcomp, &info_attachments)) {
				gchar *changekey = NULL;
				GSList *ids = NULL;

				success = e_ews_connection_create_attachments_sync (cbews->priv->cnc, EWS_PRIORITY_MEDIUM,
					ews_id, info_attachments, FALSE, &changekey, &ids, cancellable, error);

				g_slist_free_full (info_attachments, (GDestroyNotify) e_ews_attachment_info_free);
				g_slist_free_full (ids, g_free);

				if (success && changekey) {
					g_free (ews_id->change_key);
					ews_id->change_key = changekey;
				} else {
					g_free (changekey);
				}
			}
		}

		removed_indexes = g_hash_table_new (g_direct_hash, g_direct_equal);

		if (success && icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY)) {
			GSList *exceptions = NULL;

			/* Excluded occurrences */
			for (prop = icalcomponent_get_first_property (icalcomp, ICAL_EXDATE_PROPERTY);
			     prop;
			     prop = icalcomponent_get_next_property (icalcomp, ICAL_EXDATE_PROPERTY)) {
				exceptions = g_slist_prepend (exceptions, g_strdup (icalproperty_get_value_as_string (prop)));
			}

			for (link = exceptions; link && success; link = g_slist_next (link)) {
				success = ecb_ews_remove_item_sync (cbews, cal_cache, removed_indexes, uid, link->data, cancellable, error);
			}

			g_slist_free_full (exceptions, g_free);
		}

		if (success && e_cal_component_has_attendees (master) && e_cal_component_has_attachments (master)) {
			if (ews_id) {
				e_cal_util_set_x_property (icalcomp, "X-EVOLUTION-ITEMID", ews_id->id);
				e_cal_util_set_x_property (icalcomp, "X-EVOLUTION-CHANGEKEY", ews_id->change_key);
			}

			/* In case we have attendees and atachemnts we have to fake update items,
			 * this is the only way to pass attachments in meeting invite mail */
			success = ecb_ews_modify_item_sync (cbews, removed_indexes, NULL, icalcomp, cancellable, error);
		}

		icalcomponent_free (icalcomp);
		e_ews_id_free (ews_id);
		g_clear_object (&item);

		for (link = (GSList *) instances; link && success; link = g_slist_next (link)) {
			ECalComponent *comp = link->data;

			if (comp == master)
				continue;

			icalcomp = e_cal_component_get_icalcomponent (comp);

			success = ecb_ews_modify_item_sync (cbews, removed_indexes, NULL, icalcomp, cancellable, error);
		}

		if (success && items) {
			EEwsItem *item = items->data;
			const EwsId *item_id;

			item_id = e_ews_item_get_id (item);
			*out_new_uid = g_strdup (item_id->id);
		}

		g_slist_free_full (items, g_object_unref);
		g_hash_table_destroy (removed_indexes);
	}

	g_rec_mutex_unlock (&cbews->priv->cnc_lock);

	g_clear_object (&cal_cache);
	e_ews_folder_id_free (fid);

	ecb_ews_convert_error_to_edc_error (error);
	ecb_ews_maybe_disconnect_sync (cbews, error, cancellable);

	return success;
}