/// <summary>begins to send APPEND command</summary>
        /// <remarks>valid in authenticated state</remarks>
        public IAsyncResult BeginAppend(Stream messageBodyStream, DateTimeOffset? internalDate, IImapMessageFlagSet flags, string mailboxName)
        {
            RejectNonAuthenticatedState();
              RejectTransactionProceeding();

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

              RejectInvalidMailboxNameArgument(mailboxName);

              // append message
              var messagesToUpload = new List<ImapString>(1);

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

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

              // append-data
              messagesToUpload.Add(new ImapLiteralStream(messageBodyStream, ImapLiteralOptions.Synchronizing));

              AppendTransaction t = null;

              try {
            t = new AppendTransaction(connection, false);

            // mailbox name
            t.RequestArguments["mailbox name"] = new ImapMailboxNameString(mailboxName);

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

            var asyncResult = BeginProcessTransaction(t, handlesIncapableAsException);

            // wait for started (or completed)
            for (;;) {
              if (asyncResult.IsCompleted)
            break;
              else if (IsTransactionProceeding)
            break;
              else
            System.Threading.Thread.Sleep(10);
            }

            return asyncResult;
              }
              catch {
            if (t != null) {
              t.Dispose();
              t = null;
            }

            throw;
              }
        }
        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;
        }