@Override
  protected void internalStore(Mail mail) throws MessagingException, IOException {
    try {
      Session session = login();
      try {
        String name = Text.escapeIllegalJcrChars(mail.getName());
        final String xpath = "/jcr:root/" + MAIL_PATH + "//element(" + name + ",james:mail)";

        QueryManager manager = session.getWorkspace().getQueryManager();
        @SuppressWarnings("deprecation")
        Query query = manager.createQuery(xpath, Query.XPATH);
        NodeIterator iterator = query.execute().getNodes();

        if (iterator.hasNext()) {
          while (iterator.hasNext()) {
            setMail(iterator.nextNode(), mail);
          }
        } else {
          Node parent = session.getRootNode().getNode(MAIL_PATH);
          Node node = parent.addNode(name, "james:mail");
          Node resource = node.addNode("jcr:content", "nt:resource");
          resource.setProperty("jcr:mimeType", "message/rfc822");
          setMail(node, mail);
        }
        session.save();
        logger.info("Mail " + mail.getName() + " stored in repository");
      } finally {
        session.logout();
      }
    } catch (IOException e) {
      throw new MessagingException("Unable to store message: " + mail.getName(), e);
    } catch (RepositoryException e) {
      throw new MessagingException("Unable to store message: " + mail.getName(), e);
    }
  }
 @Override
 protected void internalRemove(String key) throws MessagingException {
   try {
     Session session = login();
     try {
       String name = ISO9075.encode(Text.escapeIllegalJcrChars(key));
       QueryManager manager = session.getWorkspace().getQueryManager();
       @SuppressWarnings("deprecation")
       Query query =
           manager.createQuery(
               "/jcr:root/" + MAIL_PATH + "//element(" + name + ",james:mail)", Query.XPATH);
       NodeIterator nodes = query.execute().getNodes();
       if (nodes.hasNext()) {
         while (nodes.hasNext()) {
           nodes.nextNode().remove();
         }
         session.save();
         logger.info("Mail " + key + " removed from repository");
       } else {
         logger.warn("Mail " + key + " not found");
       }
     } finally {
       session.logout();
     }
   } catch (RepositoryException e) {
     throw new MessagingException("Unable to remove message: " + key, e);
   }
 }
 /**
  * Writes the mail attributes to the <code>jamesattr:*</code> property.
  *
  * @param node mail node
  * @param mail mail message
  * @throws RepositoryException if a repository error occurs
  * @throws IOException if an IO error occurs
  */
 @SuppressWarnings("deprecation")
 private void setAttributes(Node node, Mail mail) throws RepositoryException, IOException {
   Iterator<String> iterator = mail.getAttributeNames();
   while (iterator.hasNext()) {
     String name = iterator.next();
     Object value = mail.getAttribute(name);
     name = "jamesattr:" + Text.escapeIllegalJcrChars(name);
     if (value instanceof String || value == null) {
       node.setProperty(name, (String) value);
     } else {
       ByteArrayOutputStream buffer = new ByteArrayOutputStream();
       ObjectOutputStream output = new ObjectOutputStream(buffer);
       output.writeObject(value);
       output.close();
       node.setProperty(name, new ByteArrayInputStream(buffer.toByteArray()));
     }
   }
 }
 protected String toSafeName(String key) {
   return ISO9075.encode(Text.escapeIllegalJcrChars(key));
 }