public static void PublishRosterEvent(Guid itemId, int daysAhead)
        {
            var dataService = new RosterDataService();
            var item        = dataService.GetRosterEvent(itemId);

            if (item == null)
            {
                throw new Exception(string.Format("Roster with ID '{0}' does not exists!", itemId));
            }
            if (!item.GetIsRecurrence())
            {
                throw new Exception(string.Format("Unable to publish non recurrent Roster Event with ID '{0}'!", itemId));
            }
            var wrListFields = new RosterConfigService().GetList(TableIDs.WORKING_ROSTERS).ListMetadataFields;

            var plannedRosterProps = item.RosterEventDictionary;
            var publishPeriodStart = DateTime.Today;
            var publishPeriodEnd   = DateTime.Today.AddDays(daysAhead);
            var expandedEvents     = RecurrenceItemExpander.Expand(new List <RosterEvent> {
                item
            },
                                                                   null, publishPeriodStart, publishPeriodEnd,
                                                                   FieldNames.START_DATE, FieldNames.END_DATE,
                                                                   SPContext.Current.Web.RegionalSettings.TimeZone);
            var skipProps = new[]
            {
                FieldNames.START_DATE, FieldNames.END_DATE,
                FieldNames.RECURRENCE, FieldNames.ROSTER_EVENT_ID,
                FieldNames.ID, FieldNames.PARENT_ROSTER_ID
            };
            var expandedRosterEvents = expandedEvents as IList <ExpandedRosterEvent> ?? expandedEvents.ToList();

            publishPeriodStart = expandedRosterEvents.Min(expandedEvent => expandedEvent.StartDate);
            publishPeriodEnd   = expandedRosterEvents.Max(expandedEvent => expandedEvent.StartDate);

            #region Get Working Rosters from period to avoid duplicates

            // get required fields
            var startDateFld = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.START_DATE);
            var endDateFld   = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.END_DATE);
            var parentIdFld  = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.PARENT_ROSTER_ID);
            var rEventIdFld  = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.ROSTER_EVENT_ID);

            var qp = new QueryParams {
                SkipRows = 0, TakeRows = 500
            };
            qp.SelectCriteria.Add(startDateFld);
            qp.SelectCriteria.Add(rEventIdFld);
            qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string>
                                     (parentIdFld, CompareType.Equal, ConcateOperator.And, itemId, null));
            qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string>
                                     (startDateFld, CompareType.LessOrEqual, ConcateOperator.And, publishPeriodEnd, null));
            qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string>
                                     (endDateFld, CompareType.MoreOrEqual, ConcateOperator.And, publishPeriodStart, null));

            var existingWorkRosters = dataService.ListRosterEventProperties(TableIDs.WORKING_ROSTERS, qp);
            var existingKeys        = existingWorkRosters.Select(wrProps => wrProps.FirstOrDefault(ff =>
                                                                                                   ff.Key == FieldNames.START_DATE)).Select(stKey => (DateTime)stKey.Value).ToList();

            #endregion

            foreach (var expEvent in expandedRosterEvents)
            {
                var startDate = expEvent.StartDate;
                var endDate   = expEvent.EndDate;
                if (existingKeys.Contains(startDate))
                {
                    continue;
                }                                                   // this WorkingRoster instance already published
                var newRoEv = dataService.CreateRosterEvent(TableIDs.WORKING_ROSTERS, (int)RosterEventType.WorkingRosterEvent);
                newRoEv.RosterEventDictionary[FieldNames.START_DATE]       = startDate;
                newRoEv.RosterEventDictionary[FieldNames.END_DATE]         = endDate;
                newRoEv.RosterEventDictionary[FieldNames.END_DATE]         = endDate;
                newRoEv.RosterEventDictionary[FieldNames.RECURRENCE]       = null;
                newRoEv.RosterEventDictionary[FieldNames.PARENT_ROSTER_ID] = itemId;
                foreach (var propName in plannedRosterProps.Keys.Where(propName => !skipProps.Contains(propName)))
                {
                    newRoEv.RosterEventDictionary[propName] = plannedRosterProps[propName];
                }
                dataService.SaveRosterEvent(newRoEv, TableIDs.WORKING_ROSTERS);
            }
        }