MAILET-142 Increase test coverage and refactor StripAttachment mailet

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0e49d8c2
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0e49d8c2
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0e49d8c2

Branch: refs/heads/master
Commit: 0e49d8c28c6784348999766a549551920746199e
Parents: 993f444
Author: Laura Royet <[email protected]>
Authored: Wed Dec 14 14:54:44 2016 +0100
Committer: Laura Royet <[email protected]>
Committed: Wed Dec 21 17:02:32 2016 +0100

----------------------------------------------------------------------
 .../org/apache/mailet/base/GenericMailet.java   |  35 +-
 .../apache/mailet/base/GenericMailetTest.java   | 102 +++
 mailet/pom.xml                                  |   5 +
 mailet/standard/pom.xml                         |   5 +
 .../transport/mailets/StripAttachment.java      | 544 ++++++-----
 .../james/transport/mailets/WrapText.java       |   6 -
 .../transport/mailets/StripAttachmentTest.java  | 894 ++++++++++++++-----
 server/mailet/integration-testing/pom.xml       |   6 +
 .../james/mailets/utils/SMTPMessageSender.java  |  25 +
 .../transport/mailets/StripAttachmentTest.java  | 180 ++++
 10 files changed, 1347 insertions(+), 455 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
----------------------------------------------------------------------
diff --git 
a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java 
b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
index c52a1bd..c56a226 100644
--- a/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
+++ b/mailet/base/src/main/java/org/apache/mailet/base/GenericMailet.java
@@ -20,16 +20,21 @@
 
 package org.apache.mailet.base;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+
 import javax.mail.MessagingException;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.mailet.Mail;
 import org.apache.mailet.Mailet;
 import org.apache.mailet.MailetConfig;
 import org.apache.mailet.MailetContext;
 import org.apache.mailet.MailetContext.LogLevel;
 
