public BoteMailbox(EmailFolder folder, long uidValidity, long uid) {
    super(new MailboxPath("I2P-Bote", "bote", folder.getName()), uidValidity);
    this.folder = folder;
    this.messageMap =
        Collections.synchronizedSortedMap(
            new TreeMap<Email, BoteMessage>(
                new Comparator<Email>() {
                  @Override
                  public int compare(Email email1, Email email2) {
                    // Try received dates first, this is set for all received.
                    // emails. If not set, this is a sent email, use sent date.
                    Date msg1date = email1.getReceivedDate();
                    if (msg1date == null)
                      try {
                        msg1date = email1.getSentDate();
                      } catch (MessagingException e) {
                      }

                    Date msg2date = email2.getReceivedDate();
                    if (msg2date == null)
                      try {
                        msg2date = email2.getSentDate();
                      } catch (MessagingException e) {
                      }

                    if (msg1date != null && msg2date != null) return msg1date.compareTo(msg2date);

                    // Catch-all
                    return email1.getMessageID().compareTo(email2.getMessageID());
                  }
                }));
    this.uid = uid;

    modSeq = System.currentTimeMillis();
    modSeq <<= 32;

    startListening();
    try {
      List<Email> emails = folder.getElements();
      for (Email email : emails) messageMap.put(email, new BoteMessage(email, getFolderName()));
      updateMessages();
    } catch (PasswordException e) {
      throw new RuntimeException(_t("Password required or invalid password provided"), e);
    }
  }
  protected void startListening() {
    folderListener =
        new FolderListener() {
          public void elementAdded(String messageId) {
            try {
              // Add new emails to map
              Email email = folder.getEmail(messageId);
              email.setFlag(Flag.RECENT, true);
              messageMap.put(email, new BoteMessage(email, getFolderName()));
              updateMessages();
            } catch (PasswordException e) {
              throw new RuntimeException(_t("Password required or invalid password provided"), e);
            } catch (MessagingException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
          }

          public void elementUpdated() {
            // Noop, BoteMessage has a reference to the Email
          }

          public void elementRemoved(String messageId) {
            // Remove old email from map
            Set<Email> emails = messageMap.keySet();
            Iterator<Email> iter = emails.iterator();
            while (iter.hasNext()) {
              Email email = iter.next();
              if (email.getMessageID().equals(messageId)) {
                iter.remove();
                break;
              }
            }
            updateMessages();
          }
        };
    folder.addFolderListener(folderListener);
  }
 @Override
 public String toString() {
   return folder.toString();
 }
 void saveMetadata(BoteMessage message)
     throws IOException, MessagingException, PasswordException, GeneralSecurityException {
   folder.saveMetadata(message.getEmail());
   modSeq++;
 }
 void add(BoteMessage message)
     throws IOException, MessagingException, PasswordException, GeneralSecurityException {
   folder.add(message.getEmail());
 }
 private String getFolderName() {
   return folder.getName();
 }
 protected void stopListening() {
   folder.removeFolderListener(folderListener);
   folderListener = null;
 }