CRSMail is built upon standards.
The main goal of CRSMail was flexibility. A new feature could be added by simply creating a new class implementing the required interface. Then by listing this class in the config file the new feature is available. The entire architecture builds on this idea.
A mail server needs two main servers an smtp server to accept incomming mail and a pop3 server to allow mail to be downloaded and read. The server assumes each of these run in their own threads. At startup the mail server starts the threads then main exits.
I guess I better start with some use case diagarams.
User Checking mail
+----+            +-------+            +-----------+
|User|<---POP3--->|CRSMail|<--Plugin-->|POP3 Server|
+----+            +-------+            +-----------+

User Sending mail
+----+            +-------+            +-----------+
|User|<---SMTP--->|CRSMail|<--Plugin-->|SMTP Server|
+----+            +-------+            +-----------+

Someone sending mail to a local user from the outside
+----+       +-----------+           +-------+  +----------+  +-----------+  +-------------+   +--------------+
|User|-SMTP->|Mail Server|-internet->|CRSMail|->|SMTPServer|->|User Plugin|->|StorageManger|-->|Storage Plugin|
+----+       +-----------+           +-------+  +----------+  +-----------+  +-------------+   +--------------+

Someone sending mail to a local user that gets forwarded somewhere else
+----+       +-----------+           +-------+  +----------+  +------------------+        +-----------+
|User|-SMTP->|Mail Server|-internet->|CRSMail|->|SMTPServer|->|ForwardMail Plugin|->SMTP->|Mail Server|
+----+       +-----------+           +-------+  +----------+  +------------------+        +-----------+

Configuring the server.  Plain text file
+-----+    +-------+
|Admin|--->|Notepad|
+-----+    +-------+
Server configuration
The entire server is configured by use of a config file. Each line consists of a key=value pair. Any line starting with a # is ignored. This is handled by com.calvinrsmith.shared.ConfigManager If a key is found called ConfigManager.DB with a value of true then after the parsing ConfigManager hits a database table for the rest of the key/value pairs. If a key is hit more than once then the new value is appended to any current value.

Now lets talk about the server startup.
To start the server run class com.calvinrsmith.CRSMail.Server.Mail On startup the class com.calvinrsmith.CRSMail.Config is loaded to load the options from the mail.conf file. Then the server starts the ball rolling by loading services and servers after which it's job is over. A service is a class that want's to be initilized at startup for example a database service will want to login to the database at startup and setup it's connection pools. A server is a class that will wait for an incomming connection and then handle the connection. Each service must start before the next one begins to start. Each server is derived from a thread so they all start at the same time.
What should be a service and what should be a server? Simple. Anything that listens for an incomming port connection should be a server. Anything that will be needed by more than one server should be a service thus keeping hidden interaction between servers to a minimal. If two servers are very closly linked and no other server would ever need to talk to them then they could just talk directly.
NOTE: There is only one instance of every service.

Current services and what they do:
com.calvinrsmith.CRSMail.server.DBService - Manage connections to the database. Uses com.calvinrsmith.shared.DBPool for connection pooling
com.calvinrsmith.CRSMail.server.UsersService - Manage the users of the system.
com.calvinrsmith.CRSMail.server.StorageService -Store the users messages.

Current servers and what they do:
com.calvinrsmith.CRSMail.server.SMTPServer - Handle SMTP connections. Incomming mail
com.calvinrsmith.CRSMail.server.POP3Server - Handle POP3 connections. Mail checks.
com.calvinrsmith.CRSMail.server.TransferMailServer - Transfer mail from another account to this one.

In depth detail of the classes already mentioned:
UsersService - CRSMail can manage mail for multiple domains each of which could get their user names from more than one place. For example for domain1 the user names come from the configuration file and a database table, domain2 gets it's user names from an LDAP server, domain3, get's it's names from the domain1 user table and then adds a new table for some other names and domain4 will accept any user listed in it's section of the config file as well as any user in it's table which is in it's own database. To accept this wide array of users all the users information are handles by a Users service. Then any server that wants to check if a user is local can call the service with the name of the user and what domain the user is in.
StorageService - Manages where the messages are stored. This gives the CRSMail storage independence. This service defines an interface for plugins to support various methods of storing mail. The simplist is to store each message in it's own file under the users directory. Other ideas would be to use a database or another servers format to make it easy to migrate from the other server to CRSMail. Using a database could give a quick response time, however, the attachments should probably not be stored in the databsase.
TransferMailServer - Transfer mail from another email address to one hosted by CRSMail. This gives the user the ability to check several mailboxes at once. An option could be inserted so that if the system looks for a reply-to address and if not found the insert one of the address just checked. This allows any replied messages to get replied back to where the first one came from.


MailAPI
MailAPI is a package to send and recieve mail. com.calvinrsmith.MailAPI.SendMail is the interace for sending mail. There is low level API to send each line of the an RFC822 message as well as a high level API to send mail by specifing the subject, body and attachments. The high level API simply encodes the message to RFC822 then calls the low level api to send the message. SMTP messages can be sent with com.calvinrsmith.MailaPI.SMTP This simply sends the mail once. If the send fails then it gives up. com.calvinrsmith.MailaPI.QueueSMTP can be used to insert a message into a queue and uses SMTP to send the message. If the send fails then the message goes back to the end of the queue to be tried again later. QueueSMTP extends SMTP so that either can be used just as easily. QueueSMTP uses a seperate thread to manage the queue. What other kinds of SendMail should there be? com.calvinrsmith.MailAPI.CheckMail is an interface for checking mail. Once again both high level and low level API's are provided for getting the RFC822 message or just strings for the subject, body and filenames for the attachments. POP3 implements CheckMail to allow for checking of pop3 servers. IMAP4 can be created to allow for the checking of IMAP servers.
In the case of webmail it will use the high level routines exlusivly whereas the server will use mostly the low level routines.
There will also be some classes to encode a message into MIME and to decode it from MIME.

Here are the relevent RFC's:
Layout of an email message
SMTP Protocol
POP3 Protocol
MIME Types part 1
MIME Types part 2


Future enhancments to the system:
Built in mailing list. Sending mail to qwert.list@server.com will send the message to everyone on the qwert list.

Other ideas as to how to use the server.
Configure it for SMTP only, using an SMTP plugin that can fax as the only plugin. Give this plugin a user name. Now every time someone emails fax@faxserver.com the fax is sent. If you also want to run a mail server then the plugin could be used in the server as everything else. However if you want a dedicated fax server and a dedicated mail server and don't wish to worry about emailing the fax to the right mail server you can use ForwardMail to forward the mail for fax to the fax server which will in turn fax it. Neat huh?