-import java.util.*;
-
 /**
  * GenericMailet makes writing mailets easier. It provides simple
  * versions of the lifecycle methods init and destroy and of the methods
@@ -42,6 +47,12 @@ import java.util.*;
  * @version 1.0.0, 24/04/1999
  */
 public abstract class GenericMailet implements Mailet, MailetConfig {
+
+    private static final String YES = "yes";
+    private static final String NO = "no";
+    private static final String TRUE = "true";
+    private static final String FALSE = "false";
+
     private MailetConfig config = null;
 
     /**
@@ -70,7 +81,25 @@ public abstract class GenericMailet implements Mailet, 
MailetConfig {
         }
         return MailetUtil.getInitParameter(config, name, defaultValue);
     }
-    
+
+    /**
+     * Gets a boolean valued init parameter that matches 'false', 'no', 'true' 
or 'yes' string values.
+     */
+    public boolean getBooleanParameter(String value, boolean defaultValue) {
+        if (defaultValue) {
+            return !isFalseOrNo(value);
+        }
+        return isTrueOrYes(value);
+    }
+
+    private static boolean isFalseOrNo(String value) {
+        return StringUtils.containsIgnoreCase(value, FALSE) || 
StringUtils.containsIgnoreCase(value, NO);
+    }
+
+    private static boolean isTrueOrYes(String value) {
+        return StringUtils.containsIgnoreCase(value, TRUE) || 
StringUtils.containsIgnoreCase(value, YES);
+    }
+
     /**
      * Returns a String containing the value of the named initialization
      * parameter, or null if the parameter does not exist.

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/base/src/test/java/org/apache/mailet/base/GenericMailetTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/base/src/test/java/org/apache/mailet/base/GenericMailetTest.java 
b/mailet/base/src/test/java/org/apache/mailet/base/GenericMailetTest.java
new file mode 100644
index 0000000..a8629eb
--- /dev/null
+++ b/mailet/base/src/test/java/org/apache/mailet/base/GenericMailetTest.java
@@ -0,0 +1,102 @@
+/****************************************************************
+ * 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.mailet.base;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import javax.mail.MessagingException;
+
+import org.apache.mailet.Mail;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GenericMailetTest {
+
+    private static class TestingMailet extends GenericMailet {
+
+        @Override
+        public void service(Mail mail) throws MessagingException {
+        }
+    }
+
+    private TestingMailet testee;
+
+    @Before
+    public void setup() {
+        testee = new TestingMailet();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnFalseWhenValueNullAndDefaultFalse() throws 
Exception {
+        String value = null;
+        boolean actual = testee.getBooleanParameter(value, false);
+        assertThat(actual).isFalse();
+    }
+    
+    @Test
+    public void 
getBooleanParameterShouldReturnTrueWhenValueTrueAndDefaultFalse() throws 
Exception {
+        String value = "true";
+        boolean actual = testee.getBooleanParameter(value, false);
+        assertThat(actual).isTrue();
+    }
+    
+    @Test
+    public void 
getBooleanParameterShouldReturnTrueWhenValueYesAndDefaultFalse() throws 
Exception {
+        String value = "yes";
+        boolean actual = testee.getBooleanParameter(value, false);
+        assertThat(actual).isTrue();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnFalseWhenValueOtherAndDefaultFalse() throws 
Exception {
+        String value = "other";
+        boolean actual = testee.getBooleanParameter(value, false);
+        assertThat(actual).isFalse();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnTrueWhenValueNullAndDefaultTrue() throws 
Exception {
+        String value = null;
+        boolean actual = testee.getBooleanParameter(value, true);
+        assertThat(actual).isTrue();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnFalseWhenValueNoAndDefaultTrue() throws 
Exception {
+        String value = "no";
+        boolean actual = testee.getBooleanParameter(value, true);
+        assertThat(actual).isFalse();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnFalseWhenValueFalseAndDefaultTrue() throws 
Exception {
+        String value = "false";
+        boolean actual = testee.getBooleanParameter(value, true);
+        assertThat(actual).isFalse();
+    }
+
+    @Test
+    public void 
getBooleanParameterShouldReturnTrueWhenValueOtherAndDefaultTrue() throws 
Exception {
+        String value = "other";
+        boolean actual = testee.getBooleanParameter(value, true);
+        assertThat(actual).isTrue();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/pom.xml
----------------------------------------------------------------------
diff --git a/mailet/pom.xml b/mailet/pom.xml
index fe212ca..368b27f 100644
--- a/mailet/pom.xml
+++ b/mailet/pom.xml
@@ -153,6 +153,11 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.assertj</groupId>
+                <artifactId>assertj-guava</artifactId>
+                <version>1.3.1</version>
+            </dependency>
+            <dependency>
                 <groupId>com.thoughtworks.qdox</groupId>
                 <artifactId>qdox</artifactId>
                 <version>${qdox.version}</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/standard/pom.xml
----------------------------------------------------------------------
diff --git a/mailet/standard/pom.xml b/mailet/standard/pom.xml
index 57a54d9..892ca71 100644
--- a/mailet/standard/pom.xml
+++ b/mailet/standard/pom.xml
@@ -77,6 +77,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-guava</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
index dff16a4..e9c8592 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/StripAttachment.java
@@ -19,20 +19,21 @@
 
 package org.apache.james.transport.mailets;
 
-import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.regex.Pattern;
 
+import javax.mail.BodyPart;
 import javax.mail.Message;
 import javax.mail.MessagingException;
 import javax.mail.Multipart;
@@ -41,10 +42,16 @@ import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeUtility;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailetException;
 import org.apache.mailet.base.GenericMailet;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+
 /**
  * <p>
  * Remove attachments from a Message. Supports simple removal, storing to file,
@@ -63,156 +70,159 @@ import org.apache.mailet.base.GenericMailet;
  *     &lt;remove &gt;all &lt;/remove&gt;   &lt;!-- either &quot;no&quot;, 
&quot;matched&quot;, &quot;all&quot; -- &gt;
  *     &lt;!-- attribute&gt;my.attribute.name&lt;/attribute --&gt;
  *   &lt;/mailet &gt;
+ *   
+ *   At least one of pattern and notpattern is required.
  * </pre>
  * 
  * </p>
  */
 public class StripAttachment extends GenericMailet {
 
+    private static final String MULTIPART_MIME_TYPE = "multipart/*";
     public static final String PATTERN_PARAMETER_NAME = "pattern";
-
     public static final String NOTPATTERN_PARAMETER_NAME = "notpattern";
-
     public static final String ATTRIBUTE_PARAMETER_NAME = "attribute";
-
     public static final String DIRECTORY_PARAMETER_NAME = "directory";
-
     // Either "no", "matched", "all"
     public static final String REMOVE_ATTACHMENT_PARAMETER_NAME = "remove"; 
-
     // Either "true", "false"
     public static final String DECODE_FILENAME_PARAMETER_NAME = 
"decodeFilename";
-
     public static final String REPLACE_FILENAME_PATTERN_PARAMETER_NAME = 
"replaceFilenamePattern";
-
     public static final String REMOVE_NONE = "no";
-
     public static final String REMOVE_ALL = "all";
-
     public static final String REMOVE_MATCHED = "matched";
-
     public static final String REMOVED_ATTACHMENTS_ATTRIBUTE_KEY = 
"org.apache.james.mailet.standard.mailets.StripAttachment.removed";
-
     public static final String SAVED_ATTACHMENTS_ATTRIBUTE_KEY = 
"org.apache.james.mailet.standard.mailets.StripAttachment.saved";
 
-    private String removeAttachments = null;
-
-    private String directoryName = null;
-
-    private String attributeName = null;
-
-    private Pattern regExPattern = null;
-
-    private Pattern notregExPattern = null;
+    public static final boolean DECODE_FILENAME_DEFAULT_VALUE = false;
 
-    private boolean decodeFilename = false;
+    @VisibleForTesting String removeAttachments;
+    private String directoryName;
+    private String attributeName;
+    private Pattern regExPattern;
+    private Pattern notRegExPattern;
+    private boolean decodeFilename;
 
-    private List<ReplacingPattern> filenameReplacingPatterns = null;
-
-    private static boolean getBooleanParameter(String v, boolean def) {
-        return def ? !(v != null && (v.equalsIgnoreCase("false") || v
-                .equalsIgnoreCase("no"))) : v != null
-                && (v.equalsIgnoreCase("true") || v.equalsIgnoreCase("yes"));
-    }
+    private List<ReplacingPattern> filenameReplacingPatterns;
 
     /**
      * Checks if the mandatory parameters are present, creates the directory to
-     * save the files ni (if not present).
+     * save the files in (if not present).
      * 
      * @throws MailetException
      */
+    @Override
     public void init() throws MailetException {
-        String patternString = getInitParameter(PATTERN_PARAMETER_NAME);
-        String notpatternString = getInitParameter(NOTPATTERN_PARAMETER_NAME);
-        if (patternString == null && notpatternString == null) {
-            throw new MailetException("No value for " + PATTERN_PARAMETER_NAME
-                    + " parameter was provided.");
+        regExPattern = regExFromParameter(PATTERN_PARAMETER_NAME);
+        notRegExPattern = regExFromParameter(NOTPATTERN_PARAMETER_NAME);
+        if (regExPattern == null && notRegExPattern == null) {
+            throw new MailetException("At least one of '" + 
PATTERN_PARAMETER_NAME + "' or '" + NOTPATTERN_PARAMETER_NAME + "' parameter 
should be provided.");
         }
 
         directoryName = getInitParameter(DIRECTORY_PARAMETER_NAME);
         attributeName = getInitParameter(ATTRIBUTE_PARAMETER_NAME);
 
-        removeAttachments = getInitParameter(REMOVE_ATTACHMENT_PARAMETER_NAME,
-                REMOVE_NONE).toLowerCase();
-        if (!REMOVE_MATCHED.equals(removeAttachments)
-                && !REMOVE_ALL.equals(removeAttachments)) {
-            removeAttachments = REMOVE_NONE;
-        }
-
-        try {
-            // if (patternString != null) regExPattern = new
-            // Perl5Compiler().compile(patternString);
-            if (patternString != null)
-                regExPattern = Pattern.compile(patternString);
-        } catch (Exception e) {
-            throw new MailetException("Could not compile regex ["
-                    + patternString + "].");
-        }
-        try {
-            // if (notpatternString != null) notregExPattern = new
-            // Perl5Compiler().compile(notpatternString);
-            if (notpatternString != null)
-                notregExPattern = Pattern.compile(notpatternString);
-        } catch (Exception e) {
-            throw new MailetException("Could not compile regex ["
-                    + notpatternString + "].");
+        removeAttachments = getInitParameter(REMOVE_ATTACHMENT_PARAMETER_NAME, 
REMOVE_NONE).toLowerCase(Locale.US);
+        if (!removeAttachments.equals(REMOVE_MATCHED) && 
!removeAttachments.equals(REMOVE_ALL) && 
!removeAttachments.equals(REMOVE_NONE)) {
+            throw new MailetException(String.format("Unknown remove parameter 
value '%s' waiting for '%s', '%s' or '%s'.", 
+                    removeAttachments, REMOVE_MATCHED, REMOVE_ALL, 
REMOVE_NONE));
         }
 
         if (directoryName != null) {
-            try {
-                FileUtils.forceMkdir(new File(directoryName));
-            } catch (Exception e) {
-                throw new MailetException("Could not create directory ["
-                        + directoryName + "].", e);
-            }
+            createDirectory();
         }
 
-        decodeFilename = getBooleanParameter(
-                getInitParameter(DECODE_FILENAME_PARAMETER_NAME),
-                decodeFilename);
-        if (getInitParameter(REPLACE_FILENAME_PATTERN_PARAMETER_NAME) != null) 
{
-            filenameReplacingPatterns = new PatternExtractor()
-                    
.getPatternsFromString(getInitParameter(REPLACE_FILENAME_PATTERN_PARAMETER_NAME));
+        decodeFilename = 
getBooleanParameter(getInitParameter(DECODE_FILENAME_PARAMETER_NAME), 
DECODE_FILENAME_DEFAULT_VALUE);
+        String replaceFilenamePattern = 
getInitParameter(REPLACE_FILENAME_PATTERN_PARAMETER_NAME);
+        if (replaceFilenamePattern != null) {
+            filenameReplacingPatterns = new 
PatternExtractor().getPatternsFromString(replaceFilenamePattern);
+        } else {
+            filenameReplacingPatterns = ImmutableList.of();
         }
 
-        String toLog = String.format("StripAttachment is initialised with 
regex pattern [%s / %s]",
-                patternString, notpatternString);
-        if (directoryName != null) {
-            toLog += String.format(" and will save to directory [%s]", 
directoryName);
+        logConfiguration();
+    }
+
+    private Pattern regExFromParameter(String patternParameterName) throws 
MailetException {
+        String patternString = getInitParameter(patternParameterName);
+        try {
+            if (patternString != null) {
+                return Pattern.compile(patternString);
+            }
+            return null;
+        } catch (Exception e) {
+            throw new MailetException("Could not compile regex [" + 
patternString + "].");
         }
-        if (attributeName != null) {
-            toLog += String.format(" and will store attachments to attribute 
[%s]", attributeName);
+    }
+
+    private void createDirectory() throws MailetException {
+        try {
+            FileUtils.forceMkdir(new File(directoryName));
+        } catch (Exception e) {
+            throw new MailetException("Could not create directory [" + 
directoryName + "].", e);
         }
-        log(toLog);
     }
 
+      private void logConfiguration() {
+      StringBuilder logMessage = new StringBuilder();
+      logMessage.append("StripAttachment is initialised with regex pattern [");
+      if (regExPattern != null) {
+          logMessage.append(regExPattern.pattern());
+      }
+      logMessage.append(" / ");
+      if (notRegExPattern != null) {
+          logMessage.append(notRegExPattern.pattern());
+      }
+      logMessage.append("]");
+
+      if (directoryName != null) {
+          logMessage.append(" and will save to directory [");
+          logMessage.append(directoryName);
+          logMessage.append("]");
+      }
+      if (attributeName != null) {
+          logMessage.append(" and will store attachments to attribute [");
+          logMessage.append(attributeName);
+          logMessage.append("]");
+      }
+      log(logMessage.toString());
+    }
+    
     /**
-     * Service the mail: scan it for attchemnts matching the pattern, store the
-     * content of a matchin attachment in the given directory.
+     * Service the mail: scan it for attachments matching the pattern.
+     * If a filename matches the pattern: 
+     * - the file is stored (using its name) in the given directory (if 
directoryName is given in the mailet configuration)
+     *    and the filename is stored in 'saved' mail list attribute
+     * - the part is removed (when removeAttachments mailet configuration 
property is 'all' or 'matched') 
+     *    and the filename is stored in 'removed' mail list attribute
+     * - the part filename and its content is stored in mail map attribute (if 
attributeName is given in the mailet configuration)
      * 
      * @param mail
      *            The mail to service
      * @throws MailetException
      *             Thrown when an error situation is encountered.
      */
+    @Override
     public void service(Mail mail) throws MailetException {
-        MimeMessage message;
+        MimeMessage message = getMessageFromMail(mail);
+        if (isMultipart(message)) {
+            processMultipartPartMessage(message, mail);
+        }
+    }
+
+    private boolean isMultipart(Part part) throws MailetException {
         try {
-            message = mail.getMessage();
+            return part.isMimeType(MULTIPART_MIME_TYPE);
         } catch (MessagingException e) {
-            throw new MailetException(
-                    "Could not retrieve message from Mail object", e);
+            throw new MailetException("Could not retrieve contenttype of 
MimePart.", e);
         }
-        // All MIME messages with an attachment are multipart, so we do nothing
-        // if it is not mutlipart
+    }
+
+    private MimeMessage getMessageFromMail(Mail mail) throws MailetException {
         try {
-            if (message.isMimeType("multipart/*")) {
-                analyseMultipartPartMessage(message, mail);
-            }
+            return mail.getMessage();
         } catch (MessagingException e) {
-            throw new MailetException("Could not retrieve contenttype of 
message.", e);
-        } catch (Exception e) {
-            throw new MailetException("Could not analyse message.", e);
+            throw new MailetException("Could not retrieve message from Mail 
object", e);
         }
     }
 
@@ -221,122 +231,158 @@ public class StripAttachment extends GenericMailet {
      * 
      * @return A desciption of this mailet
      */
+    @Override
     public String getMailetInfo() {
         return "StripAttachment";
     }
 
     /**
      * Checks every part in this part (if it is a Multipart) for having a
-     * filename that matches the pattern. If the name matches, the content of
-     * the part is stored (using its name) in te given diretcory.
+     * filename that matches the pattern. 
+     * If the name matches: 
+     * - the file is stored (using its name) in the given directory (if 
directoryName is given in the mailet configuration)
+     *    and the filename is stored in 'saved' mail list attribute
+     * - the part is removed (when removeAttachments mailet configuration 
property is 'all' or 'matched') 
+     *    and the filename is stored in 'removed' mail list attribute
+     * - the part filename and its content is stored in mail map attribute (if 
attributeName is given in the mailet configuration)
      * 
      * Note: this method is recursive.
      * 
      * @param part
      *            The part to analyse.
      * @param mail
-     * @return
+     * @return True if one of the subpart was removed
      * @throws Exception
      */
-    private boolean analyseMultipartPartMessage(Part part, Mail mail)
-            throws Exception {
-        if (part.isMimeType("multipart/*")) {
-            try {
-                Multipart multipart = (Multipart) part.getContent();
-                boolean atLeastOneRemoved = false;
-                int numParts = multipart.getCount();
-                for (int i = 0; i < numParts; i++) {
-                    Part p = multipart.getBodyPart(i);
-                    if (p.isMimeType("multipart/*")) {
-                        atLeastOneRemoved |= analyseMultipartPartMessage(p,
-                                mail);
-                    } else {
-                        boolean removed = checkMessageRemoved(p, mail);
-                        if (removed) {
-                            multipart.removeBodyPart(i);
-                            atLeastOneRemoved = true;
-                            i--;
-                            numParts--;
-                        }
+    @VisibleForTesting boolean processMultipartPartMessage(Part part, Mail 
mail) throws MailetException {
+        if (!isMultipart(part)) {
+            return false;
+        }
+
+        try {
+            Multipart multipart = (Multipart) part.getContent();
+            boolean atLeastOneRemoved = false;
+            boolean subpartHasBeenChanged = false;
+            List<BodyPart> bodyParts = retrieveBodyParts(multipart);
+            for (BodyPart bodyPart: bodyParts) {
+                if (isMultipart(bodyPart)) {
+                    if (processMultipartPartMessage(bodyPart, mail)) {
+                        subpartHasBeenChanged = true;
                     }
-                }
-                if (atLeastOneRemoved) {
-                    part.setContent(multipart);
-                    if (part instanceof Message) {
-                        ((Message) part).saveChanges();
+                } else {
+                    if (shouldBeRemoved(bodyPart, mail)) {
+                        multipart.removeBodyPart(bodyPart);
+                        atLeastOneRemoved = true;
                     }
                 }
-                return atLeastOneRemoved;
-            } catch (Exception e) {
-                log("Could not analyse part.", e);
             }
+            if (atLeastOneRemoved || subpartHasBeenChanged) {
+                updateBodyPart(part, multipart);
+            }
+            return atLeastOneRemoved || subpartHasBeenChanged;
+        } catch (Exception e) {
+            log("Failing while analysing part for attachments (StripAttachment 
mailet).", e);
+            return false;
         }
-        return false;
     }
 
-    private boolean checkMessageRemoved(Part part, Mail mail)
-            throws MessagingException, Exception {
-        String fileName;
-        fileName = part.getFileName();
+    private void updateBodyPart(Part part, Multipart newPartContent) throws 
MessagingException {
+        part.setContent(newPartContent);
+        if (part instanceof Message) {
+            ((Message) part).saveChanges();
+        }
+    }
 
-        // filename or name of part can be null, so we have to be careful
-        boolean ret = false;
+    private List<BodyPart> retrieveBodyParts(Multipart multipart) throws 
MessagingException {
+        ImmutableList.Builder<BodyPart> builder = ImmutableList.builder();
+        for (int i = 0; i < multipart.getCount(); i++) {
+            builder.add(multipart.getBodyPart(i));
+        }
+        return builder.build();
+    }
 
-        if (fileName != null) {
-            if (decodeFilename)
-                fileName = MimeUtility.decodeText(fileName);
-
-            if (filenameReplacingPatterns != null)
-                fileName = new ContentReplacer(false, 
this).applyPatterns(filenameReplacingPatterns, fileName);
-
-            if (fileNameMatches(fileName)) {
-                if (directoryName != null) {
-                    String filename = saveAttachmentToFile(part, fileName);
-                    if (filename != null) {
-                        @SuppressWarnings("unchecked")
-                        Collection<String> c = (Collection<String>) mail
-                                .getAttribute(SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
-                        if (c == null) {
-                            c = new ArrayList<String>();
-                            mail.setAttribute(SAVED_ATTACHMENTS_ATTRIBUTE_KEY,
-                                    (ArrayList<String>) c);
-                        }
-                        c.add(filename);
-                    }
-                }
-                if (attributeName != null) {
-                    @SuppressWarnings("unchecked")
-                    Map<String, byte[]> m = (Map<String, byte[]>) 
mail.getAttribute(attributeName);
-                    if (m == null) {
-                        m = new LinkedHashMap<String, byte[]>();
-                        mail.setAttribute(attributeName, 
(LinkedHashMap<String, byte[]>) m);
-                    }
-                    ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
-                    OutputStream os = new BufferedOutputStream(
-                            byteArrayOutputStream);
-                    part.writeTo(os);
-                    m.put(fileName, byteArrayOutputStream.toByteArray());
-                }
-                if (removeAttachments.equals(REMOVE_MATCHED)) {
-                    ret = true;
-                }
-            }
-            if (!ret) {
-                ret = removeAttachments.equals(REMOVE_ALL);
+    private boolean shouldBeRemoved(BodyPart bodyPart, Mail mail) throws 
MessagingException, Exception {
+        String fileName = getFilename(bodyPart);
+        if (fileName == null) {
+            return false;
+        }
+
+        boolean shouldRemove = removeAttachments.equals(REMOVE_ALL);
+        if (fileNameMatches(fileName)) {
+            storeBodyPartAsFile(bodyPart, mail, fileName);
+            storeBodyPartAsMailAttribute(bodyPart, mail, fileName);
+            if (removeAttachments.equals(REMOVE_MATCHED)) {
+                shouldRemove = true;
             }
-            if (ret) {
-                @SuppressWarnings("unchecked")
-                Collection<String> c = (Collection<String>) mail
-                        .getAttribute(REMOVED_ATTACHMENTS_ATTRIBUTE_KEY);
-                if (c == null) {
-                    c = new ArrayList<String>();
-                    mail.setAttribute(REMOVED_ATTACHMENTS_ATTRIBUTE_KEY,
-                            (ArrayList<String>) c);
-                }
-                c.add(fileName);
+        }
+        storeFileNameAsAttribute(mail, fileName, shouldRemove);
+        return shouldRemove;
+    }
+
+    private void storeBodyPartAsFile(BodyPart bodyPart, Mail mail, String 
fileName) throws Exception {
+        if (directoryName != null) {
+            Optional<String> filename = saveAttachmentToFile(bodyPart, 
Optional.of(fileName));
+            if (filename.isPresent()) {
+                addFilenameToAttribute(mail, filename.get(), 
SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
             }
         }
-        return ret;
+    }
+
+    private void addFilenameToAttribute(Mail mail, String filename, String 
attributeName) {
+        @SuppressWarnings("unchecked")
+        List<String> attributeValues = (List<String>) 
mail.getAttribute(attributeName);
+        if (attributeValues == null) {
+            attributeValues = new ArrayList<String>();
+            mail.setAttribute(attributeName, (Serializable) attributeValues);
+        }
+        attributeValues.add(filename);
+    }
+
+    private void storeBodyPartAsMailAttribute(BodyPart bodyPart, Mail mail, 
String fileName) throws IOException, MessagingException {
+        if (attributeName != null) {
+            addPartContent(bodyPart, mail, fileName);
+        }
+    }
+
+    private void addPartContent(BodyPart bodyPart, Mail mail, String fileName) 
throws IOException, MessagingException {
+        @SuppressWarnings("unchecked")
+        Map<String, byte[]> fileNamesToPartContent = (Map<String, byte[]>) 
mail.getAttribute(attributeName);
+        if (fileNamesToPartContent == null) {
+            fileNamesToPartContent = new LinkedHashMap<String, byte[]>();
+            mail.setAttribute(attributeName, (Serializable) 
fileNamesToPartContent);
+        }
+        ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
+        bodyPart.writeTo(new BufferedOutputStream(byteArrayOutputStream));
+        fileNamesToPartContent.put(fileName, 
byteArrayOutputStream.toByteArray());
+    }
+
+    private void storeFileNameAsAttribute(Mail mail, String fileName, boolean 
hasToBeStored) {
+        if (hasToBeStored) {
+            addFilenameToAttribute(mail, fileName, 
REMOVED_ATTACHMENTS_ATTRIBUTE_KEY);
+        }
+    }
+
+    private String getFilename(BodyPart bodyPart) throws 
UnsupportedEncodingException, MessagingException {
+        String fileName = bodyPart.getFileName();
+        if (fileName != null) {
+            return renameWithConfigurationPattern(decodeFilename(fileName));
+        }
+        return fileName;
+    }
+
+    private String renameWithConfigurationPattern(String fileName) {
+        if (filenameReplacingPatterns != null) {
+            boolean debug = false;
+            return new ContentReplacer(debug, 
this).applyPatterns(filenameReplacingPatterns, fileName);
+        }
+        return fileName;
+    }
+
+    private String decodeFilename(String fileName) throws 
UnsupportedEncodingException {
+        if (decodeFilename) {
+            return MimeUtility.decodeText(fileName);
+        }
+        return fileName;
     }
 
     /**
@@ -346,71 +392,97 @@ public class StripAttachment extends GenericMailet {
      *            The name to check for a match.
      * @return True if a match is found, false otherwise.
      */
-    private boolean fileNameMatches(String name) {
-        boolean result = true;
-        if (regExPattern != null)
-            result = regExPattern.matcher(name).matches();
-        if (result && notregExPattern != null)
-            result = !notregExPattern.matcher(name).matches();
-
-        String log = "attachment " + name + " ";
-        if (!result)
-            log += "does not match";
-        else
-            log += "matches";
-        log(log);
+    @VisibleForTesting boolean fileNameMatches(String name) {
+        if (patternsAreEquals()) {
+            return false;
+        }
+        boolean result = isMatchingPattern(name, regExPattern).or(false) 
+                || !isMatchingPattern(name, notRegExPattern).or(true);
+
+        log("attachment " + name + " " + ((result) ? "matches" : "does not 
match"));
         return result;
     }
 
+    private boolean patternsAreEquals() {
+        return regExPattern != null && notRegExPattern != null
+                && regExPattern.pattern().equals(notRegExPattern.pattern());
+    }
+
+    private Optional<Boolean> isMatchingPattern(String name, Pattern pattern) {
+        if (pattern != null) {
+            return Optional.of(pattern.matcher(name).matches());
+        }
+        return Optional.absent();
+    }
+
     /**
-     * Saves the content of the part to a file in the given directoy, using the
-     * name of the part. If a file with that name already exists, it will
+     * Saves the content of the part to a file in the given directory, using 
the
+     * name of the part. Created files have unique names.
      * 
      * @param part
      *            The MIME part to save.
      * @return
      * @throws Exception
      */
-    private String saveAttachmentToFile(Part part, String fileName)
-            throws Exception {
-        BufferedOutputStream os = null;
-        InputStream is = null;
-        File f = null;
+    @VisibleForTesting Optional<String> saveAttachmentToFile(Part part, 
Optional<String> fileName) throws Exception {
         try {
-            if (fileName == null)
-                fileName = part.getFileName();
-            int pos = -1;
-            if (fileName != null) {
-                pos = fileName.lastIndexOf(".");
-            }
-            String prefix = pos > 0 ? (fileName.substring(0, pos)) : fileName;
-            String suffix = pos > 0 ? (fileName.substring(pos)) : ".bin";
-            while (prefix.length() < 3)
-                prefix += "_";
-            if (suffix.length() == 0)
-                suffix = ".bin";
-            f = File.createTempFile(prefix, suffix, new File(directoryName));
-            log("saving content of " + f.getName() + "...");
-            os = new BufferedOutputStream(new FileOutputStream(f));
-            is = part.getInputStream();
-            if (!(is instanceof BufferedInputStream)) {
-                is = new BufferedInputStream(is);
-            }
-            int c;
-            while ((c = is.read()) != -1) {
-                os.write(c);
-            }
+            File outputFile = outputFile(part, fileName);
 
-            return f.getName();
+            log("saving content of " + outputFile.getName() + "...");
+            IOUtils.copy(part.getInputStream(), new 
FileOutputStream(outputFile));
+
+            return Optional.of(outputFile.getName());
         } catch (Exception e) {
-            log("Error while saving contents of ["
-                    + (f != null ? f.getName() : (part != null ? part
-                            .getFileName() : "NULL")) + "].", e);
-            throw e;
-        } finally {
-            is.close();
-            os.close();
+            log("Error while saving contents of", e);
+            return Optional.absent();
         }
     }
 
+    private File outputFile(Part part, Optional<String> fileName) throws 
MessagingException, IOException {
+        Optional<String> maybePartFileName = 
Optional.fromNullable(part.getFileName());
+        return createTempFile(fileName.or(maybePartFileName).orNull());
+    }
+
+    private File createTempFile(String originalFileName) throws IOException {
+        OutputFileName outputFileName = OutputFileName.from(originalFileName);
+        return File.createTempFile(outputFileName.getPrefix(), 
outputFileName.getSuffix(), new File(directoryName));
+    }
+
+    @VisibleForTesting static class OutputFileName {
+
+        private static final char PAD_CHAR = '_';
+        private static final int MIN_LENGTH = 3;
+        private static final String DEFAULT_SUFFIX = ".bin";
+
+        public static OutputFileName from(String originalFileName) {
+            if (!originalFileName.contains(".")) {
+                return new OutputFileName(prependedPrefix(originalFileName), 
DEFAULT_SUFFIX);
+            }
+
+            int lastDotPosition = originalFileName.lastIndexOf(".");
+            return new 
OutputFileName(prependedPrefix(originalFileName.substring(0, lastDotPosition)), 
+                    originalFileName.substring(lastDotPosition));
+        }
+
+        @VisibleForTesting static String prependedPrefix(String prefix) {
+            return Strings.padStart(prefix, MIN_LENGTH, PAD_CHAR);
+        }
+
+        private final String prefix;
+        private final String suffix;
+
+        private OutputFileName(String prefix, String suffix) {
+            this.prefix = prefix;
+            this.suffix = suffix;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public String getSuffix() {
+            return suffix;
+        }
+    }
 }
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/standard/src/main/java/org/apache/james/transport/mailets/WrapText.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/WrapText.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/WrapText.java
index a964bf4..04b41a6 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/WrapText.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/WrapText.java
@@ -46,12 +46,6 @@ public class WrapText extends GenericMailet {
     public String getMailetInfo() {
         return "WrapText";
     }
-
-    private static boolean getBooleanParameter(String v, boolean def) {
-        return def ? 
-                !(v != null && (v.equalsIgnoreCase("false") || 
v.equalsIgnoreCase("no"))) : 
-                    v != null && (v.equalsIgnoreCase("true") || 
v.equalsIgnoreCase("yes"))  ;
-    }
     
     public void init() throws MailetException {
         optionFlowedDelsp = 
getBooleanParameter(getInitParameter(PARAMETER_NAME_FLOWED_DELSP), 
optionFlowedDelsp);

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
index a9bd6e8..add3c55 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/StripAttachmentTest.java
@@ -19,134 +19,171 @@
 
 package org.apache.james.transport.mailets;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import javax.mail.MessagingException;
+import javax.mail.Part;
 import javax.mail.Session;
+import javax.mail.internet.InternetHeaders;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.james.transport.mailets.StripAttachment.OutputFileName;
 import org.apache.mailet.Mail;
 import org.apache.mailet.Mailet;
+import org.apache.mailet.MailetException;
 import org.apache.mailet.base.test.FakeMail;
 import org.apache.mailet.base.test.FakeMailetConfig;
-import org.junit.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
 
 public class StripAttachmentTest {
 
+    private static final String EXPECTED_ATTACHMENT_CONTENT = 
"\u0023\u00A4\u00E3\u00E0\u00E9";
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+    @Rule
+    public TemporaryFolder folder = new TemporaryFolder();
+
+    private String folderPath;
+
+    @Before
+    public void setUp() throws IOException {
+        folderPath = folder.getRoot().getPath() + "/";
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        folder.delete();
+    }
+
     @Test
-    public void testSimpleAttachment() throws MessagingException, IOException {
+    public void serviceShouldNotModifyMailWhenNotMultipart() throws 
MessagingException, IOException {
         Mailet mailet = initMailet();
+        MimeMessage message = mimeMessage();
 
-        MimeMessage message = new MimeMessage(Session
-                .getDefaultInstance(new Properties()));
+        MimeBodyPart part = new MimeBodyPart();
+        part.setText("simple text");
+        
+        message.setSubject("test");
+        message.setContent(part, "text/plain");
+        message.saveChanges();
 
-        MimeMultipart mm = new MimeMultipart();
-        MimeBodyPart mp = new MimeBodyPart();
-        mp.setText("simple text");
-        mm.addBodyPart(mp);
-        String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
-        MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\nContent-Type: 
application/octet-stream; charset=utf-8\r\n\r\n"
-                        + body).getBytes("UTF-8")));
-        mp2.setDisposition("attachment");
-        mp2.setFileName("10.tmp");
-        mm.addBodyPart(mp2);
-        String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
-        MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\nContent-Type: 
application/octet-stream; charset=utf-8\r\n\r\n"
-                        + body2).getBytes("UTF-8")));
-        mp3.setDisposition("attachment");
-        mp3.setFileName("temp.zip");
-        mm.addBodyPart(mp3);
+        MimeMessage expectedMessage = mimeMessage();
         message.setSubject("test");
-        message.setContent(mm);
+        message.setContent(part, "text/plain");
         message.saveChanges();
 
         Mail mail = FakeMail.builder()
                 .mimeMessage(message)
                 .build();
+        Mail expectedMail = FakeMail.builder()
+                .mimeMessage(expectedMessage)
+                .build();
 
         mailet.service(mail);
 
-        ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
-        mail.getMessage().writeTo(rawMessage,
-                new String[]{"Bcc", "Content-Length", "Message-ID"});
+        assertThat(mail).isEqualToComparingFieldByField(expectedMail);
+        
assertThat(mail.getMessage()).isEqualToComparingFieldByField(expectedMessage);
+        assertThat(mail.getMessage().getContent()).isEqualTo(part);
+    }
+    
+    @Test
+    public void serviceShouldSaveAttachmentInAFolderWhenPatternMatch() throws 
MessagingException, IOException {
+        Mailet mailet = initMailet();
+        MimeMessage message = mimeMessage();
+
+        MimeMultipart multiPart = new MimeMultipart();
+        MimeBodyPart textPart = new MimeBodyPart();
+        textPart.setText("simple text");
+        multiPart.addBodyPart(textPart);
+        String expectedAttachmentContent = EXPECTED_ATTACHMENT_CONTENT;
+        
multiPart.addBodyPart(createAttachmentBodyPart(expectedAttachmentContent, 
"10.tmp"));
+        
multiPart.addBodyPart(createAttachmentBodyPart("\u0014\u00A3\u00E1\u00E2\u00E4",
 "temp.zip"));
+        
+        message.setSubject("test");
+        message.setContent(multiPart);
+        message.saveChanges();
+
+        Mail mail = FakeMail.builder()
+                .mimeMessage(message)
+                .build();
+
+        mailet.service(mail);
 
         @SuppressWarnings("unchecked")
-        Collection<String> c = (Collection<String>) mail
-                .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
-        Assert.assertNotNull(c);
+        Collection<String> savedAttachments = (Collection<String>) 
mail.getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
+        assertThat(savedAttachments).isNotNull();
+        assertThat(savedAttachments).hasSize(1);
 
-        Assert.assertEquals(1, c.size());
+        String attachmentFilename = savedAttachments.iterator().next();
 
-        String name = c.iterator().next();
+        assertThat(new File(folderPath + 
attachmentFilename)).hasContent(expectedAttachmentContent);
+    }
 
-        File f = new File("./" + name);
-        try {
-            InputStream is = new FileInputStream(f);
-            String savedFile = toString(is);
-            is.close();
-            Assert.assertEquals(body, savedFile);
-        } finally {
-            FileUtils.deleteQuietly(f);
-        }
+    private MimeMessage mimeMessage() {
+        return new MimeMessage(Session
+                .getDefaultInstance(new Properties()));
+    }
+
+    private MimeBodyPart createAttachmentBodyPart(String body, String 
fileName) throws MessagingException, UnsupportedEncodingException {
+        MimeBodyPart part = createBodyPart(body);
+        part.setDisposition("attachment");
+        part.setFileName(fileName);
+        return part;
     }
 
-    public String toString(InputStream is) throws IOException {
-        final ByteArrayOutputStream sw = new ByteArrayOutputStream();
-        final byte[] buffer = new byte[1024];
-        int n;
-        while (-1 != (n = is.read(buffer))) {
-            System.err.println(new String(buffer, 0, n));
-            sw.write(buffer, 0, n);
-        }
-        return sw.toString("UTF-8");
+    private MimeBodyPart createBodyPart(String body) throws 
MessagingException, UnsupportedEncodingException {
+        return new MimeBodyPart(new ByteArrayInputStream(
+                ("Content-Transfer-Encoding: 8bit\r\nContent-Type: 
application/octet-stream; charset=utf-8\r\n\r\n"
+                        + body).getBytes("UTF-8")));
     }
 
     @Test
-    public void testSimpleAttachment2() throws MessagingException, IOException 
{
+    public void 
serviceShouldSaveAttachmentInAFolderWhenNotPatternDoesntMatch() throws 
MessagingException, IOException {
         Mailet mailet = new StripAttachment();
 
         FakeMailetConfig mci = FakeMailetConfig.builder()
                 .mailetName("Test")
-                .setProperty("directory", "./")
+                .setProperty("directory", folderPath)
                 .setProperty("remove", "all")
                 .setProperty("notpattern", "^(winmail\\.dat$)")
                 .build();
         mailet.init(mci);
 
-        MimeMessage message = new MimeMessage(Session
-                .getDefaultInstance(new Properties()));
+        MimeMessage message = mimeMessage();
 
-        MimeMultipart mm = new MimeMultipart();
-        MimeBodyPart mp = new MimeBodyPart();
-        mp.setText("simple text");
-        mm.addBodyPart(mp);
-        String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
-        MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\n\r\n" + 
body).getBytes("UTF-8")));
-        mp2.setDisposition("attachment");
-        mp2.setFileName("temp.tmp");
-        mm.addBodyPart(mp2);
-        String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
-        MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\n\r\n" + 
body2).getBytes("UTF-8")));
-        mp3.setDisposition("attachment");
-        mp3.setFileName("winmail.dat");
-        mm.addBodyPart(mp3);
+        MimeMultipart multiPart = new MimeMultipart();
+        MimeBodyPart part = new MimeBodyPart();
+        part.setText("simple text");
+        multiPart.addBodyPart(part);
+        String expectedAttachmentContent = EXPECTED_ATTACHMENT_CONTENT;
+        
multiPart.addBodyPart(createAttachmentBodyPart(expectedAttachmentContent, 
"temp.tmp"));
+        
multiPart.addBodyPart(createAttachmentBodyPart("\u0014\u00A3\u00E1\u00E2\u00E4",
 "winmail.dat"));
+        
         message.setSubject("test");
-        message.setContent(mm);
+        message.setContent(multiPart);
         message.saveChanges();
 
         Mail mail = FakeMail.builder()
@@ -155,201 +192,533 @@ public class StripAttachmentTest {
 
         mailet.service(mail);
 
-        ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
-        mail.getMessage().writeTo(rawMessage,
-                new String[]{"Bcc", "Content-Length", "Message-ID"});
-        // String res = rawMessage.toString();
-
         @SuppressWarnings("unchecked")
-        Collection<String> c = (Collection<String>) mail
-                .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
-        Assert.assertNotNull(c);
-
-        Assert.assertEquals(1, c.size());
+        Collection<String> savedAttachments = (Collection<String>) 
mail.getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
+        assertThat(savedAttachments).isNotNull();
+        assertThat(savedAttachments).hasSize(1);
 
-        String name = c.iterator().next();
+        String attachmentFilename = savedAttachments.iterator().next();
 
-        File f = new File("./" + name);
-        try {
-            InputStream is = new FileInputStream(f);
-            String savedFile = toString(is);
-            is.close();
-            Assert.assertEquals(body, savedFile);
-        } finally {
-            FileUtils.deleteQuietly(f);
-        }
+        assertThat(new File(folderPath + 
attachmentFilename)).hasContent(expectedAttachmentContent);
     }
 
     @Test
-    public void testSimpleAttachment3() throws MessagingException, IOException 
{
+    public void 
serviceShouldDecodeFilenameAndSaveAttachmentInAFolderWhenPatternMatchAndDecodeFilenameTrue()
 throws MessagingException, IOException {
         Mailet mailet = initMailet();
 
-        // System.setProperty("mail.mime.decodefilename", "true");
+        MimeMessage message = mimeMessage();
 
-        MimeMessage message = new MimeMessage(Session
-                .getDefaultInstance(new Properties()));
-
-        MimeMultipart mm = new MimeMultipart();
-        MimeBodyPart mp = new MimeBodyPart();
-        mp.setText("simple text");
-        mm.addBodyPart(mp);
-        String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
-        MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\n\r\n" + 
body).getBytes("UTF-8")));
-        mp2.setDisposition("attachment");
-        mp2
-                
.setFileName("=?iso-8859-15?Q?=E9_++++Pubblicit=E0_=E9_vietata____Milano9052.tmp?=");
-        mm.addBodyPart(mp2);
-        String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
-        MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\n\r\n" + 
body2).getBytes("UTF-8")));
-        mp3.setDisposition("attachment");
-        mp3.setFileName("temp.zip");
-        mm.addBodyPart(mp3);
+        MimeMultipart multiPart = new MimeMultipart();
+        MimeBodyPart part = new MimeBodyPart();
+        part.setText("simple text");
+        multiPart.addBodyPart(part);
+        String expectedAttachmentContent = EXPECTED_ATTACHMENT_CONTENT;
+        
multiPart.addBodyPart(createAttachmentBodyPart(expectedAttachmentContent, 
"=?iso-8859-15?Q?=E9_++++Pubblicit=E0_=E9_vietata____Milano9052.tmp?="));
+        
multiPart.addBodyPart(createAttachmentBodyPart("\u0014\u00A3\u00E1\u00E2\u00E4",
 "temp.zip"));
+        
         message.setSubject("test");
-        message.setContent(mm);
+        message.setContent(multiPart);
         message.saveChanges();
 
-        // message.writeTo(System.out);
-        // System.out.println("--------------------------\n\n\n");
-
         Mail mail = FakeMail.builder()
                 .mimeMessage(message)
                 .build();
 
         mailet.service(mail);
 
-        ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
-        mail.getMessage().writeTo(rawMessage,
-                new String[]{"Bcc", "Content-Length", "Message-ID"});
-        // String res = rawMessage.toString();
+        @SuppressWarnings("unchecked")
+        Collection<String> savedAttachments = (Collection<String>) 
mail.getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
+        assertThat(savedAttachments).isNotNull();
+        assertThat(savedAttachments).hasSize(1);
+
+        String name = savedAttachments.iterator().next();
+
+        
assertThat(name.startsWith("e_Pubblicita_e_vietata_Milano9052")).isTrue();
+        
+        assertThat(new File(folderPath + 
name)).hasContent(expectedAttachmentContent);
+    }
+
+    @Test
+    public void 
serviceShouldSaveFilenameAttachmentAndFileContentInCustomAttribute() throws 
MessagingException, IOException {
+        StripAttachment mailet = new StripAttachment();
+
+        String customAttribute = "my.custom.attribute";
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*\\.tmp")
+                .setProperty("attribute", customAttribute)
+                .build();
+        mailet.init(mci);
+        
+        MimeMessage message = mimeMessage();
+
+        MimeMultipart multiPart = new MimeMultipart();
+        MimeBodyPart part = new MimeBodyPart();
+        part.setText("simple text");
+        multiPart.addBodyPart(part);
+        String expectedKey = "10.tmp";
+        
multiPart.addBodyPart(createAttachmentBodyPart(EXPECTED_ATTACHMENT_CONTENT, 
expectedKey));
+        
multiPart.addBodyPart(createAttachmentBodyPart("\u0014\u00A3\u00E1\u00E2\u00E4",
 "temp.zip"));
+        
+        message.setSubject("test");
+        message.setContent(multiPart);
+        message.saveChanges();
+
+        Mail mail = FakeMail.builder()
+                .mimeMessage(message)
+                .build();
+
+        mailet.service(mail);
 
         @SuppressWarnings("unchecked")
-        Collection<String> c = (Collection<String>) mail
-                .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
-        Assert.assertNotNull(c);
+        Map<String, byte[]> saved = (Map<String, byte[]>) 
mail.getAttribute(customAttribute);
+        assertThat(saved).hasSize(1);
+        assertThat(saved).containsKey(expectedKey);
+        MimeBodyPart savedBodyPart = new MimeBodyPart(new 
ByteArrayInputStream(saved.get(expectedKey)));
+        String content = IOUtils.toString(savedBodyPart.getInputStream());
+        assertThat(content).isEqualTo(EXPECTED_ATTACHMENT_CONTENT);
+    }
 
-        Assert.assertEquals(1, c.size());
+    @Test
+    public void initShouldThrowWhenPatternAndNotPatternAreNull() throws 
MessagingException {
+        Mailet mailet = new StripAttachment();
 
-        String name = c.iterator().next();
-        // System.out.println("--------------------------\n\n\n");
-        // System.out.println(name);
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .build();
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("At least one of 'pattern' or 
'notpattern' parameter should be provided.");
+        mailet.init(mci);
+    }
 
-        
Assert.assertTrue(name.startsWith("e_Pubblicita_e_vietata_Milano9052"));
+    @Test
+    public void initShouldThrowWhenWrongPattern() throws MessagingException {
+        Mailet mailet = new StripAttachment();
 
-        File f = new File("./" + name);
-        try {
-            InputStream is = new FileInputStream(f);
-            String savedFile = toString(is);
-            is.close();
-            Assert.assertEquals(body, savedFile);
-        } finally {
-            FileUtils.deleteQuietly(f);
-        }
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("pattern", ".****\\.tmp")
+                .build();
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("Could not compile regex 
[.****\\.tmp]");
+        mailet.init(mci);
+    }
+
+    @Test
+    public void initShouldThrowWhenWrongNotPattern() throws MessagingException 
{
+        Mailet mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("notpattern", ".****\\.tmp")
+                .build();
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("Could not compile regex 
[.****\\.tmp]");
+        mailet.init(mci);
+    }
+
+    @Test
+    public void initShouldThrowWhenRemoveParameterIsUnknown() throws 
MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "unknown")
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("Unknown remove parameter value 
'unknown' waiting for 'matched', 'all' or 'no'.");
+        mailet.init(mci);
+    }
+
+    @Test
+    public void initShouldSetRemoveParameterWhenEqualsMatched() throws 
MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+
+        mailet.init(mci);
+        
assertThat(mailet.removeAttachments).isEqualTo(StripAttachment.REMOVE_MATCHED);
     }
 
     @Test
-    public void testToAndFromAttributes() throws MessagingException,
-            IOException {
-        Mailet strip = new StripAttachment();
+    public void initShouldSetRemoveParameterWhenEqualsAll() throws 
MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
         FakeMailetConfig mci = FakeMailetConfig.builder()
                 .mailetName("Test")
-                .setProperty("attribute", "my.attribute")
                 .setProperty("remove", "all")
-                .setProperty("notpattern", ".*\\.tmp.*")
+                .setProperty("pattern", ".*\\.tmp")
                 .build();
-        strip.init(mci);
 
-        Mailet recover = new RecoverAttachment();
-        FakeMailetConfig mci2 = FakeMailetConfig.builder()
+        mailet.init(mci);
+        
assertThat(mailet.removeAttachments).isEqualTo(StripAttachment.REMOVE_ALL);
+    }
+
+    @Test
+    public void initShouldSetRemoveParameterWhenEqualsNo() throws 
MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
                 .mailetName("Test")
-                .setProperty("attribute", "my.attribute")
+                .setProperty("remove", "no")
+                .setProperty("pattern", ".*\\.tmp")
                 .build();
-        recover.init(mci2);
 
-        Mailet onlyText = new OnlyText();
-        onlyText.init(FakeMailetConfig.builder()
+        mailet.init(mci);
+        
assertThat(mailet.removeAttachments).isEqualTo(StripAttachment.REMOVE_NONE);
+    }
+
+    @Test
+    public void initShouldSetRemoveParameterDefaultValueWhenNotGiven() throws 
MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
                 .mailetName("Test")
-                .build());
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
 
-        MimeMessage message = new MimeMessage(Session
-                .getDefaultInstance(new Properties()));
+        mailet.init(mci);
+        assertThat(mailet.removeAttachments).isEqualTo("no");
+    }
 
-        MimeMultipart mm = new MimeMultipart();
-        MimeBodyPart mp = new MimeBodyPart();
-        mp.setText("simple text");
-        mm.addBodyPart(mp);
-        String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
-        MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\nContent-Type: 
application/octet-stream; charset=utf-8\r\n\r\n"
-                        + body).getBytes("UTF-8")));
-        mp2.setDisposition("attachment");
-        mp2
-                
.setFileName("=?iso-8859-15?Q?=E9_++++Pubblicit=E0_=E9_vietata____Milano9052.tmp?=");
-        mm.addBodyPart(mp2);
-        String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
-        MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
-                ("Content-Transfer-Encoding: 8bit\r\nContent-Type: 
application/octet-stream; charset=utf-8\r\n\r\n"
-                        + body2).getBytes("UTF-8")));
-        mp3.setDisposition("attachment");
-        mp3.setFileName("temp.zip");
-        mm.addBodyPart(mp3);
-        message.setSubject("test");
-        message.setContent(mm);
-        message.saveChanges();
-        Mail mail = FakeMail.builder()
-                .mimeMessage(message)
+    @Test
+    public void serviceShouldThrowWhenUnretrievableMessage() throws 
MessagingException {
+        Mailet mailet = initMailet();
+        
+        Mail mail = mock(Mail.class);
+        when(mail.getMessage())
+            .thenThrow(new MessagingException("Test exception"));
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("Could not retrieve message from Mail 
object");
+        
+        mailet.service(mail);
+    }
+
+    @Test
+    public void serviceShouldThrowWhenUnretrievableContentTypeMessage() throws 
MessagingException {
+        Mailet mailet = initMailet();
+
+        MimeMessage message = mock(MimeMessage.class);
+        Mail mail = mock(Mail.class);
+        when(mail.getMessage())
+            .thenReturn(message);
+        when(message.isMimeType("multipart/*"))
+            .thenThrow(new MessagingException("Test exception"));
+
+        expectedException.expect(MailetException.class);
+        expectedException.expectMessage("Could not retrieve contenttype of 
MimePart.");
+        
+        mailet.service(mail);
+    }
+
+    @Test
+    public void getMailetInfoShouldReturn() throws MessagingException {
+        StripAttachment mailet = new StripAttachment();
+
+        assertThat(mailet.getMailetInfo()).isEqualTo("StripAttachment");
+    }
+
+    @Test
+    public void 
processMultipartPartMessageShouldReturnFalseWhenPartIsNotMultipart() throws 
Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
+        Part part = new MimeBodyPart(new ByteArrayInputStream(new byte[0]));
+        Mail mail = mock(Mail.class);
+        //When
+        boolean actual = mailet.processMultipartPartMessage(part, mail);
+        //Then
+        assertThat(actual).isFalse();
+    }
+
+    @Test
+    public void 
processMultipartPartMessageShouldReturnTrueWhenAtLeastOneMultipartShouldHaveBeenRemoved()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
+
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "all")
+                .setProperty("pattern", ".*")
                 .build();
+        mailet.init(mci);
+        MimeMultipart multiPart = new MimeMultipart();
+        
+        MimeBodyPart part = new MimeBodyPart(new ByteArrayInputStream(new 
byte[0]));
+        part.setFileName("removeMe.tmp");
+        multiPart.addBodyPart(part);
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPart);
+        message.saveChanges();
+        Mail mail = mock(Mail.class);
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(actual).isTrue();
+    }
 
-        Assert.assertTrue(mail.getMessage().getContent() instanceof 
MimeMultipart);
-        Assert.assertEquals(3, ((MimeMultipart) mail.getMessage().getContent())
-                .getCount());
+    @Test
+    public void 
processMultipartPartMessageShouldReturnTrueWhenAtLeastOneMultipartShouldHaveBeenRemovedAndPartialRemove()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        strip.service(mail);
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("pattern", ".*")
+                .build();
+        mailet.init(mci);
+        MimeMultipart multiPart = new MimeMultipart();
+        
+        MimeBodyPart part = new MimeBodyPart(new ByteArrayInputStream(new 
byte[0]));
+        part.setFileName("removeMe.tmp");
+        multiPart.addBodyPart(part);
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPart);
+        message.saveChanges();
+        Mail mail = mock(Mail.class);
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(actual).isTrue();
+    }
 
-        Assert.assertTrue(mail.getMessage().getContent() instanceof 
MimeMultipart);
-        Assert.assertEquals(1, ((MimeMultipart) mail.getMessage().getContent())
-                .getCount());
+    @Test
+    public void 
processMultipartPartMessageShouldPutTwoPartsInDefaultAttributeWhenTwoPartsMatch()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        onlyText.service(mail);
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*")
+                .build();
+        mailet.init(mci);
+        MimeMultipart multiPart = new MimeMultipart();
+        
+        MimeBodyPart part = new MimeBodyPart(new ByteArrayInputStream(new 
byte[0]));
+        part.setFileName("removeMe.tmp");
+        multiPart.addBodyPart(part);
+        multiPart.addBodyPart(part);
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPart);
+        message.saveChanges();
+        Mail mail = FakeMail.builder().build();
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(actual).isTrue();
+        @SuppressWarnings("unchecked")
+        List<String> values = 
(List<String>)mail.getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
+        assertThat(values).hasSize(2);
+    }
 
-        Assert.assertFalse(mail.getMessage().getContent() instanceof 
MimeMultipart);
+    @Test
+    public void 
processMultipartPartMessageShouldPutTwoPartsInCustomAttributeWhenTwoPartsMatch()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        Assert.assertEquals("simple text", mail.getMessage().getContent());
+        String customAttribute = "my.custom.attribute";
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*")
+                .setProperty("attribute", customAttribute)
+                .build();
+        mailet.init(mci);
+        
+        // Message with two matching attachments
+        MimeMultipart multiPart = new MimeMultipart();
+        MimeBodyPart attachmentPart1 = new MimeBodyPart(new 
ByteArrayInputStream(new byte[0]));
+        attachmentPart1.setFileName("removeMe1.tmp");
+        multiPart.addBodyPart(attachmentPart1);
+        MimeBodyPart attachmentPart2 = new MimeBodyPart(new 
ByteArrayInputStream(new byte[0]));
+        attachmentPart2.setFileName("removeMe2.tmp");
+        multiPart.addBodyPart(attachmentPart2);
+        
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPart);
+        message.saveChanges();
+        
+        Mail mail = FakeMail.builder().build();
+        
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        
+        //Then
+        assertThat(actual).isTrue();
+        @SuppressWarnings("unchecked")
+        Map<String, byte[]> values = (Map<String, 
byte[]>)mail.getAttribute(customAttribute);
+        assertThat(values).hasSize(2);
+    }
 
-        // prova per caricare il mime message da input stream che altrimenti
-        // javamail si comporta differentemente.
-        String mimeSource = "Message-ID: 
<26194423.21197328775426.JavaMail.bago@bagovista>\r\nSubject: 
test\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; 
charset=us-ascii\r\nContent-Transfer-Encoding: 7bit\r\n\r\nsimple text";
+    @Test
+    public void 
processMultipartPartMessageShouldReturnTrueWhenAtLeastOneSubMultipartShouldHaveBeenRemoved()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        MimeMessage mmNew = new MimeMessage(Session
-                .getDefaultInstance(new Properties()),
-                new ByteArrayInputStream(mimeSource.getBytes("UTF-8")));
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "all")
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+        mailet .init(mci);
+
+        MimeBodyPart attachmentPart = new MimeBodyPart(new 
ByteArrayInputStream(new byte[0]));
+        attachmentPart.setFileName("removeMe.tmp");
+        
+        MimeMultipart subMultiPart = new MimeMultipart();
+        subMultiPart.addBodyPart(attachmentPart);
+        
+        MimeMessage subMessage = mimeMessage();
+        subMessage.setContent(subMultiPart);
+        subMessage.saveChanges();
+        
+        MimeMultipart multiPartMixed = new MimeMultipart();
+        multiPartMixed.addBodyPart(new MimeBodyPart(new InternetHeaders(new 
ByteArrayInputStream("Content-Type: 
multipart/mixed".getBytes(Charsets.US_ASCII)))
+                , IOUtils.toByteArray(subMessage.getInputStream())));
+
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPartMixed);
+        message.saveChanges();
+        Mail mail = mock(Mail.class);
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(actual).isTrue();
+    }
 
-        mmNew.writeTo(System.out);
-        mail.setMessage(mmNew);
+    @Test
+    public void 
processMultipartPartMessageShouldReturnFalseWhenNoPartHasBeenRemovedInSubMultipart()
 throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        recover.service(mail);
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "matched")
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+        mailet.init(mci);
+        MimeMultipart mainMultiPart = new MimeMultipart();
+        MimeMessage subMessage = mimeMessage();
+        MimeMultipart subMultiPart = new MimeMultipart();
+        MimeBodyPart part = new MimeBodyPart(new ByteArrayInputStream(new 
byte[0]));
+        part.setFileName("dontRemoveMe.other");
+        subMultiPart.addBodyPart(part);
+        subMessage.setContent(subMultiPart);
+        subMessage.saveChanges();
+        mainMultiPart.addBodyPart(new MimeBodyPart(new InternetHeaders(new 
ByteArrayInputStream("Content-Type: 
multipart/mixed".getBytes(Charsets.US_ASCII)))
+                ,
+                IOUtils.toByteArray(subMessage.getInputStream())));
+        MimeMessage message = mimeMessage();
+        message.setContent(mainMultiPart);
+        message.saveChanges();
+        Mail mail = mock(Mail.class);
+        //When
+        boolean actual = mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(actual).isFalse();
+    }
 
-        Assert.assertTrue(mail.getMessage().getContent() instanceof 
MimeMultipart);
-        Assert.assertEquals(2, ((MimeMultipart) mail.getMessage().getContent())
-                .getCount());
+    @Test
+    public void 
processMultipartPartMessageShouldRemovePartWhenOnePartShouldHaveBeenRemoved() 
throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
 
-        Object actual = ((MimeMultipart) mail.getMessage().getContent())
-                .getBodyPart(1).getContent();
-        if (actual instanceof ByteArrayInputStream) {
-            Assert.assertEquals(body2, toString((ByteArrayInputStream) 
actual));
-        } else {
-            Assert.assertEquals(body2, actual);
-        }
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .setProperty("remove", "all")
+                .setProperty("pattern", ".*")
+                .build();
+        mailet.init(mci);
+        MimeMultipart multiPart = new MimeMultipart();
+        
+        MimeBodyPart part = new MimeBodyPart(new ByteArrayInputStream(new 
byte[0]));
+        part.setFileName("removeMe.tmp");
+        multiPart.addBodyPart(part);
+        MimeMessage message = mimeMessage();
+        message.setContent(multiPart);
+        message.saveChanges();
+        Mail mail = mock(Mail.class);
+        //When
+        mailet.processMultipartPartMessage(message, mail);
+        //Then
+        assertThat(multiPart.getCount()).isZero();
+    }
 
+    @Test
+    public void saveAttachmentShouldUsePartNameIfNoFilename() throws Exception 
{
+        //Given
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+        mailet.init(mci);
+        Part part = new MimeBodyPart(new ByteArrayInputStream(new byte[0]));
+        part.setFileName("example.tmp");
+        //When
+        Optional<String> maybeFilename = mailet.saveAttachmentToFile(part, 
Optional.<String> absent());
+        //Then
+        assertThat(maybeFilename).isPresent();
+        String filename = maybeFilename.get();
+        assertThat(filename).startsWith("example");
+        assertThat(filename).endsWith(".tmp");
     }
+    
+    @Test
+    public void saveAttachmentShouldReturnAbsentWhenNoFilenameAtAll() throws 
Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*\\.tmp")
+                .build();
+        mailet.init(mci);
+        Part part = new MimeBodyPart(new ByteArrayInputStream(new byte[0]));
 
+        Optional<String> maybeFilename = mailet.saveAttachmentToFile(part, 
Optional.<String> absent());
+        assertThat(maybeFilename).isAbsent();
+    }
+    
+    @Test
+    public void saveAttachmentShouldAddBinExtensionWhenNoFileNameExtension() 
throws Exception {
+        //Given
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("directory", folderPath)
+                .setProperty("pattern", ".*")
+                .build();
+        mailet.init(mci);
+        Part part = new MimeBodyPart(new ByteArrayInputStream(new byte[0]));
+        String fileName = "exampleWithoutSuffix";
+        //When
+        Optional<String> maybeFilename = mailet.saveAttachmentToFile(part, 
Optional.of(fileName));
+        //Then
+        assertThat(maybeFilename).isPresent();
+        String filename = maybeFilename.get();
+        assertThat(filename).startsWith("exampleWithoutSuffix");
+        assertThat(filename).endsWith(".bin");
+    }
+    
     private Mailet initMailet() throws MessagingException {
         Mailet mailet = new StripAttachment();
 
         FakeMailetConfig mci = FakeMailetConfig.builder()
                 .mailetName("Test")
-                .setProperty("directory", "./")
+                .setProperty("directory", folderPath)
                 .setProperty("remove", "all")
                 .setProperty("pattern", ".*\\.tmp")
                 .setProperty("decodeFilename", "true")
@@ -373,4 +742,109 @@ public class StripAttachmentTest {
         return mailet;
     }
 
+    @Test
+    public void fileNameMatchesShouldThrowWhenPatternIsNull() throws Exception 
{
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        expectedException.expect(NullPointerException.class);
+        mailet.fileNameMatches(null);
+    }
+
+    @Test
+    public void fileNameMatchesShouldReturnFalseWhenPatternDoesntMatch() 
throws Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("not matching")).isFalse();
+    }
+
+    @Test
+    public void fileNameMatchesShouldReturnTrueWhenPatternMatches() throws 
Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("I've got a pattern.")).isTrue();
+    }
+
+    @Test
+    public void fileNameMatchesShouldReturnFalseWhenNotPatternMatches() throws 
Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("notpattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("I've got a pattern.")).isFalse();
+    }
+
+    @Test
+    public void fileNameMatchesShouldReturnTrueWhenNotPatternDoesntMatch() 
throws Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("notpattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("not matching")).isTrue();
+    }
+
+    @Test
+    public void 
fileNameMatchesShouldReturnFalseWhenPatternAndNotPatternAreTheSame() throws 
Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .setProperty("notpattern", ".*pattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("not matching")).isFalse();
+        assertThat(mailet.fileNameMatches("I've got a pattern.")).isFalse();
+    }
+
+    @Test
+    public void 
fileNameMatchesShouldReturnTrueWhenPatternMatchesAndNotPatternDoesntMatch() 
throws Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .setProperty("notpattern", ".*notpattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("I've got a pattern.")).isTrue();
+    }
+
+    @Test
+    public void 
fileNameMatchesShouldReturnTrueWhenPatternDoesntMatchesAndNotPatternDoesntMatch()
 throws Exception {
+        StripAttachment mailet = new StripAttachment();
+        FakeMailetConfig mci = FakeMailetConfig.builder()
+                .setProperty("pattern", ".*pattern.*")
+                .setProperty("notpattern", ".*notpattern.*")
+                .build();
+        mailet.init(mci);
+        
+        assertThat(mailet.fileNameMatches("o.")).isTrue();
+    }
+
+    @Test
+    public void 
prependedPrefixShouldAddUnderscoreWhenPrefixIsLessThanThreeCharacters() {
+        String prefix = OutputFileName.prependedPrefix("a");
+        assertThat(prefix).isEqualTo("__a");
+    }
+
+    @Test
+    public void 
prependedPrefixShouldReturnPrefixWhenPrefixIsGreaterThanThreeCharacters() {
+        String expectedPrefix = "abcd";
+        String prefix = OutputFileName.prependedPrefix(expectedPrefix);
+        assertThat(prefix).isEqualTo(expectedPrefix);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml 
b/server/mailet/integration-testing/pom.xml
index 44c011d..51a9ac3 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -176,6 +176,12 @@
                   <version>${project.version}</version>
               </dependency>
               <dependency>
+                  <groupId>org.apache.james</groupId>
+                  <artifactId>apache-mailet-base</artifactId>
+                  <type>test-jar</type>
+                  <scope>test</scope>
+              </dependency>
+              <dependency>
                   <groupId>ch.qos.logback</groupId>
                   <artifactId>logback-classic</artifactId>
                   <version>1.1.6</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0e49d8c2/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/utils/SMTPMessageSender.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/utils/SMTPMessageSender.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/utils/SMTPMessageSender.java
index 410bd52..5ee5931 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/utils/SMTPMessageSender.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/utils/SMTPMessageSender.java
@@ -19,15 +19,22 @@
 
 package org.apache.james.mailets.utils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.IOException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 
+import javax.mail.Message;
+import javax.mail.MessagingException;
+
 import org.apache.commons.net.smtp.AuthenticatingSMTPClient;
 import org.apache.commons.net.smtp.SMTPClient;
+import org.apache.mailet.Mail;
 
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
 import com.google.common.base.Throwables;
 
 public class SMTPMessageSender implements Closeable {
@@ -69,6 +76,24 @@ public class SMTPMessageSender implements Closeable {
         }
     }
 
+    public void sendMessage(Mail mail) throws MessagingException {
+        try {
+            String from = mail.getSender().asString();
+            smtpClient.helo(senderDomain);
+            smtpClient.setSender(from);
+            smtpClient.rcpt("<" + Joiner.on(", ").join(mail.getRecipients()) + 
">");
+            smtpClient.sendShortMessageData(asString(mail.getMessage()));
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    private String asString(Message message) throws IOException, 
MessagingException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        message.writeTo(outputStream);
+        return new String(outputStream.toByteArray(), Charsets.UTF_8);
+    }
+
     public boolean messageHasBeenSent() throws IOException {
         return smtpClient.getReplyString()
             .contains("250 2.6.0 Message received");


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to