ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
				EEwsItem *item,
				GCancellable *cancellable,
				GError **error)
{
	ECalComponent *res_component = NULL;
	ETimezoneCache *timezone_cache;
	icalcomponent_kind kind;
	EEwsItemType item_type;
	icalcomponent *icalcomp, *vcomp;
	icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
	CamelEwsSettings *ews_settings;

	g_return_val_if_fail (E_IS_CAL_BACKEND_EWS (cbews), NULL);
	g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL);

	timezone_cache = E_TIMEZONE_CACHE (cbews);

	kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbews));
	ews_settings = ecb_ews_get_collection_settings (cbews);

	item_type = e_ews_item_get_item_type (item);
	if (item_type == E_EWS_ITEM_TYPE_TASK || item_type == E_EWS_ITEM_TYPE_MEMO) {
		icalproperty *icalprop;
		icaltimetype due_date, start_date, complete_date, created;
		icalproperty_status status  = ICAL_STATUS_NONE;
		icalproperty_class class = ICAL_CLASS_NONE;
		const gchar *ews_task_status, *sensitivity;
		EwsImportance item_importance;
		gint priority = 5;
		gboolean has_this_date = FALSE;

		vcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT);
		/*subject*/
		icalcomp = icalcomponent_new (item_type == E_EWS_ITEM_TYPE_TASK ? ICAL_VTODO_COMPONENT : ICAL_VJOURNAL_COMPONENT);
		icalprop = icalproperty_new_summary (e_ews_item_get_subject (item));
		icalcomponent_add_property (icalcomp, icalprop);

		/*date time created*/
		created = icaltime_from_timet_with_zone (e_ews_item_get_date_created (item), 0, utc_zone);
		icalprop = icalproperty_new_created (created);
		icalcomponent_add_property (icalcomp, icalprop);

		/*sensitivity*/
		sensitivity = e_ews_item_get_sensitivity (item);
		if (g_strcmp0 (sensitivity, "Normal") == 0)
			class = ICAL_CLASS_PUBLIC;
		else if (g_strcmp0 (sensitivity, "Private") == 0)
			class = ICAL_CLASS_PRIVATE;
		else if ((g_strcmp0 (sensitivity, "Confidential") == 0) ||
			 (g_strcmp0 (sensitivity, "Personal") == 0))
			class = ICAL_CLASS_CONFIDENTIAL;
		icalprop = icalproperty_new_class (class);
		icalcomponent_add_property (icalcomp, icalprop);

		/*description*/
		icalprop = icalproperty_new_description (e_ews_item_get_body (item));
		icalcomponent_add_property (icalcomp, icalprop);

		/*task assaingments*/
		if (e_ews_item_get_delegator (item) != NULL) {
			const gchar *task_owner = e_ews_item_get_delegator (item);
			GSList *mailboxes = NULL, *l;
			gboolean includes_last_item;
			gchar *mailtoname, *user_email;
			icalparameter *param;

			/*The task owner according to Exchange is current user, even that the task was assigned by
			 *someone else. I'm making the current user attendee and task delegator will be a task organizer */

			user_email = camel_ews_settings_dup_email (ews_settings);
			mailtoname = g_strdup_printf ("mailto:%s", user_email);
			icalprop = icalproperty_new_attendee (mailtoname);
			g_free (mailtoname);
			g_free (user_email);

			param = icalparameter_new_cn (e_ews_item_get_owner (item));
			icalproperty_add_parameter (icalprop, param);
			icalcomponent_add_property (icalcomp, icalprop);

			/* get delegator mail box*/
			e_ews_connection_resolve_names_sync (
				cbews->priv->cnc, EWS_PRIORITY_MEDIUM, task_owner,
				EWS_SEARCH_AD, NULL, FALSE, &mailboxes, NULL,
				&includes_last_item, cancellable, error);

			for (l = mailboxes; l != NULL; l = g_slist_next (l)) {
				EwsMailbox *mb = l->data;

				mailtoname = g_strdup_printf ("mailto:%s", mb->email);
				icalprop = icalproperty_new_organizer (mailtoname);
				param = icalparameter_new_cn (mb->name);
				icalproperty_add_parameter (icalprop, param);
				icalcomponent_add_property (icalcomp, icalprop);

				g_free (mailtoname);
				e_ews_mailbox_free (mb);
			}
			g_slist_free (mailboxes);
		}

		if (item_type == E_EWS_ITEM_TYPE_TASK) {
			icaltimezone *user_timezone = calendar_config_get_icaltimezone ();
			const gchar *percent_complete;

			/*start date*/
			has_this_date = FALSE;
			e_ews_item_task_has_start_date (item, &has_this_date);
			if (has_this_date) {
				start_date = icaltime_from_timet_with_zone (e_ews_item_get_start_date (item), 0, user_timezone);
				start_date.is_date = 1;
				icalprop = icalproperty_new_dtstart (start_date);
				icalcomponent_add_property (icalcomp, icalprop);
			}

			/*status*/
			ews_task_status = e_ews_item_get_status (item);
			if (g_strcmp0 (ews_task_status, "NotStarted") != 0) {
				if (g_strcmp0 (ews_task_status, "Completed") == 0)
					status = ICAL_STATUS_COMPLETED;
				else if (g_strcmp0 (ews_task_status, "InProgress") == 0)
					status = ICAL_STATUS_INPROCESS;
				else if (g_strcmp0 (ews_task_status, "WaitingOnOthers") == 0)
					status = ICAL_STATUS_NEEDSACTION;
				else if (g_strcmp0 (ews_task_status, "Deferred") == 0)
					status = ICAL_STATUS_CANCELLED;
				icalprop = icalproperty_new_status (status);
				icalcomponent_add_property (icalcomp, icalprop);
			}

			/*precent complete*/
			percent_complete = e_ews_item_get_percent_complete (item);
			icalprop  = icalproperty_new_percentcomplete (atoi (percent_complete ? percent_complete : "0"));
			icalcomponent_add_property (icalcomp, icalprop);

			/*due date*/
			e_ews_item_task_has_due_date (item, &has_this_date);
			if (has_this_date) {
				due_date = icaltime_from_timet_with_zone (e_ews_item_get_due_date (item), 0, user_timezone);
				due_date.is_date = 1;
				icalprop = icalproperty_new_due (due_date);
				icalcomponent_add_property (icalcomp, icalprop);
			}

			/*complete date*/
			has_this_date = FALSE;
			e_ews_item_task_has_complete_date (item, &has_this_date);
			if (has_this_date) {
				complete_date = icaltime_from_timet_with_zone (e_ews_item_get_complete_date (item), 0, user_timezone);
				icalprop = icalproperty_new_completed (complete_date);
				icalcomponent_add_property (icalcomp, icalprop);
			}

			/*priority*/
			item_importance = e_ews_item_get_importance (item);
			if (item_importance == EWS_ITEM_HIGH)
				priority = 3;
			else if (item_importance == EWS_ITEM_LOW)
				priority = 7;
			icalprop = icalproperty_new_priority (priority);
			icalcomponent_add_property (icalcomp, icalprop);

			/* recurrence */
			e_ews_cal_utils_recurrence_to_rrule (item, icalcomp);

			/* reminders */
			/* The Exchange server stores start of the Task reminder and Start of the Task
			   itself in separate properties, which doesn't work for evolution at the moment. */
			/* if (e_ews_item_get_reminder_is_set (item)) {
				time_t reminder_due_by = e_ews_item_get_reminder_due_by (item);
				gint minutes_before_start = e_ews_item_get_reminder_minutes_before_start (item);

				if (minutes_before_start >= 0 && reminder_due_by > (time_t) 0) {
					ECalComponentAlarmTrigger trigger;
					ECalComponentAlarmRepeat repeat;
					ECalComponentAlarm *alarm;
					icalcomponent *alarm_icalcomp;
					struct icaltimetype dtstart, due_by;

					dtstart = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, NULL, icalcomp, ICAL_DTSTART_PROPERTY, icalproperty_get_dtstart);
					due_by = icaltime_from_timet_with_zone (reminder_due_by, 0, utc_zone);

					if (icaltime_is_null_time (dtstart)) {
						dtstart = due_by;
						dtstart.is_date = 1;

						icalcomponent_set_dtstart (icalcomp, dtstart);
					}

					dtstart.is_date = 0;
					dtstart.hour = 0;
					dtstart.minute = 0;
					dtstart.second = 0;
					dtstart.zone = utc_zone;

					minutes_before_start = minutes_before_start + (
						(icaltime_as_timet_with_zone (dtstart, utc_zone) -
						 icaltime_as_timet_with_zone (due_by, utc_zone)) / 60);

					alarm = e_cal_component_alarm_new ();
					memset (&trigger, 0, sizeof (ECalComponentAlarmTrigger));

					trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
					trigger.u.rel_duration.is_neg = minutes_before_start < 0 ? 0 : 1; / * negative 'before start' means 'after start' * /
					trigger.u.rel_duration.minutes = minutes_before_start < 0 ? -minutes_before_start : minutes_before_start;

					memset (&repeat, 0, sizeof (repeat));
					repeat.repetitions = 0;

					e_cal_component_alarm_set_trigger (alarm, trigger);
					e_cal_component_alarm_set_action (alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
					e_cal_component_alarm_set_repeat (alarm, repeat);

					alarm_icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
					if (alarm_icalcomp)
						icalcomponent_add_component (icalcomp, alarm_icalcomp);

					e_cal_component_alarm_free (alarm);
				}
			} */
		}

		icalcomponent_add_component (vcomp, icalcomp);
	} else {
		struct icaltimetype dt;
		const gchar *mime_content;
		const gchar *tzid;
		gboolean timezone_set = FALSE;

		mime_content = e_ews_item_get_mime_content (item);
		vcomp = mime_content && *mime_content ? icalparser_parse_string (mime_content) : NULL;

		if (!vcomp && mime_content && *mime_content) {
			const gchar *begin_vcalendar, *end_vcalendar;

			/* Workaround Exchange 2016 error, which returns invalid iCalendar object (without 'END:VCALENDAR'),
			   when the event has at least one detached instance. */
			begin_vcalendar = camel_strstrcase (mime_content, "BEGIN:VCALENDAR");
			end_vcalendar = camel_strstrcase (mime_content, "END:VCALENDAR");

			/* If it exists, then it should be alone on a separate line */
			if (!(begin_vcalendar && (begin_vcalendar == mime_content || begin_vcalendar[-1] == '\n') &&
			    (begin_vcalendar[15 /* strlen ("BEGIN:VCALENDAR") */] == '\r' || begin_vcalendar[15] == '\n')))
				begin_vcalendar = NULL;

			/* If it exists, then it should be alone on a separate line and not at the very beginning of the mime_content */
			if (!(end_vcalendar && end_vcalendar > mime_content && end_vcalendar[-1] == '\n' &&
			    (end_vcalendar[13 /* strlen ("END:VCALENDAR") */] == '\r' || end_vcalendar[13] == '\n' || end_vcalendar[13] == '\0')))
				end_vcalendar = NULL;

			if (begin_vcalendar && !end_vcalendar) {
				gchar *str;

				str = g_strconcat (mime_content, "\r\n", "END:VCALENDAR", "\r\n", NULL);
				vcomp = icalparser_parse_string (str);
				g_free (str);
			}
		}

		if (!vcomp) {
			if (mime_content)
				g_warning ("%s: Failed to parse mime content:---%s---", G_STRFUNC, mime_content);
			return NULL;
		}

		tzid = e_ews_item_get_tzid (item);
		if (tzid == NULL) {
			/*
			 * When we are working with Exchange server 2010 or newer, we have to handle a few
			 * things more than we do working old servers. These things are:
			 * - MSDN timezone names:
			 *   Used setting StartTimeZone and EndTimeZone. MSDN timezone names are not
			 *   the same used in libical, so we need to have a table of equivalence to
			 *   convert from one to another and avoid show the MSDN timezone name to the
			 *   user and save it in the ETimezoneCache.
			 * - EvoEWSStartTimeZone/EvoEWSEndTimeZone
			 *   Used to keep track if the timezone shown to the user is the same one set
			 *   by him/her. As we have a table of equivalence, sometimes the user sets a
			 *   timezone but without EvoEWSStartTiemZone property, another timezone name,
			 *   in the same offset, can be shown. And we want to avoid this.
			 * - DTEND property:
			 *   As we have to work with DTEND setting an event when using EWS server 2010 or
			 *   newer, we have to care about set it properly here, instead of use the same
			 *   as is used in DTSTART.
			 */
			icaltimezone *start_zone, *end_zone;
			const gchar *start_tzid, *end_tzid;
			const gchar *ical_start_tzid, *ical_end_tzid;
			const gchar *evo_ews_start_tzid, *evo_ews_end_tzid;

			start_tzid = e_ews_item_get_start_tzid (item);
			end_tzid = e_ews_item_get_end_tzid (item);

			ical_start_tzid = e_cal_backend_ews_tz_util_get_ical_equivalent (start_tzid);
			ical_end_tzid = e_cal_backend_ews_tz_util_get_ical_equivalent (end_tzid);

			evo_ews_start_tzid = e_ews_item_get_iana_start_time_zone (item);
			evo_ews_end_tzid = e_ews_item_get_iana_end_time_zone (item);

			/*
			 * We have a few timezones that don't have an equivalent MSDN timezone.
			 * For those, we will get ical_start_tzid being NULL and then we need to use
			 * start_tzid, which one has the libical's expected name.
			 */
			start_zone = ecb_ews_get_timezone (
				timezone_cache,
				start_tzid,
				ical_start_tzid != NULL ? ical_start_tzid : start_tzid,
				evo_ews_start_tzid);
			end_zone = ecb_ews_get_timezone (
				timezone_cache,
				end_tzid,
				ical_end_tzid != NULL ? ical_end_tzid : end_tzid,
				evo_ews_end_tzid);

			if (start_zone != NULL) {
				icalcomp = icalcomponent_get_first_component (vcomp, kind);

				dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icalcomp, ICAL_DTSTART_PROPERTY, icalproperty_get_dtstart);
				dt = icaltime_convert_to_zone (dt, start_zone);
				icalcomponent_set_dtstart (icalcomp, dt);

				timezone_set = TRUE;
				e_timezone_cache_add_timezone (timezone_cache, start_zone);

				if (end_zone != NULL) {
					dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icalcomp, ICAL_DTEND_PROPERTY, icalproperty_get_dtend);
					dt = icaltime_convert_to_zone (dt, end_zone);
					icalcomponent_set_dtend (icalcomp, dt);

					e_timezone_cache_add_timezone (timezone_cache, end_zone);
				}
			}

			if (!timezone_set)
				tzid = start_tzid;
		}

		if (!timezone_set && tzid) {
			/*
			 * When we are working with Exchange server older than 2010, we don't set different
			 * DTSTART and DTEND properties in VTIMEZONE. The reason of that is we don't use
			 * those properties settings/changing a meeting timezone.
			 * So, for older servers, here, we only set the DTSTART and DTEND properties with
			 * the same values.
			 */
			icaltimezone *zone;
			gchar *new_tzid = NULL;

			icalcomp = icalcomponent_get_first_component (vcomp, kind);

			if (!icaltimezone_get_builtin_timezone (tzid) &&
			    icalcomponent_get_uid (icalcomp)) {
				icalcomponent *vtimezone;

				/* Add the timezone */
				vtimezone = icalcomponent_get_first_component (vcomp, ICAL_VTIMEZONE_COMPONENT);
				if (vtimezone != NULL) {
					icalproperty *prop;

					new_tzid = g_strconcat ("/evolution/ews/tzid/", icalcomponent_get_uid (icalcomp), NULL);

					zone = icaltimezone_new ();
					vtimezone = icalcomponent_new_clone (vtimezone);
					prop = icalcomponent_get_first_property (vtimezone, ICAL_TZID_PROPERTY);
					if (prop) {
						icalproperty_set_tzid (prop, new_tzid);

						prop = icalcomponent_get_first_property (vtimezone, ICAL_LOCATION_PROPERTY);
						if (!prop) {
							/* Use the original tzid as the timezone Location, to not expose
							   evolution-ews TZID. */
							prop = icalproperty_new_location (tzid);
							icalcomponent_add_property (vtimezone, prop);
						}
					} else {
						g_free (new_tzid);
						new_tzid = NULL;
					}
					icaltimezone_set_component (zone, vtimezone);
					e_timezone_cache_add_timezone (timezone_cache, zone);
					icaltimezone_free (zone, TRUE);
				}
			}

			zone = e_timezone_cache_get_timezone (timezone_cache, new_tzid ? new_tzid : tzid);

			if (!zone && new_tzid)
				zone = e_timezone_cache_get_timezone (timezone_cache, tzid);

			if (zone == NULL)
				zone = icaltimezone_get_builtin_timezone (tzid);

			if (zone != NULL) {
				dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icalcomp, ICAL_DTSTART_PROPERTY, icalproperty_get_dtstart);
				dt = icaltime_convert_to_zone (dt, zone);
				icalcomponent_set_dtstart (icalcomp, dt);

				dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icalcomp, ICAL_DTEND_PROPERTY, icalproperty_get_dtend);
				dt = icaltime_convert_to_zone (dt, zone);
				icalcomponent_set_dtend (icalcomp, dt);
			}

			g_free (new_tzid);
		}
	}

	/* Vevent or Vtodo */
	icalcomp = icalcomponent_get_first_component (vcomp, kind);
	if (icalcomp) {
		icalproperty *icalprop, *freebusy;
		struct icaltimetype itt;
		const EwsId *item_id;
		const GSList *l = NULL;
		const gchar *uid = e_ews_item_get_uid (item);

		item_id = e_ews_item_get_id (item);

		if (e_ews_item_get_is_meeting (item)) {
			gboolean is_response_requested = e_ews_item_get_is_response_requested (item);
			gchar *user_email;

			user_email = camel_ews_settings_dup_email (ews_settings);

			/* Attendees */
			for (l = e_ews_item_get_attendees (item); l != NULL; l = g_slist_next (l)) {
				icalparameter *param, *cu_type;
				gchar *mailtoname;
				const gchar *email = NULL;
				EwsAttendee *attendee = (EwsAttendee *) l->data;

				if (!attendee->mailbox)
					continue;

				if (g_strcmp0 (attendee->mailbox->routing_type, "EX") == 0)
					email = e_ews_item_util_strip_ex_address (attendee->mailbox->email);

				mailtoname = g_strdup_printf ("mailto:%s", email ? email : attendee->mailbox->email);
				icalprop = icalproperty_new_attendee (mailtoname);
				g_free (mailtoname);

				param = icalparameter_new_cn (attendee->mailbox->name);
				icalproperty_add_parameter (icalprop, param);

				if (g_ascii_strcasecmp (attendee->attendeetype, "Required") == 0) {
					param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT);
					cu_type = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
				}
				else if (g_ascii_strcasecmp (attendee->attendeetype, "Resource") == 0) {
					param = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT);
					cu_type = icalparameter_new_cutype (ICAL_CUTYPE_RESOURCE);
				}
				else {
					param = icalparameter_new_role ( ICAL_ROLE_OPTPARTICIPANT);
					cu_type = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
				}
				icalproperty_add_parameter (icalprop, cu_type);
				icalproperty_add_parameter (icalprop, param);

				if (is_response_requested) {
					param = icalparameter_new_rsvp (ICAL_RSVP_TRUE);
					icalproperty_add_parameter (icalprop, param);
				}

				if (user_email && (email || attendee->mailbox->email) && e_ews_item_get_my_response_type (item) &&
				    g_ascii_strcasecmp (email ? email : attendee->mailbox->email, user_email) == 0) {
					param = ecb_ews_responsetype_to_partstat (e_ews_item_get_my_response_type (item));
				} else {
					param = ecb_ews_responsetype_to_partstat (attendee->responsetype);
				}
				icalproperty_add_parameter (icalprop, param);

				icalcomponent_add_property (icalcomp, icalprop);
			}

			g_free (user_email);
		}

		/* Free/Busy */
		freebusy = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
		if (!freebusy && (e_ews_item_get_item_type (item) != E_EWS_ITEM_TYPE_TASK)) {
			/* Busy by default */
			freebusy = icalproperty_new_transp (ICAL_TRANSP_OPAQUE);
			icalcomponent_add_property (icalcomp, freebusy);
		}
		for (icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
		     icalprop != NULL;
		     icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY)) {
			if (g_strcmp0 (icalproperty_get_x_name (icalprop), "X-MICROSOFT-CDO-BUSYSTATUS") == 0) {
				if (g_strcmp0 (icalproperty_get_value_as_string (icalprop), "BUSY") == 0) {
					icalproperty_set_transp (freebusy, ICAL_TRANSP_OPAQUE);
				} else {
					icalproperty_set_transp (freebusy, ICAL_TRANSP_TRANSPARENT);
				}

				break;
			}
		}

		/* AllDayEvent */
		for (icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
		     icalprop != NULL;
		     icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY)) {
			if (g_strcmp0 (icalproperty_get_x_name (icalprop), "X-MICROSOFT-CDO-ALLDAYEVENT") == 0) {
				if (g_strcmp0 (icalproperty_get_value_as_string (icalprop), "TRUE") == 0) {
					struct icaltimetype dtend, dtstart;
					dtstart = icalcomponent_get_dtstart (icalcomp);
					dtstart.is_date = 1;
					icalcomponent_set_dtstart (icalcomp, dtstart);

					dtend = icalcomponent_get_dtend (icalcomp);
					dtend.is_date = 1;
					icalcomponent_set_dtend (icalcomp, dtend);
				}
				break;
			}
		}

		if (icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY)) {
			/* Exchange sets RRULE even on the children, which is broken */
			icalprop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
			if (icalprop) {
				icalcomponent_remove_property (icalcomp, icalprop);
				icalproperty_free (icalprop);
			}
		}

		/* The EXDATE sent by the server can be date-time format with timezone, while
		   the event start time can be date-only. This breaks the rules, thus correct
		   it and make also EXDATE date-only. */
		itt = icalcomponent_get_dtstart (icalcomp);
		if (icaltime_is_valid_time (itt) && itt.is_date) {
			for (icalprop = icalcomponent_get_first_property (icalcomp, ICAL_EXDATE_PROPERTY);
			     icalprop;
			     icalprop = icalcomponent_get_next_property (icalcomp, ICAL_EXDATE_PROPERTY)) {
				itt = icalproperty_get_exdate (icalprop);
				itt.is_date = 1;
				icalproperty_set_exdate (icalprop, itt);

				icalproperty_remove_parameter_by_kind (icalprop, ICAL_TZID_PARAMETER);
			}
		}

		/* Exchange sets an ORGANIZER on all events. RFC2445 says:
		 *
		 *   This property MUST NOT be specified in an iCalendar
		 *   object that specifies only a time zone definition or
		 *   that defines calendar entities that are not group
		 *   scheduled entities, but are entities only on a single
		 *   user's calendar.
		 */
		if (!icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
			if ((icalprop = icalcomponent_get_first_property (icalcomp, ICAL_ORGANIZER_PROPERTY))) {
				icalcomponent_remove_property (icalcomp, icalprop);
				icalproperty_free (icalprop);
			}
		}

		icalcomponent_set_uid (icalcomp, uid ? uid : item_id->id);

		e_cal_util_set_x_property (icalcomp, "X-EVOLUTION-ITEMID", item_id->id);
		e_cal_util_set_x_property (icalcomp, "X-EVOLUTION-CHANGEKEY", item_id->change_key);

		res_component = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icalcomp));

		/* Categories */
		e_cal_component_set_categories_list (res_component, (GSList *) e_ews_item_get_categories (item));

		/*
		 * There is no API to set/get alarm description on the server side.
		 * However, for some reason, the alarm description has been set to "REMINDER"
		 * automatically (and with no i18n). Instead of show it to the user, let's
		 * set the summary as the alarm description.
		 */
		if (e_cal_component_has_alarms (res_component)) {
			GList *alarm_uids, *l;

			alarm_uids = e_cal_component_get_alarm_uids (res_component);
			for (l = alarm_uids; l != NULL; l = l->next) {
				ECalComponentAlarm *alarm;
				ECalComponentText text;

				alarm = e_cal_component_get_alarm (res_component, l->data);
				e_cal_component_get_summary (res_component, &text);
				e_cal_component_alarm_set_description (alarm, &text);

				e_cal_component_alarm_free (alarm);
			}
			cal_obj_uid_list_free (alarm_uids);
		}
	}

	icalcomponent_free (vcomp);

	if (res_component) {
		const GSList *attachment_ids, *aid, *l;
		const gchar *uid = NULL;
		GSList *info_attachments = NULL, *uris = NULL;
		gboolean has_attachment = FALSE;

		e_ews_item_has_attachments (item, &has_attachment);
		if (!has_attachment)
			return res_component;

		e_cal_component_get_uid (res_component, &uid);

		attachment_ids = e_ews_item_get_attachments_ids (item);

		if (e_ews_connection_get_attachments_sync (
			cbews->priv->cnc,
			EWS_PRIORITY_MEDIUM,
			uid,
			attachment_ids,
			cbews->priv->attachments_dir,
			TRUE,
			&info_attachments,
			NULL, NULL,
			cancellable,
			NULL)) {
			icalcomponent *icalcomp;
			icalproperty *icalprop;
			icalparameter *icalparam;

			for (l = info_attachments; l; l = l->next) {
				EEwsAttachmentInfo *info = l->data;

				/* ignore non-uri attachments, because it's an exception */
				if (e_ews_attachment_info_get_type (info) == E_EWS_ATTACHMENT_INFO_TYPE_URI) {
					const gchar *uri = e_ews_attachment_info_get_uri (info);

					if (uri)
						uris = g_slist_append (uris, g_strdup (uri));
				}
			}

			e_cal_component_set_attachment_list (res_component, uris);

			icalcomp = e_cal_component_get_icalcomponent (res_component);
			icalprop = icalcomponent_get_first_property (icalcomp, ICAL_ATTACH_PROPERTY);
			for (aid = attachment_ids; aid && icalprop; aid = aid->next, icalprop = icalcomponent_get_next_property (icalcomp, ICAL_ATTACH_PROPERTY)) {
				icalparam = icalparameter_new_x (aid->data);
				icalparameter_set_xname (icalparam, "X-EWS-ATTACHMENTID");
				icalproperty_add_parameter (icalprop, icalparam);
			}

			g_slist_free_full (uris, g_free);
			g_slist_free_full (info_attachments, (GDestroyNotify) e_ews_attachment_info_free);
		}
	}

	return res_component;
}