private Node writeMessage(
     Session session, Map<String, Object> mapProperties, InputStream data, String storePath)
     throws IOException, RepositoryException {
   parseSMTPHeaders(mapProperties, data);
   StreamCopier streamCopier = new StreamCopier(data);
   try {
     MimeMultipart multipart = new MimeMultipart(new SMTPDataSource(mapProperties, streamCopier));
     Node message =
         messagingService.create(
             session, mapProperties, (String) mapProperties.get("message-id"), storePath);
     writeMultipartToNode(session, message, multipart);
     return message;
   } catch (MessagingException e) {
     mapProperties.put(MessageConstants.PROP_SAKAI_BODY, streamCopier.getContents());
     return messagingService.create(session, mapProperties);
   }
 }
 /**
  * @param recipient
  * @return
  */
 private List<String> getLocalPath(Session session, String recipient) {
   // assume recipient is a fully qualified email address of the form [email protected]
   String[] parts = StringUtils.split(recipient, '@');
   List<String> localPaths = new ArrayList<String>();
   if (domains.contains(parts[1])) {
     List<String> recipients = messagingService.expandAliases(parts[0]);
     for (String localRecipient : recipients) {
       try {
         String path = messagingService.getFullPathToStore(parts[0], session);
         if (path != null && path.length() > 0) {
           localPaths.add(path);
         }
       } catch (Exception ex) {
         LOGGER.warn("Failed to expand recipient {} ", localRecipient, ex);
       }
     }
   }
   return null;
 }
  public void deliver(String from, String recipient, InputStream data)
      throws TooMuchDataException, IOException {
    LOGGER.info("Got message FROM: " + from + " TO: " + recipient);
    Session session = null;
    try {
      session = slingRepository.loginAdministrative(null);

      List<String> paths = getLocalPath(session, recipient);
      if (paths.size() > 0) {
        Map<String, Object> mapProperties = new HashMap<String, Object>();
        mapProperties.put(
            JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, MessageConstants.SAKAI_MESSAGE_RT);
        mapProperties.put(MessageConstants.PROP_SAKAI_READ, false);
        mapProperties.put(MessageConstants.PROP_SAKAI_FROM, from);
        mapProperties.put(MessageConstants.PROP_SAKAI_MESSAGEBOX, MessageConstants.BOX_INBOX);

        Node createdMessage = writeMessage(session, mapProperties, data, paths.get(0));
        String messagePath = createdMessage.getPath();
        String messageId = createdMessage.getProperty("message-id").getString();
        LOGGER.info("Created message {} at: {} ", messageId, messagePath);

        // we might want alias expansion
        for (int i = 1; i < paths.size(); i++) {
          String targetPath = paths.get(i);
          messagingService.copyMessageNode(createdMessage, targetPath);
        }
        if (session.hasPendingChanges()) {
          session.save();
        }
      }
    } catch (RepositoryException e) {
      LOGGER.error("Unable to write message", e);
      throw new IOException("Message can not be written to repository");
    } finally {
      if (session != null) {
        session.logout();
      }
    }
  }