public static Pop3ReceptionEntity ReceiveEmailsFullComparation(this Pop3ConfigurationEntity config)
        {
            if (!EmailLogic.Configuration.ReciveEmails)
            {
                throw new InvalidOperationException("EmailLogic.Configuration.ReciveEmails is set to false");
            }

            using (HeavyProfiler.Log("ReciveEmails"))
                using (Disposable.Combine(SurroundReceiveEmail, func => func(config)))
                {
                    Pop3ReceptionEntity reception = Transaction.ForceNew().Using(tr => tr.Commit(
                                                                                     new Pop3ReceptionEntity {
                        Pop3Configuration = config.ToLite(), StartDate = TimeZoneManager.Now
                    }.Save()));

                    var now = TimeZoneManager.Now;
                    try
                    {
                        using (var client = GetPop3Client(config))
                        {
                            var messageInfos = client.GetMessageInfos();

                            var already = messageInfos.Select(a => a.Uid).GroupsOf(50).SelectMany(l =>
                                                                                                  (from em in Database.Query <EmailMessageEntity>()
                                                                                                   let ri = em.Mixin <EmailReceptionMixin>().ReceptionInfo
                                                                                                            where ri != null && l.Contains(ri.UniqueId)
                                                                                                            select KVP.Create(ri.UniqueId, (DateTime?)ri.SentDate))).ToDictionary();

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.NewEmails = messageInfos.Count - already.Count;
                                reception.Save();
                                tr.Commit();
                            }

                            foreach (var mi in messageInfos)
                            {
                                var sent = already.TryGetS(mi.Uid);

                                if (sent == null)
                                {
                                    sent = SaveEmail(config, reception, client, mi);
                                }

                                DeleteSavedEmail(config, now, client, mi, sent);
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate = TimeZoneManager.Now;
                                reception.Save();
                                tr.Commit();
                            }

                            client.Disconnect(); //Delete messages now
                        }
                    }
                    catch (Exception e)
                    {
                        var ex = e.LogException();

                        try
                        {
                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate   = TimeZoneManager.Now;
                                reception.Exception = ex.ToLite();
                                reception.Save();
                                tr.Commit();
                            }
                        }
                        catch { }
                    }

                    ReceptionComunication?.Invoke(reception);

                    return(reception);
                }
        }
        public static Pop3ReceptionEntity ReceiveEmailsPartialComparation(this Pop3ConfigurationEntity config)
        {
            if (!EmailLogic.Configuration.ReciveEmails)
            {
                throw new InvalidOperationException("EmailLogic.Configuration.ReciveEmails is set to false");
            }

            using (HeavyProfiler.Log("ReciveEmails"))
                using (Disposable.Combine(SurroundReceiveEmail, func => func(config)))
                {
                    Pop3ReceptionEntity reception = Transaction.ForceNew().Using(tr => tr.Commit(
                                                                                     new Pop3ReceptionEntity {
                        Pop3Configuration = config.ToLite(), StartDate = TimeZoneManager.Now
                    }.Save()));

                    var now = TimeZoneManager.Now;
                    try
                    {
                        using (var client = GetPop3Client(config))
                        {
                            var messageInfos = client.GetMessageInfos().OrderBy(m => m.Number);


                            var lastsEmails = Database.Query <EmailMessageEntity>()
                                              .Where(e => e.Mixin <EmailReceptionMixin>().ReceptionInfo.Reception.Entity.Pop3Configuration.RefersTo(config))
                                              .Select(d => new { d.CreationDate, d.Mixin <EmailReceptionMixin>().ReceptionInfo.UniqueId })
                                              .OrderByDescending(c => c.CreationDate).Take(10).ToDictionary(e => e.UniqueId);


                            List <MessageUid> messagesToSave;
                            if (lastsEmails.Any())
                            {
                                var messageJoinDict = messageInfos.ToDictionary(e => e.Uid).OuterJoinDictionarySC(lastsEmails, (key, v1, v2) => new { key, v1, v2 });
                                var messageMachings = messageJoinDict.Where(e => e.Value.v1 != null && e.Value.v2 != null).ToList();
                                messagesToSave = !messageMachings.Any()? messageInfos.ToList(): messageInfos.Where(m => m.Number > messageMachings.Select(e => e.Value.v1.Value.Number).Max()).ToList();
                            }
                            else
                            {
                                messagesToSave = messageInfos.ToList();
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.NewEmails = messagesToSave.Count;
                                reception.Save();
                                tr.Commit();
                            }

                            foreach (var mi in messagesToSave)
                            {
                                var sent = SaveEmail(config, reception, client, mi);

                                DeleteSavedEmail(config, now, client, mi, sent);
                            }

                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate = TimeZoneManager.Now;
                                reception.Save();
                                tr.Commit();
                            }

                            client.Disconnect(); //Delete messages now
                        }
                    }
                    catch (Exception e)
                    {
                        var ex = e.LogException();

                        try
                        {
                            using (Transaction tr = Transaction.ForceNew())
                            {
                                reception.EndDate   = TimeZoneManager.Now;
                                reception.Exception = ex.ToLite();
                                reception.Save();
                                tr.Commit();
                            }
                        }
                        catch { }
                    }

                    ReceptionComunication?.Invoke(reception);

                    return(reception);
                }
        }