public ArrivalMessageQuery(WaitForMessageArrivalContext context)
 {
     sequenceSet = (!context.MessageArrived || context.Mailbox.ExistsMessage <= context.CurrentMessageCount)
       ? ImapSequenceSet.CreateSet(new long[0])
       : ImapSequenceSet.CreateRangeSet(context.CurrentMessageCount + 1, context.Mailbox.ExistsMessage);
 }
        private bool WaitForMessageArrivalIdle(WaitForMessageArrivalContext context)
        {
            var waitHandles = new WaitHandle[] {context.AbortEvent, null};

              for (;;) {
            if (context.AbortEvent.WaitOne(0, false))
              return false; // aborted

            var idleAsyncResult = Client.Session.BeginIdle(context, delegate(object idleState, ImapUpdatedStatus updatedStatus) {
              var ctx = idleState as WaitForMessageArrivalAsyncResult;

              if (updatedStatus.Expunge.HasValue)
            ctx.CurrentMessageCount--;
              else if (updatedStatus.Exists.HasValue && ctx.CurrentMessageCount < updatedStatus.Exists.Value)
            return false; // DONE

              return true; // keep IDLEing
            });

            waitHandles[1] = idleAsyncResult.AsyncWaitHandle;

            var index = WaitHandle.WaitAny(waitHandles, 180 * 1000, false); // send DONE 3 minute after IDLE started

            ProcessResult(Client.Session.EndIdle(idleAsyncResult));

            switch (index) {
              case 0: // aborted
            return false;

              case 1: // IDLE completed
            return true;

              case WaitHandle.WaitTimeout:
              default:
            continue; // re-IDLE
            }
              }
        }
        private bool WaitForMessageArrivalNoOp(WaitForMessageArrivalContext context)
        {
            for (;;) {
            if (context.AbortEvent.WaitOne(context.PollingInterval, false))
              return false; // aborted

            var result = ProcessResult(Client.Session.NoOp());

            foreach (var response in result.ReceivedResponses) {
              var dataResponse = response as ImapDataResponse;

              if (dataResponse == null)
            continue;

              if (dataResponse.Type == ImapDataResponseType.Expunge)
            context.CurrentMessageCount--;
            }

            if (context.CurrentMessageCount < context.Mailbox.ExistsMessage)
              return true; // new message arrival
              }
        }
 private ImapMessageInfoList GetArrivalMessages(WaitForMessageArrivalContext context)
 {
     try {
     return new ImapMessageInfoList(this, context.FetchOptions, new ArrivalMessageQuery(context));
       }
       finally {
     context.Dispose();
       }
 }