// end of accessor public TimeZone TimeZone


        //////////////////////////////////////////////////////////////////////
        /// <summary>searches through the evententries to
        /// find the original event</summary>
        /// <param name="original">The original event to find</param>
        /// <returns> </returns>
        //////////////////////////////////////////////////////////////////////
        public EventEntry FindEvent(OriginalEvent original)
        {
            // first try the internal cache

            foreach (EventEntry entry  in this.Entries)
            {
                if (entry.SelfUri.ToString() == original.Href)
                {
                    return(entry);
                }
            }

            // did not find it in the cache. Need to call the server to get it.
            CalendarService calService = this.Service as CalendarService;

            if (calService != null)
            {
                EventQuery query   = new EventQuery(original.Href);
                EventFeed  newFeed = (EventFeed)calService.Query(query);

                if (newFeed != null && newFeed.Entries != null)
                {
                    Tracing.Assert(newFeed.Entries.Count == 1, "There should be just one entry returned");
                    return(newFeed.Entries[0] as EventEntry);
                }
            }
            return(null);
        }
示例#2
0
        public static void DeleteEventfromall(string oldTitle, string newTitle, string contents, string location, DateTime startTime, DateTime endTime, string calendarname)
        {
            GoogleCalendar ggadmin    = new GoogleCalendar(calendarname, AdminuserName, AdminuserPwd);
            string         CalendarId = ggadmin.GetCalendarId();


            Uri oCalendarUri = new Uri("http://www.google.com/calendar/feeds/" + CalendarId + "/private/full");

            string[] oldtitle = oldTitle.Split('-');
            //Search for Event
            EventQuery oEventQuery = new EventQuery(oCalendarUri.ToString());

            //oEventQuery.Query = oldTitle;
            //oEventQuery.StartDate = startTime;
            //oEventQuery.EndDate = startTime.AddDays(1);
            Google.GData.Calendar.EventFeed oEventFeed = GetService("GoogleCalendar", AdminuserName, AdminuserPwd).Query(oEventQuery);

            //Delete Related Events
            foreach (EventEntry oEventEntry in oEventFeed.Entries)
            {
                //Do your stuff here
                string[] item = oEventEntry.Title.Text.Split('-');
                if (oldtitle[0].ToString() == item[0].ToString())
                {
                    oEventEntry.Delete();
                }
            }
        }
示例#3
0
    protected bool nastanotPostoi()
    {
        bool postoi = false;

        Google.GData.Calendar.EventEntry novNastan = (Google.GData.Calendar.EventEntry)Session["novNastan"];
        string                 calendarId          = ddlKalendari.SelectedItem.Value;
        EventQuery             evQuery             = new EventQuery();
        GAuthSubRequestFactory authFactory         = new GAuthSubRequestFactory("cl", "FEITPortal");

        authFactory.Token = (string)Session["sessionToken"];
        myCalendarService.RequestFactory = authFactory;
        evQuery.Uri = new Uri("http://www.google.com/calendar/feeds/" + calendarId + "/private/full");
        Google.GData.Calendar.EventFeed evFeed = myCalendarService.Query(evQuery) as Google.GData.Calendar.EventFeed;

        if (evFeed != null)
        {
            foreach (Google.GData.Calendar.EventEntry en in evFeed.Entries)
            {
                string[] newEventId = novNastan.Content.Content.Split(':');
                string[] eventId    = en.Content.Content.Split(':');
                int      novLength  = newEventId.Length;
                int      starLength = eventId.Length;
                if (eventId[starLength - 1] == newEventId[novLength - 1])
                {
                    postoi = true;
                    break;
                }
            }
        }
        return(postoi);
    }
