/// <summary>sends CREATE command</summary>
 /// <remarks>valid in authenticated state</remarks>
 public ImapCommandResult Create(string mailboxName, out ImapMailbox createdMailbox)
 {
     using (var t = new CreateTransaction(connection, null)) {
     return CreateInternal(t, mailboxName, null, out createdMailbox);
       }
 }
        /// <summary>sends CREATE command</summary>
        /// <remarks>
        /// valid in authenticated state.
        /// this method will fail if server does not support CREATE-SPECIAL-USE extension.
        /// </remarks>
        public ImapCommandResult CreateSpecialUse(string mailboxName, IImapMailboxFlagSet useFlags, out ImapMailbox createdMailbox)
        {
            if (useFlags == null)
            throw new ArgumentNullException("useFlags");

              foreach (var useFlag in useFlags) {
            if (!ImapMailboxFlag.UseFlags.Has(useFlag))
              throw new ArgumentException(string.Format("must be one of use-flag. '{0}' is invalid.", useFlag),
                                      "useFlags");
              }

              using (var t = new CreateTransaction(connection, ImapCapability.CreateSpecialUse)) {
            var result = CreateInternal(t,
                                    mailboxName,
                                    new ImapParenthesizedString("USE", new ImapParenthesizedString(useFlags.ToArray())),
                                    out createdMailbox);

            if (result.Succeeded)
              createdMailbox.Flags = (new ImapMailboxFlagList(useFlags)).AsReadOnly();

            return result;
              }
        }
        private ImapCommandResult CreateInternal(CreateTransaction t, string mailboxName, ImapParenthesizedString createParams, out ImapMailbox createdMailbox)
        {
            RejectNonAuthenticatedState();

              RejectInvalidMailboxNameArgument(mailboxName);

              /*
               * 6.3.3. CREATE Command
               *       It is an error to attempt to create INBOX or a mailbox
               *       with a name that refers to an extant mailbox.
               */
              if (ImapMailbox.IsNameInbox(mailboxName))
            throw new ImapProtocolViolationException("It is an error to attempt to create INBOX.");

              var existingMailbox = mailboxManager.GetExist(mailboxName);

              if (existingMailbox != null && !existingMailbox.Flags.Has(ImapMailboxFlag.NonExistent))
            throw new ImapProtocolViolationException(string.Format("It is an error to attempt to create a mailbox with a name that refers to an extent mailbox. (mailboxName: '{0}')", mailboxName));

              createdMailbox = null;

              /*
               * RFC 4466 - Collected Extensions to IMAP4 ABNF
               * http://tools.ietf.org/html/rfc4466
               *
               *    create          = "CREATE" SP mailbox
               *                      [create-params]
               *                      ;; Use of INBOX gives a NO error.
               *    create-params   = SP "(" create-param *( SP create-param) ")"
               *    create-param-name = tagged-ext-label
               *    create-param      = create-param-name [SP create-param-value]
               *    create-param-value= tagged-ext-val
               *                      ;; This non-terminal shows recommended syntax
               *                      ;; for future extensions.
               */
              // mailbox name
              t.RequestArguments["mailbox name"] = new ImapMailboxNameString(mailboxName);

              // create-params
              if (createParams != null)
            t.RequestArguments["create parameters"] = createParams;

              if (ProcessTransaction(t).Succeeded) {
            if (existingMailbox == null)
              createdMailbox = mailboxManager.Add(new ImapMailbox(mailboxName));
            else
              createdMailbox = mailboxManager.Rename(existingMailbox, mailboxName);
              }
              else {
            ProcessMailboxRefferalResponse(t.Result.TaggedStatusResponse);
              }

              return t.Result;
        }