/// <summary>
 /// Creates new <see cref="ExchangeTask"/> instance, using <paramref name="schema"/> and remote storage item.
 /// </summary>
 /// <param name="schema">Entity sync schema instance.</param>
 /// <param name="item">Remote storage item.</param>
 /// <param name="timeZoneInfo">Current user timezone.</param>
 public ExchangeTask(SyncItemSchema schema, Exchange.Item item, TimeZoneInfo timeZoneInfo)
     : base(schema, item, timeZoneInfo)
 {
     _propertySet.RequestedBodyType = Exchange.BodyType.Text;
     _propertySet.Add(ExchangeUtilityImpl.LocalIdProperty);
 }
        public static List <IEmailMessage> GetIncomingEmails(
            string address,
            bool loadHtmlBody = false,
            CancellationToken cancellationToken = default)
        {
            Contract.Requires(!String.IsNullOrEmpty(address));

            var settings = GetConnectionSettings(address);

            List <IEmailMessage> GetEmails()
            {
                var service = new EWS.ExchangeService(settings.Version)
                {
                    Url = new Uri(settings.Url)
                };

                if (settings.UseDefaultCredentials)
                {
                    service.UseDefaultCredentials = true;
                }
                else
                {
                    service.Credentials = new NetworkCredential(settings.UserName, settings.Password, settings.Domain);
                }
                var mailbox       = new EWS.Mailbox(address);
                var inboxFolderId = new EWS.FolderId(EWS.WellKnownFolderName.Inbox, mailbox);
                var propertySet   = new EWS.PropertySet(EWS.BasePropertySet.FirstClassProperties)
                {
                    RequestedBodyType = EWS.BodyType.Text
                };

                if (loadHtmlBody)
                {
                    propertySet.Add(new EWS.ExtendedPropertyDefinition(ExtendedProperty_HtmlBody, EWS.MapiPropertyType.Binary));
                }
                propertySet.Add(new EWS.ExtendedPropertyDefinition(ExtendedProperty_ConversationId, EWS.MapiPropertyType.Binary));
                var view = new EWS.ItemView(100)
                {
                    OrderBy     = { { EWS.ItemSchema.DateTimeReceived, EWS.SortDirection.Ascending } },
                    PropertySet = propertySet
                };

                var emails = (from item in service.FindItems(inboxFolderId, view)
                              let email = item as EWS.EmailMessage
                                          where email != null
                                          select email).ToList();

                if (emails.Count > 0)
                {
                    propertySet.Add(EWS.ItemSchema.MimeContent);
                    service.LoadPropertiesForItems(emails, propertySet);
                }
                return(emails.ConvertAll(email => {
                    if (email.ItemClass == "IPM.Note.SMIME")
                    {
                        using (var memoryStream = new MemoryStream(email.MimeContent.Content))
                        {
                            memoryStream.Position = 0L;
                            var pkcs7Mime = (ApplicationPkcs7Mime)MimeEntity.Load(memoryStream);
                            CryptographyContext.Register(typeof(WindowsSecureMimeContext));
                            pkcs7Mime.Verify(out var mimeEntity);
                            var multipart = (Multipart)mimeEntity;
                            var body = multipart.OfType <TextPart>().FirstOrDefault()?.Text;
                            var message = multipart.OfType <TnefPart>().FirstOrDefault()?.ConvertToMessage();
                            return new EmailMessage(
                                email,
                                body,
                                message?.Attachments
                                .OfType <MimePart>()
                                .Select(mp => {
                                memoryStream.SetLength(0L);
                                using (var contentStream = mp.Content.Open())
                                {
                                    contentStream.CopyTo(memoryStream);
                                }
                                return new FileAttachment(
                                    mp.FileName,
                                    memoryStream.ToArray());
                            })
                                .ToArray());
                        }
                    }
                    else
                    {
                        return (IEmailMessage) new EmailMessage(email);
                    }
                }));
            }

            var retries = 0;

            while (true)
            {
                try
                {
                    return(GetEmails());
                }
                catch when(retries < settings.Retries)
                {
                    //await Task.Delay(settings.RetryDelay, cancellationToken);
                    retries++;
                }
            }
        }