/// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult Append(IImapAppendMessage message, ImapMailbox mailbox, out ImapAppendedUidSet appendedUids)
 {
     return AppendInternal(new[] {message}, false, mailbox, out appendedUids);
 }
 /// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// this method tries to automatically create the mailbox when server sent [TRYCREATE] response code.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult Append(IImapAppendMessage message, string mailboxName, out ImapAppendedUidSet appendedUids, out ImapMailbox createdMailbox)
 {
     return AppendInternal(new[] {message}, false, mailboxName, out appendedUids, out createdMailbox);
 }
 /// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// this method will fail if server does not support MULTIAPPEND extension.
 /// this method tries to automatically create the mailbox when server sent [TRYCREATE] response code.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult AppendMultiple(IEnumerable<IImapAppendMessage> messages, string mailboxName, out ImapAppendedUidSet appendedUids, out ImapMailbox createdMailbox)
 {
     return AppendInternal(messages, false, mailboxName, out appendedUids, out createdMailbox);
 }
        /// <summary>ends to send APPEND command</summary>
        /// <remarks>valid in authenticated state</remarks>
        public ImapCommandResult EndAppend(IAsyncResult asyncResult, out ImapAppendedUidSet appendedUid)
        {
            appendedUid = null;

              var appendAsyncResult = asyncResult as TransactionAsyncResult;

              if (appendAsyncResult == null)
            throw new ArgumentException("invalid IAsyncResult", "asyncResult");

              using (var t = appendAsyncResult.Transaction as AppendTransaction) {
            if (EndProcessTransaction(appendAsyncResult).Succeeded)
              appendedUid = t.Result.Value;
            else
              ProcessMailboxRefferalResponse(t.Result.TaggedStatusResponse);

            return t.Result;
              }
        }
 /// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// this method will fail if server does not support BINARY or MULTIAPPEND extension.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult AppendBinaryMultiple(IEnumerable<IImapAppendMessage> messages, string mailboxName, out ImapAppendedUidSet appendedUids)
 {
     return AppendInternal(messages, true, mailboxName, out appendedUids);
 }
 /// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// this method will fail if server does not support MULTIAPPEND extension.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult AppendMultiple(IEnumerable<IImapAppendMessage> messages, ImapMailbox mailbox, out ImapAppendedUidSet appendedUids)
 {
     return AppendInternal(messages, false, mailbox, out appendedUids);
 }
 /// <summary>sends APPEND command</summary>
 /// <remarks>
 /// valid in authenticated state.
 /// this method will fail if server does not support BINARY extension.
 /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null.
 /// </remarks>
 public ImapCommandResult AppendBinary(IImapAppendMessage message, string mailboxName, out ImapAppendedUidSet appendedUids)
 {
     return AppendInternal(new[] {message}, true, mailboxName, out appendedUids);
 }
        private ImapCommandResult AppendInternal(IEnumerable<IImapAppendMessage> messages, bool binary, string mailboxName, bool tryCreate, out ImapAppendedUidSet appendedUids, out ImapMailbox createdMailbox)
        {
            RejectNonAuthenticatedState();

              if (messages == null)
            throw new ArgumentNullException("messages");

              RejectInvalidMailboxNameArgument(mailboxName);

              appendedUids = null;
              createdMailbox = null;

              // append message
              var messagesToUpload = new List<ImapString>();
              var messageCount = 0;
              var literalOptions = ImapLiteralOptions.NonSynchronizingIfCapable
                           | (binary ? ImapLiteralOptions.Literal8 : ImapLiteralOptions.Literal);

              foreach (var message in messages) {
            if (message == null)
              throw new ArgumentException("contains null", "messages");

            /*
             * RFC 4466 - Collected Extensions to IMAP4 ABNF
             * http://tools.ietf.org/html/rfc4466
             *
             *    append          = "APPEND" SP mailbox 1*append-message
             *                      ;; only a single append-message may appear
             *                      ;; if MULTIAPPEND [MULTIAPPEND] capability
             *                      ;; is not present
             *    append-message  = append-opts SP append-data
             *    append-ext      = append-ext-name SP append-ext-value
             *                      ;; This non-terminal define extensions to
             *                      ;; to message metadata.
             *    append-ext-name = tagged-ext-label
             *    append-ext-value= tagged-ext-val
             *                      ;; This non-terminal shows recommended syntax
             *                      ;; for future extensions.
             *    append-data     = literal / literal8 / append-data-ext
             *    append-data-ext = tagged-ext
             *                      ;; This non-terminal shows recommended syntax
             *                      ;; for future extensions,
             *                      ;; i.e., a mandatory label followed
             *                      ;; by parameters.
             *    append-opts     = [SP flag-list] [SP date-time] *(SP append-ext)
             *                      ;; message metadata
             */

            // flag-list
            if (message.Flags != null && 0 < message.Flags.Count)
              messagesToUpload.Add(new ImapParenthesizedString(message.Flags.GetNonApplicableFlagsRemoved().ToArray()));

            // date-time
            if (message.InternalDate.HasValue)
              messagesToUpload.Add(ImapDateTimeFormat.ToDateTimeString(message.InternalDate.Value));

            // append-data
            messagesToUpload.Add(new ImapLiteralStream(message.GetMessageStream(),
                                                   literalOptions));

            messageCount++;
              }

              if (messageCount == 0)
            throw new ArgumentException("at least 1 message must be specified", "messages");

              ImapCommandResult failedResult = null;

              for (var i = 0; i < 2; i++) {
            var respTryCreate = false;

            using (var t = new AppendTransaction(connection, 1 < messageCount)) {
              // mailbox name
              t.RequestArguments["mailbox name"] = new ImapMailboxNameString(mailboxName);

              // messages to upload
              t.RequestArguments["messages to upload"] = new ImapStringList(messagesToUpload.ToArray());

              if (ProcessTransaction(t).Succeeded) {
            appendedUids = t.Result.Value;
            return t.Result;
              }
              else {
            if (ProcessMailboxRefferalResponse(t.Result.TaggedStatusResponse) || !tryCreate)
              return t.Result;
              }

              failedResult = t.Result;

              // 6.3.11. APPEND Command
              //       If the destination mailbox does not exist, a server MUST return an
              //       error, and MUST NOT automatically create the mailbox.  Unless it
              //       is certain that the destination mailbox can not be created, the
              //       server MUST send the response code "[TRYCREATE]" as the prefix of
              //       the text of the tagged NO response.  This gives a hint to the
              //       client that it can attempt a CREATE command and retry the APPEND
              //       if the CREATE is successful.
              respTryCreate = (t.Result.GetResponseCode(ImapResponseCode.TryCreate) is ImapTaggedStatusResponse);
            }

            // try create
            if (i == 0 && respTryCreate)
              if (Create(mailboxName, out createdMailbox).Failed)
            return failedResult;
              }

              return failedResult;
        }
 private ImapCommandResult AppendInternal(IEnumerable<IImapAppendMessage> messages, bool binary, string mailboxName, out ImapAppendedUidSet appendedUids, out ImapMailbox createdMailbox)
 {
     return AppendInternal(messages, binary, mailboxName, true, out appendedUids, out createdMailbox);
 }
        private ImapCommandResult AppendInternal(IEnumerable<IImapAppendMessage> messages, bool binary, string mailboxName, out ImapAppendedUidSet appendedUids)
        {
            ImapMailbox discard;

              return AppendInternal(messages, binary, mailboxName, false, out appendedUids, out discard);
        }
        private ImapCommandResult AppendInternal(IEnumerable<IImapAppendMessage> messages, bool binary, ImapMailbox mailbox, out ImapAppendedUidSet appendedUids)
        {
            ValidateMailboxRelationship(mailbox);

              ImapMailbox discard;

              return AppendInternal(messages, binary, mailbox.Name, false, out appendedUids, out discard);
        }