SLING-3297 - mail archive server sample app, contributed by Igor Bogomolov, thanks!

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1553094 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/mail-archive/docs/sling-mail-archive-server-specs.md b/mail-archive/docs/sling-mail-archive-server-specs.md
new file mode 100644
index 0000000..599b0b3
--- /dev/null
+++ b/mail-archive/docs/sling-mail-archive-server-specs.md
@@ -0,0 +1,42 @@
+Sling Mail Archive Server Specification
+=======================================
+
+Overview
+--------
+The goal of this student project is to create a mail archive server
+based on Apache Sling.
+
+The server is meant both as a high capacity archive server for mailing lists,
+as well as an example application that demonstrates Sling best practices.
+
+This is an initial specification for the server, we'll refine it as we go.
+
+Use cases
+---------
+Here's a rough initial list of use cases:
+
+* Import email live from POP/IMAP servers, as well as via Exchange web services
+* Mass imports of various mail archive file formats: mbox, Outlook PST, etc.
+* Provide time-based and thread-based mail browsing RESTful and web interfaces.
+* Provide short permanent URLs for each individual message and each thread.
+* Optional content filters to collapse repeated sections in messages (quoting other messages).
+* Optional content filters for intelligent linking (to jira etc.)
+* Optional content filters for "de-junking" Outlook messages.
+* Optional content filters for syntax coloring of code excerpts.
+* Optional exclude filters to ignore some messages (Jenkins notifications for instance)
+* Tagging of archived messages, for example to flag them as useful or obsolete. 
+* Tag-based navigation.
+* Full-text and structured search.
+* Traffic statistics.
+
+Architecture, performance, scalability etc.
+-------------------------------------------
+Also a rough list of criteria for now:
+
+* Use Sling for all web interactions, Jackrabbit Oak as the content repository once that becomes available, jQuery etc. for the front-end (or maybe http://createjs.org/)
+* OSGi services for everything, some scripting for HTML rendering and user plugins if appropriate
+* Kill -9 is fine as a shutdown mechanism, causes no harm
+* Handle huge import files, avoid loading the whole thing in memory to stay scalable
+* Scale to thousands of lists and millions of messages
+* Much less than 2 seconds response time for all common operations
+* Optional per-list access control
diff --git a/mail-archive/pom.xml b/mail-archive/pom.xml
new file mode 100644
index 0000000..d8218c6
--- /dev/null
+++ b/mail-archive/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.mailarchive.reactor</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Apache Sling Archive Server Reactor</name>
+
+    <modules>
+        <module>server</module>
+        <module>ui</module>
+    </modules>
+</project>
diff --git a/mail-archive/server/pom.xml b/mail-archive/server/pom.xml
new file mode 100644
index 0000000..2351f1f
--- /dev/null
+++ b/mail-archive/server/pom.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>18</version>
+    </parent>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.mailarchive.server</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <name>Apache Sling Mail Archive Server</name>
+    <description>Server is designed to archive messages of mailing lists and allows convenient search and navigation through them.</description>
+
+    <properties>
+        <sling.java.version>6</sling.java.version>
+    </properties>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Sling-Initial-Content>initial-content</Sling-Initial-Content>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.6.2.201302030002</version>
+                <executions>
+                    <execution>
+                        <id>prepare-agent</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>report</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>check</id>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                        <configuration>
+                            <check>
+								start with low values
+								<classRatio>40</classRatio>
+								<instructionRatio>40</instructionRatio>
+								<methodRatio>40</methodRatio>
+								<branchRatio>40</branchRatio>
+								<complexityRatio>40</complexityRatio>
+								<lineRatio>40</lineRatio>
+							</check>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mime4j-core</artifactId>
+            <version>0.8.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mime4j-mbox-iterator</artifactId>
+            <version>0.8.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mime4j-dom</artifactId>
+            <version>0.8.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-mime4j-storage</artifactId>
+            <version>0.8.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-jcr-commons</artifactId>
+            <version>2.7.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.scheduler</artifactId>
+            <version>2.3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.http.jetty</artifactId>
+            <version>2.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.4.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+        <!-- Testing -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.testing</artifactId>
+            <version>2.0.14</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/AttachmentFilter.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/AttachmentFilter.java
new file mode 100644
index 0000000..dd2cf6f
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/AttachmentFilter.java
@@ -0,0 +1,9 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import org.apache.james.mime4j.message.BodyPart;
+
+public interface AttachmentFilter {
+    
+    boolean isEligible(BodyPart attachment);
+    
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/Connector.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/Connector.java
new file mode 100644
index 0000000..ae247c5
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/Connector.java
@@ -0,0 +1,7 @@
+package org.apache.sling.mailarchiveserver.api;
+
+public interface Connector {
+
+	int checkNewMessages();
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MboxParser.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MboxParser.java
new file mode 100644
index 0000000..e4dc053
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MboxParser.java
@@ -0,0 +1,13 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.dom.Message;
+
+public interface MboxParser {
+	
+	Iterator<Message> parse(InputStream is) throws IOException;
+	
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageProcessor.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageProcessor.java
new file mode 100644
index 0000000..057a1dc
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageProcessor.java
@@ -0,0 +1,10 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import org.apache.james.mime4j.dom.Message;
+
+/** MessageProcessors are used by our {@link MessageStore}
+ *  implementation to pre-process messages before storing them.
+ */
+public interface MessageProcessor {
+	void processMessage(Message m);
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageStore.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageStore.java
new file mode 100644
index 0000000..c602e7c
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/MessageStore.java
@@ -0,0 +1,14 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.dom.Message;
+
+public interface MessageStore {
+	
+	void save(Message m) throws IOException;
+	
+	void saveAll(Iterator<Message> iterator) throws IOException;
+	
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/QueryBuilder.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/QueryBuilder.java
new file mode 100644
index 0000000..5663f9b
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/QueryBuilder.java
@@ -0,0 +1,10 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import java.util.List;
+import java.util.Map;
+
+public interface QueryBuilder {
+
+	String buildQuery(Map<String, List<String>> tokens, String lang);
+	
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchQueryParser.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchQueryParser.java
new file mode 100644
index 0000000..7e5e933
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchQueryParser.java
@@ -0,0 +1,10 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import java.util.List;
+import java.util.Map;
+
+public interface SearchQueryParser {
+    
+	Map<String, List<String>> parse(String query);
+	
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchService.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchService.java
new file mode 100644
index 0000000..e69b6f4
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/SearchService.java
@@ -0,0 +1,11 @@
+package org.apache.sling.mailarchiveserver.api;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+
+public interface SearchService {
+
+	Iterator<Resource> find(String phrase);
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/ThreadKeyGenerator.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/ThreadKeyGenerator.java
new file mode 100644
index 0000000..74cb9f4
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/api/ThreadKeyGenerator.java
@@ -0,0 +1,7 @@
+package org.apache.sling.mailarchiveserver.api;
+
+public interface ThreadKeyGenerator {
+
+	String getThreadKey(String subject);
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/AttachmentFilterImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/AttachmentFilterImpl.java
new file mode 100644
index 0000000..7b6662f
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/AttachmentFilterImpl.java
@@ -0,0 +1,54 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.james.mime4j.dom.BinaryBody;
+import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.TextBody;
+import org.apache.james.mime4j.message.BodyPart;
+import org.apache.sling.mailarchiveserver.api.AttachmentFilter;
+
+@Component
+@Service(AttachmentFilter.class)
+public class AttachmentFilterImpl implements AttachmentFilter {
+
+    private Set<String> eligibleExtensions = null;
+    private long maxSize = (long) 5e6; // 5 Mb
+
+    @Override
+    public boolean isEligible(BodyPart attachment) {
+        // extension check
+        final String filename = attachment.getFilename();
+        String ext = "";
+        int idx = filename.lastIndexOf('.');
+        if (idx > -1) {
+            ext = filename.substring(idx + 1);
+        }
+        if (eligibleExtensions != null && !eligibleExtensions.contains(ext)) {
+            return false;
+        }
+        
+        // size check
+        final Body body = attachment.getBody();
+        try {
+            if (
+                    body instanceof BinaryBody 
+                    && IOUtils.toByteArray(((BinaryBody) body).getInputStream()).length > maxSize
+                    || 
+                    body instanceof TextBody
+                    && IOUtils.toByteArray(((TextBody) body).getInputStream()).length > maxSize ) {
+                return false;
+            }
+        } catch (IOException e) {
+            return false;
+        }
+
+        // true, if nothing wrong
+        return true;
+    }
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ConnectorScheduler.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ConnectorScheduler.java
new file mode 100644
index 0000000..ac8f02a
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ConnectorScheduler.java
@@ -0,0 +1,79 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.sling.mailarchiveserver.api.Connector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+public class ConnectorScheduler implements Runnable {
+
+	private static final int SLEEP_TIME_BETWEEN_NEW_MAIL_CHECKS = 20;
+
+	private static final Logger logger = LoggerFactory.getLogger(ConnectorScheduler.class);
+	private static final int WAITING_TIME_LIMIT_BEFORE_TERMINATION = 5000; 
+
+	private boolean running = true;
+	private Thread executionThread = null;
+
+	@Reference(
+			cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, 
+			policy=ReferencePolicy.DYNAMIC,
+			referenceInterface=Connector.class)
+	private List<Connector> scheduledConnectors = new ArrayList<Connector>();
+	private Deque<Connector> executionQueue;
+
+	@Activate
+	public void activate() {
+		executionThread = new Thread(this, "Connector Scheduler's execution thread");
+		executionThread.setDaemon(true);
+		executionThread.start(); 
+	}
+
+	@Deactivate
+	public void deactivate() throws InterruptedException {
+		if (executionThread != null) {
+			running = false;
+			executionThread.join(WAITING_TIME_LIMIT_BEFORE_TERMINATION);
+		}
+	}
+
+	@Override
+	public void run() {
+		while (running) {
+			executionQueue = new ArrayDeque<Connector>(scheduledConnectors);
+			while (!executionQueue.isEmpty() && running) {
+				Connector c = executionQueue.remove();
+				int retreived = c.checkNewMessages();
+				logger.info("Processed {} messages using \"{}\" connector.", retreived, c.toString());
+			}
+			try {
+				TimeUnit.SECONDS.sleep(SLEEP_TIME_BETWEEN_NEW_MAIL_CHECKS);
+			} catch (InterruptedException e) {
+				running = false;
+			}
+		}
+	}
+
+	public synchronized void bindConnector(Connector c) {
+		logger.info("Connector " + c.toString() + " added to pool.");
+		scheduledConnectors.add(c);
+	}
+
+	public synchronized void unbindConnector(Connector c) {
+		logger.info("Connector " + c.toString() + " removed from pool.");
+		scheduledConnectors.remove(c);
+	}
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ImportMboxServlet.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ImportMboxServlet.java
new file mode 100644
index 0000000..2401209
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ImportMboxServlet.java
@@ -0,0 +1,51 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.sling.SlingServlet;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.mailarchiveserver.api.MboxParser;
+import org.apache.sling.mailarchiveserver.api.MessageStore;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("serial")
+@SlingServlet(
+		resourceTypes = "mailarchiveserver/import",
+		methods = {"POST", "PUT"})
+public class ImportMboxServlet extends SlingAllMethodsServlet {
+
+	private static final Logger logger = LoggerFactory.getLogger(ImportMboxServlet.class);
+
+	private static final String IMPORT_FILE_ATTRIB_NAME = "mboxfile";
+
+	@Reference
+	private MboxParser parser;
+	@Reference
+	private MessageStore store;
+
+	@Override
+	protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) 
+			throws ServletException, IOException {
+		RequestParameter param = request.getRequestParameter(IMPORT_FILE_ATTRIB_NAME);
+		if (param != null) {
+			logger.info("Processing attachment: " + param.toString());
+
+			InputStream mboxIS = param.getInputStream();
+			store.saveAll(parser.parse(mboxIS));
+
+			response.sendRedirect(MailArchiveServerConstants.ARCHIVE_PATH + ".html");
+		} else {
+			logger.info("No attachment to process.");
+		}
+	}
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImpl.java
new file mode 100644
index 0000000..8fb5b57
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImpl.java
@@ -0,0 +1,440 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.james.mime4j.dom.field.FieldName.SUBJECT;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.CONTENT;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.HTML_BODY;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.LIST_ID;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.NAME;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.PLAIN_BODY;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.X_ORIGINAL_HEADER;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.util.Text;
+import org.apache.james.mime4j.dom.BinaryBody;
+import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.dom.TextBody;
+import org.apache.james.mime4j.dom.field.FieldName;
+import org.apache.james.mime4j.message.BodyPart;
+import org.apache.james.mime4j.message.DefaultMessageWriter;
+import org.apache.james.mime4j.stream.Field;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.mailarchiveserver.api.AttachmentFilter;
+import org.apache.sling.mailarchiveserver.api.MessageProcessor;
+import org.apache.sling.mailarchiveserver.api.MessageStore;
+import org.apache.sling.mailarchiveserver.api.ThreadKeyGenerator;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+import org.apache.sling.mailarchiveserver.util.MessageFieldName;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+@Service(MessageStore.class)
+public class MessageStoreImpl implements MessageStore {
+
+    public static final String PLAIN_MIMETYPE = "text/plain";
+    public static final String HTML_MIMETYPE = "text/html";
+
+    @Reference
+    private	ResourceResolverFactory resourceResolverFactory;
+    @Reference
+    ThreadKeyGenerator threadKeyGen;
+    @Reference
+    AttachmentFilter attachmentFilter;
+    @Reference(
+            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, 
+            policy=ReferencePolicy.DYNAMIC,
+            referenceInterface=MessageProcessor.class)
+    private SortedSet<ServiceReference> messageProcessorRefs = new TreeSet<ServiceReference>();
+    private List<MessageProcessor> messageProcessors = new ArrayList<MessageProcessor>();
+    private boolean processorsUpdated;
+    private BundleContext bundleContext = null;
+
+    static final String FIELD_SEPARATOR = " : ";
+    private static final String[] RE_PREFIXES = { "re:", "aw:", "fw:", "re ", "aw ", "fw ", "答复"};
+    // for testing
+    String archivePath = MailArchiveServerConstants.ARCHIVE_PATH;
+    String resourceTypeKey = MailArchiveServerConstants.RT_KEY;
+
+    private static final Logger logger = LoggerFactory.getLogger(MessageStoreImpl.class);
+
+    @Activate
+    private void activate(BundleContext bc) {
+        bundleContext = bc;
+    }
+
+    protected ResourceResolver getResourceResolver() throws LoginException {
+        return resourceResolverFactory.getAdministrativeResourceResolver(null);
+    }
+
+    public void save(Message msg) throws IOException {
+        ResourceResolver resolver = null;
+        try {
+            resolver = getResourceResolver();
+            save(resolver, msg);
+        } catch (LoginException e) {
+            throw new RuntimeException("LoginException", e);
+        } finally {
+            if(resolver != null) {
+                resolver.close();
+            }
+        }
+    }
+
+    private void save(ResourceResolver resolver, Message msg) throws IOException, LoginException {
+        // apply message processors
+        for(MessageProcessor processor : getSortedMessageProcessors()) {
+            logger.debug("Calling {}", processor);
+            processor.processMessage(msg);
+        }
+
+        // into path: archive/domain/list/thread/message
+        final Map<String, Object> msgProps = new HashMap<String, Object>();
+        final List<BodyPart> attachments = new ArrayList<BodyPart>(); 
+
+        msgProps.put(resourceTypeKey, MailArchiveServerConstants.MESSAGE_RT);
+
+        StringBuilder plainBody = new StringBuilder();
+        StringBuilder htmlBody = new StringBuilder();
+        Boolean hasBody = false;
+
+        if (!msg.isMultipart()) {
+            plainBody = new StringBuilder(getTextPart(msg)); 
+        } else {
+            Multipart multipart = (Multipart) msg.getBody();
+            recursiveMultipartProcessing(multipart, plainBody, htmlBody, hasBody, attachments);
+        }
+
+        msgProps.put(PLAIN_BODY, plainBody.toString().replaceAll("\r\n", "\n"));
+        if (htmlBody.length() > 0) {
+            msgProps.put(HTML_BODY, htmlBody.toString());
+        }
+
+        msgProps.putAll(getMessagePropertiesFromHeader(msg.getHeader()));
+        
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new DefaultMessageWriter().writeHeader(msg.getHeader(), baos);
+        String origHdr = baos.toString(MailArchiveServerConstants.DEFAULT_ENCODER.charset().name());
+        msgProps.put(X_ORIGINAL_HEADER, origHdr);
+        
+        final Header hdr = msg.getHeader();
+        final String listIdRaw = hdr.getField(LIST_ID).getBody();
+        final String listId = listIdRaw.substring(1, listIdRaw.length()-1); // remove < and >
+
+        final String list = getListNodeName(listId);
+        final String domain = getDomainNodeName(listId);
+        final String subject = (String) msgProps.get(SUBJECT);
+        final String threadPath = threadKeyGen.getThreadKey(subject);
+        final String threadName = removeRe(subject);
+
+        Resource parentResource = assertEachNode(resolver, archivePath, domain, list, threadPath, threadName);
+
+        String msgNodeName = makeJcrFriendly((String) msgProps.get(NAME));
+        boolean isMsgNodeCreated = assertResource(resolver, parentResource, msgNodeName, msgProps);
+        if (isMsgNodeCreated) {
+            Resource msgResource = resolver.getResource(parentResource, msgNodeName);
+            for (BodyPart att : attachments) {
+                if (!attachmentFilter.isEligible(att)) {
+                    continue;
+                }
+                final Map<String, Object> attProps = new HashMap<String, Object>();
+                parseHeaderToProps(att.getHeader(), attProps);
+                Body body = att.getBody();
+                if (body instanceof BinaryBody) {
+                    attProps.put(CONTENT, ((BinaryBody) body).getInputStream());
+                } else if (body instanceof TextBody) {
+                    attProps.put(CONTENT, ((TextBody) body).getInputStream());
+                }
+
+                String attNodeName = Text.escapeIllegalJcrChars(att.getFilename());
+                assertResource(resolver, msgResource, attNodeName, attProps);
+            }
+
+            updateThread(resolver, parentResource, msgProps);
+        }
+    }
+
+    static void recursiveMultipartProcessing(Multipart multipart, StringBuilder plainBody, StringBuilder htmlBody, Boolean hasBody, List<BodyPart> attachments) throws IOException {
+        for (Entity enitiy : multipart.getBodyParts()) {
+            BodyPart part = (BodyPart) enitiy;
+            if (part.getDispositionType() != null && !part.getDispositionType().equals("")) {
+                // if DispositionType is null or empty, it means that it's multipart, not attached file
+                attachments.add(part);
+            } else {
+                if (part.isMimeType(PLAIN_MIMETYPE) && !hasBody) {
+                    plainBody.append(getTextPart(part));
+                    hasBody = true;
+                } else if (part.isMimeType(HTML_MIMETYPE) && !hasBody) {
+                    htmlBody.append(getTextPart(part));
+                } else if (part.isMultipart()) {
+                    recursiveMultipartProcessing((Multipart) part.getBody(), plainBody, htmlBody, hasBody, attachments);
+                } 
+            }
+        }
+    }
+
+    public void saveAll(Iterator<Message> iterator) throws IOException {
+        ResourceResolver resolver = null;
+        try {
+            resolver = getResourceResolver();
+            int mcount = 0;
+            while (iterator.hasNext()) {
+                Message msg = iterator.next();
+                save(resolver, msg);
+
+                mcount++;
+                if (mcount % 100 == 0) {
+                    logger.debug(mcount+" messages processed.");
+                }
+            }
+            logger.info(mcount+" messages processed.");
+        } catch(LoginException e) {
+            throw new RuntimeException("LoginException", e);
+        } finally {
+            if(resolver != null) {
+                resolver.close();
+            }
+        }
+    }
+
+    /**
+     *	code taken from http://www.mozgoweb.com/posts/how-to-parse-mime-message-using-mime4j-library/
+     */
+    static String getTextPart(Entity part) throws IOException {
+        TextBody tb = (TextBody) part.getBody();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        tb.writeTo(baos);
+        return baos.toString(MailArchiveServerConstants.DEFAULT_ENCODER.charset().name());
+    }
+
+    static Map<String, Object> getMessagePropertiesFromHeader(Header hdr) {
+        Map<String, Object> props = new HashMap<String, Object>();
+
+        parseHeaderToProps(hdr, props);
+
+        // message name
+        String name;
+        if (hdr.getField("Message-ID") != null) {
+            name = hdr.getField("Message-ID").getBody();
+            name = name.substring(1, name.length()-1); // remove < and >
+        } else {
+            name = Integer.toHexString(hdr.getField("Date").hashCode());
+        }
+        props.put(MessageFieldName.NAME, name);
+
+        return props;
+    }
+
+    private static void parseHeaderToProps(Header hdr, Map<String, Object> props) {
+        Set<String> processed = new HashSet<String>();
+        for (Field f : hdr.getFields()) {
+            String name = f.getName();
+            if (!processed.contains(name)) {
+                processed.add(name);
+                String value = "";
+                List<Field> fields = hdr.getFields(name);
+                for (Field fl : fields) {
+                    value += fl.getBody()+FIELD_SEPARATOR;
+                }
+                props.put(name, value.substring(0, value.length()-FIELD_SEPARATOR.length()));
+            }
+        }
+    }
+
+    static String getListNodeName(String listId) {
+        String list = "";
+        String[] split = listId.split("\\.");
+        int splitL = split.length;
+        if (splitL >= 4) {
+            for (int i = 0; i < splitL-2; i++) {
+                list += split[i] + ".";
+            }
+            list = list.substring(0, list.length() - 1);
+        } else if (splitL == 3) {
+            list = split[0];
+        } else {
+            throw new RuntimeException("List-Id is invalid: minimum 2 separatory dots required.");
+        }
+        return list;
+    }
+
+    static String getDomainNodeName(String listId) {
+        String[] split = listId.split("\\.");
+        int splitL = split.length;
+        if (splitL >= 3) {
+            return split[splitL-2] + "." + split[splitL-1];
+        } else {
+            throw new RuntimeException("List-Id is invalid: minimum 2 separatory dots required.");
+        }
+    }
+
+    private Resource assertEachNode(ResourceResolver resolver, String archive, String domain, String list, 
+            String threadPath, String threadName) throws PersistenceException, LoginException {
+        final String pathToMessage = archive+domain+"/"+list+"/"+threadPath;
+
+        String path = pathToMessage;
+        Resource resource = resolver.getResource(path);
+
+        int cnt = 0;
+        while (resource == null) {
+            cnt++;
+            path = path.substring(0, path.lastIndexOf("/"));
+            resource = resolver.getResource(path);
+        }
+
+        if (cnt > 0) {
+            int threadNodesNumber = threadPath.split("/").length;
+
+            // bind paths
+            List<String> nodePaths = new ArrayList<String>();
+            nodePaths.add(domain);
+            nodePaths.add(list);
+            for (String node : threadPath.split("/")) {
+                nodePaths.add(node);
+            }
+
+            // bind props
+            List<Map<String, Object>> nodeProps = new ArrayList<Map<String, Object>>();
+            nodeProps.add(setProperties(MailArchiveServerConstants.DOMAIN_RT, domain));
+            nodeProps.add(setProperties(MailArchiveServerConstants.LIST_RT, list));
+            for (int i = 0; i < threadNodesNumber-1; i++) {
+                nodeProps.add(null);
+            }
+            nodeProps.add(setProperties(MailArchiveServerConstants.THREAD_RT, threadName));
+
+            // checking
+            for (int i = nodePaths.size()-cnt; i < nodePaths.size(); i++) {
+                String name = nodePaths.get(i);
+                assertResource(resolver, resource, name, nodeProps.get(i));
+                resource = resolver.getResource(resource.getPath()+"/"+name);
+            }
+        }
+
+        resource = resolver.getResource(pathToMessage);
+        if (resource == null) {
+            throw new RuntimeException("Parent resource cannot be null.");
+        } else {
+            return resource;
+        }
+
+    }
+
+    private Map<String, Object> setProperties(String resourceType, String name) {
+        Map<String, Object> props = new HashMap<String, Object>();
+        props.put(resourceTypeKey, resourceType);
+        props.put(MessageFieldName.NAME, name);
+        return props;
+
+    }
+
+    private boolean assertResource(ResourceResolver resolver, Resource parent, String name, Map<String, Object> newProps) 
+            throws LoginException, PersistenceException {
+        String checkPath = parent.getPath()+"/"+name;
+        final Resource checkResource = resolver.getResource(checkPath);
+        if (checkResource == null) {
+            final Resource newResource = resolver.create(parent, name, newProps);
+            resolver.commit();
+            logger.debug(String.format("Resource created at %s .", newResource.getPath()));
+            return true;
+        } else {
+            logger.debug(String.format("Resource at %s already exists.", checkResource.getPath()));
+            return false;
+        }
+    }
+
+    private static void updateThread(ResourceResolver resolver, Resource thread, Map<String, Object> msgProps) throws PersistenceException {
+        final ModifiableValueMap thrdProps = thread.adaptTo(ModifiableValueMap.class);
+        Long prop = (Long) thrdProps.get(MessageFieldName.LAST_UPDATE);
+        Date updatedDate = null; 
+        if (prop != null) {
+            updatedDate = new Date(prop);
+        }
+        final String msgProp = (String) msgProps.get(FieldName.DATE);
+        SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
+        final Date msgDate = sdf.parse(msgProp, new ParsePosition(0));
+        if (updatedDate == null || msgDate.after(updatedDate)) {
+            thrdProps.put(MessageFieldName.LAST_UPDATE, msgDate.getTime());
+            resolver.commit();
+        } 
+    }
+
+    static String makeJcrFriendly(String s) {
+        return s.replaceAll("[\\s\\.-]+", "_").replaceAll("\\W", "").replaceAll("\\_", " ").trim().replaceAll("[ ]+", "_");
+    }
+
+    static String removeRe(String s) {
+        s = s.trim();
+        boolean flag = true;
+        while (flag) {
+            flag = false;
+            for (String prefix : RE_PREFIXES) {
+                if (s.toLowerCase().startsWith(prefix)) {
+                    s = s.substring(3).trim();
+                    flag = true;
+                }
+            }
+        }
+        return s.trim();
+    }
+
+    public synchronized void bindMessageProcessor(ServiceReference ref) {
+        synchronized (messageProcessorRefs) {
+            messageProcessorRefs.add(ref);
+        }
+        processorsUpdated = true;
+        logger.info("Message processor {} added to pool.", ref);
+    }
+
+    public void unbindMessageProcessor(ServiceReference ref) {
+        synchronized (messageProcessorRefs) {
+            messageProcessorRefs.remove(ref);
+        }
+        processorsUpdated = true;
+        logger.info("Message processor {} removed from pool.", ref);
+    }
+
+    private Collection<MessageProcessor> getSortedMessageProcessors() {
+        if(processorsUpdated) {
+            synchronized (messageProcessorRefs) {
+                processorsUpdated = false;
+                messageProcessors.clear();
+                for(ServiceReference ref : messageProcessorRefs) {
+                    messageProcessors.add((MessageProcessor)bundleContext.getService(ref));
+                }
+            }
+            logger.debug("Updated sorted list of MessageProcessor: {}", messageProcessors);
+        }
+        return messageProcessors;
+    }
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImpl.java
new file mode 100644
index 0000000..4573230
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImpl.java
@@ -0,0 +1,100 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.MessageBuilder;
+import org.apache.james.mime4j.mboxiterator.CharBufferWrapper;
+import org.apache.james.mime4j.mboxiterator.MboxIterator;
+import org.apache.james.mime4j.message.DefaultMessageBuilder;
+import org.apache.sling.mailarchiveserver.api.MboxParser;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+
+@Component
+@Service(MboxParser.class)
+public class Mime4jMboxParserImpl implements MboxParser {
+
+	@Override
+	public Iterator<Message> parse(InputStream is) throws IOException {
+		return new Mime4jParserIterator(is);
+	}
+
+	static class Mime4jParserIterator implements Iterator<Message> {
+
+		private Iterator<CharBufferWrapper> mboxIterator;
+		private static final int BUFFER_SIZE = 10*1024*1024;
+		String tempFileAbsPath = null;
+
+		public Mime4jParserIterator(InputStream is) throws IOException {
+			File tempFile = null;
+			FileOutputStream fileOS = null;
+			try {
+				// create temp file
+				tempFile = File.createTempFile("MAS_", ".mbox");
+				tempFileAbsPath = tempFile.getAbsolutePath();
+				fileOS = new FileOutputStream(tempFile);
+				FileChannel fileChannel = fileOS.getChannel();
+				byte[] buffer = new byte[BUFFER_SIZE];
+				int read = 0;
+				while ((read = is.read(buffer)) != -1) {
+					ByteBuffer buf2 = MailArchiveServerConstants.DEFAULT_ENCODER.encode(CharBuffer.wrap(new String(buffer, 0, read)));
+					fileChannel.write(buf2);
+				}
+				fileChannel.close();
+
+
+				createMboxIterator(tempFile);
+			} finally {
+				if (tempFile.exists()) {
+					tempFile.delete();
+					tempFile = null;
+				}
+				if (fileOS != null) {
+					fileOS.close();
+					fileOS = null;
+				}
+				if (is != null) {
+					is.close();
+					is = null;
+				}
+			}
+		}
+
+		private void createMboxIterator(File f) throws FileNotFoundException, IOException {
+			mboxIterator = MboxIterator.fromFile(f).charset(MailArchiveServerConstants.DEFAULT_ENCODER.charset()).build().iterator();
+		}
+
+		public boolean hasNext() {
+			return mboxIterator.hasNext();
+		}
+
+		public Message next() {
+			MessageBuilder builder = new DefaultMessageBuilder();
+			Message message = null;
+			try {
+				message = builder.parseMessage(new ByteArrayInputStream(mboxIterator.next().toString().getBytes(MailArchiveServerConstants.DEFAULT_ENCODER.charset().name())));
+			} catch (MimeException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			return message;
+		}
+
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+	}
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/QueryBuilderImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/QueryBuilderImpl.java
new file mode 100644
index 0000000..f3666d2
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/QueryBuilderImpl.java
@@ -0,0 +1,96 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.MESSAGE_FIELDS;
+import static org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.mailarchiveserver.api.QueryBuilder;
+import org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.SearchParameter;
+
+@Component
+@Service(QueryBuilder.class)
+public class QueryBuilderImpl implements QueryBuilder {
+
+	static final String BASE = "SELECT * FROM [nt:unstructured] WHERE [sling:resourceType] = 'mailarchiveserver/message'";
+	static final String DUMMY = "SELECT * FROM [nt:frozenNode] WHERE [42] = 0";
+	private static final String AND = " AND ";
+	private static final String OR = " OR ";
+
+	public static final String SQL2 = "SQL2";
+
+	private String buildSQL2Query(Map<String, List<String>> tokens) {
+		if (tokens == null) {
+			return BASE; 
+		} else if (tokens.size() == 0) {
+			return DUMMY;
+		}
+
+		String constraints = "";
+
+		// tokens constraints
+		for (String tokenClass : tokens.keySet()) {
+			if (tokenClass.equals(SearchParameter.NONE)) {
+				continue;
+			}
+			String fieldConstraint =  buildFieldConstraints(tokenClass, tokens);
+			constraints += "("+ fieldConstraint +")" + AND;
+		}
+
+		// global constraints
+		String globalConstraint = "";
+		List<String> ls = tokens.get(SearchParameter.NONE);
+		if (ls != null) {
+			for (String msgField : MESSAGE_FIELDS) {
+				for (String value : ls) {
+					if (!value.trim().equals("")) {
+						globalConstraint += sqlLikeConstraint(sqlLower(msgField), value.toLowerCase()) + OR;
+					}
+				}
+			}
+			globalConstraint = globalConstraint.substring(0, globalConstraint.length()-OR.length());
+		}
+		if (!globalConstraint.equals("")) {
+			constraints += "("+ globalConstraint +")" + AND;
+		}
+
+		if (constraints.equals("")) {
+			return BASE;
+		} else {
+			return BASE + " AND " + constraints.substring(0, constraints.length()-AND.length());
+		}
+	}
+
+	private static String buildFieldConstraints(String tokenClass, Map<String, List<String>> tokens) {
+		List<String> ls = tokens.get(tokenClass);
+		String messageField = SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP.get(tokenClass);
+		String fieldConstraint = "";
+		for (String value : ls) {
+			if (!value.trim().equals("")) {
+				fieldConstraint += sqlLikeConstraint(sqlLower(messageField), value.toLowerCase()) + OR;
+			}
+		}
+		return fieldConstraint.substring(0, fieldConstraint.length()-OR.length());
+	}
+
+	private static String sqlLikeConstraint(String messageField, String value) {
+		return messageField + " LIKE '%" + value + "%'";
+	}
+
+	private static String sqlLower(String messageField) {
+		return "LOWER("+ messageField + ")";
+	}
+
+	@Override
+	public String buildQuery(Map<String, List<String>> tokens, String lang) {
+		if (lang.trim().equalsIgnoreCase(SQL2)) {
+			return buildSQL2Query(tokens);
+		} else {
+			throw new IllegalArgumentException("Invalid lang argument!");
+		}
+	}
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchQueryParserImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchQueryParserImpl.java
new file mode 100644
index 0000000..ade42b8
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchQueryParserImpl.java
@@ -0,0 +1,118 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.mailarchiveserver.api.SearchQueryParser;
+
+@Component
+@Service(SearchQueryParser.class)
+public class SearchQueryParserImpl implements SearchQueryParser {
+
+
+	private static final String SPACE_SUBSTITUTION = ".-.";
+
+	@Override
+	public Map<String, List<String>> parse(String phrase) {
+		Map<String, List<String>> res = new HashMap<String, List<String>>();
+		phrase = phrase.trim();
+		if (phrase == "") {
+			return null;
+		}
+
+		phrase = parseQuotes(phrase);
+
+		String[] lexemes = phrase.split(" ");
+		for (String lexeme : lexemes) {
+			String[] token = lexeme.split(":");
+			if (token.length == 1) {
+				insertTokenIntoMap(postprocessQuotedPhrase(token[0].trim()), SearchParameter.NONE, res);
+			} else if (token.length > 1) {
+				String searchParam = getSearchParameter(token[0]);
+				if (searchParam != null) {
+					insertTokenIntoMap(postprocessQuotedPhrase(token[1].trim()), searchParam, res);
+				}
+			}
+		}
+		return res;
+	}
+
+	private String postprocessQuotedPhrase(String phrase) {
+		return phrase.replace(SPACE_SUBSTITUTION, " ");
+	}
+
+	private String parseQuotes(String phrase) {
+		String[] quotes = phrase.split("\"");
+		for (int i = 1; i < quotes.length; i += 2) {
+			quotes[i] = quotes[i].replace(" ", SPACE_SUBSTITUTION);
+		}
+		String res = "";
+		for (String s : quotes) {
+			res += s;
+		}
+		return res;
+	}
+
+	private static String getSearchParameter(String s) {
+		s = s.trim().toLowerCase();
+		if (SEARCH_PARAMETERES.contains(s)) {
+			return s;
+		} else {
+			return null;
+		}
+	}
+
+	private static void insertTokenIntoMap(String tokenString, String tokenClass, Map<String, List<String>> map) {
+		List<String> ls = map.get(tokenClass);
+		if (ls == null) {
+			ls = new ArrayList<String>();
+		}
+		ls.add(tokenString);
+		map.put(tokenClass, ls);
+	}
+
+	public static final Set<String> SEARCH_PARAMETERES = new HashSet<String>();
+	public static final Set<String> MESSAGE_FIELDS = new HashSet<String>();
+	public static final Map<String, String> SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP = new HashMap<String, String>();
+
+	static {
+		SEARCH_PARAMETERES.add(SearchParameter.FROM);
+		SEARCH_PARAMETERES.add(SearchParameter.SUBJ);
+		SEARCH_PARAMETERES.add(SearchParameter.LIST);
+
+		MESSAGE_FIELDS.add(SearchableMessageField.FROM);
+		MESSAGE_FIELDS.add(SearchableMessageField.SUBJ);
+		MESSAGE_FIELDS.add(SearchableMessageField.LIST);
+		MESSAGE_FIELDS.add(SearchableMessageField.BODY);
+
+		SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP.put(SearchParameter.FROM, SearchableMessageField.FROM);
+		SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP.put(SearchParameter.SUBJ, SearchableMessageField.SUBJ);
+		SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP.put(SearchParameter.LIST, SearchableMessageField.LIST);
+	}
+
+	public static class SearchParameter {
+		public static final String NONE = ""; // not in SEARCH_PARAMETERES !
+		public static final String FROM = "from";
+		public static final String SUBJ = "subject";
+		public static final String LIST = "list";
+	}
+
+	public static class SearchableMessageField {
+		public static final String FROM = "From";
+		public static final String SUBJ = "Subject";
+		public static final String LIST = "'List-Id'";
+		public static final String BODY = "Body";
+		//		public static final String DATE = "";
+		//		public static final String FROM = "";
+		//		public static final String TO = "";
+
+
+	}
+
+}
\ No newline at end of file
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchServiceImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchServiceImpl.java
new file mode 100644
index 0000000..67bff0b
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/SearchServiceImpl.java
@@ -0,0 +1,42 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import java.util.Iterator;
+
+import javax.jcr.query.Query;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.mailarchiveserver.api.SearchQueryParser;
+import org.apache.sling.mailarchiveserver.api.SearchService;
+
+@Component
+@Service(SearchService.class)
+public class SearchServiceImpl implements SearchService {
+
+	@Reference
+	private	ResourceResolverFactory resourceResolverFactory;
+	ResourceResolver resolver = null;
+	@Reference 
+	private SearchQueryParser parser;
+	private QueryBuilderImpl queryBuilder = new QueryBuilderImpl();
+
+	@Activate
+	public void activate() throws LoginException {
+		if (resolver == null) {
+			resolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+		}
+	}
+
+	@Override
+	public Iterator<Resource> find(String phrase) {
+		String query = queryBuilder.buildQuery(parser.parse(phrase), QueryBuilderImpl.SQL2);
+		Iterator<Resource> res = resolver.findResources(query, Query.JCR_SQL2);
+		return res;
+	}
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImpl.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImpl.java
new file mode 100644
index 0000000..6d074e8
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImpl.java
@@ -0,0 +1,92 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static java.lang.Character.isLetterOrDigit;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.makeJcrFriendly;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.removeRe;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.sling.mailarchiveserver.api.ThreadKeyGenerator;
+
+@Component
+@Service(ThreadKeyGenerator.class)
+public class ThreadKeyGeneratorImpl implements ThreadKeyGenerator {
+
+    /**
+     * These constants are gotten by sampling around 1500 messages 
+     * from some open source projects using SubjectLettersEntropy class.
+     * 
+     * Entropy of each letter position of the subject was calculated. And two letter positions 
+     * with biggest entropy and occurrence in at least 90% of the messages were chosen.
+     * 
+     * In order to {@link #getThreadKey(Message)} works correctly, following invariant should hold: LETTER_POS_WITH_BIGGEST_ENTROPY < LETTER_POS_WITH_2ND_BIGGEST_ENTROPY
+     */
+    private static final int LETTER_POS_WITH_BIGGEST_ENTROPY = 9;
+    private static final int LETTER_POS_WITH_2ND_BIGGEST_ENTROPY = 40;
+    private static final String UNADDRESSABLE_SUBJECT = "unaddressable subject";
+
+    public String getThreadKey(String subject) {
+        String wordCharsSubj;
+        String noReSubj;
+        if (subject != null) {
+            noReSubj = removeRe(subject);
+            wordCharsSubj = noReSubj.replaceAll("\\W", "_");
+            if (!isAddressable(wordCharsSubj)) {
+                noReSubj = wordCharsSubj = UNADDRESSABLE_SUBJECT;
+            }
+        } else {
+            noReSubj = wordCharsSubj = UNADDRESSABLE_SUBJECT;
+        }
+
+        char prefix1;
+        char prefix2;
+        prefix1 = assignPrefix(wordCharsSubj, LETTER_POS_WITH_BIGGEST_ENTROPY);
+        prefix2 = assignPrefix(wordCharsSubj, LETTER_POS_WITH_2ND_BIGGEST_ENTROPY);
+        return ""+prefix1+"/"+prefix1+prefix2+"/"+ makeJcrFriendly(noReSubj);
+    }
+
+    private static boolean isAddressable(String subject) {
+        for (char c : subject.toCharArray()) {
+            if (isLetterOrDigit(c)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static char assignPrefix(String subject, int length) {
+        char prefix;
+        if (subject.length() > length) {
+
+            int i = length;
+            while (i > -1 && !isLetterOrDigit(subject.charAt(i))) 
+                i--;
+            if (i > -1) 
+                prefix = subject.charAt(i);
+            else {
+                i = length;
+                while (i<subject.length() && !isLetterOrDigit(subject.charAt(i))) 
+                    i++;
+                if (i<subject.length()) 
+                    prefix = subject.charAt(i);
+                else 
+                    throw new IllegalArgumentException();
+            }
+
+        } else {
+
+            int i = subject.length()-1;
+            while (i > -1 && !isLetterOrDigit(subject.charAt(i))) 
+                i--;
+            if (i > -1) 
+                prefix = subject.charAt(i);
+            else 
+                throw new IllegalArgumentException();
+
+        }
+
+        return prefix;
+    }
+
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MailArchiveServerConstants.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MailArchiveServerConstants.java
new file mode 100644
index 0000000..68e51e0
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MailArchiveServerConstants.java
@@ -0,0 +1,18 @@
+package org.apache.sling.mailarchiveserver.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+public class MailArchiveServerConstants {
+	
+	public static final String ARCHIVE_PATH = "/content/mailarchiveserver/archive/";
+	
+	//RT = ResourceType
+	public static final String RT_KEY = "sling:resourceType";
+	public static final String DOMAIN_RT = "mailarchiveserver/domain";
+	public static final String LIST_RT = "mailarchiveserver/list";
+	public static final String THREAD_RT = "mailarchiveserver/thread";
+	public static final String MESSAGE_RT = "mailarchiveserver/message";
+
+	public static final CharsetEncoder DEFAULT_ENCODER = Charset.forName("UTF-8").newEncoder();
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MessageFieldName.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MessageFieldName.java
new file mode 100644
index 0000000..a822ad4
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/MessageFieldName.java
@@ -0,0 +1,20 @@
+package org.apache.sling.mailarchiveserver.util;
+
+
+public class MessageFieldName {
+	public static final String LIST_ID = "List-Id"; 
+	public static final String IN_REPLY_TO = "In-Reply-To"; 
+	public static final String LINK_ID = "linkId";
+    public static final String NAME = "jcr:text";
+    public static final String CONTENT = "jcr:data";
+    public static final String PLAIN_BODY = "Body";
+    public static final String HTML_BODY = "htmlBody";
+    public static final String LAST_UPDATE = "lastUpdate";
+    public static final String X_IMPORT_LOG = "X-mailarchive-import";
+    public static final String X_ADDC_PATH = "X-addc-path";
+    public static final String X_ORIGINAL_HEADER = "X-original-header";
+    public static final String ENCODING = "jcr:encoding";
+    
+//    public static final String X_ORIGINAL_MESSAGE = "X-original-message";
+//    public static final String FILENAME = "filename";
+}
diff --git a/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/SysStreamsLogger.java b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/SysStreamsLogger.java
new file mode 100644
index 0000000..aecaec1
--- /dev/null
+++ b/mail-archive/server/src/main/java/org/apache/sling/mailarchiveserver/util/SysStreamsLogger.java
@@ -0,0 +1,194 @@
+package org.apache.sling.mailarchiveserver.util;
+
+/**
+ * Util class to log System.err and System.out streams.
+ * 
+ * taken from http://stackoverflow.com/questions/11187461/redirect-system-out-and-system-err-to-slf4j
+ * @author itshorty
+ */
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SysStreamsLogger {
+	private static Logger sysOutLogger = LoggerFactory.getLogger("SYSOUT");
+	private static Logger sysErrLogger = LoggerFactory.getLogger("SYSERR");
+
+	public static final PrintStream sysout = System.out;
+	public static final PrintStream syserr = System.err;
+
+	protected static final String LINE_SEPERATOR = System.getProperty("line.separator");
+
+	public static void bindSystemStreams() {
+		// Enable autoflush
+		System.setOut(new PrintStream(new LoggingOutputStream(sysOutLogger, false), true));
+		System.setErr(new PrintStream(new LoggingOutputStream(sysErrLogger, true), true));
+	}
+
+	public static void unbindSystemStreams() {
+		System.setOut(sysout);
+		System.setErr(syserr);
+	}
+
+	private static class LoggingOutputStream extends java.io.OutputStream {
+
+		protected Logger log;
+		protected boolean isError;
+
+		/**
+		 * Used to maintain the contract of {@link #close()}.
+		 */
+		protected boolean hasBeenClosed = false;
+
+		/**
+		 * The internal buffer where data is stored.
+		 */
+		protected byte[] buf;
+
+		/**
+		 * The number of valid bytes in the buffer. This value is always in the
+		 * range <tt>0</tt> through <tt>buf.length</tt>; elements
+		 * <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid byte
+		 * data.
+		 */
+		protected int count;
+
+		/**
+		 * Remembers the size of the buffer for speed.
+		 */
+		private int bufLength;
+
+		/**
+		 * The default number of bytes in the buffer. =2048
+		 */
+		public static final int DEFAULT_BUFFER_LENGTH = 2048;
+
+		private LoggingOutputStream() {
+			// illegal
+		}
+
+		/**
+		 * Creates the LoggingOutputStream to flush to the given Category.
+		 * 
+		 * @param log
+		 *            the Logger to write to
+		 * 
+		 * @param isError
+		 *            the if true write to error, else info
+		 * 
+		 * @exception IllegalArgumentException
+		 *                if cat == null or priority == null
+		 */
+		public LoggingOutputStream(Logger log, boolean isError) throws IllegalArgumentException {
+			if (log == null) {
+				throw new IllegalArgumentException("log == null");
+			}
+
+			this.isError = isError;
+			this.log = log;
+			bufLength = DEFAULT_BUFFER_LENGTH;
+			buf = new byte[DEFAULT_BUFFER_LENGTH];
+			count = 0;
+		}
+
+		/**
+		 * Closes this output stream and releases any system resources
+		 * associated with this stream. The general contract of
+		 * <code>close</code> is that it closes the output stream. A closed
+		 * stream cannot perform output operations and cannot be reopened.
+		 */
+		@Override
+		public void close() {
+			flush();
+			hasBeenClosed = true;
+		}
+
+		/**
+		 * Writes the specified byte to this output stream. The general contract
+		 * for <code>write</code> is that one byte is written to the output
+		 * stream. The byte to be written is the eight low-order bits of the
+		 * argument <code>b</code>. The 24 high-order bits of <code>b</code> are
+		 * ignored.
+		 * 
+		 * @param b
+		 *            the <code>byte</code> to write
+		 */
+		@Override
+		public void write(final int b) throws IOException {
+			if (hasBeenClosed) {
+				throw new IOException("The stream has been closed.");
+			}
+
+			// don't log nulls
+			if (b == 0) {
+				return;
+			}
+
+			// would this be writing past the buffer?
+			if (count == bufLength) {
+				// grow the buffer
+				final int newBufLength = bufLength + DEFAULT_BUFFER_LENGTH;
+				final byte[] newBuf = new byte[newBufLength];
+
+				System.arraycopy(buf, 0, newBuf, 0, bufLength);
+
+				buf = newBuf;
+				bufLength = newBufLength;
+			}
+
+			buf[count] = (byte) b;
+			count++;
+		}
+
+		/**
+		 * Flushes this output stream and forces any buffered output bytes to be
+		 * written out. The general contract of <code>flush</code> is that
+		 * calling it is an indication that, if any bytes previously written
+		 * have been buffered by the implementation of the output stream, such
+		 * bytes should immediately be written to their intended destination.
+		 */
+		@Override
+		public void flush() {
+
+			if (count == 0) {
+				return;
+			}
+
+			// don't print out blank lines; flushing from PrintStream puts out
+			// these
+			if (count == LINE_SEPERATOR.length()) {
+				if (((char) buf[0]) == LINE_SEPERATOR.charAt(0) && ((count == 1) || // <-
+						// Unix
+						// &
+						// Mac,
+						// ->
+						// Windows
+						((count == 2) && ((char) buf[1]) == LINE_SEPERATOR.charAt(1)))) {
+					reset();
+					return;
+				}
+			}
+
+			final byte[] theBytes = new byte[count];
+
+			System.arraycopy(buf, 0, theBytes, 0, count);
+
+			if (isError) {
+				log.error(new String(theBytes));
+			} else {
+				log.info(new String(theBytes));
+			}
+
+			reset();
+		}
+
+		private void reset() {
+			// not resetting the buffer -- assuming that if it grew that it
+			// will likely grow similarly again
+			count = 0;
+		}
+	}
+}
\ No newline at end of file
diff --git a/mail-archive/server/src/main/resources/initial-content/content/mailarchiveserver.json b/mail-archive/server/src/main/resources/initial-content/content/mailarchiveserver.json
new file mode 100644
index 0000000..a860274
--- /dev/null
+++ b/mail-archive/server/src/main/resources/initial-content/content/mailarchiveserver.json
@@ -0,0 +1,16 @@
+{
+    "sling:resourceType":"mailarchiveserver/root",
+    "jcr:primaryType": "nt:unstructured",
+
+    "archive" : {
+        "sling:resourceType": "mailarchiveserver/archive"
+    },
+
+    "import" : {
+        "sling:resourceType": "mailarchiveserver/import"
+    },
+
+    "search" : {
+        "sling:resourceType": "mailarchiveserver/search"
+    }
+}
\ No newline at end of file
diff --git a/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResource.java b/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResource.java
new file mode 100644
index 0000000..fd6e2da
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResource.java
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+// TODO this should come from a commons module, for now
+// it's duplicated from the discovery module
+public class MockedResource extends SyntheticResource {
+
+	private final MockedResourceResolver mockedResourceResolver;
+	private Session session;
+
+	public MockedResource(MockedResourceResolver resourceResolver, String path,
+			String resourceType) {
+		super(resourceResolver, path, resourceType);
+		mockedResourceResolver = resourceResolver;
+
+		resourceResolver.register(this);
+	}
+
+	private Session getSession() {
+		synchronized (this) {
+			if (session == null) {
+				try {
+					session = mockedResourceResolver.getSession();
+				} catch (RepositoryException e) {
+					throw new RuntimeException("RepositoryException: " + e, e);
+				}
+			}
+			return session;
+		}
+	}
+
+	@Override
+	protected void finalize() throws Throwable {
+		close();
+		super.finalize();
+	}
+
+	public void close() {
+		synchronized (this) {
+			if (session != null) {
+				if (session.isLive()) {
+					session.logout();
+				}
+				session = null;
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+		if (type.equals(Node.class)) {
+			try {
+				return (AdapterType) getSession().getNode(getPath());
+			} catch (Exception e) {
+				throw new RuntimeException("Exception occurred: " + e, e);
+			}
+		} else if (type.equals(ValueMap.class)) {
+			try {
+				Session session = getSession();
+				Node node = session.getNode(getPath());
+				HashMap<String, Object> map = new HashMap<String, Object>();
+
+				PropertyIterator properties = node.getProperties();
+				while (properties.hasNext()) {
+					Property p = properties.nextProperty();
+					if (p.getType() == PropertyType.BOOLEAN) {
+						map.put(p.getName(), p.getBoolean());
+					} else if (p.getType() == PropertyType.STRING) {
+						map.put(p.getName(), p.getString());
+					} else if (p.getType() == PropertyType.DATE) {
+						map.put(p.getName(), p.getDate().getTime());
+					} else if (p.getType() == PropertyType.NAME) {
+						map.put(p.getName(), p.getName());
+					} else {
+						throw new RuntimeException(
+								"Unsupported property type: " + p.getType());
+					}
+				}
+				ValueMap valueMap = new ValueMapDecorator(map);
+				return (AdapterType) valueMap;
+			} catch (Exception e) {
+				e.printStackTrace();
+				return null;
+			}
+		} else if (type.equals(ModifiableValueMap.class)) {
+			return (AdapterType) new ModifiableValueMap() {
+
+				public Collection<Object> values() {
+					throw new UnsupportedOperationException();
+				}
+
+				public int size() {
+					throw new UnsupportedOperationException();
+				}
+
+				public Object remove(Object arg0) {
+					Session session = getSession();
+					try{
+						final Node node = session.getNode(getPath());
+						final Property p = node.getProperty(String.valueOf(arg0));
+						if (p!=null) {
+							p.remove();
+						}
+						// this is not according to the spec - but OK for tests since
+						// the return value is never used
+								return null;
+					} catch(PathNotFoundException pnfe) {
+						// perfectly fine
+						return null;
+					} catch(RepositoryException e) {
+						throw new RuntimeException(e);
+					}
+				}
+
+				public void putAll(Map<? extends String, ? extends Object> arg0) {
+					throw new UnsupportedOperationException();
+				}
+
+				public Object put(String arg0, Object arg1) {
+					Session session = getSession();
+					try{
+						final Node node = session.getNode(getPath());
+						Object result = null;
+						if (node.hasProperty(arg0)) {
+							final Property previous = node.getProperty(arg0);
+							if (previous==null) {
+								// null
+							} else if (previous.getType() == PropertyType.STRING) {
+								result = previous.getString();
+							} else if (previous.getType() == PropertyType.DATE) {
+								result = previous.getDate();
+							} else if (previous.getType() == PropertyType.BOOLEAN) {
+								result = previous.getBoolean();
+							} else {
+								throw new UnsupportedOperationException();
+							}
+						}
+						if (arg1 instanceof String) {
+							node.setProperty(arg0, (String)arg1);
+						} else if (arg1 instanceof Long) {
+							node.setProperty(arg0, (Long)arg1);
+						} else if (arg1 instanceof Calendar) {
+							node.setProperty(arg0, (Calendar)arg1);
+						} else if (arg1 instanceof Boolean) {
+							node.setProperty(arg0, (Boolean)arg1);
+						} else {
+							throw new UnsupportedOperationException();
+						}
+						return result;
+					} catch(RepositoryException e) {
+						throw new RuntimeException(e);
+					}
+				}
+
+				public Set<String> keySet() {
+					Session session = getSession();
+					try {
+						final Node node = session.getNode(getPath());
+						final PropertyIterator pi = node.getProperties();
+						final Set<String> result = new HashSet<String>();
+						while(pi.hasNext()) {
+							final Property p = pi.nextProperty();
+							result.add(p.getName());
+						}
+						return result;
+					} catch (RepositoryException e) {
+						throw new RuntimeException(e);
+					}
+				}
+
+				public boolean isEmpty() {
+					throw new UnsupportedOperationException();
+				}
+
+				public Object get(Object arg0) {
+					try {
+						Node node = session.getNode(getPath());
+						return node.getProperty(String.valueOf(arg0));
+					} catch (PathNotFoundException e) {
+						return null;
+					} catch (RepositoryException e) {
+						e.printStackTrace();
+						throw new RuntimeException();
+					}
+					// throw new UnsupportedOperationException();
+				}
+
+				public Set<Entry<String, Object>> entrySet() {
+					throw new UnsupportedOperationException();
+				}
+
+				public boolean containsValue(Object arg0) {
+					throw new UnsupportedOperationException();
+				}
+
+				public boolean containsKey(Object arg0) {
+					Session session = getSession();
+					try{
+						final Node node = session.getNode(getPath());
+						return node.hasProperty(String.valueOf(arg0));
+					} catch(RepositoryException re) {
+						throw new RuntimeException(re);
+					}
+				}
+
+				public void clear() {
+					throw new UnsupportedOperationException();
+				}
+
+				public <T> T get(String name, T defaultValue) {
+					throw new UnsupportedOperationException();
+				}
+
+				public <T> T get(String name, Class<T> type) {
+					Session session = getSession();
+					try{
+						final Node node = session.getNode(getPath());
+						if (node==null) {
+							return null;
+						}
+						Property p = node.getProperty(name);
+						if (p==null) {
+							return null;
+						}
+						if (type.equals(Calendar.class)) {
+							return (T) p.getDate();
+						} else if (type.equals(String.class)) {
+							return (T) p.getString();
+						} else {
+							throw new UnsupportedOperationException();
+						}
+					} catch(RepositoryException e) {
+						throw new RuntimeException(e);
+					}
+				}
+			};
+		} else {
+			return super.adaptTo(type);
+		}
+	}
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResourceResolver.java b/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResourceResolver.java
new file mode 100644
index 0000000..2f4b234
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/discovery/impl/setup/MockedResourceResolver.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.discovery.impl.setup;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.testing.jcr.RepositoryProvider;
+
+//TODO this should come from a commons module, for now
+//it's duplicated from the discovery module
+public class MockedResourceResolver implements ResourceResolver {
+
+	private final Repository repository;
+	
+	private Session session;
+	
+    private List<MockedResource> resources = new LinkedList<MockedResource>();
+
+    public MockedResourceResolver() throws RepositoryException {
+    	this(null);
+    }
+
+    public MockedResourceResolver(Repository repositoryOrNull) throws RepositoryException {
+    	if (repositoryOrNull==null) {
+    		this.repository = RepositoryProvider.instance().getRepository();
+    	} else {
+    		this.repository = repositoryOrNull;
+    	}
+    }
+    
+    public Session getSession() throws RepositoryException {
+        synchronized (this) {
+            if (session != null) {
+                return session;
+            }
+            session = createSession();
+            return session;
+        }
+    }
+
+    private Repository getRepository() {
+    	return repository;
+    }
+    
+    private Session createSession() throws RepositoryException {
+        final Credentials credentials = new SimpleCredentials("admin",
+                "admin".toCharArray());
+        return repository.login(credentials, "default");
+    }
+	
+	
+    @SuppressWarnings("unchecked")
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type.equals(Session.class)) {
+            try {
+                return (AdapterType) getSession();
+            } catch (RepositoryException e) {
+                throw new RuntimeException("RepositoryException: " + e, e);
+            }
+        } else if (type.equals(Repository.class)) {
+        	return (AdapterType) getRepository();
+        }
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource resolve(HttpServletRequest request, String absPath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource resolve(String absPath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    @Deprecated
+    public Resource resolve(HttpServletRequest request) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String map(String resourcePath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String map(HttpServletRequest request, String resourcePath) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Resource getResource(String path) {
+        Session session;
+        try {
+            session = getSession();
+            session.getNode(path);
+        } catch (PathNotFoundException e) {
+            return null;
+        } catch (RepositoryException e) {
+            throw new RuntimeException("RepositoryException: " + e, e);
+        }
+        return new MockedResource(this, path, "nt:unstructured");
+    }
+
+    public Resource getResource(Resource base, String path) {
+        if (base.getPath().equals("/")) {
+            return getResource("/" + path);
+        } else {
+            return getResource(base.getPath() + "/" + path);
+        }
+    }
+
+    public String[] getSearchPath() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Resource> listChildren(Resource parent) {
+        try {
+            Node node = parent.adaptTo(Node.class);
+            final NodeIterator nodes = node.getNodes();
+            return new Iterator<Resource>() {
+
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+
+                public Resource next() {
+                    Node next = nodes.nextNode();
+                    try {
+                        return new MockedResource(MockedResourceResolver.this,
+                                next.getPath(), "nt:unstructured");
+                    } catch (RepositoryException e) {
+                        throw new RuntimeException("RepositoryException: " + e,
+                                e);
+                    }
+                }
+
+                public boolean hasNext() {
+                    return nodes.hasNext();
+                }
+            };
+        } catch (RepositoryException e) {
+            throw new RuntimeException("RepositoryException: " + e, e);
+        }
+    }
+
+    public Iterable<Resource> getChildren(Resource parent) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Resource> findResources(String query, String language) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<Map<String, Object>> queryResources(String query,
+            String language) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public ResourceResolver clone(Map<String, Object> authenticationInfo)
+            throws LoginException {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public boolean isLive() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public void close() {
+        Iterator<MockedResource> it = resources.iterator();
+        while (it.hasNext()) {
+            MockedResource r = it.next();
+            r.close();
+        }
+        if (session != null) {
+            if (session.isLive()) {
+                session.logout();
+            }
+            session = null;
+        }
+    }
+
+    public void register(MockedResource mockedResource) {
+        resources.add(mockedResource);
+    }
+
+    public String getUserID() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Iterator<String> getAttributeNames() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public Object getAttribute(String name) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public void delete(Resource resource) throws PersistenceException {
+        if (resources.contains(resource)) {
+            resources.remove(resource);
+            Node node = resource.adaptTo(Node.class);
+            try {
+                node.remove();
+            } catch (RepositoryException e) {
+                throw new PersistenceException("RepositoryException: "+e, e);
+            }
+        } else {
+            throw new UnsupportedOperationException("Not implemented");
+        }
+    }
+
+    public Resource create(Resource parent, String name,
+            Map<String, Object> properties) throws PersistenceException {
+        final Node parentNode = parent.adaptTo(Node.class);
+        try {
+            final Node child;
+            if (properties!=null && properties.containsKey("jcr:primaryType")) {
+                child = parentNode.addNode(name, (String) properties.get("jcr:primaryType"));
+            } else {
+                child = parentNode.addNode(name);
+            }
+            if (properties!=null) {
+                final Iterator<Entry<String, Object>> it = properties.entrySet().iterator();
+                while(it.hasNext()) {
+                    final Entry<String, Object> entry = it.next();
+                    if (entry.getKey().equals("jcr:primaryType")) {
+                        continue;
+                    }
+                    if (entry.getValue() instanceof String) {
+                        child.setProperty(entry.getKey(), (String)entry.getValue());
+                    } else if (entry.getValue() instanceof Boolean) {
+                        child.setProperty(entry.getKey(), (Boolean)entry.getValue());
+                    } else if (entry.getValue() instanceof InputStream) {
+                        child.setProperty(entry.getKey(), new String(IOUtils.toByteArray((InputStream)entry.getValue())));
+                    } else {
+                        throw new UnsupportedOperationException("Not implemented");
+                    }
+                }
+            }
+            return getResource(parent, name);
+        } catch (RepositoryException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void revert() {
+        try {
+            this.session.refresh(false);
+        } catch (final RepositoryException re) {
+            throw new RuntimeException("Unable to commit changes.", re);
+        }
+    }
+
+    public void commit() throws PersistenceException {
+        try {
+            this.session.save();
+        } catch (final RepositoryException re) {
+            throw new PersistenceException("Unable to commit changes.", re);
+        }
+    }
+
+    public boolean hasChanges() {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    public String getParentResourceType(Resource resource) {
+        //  Auto-generated method stub
+        return null;
+    }
+
+    public String getParentResourceType(String resourceType) {
+        //  Auto-generated method stub
+        return null;
+    }
+
+    public boolean isResourceType(Resource resource, String resourceType) {
+        //  Auto-generated method stub
+        return false;
+    }
+
+    public void refresh() {
+        //  Auto-generated method stub
+
+    }
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplAttachmentsTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplAttachmentsTest.java
new file mode 100644
index 0000000..ed229c4
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplAttachmentsTest.java
@@ -0,0 +1,205 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.getResourcePath;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.CONTENT;
+import static org.apache.sling.mailarchiveserver.util.MessageFieldName.LIST_ID;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Random;
+
+import org.apache.james.mime4j.dom.BinaryBody;
+import org.apache.james.mime4j.dom.Body;
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.dom.TextBody;
+import org.apache.james.mime4j.message.BodyPart;
+import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.james.mime4j.message.MultipartImpl;
+import org.apache.james.mime4j.storage.StorageBodyFactory;
+import org.apache.james.mime4j.stream.Field;
+import org.apache.james.mime4j.stream.RawField;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.discovery.impl.setup.MockedResourceResolver;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MessageStoreImplAttachmentsTest {
+    private ResourceResolver resolver;
+    private Resource testRoot;
+    private MessageStoreImpl store;
+
+    /**
+     * Some code is taken from http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/serversidetests/WriteableResourcesTest.java
+     */
+    @Before
+    public void setup() throws Exception {
+        resolver = new MockedResourceResolver();
+        assertNotNull("Expecting non-null ResourceResolver", resolver);
+        final Resource root = resolver.getResource("/");
+        assertNotNull("Expecting non-null root Resource", root);
+        final String path = getClass().getSimpleName() + "_" + System.currentTimeMillis();
+        testRoot = resolver.create(root, path, null);
+        resolver.commit();
+
+        store = new MessageStoreImpl() {
+            protected ResourceResolver getResourceResolver() {
+                return resolver;
+            }
+        };
+        store.threadKeyGen = new ThreadKeyGeneratorImpl();
+        store.attachmentFilter = new AttachmentFilterImpl();
+        store.archivePath = testRoot.getPath() + "/";
+        store.resourceTypeKey = MessageStoreImplRepositoryTest.TEST_RT_KEY;
+    }
+
+    @After
+    public void cleanup() throws Exception {
+        resolver.close();
+        resolver = null;
+        testRoot = null;
+        store = null;
+    }
+
+    @Test
+    public void simpleMultipartMessageTest() throws IOException {
+        Multipart multipart = new MultipartImpl("mixed");
+        BodyPart att0 = createTextBody("This is the first part of the template..", "plain", true);
+        multipart.addBodyPart(att0);
+        BodyPart att1 = createRandomBinaryAttachment(200);
+        multipart.addBodyPart(att1);
+        BodyPart att2 = createRandomBinaryAttachment(300);
+        multipart.addBodyPart(att2);
+        BodyPart att3 = createTextBody("Some sample text here...?!", "html", true);
+        multipart.addBodyPart(att3);
+        BodyPart att4 = createRandomBinaryAttachment(100);
+        multipart.addBodyPart(att4);
+        BodyPart att5 = createTextBody("Some other text here...?!", "plain", true);
+        multipart.addBodyPart(att5);
+        
+        MessageImpl message = new MessageImpl();
+        message.setMultipart(multipart);
+        message.setSubject("Template message");
+        message.setDate(new Date());
+        message.getHeader().setField(new RawField(LIST_ID, "<list.example.com>"));
+
+        assertSaveMessageWithAttachments(message, 6);
+    }
+    
+    @Test
+    public void recursiveMultipartMessageTest() throws IOException {
+        Multipart multipart = new MultipartImpl("mixed");
+        BodyPart att1 = createRandomBinaryAttachment(100);
+        multipart.addBodyPart(att1);
+        BodyPart att2 = createRandomBinaryAttachment(133);
+        multipart.addBodyPart(att2);
+        
+        Multipart nestedMultipart = new MultipartImpl("mixed");
+        BodyPart nBody = createTextBody("Some sample text here...?!", "plain", false);
+        nestedMultipart.addBodyPart(nBody);
+        BodyPart nAtt1 = createRandomBinaryAttachment(300);
+        nestedMultipart.addBodyPart(nAtt1);
+        BodyPart NAtt2 = createRandomBinaryAttachment(100);
+        nestedMultipart.addBodyPart(NAtt2);
+        BodyPart nAtt3 = createTextBody("Some other text here...<br>?!", "html", true);
+        nestedMultipart.addBodyPart(nAtt3);
+        
+        BodyPart nestedMessage = new BodyPart();
+        nestedMessage.setMultipart(nestedMultipart);
+        multipart.addBodyPart(nestedMessage);
+
+        MessageImpl message = new MessageImpl();
+        message.setMultipart(multipart);
+        message.setSubject("Template message");
+        message.setDate(new Date());
+        message.getHeader().setField(new RawField(LIST_ID, "<list.example.com>"));
+
+        assertSaveMessageWithAttachments(message, 5);
+    }
+
+    private void assertSaveMessageWithAttachments(Message msg, int num) throws IOException {
+        store.save(msg);
+
+        List<BodyPart> attList = new LinkedList<BodyPart>();
+        MessageStoreImpl.recursiveMultipartProcessing((Multipart) msg.getBody(), new StringBuilder(), new StringBuilder(), false, attList); 
+        @SuppressWarnings("unchecked")
+        Queue<BodyPart> attachmentsMsg = (Queue<BodyPart>) attList;
+        assertTrue("No attachments found", attachmentsMsg.size() > 0);
+        assertEquals("", num, attachmentsMsg.size());
+        
+        final Resource r = resolver.getResource(getResourcePath(msg, store));
+        assertNotNull("Expecting non-null Resource", r);
+        for (Resource aRes : r.getChildren()) {
+            final ModifiableValueMap aMap = aRes.adaptTo(ModifiableValueMap.class);
+            BodyPart aMsg = attachmentsMsg.poll();
+            assertNotNull("JCR contains more attachments", aMsg);
+
+            for (Field f : aMsg.getHeader().getFields()) {
+                String name = f.getName();
+                assertEquals("Field "+name+" is different", (aMap.get(name, String.class)), f.getBody());
+            }
+            
+            if (aMsg.getBody() instanceof TextBody) {
+                assertEquals("Content is not the same", MessageStoreImpl.getTextPart(aMsg), aMap.get(CONTENT, String.class));
+            } else if (aMsg.getBody() instanceof BinaryBody) {
+                assertEquals("Content is not the same", getBinPart(aMsg), aMap.get(CONTENT, String.class));
+            } else {
+                fail("Unknown type of attachment body");
+            }
+        }
+        assertEquals("Message contains more attachments", attachmentsMsg.poll(), null);
+    }
+
+    private String getBinPart(Entity part) throws IOException {
+        BinaryBody bb = (BinaryBody) part.getBody();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        bb.writeTo(baos);
+        return new String(baos.toByteArray());
+    }
+
+    /*
+     * taken from http://svn.apache.org/repos/asf/james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
+     */
+    private static BodyPart createTextBody(String text, String subtype, boolean isAttachment) {
+        TextBody body = new StorageBodyFactory().textBody(text, MailArchiveServerConstants.DEFAULT_ENCODER.charset().name());
+
+        BodyPart bodyPart = new BodyPart();
+        if (isAttachment) {
+            bodyPart.setContentDisposition("attachment", "file"+Math.random());
+        }
+        bodyPart.setText(body, subtype);
+
+        return bodyPart;
+    }
+
+    /*
+     * taken from http://svn.apache.org/repos/asf/james/mime4j/trunk/examples/src/main/java/org/apache/james/mime4j/samples/transform/TransformMessage.java
+     */
+    private static BodyPart createRandomBinaryAttachment(int numberOfBytes) throws IOException {
+        byte[] data = new byte[numberOfBytes];
+        new Random().nextBytes(data);
+
+        Body body = new StorageBodyFactory().binaryBody(new ByteArrayInputStream(data));
+
+        BodyPart bodyPart = new BodyPart();
+        bodyPart.setContentDisposition("attachment", "file"+Math.random());
+        bodyPart.setBody(body, "application/octet-stream");
+
+        return bodyPart;
+    }
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTest.java
new file mode 100644
index 0000000..befc718
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTest.java
@@ -0,0 +1,129 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.assertValueMap;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.getResourcePath;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.readTextFile;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.specialPathFromFilePath;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.MessageBuilder;
+import org.apache.james.mime4j.message.DefaultMessageBuilder;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.discovery.impl.setup.MockedResourceResolver;
+import org.apache.sling.mailarchiveserver.api.MboxParser;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MessageStoreImplRepositoryTest {
+	private ResourceResolver resolver;
+	private Resource testRoot;
+	private MessageStoreImpl store;
+
+	static final String TEST_RT_KEY = "sling_resourceType";
+	private static final String TEST_FOLDER = "test_files/";
+	private static final String BODY_SUFFIX = "_body";
+	private static final String HEADERS_SUFFIX = "_headers";
+
+	private static final String SINGLEPART_FILE = "singlepart.txt";
+	private static final String MULTIPART_FILE = "multipart.txt";
+	private static final String WRONGBODY_FILE = "wrongbody.txt";
+	private static final String MBOX_FILE = "three_messages.mbox";
+
+	/**
+	 * Some code is taken from http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/serversidetests/WriteableResourcesTest.java
+	 */
+	@Before
+	public void setup() throws Exception {
+		resolver = new MockedResourceResolver();
+		assertNotNull("Expecting non-null ResourceResolver", resolver);
+		final Resource root = resolver.getResource("/");
+		assertNotNull("Expecting non-null root Resource", root);
+		final String path = getClass().getSimpleName() + "_" + System.currentTimeMillis();
+		testRoot = resolver.create(root, path, null);
+		resolver.commit();
+
+		store = new MessageStoreImpl() {
+		    protected ResourceResolver getResourceResolver() {
+		        return resolver;
+		    }
+		};
+		store.threadKeyGen = new ThreadKeyGeneratorImpl();
+		store.archivePath = testRoot.getPath() + "/";
+		store.resourceTypeKey = TEST_RT_KEY;
+	}
+
+	@After
+	public void cleanup() throws Exception {
+		resolver.close();
+		resolver = null;
+		testRoot = null;
+		store = null;
+	}
+
+
+	@Test
+	public void testSaveMessage() throws FileNotFoundException, MimeException, IOException  {
+		assertSaveMessage(SINGLEPART_FILE);
+		assertSaveMessage(MULTIPART_FILE);
+		assertSaveMessage(WRONGBODY_FILE);
+	}
+
+	@Test
+	public void testStructure() throws IOException {
+		MboxParser parser = new Mime4jMboxParserImpl();
+		final File file = new File(TEST_FOLDER + MBOX_FILE);
+		store.saveAll(parser.parse(new FileInputStream(file)));
+		assertStructure();
+	}
+
+	private void assertSaveMessage(String messageFile) throws MimeException, IOException, FileNotFoundException {
+		MessageBuilder builder = new DefaultMessageBuilder();
+		Message msg = builder.parseMessage(new FileInputStream(TEST_FOLDER + messageFile));
+
+		store.save(msg);
+
+		final Resource r = resolver.getResource(getResourcePath(msg, store));
+		assertNotNull("Expecting non-null Resource", r);
+		final ModifiableValueMap m = r.adaptTo(ModifiableValueMap.class);
+
+		File bodyFile = new File(TEST_FOLDER + specialPathFromFilePath(messageFile, BODY_SUFFIX));
+		if (bodyFile.exists()) {
+			String expectedBody = readTextFile(bodyFile);
+			assertValueMap(m, "Body", expectedBody);
+		}
+
+		File headersFile = new File(TEST_FOLDER + specialPathFromFilePath(messageFile, HEADERS_SUFFIX));
+		if (headersFile.exists()) {
+			MessageStoreImplRepositoryTestUtil.assertHeaders(headersFile, m);
+		}
+
+		assertTrue(headersFile.exists() || bodyFile.exists()); // test at least something 
+	}
+
+	private void assertStructure() {
+		List<String> types = new ArrayList<String>();
+		types.add(MailArchiveServerConstants.DOMAIN_RT);
+		types.add(MailArchiveServerConstants.LIST_RT);
+		types.add(null);
+		types.add(null);
+		types.add(MailArchiveServerConstants.THREAD_RT);
+		types.add(MailArchiveServerConstants.MESSAGE_RT);
+
+		MessageStoreImplRepositoryTestUtil.assertLayer(testRoot, types, 0);
+	}
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTestUtil.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTestUtil.java
new file mode 100644
index 0000000..5e71cb3
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplRepositoryTestUtil.java
@@ -0,0 +1,142 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.getDomainNodeName;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.getListNodeName;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.makeJcrFriendly;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import org.apache.james.mime4j.dom.Header;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.stream.Field;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+
+public class MessageStoreImplRepositoryTestUtil {
+
+    private static final String TEST_FILE_FIELD_SEPARATOR = " : ";
+
+    /**
+     * Code is taken from http://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/serversidetests/WriteableResourcesTest.java
+     */
+    static void assertValueMap(ValueMap m, String ... keyValue) {
+        assertNotNull("Expecting non-null ValueMap", m);
+        for(int i=0 ; i< keyValue.length; i+=2) {
+            final String key = keyValue[i];
+            final String value = keyValue[i+1];
+            assertEquals("Expecting " + key + "=" + value, value, m.get(key, String.class));
+        }
+    }
+
+    static String readTextFile(File bodyFile) throws FileNotFoundException {
+        Scanner sc = null;
+        try {
+            sc = new Scanner(bodyFile);
+            String expectedBody = ""; 
+            while (sc.hasNextLine()) {
+                expectedBody += sc.nextLine() + "\n";
+            }
+            expectedBody = expectedBody.substring(0, expectedBody.length()-1);
+            return expectedBody;
+        } finally {
+            if (sc != null) {
+                sc.close();
+            }
+        }
+    }
+
+    static String specialPathFromFilePath(String fpath, String suffix, String ext) {
+        int dotIdx = fpath.lastIndexOf(".");
+        String bodyPath = fpath.substring(0, dotIdx) + suffix + "." + ext; 
+        return bodyPath;
+    }
+
+    static String specialPathFromFilePath(String fpath, String suffix) {
+        int dotIdx = fpath.lastIndexOf(".");
+        return specialPathFromFilePath(fpath, suffix, fpath.substring(dotIdx + 1));
+    }
+
+    static String getResourcePath(Message msg, MessageStoreImpl store) {
+        final Header hdr = msg.getHeader();
+        final String listIdRaw = hdr.getField("List-Id").getBody();
+        final String listId = listIdRaw.substring(1, listIdRaw.length()-1); // remove < and >
+
+        String msgId;
+        final Field msgIdField = hdr.getField("Message-ID");
+        if (msgIdField != null) {
+            msgId = msgIdField.getBody();
+            msgId = msgId.substring(1, msgId.length()-1);
+        } else {
+            msgId = Integer.toHexString(hdr.getField("Date").hashCode());
+        }
+        msgId = makeJcrFriendly(msgId);
+
+        String subject = null;
+        final Field subjectField = hdr.getField("Subject");
+        if (subjectField != null) {
+            subject = subjectField.getBody();
+        }
+
+        String threadPath = store.threadKeyGen.getThreadKey(subject);
+        String path = store.archivePath + getDomainNodeName(listId) + "/" + getListNodeName(listId) +
+                "/" + threadPath + "/" + msgId;
+        return path;
+    }
+
+    static void assertHeaders(File headersFile, ModifiableValueMap m) throws FileNotFoundException {
+        Map<String, List<String>> expectedHeaders = new HashMap<String, List<String>>();
+        Scanner sc = new Scanner(headersFile);
+        while (sc.hasNextLine()) {
+            String line = sc.nextLine();
+            if (line.startsWith("//")) 
+                continue;
+            String[] colon = line.split(TEST_FILE_FIELD_SEPARATOR);
+            String header = colon[0];
+            String value = colon[1];
+            List<String> values;
+            if ((values = expectedHeaders.get(header)) == null) {
+                values = new ArrayList<String>();
+                expectedHeaders.put(header, values);
+            }
+            values.add(value);
+        }
+        sc.close();
+
+        assertEquals("Expecting same number of headers", m.keySet().size()-2, expectedHeaders.keySet().size()); 
+        // -1 for Body (should be no htmlBody)
+        // -1 for X-original-header
+
+        for (String expectedHeader : expectedHeaders.keySet()) {
+            assertTrue("Expecting header \""+expectedHeader+"\" to exist", m.containsKey(expectedHeader));
+            String values = m.get(expectedHeader, String.class);
+            for (String expectedValue : expectedHeaders.get(expectedHeader)) {
+                assertTrue("Expecting header \""+expectedHeader+"\" to contain the value", values.contains(expectedValue));
+            }
+        }
+    }
+
+    static void assertLayer(Resource root, List<String> types, int depth) {
+        for (Resource child : root.getChildren()) {
+            final ModifiableValueMap m = child.adaptTo(ModifiableValueMap.class);
+            if (m.keySet().contains(MessageStoreImplRepositoryTest.TEST_RT_KEY)) {
+                String type = m.get(MessageStoreImplRepositoryTest.TEST_RT_KEY, String.class);
+                assertEquals(String.format("Expecting %s to have %s type", child.getPath(), types.get(depth)), types.get(depth), type);
+            }
+            if (child.getChildren().iterator().hasNext()) {
+                assertLayer(child, types, depth+1);
+            }
+        }
+
+    }
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplStaticMethodsTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplStaticMethodsTest.java
new file mode 100644
index 0000000..9fde627
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/MessageStoreImplStaticMethodsTest.java
@@ -0,0 +1,49 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.getDomainNodeName;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.getListNodeName;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.makeJcrFriendly;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.removeRe;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.message.MessageImpl;
+import org.apache.sling.mailarchiveserver.util.MailArchiveServerConstants;
+import org.junit.Test;
+
+public class MessageStoreImplStaticMethodsTest {
+	
+	@Test
+	public void testMakeJcrFriendly() {
+		assertEquals("Remove each char", "", makeJcrFriendly("��!@#$%^&*()+={}[]<>,/?\\;:'\""));
+		assertEquals("Substitute each char with _ char, trimming", "a", makeJcrFriendly(".a_")); 
+		assertEquals("Substitute each char with _ char", "b_e", makeJcrFriendly("b_ .-e"));
+	}
+
+	@Test
+	public void testRemoveRe() {
+		assertEquals(removeRe("abc"), "abc");
+		assertEquals(removeRe("Re:re"), "re");
+		assertEquals(removeRe("RE: abc"), "abc");
+		assertEquals(removeRe("re: RE: "), "");
+		assertEquals(removeRe(" re:  abc  "), "abc");
+		assertEquals(removeRe(" re:fw:  aw:RE: FW: subj "), "subj");
+		assertEquals(removeRe(""), "");
+		assertEquals(removeRe("     "), "");
+		assertEquals(removeRe("Re:   "), "");
+	}
+	
+	@Test
+	public void testNodeNamesFromListId() {
+		assertEquals(getListNodeName("dev.sling.apache.org"), "dev.sling");
+		assertEquals(getDomainNodeName("dev.sling.apache.org"), "apache.org");
+		assertEquals(getListNodeName("proj.apache.org"), "proj");
+		assertEquals(getDomainNodeName("proj.apache.org"), "apache.org");
+		assertEquals(getListNodeName("a.b.c.apache.org"), "a.b.c");
+		assertEquals(getDomainNodeName("a.b.c.apache.org"), "apache.org");
+	}
+	
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplCountTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplCountTest.java
new file mode 100644
index 0000000..f12489b
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplCountTest.java
@@ -0,0 +1,61 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.james.mime4j.dom.Message;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class Mime4jMboxParserImplCountTest {
+
+	private static Mime4jMboxParserImpl parser = new Mime4jMboxParserImpl();
+	private String filePath;
+	private int expectedMessagesCount;
+	
+	static final String TEST_FOLDER = "test_files/";
+	
+	@Parameters(name="{0}")
+    public static Collection<Object[]> data() {
+        List<Object[]> params = new ArrayList<Object[]>();
+        params.add(new Object[] {TEST_FOLDER+"three_messages.mbox", 3} );
+        params.add(new Object[] {TEST_FOLDER+"mbox/jackrabbit-dev-201201.mbox", 323} );
+        params.add(new Object[] {TEST_FOLDER+"mbox/hadoop-common-dev-201202.mbox", 296} );
+        params.add(new Object[] {TEST_FOLDER+"mbox/sling-dev-201203.mbox", 227} );
+        params.add(new Object[] {TEST_FOLDER+"mbox/tomcat-dev-201204.mbox", 658} );
+        return params;
+    }
+    
+    public Mime4jMboxParserImplCountTest(String path, int count) {
+    	filePath = path;
+    	expectedMessagesCount = count;
+    }
+
+	@Test
+	public void testParse() throws IOException {
+		Iterator<Message> iter = parser.parse(new FileInputStream(new File(filePath)));
+		
+		int cnt = 0;
+		Set<Message> set = new HashSet<Message>();
+		while (iter.hasNext()) {
+			Message message = (Message) iter.next();
+			cnt++;
+			set.add(message);
+		}
+		assertEquals("Expecting correct number of messages parsed", expectedMessagesCount, cnt);
+		assertEquals("Expecting all messages unique", expectedMessagesCount, set.size());
+	}
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplStreamingTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplStreamingTest.java
new file mode 100644
index 0000000..31e21f7
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplStreamingTest.java
@@ -0,0 +1,78 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.sling.mailarchiveserver.impl.Mime4jMboxParserImpl.Mime4jParserIterator;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * In this class there is a test that parses big file. It will take a while to execute.
+ */
+public class Mime4jMboxParserImplStreamingTest {
+
+	private Mime4jMboxParserImpl parser = new Mime4jMboxParserImpl();
+	private final Logger log = LoggerFactory.getLogger(getClass());
+
+	private static final String TEST_FOLDER = Mime4jMboxParserImplCountTest.TEST_FOLDER;
+	private static final String TEST_FILE_NAME = TEST_FOLDER  + "mbox/tomcat-dev-201204.mbox";
+	private static final double TEST_FILE_RATIO = 1.2;
+
+	@Test
+	public void testParserIsStreaming() throws IOException {
+		File tempf = null;
+		FileInputStream fis = null;
+		FileOutputStream fos = null;
+		try {
+            final long maxMem = Runtime.getRuntime().maxMemory();
+		    log.info("Max memory={}, reading from {}, might take a while...", maxMem, TEST_FILE_NAME);
+		    log.info("TODO: this test fails with 'Size exceeds Integer.MAX_VALUE' if maxMem is over a certain limit");
+			final File fileToSample = new File(TEST_FILE_NAME);
+			final int count = (int) (maxMem * TEST_FILE_RATIO / fileToSample.length()) + 1;
+
+			fis = new FileInputStream(fileToSample);
+			final byte[] sample = new byte[(int) fileToSample.length()];
+			assertEquals("Expecting the correct number of bytes read", fis.read(sample), fileToSample.length()); 
+
+			tempf = File.createTempFile("MAS_", ".mbox");
+			fos = new FileOutputStream(tempf);
+			for (int i = 0; i < count; i++) {
+				fos.write(sample);
+			}
+            fos.flush();
+            fos.close();
+			fos = null;
+
+			parser.parse(new FileInputStream(tempf));
+
+		} catch(OutOfMemoryError e) {
+			fail("Got OutOfMemoryError, looks like the Parser is not streaming");
+		} finally {
+			if (tempf != null) {
+				tempf.delete();
+			}
+			if (fis != null) {
+				fis.close();
+			}
+			if (fos != null) {
+				fos.close();
+			}
+		}
+	}
+
+	@Test
+	public void testTempFileIsDeleted() throws IOException {
+		File testFile = new File(TEST_FOLDER + "mbox/tomcat-dev-201204.mbox");
+		Mime4jParserIterator iter = (Mime4jParserIterator) parser.parse(new FileInputStream(testFile));
+		assertFalse("Expecting temp file to be deleted", new File(iter.tempFileAbsPath).exists());
+	}	
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplTest.java
new file mode 100644
index 0000000..edb8fe7
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/Mime4jMboxParserImplTest.java
@@ -0,0 +1,73 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.readTextFile;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImpl.*;
+import static org.apache.sling.mailarchiveserver.impl.MessageStoreImplRepositoryTestUtil.specialPathFromFilePath;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.dom.Entity;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.message.BodyPart;
+import org.junit.Test;
+
+/**
+ * In this class there is a test that parses big file. It will take a while to execute.
+ */
+public class Mime4jMboxParserImplTest {
+
+    private Mime4jMboxParserImpl parser = new Mime4jMboxParserImpl();
+
+    private static final String TEST_FOLDER = Mime4jMboxParserImplCountTest.TEST_FOLDER;
+    private static final String WRONGBODY_MBOX = "wrongbody.mbox";
+
+    @Test
+    public void testMboxParsing() throws IOException {
+        final String testPath = TEST_FOLDER + WRONGBODY_MBOX;
+        Iterator<Message> iter = parser.parse(new FileInputStream(new File(testPath)));
+
+        boolean fail = true;
+        int i = 1;
+        while (iter.hasNext()) {
+            final Message message = iter.next();
+            File bodyFile = new File(specialPathFromFilePath(testPath, "_bodyOf" + i, "txt"));
+            if (bodyFile.exists()) {
+                final String actual = getPlainBody(message);
+                final String expected = readTextFile(bodyFile);
+                assertEquals("Body #"+i, expected, actual);
+                fail = false;
+            }
+            i++;
+        }
+
+        if (fail) {
+            fail("No file with expected body.");
+        }
+    }
+
+    /**
+     *        code taken from http://www.mozgoweb.com/posts/how-to-parse-mime-message-using-mime4j-library/
+     */
+    private static String getPlainBody(Message msg) throws IOException {
+        if (!msg.isMultipart()) {
+            return getTextPart(msg);
+        } else {
+            Multipart multipart = (Multipart) msg.getBody();
+            for (Entity enitiy : multipart.getBodyParts()) {
+                BodyPart part = (BodyPart) enitiy;
+                if (part.isMimeType("text/plain")) {
+                    return getTextPart(part);
+                }
+            }
+        }
+
+        return null;
+    }
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/SearchServiceTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/SearchServiceTest.java
new file mode 100644
index 0000000..cbc649c
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/SearchServiceTest.java
@@ -0,0 +1,111 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SearchServiceTest {
+
+	private static SearchQueryParserImpl parser = new SearchQueryParserImpl();
+	private static QueryBuilderImpl builder = new QueryBuilderImpl();
+
+	private String searchPhrase;
+	private String expectedQuery;
+
+	@Parameters(name="{0}")
+	public static Collection<Object[]> data() {
+		List<Object[]> params = new ArrayList<Object[]>();
+		params.add(new Object[] {"blank search field", "", QueryBuilderImpl.BASE } );
+
+		params.add(new Object[] {"one word", "word", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(Body) LIKE '%word%' "
+				+ "OR LOWER(Subject) LIKE '%word%' "
+				+ "OR LOWER('List-Id') LIKE '%word%' "
+				+ "OR LOWER(From) LIKE '%word%')" 
+		} );	
+		
+		// TODO logically this is true, practically order by score because
+		params.add(new Object[] {"two words", "hello word", QueryBuilderImpl.BASE + " AND " 
+				+ "(LOWER(Body) LIKE '%hello%' "
+				+ "OR LOWER(Body) LIKE '%word%' "
+				+ "OR LOWER(Subject) LIKE '%hello%' "
+				+ "OR LOWER(Subject) LIKE '%word%' "
+				+ "OR LOWER('List-Id') LIKE '%hello%' "
+				+ "OR LOWER('List-Id') LIKE '%word%' "
+				+ "OR LOWER(From) LIKE '%hello%' " 
+				+ "OR LOWER(From) LIKE '%word%')" 
+		} );	
+
+		params.add(new Object[] {"field search", "hello from:world", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(From) LIKE '%world%') "
+				+ "AND (LOWER(Body) LIKE '%hello%' "
+				+ "OR LOWER(Subject) LIKE '%hello%' "
+				+ "OR LOWER('List-Id') LIKE '%hello%' "
+				+ "OR LOWER(From) LIKE '%hello%')" 
+		} );
+
+		params.add(new Object[] {"caps", "SuBjecT:HeRE THeRe", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(Subject) LIKE '%here%') " 
+				+ "AND (LOWER(Body) LIKE '%there%' "
+				+ "OR LOWER(Subject) LIKE '%there%' "
+				+ "OR LOWER('List-Id') LIKE '%there%' "
+				+ "OR LOWER(From) LIKE '%there%')" 
+		} );
+
+		params.add(new Object[] {"non-existent field", "FROM:me list:public about:stuff", QueryBuilderImpl.BASE + " AND " 
+				+ "(LOWER('List-Id') LIKE '%public%') "
+				+ "AND (LOWER(From) LIKE '%me%')" 
+		} );
+
+		params.add(new Object[] {"just non-existent field", "frome:e", QueryBuilderImpl.DUMMY } );
+
+		params.add(new Object[] {"two spaces (parsing)", "a  b", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(Body) LIKE '%a%' "
+				+ "OR LOWER(Body) LIKE '%b%' "
+				+ "OR LOWER(Subject) LIKE '%a%' "
+				+ "OR LOWER(Subject) LIKE '%b%' "
+				+ "OR LOWER('List-Id') LIKE '%a%' "
+				+ "OR LOWER('List-Id') LIKE '%b%' "
+				+ "OR LOWER(From) LIKE '%a%' " 
+				+ "OR LOWER(From) LIKE '%b%')" 
+		} );	
+
+		params.add(new Object[] {"quoted text", "\"hel  wrd\"", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(Body) LIKE '%hel  wrd%' "
+				+ "OR LOWER(Subject) LIKE '%hel  wrd%' "
+				+ "OR LOWER('List-Id') LIKE '%hel  wrd%' "
+				+ "OR LOWER(From) LIKE '%hel  wrd%')" 
+		} );	
+		
+		params.add(new Object[] {"quoted field", "from:\"w r d\" hello ", QueryBuilderImpl.BASE + " AND "
+				+ "(LOWER(From) LIKE '%w r d%') "
+				+ "AND (LOWER(Body) LIKE '%hello%' "
+				+ "OR LOWER(Subject) LIKE '%hello%' "
+				+ "OR LOWER('List-Id') LIKE '%hello%' "
+				+ "OR LOWER(From) LIKE '%hello%')" 
+		} );
+
+		//        params.add(new Object[] {"name", "", QueryBuilderImpl.BASE} );
+		return params;
+	}
+
+	public SearchServiceTest(String description, String one, String two) {
+		searchPhrase = one;
+		expectedQuery = two;
+	}
+
+	@Test
+	public void testQueryPipeline() {
+		String query = builder.buildQuery(parser.parse(searchPhrase), QueryBuilderImpl.SQL2);
+		assertTrue(String.format("\nExpected: %s\n   Output: %s", expectedQuery, query), expectedQuery.equals(query));
+	}
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplSubjectEqualityTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplSubjectEqualityTest.java
new file mode 100644
index 0000000..fa00f9e
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplSubjectEqualityTest.java
@@ -0,0 +1,41 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ThreadKeyGeneratorImplSubjectEqualityTest {
+    private ThreadKeyGeneratorImpl generator = new ThreadKeyGeneratorImpl();
+    private final String orig;
+    private final String re;
+
+    public ThreadKeyGeneratorImplSubjectEqualityTest(String input, String expected) {
+        this.orig = input;
+        this.re = expected;
+    }
+
+    @Parameters(name="{0}")
+    public static List<Object[]> data() {
+        final List<Object[]> result = new ArrayList<Object[]>();
+
+        result.add(new Object[] {"Chef cookbooks for Installing CQ & packages", "Re: Chef cookbooks for Installing CQ & packages"} ); 
+        result.add(new Object[] {"Dropbox to throw random files in and be accessible through http/ ftp?", "Re: Dropbox to throw random files in and be accessible through http/ ftp?"} ); 
+        result.add(new Object[] {"Dropbox to throw random files in and be accessible through http/ ftp?", "RE: Dropbox to throw random files in and be accessible through http/ ftp?"} ); 
+        result.add(new Object[] {"CRX integration guidelines for ES3", "答复: CRX integration guidelines for ES3"} ); 
+        //        result.add(new Object[] {, } ); 
+
+        return result;
+    }
+
+    @Test
+    public void testGetThreadKey() {
+        assertEquals(generator.getThreadKey(orig), generator.getThreadKey(re));
+    }
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplTest.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplTest.java
new file mode 100644
index 0000000..80cf645
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/impl/ThreadKeyGeneratorImplTest.java
@@ -0,0 +1,54 @@
+package org.apache.sling.mailarchiveserver.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ThreadKeyGeneratorImplTest {
+	private static final String UNADDRESSABLE_SUBJECT_KEY = "a/at/unaddressable_subject";
+    private ThreadKeyGeneratorImpl generator = new ThreadKeyGeneratorImpl();
+	private final String input;
+	private final String expected;
+
+	@Parameters(name="{0}")
+	public static List<Object[]> data() {
+		final List<Object[]> result = new ArrayList<Object[]>();
+		
+		result.add(new Object[] {"'''''''9>*'''''''''''''''''''''''''''40>*", "9/90/940"} ); 
+		result.add(new Object[] {"'abc'''9>*'''''''''''''''''''''''''''40>*", "9/90/abc940"} ); 
+		result.add(new Object[] {"abcdefg9>*'''''''''''''''''''''''''''40>*", "9/90/abcdefg940"} ); 
+		result.add(new Object[] {"abcdefg9>h'''''''''''''''''''''''''''40>*", "h/h0/abcdefg9h40"} ); 
+		result.add(new Object[] {"abcdefg9>hi''''''''''''''''''''''''''40>*", "h/h0/abcdefg9hi40"} ); 
+		result.add(new Object[] {"abcdefg9>hijklmnopqrstuvwxyzabcdefghi40>*", "h/h0/abcdefg9hijklmnopqrstuvwxyzabcdefghi40"} ); 
+		result.add(new Object[] {"abcdefg9>hijklmnopqrstuvwxyzabcdefghi40>j", "h/hj/abcdefg9hijklmnopqrstuvwxyzabcdefghi40j"} ); 
+		result.add(new Object[] {"abcdefg9>hijklmnopqrstuvwxyzabcdefghi40>jk","h/hj/abcdefg9hijklmnopqrstuvwxyzabcdefghi40jk"} ); 
+		result.add(new Object[] {"'''''''9>'''''''abc''''''''''''''''''40>*", "9/90/9abc40"} ); 
+		result.add(new Object[] {"'''''''9>*'''''''''''''''''''''''''''40>*abc'", "9/90/940abc"} ); 
+		result.add(new Object[] {"", UNADDRESSABLE_SUBJECT_KEY} ); 
+		result.add(new Object[] {"Re: ", UNADDRESSABLE_SUBJECT_KEY} ); 
+		result.add(new Object[] {null, UNADDRESSABLE_SUBJECT_KEY} ); 
+		result.add(new Object[] {"*", UNADDRESSABLE_SUBJECT_KEY} ); 
+		result.add(new Object[] {"1.5.0", "0/00/1_5_0"} ); 
+		result.add(new Object[] {"把握正确方向,做个效率为先的领导助手", UNADDRESSABLE_SUBJECT_KEY} ); 
+		result.add(new Object[] {"remove   consecutive - . - whitespaces", "c/cs/remove_consecutive_whitespaces"} ); 
+
+		return result;
+	}
+
+	public ThreadKeyGeneratorImplTest(String input, String expected) {
+		this.input = input;
+		this.expected = expected;
+	}
+
+	@Test
+	public void testGetThreadKey() {
+		assertEquals(expected, generator.getThreadKey(input));
+	}
+}
\ No newline at end of file
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SearchSandbox.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SearchSandbox.java
new file mode 100644
index 0000000..533532c
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SearchSandbox.java
@@ -0,0 +1,93 @@
+package org.apache.sling.mailarchiveserver.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Scanner;
+
+import javax.jcr.query.Query;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+
+/**
+ * Helper REPL for querying JCR with SQL2 or XPath
+ * 
+ * @author bogomolo
+ */
+
+@Component
+public class SearchSandbox {
+
+	@Reference
+	private	ResourceResolverFactory resourceResolverFactory;
+	ResourceResolver resolver = null;
+
+	@Activate
+	public void test() throws PersistenceException, LoginException {
+		System.out.println("*** Search service sandbox");
+
+		if (resolver == null) {
+			resolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+		}
+
+		Resource testRoot;
+
+		final Resource root = resolver.getResource("/");
+		final String path = getClass().getSimpleName();
+		testRoot = resolver.getResource(root, path);
+		if (testRoot == null) {
+			testRoot = resolver.create(root, path, null);
+			resolver.commit();
+		}
+		
+		for (int i = 0; i < 3; i++) {
+			final Props props = new Props("title", "HELLO", "jcr:text", "world");
+			resolver.create(testRoot, "child_" + System.currentTimeMillis(), props).getPath();
+			resolver.commit();
+		}
+
+		Scanner sc = new Scanner(System.in);
+		System.out.println("Type \"quit\" to continue loading MAS.");
+		System.out.print("*** New query: >");
+		String query = sc.nextLine();
+		while (!query.equalsIgnoreCase("quit")) {
+			try {
+				System.out.println("*** sql");
+				Iterator<Resource> resSQL = resolver.findResources(query, Query.JCR_SQL2);
+				while (resSQL.hasNext()) {
+					Resource resource = (Resource) resSQL.next();
+					System.out.println(resource.toString());
+				}
+				
+//				System.out.println("*** xpath");
+//				Iterator<Resource> resXPath = resolver.findResources(query, Query.XPATH);
+//				while (resXPath.hasNext()) {
+//					Resource resource = (Resource) resXPath.next();
+//					System.out.println(resource.toString());
+//				}
+
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			
+			System.out.print("*** New query: >");
+			query = sc.nextLine();
+		}
+	}
+
+	@SuppressWarnings("serial")
+	private static class Props extends HashMap<String, Object> {
+		Props(String ... keyValue) {
+			for(int i=0 ; i< keyValue.length; i+=2) {
+				put(keyValue[i], keyValue[i+1]);
+			}
+		}
+	}
+
+}
diff --git a/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SubjectLettersEntropy.java b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SubjectLettersEntropy.java
new file mode 100644
index 0000000..8fa2050
--- /dev/null
+++ b/mail-archive/server/src/test/java/org/apache/sling/mailarchiveserver/util/SubjectLettersEntropy.java
@@ -0,0 +1,104 @@
+package org.apache.sling.mailarchiveserver.util;
+
+import java.io.PrintStream;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ValueMap;
+
+/**
+ * Util class to calculate entropy of a letter position in the message subject.
+ * 
+ * @author bogomolo
+ */
+
+@Component
+public class SubjectLettersEntropy {
+
+	private static final int SAMPLE_LENGTH = 300;
+	private static final int ALPHABET_LENGTH = 26;
+	private static final double THRESHOLD = 0.9;
+
+	private static final double MAX_THEOR_ENTROPY = -Math.log10(1./ALPHABET_LENGTH);
+
+	@Reference
+	ResourceResolverFactory resourceResolverFactory;
+	private ResourceResolver resolver = null;
+	public static SubjectLettersEntropy instance = null;
+
+	public SubjectLettersEntropy() {
+		if (instance == null) {
+			instance = this;
+		} 
+	}
+
+	int[][] count = new int[SAMPLE_LENGTH][ALPHABET_LENGTH];
+	double[] entropy = new double[SAMPLE_LENGTH];
+	int messages = 0;
+
+	public void calculateEntropyAndPrint(PrintStream out) {
+		try {
+			if (resourceResolverFactory == null) {
+				System.out.println("resourceResolverFactory is NULL");
+			}
+			resolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+
+			String root = "/content/mailarchiveserver/archive"; // /domain/project/list/t/th/thread/message
+			Resource main = resolver.getResource(root);
+			iterate(main, 6);
+			int[] sum = new int[SAMPLE_LENGTH];
+
+			for (int i = 0; i < sum.length; i++) {
+				for (int j = 0; j < ALPHABET_LENGTH; j++) {
+					sum[i] += count[i][j];
+				}
+			}
+
+			for (int i = 0; i < sum.length; i++) {
+				for (int j = 0; j < ALPHABET_LENGTH; j++) {
+					if (count[i][j] > 0) {
+						double num = count[i][j]/1./sum[i];
+						entropy[i] += - num * Math.log10(num); 
+					}
+				}
+			}
+
+			System.out.println(String.format("%s\t%s\t%s", "charAt","entropy", "sum"));
+			for (int i = 0; i < sum.length; i++) {
+				if (entropy[i] >= MAX_THEOR_ENTROPY*THRESHOLD || sum[i] >= messages*THRESHOLD) 
+					System.out.println(String.format("%d\t%.3f\t%d", i, entropy[i], sum[i]));
+			}
+			out.println("Messages #: "+messages);
+			
+		} catch (LoginException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void countLetters(Resource r) {
+		messages++;
+		ValueMap properties = r.adaptTo(ValueMap.class);
+		String subj = properties.get("Subject", (String) null);
+		for (int i = 0; i < Math.min(subj.length(), SAMPLE_LENGTH); i++) {
+			Character c = Character.toLowerCase(subj.charAt(i));
+			if (c.toString().matches("[a-z]")) {
+				count[i][c-'a']++;
+			}
+		}
+	}
+
+	private void iterate(Resource r, int lvl) {
+		for (Resource child : r.getChildren()) {
+			if (lvl == 0) {
+				countLetters(child);
+			} else {
+				iterate(child, lvl-1);
+			}
+		}
+	}
+
+}
diff --git a/mail-archive/server/test_files/multipart.txt b/mail-archive/server/test_files/multipart.txt
new file mode 100644
index 0000000..fa07cd7
--- /dev/null
+++ b/mail-archive/server/test_files/multipart.txt
@@ -0,0 +1,109 @@
+Return-Path: <common-dev-return-77410-apmail-hadoop-common-dev-archive=hadoop.apache.org@hadoop.apache.org>
+X-Original-To: apmail-hadoop-common-dev-archive@www.apache.org
+Delivered-To: apmail-hadoop-common-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 275929C5F
+	for <apmail-hadoop-common-dev-archive@www.apache.org>; Sun,  1 Jan 2012 05:31:21 +0000 (UTC)
+Received: (qmail 5467 invoked by uid 500); 1 Jan 2012 05:31:20 -0000
+Delivered-To: apmail-hadoop-common-dev-archive@hadoop.apache.org
+Received: (qmail 4867 invoked by uid 500); 1 Jan 2012 05:31:08 -0000
+Mailing-List: contact common-dev-help@hadoop.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:common-dev-help@hadoop.apache.org>
+List-Unsubscribe: <mailto:common-dev-unsubscribe@hadoop.apache.org>
+List-Post: <mailto:common-dev@hadoop.apache.org>
+List-Id: <common-dev.hadoop.apache.org>
+Reply-To: common-dev@hadoop.apache.org
+Delivered-To: mailing list common-dev@hadoop.apache.org
+Received: (qmail 4859 invoked by uid 99); 1 Jan 2012 05:31:05 -0000
+Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Jan 2012 05:31:05 +0000
+X-ASF-Spam-Status: No, hits=1.5 required=5.0
+	tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS
+X-Spam-Check-By: apache.org
+Received-SPF: pass (athena.apache.org: domain of ronald.petty@gmail.com designates 74.125.82.176 as permitted sender)
+Received: from [74.125.82.176] (HELO mail-we0-f176.google.com) (74.125.82.176)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Jan 2012 05:31:00 +0000
+Received: by werm10 with SMTP id m10so10570169wer.35
+        for <common-dev@hadoop.apache.org>; Sat, 31 Dec 2011 21:30:39 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+        d=gmail.com; s=gamma;
+        h=mime-version:from:date:message-id:subject:to:content-type;
+        bh=zbylm9gc+1ZZdrKyuZCh2myzsS2W9C01CCAV9oo6vkA=;
+        b=czzeM+s45qAT+QBYb+swdHIsKQUHn1mocaeE0Jd4ZbBZfepTDA3IjAgX0QPxeibfOx
+         phTYdcY0ZaqeOoCVxIrwlZs0vfwF5FkH33yOIIJ9mJ1iGxFHtWTlYWDTrSDkVRhH6Jgj
+         BWMpsbhh5I8p56G9zhKI0xS4joa6Wssnq83WQ=
+Received: by 10.216.138.101 with SMTP id z79mr31006394wei.7.1325395838866;
+ Sat, 31 Dec 2011 21:30:38 -0800 (PST)
+MIME-Version: 1.0
+Received: by 10.216.6.27 with HTTP; Sat, 31 Dec 2011 21:30:17 -0800 (PST)
+From: Ronald Petty <ronald.petty@gmail.com>
+Date: Sun, 1 Jan 2012 00:30:17 -0500
+Message-ID: <CA+mbt7jXoOyp+zXFV2GEyVGTqDQ4atxVKGmec5gfoVhP=32bRw@mail.gmail.com>
+Subject: Building Trunk on EC2
+To: common-dev@hadoop.apache.org
+Content-Type: multipart/alternative; boundary=0016e6d6417629976904b570c4d2
+
+--0016e6d6417629976904b570c4d2
+Content-Type: text/plain; charset=ISO-8859-1
+
+Hello,
+
+If anyone is interested, here are my notes on how to build trunk on bare
+bones AWS EC2 instance.
+
+   1. Create a XL 64-bit AWS EC2 instance (anything smaller fails due to
+   lack of RAM)
+   2. SSH to EC2 instance
+   3. sudo useradd -u 1000 hadoop
+   4. sudo yum install svn gcc.x86_64 gcc-c++.x86_64 libtool.x86_64
+   make.x86_64 automake.noarch autoconf.noarch java-1.6.0-openjdk-devel.x86_64
+   zlib-devel.x86_64
+   5. set JAVA_HOME in vi /etc/profile.d/aws-apitools-common.sh to
+   /usr/lib/jvm/java  (if you don't the native components will not build due
+   to using an incorrect JAVA_HOME even if you set evn JAVA_HOME)
+   6. reboot
+   7. login
+   8. su hadoop
+   9. sudo mkdir /data
+   10. sudo chown -R hadoop:hadoop /data
+   11. cd /data
+   12. wget http://apache.petsads.us//forrest/apache-forrest-0.9.tar.gz
+   13. wget
+   http://mirror.cc.columbia.edu/pub/software/apache//maven/binaries/apache-maven-3.0.3-bin.tar.gz
+   14. wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
+   15. wget
+   http://superb-sea2.dl.sourceforge.net/project/findbugs/findbugs/2.0.0/findbugs-2.0.0.tar.gz
+   16. gunzip *.gz
+   17. tar xf apache-forrest-0.9.tar
+   18. tar xf apache-maven-3.0.3-bin.tar
+   19. tar xf findbugs-2.0.0.tar
+   20. tar xf protobuf-2.4.1.tar
+   21. export FORREST_HOME=/data/apache-forrest-0.9
+   22. export MAVEN_HOME=/data/apache-maven-3.0.3
+   23. export FINDBUGS_HOME=/data/findbugs-2.0.0
+   24. cd protobuf-2.4.1
+   25. ./configure
+   26. make
+   27. sudo make install
+   28. cd ..
+   29. export
+   PATH=/usr/local/bin/:/data/apache-maven-3.0.3/bin/:/data/apache-forrest-0.9/bin/:/data/findbugs-2.0.0/bin/:$PATH
+   30. svn checkout
+http://svn.apache.org/repos/asf/hadoop/common/trunk/hadoop-trunk
+   31. cd hadoop-trunk
+   32. mvn package -Pdist,native,docs -DskipTests -Dtar
+
+I have not actually used the constructed tar yet, but wanted to share my
+notes.  I did notice two things missing (compared to the regular pre-yarn
+releases), there is no conf directory, nor example jars.  I know trunk is
+being worked on but I am not sure what the plan is there (or if I simply
+missed something.)
+
+If you have any comments, questions, or advice I love to here it.
+
+Kindest regards.
+
+Ron
+
+--0016e6d6417629976904b570c4d2--
diff --git a/mail-archive/server/test_files/multipart_body.txt b/mail-archive/server/test_files/multipart_body.txt
new file mode 100644
index 0000000..7ca9ab4
--- /dev/null
+++ b/mail-archive/server/test_files/multipart_body.txt
@@ -0,0 +1,59 @@
+Hello,
+
+If anyone is interested, here are my notes on how to build trunk on bare
+bones AWS EC2 instance.
+
+   1. Create a XL 64-bit AWS EC2 instance (anything smaller fails due to
+   lack of RAM)
+   2. SSH to EC2 instance
+   3. sudo useradd -u 1000 hadoop
+   4. sudo yum install svn gcc.x86_64 gcc-c++.x86_64 libtool.x86_64
+   make.x86_64 automake.noarch autoconf.noarch java-1.6.0-openjdk-devel.x86_64
+   zlib-devel.x86_64
+   5. set JAVA_HOME in vi /etc/profile.d/aws-apitools-common.sh to
+   /usr/lib/jvm/java  (if you don't the native components will not build due
+   to using an incorrect JAVA_HOME even if you set evn JAVA_HOME)
+   6. reboot
+   7. login
+   8. su hadoop
+   9. sudo mkdir /data
+   10. sudo chown -R hadoop:hadoop /data
+   11. cd /data
+   12. wget http://apache.petsads.us//forrest/apache-forrest-0.9.tar.gz
+   13. wget
+   http://mirror.cc.columbia.edu/pub/software/apache//maven/binaries/apache-maven-3.0.3-bin.tar.gz
+   14. wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
+   15. wget
+   http://superb-sea2.dl.sourceforge.net/project/findbugs/findbugs/2.0.0/findbugs-2.0.0.tar.gz
+   16. gunzip *.gz
+   17. tar xf apache-forrest-0.9.tar
+   18. tar xf apache-maven-3.0.3-bin.tar
+   19. tar xf findbugs-2.0.0.tar
+   20. tar xf protobuf-2.4.1.tar
+   21. export FORREST_HOME=/data/apache-forrest-0.9
+   22. export MAVEN_HOME=/data/apache-maven-3.0.3
+   23. export FINDBUGS_HOME=/data/findbugs-2.0.0
+   24. cd protobuf-2.4.1
+   25. ./configure
+   26. make
+   27. sudo make install
+   28. cd ..
+   29. export
+   PATH=/usr/local/bin/:/data/apache-maven-3.0.3/bin/:/data/apache-forrest-0.9/bin/:/data/findbugs-2.0.0/bin/:$PATH
+   30. svn checkout
+http://svn.apache.org/repos/asf/hadoop/common/trunk/hadoop-trunk
+   31. cd hadoop-trunk
+   32. mvn package -Pdist,native,docs -DskipTests -Dtar
+
+I have not actually used the constructed tar yet, but wanted to share my
+notes.  I did notice two things missing (compared to the regular pre-yarn
+releases), there is no conf directory, nor example jars.  I know trunk is
+being worked on but I am not sure what the plan is there (or if I simply
+missed something.)
+
+If you have any comments, questions, or advice I love to here it.
+
+Kindest regards.
+
+Ron
+
diff --git a/mail-archive/server/test_files/singlepart.txt b/mail-archive/server/test_files/singlepart.txt
new file mode 100644
index 0000000..5def697
--- /dev/null
+++ b/mail-archive/server/test_files/singlepart.txt
@@ -0,0 +1,66 @@
+Return-Path: <common-dev-return-77583-apmail-hadoop-common-dev-archive=hadoop.apache.org@hadoop.apache.org>
+X-Original-To: apmail-hadoop-common-dev-archive@www.apache.org
+Delivered-To: apmail-hadoop-common-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 04D6296E1
+	for <apmail-hadoop-common-dev-archive@www.apache.org>; Wed,  1 Feb 2012 00:23:25 +0000 (UTC)
+Received: (qmail 97997 invoked by uid 500); 1 Feb 2012 00:23:21 -0000
+Delivered-To: apmail-hadoop-common-dev-archive@hadoop.apache.org
+Received: (qmail 97504 invoked by uid 500); 1 Feb 2012 00:23:20 -0000
+Mailing-List: contact common-dev-help@hadoop.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:common-dev-help@hadoop.apache.org>
+List-Unsubscribe: <mailto:common-dev-unsubscribe@hadoop.apache.org>
+List-Post: <mailto:common-dev@hadoop.apache.org>
+List-Id: <common-dev.hadoop.apache.org>
+Reply-To: common-dev@hadoop.apache.org
+Delivered-To: mailing list common-dev@hadoop.apache.org
+Received: (qmail 97483 invoked by uid 99); 1 Feb 2012 00:23:20 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Feb 2012 00:23:20 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED,T_RP_MATCHES_RCVD
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Feb 2012 00:23:17 +0000
+Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116])
+	by hel.zones.apache.org (Postfix) with ESMTP id CF2F31679FA
+	for <common-dev@hadoop.apache.org>; Wed,  1 Feb 2012 00:22:56 +0000 (UTC)
+Date: Wed, 1 Feb 2012 00:22:56 +0000 (UTC)
+From: "Roman Shaposhnik (Created) (JIRA)" <jira@apache.org>
+To: common-dev@hadoop.apache.org
+Message-ID: <250130243.649.1328055776849.JavaMail.tomcat@hel.zones.apache.org>
+Subject: [jira] [Created] (HADOOP-8010) hadoop-config.sh spews error message
+ when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 7bit
+X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394
+X-Virus-Checked: Checked by ClamAV on apache.org
+
+hadoop-config.sh spews error message when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present
+-------------------------------------------------------------------------------------------------------------
+
+                 Key: HADOOP-8010
+                 URL: https://issues.apache.org/jira/browse/HADOOP-8010
+             Project: Hadoop Common
+          Issue Type: Bug
+          Components: scripts
+    Affects Versions: 1.0.0
+            Reporter: Roman Shaposhnik
+            Assignee: Roman Shaposhnik
+            Priority: Minor
+             Fix For: 1.0.1
+
+
+Running hadoop daemon commands when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present produces:
+{noformat}
+  [: 76: true: unexpected operator
+{noformat}
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
diff --git a/mail-archive/server/test_files/singlepart_body.txt b/mail-archive/server/test_files/singlepart_body.txt
new file mode 100644
index 0000000..4845a3b
--- /dev/null
+++ b/mail-archive/server/test_files/singlepart_body.txt
@@ -0,0 +1,27 @@
+hadoop-config.sh spews error message when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present
+-------------------------------------------------------------------------------------------------------------
+
+                 Key: HADOOP-8010
+                 URL: https://issues.apache.org/jira/browse/HADOOP-8010
+             Project: Hadoop Common
+          Issue Type: Bug
+          Components: scripts
+    Affects Versions: 1.0.0
+            Reporter: Roman Shaposhnik
+            Assignee: Roman Shaposhnik
+            Priority: Minor
+             Fix For: 1.0.1
+
+
+Running hadoop daemon commands when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present produces:
+{noformat}
+  [: 76: true: unexpected operator
+{noformat}
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
+
diff --git a/mail-archive/server/test_files/singlepart_headers.txt b/mail-archive/server/test_files/singlepart_headers.txt
new file mode 100644
index 0000000..f35d7a4
--- /dev/null
+++ b/mail-archive/server/test_files/singlepart_headers.txt
@@ -0,0 +1,37 @@
+// this is a comment, no blank lines please
+// name/value separator should be equals to MessageStoreImplRepositoryTest.TEST_FILE_FIELD_SEPARATOR
+Return-Path : <common-dev-return-77583-apmail-hadoop-common-dev-archive=hadoop.apache.org@hadoop.apache.org>
+X-Original-To : apmail-hadoop-common-dev-archive@www.apache.org
+Delivered-To : apmail-hadoop-common-dev-archive@www.apache.org
+Received : from mail.apache.org (hermes.apache.org [140.211.11.3])	by minotaur.apache.org (Postfix) with SMTP id 04D6296E1	for <apmail-hadoop-common-dev-archive@www.apache.org>; Wed,  1 Feb 2012 00:23:25 +0000 (UTC)
+Received : (qmail 97997 invoked by uid 500); 1 Feb 2012 00:23:21 -0000
+Delivered-To : apmail-hadoop-common-dev-archive@hadoop.apache.org
+Received : (qmail 97504 invoked by uid 500); 1 Feb 2012 00:23:20 -0000
+Mailing-List : contact common-dev-help@hadoop.apache.org; run by ezmlm
+Precedence : bulk
+List-Help : <mailto:common-dev-help@hadoop.apache.org>
+List-Unsubscribe : <mailto:common-dev-unsubscribe@hadoop.apache.org>
+List-Post : <mailto:common-dev@hadoop.apache.org>
+List-Id : <common-dev.hadoop.apache.org>
+Reply-To : common-dev@hadoop.apache.org
+Delivered-To : mailing list common-dev@hadoop.apache.org
+Received : (qmail 97483 invoked by uid 99); 1 Feb 2012 00:23:20 -0000
+Received : from nike.apache.org (HELO nike.apache.org) (192.87.106.230)    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Feb 2012 00:23:20 +0000
+X-ASF-Spam-Status : No, hits=-2000.0 required=5.0	tests=ALL_TRUSTED,T_RP_MATCHES_RCVD
+X-Spam-Check-By : apache.org
+Received : from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116)    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Feb 2012 00:23:17 +0000
+Received : from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116])	by hel.zones.apache.org (Postfix) with ESMTP id CF2F31679FA	for <common-dev@hadoop.apache.org>; Wed,  1 Feb 2012 00:22:56 +0000 (UTC)
+Date : Wed, 1 Feb 2012 00:22:56 +0000 (UTC)
+From : "Roman Shaposhnik (Created) (JIRA)" <jira@apache.org>
+To : common-dev@hadoop.apache.org
+Message-ID : <250130243.649.1328055776849.JavaMail.tomcat@hel.zones.apache.org>
+Subject : [jira] [Created] (HADOOP-8010) hadoop-config.sh spews error message when HADOOP_HOME_WARN_SUPPRESS is set to true and HADOOP_HOME is present
+MIME-Version : 1.0
+Content-Type : text/plain; charset=utf-8
+Content-Transfer-Encoding : 7bit
+X-JIRA-FingerPrint : 30527f35849b9dde25b450d4833f0394
+X-Virus-Checked : Checked by ClamAV on apache.org
+jcr:primaryType : nt:unstructured
+jcr:text : 250130243.649.1328055776849.JavaMail.tomcat@hel.zones.apache.org
+// sling_resourceType instead of sling:resourceType beacause of javax.jcr.NamespaceException otherwise
+sling_resourceType : mailarchiveserver/message
\ No newline at end of file
diff --git a/mail-archive/server/test_files/three_messages.mbox b/mail-archive/server/test_files/three_messages.mbox
new file mode 100644
index 0000000..571003e
--- /dev/null
+++ b/mail-archive/server/test_files/three_messages.mbox
@@ -0,0 +1,250 @@
+From common-dev-return-77881-apmail-hadoop-common-dev-archive=hadoop.apache.org@hadoop.apache.org  Thu Mar  1 02:57:25 2012
+Return-Path: <common-dev-return-77881-apmail-hadoop-common-dev-archive=hadoop.apache.org@hadoop.apache.org>
+X-Original-To: apmail-hadoop-common-dev-archive@www.apache.org
+Delivered-To: apmail-hadoop-common-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 8C416925D
+	for <apmail-hadoop-common-dev-archive@www.apache.org>; Thu,  1 Mar 2012 02:57:25 +0000 (UTC)
+Received: (qmail 9815 invoked by uid 500); 1 Mar 2012 02:57:24 -0000
+Delivered-To: apmail-hadoop-common-dev-archive@hadoop.apache.org
+Received: (qmail 9089 invoked by uid 500); 1 Mar 2012 02:57:22 -0000
+Mailing-List: contact common-dev-help@hadoop.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:common-dev-help@hadoop.apache.org>
+List-Unsubscribe: <mailto:common-dev-unsubscribe@hadoop.apache.org>
+List-Post: <mailto:common-dev@hadoop.apache.org>
+List-Id: <common-dev.hadoop.apache.org>
+Reply-To: common-dev@hadoop.apache.org
+Delivered-To: mailing list common-dev@hadoop.apache.org
+Received: (qmail 9040 invoked by uid 99); 1 Mar 2012 02:57:20 -0000
+Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2012 02:57:20 +0000
+X-ASF-Spam-Status: No, hits=1.5 required=5.0
+	tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS
+X-Spam-Check-By: apache.org
+Received-SPF: pass (athena.apache.org: domain of masmertoz@gmail.com designates 209.85.210.176 as permitted sender)
+Received: from [209.85.210.176] (HELO mail-iy0-f176.google.com) (209.85.210.176)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2012 02:57:14 +0000
+Received: by iagw33 with SMTP id w33so272974iag.35
+        for <common-dev@hadoop.apache.org>; Wed, 29 Feb 2012 18:56:53 -0800 (PST)
+Received-SPF: pass (google.com: domain of masmertoz@gmail.com designates 10.42.147.199 as permitted sender) client-ip=10.42.147.199;
+Authentication-Results: mr.google.com; spf=pass (google.com: domain of masmertoz@gmail.com designates 10.42.147.199 as permitted sender) smtp.mail=masmertoz@gmail.com; dkim=pass header.i=masmertoz@gmail.com
+Received: from mr.google.com ([10.42.147.199])
+        by 10.42.147.199 with SMTP id o7mr2309493icv.50.1330570613677 (num_hops = 1);
+        Wed, 29 Feb 2012 18:56:53 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+        d=gmail.com; s=gamma;
+        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
+         :content-type;
+        bh=ca6tWWewYqZQb+wuqEDo3x908P9XiZM0DtWMOMrehQ4=;
+        b=CF9YqcgV+7bycKErB/pbmhFQldN1wxWkybLoH3+W9Oek4/FwP6kaZxPRuO5KeyLamw
+         eFmk3EBAa16qxEX0tul8Ik3BxFC72fK8JmZti78aTmdREjtet/C4a52ho8/bAaSkOCry
+         +eJqQtx2fh0Kn6ZaoMIgZiRbGaj9zXftmWexM=
+MIME-Version: 1.0
+Received: by 10.42.147.199 with SMTP id o7mr1907969icv.50.1330570613623; Wed,
+ 29 Feb 2012 18:56:53 -0800 (PST)
+Received: by 10.42.241.132 with HTTP; Wed, 29 Feb 2012 18:56:53 -0800 (PST)
+In-Reply-To: <CAENBeZZYO8sTZcQjWQ8aUndBJo3mcQKbxJiL2S47qryM8KN7tw@mail.gmail.com>
+References: <CAENBeZZYO8sTZcQjWQ8aUndBJo3mcQKbxJiL2S47qryM8KN7tw@mail.gmail.com>
+Date: Thu, 1 Mar 2012 03:56:53 +0100
+Message-ID: <CAENBeZbtbnESj6s0Bgkv5h7uSRUEQnZ+aWZm6z6pxGjxaSFiqg@mail.gmail.com>
+Subject: Re: Developing and deploying hadoop
+From: Merto Mertek <masmertoz@gmail.com>
+To: common-dev@hadoop.apache.org
+Content-Type: multipart/alternative; boundary=90e6ba6e8c04c60cb804ba259c76
+X-Virus-Checked: Checked by ClamAV on apache.org
+
+--90e6ba6e8c04c60cb804ba259c76
+Content-Type: text/plain; charset=ISO-8859-1
+
+I would be glad to hear what is your development cycle and how you deploy
+new features to production cluster...  How do you deploy them to the
+production cluster? With bash scripts and rsync, ant, maven or any other
+automation tool? I would be thankfull if you could point me to any resource
+describing best practices in developing, deploying and automatization of
+java project in unix/linux environment..
+
+thanks..
+
+
+On 13 February 2012 11:26, Merto Mertek <masmertoz@gmail.com> wrote:
+
+> I am interested in some general tips on how to develop and deploy new
+> versions of hadoop. I've been trying to compile a new version of  hadoop
+> and place the new jar to the cluster in the lib folder, however it was not
+> picked despite the classpath was explicitly set to the lib folder. I am
+> interested in the following questions:
+>
+> a) How to deploy a new version? Just copy the new compiled jar file to all
+> lib folders on all nodes?
+> b) Should I make just a new compile or a new release ('ant' vs 'ant tar')?
+> c) How do you develop and deploy hadoop locally and how remotely?  For
+> deploying builds are you using your own sh scripts or are you using any
+> tools like ant/maven?
+> d) What is the purpose of the folder $HADOOP_HOME/share/hadoop?
+>
+>
+> Any other tips are welcomed..
+>
+> Thank you
+>
+
+--90e6ba6e8c04c60cb804ba259c76--
+
+From dev-return-126904-apmail-tomcat-dev-archive=tomcat.apache.org@tomcat.apache.org  Mon Apr  2 02:59:53 2012
+Return-Path: <dev-return-126904-apmail-tomcat-dev-archive=tomcat.apache.org@tomcat.apache.org>
+X-Original-To: apmail-tomcat-dev-archive@www.apache.org
+Delivered-To: apmail-tomcat-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+    by minotaur.apache.org (Postfix) with SMTP id 334159308
+    for <apmail-tomcat-dev-archive@www.apache.org>; Mon,  2 Apr 2012 02:59:53 +0000 (UTC)
+Received: (qmail 36894 invoked by uid 500); 2 Apr 2012 02:59:51 -0000
+Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org
+Received: (qmail 36800 invoked by uid 500); 2 Apr 2012 02:59:51 -0000
+Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@tomcat.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@tomcat.apache.org>
+List-Post: <mailto:dev@tomcat.apache.org>
+List-Id: <dev.tomcat.apache.org>
+Reply-To: "Tomcat Developers List" <dev@tomcat.apache.org>
+Delivered-To: mailing list dev@tomcat.apache.org
+Received: (qmail 36740 invoked by uid 99); 2 Apr 2012 02:59:51 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Apr 2012 02:59:50 +0000
+X-ASF-Spam-Status: No, hits=-1996.0 required=5.0
+    tests=ALL_TRUSTED,DCC_CHECK
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.115] (HELO eir.zones.apache.org) (140.211.11.115)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Apr 2012 02:59:48 +0000
+Received: by eir.zones.apache.org (Postfix, from userid 80)
+    id EE2AA3D94; Mon,  2 Apr 2012 02:59:27 +0000 (UTC)
+From: bugzilla@apache.org
+To: dev@tomcat.apache.org
+Subject: DO NOT REPLY [Bug 53022] session is expired/removed/not found by
+ unknown reason
+Date: Mon, 02 Apr 2012 02:59:27 +0000
+X-Bugzilla-Reason: AssignedTo
+X-Bugzilla-Type: changed
+X-Bugzilla-Watch-Reason: None
+X-Bugzilla-Product: Tomcat 7
+X-Bugzilla-Component: Catalina
+X-Bugzilla-Keywords: 
+X-Bugzilla-Severity: critical
+X-Bugzilla-Who: lu4242@apache.org
+X-Bugzilla-Status: NEW
+X-Bugzilla-Priority: P2
+X-Bugzilla-Assigned-To: dev@tomcat.apache.org
+X-Bugzilla-Target-Milestone: ---
+X-Bugzilla-Changed-Fields: CC
+In-Reply-To: <bug-53022-78@https.issues.apache.org/bugzilla/>
+References: <bug-53022-78@https.issues.apache.org/bugzilla/>
+X-Bugzilla-URL: https://issues.apache.org/bugzilla/
+Auto-Submitted: auto-generated
+Content-Type: text/plain; charset="UTF-8"
+MIME-Version: 1.0
+
+https://issues.apache.org/bugzilla/show_bug.cgi?id=53022
+
+Leonardo Uribe <lu4242@apache.org> changed:
+
+           What    |Removed                     |Added
+----------------------------------------------------------------------------
+                 CC|                            |lu4242@apache.org
+
+-- 
+Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
+------- You are receiving this mail because: -------
+You are the assignee for the bug.
+
+---------------------------------------------------------------------
+To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
+For additional commands, e-mail: dev-help@tomcat.apache.org
+
+
+From dev-return-33924-apmail-jackrabbit-dev-archive=jackrabbit.apache.org@jackrabbit.apache.org  Wed Jan 25 17:04:43 2012
+Return-Path: <dev-return-33924-apmail-jackrabbit-dev-archive=jackrabbit.apache.org@jackrabbit.apache.org>
+X-Original-To: apmail-jackrabbit-dev-archive@www.apache.org
+Delivered-To: apmail-jackrabbit-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+    by minotaur.apache.org (Postfix) with SMTP id A60F99C19
+    for <apmail-jackrabbit-dev-archive@www.apache.org>; Wed, 25 Jan 2012 17:04:43 +0000 (UTC)
+Received: (qmail 52953 invoked by uid 500); 25 Jan 2012 17:04:43 -0000
+Delivered-To: apmail-jackrabbit-dev-archive@jackrabbit.apache.org
+Received: (qmail 52911 invoked by uid 500); 25 Jan 2012 17:04:42 -0000
+Mailing-List: contact dev-help@jackrabbit.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@jackrabbit.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@jackrabbit.apache.org>
+List-Post: <mailto:dev@jackrabbit.apache.org>
+List-Id: <dev.jackrabbit.apache.org>
+Reply-To: dev@jackrabbit.apache.org
+Delivered-To: mailing list dev@jackrabbit.apache.org
+Received: (qmail 52903 invoked by uid 99); 25 Jan 2012 17:04:42 -0000
+Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Jan 2012 17:04:42 +0000
+X-ASF-Spam-Status: No, hits=-1.6 required=5.0
+    tests=RCVD_IN_DNSWL_MED,SPF_NEUTRAL
+X-Spam-Check-By: apache.org
+Received-SPF: neutral (athena.apache.org: local policy)
+Received: from [64.18.1.31] (HELO exprod6og113.obsmtp.com) (64.18.1.31)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Jan 2012 17:04:33 +0000
+Received: from outbound-smtp-2.corp.adobe.com ([193.104.215.16]) by exprod6ob113.postini.com ([64.18.5.12]) with SMTP
+    ID DSNKTyA2DGVL/RbMVKoAyiWEtOdqxaX7p0B0@postini.com; Wed, 25 Jan 2012 09:04:13 PST
+Received: from inner-relay-1.corp.adobe.com (inner-relay-1.corp.adobe.com [153.32.1.51])
+    by outbound-smtp-2.corp.adobe.com (8.12.10/8.12.10) with ESMTP id q0PH4A2U021951
+    for <dev@jackrabbit.apache.org>; Wed, 25 Jan 2012 09:04:11 -0800 (PST)
+Received: from nacas02.corp.adobe.com (nacas02.corp.adobe.com [10.8.189.100])
+    by inner-relay-1.corp.adobe.com (8.12.10/8.12.10) with ESMTP id q0PH49MN015128
+    for <dev@jackrabbit.apache.org>; Wed, 25 Jan 2012 09:04:10 -0800 (PST)
+Received: from eurcas01.eur.adobe.com (10.128.4.27) by nacas02.corp.adobe.com
+ (10.8.189.100) with Microsoft SMTP Server (TLS) id 8.3.192.1; Wed, 25 Jan
+ 2012 09:04:09 -0800
+Received: from susi.local (10.136.140.49) by eurcas01.eur.adobe.com
+ (10.128.4.111) with Microsoft SMTP Server id 8.3.192.1; Wed, 25 Jan 2012
+ 17:04:08 +0000
+Message-ID: <4F203608.3050200@apache.org>
+Date: Wed, 25 Jan 2012 17:04:08 +0000
+From: =?ISO-8859-1?Q?Michael_D=FCrig?= <mduerig@apache.org>
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20111222 Thunderbird/9.0.1
+MIME-Version: 1.0
+To: <dev@jackrabbit.apache.org>
+Subject: [jr3 Microkernel] how should we handle failed save operations?
+Content-Type: text/plain; charset="ISO-8859-1"; format=flowed
+Content-Transfer-Encoding: 7bit
+
+
+Hi,
+
+In an earlier discussion (probably offline), we decided to not implement 
+Item.refresh() since it doesn't go well with the MVCC model jr3 is based 
+on. Furthermore, JCR doesn't have an Item.undo() method for undoing changes.
+
+This may lead to problems when a Session.save() fails due to the 
+underlying Microkernel.commit failing because it detected a conflict. 
+Now there might be some transient changes (like deletions) which can't 
+be selectively undone by the user. So the user is left with a transient 
+space containing his changes but he can only discard them as a whole. 
+Not very satisfactory.
+
+Possible solutions:
+
+1) The Microkernel makes as much effort as possible to three way merge 
+changes.
+
+2) The user needs to do a session refresh with keep changes = true and 
+save again.
+
+3) Introduce a Item.undo method on the JCR API.
+
+
+1) Mitigates the problem such that it only occurs rarely.
+
+2) Is really nothing more than moving the problem of the failed commit 
+due to a conflict from the Microkernel to the transient space: now the 
+transient space needs to do conflict resolution.
+
+3) Is what I think we should do. This enable the user to resolve his 
+conflicts selectively.
+
+Michael
diff --git a/mail-archive/server/test_files/wrongbody.mbox b/mail-archive/server/test_files/wrongbody.mbox
new file mode 100644
index 0000000..693dd8b
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody.mbox
@@ -0,0 +1,883 @@
+From dev-return-26289-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Thu Mar 29 20:49:50 2012
+Return-Path: <dev-return-26289-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 266239F8E
+	for <apmail-sling-dev-archive@www.apache.org>; Thu, 29 Mar 2012 20:49:50 +0000 (UTC)
+Received: (qmail 13616 invoked by uid 500); 29 Mar 2012 20:49:49 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 13515 invoked by uid 500); 29 Mar 2012 20:49:49 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 13297 invoked by uid 99); 29 Mar 2012 20:49:49 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Mar 2012 20:49:49 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED,T_RP_MATCHES_RCVD
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Mar 2012 20:49:46 +0000
+Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116])
+	by hel.zones.apache.org (Postfix) with ESMTP id A00E934B3A6
+	for <dev@sling.apache.org>; Thu, 29 Mar 2012 20:49:25 +0000 (UTC)
+Date: Thu, 29 Mar 2012 20:49:25 +0000 (UTC)
+From: "Carsten Ziegeler (Commented) (JIRA)" <jira@apache.org>
+To: dev@sling.apache.org
+Message-ID: <1997318514.34674.1333054165672.JavaMail.tomcat@hel.zones.apache.org>
+In-Reply-To: <1651017606.30866.1322744801989.JavaMail.tomcat@hel.zones.apache.org>
+Subject: [jira] [Commented] (SLING-2311) Sling Performance Testing tool
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 7bit
+X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394
+
+
+    [ https://issues.apache.org/jira/browse/SLING-2311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13241609#comment-13241609 ] 
+
+Carsten Ziegeler commented on SLING-2311:
+-----------------------------------------
+
+Great stuff - I think we should definitely have something like this, not sure whether we should start a new module or add it to commons testing or could just test
+junit-perf for this?
+                
+> Sling Performance Testing tool
+> ------------------------------
+>
+>                 Key: SLING-2311
+>                 URL: https://issues.apache.org/jira/browse/SLING-2311
+>             Project: Sling
+>          Issue Type: New Feature
+>          Components: Testing
+>            Reporter: Antonio Sanso
+>            Assignee: Carsten Ziegeler
+>            Priority: Minor
+>         Attachments: ResolveWithManyAliasTest.java, SLING-2311-patch.txt
+>
+>
+> As described/discussed in [0] it would be nice to have a performance test tool in Sling .
+> This can be useful in different situations (e.g. micro benchmarks of a feature and so on).
+> Patch to follow
+> [0] http://sling.markmail.org/message/bz44im7aqeae4r57
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
+
+From dev-return-26290-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Fri Mar 30 00:11:52 2012
+Return-Path: <dev-return-26290-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id B5CD39755
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 00:11:52 +0000 (UTC)
+Received: (qmail 52185 invoked by uid 500); 30 Mar 2012 00:11:52 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 52143 invoked by uid 500); 30 Mar 2012 00:11:52 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 52130 invoked by uid 99); 30 Mar 2012 00:11:52 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 00:11:52 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED,T_RP_MATCHES_RCVD
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 00:11:49 +0000
+Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116])
+	by hel.zones.apache.org (Postfix) with ESMTP id 0120E34DB88
+	for <dev@sling.apache.org>; Fri, 30 Mar 2012 00:11:29 +0000 (UTC)
+Date: Fri, 30 Mar 2012 00:11:29 +0000 (UTC)
+From: "Carsten Ziegeler (Updated) (JIRA)" <jira@apache.org>
+To: dev@sling.apache.org
+Message-ID: <338053853.35872.1333066289015.JavaMail.tomcat@hel.zones.apache.org>
+In-Reply-To: <1269013084.29325.1332957568495.JavaMail.tomcat@hel.zones.apache.org>
+Subject: [jira] [Updated] (SLING-2450) JcrInstaller generates incorrect node
+ name in /apps/system/config (or else the installer doesn't process the
+ nodename properly)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 7bit
+X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394
+
+
+     [ https://issues.apache.org/jira/browse/SLING-2450?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
+
+Carsten Ziegeler updated SLING-2450:
+------------------------------------
+
+    Affects Version/s: Installer Core 3.3.4
+                       Installer Configuration Factory 1.0.4
+        Fix Version/s: Installer Configuration Factory 1.0.6
+                       JCR Installer 3.1.4
+                       Installer Core 3.3.6
+    
+> JcrInstaller generates incorrect node name in /apps/system/config (or else the installer doesn't process the nodename properly)
+> -------------------------------------------------------------------------------------------------------------------------------
+>
+>                 Key: SLING-2450
+>                 URL: https://issues.apache.org/jira/browse/SLING-2450
+>             Project: Sling
+>          Issue Type: Bug
+>          Components: Installer
+>    Affects Versions: Installer Core 3.3.4, JCR Installer 3.1.2, Installer Configuration Factory 1.0.4
+>            Reporter: Tyson Norris
+>            Assignee: Carsten Ziegeler
+>             Fix For: Installer Core 3.3.6, JCR Installer 3.1.4, Installer Configuration Factory 1.0.6
+>
+>
+> when using ConfigurationAdmin or osgi web console to create a config for a ManagedServiceFactory, a nt:file node is created in /apps/system/config with a node name like:
+> com.adobe.granite.auth.oauth.provider.com.adobe.granite.auth.oauth.provider.99bd39e3-4367-47b0-a5a2-b4e1a0f8a5b9.config
+> The installer, however will not process the node (and create the managed service propertly) unless the node name is formatted like:
+> com.adobe.granite.auth.oauth.provider-99bd39e3-4367-47b0-a5a2-b4e1a0f8a5b9.config
+> Note that:
+> - "com.adobe.granite.auth.oauth.provider" string only occurs once
+> - there is a dash "-" after "provider"
+> I'm not sure which problem it is, but it may be one of:
+> - the JcrInstaller generates the wrong node name
+> - OR the JcrInstaller does not process the node name properly
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
+
+From dev-return-26291-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Fri Mar 30 00:11:53 2012
+Return-Path: <dev-return-26291-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 11EDE9792
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 00:11:53 +0000 (UTC)
+Received: (qmail 52478 invoked by uid 500); 30 Mar 2012 00:11:52 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 52403 invoked by uid 500); 30 Mar 2012 00:11:52 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 52393 invoked by uid 99); 30 Mar 2012 00:11:52 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 00:11:52 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED,T_RP_MATCHES_RCVD
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 00:11:50 +0000
+Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116])
+	by hel.zones.apache.org (Postfix) with ESMTP id 36D9F34DB8B
+	for <dev@sling.apache.org>; Fri, 30 Mar 2012 00:11:29 +0000 (UTC)
+Date: Fri, 30 Mar 2012 00:11:29 +0000 (UTC)
+From: "Carsten Ziegeler (Resolved) (JIRA)" <jira@apache.org>
+To: dev@sling.apache.org
+Message-ID: <1662610421.35874.1333066289235.JavaMail.tomcat@hel.zones.apache.org>
+In-Reply-To: <1269013084.29325.1332957568495.JavaMail.tomcat@hel.zones.apache.org>
+Subject: [jira] [Resolved] (SLING-2450) JcrInstaller generates incorrect
+ node name in /apps/system/config (or else the installer doesn't process the
+ nodename properly)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 7bit
+X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394
+
+
+     [ https://issues.apache.org/jira/browse/SLING-2450?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
+
+Carsten Ziegeler resolved SLING-2450.
+-------------------------------------
+
+    Resolution: Fixed
+
+Actually this was a serious of smaller bugs in all three components. I've fixed the factory configuration handling in revision 1307172. In addition it now uses the alias name when writing back an overwritten configuration
+                
+> JcrInstaller generates incorrect node name in /apps/system/config (or else the installer doesn't process the nodename properly)
+> -------------------------------------------------------------------------------------------------------------------------------
+>
+>                 Key: SLING-2450
+>                 URL: https://issues.apache.org/jira/browse/SLING-2450
+>             Project: Sling
+>          Issue Type: Bug
+>          Components: Installer
+>    Affects Versions: Installer Core 3.3.4, JCR Installer 3.1.2, Installer Configuration Factory 1.0.4
+>            Reporter: Tyson Norris
+>            Assignee: Carsten Ziegeler
+>             Fix For: Installer Core 3.3.6, JCR Installer 3.1.4, Installer Configuration Factory 1.0.6
+>
+>
+> when using ConfigurationAdmin or osgi web console to create a config for a ManagedServiceFactory, a nt:file node is created in /apps/system/config with a node name like:
+> com.adobe.granite.auth.oauth.provider.com.adobe.granite.auth.oauth.provider.99bd39e3-4367-47b0-a5a2-b4e1a0f8a5b9.config
+> The installer, however will not process the node (and create the managed service propertly) unless the node name is formatted like:
+> com.adobe.granite.auth.oauth.provider-99bd39e3-4367-47b0-a5a2-b4e1a0f8a5b9.config
+> Note that:
+> - "com.adobe.granite.auth.oauth.provider" string only occurs once
+> - there is a dash "-" after "provider"
+> I'm not sure which problem it is, but it may be one of:
+> - the JcrInstaller generates the wrong node name
+> - OR the JcrInstaller does not process the node name properly
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
+
+From dev-return-26292-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Fri Mar 30 03:14:05 2012
+Return-Path: <dev-return-26292-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id 01B7B9203
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 03:14:05 +0000 (UTC)
+Received: (qmail 7358 invoked by uid 500); 30 Mar 2012 03:14:04 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 7108 invoked by uid 500); 30 Mar 2012 03:14:03 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 7064 invoked by uid 99); 30 Mar 2012 03:14:01 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:14:01 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.8] (HELO aegis.apache.org) (140.211.11.8)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:13:58 +0000
+Received: from aegis.apache.org (localhost [127.0.0.1])
+	by aegis.apache.org (Postfix) with ESMTP id BCBCEC00A0;
+	Fri, 30 Mar 2012 03:13:37 +0000 (UTC)
+Date: Fri, 30 Mar 2012 03:12:56 +0000 (UTC)
+From: Apache Jenkins Server <jenkins@builds.apache.org>
+To: dev@sling.apache.org, cziegeler@googlemail.com
+Message-ID: <2121048278.104.1333077217756.JavaMail.hudson@aegis>
+In-Reply-To: <1732558901.1278.1332988865440.JavaMail.hudson@aegis>
+References: <1732558901.1278.1332988865440.JavaMail.hudson@aegis>
+Subject: Jenkins build is back to normal : sling-trunk-1.6 #1288
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+X-Jenkins-Job: sling-trunk-1.6
+X-Jenkins-Result: SUCCESS
+
+See <https://builds.apache.org/job/sling-trunk-1.6/1288/changes>
+
+
+From dev-return-26293-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Fri Mar 30 03:16:33 2012
+Return-Path: <dev-return-26293-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id C03AA926F
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 03:16:33 +0000 (UTC)
+Received: (qmail 11978 invoked by uid 500); 30 Mar 2012 03:16:33 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 11936 invoked by uid 500); 30 Mar 2012 03:16:33 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 11912 invoked by uid 99); 30 Mar 2012 03:16:32 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:16:32 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.8] (HELO aegis.apache.org) (140.211.11.8)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:16:26 +0000
+Received: from aegis.apache.org (localhost [127.0.0.1])
+	by aegis.apache.org (Postfix) with ESMTP id 3E8CBC00A0
+	for <dev@sling.apache.org>; Fri, 30 Mar 2012 03:16:05 +0000 (UTC)
+Date: Fri, 30 Mar 2012 03:16:05 +0000 (UTC)
+From: Apache Jenkins Server <jenkins@builds.apache.org>
+To: dev@sling.apache.org
+Message-ID: <1937985321.105.1333077365240.JavaMail.hudson@aegis>
+In-Reply-To: <1953604574.1290.1332996985382.JavaMail.hudson@aegis>
+References: <1953604574.1290.1332996985382.JavaMail.hudson@aegis>
+Subject: Build failed in Jenkins: sling-samples-1.5 #298
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+X-Jenkins-Job: sling-samples-1.5
+X-Jenkins-Result: FAILURE
+
+See <https://builds.apache.org/job/sling-samples-1.5/298/>
+
+------------------------------------------
+[...truncated 946 lines...]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling User Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] artifact net.alchim31.maven:yuicompressor-maven-plugin: checking for updates from oss.sonatype.org
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 28 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Compiling 1 source file to <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/classes>
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Access Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 14 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Nothing to compile - all classes are up to date
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[WARNING] Warning building bundle org.apache.sling.samples:org.apache.sling.samples.accessmanager.ui:bundle:0.9-SNAPSHOT : Did not find matching referal for *
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Samples (Builder)
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$sling-samples-builder/builds/2012-03-30_03-13-42/archive/org.apache.sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[INFO] 
+[INFO] 
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Apache Sling ESP blog sample .......................... SUCCESS [20.231s]
+[INFO] Apache Sling Javashell sample ......................... SUCCESS [3.668s]
+[INFO] Apache Sling Sample Path Based Resource Type Provider . SUCCESS [12.550s]
+[INFO] Apache Sling Sample Post Servlet Extensions ........... SUCCESS [5.441s]
+[INFO] Apache Sling Sample Application ....................... SUCCESS [8.255s]
+[INFO] Apache Sling - Slingshot Demo ......................... SUCCESS [5.227s]
+[INFO] Apache Sling Webloader Service ........................ SUCCESS [3.886s]
+[INFO] Apache Sling Webloader User Interface ................. SUCCESS [3.669s]
+[INFO] Apache Sling Sample Custom Login Form ................. SUCCESS [4.275s]
+[INFO] Apache Sling Slingbucks - sample coffee store management application  SUCCESS [4.470s]
+[INFO] Dependency Install Sample ............................. SUCCESS [3.199s]
+[INFO] Apache Sling Sample Framework Fragment Bundle ......... SUCCESS [7.564s]
+[INFO] Apache Sling User Manager UI sample ................... SUCCESS [5.916s]
+[INFO] Apache Sling Access Manager UI sample ................. SUCCESS [3.523s]
+[INFO] Apache Sling Samples (Builder) ........................ SUCCESS [1.059s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 1 minute 50 seconds
+[INFO] Finished at: Fri Mar 30 03:16:02 UTC 2012
+[INFO] Final Memory: 71M/106M
+[INFO] ------------------------------------------------------------------------
+channel stopped
+[locks-and-latches] Releasing all the locks
+[locks-and-latches] All the locks released
+Maven RedeployPublished use remote ubuntu1 maven settings from : /home/jenkins/.m2/settings.xml
+[INFO] Deployment in https://repository.apache.org/content/repositories/snapshots/ (id=,uniqueVersion=false)
+Deploying the main artifact installing-dependencies-sample-0.0.1-SNAPSHOT.jar
+ERROR: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+org.apache.maven.artifact.deployer.ArtifactDeploymentException: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:175)
+	at hudson.maven.reporters.MavenArtifactRecord.deploy(MavenArtifactRecord.java:182)
+	at hudson.maven.RedeployPublisher.perform(RedeployPublisher.java:176)
+	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:19)
+	at hudson.model.AbstractBuild$AbstractRunner.perform(AbstractBuild.java:703)
+	at hudson.model.AbstractBuild$AbstractRunner.performAllBuildSteps(AbstractBuild.java:678)
+	at hudson.maven.MavenModuleSetBuild$RunnerImpl.post2(MavenModuleSetBuild.java:998)
+	at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:625)
+	at hudson.model.Run.run(Run.java:1435)
+	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:481)
+	at hudson.model.ResourceController.execute(ResourceController.java:88)
+	at hudson.model.Executor.run(Executor.java:238)
+Caused by: org.apache.maven.wagon.TransferFailedException: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:562)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:471)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:451)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putRemoteFile(DefaultWagonManager.java:543)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putArtifact(DefaultWagonManager.java:494)
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:160)
+	... 11 more
+[INFO] Deployment failed after 1.4 sec
+Build step 'Deploy artifacts to Maven repository' changed build result to FAILURE
+
+From dev-return-26294-apmail-sling-dev-archive=sling.apache.org@sling.apache.org  Fri Mar 30 03:32:18 2012
+Return-Path: <dev-return-26294-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id ADDBD923A
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 03:32:18 +0000 (UTC)
+Received: (qmail 37670 invoked by uid 500); 30 Mar 2012 03:32:18 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 37379 invoked by uid 500); 30 Mar 2012 03:32:15 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 37347 invoked by uid 99); 30 Mar 2012 03:32:14 -0000
+Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:32:14 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.8] (HELO aegis.apache.org) (140.211.11.8)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:32:11 +0000
+Received: from aegis.apache.org (localhost [127.0.0.1])
+	by aegis.apache.org (Postfix) with ESMTP id C4FF1C00A0
+	for <dev@sling.apache.org>; Fri, 30 Mar 2012 03:31:51 +0000 (UTC)
+Date: Fri, 30 Mar 2012 03:31:51 +0000 (UTC)
+From: Apache Jenkins Server <jenkins@builds.apache.org>
+To: dev@sling.apache.org
+Message-ID: <247422794.107.1333078311766.JavaMail.hudson@aegis>
+In-Reply-To: <1042696744.1289.1332996773813.JavaMail.hudson@aegis>
+References: <1042696744.1289.1332996773813.JavaMail.hudson@aegis>
+Subject: Build failed in Jenkins: sling-contrib-1.5 #848
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+X-Jenkins-Job: sling-contrib-1.5
+X-Jenkins-Result: FAILURE
+X-Virus-Checked: Checked by ClamAV on apache.org
+
+See <https://builds.apache.org/job/sling-contrib-1.5/848/>
+
+------------------------------------------
+[...truncated 3070 lines...]
+[INFO] Copying bundle from /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/org.apache.sling.scripting.xproc/2.0.0-SNAPSHOT/org.apache.sling.scripting.xproc-2.0.0-SNAPSHOT.jar to <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/launchpad-bundles/resources/bundles/15/org.apache.sling.scripting.xproc-2.0.0-SNAPSHOT.jar>
+[INFO] snapshot org.apache.sling:org.apache.sling.extensions.apt.servlet:2.0.3-SNAPSHOT: checking for updates from apache.snapshots
+[INFO] Copying bundle from /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/org.apache.sling.extensions.apt.servlet/2.0.3-SNAPSHOT/org.apache.sling.extensions.apt.servlet-2.0.3-SNAPSHOT.jar to <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/launchpad-bundles/resources/bundles/15/org.apache.sling.extensions.apt.servlet-2.0.3-SNAPSHOT.jar>
+[INFO] snapshot org.apache.sling:org.apache.sling.extensions.apt.parser:2.0.3-SNAPSHOT: checking for updates from apache.snapshots
+[INFO] Copying bundle from /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/org.apache.sling.extensions.apt.parser/2.0.3-SNAPSHOT/org.apache.sling.extensions.apt.parser-2.0.3-SNAPSHOT.jar to <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/launchpad-bundles/resources/bundles/15/org.apache.sling.extensions.apt.parser-2.0.3-SNAPSHOT.jar>
+[INFO] snapshot org.apache.sling.samples:org.apache.sling.samples.path-based.rtp:2.0.5-SNAPSHOT: checking for updates from apache.snapshots
+Downloading: http://repository.apache.org/snapshots/org/apache/sling/samples/org.apache.sling.samples.path-based.rtp/2.0.5-SNAPSHOT/org.apache.sling.samples.path-based.rtp-2.0.5-SNAPSHOT.jar
+[INFO] Copying bundle from /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/samples/org.apache.sling.samples.path-based.rtp/2.0.5-SNAPSHOT/org.apache.sling.samples.path-based.rtp-2.0.5-SNAPSHOT.jar to <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/launchpad-bundles/resources/bundles/15/org.apache.sling.samples.path-based.rtp-2.0.5-SNAPSHOT.jar>
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 0 resource
+[INFO] Copying 3 resources
+[INFO] [build-helper:reserve-network-port {execution: reserve-network-port}]
+[INFO] Reserved port 51931 for http.port
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] No sources to compile
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 50 resources
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] Compiling 7 source files to <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/test-classes>
+[WARNING] DEPRECATED [systemProperties]: Use systemPropertyVariables instead.
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [war:war {execution: default-war}]
+[INFO] Packaging webapp
+[INFO] Assembling webapp [org.apache.sling.launchpad.contrib-testing] in [<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT]>
+[INFO] Processing war project
+[INFO] Copying webapp webResources [<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/launchpad-bundles]> to [<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT]>
+[INFO] Copying webapp webResources [<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing]> to [<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT]>
+[INFO] Processing overlay [ id org.apache.sling:org.apache.sling.launchpad.base:webapp]
+[INFO] Webapp assembled in [382 msecs]
+[INFO] Building war: <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war>
+[INFO] WEB-INF/web.xml already added, skipping
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/pom.xml> to /home/hudson/hudson/jobs/sling-contrib-1.5/modules/org.apache.sling$org.apache.sling.launchpad.contrib-testing/builds/2012-03-30_03-16-13/archive/org.apache.sling/org.apache.sling.launchpad.contrib-testing/4-SNAPSHOT/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war> to /home/hudson/hudson/jobs/sling-contrib-1.5/modules/org.apache.sling$org.apache.sling.launchpad.contrib-testing/builds/2012-03-30_03-16-13/archive/org.apache.sling/org.apache.sling.launchpad.contrib-testing/4-SNAPSHOT/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: delete-sling-folder}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] SLING-845 - delete parent sling folder before integration tests
+[INFO] Executed tasks
+[INFO] [cargo:start {execution: start-container}]
+[INFO] [beddedLocalContainer] Jetty 6.x Embedded starting...
+2012-03-30 03:31:02.343:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
+2012-03-30 03:31:02.390:INFO::jetty-6.1.26
+2012-03-30 03:31:02.492:INFO::Extract <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war> to /tmp/Jetty_0_0_0_0_51931_org.apache.sling.launchpad.contrib.testing.4.SNAPSHOT.war__org.apache.sling.launchpad.contrib.testing.4.SNAPSHOT__tnfk2g/webapp
+log4j:WARN No appenders could be found for logger (org.apache.jasper.compiler.JspRuntimeContext).
+log4j:WARN Please initialize the log4j system properly.
+2012-03-30 03:31:04.460:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Setting sling.home=<https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/sling/_org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT> (servlet context path)
+2012-03-30 03:31:04.462:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Checking launcher JAR in <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/sling/_org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT>
+2012-03-30 03:31:04.463:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Checking launcher JAR in folder <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/sling/_org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT>
+2012-03-30 03:31:04.466:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Installing new launcher: file:/tmp/Jetty_0_0_0_0_51931_org.apache.sling.launchpad.contrib.testing.4.SNAPSHOT.war__org.apache.sling.launchpad.contrib.testing.4.SNAPSHOT__tnfk2g/webapp/WEB-INF//resources/org.apache.sling.launchpad.base.jar, 2.3.1.SNAPSHOT, Last-Modified:Fri Mar 30 01:28:08 UTC 2012 (org.apache.sling.launchpad.base.jar.1333078264466)
+2012-03-30 03:31:04.466:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Loading launcher class org.apache.sling.launchpad.base.webapp.SlingServletDelegate from org.apache.sling.launchpad.base.jar.1333078264466
+2012-03-30 03:31:04.474:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Starting launcher ...
+2012-03-30 03:31:04.474:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Starting Apache Sling in <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/sling/_org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT>
+30.03.2012 03:31:05.793 *INFO* [FelixStartLevel] org.apache.sling.commons.logservice Service [org.apache.sling.commons.logservice.internal.LogServiceFactory,7] ServiceEvent REGISTERED
+30.03.2012 03:31:05.795 *INFO* [FelixStartLevel] org.apache.sling.commons.logservice Service [org.apache.sling.commons.logservice.internal.LogReaderServiceFactory,8] ServiceEvent REGISTERED
+30.03.2012 03:31:05.796 *INFO* [FelixDispatchQueue] org.apache.sling.commons.logservice BundleEvent STARTED
+30.03.2012 03:31:05.796 *INFO* [FelixDispatchQueue] jcl.over.slf4j BundleEvent RESOLVED
+30.03.2012 03:31:05.796 *INFO* [FelixDispatchQueue] jcl.over.slf4j BundleEvent STARTED
+30.03.2012 03:31:05.797 *INFO* [FelixDispatchQueue] log4j.over.slf4j BundleEvent RESOLVED
+30.03.2012 03:31:05.797 *INFO* [FelixDispatchQueue] log4j.over.slf4j BundleEvent STARTED
+*sys-package-mgr*: processing new jar, '/home/jenkins/jenkins-slave/maven-agent.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/jenkins-slave/classworlds.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/rt.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/jsse.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/jce.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/charsets.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/ext/sunjce_provider.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/ext/localedata.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/ext/sunpkcs11.jar'
+*sys-package-mgr*: processing new jar, '/home/jenkins/tools/java/jdk1.5.0_22-32/jre/lib/ext/dnsns.jar'
+2012-03-30 03:31:18.400:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Apache Sling successfully started in <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/sling/_org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT>
+2012-03-30 03:31:18.400:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Startup completed
+2012-03-30 03:31:18.400:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Servlet sling initialized
+2012-03-30 03:31:18.409:INFO::Extract <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/cargo/cargocpc.war> to /tmp/Jetty_0_0_0_0_51931_cargocpc.war__cargocpc__dmlwk0/webapp
+2012-03-30 03:31:18.447:INFO::Started SelectChannelConnector@0.0.0.0:51931
+[INFO] [beddedLocalContainer] Jetty 6.x Embedded started on port [51931]
+[WARNING] DEPRECATED [systemProperties]: Use systemPropertyVariables instead.
+[INFO] [surefire:test {execution: surefire-integration-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+Running org.apache.sling.launchpad.webapp.integrationtest.PathBasedResourceTypeTest
+Checking if the required Sling services are started (timeout 60 seconds)...
+(base URLs=http://localhost:51931/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT and http://localhost:51931/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT)
+Sling services seem to be started, continuing with integration tests.
+Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.907 sec
+Running org.apache.sling.launchpad.webapp.integrationtest.apt.SimpleAptRenderingTest
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.101 sec
+Running org.apache.sling.launchpad.webapp.integrationtest.SlingResourceTypeRenderingTest
+Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.701 sec
+Running org.apache.sling.launchpad.webapp.integrationtest.xproc.XsltTest
+<?xml version="1.0" encoding="UTF-8"?><no_xml jcr:primaryType="sling:Folder" jcr:created="2012-03-30T03:31:21.426Z" jcr:createdBy="admin" sling:resourceType="XsltTest1333078280622" title="no_xml" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:test2="test2=http://sling.apache.org/test/two" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ocm="http://jackrabbit.apache.org/ocm" xmlns:slingevent="http://sling.apache.org/jcr/event/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:test1="http://sling.apache.org/test/one" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:fn_old="http://www.w3.org/2004/10/xpath-functions" xmlns:rep="internal" xmlns:jcr="http://www.jcp.org/jcr/1.0"/>
+Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.905 sec
+Running org.apache.sling.launchpad.webapp.integrationtest.GetStarTest
+Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.086 sec
+Running org.apache.sling.launchpad.webapp.integrationtest.scala.ScalaScriptingTest
+Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 9.411 sec
+
+Results :
+
+Tests run: 15, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results
+[INFO] [cargo:stop {execution: stop-container}]
+[INFO] [beddedLocalContainer] Jetty 6.x Embedded is stopping...
+2012-03-30 03:31:31.854:INFO::Stopped SelectChannelConnector@0.0.0.0:51931
+[INFO] [beddedLocalContainer] Jetty 6.x Embedded is stopped
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war
+[INFO] Checking legal files in: org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war> to /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/org.apache.sling.launchpad.contrib-testing/4-SNAPSHOT/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT.war
+[INFO] Installing <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/org.apache.sling.launchpad.contrib-testing/4-SNAPSHOT/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar
+2012-03-30 03:31:32.395:INFO:/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT:sling: Apache Sling has been stopped
+[JENKINS] Archiving <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/launchpad/testing/target/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-contrib-1.5/modules/org.apache.sling$org.apache.sling.launchpad.contrib-testing/builds/2012-03-30_03-16-13/archive/org.apache.sling/org.apache.sling.launchpad.contrib-testing/4-SNAPSHOT/org.apache.sling.launchpad.contrib-testing-4-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Contrib (Builder)
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting file-set: <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5> (included: [derby.log, cachedir, sling], excluded: [])
+[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/pom.xml> to /home/jenkins/jenkins-slave/maven-repositories/1/org/apache/sling/sling-contrib-builder/2-SNAPSHOT/sling-contrib-builder-2-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-contrib-1.5/ws/contrib-1.5/pom.xml> to /home/hudson/hudson/jobs/sling-contrib-1.5/modules/org.apache.sling$sling-contrib-builder/builds/2012-03-30_03-16-11/archive/org.apache.sling/sling-contrib-builder/2-SNAPSHOT/sling-contrib-builder-2-SNAPSHOT.pom
+[INFO] 
+[INFO] 
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Apache Sling Commons Java Compiler .................... SUCCESS [59.688s]
+[INFO] Apache Sling Commons FileSystem ClassLoader ........... SUCCESS [4.147s]
+[INFO] Apache Sling Commons HTML Utilities ................... SUCCESS [5.178s]
+[INFO] Apache Sling APT parser ............................... SUCCESS [7.445s]
+[INFO] Apache Sling APT servlet .............................. SUCCESS [4.749s]
+[INFO] Apache Sling Dojo JavaScript Library .................. SUCCESS [1:40.633s]
+[INFO] Apache Sling Dojo Data Extension ...................... SUCCESS [3.448s]
+[INFO] Apache Sling Google Web Toolkit Servlet Library ....... SUCCESS [18.886s]
+[INFO] Apache Sling Google Web Toolkit Sample ................ SUCCESS [40.530s]
+[INFO] Apache Sling Internationalization Support ............. SUCCESS [16.934s]
+[INFO] Apache Sling OSGi Bundle Repository ................... SUCCESS [7.476s]
+[INFO] Apache Sling Rewriter ................................. SUCCESS [6.478s]
+[INFO] Apache Sling Repository Accessor ...................... SUCCESS [4.906s]
+[INFO] Apache Sling JCR Java Compiler ........................ SUCCESS [6.421s]
+[INFO] Apache Sling JCR Prefs ................................ SUCCESS [4.734s]
+[INFO] Apache Sling Atom Tag Library ......................... SUCCESS [6.238s]
+[INFO] Apache Sling Scripting Freemarker Support ............. SUCCESS [17.565s]
+[INFO] Apache Sling Scripting Java Support ................... SUCCESS [7.565s]
+[INFO] Apache Sling Scripting JST Support .................... SUCCESS [12.278s]
+[INFO] Apache Sling Scripting Python Support ................. SUCCESS [10.852s]
+[INFO] Apache Sling Scripting Ruby Support ................... SUCCESS [46.809s]
+[INFO] Scala Script Engine ................................... SUCCESS [53.394s]
+[INFO] Apache Sling Scala Scripting Configuration ............ SUCCESS [6.993s]
+[INFO] Scala for Sling Demo Application - Hello World ........ SUCCESS [3.356s]
+[INFO] Scala for Sling Demo Application - Forum .............. SUCCESS [3.976s]
+[INFO] Apache Sling Scripting Velocity Support ............... SUCCESS [8.876s]
+[INFO] Apache Sling Scripting W3C XML Processing Support ..... SUCCESS [6.998s]
+[INFO] Apache Sling Features for ServiceMix Kernel ........... SUCCESS [4.221s]
+[INFO] Apache Sling Launchpad Contrib Testing ................ SUCCESS [6:18.119s]
+[INFO] Apache Sling Contrib (Builder) ........................ SUCCESS [10.625s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 15 minutes 6 seconds
+[INFO] Finished at: Fri Mar 30 03:31:46 UTC 2012
+[INFO] Final Memory: 107M/184M
+[INFO] ------------------------------------------------------------------------
+channel stopped
+2012-03-30 03:31:48.216:INFO::Shutdown hook executing
+2012-03-30 03:31:48.217:INFO::Shutdown hook complete
+[locks-and-latches] Releasing all the locks
+[locks-and-latches] All the locks released
+Maven RedeployPublished use remote ubuntu1 maven settings from : /home/jenkins/.m2/settings.xml
+[INFO] Deployment in https://repository.apache.org/content/repositories/snapshots/ (id=,uniqueVersion=false)
+Deploying the main artifact org.apache.sling.atom.taglib-0.9.0-SNAPSHOT.jar
+ERROR: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/org.apache.sling.atom.taglib/0.9.0-SNAPSHOT/org.apache.sling.atom.taglib-0.9.0-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+org.apache.maven.artifact.deployer.ArtifactDeploymentException: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/org.apache.sling.atom.taglib/0.9.0-SNAPSHOT/org.apache.sling.atom.taglib-0.9.0-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:175)
+	at hudson.maven.reporters.MavenArtifactRecord.deploy(MavenArtifactRecord.java:182)
+	at hudson.maven.RedeployPublisher.perform(RedeployPublisher.java:176)
+	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:19)
+	at hudson.model.AbstractBuild$AbstractRunner.perform(AbstractBuild.java:703)
+	at hudson.model.AbstractBuild$AbstractRunner.performAllBuildSteps(AbstractBuild.java:678)
+	at hudson.maven.MavenModuleSetBuild$RunnerImpl.post2(MavenModuleSetBuild.java:998)
+	at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:625)
+	at hudson.model.Run.run(Run.java:1435)
+	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:481)
+	at hudson.model.ResourceController.execute(ResourceController.java:88)
+	at hudson.model.Executor.run(Executor.java:238)
+Caused by: org.apache.maven.wagon.TransferFailedException: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/org.apache.sling.atom.taglib/0.9.0-SNAPSHOT/org.apache.sling.atom.taglib-0.9.0-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:562)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:471)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:451)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putRemoteFile(DefaultWagonManager.java:543)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putArtifact(DefaultWagonManager.java:494)
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:160)
+	... 11 more
+[INFO] Deployment failed after 0.9 sec
+Build step 'Deploy artifacts to Maven repository' changed build result to FAILURE
+
diff --git a/mail-archive/server/test_files/wrongbody.txt b/mail-archive/server/test_files/wrongbody.txt
new file mode 100644
index 0000000..732c647
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody.txt
@@ -0,0 +1,294 @@
+Return-Path: <dev-return-26293-apmail-sling-dev-archive=sling.apache.org@sling.apache.org>
+X-Original-To: apmail-sling-dev-archive@www.apache.org
+Delivered-To: apmail-sling-dev-archive@www.apache.org
+Received: from mail.apache.org (hermes.apache.org [140.211.11.3])
+	by minotaur.apache.org (Postfix) with SMTP id C03AA926F
+	for <apmail-sling-dev-archive@www.apache.org>; Fri, 30 Mar 2012 03:16:33 +0000 (UTC)
+Received: (qmail 11978 invoked by uid 500); 30 Mar 2012 03:16:33 -0000
+Delivered-To: apmail-sling-dev-archive@sling.apache.org
+Received: (qmail 11936 invoked by uid 500); 30 Mar 2012 03:16:33 -0000
+Mailing-List: contact dev-help@sling.apache.org; run by ezmlm
+Precedence: bulk
+List-Help: <mailto:dev-help@sling.apache.org>
+List-Unsubscribe: <mailto:dev-unsubscribe@sling.apache.org>
+List-Post: <mailto:dev@sling.apache.org>
+List-Id: <dev.sling.apache.org>
+Reply-To: dev@sling.apache.org
+Delivered-To: mailing list dev@sling.apache.org
+Received: (qmail 11912 invoked by uid 99); 30 Mar 2012 03:16:32 -0000
+Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:16:32 +0000
+X-ASF-Spam-Status: No, hits=-2000.0 required=5.0
+	tests=ALL_TRUSTED
+X-Spam-Check-By: apache.org
+Received: from [140.211.11.8] (HELO aegis.apache.org) (140.211.11.8)
+    by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 Mar 2012 03:16:26 +0000
+Received: from aegis.apache.org (localhost [127.0.0.1])
+	by aegis.apache.org (Postfix) with ESMTP id 3E8CBC00A0
+	for <dev@sling.apache.org>; Fri, 30 Mar 2012 03:16:05 +0000 (UTC)
+Date: Fri, 30 Mar 2012 03:16:05 +0000 (UTC)
+From: Apache Jenkins Server <jenkins@builds.apache.org>
+To: dev@sling.apache.org
+Message-ID: <1937985321.105.1333077365240.JavaMail.hudson@aegis>
+In-Reply-To: <1953604574.1290.1332996985382.JavaMail.hudson@aegis>
+References: <1953604574.1290.1332996985382.JavaMail.hudson@aegis>
+Subject: Build failed in Jenkins: sling-samples-1.5 #298
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 7bit
+X-Jenkins-Job: sling-samples-1.5
+X-Jenkins-Result: FAILURE
+
+See <https://builds.apache.org/job/sling-samples-1.5/298/>
+
+------------------------------------------
+[...truncated 946 lines...]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling User Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] artifact net.alchim31.maven:yuicompressor-maven-plugin: checking for updates from oss.sonatype.org
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 28 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Compiling 1 source file to <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/classes>
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Access Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 14 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Nothing to compile - all classes are up to date
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[WARNING] Warning building bundle org.apache.sling.samples:org.apache.sling.samples.accessmanager.ui:bundle:0.9-SNAPSHOT : Did not find matching referal for *
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Samples (Builder)
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$sling-samples-builder/builds/2012-03-30_03-13-42/archive/org.apache.sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[INFO] 
+[INFO] 
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Apache Sling ESP blog sample .......................... SUCCESS [20.231s]
+[INFO] Apache Sling Javashell sample ......................... SUCCESS [3.668s]
+[INFO] Apache Sling Sample Path Based Resource Type Provider . SUCCESS [12.550s]
+[INFO] Apache Sling Sample Post Servlet Extensions ........... SUCCESS [5.441s]
+[INFO] Apache Sling Sample Application ....................... SUCCESS [8.255s]
+[INFO] Apache Sling - Slingshot Demo ......................... SUCCESS [5.227s]
+[INFO] Apache Sling Webloader Service ........................ SUCCESS [3.886s]
+[INFO] Apache Sling Webloader User Interface ................. SUCCESS [3.669s]
+[INFO] Apache Sling Sample Custom Login Form ................. SUCCESS [4.275s]
+[INFO] Apache Sling Slingbucks - sample coffee store management application  SUCCESS [4.470s]
+[INFO] Dependency Install Sample ............................. SUCCESS [3.199s]
+[INFO] Apache Sling Sample Framework Fragment Bundle ......... SUCCESS [7.564s]
+[INFO] Apache Sling User Manager UI sample ................... SUCCESS [5.916s]
+[INFO] Apache Sling Access Manager UI sample ................. SUCCESS [3.523s]
+[INFO] Apache Sling Samples (Builder) ........................ SUCCESS [1.059s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 1 minute 50 seconds
+[INFO] Finished at: Fri Mar 30 03:16:02 UTC 2012
+[INFO] Final Memory: 71M/106M
+[INFO] ------------------------------------------------------------------------
+channel stopped
+[locks-and-latches] Releasing all the locks
+[locks-and-latches] All the locks released
+Maven RedeployPublished use remote ubuntu1 maven settings from : /home/jenkins/.m2/settings.xml
+[INFO] Deployment in https://repository.apache.org/content/repositories/snapshots/ (id=,uniqueVersion=false)
+Deploying the main artifact installing-dependencies-sample-0.0.1-SNAPSHOT.jar
+ERROR: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+org.apache.maven.artifact.deployer.ArtifactDeploymentException: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:175)
+	at hudson.maven.reporters.MavenArtifactRecord.deploy(MavenArtifactRecord.java:182)
+	at hudson.maven.RedeployPublisher.perform(RedeployPublisher.java:176)
+	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:19)
+	at hudson.model.AbstractBuild$AbstractRunner.perform(AbstractBuild.java:703)
+	at hudson.model.AbstractBuild$AbstractRunner.performAllBuildSteps(AbstractBuild.java:678)
+	at hudson.maven.MavenModuleSetBuild$RunnerImpl.post2(MavenModuleSetBuild.java:998)
+	at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:625)
+	at hudson.model.Run.run(Run.java:1435)
+	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:481)
+	at hudson.model.ResourceController.execute(ResourceController.java:88)
+	at hudson.model.Executor.run(Executor.java:238)
+Caused by: org.apache.maven.wagon.TransferFailedException: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:562)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:471)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:451)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putRemoteFile(DefaultWagonManager.java:543)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putArtifact(DefaultWagonManager.java:494)
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:160)
+	... 11 more
+[INFO] Deployment failed after 1.4 sec
+Build step 'Deploy artifacts to Maven repository' changed build result to FAILURE
diff --git a/mail-archive/server/test_files/wrongbody_body.txt b/mail-archive/server/test_files/wrongbody_body.txt
new file mode 100644
index 0000000..411c5ba
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody_body.txt
@@ -0,0 +1,254 @@
+See <https://builds.apache.org/job/sling-samples-1.5/298/>
+
+------------------------------------------
+[...truncated 946 lines...]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling User Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] artifact net.alchim31.maven:yuicompressor-maven-plugin: checking for updates from oss.sonatype.org
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 28 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Compiling 1 source file to <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/classes>
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Access Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 14 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Nothing to compile - all classes are up to date
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[WARNING] Warning building bundle org.apache.sling.samples:org.apache.sling.samples.accessmanager.ui:bundle:0.9-SNAPSHOT : Did not find matching referal for *
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Samples (Builder)
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$sling-samples-builder/builds/2012-03-30_03-13-42/archive/org.apache.sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[INFO] 
+[INFO] 
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Apache Sling ESP blog sample .......................... SUCCESS [20.231s]
+[INFO] Apache Sling Javashell sample ......................... SUCCESS [3.668s]
+[INFO] Apache Sling Sample Path Based Resource Type Provider . SUCCESS [12.550s]
+[INFO] Apache Sling Sample Post Servlet Extensions ........... SUCCESS [5.441s]
+[INFO] Apache Sling Sample Application ....................... SUCCESS [8.255s]
+[INFO] Apache Sling - Slingshot Demo ......................... SUCCESS [5.227s]
+[INFO] Apache Sling Webloader Service ........................ SUCCESS [3.886s]
+[INFO] Apache Sling Webloader User Interface ................. SUCCESS [3.669s]
+[INFO] Apache Sling Sample Custom Login Form ................. SUCCESS [4.275s]
+[INFO] Apache Sling Slingbucks - sample coffee store management application  SUCCESS [4.470s]
+[INFO] Dependency Install Sample ............................. SUCCESS [3.199s]
+[INFO] Apache Sling Sample Framework Fragment Bundle ......... SUCCESS [7.564s]
+[INFO] Apache Sling User Manager UI sample ................... SUCCESS [5.916s]
+[INFO] Apache Sling Access Manager UI sample ................. SUCCESS [3.523s]
+[INFO] Apache Sling Samples (Builder) ........................ SUCCESS [1.059s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 1 minute 50 seconds
+[INFO] Finished at: Fri Mar 30 03:16:02 UTC 2012
+[INFO] Final Memory: 71M/106M
+[INFO] ------------------------------------------------------------------------
+channel stopped
+[locks-and-latches] Releasing all the locks
+[locks-and-latches] All the locks released
+Maven RedeployPublished use remote ubuntu1 maven settings from : /home/jenkins/.m2/settings.xml
+[INFO] Deployment in https://repository.apache.org/content/repositories/snapshots/ (id=,uniqueVersion=false)
+Deploying the main artifact installing-dependencies-sample-0.0.1-SNAPSHOT.jar
+ERROR: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+org.apache.maven.artifact.deployer.ArtifactDeploymentException: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:175)
+	at hudson.maven.reporters.MavenArtifactRecord.deploy(MavenArtifactRecord.java:182)
+	at hudson.maven.RedeployPublisher.perform(RedeployPublisher.java:176)
+	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:19)
+	at hudson.model.AbstractBuild$AbstractRunner.perform(AbstractBuild.java:703)
+	at hudson.model.AbstractBuild$AbstractRunner.performAllBuildSteps(AbstractBuild.java:678)
+	at hudson.maven.MavenModuleSetBuild$RunnerImpl.post2(MavenModuleSetBuild.java:998)
+	at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:625)
+	at hudson.model.Run.run(Run.java:1435)
+	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:481)
+	at hudson.model.ResourceController.execute(ResourceController.java:88)
+	at hudson.model.Executor.run(Executor.java:238)
+Caused by: org.apache.maven.wagon.TransferFailedException: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:562)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:471)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:451)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putRemoteFile(DefaultWagonManager.java:543)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putArtifact(DefaultWagonManager.java:494)
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:160)
+	... 11 more
+[INFO] Deployment failed after 1.4 sec
+Build step 'Deploy artifacts to Maven repository' changed build result to FAILURE
+
diff --git a/mail-archive/server/test_files/wrongbody_bodyOf1.txt b/mail-archive/server/test_files/wrongbody_bodyOf1.txt
new file mode 100644
index 0000000..7d3f3b1
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody_bodyOf1.txt
@@ -0,0 +1,36 @@
+
+    [ https://issues.apache.org/jira/browse/SLING-2311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13241609#comment-13241609 ] 
+
+Carsten Ziegeler commented on SLING-2311:
+-----------------------------------------
+
+Great stuff - I think we should definitely have something like this, not sure whether we should start a new module or add it to commons testing or could just test
+junit-perf for this?
+                
+> Sling Performance Testing tool
+> ------------------------------
+>
+>                 Key: SLING-2311
+>                 URL: https://issues.apache.org/jira/browse/SLING-2311
+>             Project: Sling
+>          Issue Type: New Feature
+>          Components: Testing
+>            Reporter: Antonio Sanso
+>            Assignee: Carsten Ziegeler
+>            Priority: Minor
+>         Attachments: ResolveWithManyAliasTest.java, SLING-2311-patch.txt
+>
+>
+> As described/discussed in [0] it would be nice to have a performance test tool in Sling .
+> This can be useful in different situations (e.g. micro benchmarks of a feature and so on).
+> Patch to follow
+> [0] http://sling.markmail.org/message/bz44im7aqeae4r57
+
+--
+This message is automatically generated by JIRA.
+If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
+For more information on JIRA, see: http://www.atlassian.com/software/jira
+
+        
+
+
diff --git a/mail-archive/server/test_files/wrongbody_bodyOf4.txt b/mail-archive/server/test_files/wrongbody_bodyOf4.txt
new file mode 100644
index 0000000..fd10301
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody_bodyOf4.txt
@@ -0,0 +1,4 @@
+See <https://builds.apache.org/job/sling-trunk-1.6/1288/changes>
+
+
+
diff --git a/mail-archive/server/test_files/wrongbody_bodyOf5.txt b/mail-archive/server/test_files/wrongbody_bodyOf5.txt
new file mode 100644
index 0000000..e4e7fd8
--- /dev/null
+++ b/mail-archive/server/test_files/wrongbody_bodyOf5.txt
@@ -0,0 +1,255 @@
+See <https://builds.apache.org/job/sling-samples-1.5/298/>
+
+------------------------------------------
+[...truncated 946 lines...]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/framework-fragment/target/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$org.apache.sling.samples.frameworkfragment/builds/2012-03-30_03-13-43/archive/org.apache.sling/org.apache.sling.samples.frameworkfragment/0.9.9-SNAPSHOT/org.apache.sling.samples.frameworkfragment-0.9.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling User Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] artifact net.alchim31.maven:yuicompressor-maven-plugin: checking for updates from oss.sonatype.org
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 28 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/js/usermanager/usermanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/main/resources/css/usermanager/usermanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Compiling 1 source file to <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/classes>
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/usermanager-ui/target/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.usermanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.usermanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.usermanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Access Manager UI sample
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] Deleting <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target>
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [remote-resources:process {execution: default}]
+[INFO] [resources:resources {execution: default-resources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] Copying 14 resources
+[INFO] Copying 3 resources
+[WARNING] DEPRECATED [tasks]: Use target instead
+[INFO] [antrun:run {execution: default}]
+[WARNING] Parameter tasks is deprecated, use target instead
+[INFO] Executing tasks
+
+main:
+     [echo] **************** WARNING (SLING-443/SLING-1782) ******************************
+     [echo] On most platforms, you'll get OutOfMemoryErrors when building unless you set
+     [echo] on 32bit platforms: MAVEN_OPTS="-Xmx256M -XX:MaxPermSize=256M", see SLING-443
+     [echo] on 64bit platforms: MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M", see SLING-1782
+     [echo] ******************************************************************************
+[INFO] Executed tasks
+[INFO] [yuicompressor:compress {execution: default}]
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/js/accessmanager/accessmanager.min.js> is younger than original, use 'force' option or clean your target
+[INFO] nothing to do, <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/main/resources/css/accessmanager/accessmanager.min.css> is younger than original, use 'force' option or clean your target
+[INFO] nb warnings: 0, nb errors: 0
+[INFO] [compiler:compile {execution: default-compile}]
+[INFO] Nothing to compile - all classes are up to date
+[INFO] [scr:scr {execution: generate-scr-scrdescriptor}]
+[INFO] [resources:testResources {execution: default-testResources}]
+[INFO] Using 'UTF-8' encoding to copy filtered resources.
+[INFO] skip non existing resourceDirectory <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/src/test/resources>
+[INFO] Copying 3 resources
+[INFO] [compiler:testCompile {execution: default-testCompile}]
+[INFO] No sources to compile
+[INFO] [surefire:test {execution: default-test}]
+[INFO] Surefire report directory: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/surefire-reports>
+
+-------------------------------------------------------
+ T E S T S
+-------------------------------------------------------
+There are no tests to run.
+
+Results :
+
+Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
+
+[JENKINS] Recording test results[INFO] [animal-sniffer:check {execution: default}]
+[INFO] Checking unresolved references to org.codehaus.mojo.signature:java15:1.0
+
+[INFO] [bundle:bundle {execution: default-bundle}]
+[WARNING] Warning building bundle org.apache.sling.samples:org.apache.sling.samples.accessmanager.ui:bundle:0.9-SNAPSHOT : Did not find matching referal for *
+[INFO] Preparing source:jar
+[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] [enforcer:enforce {execution: enforce-java}]
+[INFO] [source:jar {execution: attach-sources}]
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] Building jar: <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar>
+[INFO] META-INF already added, skipping
+[INFO] META-INF/LICENSE already added, skipping
+[INFO] META-INF/NOTICE already added, skipping
+[INFO] META-INF/DEPENDENCIES already added, skipping
+[INFO] [ianal:verify-legal-files {execution: default}]
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Checking legal files in: org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT.jar
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] [bundle:install {execution: default-install}]
+[INFO] Local OBR update disabled (enable with -DobrRepository)
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/accessmanager-ui/target/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling.samples$org.apache.sling.samples.accessmanager.ui/builds/2012-03-30_03-13-43/archive/org.apache.sling.samples/org.apache.sling.samples.accessmanager.ui/0.9-SNAPSHOT/org.apache.sling.samples.accessmanager.ui-0.9-SNAPSHOT-sources.jar
+[INFO] ------------------------------------------------------------------------
+[INFO] Building Apache Sling Samples (Builder)
+[INFO]    task-segment: [clean, install]
+[INFO] ------------------------------------------------------------------------
+[INFO] [clean:clean {execution: default-clean}]
+[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
+[INFO] [install:install {execution: default-install}]
+[INFO] Installing <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/jenkins/jenkins-slave/maven-repositories/0/org/apache/sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[JENKINS] Archiving <https://builds.apache.org/job/sling-samples-1.5/ws/contrib-1.5/pom.xml> to /home/hudson/hudson/jobs/sling-samples-1.5/modules/org.apache.sling$sling-samples-builder/builds/2012-03-30_03-13-42/archive/org.apache.sling/sling-samples-builder/2-SNAPSHOT/sling-samples-builder-2-SNAPSHOT.pom
+[INFO] 
+[INFO] 
+[INFO] ------------------------------------------------------------------------
+[INFO] Reactor Summary:
+[INFO] ------------------------------------------------------------------------
+[INFO] Apache Sling ESP blog sample .......................... SUCCESS [20.231s]
+[INFO] Apache Sling Javashell sample ......................... SUCCESS [3.668s]
+[INFO] Apache Sling Sample Path Based Resource Type Provider . SUCCESS [12.550s]
+[INFO] Apache Sling Sample Post Servlet Extensions ........... SUCCESS [5.441s]
+[INFO] Apache Sling Sample Application ....................... SUCCESS [8.255s]
+[INFO] Apache Sling - Slingshot Demo ......................... SUCCESS [5.227s]
+[INFO] Apache Sling Webloader Service ........................ SUCCESS [3.886s]
+[INFO] Apache Sling Webloader User Interface ................. SUCCESS [3.669s]
+[INFO] Apache Sling Sample Custom Login Form ................. SUCCESS [4.275s]
+[INFO] Apache Sling Slingbucks - sample coffee store management application  SUCCESS [4.470s]
+[INFO] Dependency Install Sample ............................. SUCCESS [3.199s]
+[INFO] Apache Sling Sample Framework Fragment Bundle ......... SUCCESS [7.564s]
+[INFO] Apache Sling User Manager UI sample ................... SUCCESS [5.916s]
+[INFO] Apache Sling Access Manager UI sample ................. SUCCESS [3.523s]
+[INFO] Apache Sling Samples (Builder) ........................ SUCCESS [1.059s]
+[INFO] ------------------------------------------------------------------------
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESSFUL
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time: 1 minute 50 seconds
+[INFO] Finished at: Fri Mar 30 03:16:02 UTC 2012
+[INFO] Final Memory: 71M/106M
+[INFO] ------------------------------------------------------------------------
+channel stopped
+[locks-and-latches] Releasing all the locks
+[locks-and-latches] All the locks released
+Maven RedeployPublished use remote ubuntu1 maven settings from : /home/jenkins/.m2/settings.xml
+[INFO] Deployment in https://repository.apache.org/content/repositories/snapshots/ (id=,uniqueVersion=false)
+Deploying the main artifact installing-dependencies-sample-0.0.1-SNAPSHOT.jar
+ERROR: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+org.apache.maven.artifact.deployer.ArtifactDeploymentException: Error deploying artifact: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:175)
+	at hudson.maven.reporters.MavenArtifactRecord.deploy(MavenArtifactRecord.java:182)
+	at hudson.maven.RedeployPublisher.perform(RedeployPublisher.java:176)
+	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:19)
+	at hudson.model.AbstractBuild$AbstractRunner.perform(AbstractBuild.java:703)
+	at hudson.model.AbstractBuild$AbstractRunner.performAllBuildSteps(AbstractBuild.java:678)
+	at hudson.maven.MavenModuleSetBuild$RunnerImpl.post2(MavenModuleSetBuild.java:998)
+	at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:625)
+	at hudson.model.Run.run(Run.java:1435)
+	at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:481)
+	at hudson.model.ResourceController.execute(ResourceController.java:88)
+	at hudson.model.Executor.run(Executor.java:238)
+Caused by: org.apache.maven.wagon.TransferFailedException: Failed to transfer file: https://repository.apache.org/content/repositories/snapshots/org/apache/sling/installing-dependencies-sample/0.0.1-SNAPSHOT/installing-dependencies-sample-0.0.1-SNAPSHOT.jar. Return code is: 401, ReasonPhrase:Unauthorized.
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:562)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:471)
+	at org.apache.maven.wagon.shared.http4.AbstractHttpClientWagon.put(AbstractHttpClientWagon.java:451)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putRemoteFile(DefaultWagonManager.java:543)
+	at org.apache.maven.repository.legacy.DefaultWagonManager.putArtifact(DefaultWagonManager.java:494)
+	at hudson.maven.artifact.deployer.DefaultArtifactDeployer.deploy(DefaultArtifactDeployer.java:160)
+	... 11 more
+[INFO] Deployment failed after 1.4 sec
+Build step 'Deploy artifacts to Maven repository' changed build result to FAILURE
+
+
diff --git a/mail-archive/ui/pom.xml b/mail-archive/ui/pom.xml
new file mode 100644
index 0000000..dedb453
--- /dev/null
+++ b/mail-archive/ui/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>18</version>
+    </parent>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.mailarchive.ui</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+    <name>Apache Sling Mail Archive Server UI</name>
+    <description>User interface for Mail Archive Server.</description>
+
+    <properties>
+        <sling.java.version>6</sling.java.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Sling-Initial-Content>
+							initial-content; uninstall:=true
+						</Sling-Initial-Content>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.mailarchive.server</artifactId>
+            <version>0.1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/archive/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/archive/html.esp
new file mode 100644
index 0000000..2a0d789
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/archive/html.esp
@@ -0,0 +1,59 @@
+<html>
+
+<head>
+<% load("../head.esp"); %>
+<title>Mail archive</title>
+</head>
+
+<body>
+
+<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>
+
+<div class="content">
+
+<table width="100%">
+<colgroup>
+<col style="width: 33%" />
+<col style="width: 33%" />
+<col style="width: 33%" />
+</colgroup>
+<%
+	var cnt = 0;
+	var archiveChildren = currentNode.getChildren();
+	for(i in archiveChildren) {
+		var domain = archiveChildren[i];
+%>
+
+	<td>
+	<div class="domain">
+		<h4><%= domain["jcr:text"] %>  lists:</h4>
+		<ul>
+<%
+		var domainChildren = domain.getChildren();
+		for(k in domainChildren) {
+			var list = domainChildren[k];
+%>
+			<li><a href="<%= list.getPath() %>.html">  <%= list["jcr:text"] %></a></li>
+<% 
+		}
+%>
+		</ul>
+	</div>
+	</td>
+
+<% 
+		if (cnt % 3 == 2)
+			out.print("</tr>");
+		cnt++;
+	}
+	if (cnt % 3 != 2)
+		out.print("</tr>");
+%>
+
+</table>
+</div>
+
+
+</body>
+
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/head.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/head.esp
new file mode 100644
index 0000000..d71f138
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/head.esp
@@ -0,0 +1,36 @@
+<link rel="stylesheet" href="/apps/mailarchiveserver/styles.css"/>
+<script type="text/javascript" src="/apps/mailarchiveserver/util.js"></script>
+<% 
+	var threadNodesNumber = 3
+
+	var startPage = "/mailarchiveserver/archive.html"
+	var homePage = "/mailarchiveserver.html?noredirect"
+
+	function dateComparator (a, b) {
+	if (a.date > b.date)
+		return 1;
+	else if (a.date < b.date)
+		return -1;
+	else
+		return 0;
+	}
+
+	function OrderedRenderer (comparator, renderOptions) {
+		this.list = []
+		this.addMsg = function (msg) {
+			var obj = new Object();
+			obj.path = msg.getPath();
+			obj.date = new Date(msg["Date"]);
+			this.list.push(obj);
+		}
+		this.sort = function () {
+			this.list.sort(comparator);
+		}
+		this.render = function () {
+			while (this.list.length > 0) {
+				 sling.include(this.list.pop().path, renderOptions); 
+			}
+		}
+	}
+	
+%>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/import/mbox.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/import/mbox.esp
new file mode 100644
index 0000000..6521f70
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/import/mbox.esp
@@ -0,0 +1,22 @@
+<html>
+	<head>
+		<% load("../head.esp"); %>
+	</head>
+
+	<body>
+	<div class="navbar">
+	<a href=<%= homePage %>>< back</a>
+	</div>
+
+	<div class="content">
+		<form method="POST" enctype="multipart/form-data" >
+
+		    Select .mbox file: <input type="file" name="mboxfile" /> <br> 
+		    <input type="submit" value="Import to archive" />
+		
+		</form>
+	</div>
+
+
+	</body>
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/list/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/list/html.esp
new file mode 100755
index 0000000..39c8757
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/list/html.esp
@@ -0,0 +1,32 @@
+<html>
+<head>
+<% load("../head.esp"); %>
+<title><%= currentNode["jcr:text"] %></title>
+</head>
+
+<body>
+<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>
+
+<%
+
+function iterate(renderer, node, lvl) {
+	for (i in node.getChildren()) {
+		var child = node[i]
+		if (child) {
+			if (lvl == 0) {
+				renderer.addMsg(child)
+			} else {
+				iterate(renderer, child, lvl-1)
+			}
+		}
+	}
+}
+
+var renderer = new OrderedRenderer(dateComparator, "replaceSelectors=preview")
+iterate(renderer, currentNode, threadNodesNumber)
+renderer.sort()
+renderer.render()
+
+%>
+</body>
+</html>
\ No newline at end of file
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/html.esp
new file mode 100644
index 0000000..631c0b1
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/html.esp
@@ -0,0 +1,66 @@
+<html>
+
+<head>
+<link rel="stylesheet" href="/apps/mailarchiveserver/styles.css"/>
+<script type="text/javascript" src="/apps/mailarchiveserver/util.js"></script>
+<title>
+	From 
+	<% 
+		var from = currentNode.From
+		out.print(from.match(/\w+ \w+/))
+	%>, 
+	<%
+		out.print(currentNode.Subject)
+	%> 
+</title>
+</head>
+
+<body>
+<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>
+
+<div class="message">
+	<div class="header">
+		<span class="from">	
+		From 
+		<% 
+			var from = currentNode["From"];
+			if (from.indexOf(" ") > 0)
+				out.print(from.substring(0, from.indexOf(" ")))
+			else
+				out.print(from)
+		%> 
+		</span>
+		<span class="date">
+		<%
+			var d = new Date(currentNode["Date"])
+			var now = Date.now()
+			if (now - d.value < 79200000)
+				out.print(d.getHours()+":"+d.getMinutes())
+			else {
+				var m_names = new Array("Jan", "Feb", "Mar", 
+					"Apr", "May", "Jun", "Jul", "Aug", "Sep", 
+					"Oct", "Nov", "Dec")
+				out.print(m_names[d.getMonth()]+" "+d.getDate())
+			}
+		%>
+		</span>
+		<br/>
+		<a class="nolinkstyle" href="<%= currentNode.getParent().getPath() %>.html"><%= currentNode["Subject"] %></a>
+	</div>
+	<div class="body">
+		<%  
+			var lines = currentNode["Body"].split('\n');
+			for (i in lines) {
+				var line = lines[i];
+		%>
+		<script type="text/javascript">
+			document.write(toHtmlString("<%= new String(line) %>"));
+		</script>
+		<%
+				out.print("<br>");
+			}
+		%>
+	</div>
+</div>
+</body>
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/preview.html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/preview.html.esp
new file mode 100644
index 0000000..8be6ecd
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/message/preview.html.esp
@@ -0,0 +1,60 @@
+<div>
+
+<a class="nolinkstyle" href=<% 
+		out.print("\"")			
+		out.print(currentNode.getPath())			
+		out.print(".html")
+		out.print("\"")
+%>>
+
+	<div class="message"> 
+		<b>
+		<span>	
+		From 
+		<% 
+			var from = currentNode["From"];
+			if (from.indexOf(" ") > 0)
+				out.print(from.substring(0, from.indexOf(" ")))
+			else
+				out.print(from)
+		%> 
+		</span>
+		<span>
+		<%
+			var d = new Date(currentNode["Date"])
+			var now = Date.now()
+			if (now - d.value < 79200000) {
+				out.print(" at ")
+				out.print(d.getHours()+":"+d.getMinutes())
+			} else {
+				out.print(" on ")
+				var m_names = new Array("Jan", "Feb", "Mar", 
+					"Apr", "May", "Jun", "Jul", "Aug", "Sep", 
+					"Oct", "Nov", "Dec")
+				out.print(m_names[d.getMonth()]+" "+d.getDate())
+			}
+		%>
+		</span>
+		</b>
+
+		<br>
+		<%= currentNode["Subject"] %> <br>
+
+		<div class="bodypreview">
+		<%
+			var lines = currentNode["Body"].split('\n');
+			for (i=0; i<Math.min(5,lines.length); i++ ) {
+				var line = lines[i];
+		%>
+		<script type="text/javascript">
+			document.write(toHtmlString("<%= new String(line) %>"));
+		</script>
+		<%
+				out.print("<br>");
+			}
+		%>
+		</div>
+	</div>
+
+</a>
+</div>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/navbar.html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/navbar.html.esp
new file mode 100644
index 0000000..08f10d6
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/navbar.html.esp
@@ -0,0 +1,68 @@
+<div class="navbar">
+	<% load("head.esp"); %>
+
+<!-- NAVIGATION BAR -->
+
+	<a href=<%= homePage %>>home</a> > 
+<%
+	if (currentNode.getName() == "search") {
+%>
+		<a href="/mailarchiveserver/search.html">search</a>
+<%
+	} else {
+%>
+		<a href="/mailarchiveserver/archive.html">archive</a>
+<%		
+		var name = [];
+		var href = [];
+		var node = currentNode;
+		var folding = false;
+		var fname = "";
+		var fhref = "";
+		while (node.getName() != "archive") {
+			var rt = node["sling:resourceType"];
+			if (rt == "mailarchiveserver/list") 
+				folding = true;
+			
+			if (rt != undefined) {
+				if (!folding) {
+					name.push(node["jcr:text"]);
+					href.push(node.getPath()+".html");
+				} else {
+					fname += node["jcr:text"]+".";
+					if (fhref == "")
+						fhref = node.getPath()+".html";
+				}
+			}
+			node = node.getParent();
+		}
+		if (folding) {
+			name.push(fname.substring(0, fname.length-1));
+			href.push(fhref);
+		}
+
+		while (name.length > 0) {
+			out.print(" > <a href="+href.pop()+">"+name.pop()+"</a>");
+		}
+	}
+%>
+</div>
+
+<!-- SAERCH BAR -->
+
+<form method="GET" action="/mailarchiveserver/search.html" style="width: 40%; margin: 1em auto;">
+    <input type="text" name="q" style="width: 70%;" value='<%= request.getParameter('q') ? request.getParameter('q') : '' %>' /> 
+    <input type="submit" value="Search" style="width: 23%;" /> <span 
+title='You can search in the following ways
+(similar to Markmail)
+General terms:	server
+Or phrases: 	"latest news"
+Sender field:	from:"Roy Fielding", from:adobe.com
+Subject field:	subject:"how to"
+List field:		list:sling
+
+Search is NOT case sensitive, i.e. searching for list:oak and LIST:OAK will produce same results.
+
+Constraints are ANDed together except in the case of multiple fielded constraints of the same type which will be ORed together.
+'>(?)</span> <br> 
+</form>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/root/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/root/html.esp
new file mode 100644
index 0000000..6ee5724
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/root/html.esp
@@ -0,0 +1,26 @@
+<html>
+
+<head>
+<%
+	load("../head.esp"); 
+	if (! request.getRequestParameter("noredirect") ) {
+		response.sendRedirect(startPage)
+	}
+%>
+	<title>Mail Archive Server</title>
+</head>
+
+<body>
+	<div class="content">
+		<h1>Welcome to the Mail Archive Server!</h1> <br>
+
+		<dl>
+		  <dt>Choose what you want to do:</dt> <br>
+		  <dd><a href="<%= currentNode.getPath() %>/import.mbox.html">Import mbox file to the archive</a></dd> <br>
+		  <dd><a href="<%= currentNode.getPath() %>/archive.html">Browse archive</a></dd> <br>
+		  <dd><a href="<%= currentNode.getPath() %>/search.html">Search archive</a></dd> <br>
+		</dl>
+	</div>
+</body>
+
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/search/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/search/html.esp
new file mode 100644
index 0000000..1e97550
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/search/html.esp
@@ -0,0 +1,31 @@
+<html>
+
+<head>
+<% load("../head.esp"); %>
+<title>Search mail archive</title>
+</head>
+
+<body>
+	<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>
+
+	<div class="content">
+<%
+	var phrase = request.getParameter("q")
+	if (phrase) {
+		var service = sling.getService(Packages.org.apache.sling.mailarchiveserver.api.SearchService) 
+		var resIter = service.find(phrase)
+		var renderer = new OrderedRenderer(dateComparator, "forceResourceType=mailarchiveserver/message,replaceSelectors=preview")
+		while (resIter.hasNext()) {
+			var resource = resIter.next()
+			var node = resource.adaptTo(Packages.javax.jcr.Node)
+			renderer.addMsg(node)
+		}
+		out.print("Found " + renderer.list.length + " messages <br>")
+		renderer.sort()
+		renderer.render()
+	}
+%>
+	</div>
+</body>
+
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/styles.css b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/styles.css
new file mode 100644
index 0000000..376839d
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/styles.css
@@ -0,0 +1,49 @@
+/*
+ * Modified version of slingbucks styles:
+ * http://svn.apache.org/repos/asf/sling/trunk/samples/slingbucks/src/main/resources/SLING-CONTENT/apps/slingbucks/common/slingbucks.css
+ */
+
+body {
+  font-family: Georgia, Verdana, Arial, Sans-Serif;
+}
+
+.message {
+  margin-bottom: 1em;
+  border: solid #CCCCCC 1px;
+  padding: 1em;
+}
+
+.header {
+  font-size:120%;
+  margin-bottom: 1em;
+  padding-bottom: 0.5em;
+  border-bottom: solid thin blue;
+  text-align: justify;
+}
+
+.from, .date {
+  font-weight: bold;
+}
+
+.date {
+  float: right;
+}
+
+.content {
+  width:75%;
+  margin:1em auto;
+}
+
+.navbar {
+  margin: 1em;
+}
+
+.nolinkstyle {
+  color: inherit;
+  text-decoration: none;
+}
+
+.bodypreview {
+  margin-top: 1em;
+  font-size:80%;
+}
\ No newline at end of file
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/thread/html.esp b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/thread/html.esp
new file mode 100644
index 0000000..21a96d0
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/thread/html.esp
@@ -0,0 +1,25 @@
+<html>
+	<head>
+	<% load("../head.esp"); %>
+	<title>
+	<%= currentNode["jcr:text"] %>
+	</title>
+	</head>
+
+	<body>
+
+		<% sling.include(currentNode.getPath(), "forceResourceType=mailarchiveserver,replaceSelectors=navbar"); %>
+
+		<h2> <%= currentNode["jcr:text"] %> </h2>
+		
+		<%
+		var messages = currentNode.getChildren()
+		for(i in messages) {
+			var m = messages[i]
+		%>
+		
+		<% sling.include(m.getPath(), "replaceSelectors=preview"); %>
+	
+		<%}%>
+	</body>
+</html>
diff --git a/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/util.js b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/util.js
new file mode 100644
index 0000000..876b220
--- /dev/null
+++ b/mail-archive/ui/src/main/resources/initial-content/apps/mailarchiveserver/util.js
@@ -0,0 +1,11 @@
+function toHtmlString (str) {
+	var newstr = str.replace(/\ufffd/g, "").replace(/\&/g, "&amp;").replace(/\</g, "&lt;").replace(/\>/g, "&gt;").replace(/\"/g, "&quot;");
+	return newstr;
+}
+
+// author Rafael
+// taken from http://stackoverflow.com/questions/831030/how-to-get-get-request-parameters-in-javascript
+function getRequestParam (name) {
+   if (name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
+      return decodeURIComponent(name[1]);
+}