Protocol Issues

Don't be lazy, read the IMAP RFC instead of guessing how things work based on what a couple of servers send you. If you don't fully understand the RFC, ask about it in the [:ImapProtocolList:IMAP protocol mailing list]. When you implement your input parsing, pay special attention to ABNF rules. You might be surprised at some things that server is allowed to send you. For example just because servers usually list mailbox names with quoted strings, it doesn't mean that listing them with literals isn't allowed. Also reply to BODY[] can be NIL or "hello" just as well as a literal.

IMAP allows simultaneous access for multiple clients to a mailbox. Don't expect that you're the only one accessing it. If you're using multiple clients, it's very annoying when \Seen flags aren't synchronized between the clients. If your client does changes to mailbox state, send them immediately to the server, and also show changes sent by the server immediately to the user.

Don't ignore unexpected untagged replies. Especially EXPUNGE replies must be remembered, and it's not only the EXPUNGE command that can create those replies. UIDVALIDITY changes must also completely invalidate your local mailbox cache, no matter when that happens. You might as well support handling most of the untagged responses, independently on what generated them. For example:

1 NOOP
* 1 EXPUNGE
* 1 FETCH (FLAGS (\Seen))
* 16 EXISTS
* STATUS "imap-list" (MESSAGES 6 UNSEEN 5)
* OK [UIDVALIDITY 12345]
1 OK

If you see the following, you should update your internal state:

Commands can fail - deal with it. You may have requested a message that was just expunged from server by another connection. Someone might have deleted the mailbox you just tried to access. In any case, if server replies with NO for a command, you should try to deal with it or show the error message to user. [http://www.ietf.org/rfc/rfc2180.txt RFC-2180] helps you with figuring out how to handle FETCH and STORE errors. Just don't keep retrying a failed command forever.