// Add a new message to a mailbox
func cmdAppend(args commandArgs, c *Conn) {
	if !c.assertAuthenticated(args.ID()) {
		return
	}

	mailboxName := args.Arg(appendArgMailbox)
	mailbox, err := c.User.MailboxByName(mailboxName)
	if err != nil {
		c.writeResponse(args.ID(), "NO could not get mailbox")
		return
	}

	length, err := strconv.ParseUint(args.Arg(appendArgLength), 10, 64)
	if err != nil || length == 0 {
		c.writeResponse(args.ID(), "BAD invalid length for message literal")
		return
	}

	flagString := args.Arg(appendArgFlags)
	flags := types.Flags(0)
	if flagString != "" {
		flags = types.FlagsFromString(flagString)
	}

	// Tell client to send the mail message
	c.writeResponse("+", "go ahead, feed me your message")

	// Read in the whole message
	messageData, err := c.ReadFixedLength(int(length))
	if err != nil {
		return
	}

	msg := mailbox.NewMessage()
	rawMsg, err := types.MessageFromBytes(messageData)
	if err != nil {
		c.writeResponse(args.ID(), "NO "+err.Error())
		return
	}
	msg = msg.SetHeaders(rawMsg.Headers)
	msg = msg.SetBody(rawMsg.Body)
	msg = msg.OverwriteFlags(flags)

	msg, err = msg.Save()
	if err != nil {
		c.writeResponse(args.ID(), "NO "+err.Error())
		return
	}

	c.writeResponse(args.ID(), "OK APPEND completed")
}
func cmdStoreFlags(args commandArgs, c *Conn) {
	if !c.assertSelected(args.ID(), ReadWrite) {
		return
	}

	operation := args.Arg(storeArgOperation)
	flags := args.Arg(storeArgFlags)
	uid := strings.ToUpper(args.Arg(storeArgUID)) == "UID "
	seqSetStr := args.Arg(storeArgRange)

	silent := false
	if args.Arg(storeArgSilent) == ".SILENT" {
		silent = true
	}

	var msgs []mailstore.Message
	seqSet, err := types.InterpretSequenceSet(seqSetStr)
	if err != nil {
		c.writeResponse(args.ID(), "NO "+err.Error())
		return
	}
	if uid {
		msgs = c.SelectedMailbox.MessageSetByUID(seqSet)
	} else {
		msgs = c.SelectedMailbox.MessageSetBySequenceNumber(seqSet)
	}

	flagField := types.FlagsFromString(flags)
	for _, msg := range msgs {

		if operation == "+" {
			msg = msg.AddFlags(flagField)
		} else if operation == "-" {
			msg = msg.RemoveFlags(flagField)
		} else {
			msg = msg.OverwriteFlags(flagField)
		}
		msg.Save()

		if err != nil {
			c.writeResponse(args.ID(), "NO "+err.Error())
			return
		}

		// Auto-fetch for the client
		if !silent {
			newFlags, err := fetch("FLAGS", c, msg)
			if err != nil {
				c.writeResponse(args.ID(), "NO "+err.Error())
				return
			}

			fetchResponse := fmt.Sprintf("%d FETCH (%s)",
				msg.SequenceNumber(),
				newFlags,
			)

			c.writeResponse("", fetchResponse)
		}
	}

	c.writeResponse(args.ID(), "OK STORE Completed")
}