/// <summary>
        /// Syncs WFM schedule XML to Outlook calendar
        /// </summary>
        /// <remarks>
        /// Sync logic is very basic. We delete all future meetings and create new ones based on WFM schedule.
        /// </remarks>
        /// <param name="scheduleXml">Full XML response from WFM</param>
        private void InternalSync(string scheduleXml)
        {
            WfmSchedule schedule = WfmSchedule.Parse(scheduleXml);

            string[] segmentFilter    = Globals.ThisAddIn.userOptions.segmentFilter.ToLower().Split(new char[] { ';', ',' }).Select(s => s.Trim()).ToArray();
            var      matchingSegments = schedule.GetMatchingSegments(segmentFilter);

            Log.WriteEntry(String.Format("Found {0} segments from WFM with {1} segment names: {2}", matchingSegments.Count, userOptions.syncMode, String.Join(", ", segmentFilter)));

            if (Globals.ThisAddIn.userOptions.lastSyncTime == DateTime.MinValue && matchingSegments.Count == 0)
            {
                // this is the first run of the meeting and there were no segments found
                MessageBox.Show(String.Format("I noticed this is your first WFM for Outlook sync and we did not find any segments from WFM. Please ensure that your segment filter is configured correctly.", userOptions.segmentFilter),
                                "First sync notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            int stats_meetingsDeleted = DeleteFutureMeetings();

            var syncTimeNow = DateTime.Now;

            int stats_totalSegmentsFromWfm = schedule.Segments.Count;
            int stats_meetingsCreated      = 0;

            int PercentPerSegment = (int)Math.Floor(40.0 / (double)stats_totalSegmentsFromWfm);
            int progressPercent   = 60;

            Globals.Ribbons.CalendarIntegrationRibbon.syncBackgroundWorker.ReportProgress(progressPercent);

            Log.WriteDebug("SyncEngine : Starting meeting creation loop");
            foreach (var seg in matchingSegments)
            {
                CreateMeetingOnCalendar(syncTimeNow, seg);
                stats_meetingsCreated++;

                Log.WriteDebug(String.Format("SyncEngine : meeting created \r\n{0}", seg.ToString()));

                // update progress
                progressPercent += PercentPerSegment;
                Globals.Ribbons.CalendarIntegrationRibbon.syncBackgroundWorker.ReportProgress(progressPercent);
            }

            // output stats to our sync log
            Log.WriteEntry(String.Format("Segments from WFM: {0}\r\nMeetings created: {1}\r\nMeetings deleted: {2}",
                                         stats_totalSegmentsFromWfm, stats_meetingsCreated, stats_meetingsDeleted));
        }
        public static WfmSchedule Parse(string xml)
        {
            WfmSchedule schedule = new WfmSchedule();

            //var xmlDoc = XDocument.Load(@"C:\sources\WFM-For-Outlook\WFM For Outlook\eeSchedule.xml");
            var xmlDoc = XDocument.Parse(xml);

            // extract segment code-to-name dictionary
            var segmentCodes = from c in xmlDoc.Root.Descendants("SegmentCodes").Descendants("SegmentCode")
                               select c;

            foreach (var segmentCode in segmentCodes)
            {
                var code = segmentCode.Attribute("SK").Value;
                var name = segmentCode.Element("Code").Value;
                schedule.SegmentCodeToName.Add(code, name);
            }

            // extract segments
            var segments = from s in xmlDoc.Root.Descendants("Segments").Descendants()
                           where s.Name == "DetailSegment" || s.Name == "GeneralSegment"
                           select s;

            foreach (var segment in segments)
            {
                string  code = segment.Element("SegmentCode").Attribute("SK").Value;
                string  name; schedule.SegmentCodeToName.TryGetValue(code, out name);
                Segment s = new Segment()
                {
                    Code        = code,
                    Name        = name,
                    Memo        = segment.Element("Memo").Value,
                    IsAllDay    = segment.Name.ToString().Equals("GeneralSegment", StringComparison.InvariantCultureIgnoreCase),
                    StartTime   = segment.Element("StartTime") == null ? DateTime.MinValue : DateTime.Parse(segment.Element("StartTime").Value),
                    EndTime     = segment.Element("StopTime") == null ? DateTime.MinValue : DateTime.Parse(segment.Element("StopTime").Value),
                    NominalDate = DateTime.Parse(segment.Element("NominalDate").Value),
                };
                schedule.Segments.Add(s);
            }

            return(schedule);
        }