/// <summary>
        /// Run the mail synchronization service
        /// </summary>
        public void Run(object sender, EventArgs e, object[] parameters)
        {
            try
            {
                this.m_jobStateManager.SetState(this, JobStateType.Running);

                // We are to poll for alerts always (never push supported)
                var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami"));
                using (this.GetCredentials(amiClient.Client, out Credentials credentials))
                {
                    amiClient.Client.Credentials = credentials;

                    // When was the last time we polled an alert?
                    var lastSync = this.m_synchronizationLogService.GetLastTime(typeof(MailMessage));
                    var syncTime = new DateTimeOffset(lastSync.GetValueOrDefault());
                    // Poll action for all alerts to "everyone"
                    AmiCollection serverAlerts = amiClient.GetMailMessages(a => a.CreationTime >= syncTime && a.RcptTo.Any(o => o.UserName == "SYSTEM")); // SYSTEM WIDE ALERTS


                    // 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, AuthenticationContext.SystemPrincipal))
                    {
                        userNameFilter = Expression.OrElse(userNameFilter,
                                                           Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName))
                                                           );
                    }

                    ParameterExpression parmExpr       = Expression.Parameter(typeof(MailMessage), "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.GetMailMessages(Expression.Lambda <Func <MailMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList();

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

                    this.m_synchronizationLogService.Save(typeof(MailMessage), String.Empty, String.Empty, "Mail", DateTime.Now);

                    // 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));
                    //    }
                    //}
                    this.m_jobStateManager.SetState(this, JobStateType.Completed);
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message);
                this.m_jobStateManager.SetState(this, JobStateType.Aborted);
                this.m_jobStateManager.SetProgress(this, ex.Message, 0.0f);
            }
        }