public IEnumerable <Meeting> GetUpcomingAppointmentsForRoom(IRoom room)
        {
            var isTracked = _changeNotificationService.IsTrackedForChanges(room);

            return(_meetingCacheService.GetUpcomingAppointmentsForRoom(room.RoomAddress, isTracked, () =>
            {
                return Task.Run(() =>
                {
                    try
                    {
                        return ExchangeServiceExecuteWithImpersonationCheck(room.RoomAddress, svc =>
                        {
                            var apt = svc.FindAppointments(WellKnownFolderName.Calendar, new CalendarView(_dateTimeService.Now.Date, _dateTimeService.Now.Date.AddDays(2))
                            {
                                PropertySet = new PropertySet(AppointmentSchema.Id, AppointmentSchema.LegacyFreeBusyStatus)
                            }).ToList();
                            __log.DebugFormat("Got {0} appointments for {1} via {2} with {3}", apt.Count, room.RoomAddress, svc.GetHashCode(), svc.CookieContainer.GetCookieHeader(svc.Url));
                            if (_ignoreFree)
                            {
                                apt = apt.Where(i => i.LegacyFreeBusyStatus != LegacyFreeBusyStatus.Free).ToList();
                            }

                            // short-circuit if we don't have any meetings
                            if (!apt.Any())
                            {
                                return new Meeting[] {};
                            }

                            // now that we have the items, load the data (can't load attendees in the FindAppointments call...)
                            svc.LoadPropertiesForItems(apt, new PropertySet(
                                                           AppointmentSchema.Id,
                                                           AppointmentSchema.Subject,
                                                           AppointmentSchema.Sensitivity,
                                                           AppointmentSchema.Organizer,
                                                           AppointmentSchema.Start,
                                                           AppointmentSchema.End,
                                                           AppointmentSchema.IsAllDayEvent,
                                                           AppointmentSchema.RequiredAttendees,
                                                           AppointmentSchema.OptionalAttendees));

                            var meetings = _meetingRepository.GetMeetingInfo(room.OrganizationId, apt.Select(i => i.Id.UniqueId).ToArray()).ToDictionary(i => i.UniqueId);
                            return apt.Select(i => BuildMeeting(i, meetings.TryGetValue(i.Id.UniqueId) ?? new MeetingEntity()
                            {
                                Id = i.Id.UniqueId, OrganizationId = room.OrganizationId
                            })).ToArray().AsEnumerable();
                        });
                    }
                    catch (ServiceResponseException ex)
                    {
                        CheckForAccessDenied(room, ex);
                        __log.DebugFormat("Unexpected error ({0}) getting appointments for {1}", ex.ErrorCode, room.RoomAddress);
                        throw;
                    }
                });
            }).Result);
        }
        public IEnumerable <Meeting> GetUpcomingAppointmentsForRoom(string roomAddress)
        {
            var isTracked = _changeNotificationService.IsTrackedForChanges(roomAddress);

            using (_concurrencyLimiter.StartOperation())
            {
                return(_meetingCacheService.GetUpcomingAppointmentsForRoom(roomAddress, isTracked, () =>
                {
                    return Task.Run(() =>
                    {
                        try
                        {
                            var calId = new FolderId(WellKnownFolderName.Calendar, new Mailbox(roomAddress));
                            var cal = CalendarFolder.Bind(_exchangeService, calId);
                            var apt = cal.FindAppointments(new CalendarView(_dateTimeService.Now.Date, _dateTimeService.Now.Date.AddDays(2))).ToList();
                            log.DebugFormat("Got {0} appointments for {1} via {2} with {3}", apt.Count, roomAddress, _exchangeService.GetHashCode(), _exchangeService.CookieContainer.GetCookieHeader(_exchangeService.Url));
                            if (_ignoreFree)
                            {
                                apt = apt.Where(i => i.LegacyFreeBusyStatus != LegacyFreeBusyStatus.Free).ToList();
                            }
                            var meetings = _meetingRepository.GetMeetingInfo(apt.Select(i => i.Id.UniqueId).ToArray()).ToDictionary(i => i.Id);
                            return apt.Select(i => BuildMeeting(i, meetings.TryGetValue(i.Id.UniqueId) ?? new MeetingInfo()
                            {
                                Id = i.Id.UniqueId
                            })).ToArray().AsEnumerable();
                        }
                        catch (ServiceResponseException ex)
                        {
                            if (ex.ErrorCode == ServiceError.ErrorFolderNotFound || ex.ErrorCode == ServiceError.ErrorNonExistentMailbox || ex.ErrorCode == ServiceError.ErrorAccessDenied)
                            {
                                log.DebugFormat("Access denied ({0}) getting appointments for {1}", ex.ErrorCode, roomAddress);
                                throw new AccessDeniedException("Folder/mailbox not found or access denied", ex);
                            }
                            log.DebugFormat("Unexpected error ({0}) getting appointments for {1}", ex.ErrorCode, roomAddress);
                            throw;
                        }
                    });
                }).Result);
            }
        }