示例#4
0
        private static EventEntry InsertEvent(EventFeed feed, String title, 
            String author, DateTime startTime, DateTime endTime, bool fAllDay,
            String place)
        {
            EventEntry entry = new EventEntry();

            entry.Title = new AtomTextConstruct(
                                AtomTextConstructElementType.Title, 
                                title);
            entry.Authors.Add(new AtomPerson(AtomPersonType.Author, author));
            entry.Published = DateTime.Now;
            entry.Updated = DateTime.Now;


            Where newPlace = new Where();
            newPlace.ValueString = place;
            entry.Locations.Add(newPlace);

            When newTime = new When();
            newTime.StartTime = startTime;
            newTime.EndTime = endTime;
            newTime.AllDay = fAllDay; 
            entry.Times.Add(newTime);

            return feed.Insert(entry) as EventEntry;
        }
        public void HasEvents_NoEvents_ReturnsFalse()
        {
            var feed = new EventFeed( null, null );

            _calendarService.Setup( x => x.Query( It.IsAny<EventQuery>() ) ).Returns( feed );

            bool hasEvents = _calendarPurge.HasEvents();

            Assert.IsFalse( hasEvents );
        }
        public void HasEvents_WithEvents_ReturnsTrue()
        {
            var feed = new EventFeed( null, null );
            feed.Entries.Add( new EventEntry() );

            _calendarService.Setup( x => x.Query( It.IsAny<EventQuery>() ) ).Returns( feed );

            bool hasEvents = _calendarPurge.HasEvents();

            Assert.IsTrue( hasEvents );
        }
