private void OnAppointmentsChanged(object sender, PersistentObjectsEventArgs e)
        {
            using (new WaitCursor()) {
                bool bRefreshScheduler = false;

                Model.Service service = new Model.Service(Program.Service);

                foreach (Appointment apt in e.Objects)
                {
                    Model.Appointment obj = apt.GetSourceObject((SchedulerStorage)sender) as Model.Appointment;

                    if (obj != null)
                    {
                        Model.Appointment utc = obj.Clone(DateTimeKind.Utc);

                        service.AttachTo("Appointments", utc);
                        service.UpdateObject(utc);

                        if (!bRefreshScheduler)
                        {
                            if (Filter.Current.User != null && (!obj.AssignedTo.HasValue || obj.AssignedTo.Value != Filter.Current.User.ID))
                            {
                                bRefreshScheduler = true;
                            }
                        }
                    }
                }

                try {
                    service.SaveChanges(System.Data.Services.Client.SaveChangesOptions.Batch);
                } catch (DataServiceRequestException error) {
                    if (error.InnerException is DataServiceClientException &&
                        ((DataServiceClientException)error.InnerException).StatusCode == 404)
                    {
                        return;
                    }

                    if (error.Response.BatchStatusCode == 404)
                    {
                        return;
                    }

#if DEBUG
                    Debugger.Break();
#endif
                    throw;
                }

                gridControl.RefreshDataSource();

                if (bRefreshScheduler)
                {
                    isDirty = true;
                    schedulerControl.RefreshData();
                }
            }
        }
        private void OnRowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e)
        {
            using (new WaitCursor()) {
                Model.Service service = new Model.Service(Program.Service);

                Model.Appointment obj = e.Row as Model.Appointment;

                if (obj != null)
                {
                    if (obj.Resource != null)
                    {
                        obj.AssignedTo = obj.Resource.ID;
                        obj.Resource   = null;
                    }

                    if (obj.ID != Guid.Empty)
                    {
                        Model.Appointment utc = obj.Clone(DateTimeKind.Utc);

                        service.AttachTo("Appointments", utc);
                        service.UpdateObject(utc);
                    }
                    else
                    {
                        obj.ID = Guid.NewGuid();

                        if (!obj.AssignedTo.HasValue && Filter.Current.User != null)
                        {
                            obj.AssignedTo = Filter.Current.User.ID;
                        }

                        Model.Appointment utc = obj.Clone(DateTimeKind.Utc);

                        service.AddToAppointments(utc);
                    }
                }

                schedulerStorage.RefreshData();

                service.SaveChanges(System.Data.Services.Client.SaveChangesOptions.Batch);
            }
        }
        void Delete(Model.Appointment obj)
        {
            if (obj == null)
            {
                return;
            }

            BindingList <Model.Appointment> appointmentDataSource
                = schedulerStorage.Appointments.DataSource as BindingList <Model.Appointment>;

            if (appointmentDataSource != null)
            {
                appointmentDataSource.Remove(obj);
            }

            BindingList <Model.Appointment> taskDataSource
                = gridControl.DataSource as BindingList <Model.Appointment>;

            if (taskDataSource != null)
            {
                taskDataSource.Remove(obj);
            }


            Model.Service service = new Model.Service(Program.Service);

            try {
                Model.Appointment utc = obj.Clone(DateTimeKind.Utc);

                service.AttachTo("Appointments", utc);
                service.DeleteObject(utc);

                service.SaveChanges();
            } catch (DataServiceRequestException e) {
                if (e.InnerException is DataServiceClientException &&
                    ((DataServiceClientException)e.InnerException).StatusCode == 404)
                {
                    return;
                }

                if (e.Response.BatchStatusCode == 404)
                {
                    return;
                }

#if DEBUG
                Debugger.Break();
#endif
                throw;
            }
        }
        void OnAppointmentsInserted(object sender, PersistentObjectsEventArgs e)
        {
            using (new WaitCursor()) {
                Model.Service service = new Model.Service(Program.Service);

                foreach (Appointment apt in e.Objects)
                {
                    Model.Appointment.ItemCode defaultValue = apt.AllDay ?
                                                              Model.Appointment.ItemCode.Task : Model.Appointment.ItemCode.Event;

                    if (apt.CustomFields["ItemType"] == null)
                    {
                        apt.CustomFields["ItemType"] = defaultValue;
                    }

                    if (apt.CustomFields["CompletionStatus"] == null)
                    {
                        apt.CustomFields["CompletionStatus"] = (int)Model.Appointment.CompletionCode.NotStarted;
                    }

                    if (Filter.Current.User != null)
                    {
                        if (apt.ResourceId == null || !(apt.ResourceId is Guid) ||
                            ((Guid)apt.ResourceId == Guid.Empty))
                        {
                            apt.ResourceId = Filter.Current.User.ID;
                        }
                    }

                    Model.Appointment obj
                        = apt.GetSourceObject((SchedulerStorage)sender) as Model.Appointment;

                    if (obj != null)
                    {
                        bool bIsNew = false;

                        if (obj.ID == Guid.Empty)
                        {
                            bIsNew = true;
                            obj.ID = Guid.NewGuid();
                        }

                        if (obj.AssignedTo == null &&
                            Filter.Current.User != null)
                        {
                            obj.AssignedTo = Filter.Current.User.ID;
                        }

                        obj.ItemType         = (int)apt.CustomFields["ItemType"];
                        obj.CompletionStatus = (int)apt.CustomFields["CompletionStatus"];

                        Model.Appointment utc = obj.Clone(DateTimeKind.Utc);

                        if (bIsNew)
                        {
                            service.AddToAppointments(utc);
                        }
                        else
                        {
                            service.AttachTo("Appointments", utc);
                            service.UpdateObject(utc);
                        }

                        BindingList <Model.Appointment> taskDataSource
                            = gridControl.DataSource as BindingList <Model.Appointment>;

                        if (taskDataSource != null)
                        {
                            if (obj != null &&
                                !taskDataSource.Any <Model.Appointment>(it => it.ID == obj.ID) &&
                                obj.AppointmentType == (int)AppointmentType.Normal)
                            {
                                taskDataSource.Add(obj);
                            }
                        }
                    }
                }

                service.SaveChanges(System.Data.Services.Client.SaveChangesOptions.Batch);
            }
        }