/**
   * Subetha MessageListener. Called when an SMTP message has bee received. Could be a send request
   * from our domain or an email to our domain
   */
  public void deliver(String sFrom, String sRecipient, final InputStream data)
      throws TooMuchDataException, IOException {
    log.debug("deliver email from: " + sFrom + " to: " + sRecipient);
    log.debug("email from: " + sFrom + " to: " + sRecipient);
    final DeliverEvent event = new DeliverEvent(sFrom, sRecipient, data);
    Filter terminal =
        new Filter() {

          public void doEvent(FilterChain chain, Event e) {
            MailboxAddress from = MailboxAddress.parse(event.getFrom());
            MailboxAddress recip = MailboxAddress.parse(event.getRecipient());

            MimeMessage mm = parseInput(data);

            Mailbox recipMailbox = resourceFactory.getMailbox(recip);
            log.debug("recipient is known to us, so store: " + recip);
            storeMail(recipMailbox, mm);
          }
        };
    FilterChain chain = new FilterChain(filters, terminal);
    chain.doEvent(event);
  }
  /** Subetha.MessageListener */
  public boolean accept(String sFrom, String sRecipient) {
    log.debug("accept? " + sFrom + " - " + sRecipient);
    if (sFrom == null || sFrom.length() == 0) {
      log.error("Cannot accept email with no from address. Recipient is: " + sRecipient);
      return false;
    }
    final AcceptEvent event = new AcceptEvent(sFrom, sRecipient);
    Filter terminal =
        new Filter() {

          public void doEvent(FilterChain chain, Event e) {
            MailboxAddress recip = MailboxAddress.parse(event.getRecipient());
            Mailbox recipMailbox = resourceFactory.getMailbox(recip);

            boolean b = (recipMailbox != null && !recipMailbox.isEmailDisabled());
            log.debug(
                "accept email from: " + event.getFrom() + " to: " + event.getRecipient() + "?" + b);
            event.setAccept(b);
          }
        };
    FilterChain chain = new FilterChain(filters, terminal);
    chain.doEvent(event);
    return event.isAccept();
  }