示例#7
0
    private void GetEvents()
    {
        CalendarService oCalendarService = GAuthenticate();
        //Uri oCalendarUri = new Uri("https://www.google.com/calendar/feeds/[email protected]/private/full");

        //Search for Event
        EventQuery oEventQuery = new EventQuery();

        oEventQuery.Uri = new Uri("https://www.google.com/calendar/feeds/[email protected]/private/full");
        //oEventQuery.Query = "Query String";
        oEventQuery.ExtraParameters = "orderby=starttime&sortorder=ascending";
        oEventQuery.StartTime       = DateTime.Now;
        oEventQuery.EndTime         = DateTime.Now.AddDays(50);
        //oEventQuery.SingleEvents = true;

        Google.GData.Calendar.EventFeed oEventFeed = oCalendarService.Query(oEventQuery);
        string    dt    = "";
        DataTable table = new DataTable();

        table.Columns.Add(new DataColumn("EventTitle"));
        table.Columns.Add(new DataColumn("EventSummary"));
        table.Columns.Add(new DataColumn("EventStartDate"));
        table.Columns.Add(new DataColumn("EventEndDate"));
        table.Columns.Add(new DataColumn("EventStatus"));
        table.Columns.Add(new DataColumn("EventId"));
        table.Columns.Add(new DataColumn("EventLocation"));
        table.Columns.Add(new DataColumn("EventUId"));

        foreach (var entry in oEventFeed.Entries)
        {
            Google.GData.Calendar.EventEntry eventEntry = entry as Google.GData.Calendar.EventEntry;
            if (eventEntry != null)
            {
                if (eventEntry.Times.Count != 0)
                {
                    DataRow dr = table.NewRow();
                    dr["EventUId"]       = eventEntry.Uid.Value;
                    dr["EventId"]        = eventEntry.EventId.ToString();
                    dr["EventTitle"]     = eventEntry.Title.Text;
                    dr["EventSummary"]   = eventEntry.Summary.Text;
                    dr["EventStartDate"] = eventEntry.Times[0].StartTime.ToString("dd/MM/yyyy");
                    dr["EventEndDate"]   = eventEntry.Times[0].EndTime.ToString("dd/MM/yyyy");
                    dr["EventStatus"]    = eventEntry.Status.Value.ToString();
                    dr["EventLocation"]  = Convert.ToString(eventEntry.Locations[0].ValueString);
                    table.Rows.Add(dr);
                    //dt = dt + eventEntry.Title.Text + "<br/>";
                }
            }
        }
        //eventsLabel.Text = dt;
        gvCal.DataSource = table;
        gvCal.DataBind();
    }
 public void TestConvertEventsToFreeBusy()
 {
     ExchangeUser user = new ExchangeUser();
     EventEntry googleAppsEvent = new EventEntry("title", "description", "location");
     DateTimeRange coveredRange = new DateTimeRange(DateTime.MaxValue, DateTime.MinValue);
     List<DateTimeRange> busyTimes = new List<DateTimeRange>();
     List<DateTimeRange> tentativeTimes = new List<DateTimeRange>();
     DateTime startDate = new DateTime(2007, 07, 1, 10, 0, 0, DateTimeKind.Utc);
     DateTime endDate = new DateTime(2007, 07, 1, 11, 0, 0, DateTimeKind.Utc);
     When when = new When(startDate, endDate);
     Uri uri = new Uri("https://www.google.com/calendar/feeds/[email protected]/private/full");
     EventFeed googleAppsFeed = new EventFeed(uri, null);
     AtomEntryCollection entries = new AtomEntryCollection(googleAppsFeed);
 }
        /// <summary>
        /// Sync a users free busy information between Google Calendar and the
        /// SchedulePlus Public Folder store
        /// </summary>
        /// <param name="user">The user to synchronize</param>
        /// <param name="googleAppsFeed">The Google Calendar events for the user</param>
        /// <param name="exchangeGateway">The Exchange Gateway to use</param>
        /// <param name="window">The DateTimeRange to synchronize for</param>
        public void SyncUser(
            ExchangeUser user,
            EventFeed googleAppsFeed,
            ExchangeService exchangeGateway,
            DateTimeRange window)
        {
            if (_log.IsInfoEnabled)
            {
                _log.InfoFormat("Creating F/B message.  [User={0}]", user.Email);
                _log.DebugFormat("The feed time zone is {0}", googleAppsFeed.TimeZone.Value);
            }

            string userFreeBusyUrl = FreeBusyUrl.GenerateUrlFromDN(_exchangeServerUrl,
                                                                   user.LegacyExchangeDN);

            List<string> busyMonthValues = new List<string>();
            List<string> busyBase64Data = new List<string>();
            List<string> tentativeMonthValues = new List<string>();
            List<string> tentativeBase64Data = new List<string>();

            ConvertEventsToFreeBusy(user,
                                    googleAppsFeed.Entries,
                                    window,
                                    busyMonthValues,
                                    busyBase64Data,
                                    tentativeMonthValues,
                                    tentativeBase64Data);



            string startDate = FreeBusyConverter.ConvertToSysTime(window.Start).ToString();
            string endDate = FreeBusyConverter.ConvertToSysTime(window.End).ToString();

            exchangeGateway.FreeBusy.CreateFreeBusyMessage(userFreeBusyUrl,
                                                           user.FreeBusyCommonName,
                                                           busyMonthValues,
                                                           busyBase64Data,
                                                           tentativeMonthValues,
                                                           tentativeBase64Data,
                                                           startDate,
                                                           endDate);

            if ( _log.IsInfoEnabled )
            {
                _log.Info( "Free/Busy message with the right properties created successfully." );
            }
        }
示例#10
0
    private void DeleteEvent()
    {
        CalendarService oCalendarService = GAuthenticate();

        //Search for Event
        EventQuery oEventQuery = new EventQuery();

        oEventQuery.Uri             = new Uri("https://www.google.com/calendar/feeds/[email protected]/private/full");
        oEventQuery.ExtraParameters = "extq=[SynchronizationID:{Your GUID Here}]";

        Google.GData.Calendar.EventFeed oEventFeed = oCalendarService.Query(oEventQuery);

        //Delete Related Events
        foreach (Google.GData.Calendar.EventEntry oEventEntry in oEventFeed.Entries)
        {
            oEventEntry.Delete();
            break;
        }
    }
