/// <summary>
        /// Start the daemon service
        /// </summary>
        public bool Start()
        {
            this.Starting?.Invoke(this, EventArgs.Empty);

            this.m_configuration         = ApplicationContext.Current.Configuration.GetSection <SynchronizationConfigurationSection>();
            this.m_securityConfiguration = ApplicationContext.Current.Configuration.GetSection <SecurityConfigurationSection>();

            // Application context has started
            ApplicationContext.Current.Started += (o, e) =>
            {
                try
                {
                    // We are to poll for alerts always (never push supported)
                    TimeSpan pollInterval = this.m_configuration.PollInterval == TimeSpan.MinValue ? new TimeSpan(0, 10, 0) : this.m_configuration.PollInterval;
                    this.m_alertRepository = ApplicationContext.Current.GetService <IAlertRepositoryService>();
                    Action <Object> pollAction = null;
                    pollAction = x =>
                    {
                        try
                        {
                            var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                            amiClient.Client.Credentials = this.GetCredentials(amiClient.Client);
                            // Pull from alerts
                            if (!this.m_isRunning)
                            {
                                return;
                            }

                            // When was the last time we polled an alert?
                            var lastTime = SynchronizationLog.Current.GetLastTime(typeof(AlertMessage));

                            var syncTime = lastTime.HasValue ? new DateTimeOffset(lastTime.Value) : DateTimeOffset.Now.AddHours(-1);

                            // Poll action for all alerts to "everyone"
                            AmiCollection <AlertMessageInfo> serverAlerts = amiClient.GetAlerts(a => a.CreationTime >= lastTime && a.To.Contains("everyone"));


                            // TODO: We need to filter by users in which this tablet will be interested in

                            ParameterExpression userParameter = Expression.Parameter(typeof(SecurityUser), "u");
                            // User name filter
                            Expression userNameFilter = Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(this.m_securityConfiguration.DeviceName));

                            // Or eith other users which have logged into this tablet
                            foreach (var user in ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Query(u => u.LastLoginTime != null && u.UserName != this.m_securityConfiguration.DeviceName))
                            {
                                userNameFilter = Expression.OrElse(userNameFilter,
                                                                   Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName))
                                                                   );
                            }

                            ParameterExpression parmExpr       = Expression.Parameter(typeof(AlertMessage), "a");
                            Expression          timeExpression = Expression.GreaterThanOrEqual(
                                Expression.Convert(Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("CreationTime")), typeof(DateTimeOffset)),
                                Expression.Constant(syncTime)
                                ),
                            // this tablet expression
                                                userExpression = Expression.Call(
                                (MethodInfo)typeof(Enumerable).GetGenericMethod("Any", new Type[] { typeof(SecurityUser) }, new Type[] { typeof(IEnumerable <SecurityUser>), typeof(Func <SecurityUser, bool>) }),
                                Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("RcptTo")),
                                Expression.Lambda <Func <SecurityUser, bool> >(userNameFilter, userParameter));

                            serverAlerts.CollectionItem = serverAlerts.CollectionItem.Union(amiClient.GetAlerts(Expression.Lambda <Func <AlertMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList();

                            // Import the alerts
                            foreach (var itm in serverAlerts.CollectionItem)
                            {
                                this.m_tracer.TraceVerbose("Importing ALERT: [{0}]: {1}", itm.AlertMessage.TimeStamp, itm.AlertMessage.Subject);
                                itm.AlertMessage.Body = String.Format("<pre>{0}</pre>", itm.AlertMessage.Body);
                                this.m_alertRepository.BroadcastAlert(itm.AlertMessage);
                            }

                            // Push alerts which I have created or updated
                            //int tc = 0;
                            //foreach(var itm in this.m_alertRepository.Find(a=> (a.TimeStamp >= lastTime ) && a.Flags != AlertMessageFlags.System, 0, null, out tc))
                            //{
                            //    if (!String.IsNullOrEmpty(itm.To))
                            //    {
                            //        this.m_tracer.TraceVerbose("Sending ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject);
                            //        if (itm.UpdatedTime != null)
                            //            amiClient.UpdateAlert(itm.Key.ToString(), new AlertMessageInfo(itm));
                            //        else
                            //            amiClient.CreateAlert(new AlertMessageInfo(itm));
                            //    }
                            //}

                            SynchronizationLog.Current.Save(typeof(AlertMessage), null, null, null);
                        }
                        catch (Exception ex)
                        {
                            this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message);
                        }
                        finally
                        {
                            // Re-schedule myself in the poll interval time
                            ApplicationContext.Current.GetService <IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                        }
                    };

                    //ApplicationContext.Current.GetService<IThreadPoolService>().QueueUserWorkItem(pollInterval, pollAction, null);
                    this.m_isRunning = true;

                    pollAction(null);
                }
                catch (Exception ex)
                {
                    this.m_tracer.TraceError("Error starting Alert Sync: {0}", ex.Message);
                }
                //this.m_alertRepository.Committed +=
            };

            this.Started?.Invoke(this, EventArgs.Empty);

            return(true);
        }