public void TestConvertToSysTime()
        {
            long     ticksInMinute = (long)60 * 10000000;
            DateTime utc1601_1_1   = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            DateTime rawNow        = DateTime.Now;
            DateTime now           = new DateTime(rawNow.Year,
                                                  rawNow.Month,
                                                  rawNow.Day,
                                                  rawNow.Hour,
                                                  rawNow.Minute,
                                                  0,
                                                  0,
                                                  rawNow.Kind);
            int prevSysTime = FreeBusyConverter.ConvertToSysTime(now) - 1;

            for (int i = 0; i < 60 * 24 * 368; i++)
            {
                DateTime future  = now.AddTicks(i * ticksInMinute);
                int      sysTime = FreeBusyConverter.ConvertToSysTime(future);
                DateTime check   = utc1601_1_1.AddTicks(sysTime * ticksInMinute);

                Assert.AreEqual(future, check);
                Assert.AreEqual(prevSysTime + 1, sysTime);

                prevSysTime++;
            }
        }
        private static void ConvertEventsToFreeBusy(
            ExchangeUser user,
            AtomEntryCollection entries,
            DateTimeRange coveredRange,
            List <string> busyMonthValues,
            List <string> busyBase64Data,
            List <string> tentativeMonthValues,
            List <string> tentativeBase64Data)
        {
            List <DateTimeRange> busyTimes      = new List <DateTimeRange>();
            List <DateTimeRange> tentativeTimes = new List <DateTimeRange>();

            foreach (EventEntry googleAppsEvent in entries)
            {
                ConvertEventToFreeBusy(user, googleAppsEvent, coveredRange, busyTimes, tentativeTimes);
            }

            FreeBusyConverter.CondenseFreeBusyTimes(busyTimes);
            FreeBusyConverter.CondenseFreeBusyTimes(tentativeTimes);

            FreeBusyConverter.ConvertDateTimeBlocksToBase64String(coveredRange.Start,
                                                                  coveredRange.End,
                                                                  busyTimes,
                                                                  busyMonthValues,
                                                                  busyBase64Data);

            FreeBusyConverter.ConvertDateTimeBlocksToBase64String(coveredRange.Start,
                                                                  coveredRange.End,
                                                                  tentativeTimes,
                                                                  tentativeMonthValues,
                                                                  tentativeBase64Data);
        }
        public void TestConvertRasterToFreeBusy()
        {
            for (char c = ' '; c < 256; c++)
            {
                if (c < '0' || c > '4')
                {
                    Assert.AreEqual(BusyStatus.Free, FreeBusyConverter.ConvertRasterToFreeBusy(c));
                }
            }

            Assert.AreEqual(BusyStatus.Free, FreeBusyConverter.ConvertRasterToFreeBusy('0'));
            Assert.AreEqual(BusyStatus.Tentative, FreeBusyConverter.ConvertRasterToFreeBusy('1'));
            Assert.AreEqual(BusyStatus.Busy, FreeBusyConverter.ConvertRasterToFreeBusy('2'));
            Assert.AreEqual(BusyStatus.OutOfOffice, FreeBusyConverter.ConvertRasterToFreeBusy('3'));
            Assert.AreEqual(BusyStatus.Free, FreeBusyConverter.ConvertRasterToFreeBusy('4'));
        }
        /// <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.");
            }
        }
        private static int CompareAppointmentsByRanges(
            Appointment x,
            Appointment y)
        {
            if ((x == null) && (y == null))
            {
                // If x is null and y is null, they are equal.
                return(0);
            }

            if (x == null)
            {
                // If x is null and y is not null, y is greater.
                return(-1);
            }

            if (y == null)
            {
                // If x is not null and y is null, x is greater.
                return(1);
            }

            return(FreeBusyConverter.CompareRangesByStartThenEnd(x.Range, y.Range));
        }
 private static int ReverseCompareRanges(
     DateTimeRange x,
     DateTimeRange y)
 {
     return(FreeBusyConverter.CompareRangesByStartThenEnd(y, x));
 }
        public void TestCondenseFreeBusyTimes()
        {
            DateTimeRange        range             = null;
            List <DateTimeRange> testFreeBusyTimes = new List <DateTimeRange>();
            List <DateTimeRange> expectedResult    = new List <DateTimeRange>();

            // The first test case is
            // Event 1 [.....]
            // Event 2    [.....]
            // Event 3       [.....]
            // Result  [...........]
            range = new DateTimeRange(DateTime.Parse("2007-06-01T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-01T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-01T07:30:00.000Z"),
                                      DateTime.Parse("2007-06-01T08:30:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-01T08:00:00.000Z"),
                                      DateTime.Parse("2007-06-01T09:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-01T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-01T09:00:00.000Z"));
            expectedResult.Add(range);

            // The second test case is
            // Event 1 [.....]
            // Event 2       [.....]
            // Result  [...........]
            range = new DateTimeRange(DateTime.Parse("2007-06-02T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-02T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-02T08:00:00.000Z"),
                                      DateTime.Parse("2007-06-02T09:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-02T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-02T09:00:00.000Z"));
            expectedResult.Add(range);

            // The third test case is
            // Event 1 [.....]
            // Event 2 [.....]
            // Result  [.....]
            range = new DateTimeRange(DateTime.Parse("2007-06-03T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-03T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-03T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-03T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-03T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-03T08:00:00.000Z"));
            expectedResult.Add(range);

            // The forth test case is
            // Event 1 [..]
            // Event 2    [.....]
            // Event 3          [..]
            // Result  [...........]
            range = new DateTimeRange(DateTime.Parse("2007-06-04T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-04T07:30:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-04T07:30:00.000Z"),
                                      DateTime.Parse("2007-06-04T08:30:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-04T08:30:00.000Z"),
                                      DateTime.Parse("2007-06-04T09:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-04T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-04T09:00:00.000Z"));
            expectedResult.Add(range);

            // The fifth test case is
            // Event 1 [..........]
            // Event 2   [.....]
            // Result  [..........]
            range = new DateTimeRange(DateTime.Parse("2007-06-05T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-05T09:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-05T07:30:00.000Z"),
                                      DateTime.Parse("2007-06-05T08:30:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-05T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-05T09:00:00.000Z"));
            expectedResult.Add(range);

            // The sixth test case is
            // Event 1 [.....]
            // Event 2 [...]
            // Result  [.....]
            range = new DateTimeRange(DateTime.Parse("2007-06-06T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-06T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-06T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-06T07:30:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-06T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-06T08:00:00.000Z"));
            expectedResult.Add(range);

            // The seventh test case is
            // Event 1 [.....]
            // Event 2   [...]
            // Result  [.....]
            range = new DateTimeRange(DateTime.Parse("2007-06-07T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-07T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-07T07:30:00.000Z"),
                                      DateTime.Parse("2007-06-07T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-07T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-07T08:00:00.000Z"));
            expectedResult.Add(range);

            // The eight test case is
            // Event 1 [...............]
            // Event 2   [...]
            // Event 3          [...]
            // Result  [...............]
            range = new DateTimeRange(DateTime.Parse("2007-06-08T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-08T10:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-08T07:30:00.000Z"),
                                      DateTime.Parse("2007-06-08T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-08T08:30:00.000Z"),
                                      DateTime.Parse("2007-06-08T09:00:00.000Z"));
            testFreeBusyTimes.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-08T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-08T10:00:00.000Z"));
            expectedResult.Add(range);

            // The ninth test case is
            // Event 1 [.....]
            // Event 2            [.....]
            // Result  [.....]    [.....]
            range = new DateTimeRange(DateTime.Parse("2007-06-09T07:00:00.000Z"),
                                      DateTime.Parse("2007-06-09T08:00:00.000Z"));
            testFreeBusyTimes.Add(range);
            expectedResult.Add(range);

            range = new DateTimeRange(DateTime.Parse("2007-06-09T09:00:00.000Z"),
                                      DateTime.Parse("2007-06-09T10:00:00.000Z"));
            testFreeBusyTimes.Add(range);
            expectedResult.Add(range);

            testFreeBusyTimes.Sort(ReverseCompareRanges);

            List <DateTimeRange> copyFreeBusyTimes = new List <DateTimeRange>();

            foreach (DateTimeRange temp in testFreeBusyTimes)
            {
                copyFreeBusyTimes.Add(new DateTimeRange(temp.Start, temp.End));
            }

            List <DateTimeRange> oldResult = OldCondenseFreeBusyTimes(copyFreeBusyTimes);

            FreeBusyConverter.CondenseFreeBusyTimes(testFreeBusyTimes);

            Assert.IsTrue(CompareRangeLists(testFreeBusyTimes, expectedResult));
            Assert.IsTrue(CompareRangeLists(testFreeBusyTimes, oldResult));
        }
        public void TestConvertDateTimeBlocks()
        {
            List <DateTimeRange> src = new List <DateTimeRange>();
            List <DateTimeRange> dst = new List <DateTimeRange>();

            DateTime s         = DateTime.MinValue;
            DateTime e         = DateTime.MinValue;
            DateTime startDate = new DateTime(2007, 07, 1, 0, 0, 0, DateTimeKind.Utc);
            DateTime endDate   = new DateTime(2008, 05, 31, 0, 0, 0, DateTimeKind.Utc);

            s = new DateTime(2007, 07, 23, 13, 45, 00, DateTimeKind.Unspecified);
            src.Add(new DateTimeRange(s, s.AddHours(3)));
            dst.Add(new DateTimeRange(s, s.AddHours(3)));

            s = new DateTime(2007, 07, 30, 13, 45, 00, DateTimeKind.Unspecified);
            src.Add(new DateTimeRange(s, s));
            dst.Add(new DateTimeRange(s, s));

            s = new DateTime(2007, 08, 15, 13, 45, 00, DateTimeKind.Unspecified);
            e = new DateTime(2007, 10, 11, 02, 45, 00, DateTimeKind.Unspecified);
            src.Add(new DateTimeRange(s, e));
            dst.Add(new DateTimeRange(s,
                                      new DateTime(2007, 08, 31, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2007, 09, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2007, 09, 30, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2007, 10, 01, 00, 00, 00, DateTimeKind.Unspecified), e));

            src.Add(new DateTimeRange(
                        new DateTime(2008, 01, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 03, 31, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2008, 01, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 01, 31, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2008, 02, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 02, 29, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2008, 03, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 03, 31, 23, 59, 00, DateTimeKind.Unspecified)));

            src.Add(new DateTimeRange(
                        new DateTime(2008, 04, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 05, 30, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2008, 04, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 04, 30, 23, 59, 00, DateTimeKind.Unspecified)));
            dst.Add(new DateTimeRange(
                        new DateTime(2008, 05, 01, 00, 00, 00, DateTimeKind.Unspecified),
                        new DateTime(2008, 05, 30, 23, 59, 00, DateTimeKind.Unspecified)));

            List <string> monthData  = new List <string>();
            List <string> base64Data = new List <string>();

            FreeBusyConverter.ConvertDateTimeBlocksToBase64String(startDate,
                                                                  endDate,
                                                                  src,
                                                                  monthData,
                                                                  base64Data);

            List <DateTimeRange> result = new List <DateTimeRange>();

            for (int i = 0; i < monthData.Count; i++)
            {
                int    month = int.Parse(monthData[i]);
                string data  = base64Data[i];

                List <DateTimeRange> r =
                    FreeBusyConverter.ConvertBase64StringsToDateTimeBlocks(month, data);

                result.AddRange(r);
            }

            Assert.AreEqual(dst.Count, result.Count);
            for (int i = 0; i < dst.Count; i++)
            {
                Assert.AreEqual(dst[i], result[i]);
            }
        }
        public void TestParseRasterFreeBusy()
        {
            DateTime startDate = new DateTime(2008, 05, 1, 10, 0, 0, DateTimeKind.Utc);
            DateTime date1     = new DateTime(2008, 05, 1, 10, 15, 0, DateTimeKind.Utc);
            DateTime date2     = new DateTime(2008, 05, 1, 10, 30, 0, DateTimeKind.Utc);
            DateTime date3     = new DateTime(2008, 05, 1, 10, 45, 0, DateTimeKind.Utc);
            DateTime date4     = new DateTime(2008, 05, 1, 11, 0, 0, DateTimeKind.Utc);
            DateTime date5     = new DateTime(2008, 05, 1, 11, 15, 0, DateTimeKind.Utc);
            FreeBusy freeBusy  = new FreeBusy();

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "1", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 1);
            Assert.AreEqual(freeBusy.Tentative[0].Start, startDate);
            Assert.AreEqual(freeBusy.Tentative[0].End, date1);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "2", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 1);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, startDate);
            Assert.AreEqual(freeBusy.All[0].End, date1);
            Assert.AreEqual(freeBusy.Busy[0].Start, startDate);
            Assert.AreEqual(freeBusy.Busy[0].End, date1);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "3", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 1);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, startDate);
            Assert.AreEqual(freeBusy.All[0].End, date1);
            Assert.AreEqual(freeBusy.OutOfOffice[0].Start, startDate);
            Assert.AreEqual(freeBusy.OutOfOffice[0].End, date1);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "4", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "11", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 1);
            Assert.AreEqual(freeBusy.Tentative[0].Start, startDate);
            Assert.AreEqual(freeBusy.Tentative[0].End, date2);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "22", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 1);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, startDate);
            Assert.AreEqual(freeBusy.All[0].End, date2);
            Assert.AreEqual(freeBusy.Busy[0].Start, startDate);
            Assert.AreEqual(freeBusy.Busy[0].End, date2);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "33", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 1);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, startDate);
            Assert.AreEqual(freeBusy.All[0].End, date2);
            Assert.AreEqual(freeBusy.OutOfOffice[0].Start, startDate);
            Assert.AreEqual(freeBusy.OutOfOffice[0].End, date2);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "44", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "0114", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 1);
            Assert.AreEqual(freeBusy.Tentative[0].Start, date1);
            Assert.AreEqual(freeBusy.Tentative[0].End, date3);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "0224", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 1);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, date1);
            Assert.AreEqual(freeBusy.All[0].End, date3);
            Assert.AreEqual(freeBusy.Busy[0].Start, date1);
            Assert.AreEqual(freeBusy.Busy[0].End, date3);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "0334", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 1);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 1);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            Assert.AreEqual(freeBusy.All[0].Start, date1);
            Assert.AreEqual(freeBusy.All[0].End, date3);
            Assert.AreEqual(freeBusy.OutOfOffice[0].Start, date1);
            Assert.AreEqual(freeBusy.OutOfOffice[0].End, date3);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "0440", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 0);
            Assert.AreEqual(freeBusy.Busy.Count, 0);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 0);
            Assert.AreEqual(freeBusy.Tentative.Count, 0);
            ClearFreeBusy(freeBusy);

            FreeBusyConverter.ParseRasterFreeBusy(startDate, 15, "40312", freeBusy);
            Assert.AreEqual(freeBusy.All.Count, 2);
            Assert.AreEqual(freeBusy.Busy.Count, 1);
            Assert.AreEqual(freeBusy.OutOfOffice.Count, 1);
            Assert.AreEqual(freeBusy.Tentative.Count, 1);
            Assert.AreEqual(freeBusy.All[0].Start, date2);
            Assert.AreEqual(freeBusy.All[0].End, date3);
            Assert.AreEqual(freeBusy.All[1].Start, date4);
            Assert.AreEqual(freeBusy.All[1].End, date5);
            Assert.AreEqual(freeBusy.Busy[0].Start, date4);
            Assert.AreEqual(freeBusy.Busy[0].End, date5);
            Assert.AreEqual(freeBusy.Tentative[0].Start, date3);
            Assert.AreEqual(freeBusy.Tentative[0].End, date4);
            Assert.AreEqual(freeBusy.OutOfOffice[0].Start, date2);
            Assert.AreEqual(freeBusy.OutOfOffice[0].End, date3);
            ClearFreeBusy(freeBusy);
        }
        /// <summary>
        /// Combines the free busy and appointment blocks supplied to the exchange user object
        /// If no appointments are supplied the user will still have free busy time blocks assigned
        /// to them, with a null appointment assigned to the free busy time.
        /// </summary>
        /// <param name="exchangeUser">Exchange users to apply freeBusy and appointments</param>
        /// <param name="freeBusy">The collection of FreeBusy blocks to assign to exchangeUser</param>
        /// <param name="appointments">The collection of appointment blocks to assign to exchangeUser</param>
        /// <param name="window">Window to merge for</param>
        protected void MergeFreeBusyWithAppointments(
            ExchangeUser exchangeUser,
            FreeBusy freeBusy,
            List <Appointment> appointments,
            DateTimeRange window)
        {
            using (BlockTimer bt = new BlockTimer("MergeFreeBusyWithAppointments"))
            {
                IntervalTree <FreeBusyTimeBlock> busyIntervals =
                    new IntervalTree <FreeBusyTimeBlock>();
                FreeBusyCollection busyTimes       = new FreeBusyCollection();
                int appointmentsCount              = 0;
                List <DateTimeRange> combinedTimes =
                    FreeBusyConverter.MergeFreeBusyLists(freeBusy.All, freeBusy.Tentative);

                /* Add the date ranges from each collection in the FreeBusy object */
                ConvertFreeBusyToBlocks(window,
                                        combinedTimes,
                                        busyTimes,
                                        busyIntervals);

                if (appointments != null && appointments.Count > 0)
                {
                    appointmentsCount = appointments.Count;
                    foreach (Appointment appt in appointments)
                    {
                        log.DebugFormat("Appt \"{0}\" {1} {2} response = {3} status = {4} busy = {5}",
                                        appt.Subject,
                                        appt.Range,
                                        appt.StartDate.Kind,
                                        appt.ResponseStatus,
                                        appt.MeetingStatus,
                                        appt.BusyStatus);

                        if (appt.BusyStatus == BusyStatus.Free)
                        {
                            continue;
                        }

                        DateTimeRange            range  = new DateTimeRange(appt.StartDate, appt.EndDate);
                        List <FreeBusyTimeBlock> result =
                            busyIntervals.FindAll(range, IntervalTreeMatch.Overlap);

                        log.DebugFormat("Found {0} ranges overlap {1}", result.Count, range);

                        foreach (FreeBusyTimeBlock block in result)
                        {
                            log.DebugFormat("Adding \"{0}\" to FB {1} {2}",
                                            appt.Subject,
                                            block.Range,
                                            block.StartDate.Kind);
                            block.Appointments.Add(appt);
                        }

                        busyTimes.Appointments.Add(appt);
                    }
                }

                foreach (FreeBusyTimeBlock block in busyTimes.Values)
                {
                    block.Appointments.Sort(CompareAppointmentsByRanges);
                }

                log.InfoFormat("Merge Result of {0} + Appointment {1} -> {2}",
                               combinedTimes.Count,
                               appointmentsCount,
                               busyTimes.Count);

                /* Assign the data structure to the exchange user */
                exchangeUser.BusyTimes = busyTimes;
            }
        }