示例#11
0
文件: GGSync.cs 项目: wertkh32/gg
 /// <summary>
 /// Sync GG calendar events to local list
 /// </summary>
 /// <param name="addToLocal">List of GGItems to be added to local GGList</param>
 /// <param name="GGEvents">Google event query results</param>
 /// <param name="server">List of bools to indicate if a Google event has a local version</param>
 private void SyncFromServerToLocal(List<GGItem> addToLocal, EventFeed GGEvents, List<bool> server)
 {
     // Loop through Google events
     for (int i = 0; i < GGEvents.Entries.Count; i++)
     {
         if (!server[i])
         {   // Google event does not has a local version, create on GG calendar : add to local list
             EventEntry e = (EventEntry)GGEvents.Entries[i];
             GGItem newGGItem = new GGItem(e.Title.Text, e.Times[0].EndTime, ExtractTagFromContents(e.Content.Content), DateTime.Parse(e.Updated.ToLongTimeString()), e.Id.AbsoluteUri, ExtractPathFromContents(e.Content.Content));
             addToLocal.Add(newGGItem);
             Log("Add to local: " + newGGItem.ToString());
         }
     }
 }
        private bool ValidateFeed( EventFeed feed )
        {
            bool isValid = true;

            if ( feed == null )
            {
                isValid = false;
            }
            else
            {
                if ( feed.TimeZone == null )
                {
                    isValid = false;
                }
            }

            return isValid;
        }
        private void LogResponse(EventFeed feed, string userName)
        {
            if ( !string.IsNullOrEmpty(logDirectory) && feed != null )
            {
                string fileName = string.Format(
                    "{0}{1}-{2}.log",
                    logDirectory,
                    DateTime.Now.ToString( "yyyyMMdd'.'HHmmss" ),
                    userName );

                using ( FileStream fs = new FileStream( fileName, FileMode.OpenOrCreate ) )
                {
                    feed.SaveToXml( fs );
                }
            }
        }
示例#14
0
文件: GGSync.cs 项目: wertkh32/gg
 /// <summary>
 /// Delete a event on Google calendar
 /// </summary>
 /// <param name="GGEvents">Google event query results</param>
 /// <param name="server">List of bools to indicate if a Google event has a local version</param>
 /// <param name="ggItem">local version of the Google Event</param>
 private void DeleteEvents(EventFeed GGEvents, List<bool> server, GGItem ggItem)
 {
     if (ggItem.GetEventAbsoluteUrl().CompareTo(string.Empty) != 0)
     {
         AtomEntry theEvent = FindGoogleEvent(GGEvents, server, ggItem.GetEventAbsoluteUrl());
         if (theEvent != null)
         {
             theEvent.Delete();
         }
     }
 }
        public EventFeed Next(EventFeed calFeed)
        {
            // just query the same query again.
            if (calFeed.NextChunk != null)
            {
                _Query.Uri = new Uri(calFeed.NextChunk);
                calFeed = _Service.Query(_Query) as EventFeed;
            }
            else
                calFeed = null;

            return calFeed;
        }
示例#16
0
文件: GGSync.cs 项目: wertkh32/gg
 /// <summary>
 /// Find the coreponding Google event with specified ID
 /// </summary>
 /// <param name="GGEvents">Google event query results</param>
 /// <param name="server">List of bools to indicate if a Google event has a local version</param>
 /// <param name="id">ID of the Google event</param>
 /// <returns></returns>
 private AtomEntry FindGoogleEvent(EventFeed GGEvents, List<bool> server, string id)
 {
     AtomEntry theEvent = null;
     for (int k = 0; k < GGEvents.Entries.Count; k++)
     {
         if (GGEvents.Entries[k].Id.AbsoluteUri == id)
         {
             theEvent = GGEvents.Entries[k];
             server[k] = true;
             Log("Found");
             break;
         }
     }
     return theEvent;
 }
示例#17
0
文件: GGSync.cs 项目: wertkh32/gg
        /// <summary>
        /// Prepare for synchronization
        /// </summary>
        /// <param name="ggList">Local GGList</param>
        /// <param name="addToLocal">List of GGItems to be added to local GGList</param>
        /// <param name="removeFromLocal">List of GGItems to be removed from local GGList</param>
        /// <param name="GGService">Google calendar service object</param>
        /// <param name="GGCalendar">GG calendar</param>
        /// <param name="GGEvents">Google event query results</param>
        /// <param name="server">List of bools to indicate if a Google event has a local version</param>
        /// <param name="toBeSyncedList">List of GGItems to be synced</param>
        /// <param name="toBeDeletedList">List of GGItems to be deleted on Google calendar</param>
        private void PrepareForSync(GGList ggList, out List<GGItem> addToLocal, out List<GGItem> removeFromLocal, out CalendarService GGService, out CalendarEntry GGCalendar, out EventFeed GGEvents, out List<bool> server, out List<GGItem> toBeSyncedList, out List<GGItem> toBeDeletedList)
        {
            // List of GGItems to be add to local GGList
            addToLocal = new List<GGItem>();
            // List of GGItems to be removed from local GGList
            removeFromLocal = new List<GGItem>();

            // Create Google calendar service object
            GGService = new CalendarService("GG");
            // Set credentials
            GGService.setUserCredentials(username, password);

            // Select GG calendar, create one if not exists
            GGCalendar = SelectGGCalendar(GGService);
            if (GGCalendar == null)
            {
                GGCalendar = CreateGGCalendar(GGService);
            }

            Log("operate on calender: " + GGCalendar.Title.Text);

            // Query and get all events on GG calendar
            EventQuery q = new EventQuery();
            q.Uri = new Uri("https://www.google.com/calendar/feeds/" + GGCalendar.Id.AbsoluteUri.Substring(63) + "/private/full");
            GGEvents = GGService.Query(q);

            // True if a Google event has a coresponding GGItem
            server = new List<bool>();
            for (int i = 0; i < GGEvents.Entries.Count; i++)
            {
                server.Add(false);
            }

            toBeSyncedList = ggList.GetInnerList();
            toBeDeletedList = ggList.GetDeletedList();
        }
        /// <summary>
        /// Merges a users appointment schedule from with appointments generated from a
        /// GoogleApps feed
        /// </summary>
        /// <param name="user">User to update with Google Apps information</param>
        /// <param name="googleAppsFeed">Source feed to generate appointment information</param>
        /// <param name="exchangeGateway">Gateway to sync Appointments with</param>
        /// <param name="window">DateRange to sync for</param>
        public void SyncUser(
            ExchangeUser user,
            EventFeed googleAppsFeed,
            ExchangeService exchangeGateway,
            DateTimeRange window)
        {
            exchangeGateway.GetCalendarInfoForUser(user, window);
            if (!user.HaveAppointmentDetail)
            {
                // Cannot sync if there is no appointment detail
                log.InfoFormat("Skipped Sync of {0} due to missing appointment lookup failure", user.Email);
                return;
            }

            List<Appointment> toUpdate = new List<Appointment>();
            List<Appointment> toDelete = new List<Appointment>();
            List<Appointment> toCreate = new List<Appointment>();

            OlsonTimeZone feedTimeZone = OlsonUtil.GetTimeZone(googleAppsFeed.TimeZone.Value);
            IntervalTree<Appointment> gcalApptTree =
                CreateAppointments(user, feedTimeZone, googleAppsFeed);

            /* Iterate through each Free/Busy time block for the user */
            foreach (FreeBusyTimeBlock fbtb in user.BusyTimes.Values)
            {
                /* Iterate through each appointment for the Free/Busy time block */
                foreach (Appointment appt in fbtb.Appointments)
                {
                    log.Debug(String.Format("Exchange @ '{0} {1}'",
                               appt.Range,
                               ValidateOwnership(appt)));
                    /* Validate that this is a GCalender appoint */
                    if ( ValidateOwnership( appt ) )
                    {
                        /* If the GCalender appointments do not contain an
                         * appointment for this period, add it for deletion */
                        if (gcalApptTree.FindExact(appt.Range) == null)
                        {
                            toDelete.Add( appt );
                        }
                    }
                }
            }

            /* Iterate through each Google Apps appointment */
            AppointmentCollection appointments = user.BusyTimes.Appointments;
            List<Appointment> gcalApptList = gcalApptTree.GetNodeList();

            foreach (Appointment newAppt in gcalApptList)
            {
                // If the meeting was cancelled
                log.DebugFormat("Looking @ {0} {1}", newAppt.Range, newAppt.Range.Start.Kind);

                if ( newAppt.MeetingStatus == MeetingStatus.Cancelled )
                {
                    // Check if there is an existing appointment that matches
                    List<Appointment> matches = appointments.Get(newAppt.Range);
                    foreach (Appointment a in matches)
                    {
                        if (ValidateOwnership(a))
                        {
                            toDelete.Add(a);
                        }
                    }

                    // Work is done for this appointment, continue to next entry
                    continue;
                }

                bool updatedAppointment = false;

                List<Appointment> apptList = appointments.Get(newAppt.Range);
                log.DebugFormat("Looking up preexisting event: {0} {1}", newAppt.Range, newAppt.Range.Start.Kind);
                log.DebugFormat("Found {0} matching items", apptList.Count);

                // Check that there is a free busy block that correlates with this appointment
                foreach ( Appointment existingAppt in apptList )
                {
                    if (ValidateOwnership(existingAppt) && !updatedAppointment)
                    {
                        UpdateAppointmentInfo(existingAppt, newAppt);
                        toUpdate.Add( existingAppt );
                        updatedAppointment = true;
                    }
                }

                if (!updatedAppointment)
                {
                    toCreate.Add( newAppt );
                    log.DebugFormat("ADDING '{0}' - Not an update",
                            newAppt.Range);
                }
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat(
                    "AppointmentWriter for '{0}'.  [{1} deleted, {2} updated, {3} new]",
                    user.Email,
                    toDelete.Count,
                    toUpdate.Count,
                    toCreate.Count);
            }

            exchangeGateway.Appointments.DeleteAppointments(user, toDelete);
            // TODO: Updates are not currently published
            // exchangeGateway.Appointments.UpdateAppointments( user, updateAppointments );
            exchangeGateway.Appointments.WriteAppointments(user, toCreate);
        }
示例#19
0
文件: GGSync.cs 项目: wertkh32/gg
        /// <summary>
        /// Sync local GGItem to GG calendar
        /// </summary>
        /// <param name="addToLocal">List of GGItems to be added to local GGList</param>
        /// <param name="removeFromLocal">List of GGItems to be removed from local GGList</param>
        /// <param name="GGService">Google calendar service object</param>
        /// <param name="GGCalendar">GG calendar</param>
        /// <param name="GGEvents">Google event query results</param>
        /// <param name="server">List of bools to indicate if a Google event has a local version</param>
        /// <param name="ggItem">The local GGItem to be synced</param>
        private void SyncFromLocalToServer(List<GGItem> addToLocal, List<GGItem> removeFromLocal, CalendarService GGService, CalendarEntry GGCalendar, EventFeed GGEvents, List<bool> server, GGItem ggItem)
        {
            if (ggItem.GetEventAbsoluteUrl() == String.Empty)
            {   // Not synced : add to GG Calendar
                Log("Never synced");
                ggItem.SetEventAbsoluteUrl(AddGGEvent(GGService, GGCalendar, ggItem));
                Log("Add to server: " + ggItem.ToString());
            }
            else
            {   // Synced before
                Log("Synced before");
                string id = ggItem.GetEventAbsoluteUrl();

                // Find the coresponding Google event
                AtomEntry theEvent = FindGoogleEvent(GGEvents, server, id);

                if (theEvent == null)
                {   // Not found: deleted on GG calendar : remove from local list
                    Log("Event is deleted on server");
                    removeFromLocal.Add(ggItem);
                    Log("Removed in local list");
                }
                else
                {   // Found
                    SolveConflict(addToLocal, removeFromLocal, GGService, GGCalendar, ggItem, theEvent);
                }
            }
        }
        private EventFeed createEventFeedFromEvents(List<DateTimeRange> events)
        {
            Uri uri = new Uri("http://localhost");
            EventFeed result = new EventFeed(uri, null);
            result.TimeZone = new Google.GData.Calendar.TimeZone("EST");

            foreach (DateTimeRange r in events)
            {
                EventEntry e = result.CreateFeedEntry() as EventEntry;

                DateTime start = DateTime.SpecifyKind(r.Start, DateTimeKind.Utc).ToLocalTime();
                DateTime end = DateTime.SpecifyKind(r.End, DateTimeKind.Utc).ToLocalTime();
                e.Times.Add(new When(start, end));
                result.Entries.Add(e);
            }

            return result;
        }
        /// <summary>
        /// Returns a set of appointments from a GoogleApps Feed
        /// </summary>
        /// <param name="user">The exchange user to get apointments for</param>
        /// <param name="srcTimeZone">The time zone to use</param>
        /// <param name="googleAppsFeed">Source feed to create array from</param>
        /// <returns></returns>
        private IntervalTree<Appointment> CreateAppointments(
            ExchangeUser user,
            OlsonTimeZone srcTimeZone,
            EventFeed googleAppsFeed)
        {
            IntervalTree<Appointment> result = new IntervalTree<Appointment>();

            foreach ( EventEntry eventEntry in googleAppsFeed.Entries )
            {
                try
                {
                    CreateAppointment(result, user, srcTimeZone, eventEntry);
                }
                catch ( GCalExchangeException ex )
                {
                    if ( ex.ErrorCode == GCalExchangeErrorCode.OlsonTZError )
                    {
                        log.Error( "Error creating appointment (TimeZone issue)", ex );
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            return result;
        }
        public void Purge_TwoEventsInRange_ReturnsTwo()
        {
            var start = new DateTime( 2014, 1, 1 );
            var end = new DateTime( 2014, 2, 1 );

            var entryOne = new EventEntry( "EntryOne" );
            var entryOneDate = new When( new DateTime( 2014, 1, 1 ), new DateTime( 2014, 1, 1 ) );
            entryOne.Times.Add( entryOneDate );

            var entryTwo = new EventEntry( "EntryOne" );
            var entryTwoDate = new When( new DateTime( 2014, 2, 1 ), new DateTime( 2014, 2, 1 ) );
            entryTwo.Times.Add( entryTwoDate );

            var entryThree = new EventEntry( "EntryOne" );
            var entryThreeDate = new When( new DateTime( 2014, 3, 1 ), new DateTime( 2014, 3, 1 ) );
            entryThree.Times.Add( entryThreeDate );

            var feed = new EventFeed( null, _service.Object );
            feed.Entries.Add( entryOne );
            feed.Entries.Add( entryTwo );
            feed.Entries.Add( entryThree );

            _service.Setup( x => x.Delete( entryOne ) );
            _service.Setup( x => x.Delete( entryTwo ) );

            _calendarService.Setup( x => x.Query( It.IsAny<EventQuery>() ) )
                            .Callback( () => feed.Entries.Remove( feed.Entries[2] ) )
                            .Returns( feed );

            List<string> results = _calendarPurge.Purge( start, end ).ToList();

            Assert.AreEqual( 2, results.Count );
        }