[MEAR-327] update to parent pom 39
diff --git a/pom.xml b/pom.xml
index dc8d7ba..b2b7232 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,4 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements. See the NOTICE file
@@ -18,14 +17,13 @@
   specific language governing permissions and limitations
   under the License.
 -->
-
 <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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>maven-plugins</artifactId>
     <groupId>org.apache.maven.plugins</groupId>
-    <version>37</version>
+    <artifactId>maven-plugins</artifactId>
+    <version>39</version>
     <relativePath />
   </parent>
 
@@ -36,31 +34,6 @@
   <name>Apache Maven EAR Plugin</name>
   <description>Generates a J2EE Enterprise Archive (EAR) file.</description>
 
-  <prerequisites>
-    <maven>${mavenVersion}</maven>
-  </prerequisites>
-
-  <scm>
-    <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-ear-plugin.git</connection>
-    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-ear-plugin.git</developerConnection>
-    <url>https://github.com/apache/maven-ear-plugin/tree/${project.scm.tag}</url>
-    <tag>HEAD</tag>
-  </scm>
-  <issueManagement>
-    <system>JIRA</system>
-    <url>https://issues.apache.org/jira/browse/MEAR</url>
-  </issueManagement>
-  <ciManagement>
-    <system>Jenkins</system>
-    <url>https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-ear-plugin/</url>
-  </ciManagement>
-  <distributionManagement>
-    <site>
-      <id>apache.website</id>
-      <url>scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}</url>
-    </site>
-  </distributionManagement>
-
   <contributors>
     <contributor>
       <name>Guillaume Boucherie</name>
@@ -79,6 +52,31 @@
     </contributor>
   </contributors>
 
+  <prerequisites>
+    <maven>${mavenVersion}</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-ear-plugin.git</connection>
+    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-ear-plugin.git</developerConnection>
+    <tag>HEAD</tag>
+    <url>https://github.com/apache/maven-ear-plugin/tree/${project.scm.tag}</url>
+  </scm>
+  <issueManagement>
+    <system>JIRA</system>
+    <url>https://issues.apache.org/jira/browse/MEAR</url>
+  </issueManagement>
+  <ciManagement>
+    <system>Jenkins</system>
+    <url>https://ci-maven.apache.org/job/Maven/job/maven-box/job/maven-ear-plugin/</url>
+  </ciManagement>
+  <distributionManagement>
+    <site>
+      <id>apache.website</id>
+      <url>scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}</url>
+    </site>
+  </distributionManagement>
+
   <properties>
     <mavenArchiverVersion>3.6.0</mavenArchiverVersion>
     <mavenFilteringVersion>3.3.1</mavenFilteringVersion>
@@ -195,28 +193,28 @@
   <build>
     <resources>
       <resource>
-        <directory>src/main/filtered-resources</directory>
         <filtering>true</filtering>
+        <directory>src/main/filtered-resources</directory>
       </resource>
     </resources>
     <testResources>
       <testResource>
-        <directory>src/test/resources</directory>
         <filtering>true</filtering>
+        <directory>src/test/resources</directory>
         <includes>
           <include>**/pom.xml</include>
         </includes>
       </testResource>
       <testResource>
-        <directory>src/test/resources</directory>
         <filtering>false</filtering>
+        <directory>src/test/resources</directory>
         <excludes>
           <exclude>**/pom.xml</exclude>
         </excludes>
       </testResource>
       <testResource>
-        <directory>src/test/filtered-resources</directory>
         <filtering>true</filtering>
+        <directory>src/test/filtered-resources</directory>
       </testResource>
     </testResources>
 
@@ -305,14 +303,6 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-failsafe-plugin</artifactId>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
             <configuration>
               <systemPropertyVariables>
                 <maven.home>${maven.home}</maven.home>
@@ -322,6 +312,14 @@
                 <basedirectory>${basedir}</basedirectory>
               </systemPropertyVariables>
             </configuration>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>integration-test</goal>
+                  <goal>verify</goal>
+                </goals>
+              </execution>
+            </executions>
           </plugin>
         </plugins>
       </build>
@@ -337,6 +335,10 @@
             <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
+              <configuration>
+                <showDeprecation>true</showDeprecation>
+                <release>${javaVersion}</release>
+              </configuration>
               <dependencies>
                 <dependency>
                   <groupId>org.apache.maven.shared</groupId>
@@ -344,10 +346,6 @@
                   <version>3.3.2</version>
                 </dependency>
               </dependencies>
-              <configuration>
-                <showDeprecation>true</showDeprecation>
-                <release>${javaVersion}</release>
-              </configuration>
             </plugin>
           </plugins>
         </pluginManagement>
diff --git a/src/main/java/org/apache/maven/plugins/ear/AbstractEarModule.java b/src/main/java/org/apache/maven/plugins/ear/AbstractEarModule.java
index 05026b0..6ac03ed 100644
--- a/src/main/java/org/apache/maven/plugins/ear/AbstractEarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/AbstractEarModule.java
@@ -1,455 +1,421 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.util.Set;

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugin.MojoFailureException;

-import org.apache.maven.plugins.ear.util.ArtifactRepository;

-import org.apache.maven.shared.mapping.MappingUtils;

-import org.codehaus.plexus.interpolation.InterpolationException;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * A base implementation of an {@link EarModule}.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public abstract class AbstractEarModule

-    implements EarModule

-{

-

-    /**

-     * The module element.

-     */

-    protected static final String MODULE_ELEMENT = "module";

-

-    /**

-     * The java module.

-     */

-    protected static final String JAVA_MODULE = "java";

-

-    /**

-     * The alt-dd module.

-     */

-    protected static final String ALT_DD = "alt-dd";

-

-    private Artifact artifact;

-

-    // Those are set by the configuration

-

-    private String groupId;

-

-    private String artifactId;

-

-    /**

-     * The type of the artifact

-     */

-    protected String type;

-

-    private String classifier;

-

-    /**

-     * The bundleDir.

-     */

-    protected String bundleDir;

-

-    /**

-     * The bundleFileName.

-     */

-    protected String bundleFileName;

-

-    /**

-     * excluded by default {@code false}.

-     */

-    protected Boolean excluded = Boolean.FALSE;

-

-    private String uri;

-

-    /**

-     * unpack

-     */

-    protected Boolean unpack = null;

-

-    /**

-     * The alternate deployment descriptor.

-     */

-    protected String altDeploymentDescriptor;

-

-    private String moduleId;

-

-    /**

-     * Directory of module which contains libraries packaged into module. {@code null} value means that module

-     * doesn't contain any library. Each module type can provide default value for this directory and this option

-     * can be used to override that default value. If module libraries are located at the root of module then use

-     * single slash (/) to configure that in POM. That is, a single slash is treated as an empty string.

-     */

-    protected String libDirectory;

-

-    /**

-     * If module is considered for inclusion into the Class-Path entry of MANIFEST.mf of other modules. {@code false}

-     * value leads to removal of the module from the Class-Path entry. {@code true} value leads to modification of the

-     * reference to the module in the Class-Path entry if such reference exists or leads to adding of the module into

-     * the Class-Path entry if such reference doesn't exist. Removal, modification or adding of the reference in the

-     * Class-Path entry depends on libDirectory property of another module and on skinnyWars / skinnyModules parameters

-     * of EAR Plugin.

-     */

-    protected boolean classPathItem;

-

-    // This is injected once the module has been built.

-

-    /**

-     * The {@link EarExecutionContext}

-     */

-    protected EarExecutionContext earExecutionContext;

-

-    /**

-     * Empty constructor to be used when the module is built based on the configuration.

-     */

-    public AbstractEarModule()

-    {

-    }

-

-    /**

-     * Creates an ear module from the artifact.

-     * 

-     * @param a the artifact

-     */

-    public AbstractEarModule( Artifact a )

-    {

-        this.artifact = a;

-        this.groupId = a.getGroupId();

-        this.artifactId = a.getArtifactId();

-        this.type = a.getType();

-        this.classifier = a.getClassifier();

-        this.bundleDir = null;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void setEarExecutionContext( EarExecutionContext earExecutionContext )

-    {

-        this.earExecutionContext = earExecutionContext;

-    }

-

-    /** {@inheritDoc} */

-    public void resolveArtifact( Set<Artifact> artifacts )

-        throws EarPluginException, MojoFailureException

-    {

-        // If the artifact is already set no need to resolve it

-        if ( artifact == null )

-        {

-            // Make sure that at least the groupId and the artifactId are specified

-            if ( groupId == null || artifactId == null )

-            {

-                throw new MojoFailureException( "Could not resolve artifact[" + groupId + ":" + artifactId + ":"

-                    + getType() + "]" );

-            }

-            final ArtifactRepository ar = earExecutionContext.getArtifactRepository();

-            artifact = ar.getUniqueArtifact( groupId, artifactId, getType(), classifier );

-            // Artifact has not been found

-            if ( artifact == null )

-            {

-                Set<Artifact> candidates = ar.getArtifacts( groupId, artifactId, getType() );

-                if ( candidates.size() > 1 )

-                {

-                    throw new MojoFailureException( "Artifact[" + this + "] has " + candidates.size()

-                        + " candidates, please provide a classifier." );

-                }

-                else

-                {

-                    throw new MojoFailureException( "Artifact[" + this + "] is not a dependency of the project." );

-                }

-            }

-        }

-    }

-

-    /**

-     * @return {@link #artifact}

-     */

-    public Artifact getArtifact()

-    {

-        return artifact;

-    }

-

-    /**

-     * @return {@link #moduleId}

-     */

-    public String getModuleId()

-    {

-        return moduleId;

-    }

-

-    /**

-     * @return Return the URI.

-     */

-    public String getUri()

-    {

-        if ( uri == null )

-        {

-            if ( getBundleDir() == null )

-            {

-                uri = getBundleFileName();

-            }

-            else

-            {

-                uri = getBundleDir() + getBundleFileName();

-            }

-        }

-        return uri;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public String getType()

-    {

-        return type;

-    }

-

-    /**

-     * Returns the artifact's groupId.

-     * 

-     * @return {@link #groupId}

-     */

-    public String getGroupId()

-    {

-        return groupId;

-    }

-

-    /**

-     * Returns the artifact's Id.

-     * 

-     * @return {@link #artifactId}

-     */

-    public String getArtifactId()

-    {

-        return artifactId;

-    }

-

-    /**

-     * Returns the artifact's classifier.

-     * 

-     * @return the artifact classifier

-     */

-    public String getClassifier()

-    {

-        return classifier;

-    }

-

-    /**

-     * Returns the bundle directory. If null, the module is bundled in the root of the EAR.

-     * 

-     * @return the custom bundle directory

-     */

-    public String getBundleDir()

-    {

-        bundleDir = cleanArchivePath( bundleDir );

-        return bundleDir;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public String getLibDir()

-    {

-        libDirectory = cleanArchivePath( libDirectory );

-        return libDirectory;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public boolean isClassPathItem()

-    {

-        return classPathItem;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public String getBundleFileName()

-    {

-        if ( bundleFileName == null )

-        {

-            try

-            {

-                String outputFileNameMapping = earExecutionContext.getOutputFileNameMapping();

-                bundleFileName = MappingUtils.evaluateFileNameMapping( outputFileNameMapping, artifact );

-            }

-            catch ( InterpolationException e )

-            {

-                // We currently ignore this here, cause assumption is that

-                // has already been happened before..

-                // FIXME: Should be checked first.

-            }

-

-            // bundleFileName = earExecutionContext.getFileNameMapping().mapFileName( artifact );

-        }

-        return bundleFileName;

-    }

-

-    /**

-     * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a

-     * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to

-     * the application's root directory.

-     * 

-     * @return the alternative deployment descriptor for this module

-     */

-    public String getAltDeploymentDescriptor()

-    {

-        return altDeploymentDescriptor;

-    }

-

-    /**

-     * Specify whether this module should be excluded or not.

-     * 

-     * @return true if this module should be skipped, false otherwise

-     */

-    public boolean isExcluded()

-    {

-        return excluded;

-    }

-

-    /**

-     * @return {@link #unpack}

-     */

-    public Boolean shouldUnpack()

-    {

-        return unpack;

-    }

-

-    /**

-     * Writes the alternative deployment descriptor if necessary.

-     * 

-     * @param writer the writer to use

-     * @param version the java EE version in use

-     */

-    protected void writeAltDeploymentDescriptor( XMLWriter writer, String version )

-    {

-        if ( getAltDeploymentDescriptor() != null )

-        {

-            writer.startElement( ALT_DD );

-            writer.writeText( getAltDeploymentDescriptor() );

-            writer.endElement();

-        }

-    }

-

-    /**

-     * Starts a new {@link #MODULE_ELEMENT} on the specified writer, possibly including an id attribute.

-     * 

-     * @param writer the XML writer.

-     * @param generateId whether an id should be generated

-     */

-    protected void startModuleElement( XMLWriter writer, Boolean generateId )

-    {

-        writer.startElement( MODULE_ELEMENT );

-

-        // If a moduleId is specified, always include it

-        if ( getModuleId() != null )

-        {

-            writer.addAttribute( "id", getModuleId() );

-        }

-        else if ( generateId )

-        {

-            // No module id was specified but one should be generated.

-            // FIXME: Should we use the mapping using outputFileNameMapping instead

-            // of doing this on our own?

-            Artifact theArtifact = getArtifact();

-            String generatedId = theArtifact.getType().toUpperCase() + "_" + theArtifact.getGroupId() + "."

-                + theArtifact.getArtifactId();

-            if ( null != theArtifact.getClassifier() && theArtifact.getClassifier().trim().length() > 0 )

-            {

-                generatedId += "-" + theArtifact.getClassifier().trim();

-            }

-            writer.addAttribute( "id", generatedId );

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public String toString()

-    {

-        StringBuilder sb = new StringBuilder();

-        sb.append( getType() ).append( ":" ).append( groupId ).append( ":" ).append( artifactId );

-        if ( classifier != null )

-        {

-            sb.append( ":" ).append( classifier );

-        }

-        if ( artifact != null )

-        {

-            sb.append( ":" ).append( artifact.getVersion() );

-        }

-        return sb.toString();

-    }

-

-    /**

-     * Cleans the path pointing to the resource inside the archive so that it might be used properly.

-     * 

-     * @param path the path to clean, can be {@code null}

-     * @return the cleaned path or {@code null} if given {@code path} is {@code null}

-     */

-    static String cleanArchivePath( String path )

-    {

-        if ( path == null )

-        {

-            return null;

-        }

-

-        // Using slashes

-        path = path.replace( '\\', '/' );

-

-        // Remove '/' prefix if any so that path is a relative path

-        if ( path.startsWith( "/" ) )

-        {

-            path = path.substring( 1, path.length() );

-        }

-

-        if ( path.length() > 0 && !path.endsWith( "/" ) )

-        {

-            // Adding '/' suffix to specify a path structure if it is not empty

-            path = path + "/";

-        }

-

-        return path;

-    }

-

-    /**

-     * Sets the URI of the module explicitly for testing purposes.

-     * 

-     * @param uri the uri

-     */

-    void setUri( String uri )

-    {

-        this.uri = uri;

-

-    }

-

-    /**

-     * @return always {@code true}

-     */

-    public boolean changeManifestClasspath()

-    {

-        return true;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.ear.util.ArtifactRepository;
+import org.apache.maven.shared.mapping.MappingUtils;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * A base implementation of an {@link EarModule}.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractEarModule implements EarModule {
+
+    /**
+     * The module element.
+     */
+    protected static final String MODULE_ELEMENT = "module";
+
+    /**
+     * The java module.
+     */
+    protected static final String JAVA_MODULE = "java";
+
+    /**
+     * The alt-dd module.
+     */
+    protected static final String ALT_DD = "alt-dd";
+
+    private Artifact artifact;
+
+    // Those are set by the configuration
+
+    private String groupId;
+
+    private String artifactId;
+
+    /**
+     * The type of the artifact
+     */
+    protected String type;
+
+    private String classifier;
+
+    /**
+     * The bundleDir.
+     */
+    protected String bundleDir;
+
+    /**
+     * The bundleFileName.
+     */
+    protected String bundleFileName;
+
+    /**
+     * excluded by default {@code false}.
+     */
+    protected Boolean excluded = Boolean.FALSE;
+
+    private String uri;
+
+    /**
+     * unpack
+     */
+    protected Boolean unpack = null;
+
+    /**
+     * The alternate deployment descriptor.
+     */
+    protected String altDeploymentDescriptor;
+
+    private String moduleId;
+
+    /**
+     * Directory of module which contains libraries packaged into module. {@code null} value means that module
+     * doesn't contain any library. Each module type can provide default value for this directory and this option
+     * can be used to override that default value. If module libraries are located at the root of module then use
+     * single slash (/) to configure that in POM. That is, a single slash is treated as an empty string.
+     */
+    protected String libDirectory;
+
+    /**
+     * If module is considered for inclusion into the Class-Path entry of MANIFEST.mf of other modules. {@code false}
+     * value leads to removal of the module from the Class-Path entry. {@code true} value leads to modification of the
+     * reference to the module in the Class-Path entry if such reference exists or leads to adding of the module into
+     * the Class-Path entry if such reference doesn't exist. Removal, modification or adding of the reference in the
+     * Class-Path entry depends on libDirectory property of another module and on skinnyWars / skinnyModules parameters
+     * of EAR Plugin.
+     */
+    protected boolean classPathItem;
+
+    // This is injected once the module has been built.
+
+    /**
+     * The {@link EarExecutionContext}
+     */
+    protected EarExecutionContext earExecutionContext;
+
+    /**
+     * Empty constructor to be used when the module is built based on the configuration.
+     */
+    public AbstractEarModule() {}
+
+    /**
+     * Creates an ear module from the artifact.
+     *
+     * @param a the artifact
+     */
+    public AbstractEarModule(Artifact a) {
+        this.artifact = a;
+        this.groupId = a.getGroupId();
+        this.artifactId = a.getArtifactId();
+        this.type = a.getType();
+        this.classifier = a.getClassifier();
+        this.bundleDir = null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setEarExecutionContext(EarExecutionContext earExecutionContext) {
+        this.earExecutionContext = earExecutionContext;
+    }
+
+    /** {@inheritDoc} */
+    public void resolveArtifact(Set<Artifact> artifacts) throws EarPluginException, MojoFailureException {
+        // If the artifact is already set no need to resolve it
+        if (artifact == null) {
+            // Make sure that at least the groupId and the artifactId are specified
+            if (groupId == null || artifactId == null) {
+                throw new MojoFailureException(
+                        "Could not resolve artifact[" + groupId + ":" + artifactId + ":" + getType() + "]");
+            }
+            final ArtifactRepository ar = earExecutionContext.getArtifactRepository();
+            artifact = ar.getUniqueArtifact(groupId, artifactId, getType(), classifier);
+            // Artifact has not been found
+            if (artifact == null) {
+                Set<Artifact> candidates = ar.getArtifacts(groupId, artifactId, getType());
+                if (candidates.size() > 1) {
+                    throw new MojoFailureException("Artifact[" + this + "] has " + candidates.size()
+                            + " candidates, please provide a classifier.");
+                } else {
+                    throw new MojoFailureException("Artifact[" + this + "] is not a dependency of the project.");
+                }
+            }
+        }
+    }
+
+    /**
+     * @return {@link #artifact}
+     */
+    public Artifact getArtifact() {
+        return artifact;
+    }
+
+    /**
+     * @return {@link #moduleId}
+     */
+    public String getModuleId() {
+        return moduleId;
+    }
+
+    /**
+     * @return Return the URI.
+     */
+    public String getUri() {
+        if (uri == null) {
+            if (getBundleDir() == null) {
+                uri = getBundleFileName();
+            } else {
+                uri = getBundleDir() + getBundleFileName();
+            }
+        }
+        return uri;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Returns the artifact's groupId.
+     *
+     * @return {@link #groupId}
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * Returns the artifact's Id.
+     *
+     * @return {@link #artifactId}
+     */
+    public String getArtifactId() {
+        return artifactId;
+    }
+
+    /**
+     * Returns the artifact's classifier.
+     *
+     * @return the artifact classifier
+     */
+    public String getClassifier() {
+        return classifier;
+    }
+
+    /**
+     * Returns the bundle directory. If null, the module is bundled in the root of the EAR.
+     *
+     * @return the custom bundle directory
+     */
+    public String getBundleDir() {
+        bundleDir = cleanArchivePath(bundleDir);
+        return bundleDir;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getLibDir() {
+        libDirectory = cleanArchivePath(libDirectory);
+        return libDirectory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isClassPathItem() {
+        return classPathItem;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBundleFileName() {
+        if (bundleFileName == null) {
+            try {
+                String outputFileNameMapping = earExecutionContext.getOutputFileNameMapping();
+                bundleFileName = MappingUtils.evaluateFileNameMapping(outputFileNameMapping, artifact);
+            } catch (InterpolationException e) {
+                // We currently ignore this here, cause assumption is that
+                // has already been happened before..
+                // FIXME: Should be checked first.
+            }
+
+            // bundleFileName = earExecutionContext.getFileNameMapping().mapFileName( artifact );
+        }
+        return bundleFileName;
+    }
+
+    /**
+     * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a
+     * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to
+     * the application's root directory.
+     *
+     * @return the alternative deployment descriptor for this module
+     */
+    public String getAltDeploymentDescriptor() {
+        return altDeploymentDescriptor;
+    }
+
+    /**
+     * Specify whether this module should be excluded or not.
+     *
+     * @return true if this module should be skipped, false otherwise
+     */
+    public boolean isExcluded() {
+        return excluded;
+    }
+
+    /**
+     * @return {@link #unpack}
+     */
+    public Boolean shouldUnpack() {
+        return unpack;
+    }
+
+    /**
+     * Writes the alternative deployment descriptor if necessary.
+     *
+     * @param writer the writer to use
+     * @param version the java EE version in use
+     */
+    protected void writeAltDeploymentDescriptor(XMLWriter writer, String version) {
+        if (getAltDeploymentDescriptor() != null) {
+            writer.startElement(ALT_DD);
+            writer.writeText(getAltDeploymentDescriptor());
+            writer.endElement();
+        }
+    }
+
+    /**
+     * Starts a new {@link #MODULE_ELEMENT} on the specified writer, possibly including an id attribute.
+     *
+     * @param writer the XML writer.
+     * @param generateId whether an id should be generated
+     */
+    protected void startModuleElement(XMLWriter writer, Boolean generateId) {
+        writer.startElement(MODULE_ELEMENT);
+
+        // If a moduleId is specified, always include it
+        if (getModuleId() != null) {
+            writer.addAttribute("id", getModuleId());
+        } else if (generateId) {
+            // No module id was specified but one should be generated.
+            // FIXME: Should we use the mapping using outputFileNameMapping instead
+            // of doing this on our own?
+            Artifact theArtifact = getArtifact();
+            String generatedId = theArtifact.getType().toUpperCase() + "_" + theArtifact.getGroupId() + "."
+                    + theArtifact.getArtifactId();
+            if (null != theArtifact.getClassifier()
+                    && theArtifact.getClassifier().trim().length() > 0) {
+                generatedId += "-" + theArtifact.getClassifier().trim();
+            }
+            writer.addAttribute("id", generatedId);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getType()).append(":").append(groupId).append(":").append(artifactId);
+        if (classifier != null) {
+            sb.append(":").append(classifier);
+        }
+        if (artifact != null) {
+            sb.append(":").append(artifact.getVersion());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Cleans the path pointing to the resource inside the archive so that it might be used properly.
+     *
+     * @param path the path to clean, can be {@code null}
+     * @return the cleaned path or {@code null} if given {@code path} is {@code null}
+     */
+    static String cleanArchivePath(String path) {
+        if (path == null) {
+            return null;
+        }
+
+        // Using slashes
+        path = path.replace('\\', '/');
+
+        // Remove '/' prefix if any so that path is a relative path
+        if (path.startsWith("/")) {
+            path = path.substring(1, path.length());
+        }
+
+        if (path.length() > 0 && !path.endsWith("/")) {
+            // Adding '/' suffix to specify a path structure if it is not empty
+            path = path + "/";
+        }
+
+        return path;
+    }
+
+    /**
+     * Sets the URI of the module explicitly for testing purposes.
+     *
+     * @param uri the uri
+     */
+    void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    /**
+     * @return always {@code true}
+     */
+    public boolean changeManifestClasspath() {
+        return true;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java b/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
index 704f158..40925fb 100644
--- a/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
@@ -1,417 +1,403 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.util.ArrayList;

-import java.util.List;

-import java.util.Set;

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;

-import org.apache.maven.plugin.AbstractMojo;

-import org.apache.maven.plugin.MojoExecutionException;

-import org.apache.maven.plugin.MojoFailureException;

-import org.apache.maven.plugins.annotations.Parameter;

-import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;

-import org.apache.maven.plugins.ear.util.JavaEEVersion;

-import org.apache.maven.project.MavenProject;

-import org.codehaus.plexus.configuration.PlexusConfiguration;

-import org.codehaus.plexus.configuration.PlexusConfigurationException;

-

-/**

- * A base class for EAR-processing related tasks.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public abstract class AbstractEarMojo

-    extends AbstractMojo

-{

-    /**

-     * The application XML URI {@code META-INF/application.xml}

-     */

-    public static final String APPLICATION_XML_URI = "META-INF/application.xml";

-

-    /**

-     * The {@code META-INF} folder.

-     */

-    public static final String META_INF = "META-INF";

-

-    /**

-     * UTF-8 encoding constant.

-     */

-    public static final String UTF_8 = "UTF-8";

-

-    /**

-     * The version of the application.xml to generate. Valid values are 1.3, 1.4, 5, 6, 7 and 8.

-     */

-    @Parameter( defaultValue = "7" )

-    protected String version;

-

-    /**

-     * Character encoding for the auto-generated deployment file(s).

-     */

-    @Parameter( defaultValue = "UTF-8" )

-    protected String encoding;

-

-    /**

-     * Directory where the deployment descriptor file(s) will be auto-generated.

-     */

-    @Parameter( defaultValue = "${project.build.directory}" )

-    protected String generatedDescriptorLocation;

-

-    /**

-     * The maven project.

-     */

-    @Parameter( defaultValue = "${project}", readonly = true, required = true )

-    protected MavenProject project;

-

-    /**

-     * The ear modules configuration.

-     */

-    @Parameter

-    private EarModule[] modules;

-

-    /**

-     * The artifact type mappings.

-     */

-    @Parameter

-    protected PlexusConfiguration artifactTypeMappings;

-

-    /**

-     * The default bundle dir for libraries.

-     */

-    @Parameter

-    protected String defaultLibBundleDir;

-

-    /**

-     * Should libraries be added in application.xml

-     */

-    @Parameter( defaultValue = "false" )

-    private Boolean includeLibInApplicationXml = Boolean.FALSE;

-

-    /**

-     * Only here to identify migration issues. The usage of this parameter will fail the build. If you need file name

-     * mapping please use {@link #outputFileNameMapping} instead.

-     * 

-     * @deprecated

-     */

-    @Parameter

-    private String fileNameMapping;

-

-    /**

-     * The file name mapping to use for all dependencies included in the EAR file. The mapping between artifacts and the

-     * file names which is used within the EAR file.

-     * Details see

-     * <a href="./examples/customize-file-name-mapping.html">Customizing The File Name Mapping</a>.

-     *

-     * @since 3.0.0

-     */

-    @Parameter( defaultValue = "@{groupId}@-@{artifactId}@-@{version}@@{dashClassifier?}@.@{extension}@",

-                required = true )

-    private String outputFileNameMapping;

-

-    /**

-     * Directory that resources are copied to during the build.

-     */

-    @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}", required = true )

-    private File workDirectory;

-

-    /**

-     * The JBoss specific configuration.

-     * 

-     * @parameter

-     */

-    @Parameter

-    private PlexusConfiguration jboss;

-

-    /**

-     * The id to use to define the main artifact (e.g. the artifact without a classifier) when there is multiple

-     * candidates.

-     * 

-     * @parameter

-     */

-    @Parameter

-    private String mainArtifactId = "none";

-

-    private List<EarModule> earModules;

-

-    private List<EarModule> allEarModules;

-

-    private List<EarModule> providedEarModules;

-

-    private JbossConfiguration jbossConfiguration;

-

-    /** {@inheritDoc} */

-    public void execute()

-        throws MojoExecutionException, MojoFailureException

-    {

-        if ( fileNameMapping != null )

-        {

-            getLog().error( "fileNameMapping has been removed with version 3.0.0. You are still using it." );

-            getLog().error( "Use outputFileNameMapping instead." );

-            throw new MojoExecutionException( "fileNameMapping has been removed with version 3.0.0 "

-                + "but you are still using it." );

-        }

-

-        final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );

-        getLog().debug( "Resolving artifact type mappings ..." );

-        ArtifactTypeMappingService typeMappingService;

-        try

-        {

-            typeMappingService = new ArtifactTypeMappingService();

-            typeMappingService.configure( artifactTypeMappings );

-        }

-        catch ( EarPluginException e )

-        {

-            throw new MojoExecutionException( "Failed to initialize artifact type mappings", e );

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            throw new MojoExecutionException( "Invalid artifact type mappings configuration", e );

-        }

-

-        getLog().debug( "Initializing JBoss configuration if necessary ..." );

-        try

-        {

-            initializeJbossConfiguration();

-        }

-        catch ( EarPluginException e )

-        {

-            throw new MojoExecutionException( "Failed to initialize JBoss configuration", e );

-        }

-

-        getLog().debug( "Initializing ear execution context" );

-        EarExecutionContext earExecutionContext =

-            new EarExecutionContext( project, mainArtifactId, defaultLibBundleDir, jbossConfiguration,

-                                     outputFileNameMapping, typeMappingService );

-

-        getLog().debug( "Resolving ear modules ..." );

-        List<EarModule> allModules = new ArrayList<>();

-        try

-        {

-            if ( modules != null && modules.length > 0 )

-            {

-                // Let's validate user-defined modules

-                EarModule module;

-

-                for ( EarModule module1 : modules )

-                {

-                    module = module1;

-                    getLog().debug( "Resolving ear module[" + module + "]" );

-                    module.setEarExecutionContext( earExecutionContext );

-                    module.resolveArtifact( project.getArtifacts() );

-                    allModules.add( module );

-                }

-            }

-

-            // Let's add other modules

-            Set<Artifact> artifacts = project.getArtifacts();

-            for ( Artifact artifact : artifacts )

-            {

-                // If the artifact's type is POM, ignore and continue

-                // since it's used for transitive deps only.

-                if ( "pom".equals( artifact.getType() ) )

-                {

-                    continue;

-                }

-

-                // Artifact is not yet registered and it has not test scope, nor is it optional

-                ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE_PLUS_RUNTIME );

-                if ( !isArtifactRegistered( artifact, allModules ) && !artifact.isOptional()

-                    && filter.include( artifact ) )

-                {

-                    EarModule module = EarModuleFactory.newEarModule( artifact, javaEEVersion, defaultLibBundleDir,

-                                                                      includeLibInApplicationXml, typeMappingService );

-                    module.setEarExecutionContext( earExecutionContext );

-                    allModules.add( module );

-                }

-            }

-        }

-        catch ( EarPluginException e )

-        {

-            throw new MojoExecutionException( "Failed to initialize ear modules", e );

-        }

-

-        // Now we have everything let's built modules which have not been excluded

-        ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );

-        allEarModules = new ArrayList<>();

-        providedEarModules = new ArrayList<>();

-        earModules = new ArrayList<>();

-        for ( EarModule earModule : allModules )

-        {

-            if ( earModule.isExcluded() )

-            {

-                getLog().debug( "Skipping ear module[" + earModule + "]" );

-            }

-            else

-            {

-                allEarModules.add( earModule );

-                if ( filter.include( earModule.getArtifact() ) )

-                {

-                    earModules.add( earModule );

-                }

-                else

-                {

-                    providedEarModules.add( earModule );

-                }

-            }

-        }

-

-    }

-

-    /**

-     * @return The list of {@link #earModules}. This corresponds to modules needed at runtime.

-     */

-    protected List<EarModule> getModules()

-    {

-        if ( earModules == null )

-        {

-            throw new IllegalStateException( "Ear modules have not been initialized" );

-        }

-        return earModules;

-    }

-

-    /**

-     * @return The list of {@link #allEarModules}. This corresponds to all modules (provided + compile + runtime).

-     */

-    protected List<EarModule> getAllEarModules()

-    {

-        if ( allEarModules == null )

-        {

-            throw new IllegalStateException( "EAR modules have not been initialized" );

-        }

-        return allEarModules;

-    }

-

-    /**

-     * @return the list of {@link #providedEarModules}. This corresponds to provided modules.

-     */

-    protected List<EarModule> getProvidedEarModules()

-    {

-        if ( providedEarModules == null )

-        {

-            throw new IllegalStateException( "Jar modules have not been initialized" );

-        }

-        return providedEarModules;

-    }

-

-    /**

-     * @return {@link MavenProject}

-     */

-    protected MavenProject getProject()

-    {

-        return project;

-    }

-

-    /**

-     * @return {@link #workDirectory}

-     */

-    protected File getWorkDirectory()

-    {

-        return workDirectory;

-    }

-

-    /**

-     * @return {@link #jbossConfiguration}

-     */

-    protected JbossConfiguration getJbossConfiguration()

-    {

-        return jbossConfiguration;

-    }

-

-    /**

-     * @return {@link #outputFileNameMapping}

-     */

-    public String getOutputFileNameMapping()

-    {

-        return outputFileNameMapping;

-    }

-

-    private static boolean isArtifactRegistered( Artifact a, List<EarModule> currentList )

-    {

-        for ( EarModule em : currentList )

-        {

-            if ( em.getArtifact().equals( a ) )

-            {

-                return true;

-            }

-        }

-        return false;

-    }

-

-    /**

-     * Initializes the JBoss configuration.

-     * 

-     * @throws EarPluginException if the configuration is invalid

-     */

-    private void initializeJbossConfiguration()

-        throws EarPluginException

-    {

-        if ( jboss == null )

-        {

-            jbossConfiguration = null;

-        }

-        else

-        {

-            String childVersion = jboss.getChild( JbossConfiguration.VERSION ).getValue();

-            if ( childVersion == null )

-            {

-                getLog().info( "JBoss version not set, using JBoss 4 by default" );

-                childVersion = JbossConfiguration.VERSION_4;

-            }

-            final String securityDomain = jboss.getChild( JbossConfiguration.SECURITY_DOMAIN ).getValue();

-            final String unauthenticatedPrincipal =

-                jboss.getChild( JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL ).getValue();

-

-            final PlexusConfiguration loaderRepositoryEl = jboss.getChild( JbossConfiguration.LOADER_REPOSITORY );

-            final String loaderRepository = loaderRepositoryEl.getValue();

-            final String loaderRepositoryClass =

-                loaderRepositoryEl.getAttribute( JbossConfiguration.LOADER_REPOSITORY_CLASS_ATTRIBUTE );

-            final PlexusConfiguration loaderRepositoryConfigEl =

-                jboss.getChild( JbossConfiguration.LOADER_REPOSITORY_CONFIG );

-            final String loaderRepositoryConfig = loaderRepositoryConfigEl.getValue();

-            final String configParserClass =

-                loaderRepositoryConfigEl.getAttribute( JbossConfiguration.CONFIG_PARSER_CLASS_ATTRIBUTE );

-

-            final String jmxName = jboss.getChild( JbossConfiguration.JMX_NAME ).getValue();

-            final String moduleOrder = jboss.getChild( JbossConfiguration.MODULE_ORDER ).getValue();

-

-            final List<String> dataSources = new ArrayList<>();

-            final PlexusConfiguration dataSourcesEl = jboss.getChild( JbossConfiguration.DATASOURCES );

-            if ( dataSourcesEl != null )

-            {

-

-                final PlexusConfiguration[] dataSourcesConfig =

-                    dataSourcesEl.getChildren( JbossConfiguration.DATASOURCE );

-                for ( PlexusConfiguration dataSourceConfig : dataSourcesConfig )

-                {

-                    dataSources.add( dataSourceConfig.getValue() );

-

-                }

-            }

-            final String libraryDirectory = jboss.getChild( JbossConfiguration.LIBRARY_DIRECTORY ).getValue();

-            jbossConfiguration =

-                new JbossConfiguration( childVersion, securityDomain, unauthenticatedPrincipal, jmxName,

-                                        loaderRepository, moduleOrder, dataSources, libraryDirectory,

-                                        loaderRepositoryConfig, loaderRepositoryClass, configParserClass );

-        }

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;
+import org.apache.maven.plugins.ear.util.JavaEEVersion;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+/**
+ * A base class for EAR-processing related tasks.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractEarMojo extends AbstractMojo {
+    /**
+     * The application XML URI {@code META-INF/application.xml}
+     */
+    public static final String APPLICATION_XML_URI = "META-INF/application.xml";
+
+    /**
+     * The {@code META-INF} folder.
+     */
+    public static final String META_INF = "META-INF";
+
+    /**
+     * UTF-8 encoding constant.
+     */
+    public static final String UTF_8 = "UTF-8";
+
+    /**
+     * The version of the application.xml to generate. Valid values are 1.3, 1.4, 5, 6, 7 and 8.
+     */
+    @Parameter(defaultValue = "7")
+    protected String version;
+
+    /**
+     * Character encoding for the auto-generated deployment file(s).
+     */
+    @Parameter(defaultValue = "UTF-8")
+    protected String encoding;
+
+    /**
+     * Directory where the deployment descriptor file(s) will be auto-generated.
+     */
+    @Parameter(defaultValue = "${project.build.directory}")
+    protected String generatedDescriptorLocation;
+
+    /**
+     * The maven project.
+     */
+    @Parameter(defaultValue = "${project}", readonly = true, required = true)
+    protected MavenProject project;
+
+    /**
+     * The ear modules configuration.
+     */
+    @Parameter
+    private EarModule[] modules;
+
+    /**
+     * The artifact type mappings.
+     */
+    @Parameter
+    protected PlexusConfiguration artifactTypeMappings;
+
+    /**
+     * The default bundle dir for libraries.
+     */
+    @Parameter
+    protected String defaultLibBundleDir;
+
+    /**
+     * Should libraries be added in application.xml
+     */
+    @Parameter(defaultValue = "false")
+    private Boolean includeLibInApplicationXml = Boolean.FALSE;
+
+    /**
+     * Only here to identify migration issues. The usage of this parameter will fail the build. If you need file name
+     * mapping please use {@link #outputFileNameMapping} instead.
+     *
+     * @deprecated
+     */
+    @Parameter
+    private String fileNameMapping;
+
+    /**
+     * The file name mapping to use for all dependencies included in the EAR file. The mapping between artifacts and the
+     * file names which is used within the EAR file.
+     * Details see
+     * <a href="./examples/customize-file-name-mapping.html">Customizing The File Name Mapping</a>.
+     *
+     * @since 3.0.0
+     */
+    @Parameter(
+            defaultValue = "@{groupId}@-@{artifactId}@-@{version}@@{dashClassifier?}@.@{extension}@",
+            required = true)
+    private String outputFileNameMapping;
+
+    /**
+     * Directory that resources are copied to during the build.
+     */
+    @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}", required = true)
+    private File workDirectory;
+
+    /**
+     * The JBoss specific configuration.
+     *
+     * @parameter
+     */
+    @Parameter
+    private PlexusConfiguration jboss;
+
+    /**
+     * The id to use to define the main artifact (e.g. the artifact without a classifier) when there is multiple
+     * candidates.
+     *
+     * @parameter
+     */
+    @Parameter
+    private String mainArtifactId = "none";
+
+    private List<EarModule> earModules;
+
+    private List<EarModule> allEarModules;
+
+    private List<EarModule> providedEarModules;
+
+    private JbossConfiguration jbossConfiguration;
+
+    /** {@inheritDoc} */
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (fileNameMapping != null) {
+            getLog().error("fileNameMapping has been removed with version 3.0.0. You are still using it.");
+            getLog().error("Use outputFileNameMapping instead.");
+            throw new MojoExecutionException(
+                    "fileNameMapping has been removed with version 3.0.0 " + "but you are still using it.");
+        }
+
+        final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion(version);
+        getLog().debug("Resolving artifact type mappings ...");
+        ArtifactTypeMappingService typeMappingService;
+        try {
+            typeMappingService = new ArtifactTypeMappingService();
+            typeMappingService.configure(artifactTypeMappings);
+        } catch (EarPluginException e) {
+            throw new MojoExecutionException("Failed to initialize artifact type mappings", e);
+        } catch (PlexusConfigurationException e) {
+            throw new MojoExecutionException("Invalid artifact type mappings configuration", e);
+        }
+
+        getLog().debug("Initializing JBoss configuration if necessary ...");
+        try {
+            initializeJbossConfiguration();
+        } catch (EarPluginException e) {
+            throw new MojoExecutionException("Failed to initialize JBoss configuration", e);
+        }
+
+        getLog().debug("Initializing ear execution context");
+        EarExecutionContext earExecutionContext = new EarExecutionContext(
+                project,
+                mainArtifactId,
+                defaultLibBundleDir,
+                jbossConfiguration,
+                outputFileNameMapping,
+                typeMappingService);
+
+        getLog().debug("Resolving ear modules ...");
+        List<EarModule> allModules = new ArrayList<>();
+        try {
+            if (modules != null && modules.length > 0) {
+                // Let's validate user-defined modules
+                EarModule module;
+
+                for (EarModule module1 : modules) {
+                    module = module1;
+                    getLog().debug("Resolving ear module[" + module + "]");
+                    module.setEarExecutionContext(earExecutionContext);
+                    module.resolveArtifact(project.getArtifacts());
+                    allModules.add(module);
+                }
+            }
+
+            // Let's add other modules
+            Set<Artifact> artifacts = project.getArtifacts();
+            for (Artifact artifact : artifacts) {
+                // If the artifact's type is POM, ignore and continue
+                // since it's used for transitive deps only.
+                if ("pom".equals(artifact.getType())) {
+                    continue;
+                }
+
+                // Artifact is not yet registered and it has not test scope, nor is it optional
+                ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE_PLUS_RUNTIME);
+                if (!isArtifactRegistered(artifact, allModules) && !artifact.isOptional() && filter.include(artifact)) {
+                    EarModule module = EarModuleFactory.newEarModule(
+                            artifact,
+                            javaEEVersion,
+                            defaultLibBundleDir,
+                            includeLibInApplicationXml,
+                            typeMappingService);
+                    module.setEarExecutionContext(earExecutionContext);
+                    allModules.add(module);
+                }
+            }
+        } catch (EarPluginException e) {
+            throw new MojoExecutionException("Failed to initialize ear modules", e);
+        }
+
+        // Now we have everything let's built modules which have not been excluded
+        ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME);
+        allEarModules = new ArrayList<>();
+        providedEarModules = new ArrayList<>();
+        earModules = new ArrayList<>();
+        for (EarModule earModule : allModules) {
+            if (earModule.isExcluded()) {
+                getLog().debug("Skipping ear module[" + earModule + "]");
+            } else {
+                allEarModules.add(earModule);
+                if (filter.include(earModule.getArtifact())) {
+                    earModules.add(earModule);
+                } else {
+                    providedEarModules.add(earModule);
+                }
+            }
+        }
+    }
+
+    /**
+     * @return The list of {@link #earModules}. This corresponds to modules needed at runtime.
+     */
+    protected List<EarModule> getModules() {
+        if (earModules == null) {
+            throw new IllegalStateException("Ear modules have not been initialized");
+        }
+        return earModules;
+    }
+
+    /**
+     * @return The list of {@link #allEarModules}. This corresponds to all modules (provided + compile + runtime).
+     */
+    protected List<EarModule> getAllEarModules() {
+        if (allEarModules == null) {
+            throw new IllegalStateException("EAR modules have not been initialized");
+        }
+        return allEarModules;
+    }
+
+    /**
+     * @return the list of {@link #providedEarModules}. This corresponds to provided modules.
+     */
+    protected List<EarModule> getProvidedEarModules() {
+        if (providedEarModules == null) {
+            throw new IllegalStateException("Jar modules have not been initialized");
+        }
+        return providedEarModules;
+    }
+
+    /**
+     * @return {@link MavenProject}
+     */
+    protected MavenProject getProject() {
+        return project;
+    }
+
+    /**
+     * @return {@link #workDirectory}
+     */
+    protected File getWorkDirectory() {
+        return workDirectory;
+    }
+
+    /**
+     * @return {@link #jbossConfiguration}
+     */
+    protected JbossConfiguration getJbossConfiguration() {
+        return jbossConfiguration;
+    }
+
+    /**
+     * @return {@link #outputFileNameMapping}
+     */
+    public String getOutputFileNameMapping() {
+        return outputFileNameMapping;
+    }
+
+    private static boolean isArtifactRegistered(Artifact a, List<EarModule> currentList) {
+        for (EarModule em : currentList) {
+            if (em.getArtifact().equals(a)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Initializes the JBoss configuration.
+     *
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private void initializeJbossConfiguration() throws EarPluginException {
+        if (jboss == null) {
+            jbossConfiguration = null;
+        } else {
+            String childVersion = jboss.getChild(JbossConfiguration.VERSION).getValue();
+            if (childVersion == null) {
+                getLog().info("JBoss version not set, using JBoss 4 by default");
+                childVersion = JbossConfiguration.VERSION_4;
+            }
+            final String securityDomain =
+                    jboss.getChild(JbossConfiguration.SECURITY_DOMAIN).getValue();
+            final String unauthenticatedPrincipal =
+                    jboss.getChild(JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL).getValue();
+
+            final PlexusConfiguration loaderRepositoryEl = jboss.getChild(JbossConfiguration.LOADER_REPOSITORY);
+            final String loaderRepository = loaderRepositoryEl.getValue();
+            final String loaderRepositoryClass =
+                    loaderRepositoryEl.getAttribute(JbossConfiguration.LOADER_REPOSITORY_CLASS_ATTRIBUTE);
+            final PlexusConfiguration loaderRepositoryConfigEl =
+                    jboss.getChild(JbossConfiguration.LOADER_REPOSITORY_CONFIG);
+            final String loaderRepositoryConfig = loaderRepositoryConfigEl.getValue();
+            final String configParserClass =
+                    loaderRepositoryConfigEl.getAttribute(JbossConfiguration.CONFIG_PARSER_CLASS_ATTRIBUTE);
+
+            final String jmxName = jboss.getChild(JbossConfiguration.JMX_NAME).getValue();
+            final String moduleOrder =
+                    jboss.getChild(JbossConfiguration.MODULE_ORDER).getValue();
+
+            final List<String> dataSources = new ArrayList<>();
+            final PlexusConfiguration dataSourcesEl = jboss.getChild(JbossConfiguration.DATASOURCES);
+            if (dataSourcesEl != null) {
+
+                final PlexusConfiguration[] dataSourcesConfig =
+                        dataSourcesEl.getChildren(JbossConfiguration.DATASOURCE);
+                for (PlexusConfiguration dataSourceConfig : dataSourcesConfig) {
+                    dataSources.add(dataSourceConfig.getValue());
+                }
+            }
+            final String libraryDirectory =
+                    jboss.getChild(JbossConfiguration.LIBRARY_DIRECTORY).getValue();
+            jbossConfiguration = new JbossConfiguration(
+                    childVersion,
+                    securityDomain,
+                    unauthenticatedPrincipal,
+                    jmxName,
+                    loaderRepository,
+                    moduleOrder,
+                    dataSources,
+                    libraryDirectory,
+                    loaderRepositoryConfig,
+                    loaderRepositoryClass,
+                    configParserClass);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/AbstractXmlWriter.java b/src/main/java/org/apache/maven/plugins/ear/AbstractXmlWriter.java
index c22bc69..1eb1d08 100644
--- a/src/main/java/org/apache/maven/plugins/ear/AbstractXmlWriter.java
+++ b/src/main/java/org/apache/maven/plugins/ear/AbstractXmlWriter.java
@@ -1,63 +1,72 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.codehaus.plexus.util.WriterFactory;

-import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-import java.io.File;

-import java.io.IOException;

-import java.io.Writer;

-

-/**

- * A base class for deployment descriptor file generators.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-abstract class AbstractXmlWriter

-{

-

-    private final String encoding;

-

-    AbstractXmlWriter( String encoding )

-    {

-        this.encoding = encoding;

-    }

-

-    Writer initializeWriter( final File destinationFile )

-        throws EarPluginException

-    {

-        try

-        {

-            return WriterFactory.newXmlWriter( destinationFile );

-        }

-        catch ( IOException ex )

-        {

-            throw new EarPluginException( 

-                    "Exception while opening file[" + destinationFile.getAbsolutePath() + "]", ex );

-        }

-    }

-

-    XMLWriter initializeXmlWriter( final Writer writer, final String docType )

-    {

-        return new PrettyPrintXMLWriter( writer, encoding, docType );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * A base class for deployment descriptor file generators.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+abstract class AbstractXmlWriter {
+
+    private final String encoding;
+
+    AbstractXmlWriter(String encoding) {
+        this.encoding = encoding;
+    }
+
+    Writer initializeWriter(final File destinationFile) throws EarPluginException {
+        try {
+            return WriterFactory.newXmlWriter(destinationFile);
+        } catch (IOException ex) {
+            throw new EarPluginException("Exception while opening file[" + destinationFile.getAbsolutePath() + "]", ex);
+        }
+    }
+
+    XMLWriter initializeXmlWriter(final Writer writer, final String docType) {
+        return new PrettyPrintXMLWriter(writer, encoding, docType);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/AppClientModule.java b/src/main/java/org/apache/maven/plugins/ear/AppClientModule.java
index 6ff9994..2464fe5 100644
--- a/src/main/java/org/apache/maven/plugins/ear/AppClientModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/AppClientModule.java
@@ -1,68 +1,81 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The {@link EarModule} implementation for an application client module.

- * 

- * @author Stephane Nicoll

- */

-public class AppClientModule

-    extends AbstractEarModule

-{

-    /**

-     * Default type of the artifact of an application client module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "app-client";

-

-    /**

-     * Create an instance.

-     */

-    public AppClientModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public AppClientModule( Artifact a )

-    {

-        super( a );

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        startModuleElement( writer, generateId );

-        writer.startElement( JAVA_MODULE );

-        writer.writeText( getUri() );

-        writer.endElement();

-

-        writeAltDeploymentDescriptor( writer, version );

-

-        writer.endElement();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for an application client module.
+ *
+ * @author Stephane Nicoll
+ */
+public class AppClientModule extends AbstractEarModule {
+    /**
+     * Default type of the artifact of an application client module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "app-client";
+
+    /**
+     * Create an instance.
+     */
+    public AppClientModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public AppClientModule(Artifact a) {
+        super(a);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        startModuleElement(writer, generateId);
+        writer.startElement(JAVA_MODULE);
+        writer.writeText(getUri());
+        writer.endElement();
+
+        writeAltDeploymentDescriptor(writer, version);
+
+        writer.endElement();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriter.java b/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriter.java
index d9e4bbd..817ec0b 100644
--- a/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriter.java
+++ b/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriter.java
@@ -1,305 +1,276 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.IOException;

-import java.io.Writer;

-

-import org.apache.maven.plugins.ear.util.JavaEEVersion;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * An <code>XmlWriter</code> based implementation used to generate an {@code application.xml} file.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-final class ApplicationXmlWriter

-    extends AbstractXmlWriter

-{

-    //@formatter:off

-    public static final String DOCTYPE_1_3 = "application PUBLIC\n" 

-            + "\t\"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN\"\n"

-            + "\t\"http://java.sun.com/dtd/application_1_3.dtd\"";

-    //@formatter:on

-

-    private static final String APPLICATION_ELEMENT = "application";

-

-    private final JavaEEVersion version;

-

-    private final Boolean generateModuleId;

-

-    ApplicationXmlWriter( JavaEEVersion version, String encoding, Boolean generateModuleId )

-    {

-        super( encoding );

-        this.version = version;

-        this.generateModuleId = generateModuleId;

-    }

-

-    void write( ApplicationXmlWriterContext context )

-        throws EarPluginException

-    {

-        try ( Writer w = initializeWriter( context.getDestinationFile() ) )

-        {

-            XMLWriter writer = null;

-            if ( JavaEEVersion.ONE_DOT_THREE.eq( version ) )

-            {

-                writer = initializeRootElementOneDotThree( w );

-            }

-            else if ( JavaEEVersion.ONE_DOT_FOUR.eq( version ) )

-            {

-                writer = initializeRootElementOneDotFour( w );

-            }

-            else if ( JavaEEVersion.FIVE.eq( version ) )

-            {

-                writer = initializeRootElementFive( w );

-            }

-            else if ( JavaEEVersion.SIX.eq( version ) )

-            {

-                writer = initializeRootElementSix( w );

-            }

-            else if ( JavaEEVersion.SEVEN.eq( version ) )

-            {

-                writer = initializeRootElementSeven( w );

-            }

-            else if ( JavaEEVersion.EIGHT.eq( version ) )

-            {

-                writer = initializeRootElementEight( w );

-            }

-            else if ( JavaEEVersion.NINE.eq( version ) )

-            {

-                writer = initializeRootElementNine( w );

-            }

-            else if ( JavaEEVersion.TEN.eq( version ) )

-            {

-                writer = initializeRootElementTen( w );

-            }

-    

-            // writer is still on root element, so we can still add this attribute

-            if ( context.getApplicationId() != null )

-            {

-                writer.addAttribute( "id", context.getApplicationId() );

-            }

-    

-            // As from JavaEE6

-            if ( version.ge( JavaEEVersion.SIX ) )

-            {

-                writeApplicationName( context.getApplicationName(), writer );

-            }

-    

-            // IMPORTANT: the order of the description and display-name elements was

-            // reversed between J2EE 1.3 and J2EE 1.4.

-            if ( version.eq( JavaEEVersion.ONE_DOT_THREE ) )

-            {

-                writeDisplayName( context.getDisplayName(), writer );

-                writeDescription( context.getDescription(), writer );

-            }

-            else

-            {

-                writeDescription( context.getDescription(), writer );

-                writeDisplayName( context.getDisplayName(), writer );

-            }

-    

-            // As from JavaEE6

-            if ( version.ge( JavaEEVersion.SIX ) )

-            {

-                writeInitializeInOrder( context.getInitializeInOrder(), writer );

-            }

-    

-            // Do not change this unless you really know what you're doing :)

-            for ( EarModule module : context.getEarModules() )

-            {

-                module.appendModule( writer, version.getVersion(), generateModuleId );

-            }

-    

-            for ( SecurityRole securityRole : context.getSecurityRoles() )

-            {

-                securityRole.appendSecurityRole( writer );

-            }

-    

-            if ( version.ge( JavaEEVersion.FIVE ) )

-            {

-                writeLibraryDirectory( context.getLibraryDirectory(), writer );

-            }

-    

-            if ( version.ge( JavaEEVersion.SIX ) )

-            {

-                for ( EnvEntry envEntry : context.getEnvEntries() )

-                {

-                    envEntry.appendEnvEntry( writer );

-                }

-                for ( EjbRef ejbEntry : context.getEjbEntries() )

-                {

-                    ejbEntry.appendEjbRefEntry( writer );

-                }

-                for ( ResourceRef resourceEntry : context.getResourceRefs() )

-                {

-                    resourceEntry.appendResourceRefEntry( writer );

-                }

-            }

-    

-            writer.endElement();

-        }

-        catch ( IOException ex )

-        {

-            // ignore

-        }

-    }

-

-    private void writeApplicationName( String applicationName, XMLWriter writer )

-    {

-        if ( applicationName != null )

-        {

-            writer.startElement( "application-name" );

-            writer.writeText( applicationName );

-            writer.endElement();

-        }

-    }

-

-    private void writeDescription( String description, XMLWriter writer )

-    {

-        if ( description != null )

-        {

-            writer.startElement( "description" );

-            writer.writeText( description );

-            writer.endElement();

-        }

-    }

-

-    private void writeDisplayName( String displayName, XMLWriter writer )

-    {

-        if ( displayName != null )

-        {

-            writer.startElement( "display-name" );

-            writer.writeText( displayName );

-            writer.endElement();

-        }

-    }

-

-    private void writeInitializeInOrder( Boolean initializeInOrder, XMLWriter writer )

-    {

-        if ( initializeInOrder != null )

-        {

-            writer.startElement( "initialize-in-order" );

-            writer.writeText( initializeInOrder.toString() );

-            writer.endElement();

-        }

-    }

-

-    private void writeLibraryDirectory( String libraryDirectory, XMLWriter writer )

-    {

-        if ( libraryDirectory != null )

-        {

-            writer.startElement( "library-directory" );

-            writer.writeText( libraryDirectory );

-            writer.endElement();

-        }

-    }

-

-    private XMLWriter initializeRootElementOneDotThree( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, DOCTYPE_1_3 );

-        writer.startElement( APPLICATION_ELEMENT );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementOneDotFour( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "http://java.sun.com/xml/ns/j2ee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-                             "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" );

-        writer.addAttribute( "version", "1.4" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementFive( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "http://java.sun.com/xml/ns/javaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-                             "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" );

-        writer.addAttribute( "version", "5" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementSix( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "http://java.sun.com/xml/ns/javaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-                             "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" );

-        writer.addAttribute( "version", "6" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementSeven( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "http://xmlns.jcp.org/xml/ns/javaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-            "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd" );

-        writer.addAttribute( "version", "7" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementEight( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "http://xmlns.jcp.org/xml/ns/javaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-            "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_8.xsd" );

-        writer.addAttribute( "version", "8" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementNine( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "https://jakarta.ee/xml/ns/jakartaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-            "https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/application_9.xsd" );

-        writer.addAttribute( "version", "9" );

-        return writer;

-    }

-

-    private XMLWriter initializeRootElementTen( Writer w )

-    {

-        XMLWriter writer = initializeXmlWriter( w, null );

-        writer.startElement( APPLICATION_ELEMENT );

-        writer.addAttribute( "xmlns", "https://jakarta.ee/xml/ns/jakartaee" );

-        writer.addAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );

-        writer.addAttribute( "xsi:schemaLocation",

-            "https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/application_10.xsd" );

-        writer.addAttribute( "version", "10" );

-        return writer;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.maven.plugins.ear.util.JavaEEVersion;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * An <code>XmlWriter</code> based implementation used to generate an {@code application.xml} file.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+final class ApplicationXmlWriter extends AbstractXmlWriter {
+    // @formatter:off
+    public static final String DOCTYPE_1_3 = "application PUBLIC\n"
+            + "\t\"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN\"\n"
+            + "\t\"http://java.sun.com/dtd/application_1_3.dtd\"";
+    // @formatter:on
+
+    private static final String APPLICATION_ELEMENT = "application";
+
+    private final JavaEEVersion version;
+
+    private final Boolean generateModuleId;
+
+    ApplicationXmlWriter(JavaEEVersion version, String encoding, Boolean generateModuleId) {
+        super(encoding);
+        this.version = version;
+        this.generateModuleId = generateModuleId;
+    }
+
+    void write(ApplicationXmlWriterContext context) throws EarPluginException {
+        try (Writer w = initializeWriter(context.getDestinationFile())) {
+            XMLWriter writer = null;
+            if (JavaEEVersion.ONE_DOT_THREE.eq(version)) {
+                writer = initializeRootElementOneDotThree(w);
+            } else if (JavaEEVersion.ONE_DOT_FOUR.eq(version)) {
+                writer = initializeRootElementOneDotFour(w);
+            } else if (JavaEEVersion.FIVE.eq(version)) {
+                writer = initializeRootElementFive(w);
+            } else if (JavaEEVersion.SIX.eq(version)) {
+                writer = initializeRootElementSix(w);
+            } else if (JavaEEVersion.SEVEN.eq(version)) {
+                writer = initializeRootElementSeven(w);
+            } else if (JavaEEVersion.EIGHT.eq(version)) {
+                writer = initializeRootElementEight(w);
+            } else if (JavaEEVersion.NINE.eq(version)) {
+                writer = initializeRootElementNine(w);
+            } else if (JavaEEVersion.TEN.eq(version)) {
+                writer = initializeRootElementTen(w);
+            }
+
+            // writer is still on root element, so we can still add this attribute
+            if (context.getApplicationId() != null) {
+                writer.addAttribute("id", context.getApplicationId());
+            }
+
+            // As from JavaEE6
+            if (version.ge(JavaEEVersion.SIX)) {
+                writeApplicationName(context.getApplicationName(), writer);
+            }
+
+            // IMPORTANT: the order of the description and display-name elements was
+            // reversed between J2EE 1.3 and J2EE 1.4.
+            if (version.eq(JavaEEVersion.ONE_DOT_THREE)) {
+                writeDisplayName(context.getDisplayName(), writer);
+                writeDescription(context.getDescription(), writer);
+            } else {
+                writeDescription(context.getDescription(), writer);
+                writeDisplayName(context.getDisplayName(), writer);
+            }
+
+            // As from JavaEE6
+            if (version.ge(JavaEEVersion.SIX)) {
+                writeInitializeInOrder(context.getInitializeInOrder(), writer);
+            }
+
+            // Do not change this unless you really know what you're doing :)
+            for (EarModule module : context.getEarModules()) {
+                module.appendModule(writer, version.getVersion(), generateModuleId);
+            }
+
+            for (SecurityRole securityRole : context.getSecurityRoles()) {
+                securityRole.appendSecurityRole(writer);
+            }
+
+            if (version.ge(JavaEEVersion.FIVE)) {
+                writeLibraryDirectory(context.getLibraryDirectory(), writer);
+            }
+
+            if (version.ge(JavaEEVersion.SIX)) {
+                for (EnvEntry envEntry : context.getEnvEntries()) {
+                    envEntry.appendEnvEntry(writer);
+                }
+                for (EjbRef ejbEntry : context.getEjbEntries()) {
+                    ejbEntry.appendEjbRefEntry(writer);
+                }
+                for (ResourceRef resourceEntry : context.getResourceRefs()) {
+                    resourceEntry.appendResourceRefEntry(writer);
+                }
+            }
+
+            writer.endElement();
+        } catch (IOException ex) {
+            // ignore
+        }
+    }
+
+    private void writeApplicationName(String applicationName, XMLWriter writer) {
+        if (applicationName != null) {
+            writer.startElement("application-name");
+            writer.writeText(applicationName);
+            writer.endElement();
+        }
+    }
+
+    private void writeDescription(String description, XMLWriter writer) {
+        if (description != null) {
+            writer.startElement("description");
+            writer.writeText(description);
+            writer.endElement();
+        }
+    }
+
+    private void writeDisplayName(String displayName, XMLWriter writer) {
+        if (displayName != null) {
+            writer.startElement("display-name");
+            writer.writeText(displayName);
+            writer.endElement();
+        }
+    }
+
+    private void writeInitializeInOrder(Boolean initializeInOrder, XMLWriter writer) {
+        if (initializeInOrder != null) {
+            writer.startElement("initialize-in-order");
+            writer.writeText(initializeInOrder.toString());
+            writer.endElement();
+        }
+    }
+
+    private void writeLibraryDirectory(String libraryDirectory, XMLWriter writer) {
+        if (libraryDirectory != null) {
+            writer.startElement("library-directory");
+            writer.writeText(libraryDirectory);
+            writer.endElement();
+        }
+    }
+
+    private XMLWriter initializeRootElementOneDotThree(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, DOCTYPE_1_3);
+        writer.startElement(APPLICATION_ELEMENT);
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementOneDotFour(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "http://java.sun.com/xml/ns/j2ee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd");
+        writer.addAttribute("version", "1.4");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementFive(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "http://java.sun.com/xml/ns/javaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd");
+        writer.addAttribute("version", "5");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementSix(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "http://java.sun.com/xml/ns/javaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd");
+        writer.addAttribute("version", "6");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementSeven(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "http://xmlns.jcp.org/xml/ns/javaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd");
+        writer.addAttribute("version", "7");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementEight(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "http://xmlns.jcp.org/xml/ns/javaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_8.xsd");
+        writer.addAttribute("version", "8");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementNine(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "https://jakarta.ee/xml/ns/jakartaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/application_9.xsd");
+        writer.addAttribute("version", "9");
+        return writer;
+    }
+
+    private XMLWriter initializeRootElementTen(Writer w) {
+        XMLWriter writer = initializeXmlWriter(w, null);
+        writer.startElement(APPLICATION_ELEMENT);
+        writer.addAttribute("xmlns", "https://jakarta.ee/xml/ns/jakartaee");
+        writer.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        writer.addAttribute(
+                "xsi:schemaLocation",
+                "https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/application_10.xsd");
+        writer.addAttribute("version", "10");
+        return writer;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriterContext.java b/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriterContext.java
index 9730acc..ba49a81 100644
--- a/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriterContext.java
+++ b/src/main/java/org/apache/maven/plugins/ear/ApplicationXmlWriterContext.java
@@ -1,196 +1,206 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.util.List;

-

-/**

- * A context for the {@link ApplicationXmlWriter}.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-class ApplicationXmlWriterContext

-{

-

-    private String applicationId;

-

-    private final File destinationFile;

-

-    private final List<EarModule> earModules;

-

-    private final List<SecurityRole> securityRoles;

-

-    private final List<EnvEntry> envEntries;

-

-    private final List<EjbRef> ejbEntries;

-

-    private final List<ResourceRef> resourceRefs;

-

-    private final String displayName;

-

-    private final String description;

-

-    private final String libraryDirectory;

-

-    private final String applicationName;

-

-    private final Boolean initializeInOrder;

-

-    ApplicationXmlWriterContext( File destinationFile, List<EarModule> earModules,

-                                        List<SecurityRole> securityRoles, List<EnvEntry> envEntries,

-                                        List<EjbRef> ejbEntries, List<ResourceRef> resourceRefs, String displayName,

-                                        String description, String libraryDirectory, String applicationName,

-                                        Boolean initializeInOrder )

-    {

-        this.destinationFile = destinationFile;

-        this.earModules = earModules;

-        this.securityRoles = securityRoles;

-        this.envEntries = envEntries;

-        this.ejbEntries = ejbEntries;

-        this.resourceRefs = resourceRefs;

-        this.displayName = displayName;

-        this.description = description;

-        this.libraryDirectory = libraryDirectory;

-        this.applicationName = applicationName;

-        this.initializeInOrder = initializeInOrder;

-    }

-

-    public final ApplicationXmlWriterContext setApplicationId( String applicationId )

-    {

-        this.applicationId = applicationId;

-        return this;

-    }

-

-    public final String getApplicationId()

-    {

-        return applicationId;

-    }

-

-    /**

-     * Returns the name of the file to use to write application.xml to.

-     * 

-     * @return the output file

-     */

-    public File getDestinationFile()

-    {

-        return destinationFile;

-    }

-

-    /**

-     * Returns the list of {@link EarModule} instances.

-     * 

-     * @return the ear modules

-     */

-    public List<EarModule> getEarModules()

-    {

-        return earModules;

-    }

-

-    /**

-     * Returns the list of {@link SecurityRole} instances.

-     * 

-     * @return the security roles

-     */

-    public List<SecurityRole> getSecurityRoles()

-    {

-        return securityRoles;

-    }

-

-    /**

-     * Returns the list of {@link EnvEntry} instances (as per JavaEE 6).

-     * 

-     * @return the env-entry elements

-     */

-    public List<EnvEntry> getEnvEntries()

-    {

-        return envEntries;

-    }

-

-    /**

-     * Returns the list of {@link EjbRef}.

-     * 

-     * @return the env-ref elements

-     */

-    public List<EjbRef> getEjbEntries()

-    {

-        return ejbEntries;

-    }

-

-    /**

-     * Returns the list of {@link ResourceRef}.

-     * 

-     * @return the resource-ref elements.

-     */

-    public List<ResourceRef> getResourceRefs()

-    {

-        return resourceRefs;

-    }

-

-    /**

-     * Returns the display name.

-     * 

-     * @return the display name

-     */

-    public String getDisplayName()

-    {

-        return displayName;

-    }

-

-    /**

-     * Returns the description.

-     * 

-     * @return the description

-     */

-    public String getDescription()

-    {

-        return description;

-    }

-

-    /**

-     * Returns the library directory (as per JavaEE 5).

-     * 

-     * @return the library directory

-     */

-    public String getLibraryDirectory()

-    {

-        return libraryDirectory;

-    }

-

-    /**

-     * Returns the application name (as per JavaEE 6).

-     * 

-     * @return the application name

-     */

-    public String getApplicationName()

-    {

-        return applicationName;

-    }

-

-    /**

-     * Returns the value of the initialize in order parameter (as per JavaEE 6).

-     * 

-     * @return the initialize in order value

-     */

-    public Boolean getInitializeInOrder()

-    {

-        return initializeInOrder;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * A context for the {@link ApplicationXmlWriter}.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+class ApplicationXmlWriterContext {
+
+    private String applicationId;
+
+    private final File destinationFile;
+
+    private final List<EarModule> earModules;
+
+    private final List<SecurityRole> securityRoles;
+
+    private final List<EnvEntry> envEntries;
+
+    private final List<EjbRef> ejbEntries;
+
+    private final List<ResourceRef> resourceRefs;
+
+    private final String displayName;
+
+    private final String description;
+
+    private final String libraryDirectory;
+
+    private final String applicationName;
+
+    private final Boolean initializeInOrder;
+
+    ApplicationXmlWriterContext(
+            File destinationFile,
+            List<EarModule> earModules,
+            List<SecurityRole> securityRoles,
+            List<EnvEntry> envEntries,
+            List<EjbRef> ejbEntries,
+            List<ResourceRef> resourceRefs,
+            String displayName,
+            String description,
+            String libraryDirectory,
+            String applicationName,
+            Boolean initializeInOrder) {
+        this.destinationFile = destinationFile;
+        this.earModules = earModules;
+        this.securityRoles = securityRoles;
+        this.envEntries = envEntries;
+        this.ejbEntries = ejbEntries;
+        this.resourceRefs = resourceRefs;
+        this.displayName = displayName;
+        this.description = description;
+        this.libraryDirectory = libraryDirectory;
+        this.applicationName = applicationName;
+        this.initializeInOrder = initializeInOrder;
+    }
+
+    public final ApplicationXmlWriterContext setApplicationId(String applicationId) {
+        this.applicationId = applicationId;
+        return this;
+    }
+
+    public final String getApplicationId() {
+        return applicationId;
+    }
+
+    /**
+     * Returns the name of the file to use to write application.xml to.
+     *
+     * @return the output file
+     */
+    public File getDestinationFile() {
+        return destinationFile;
+    }
+
+    /**
+     * Returns the list of {@link EarModule} instances.
+     *
+     * @return the ear modules
+     */
+    public List<EarModule> getEarModules() {
+        return earModules;
+    }
+
+    /**
+     * Returns the list of {@link SecurityRole} instances.
+     *
+     * @return the security roles
+     */
+    public List<SecurityRole> getSecurityRoles() {
+        return securityRoles;
+    }
+
+    /**
+     * Returns the list of {@link EnvEntry} instances (as per JavaEE 6).
+     *
+     * @return the env-entry elements
+     */
+    public List<EnvEntry> getEnvEntries() {
+        return envEntries;
+    }
+
+    /**
+     * Returns the list of {@link EjbRef}.
+     *
+     * @return the env-ref elements
+     */
+    public List<EjbRef> getEjbEntries() {
+        return ejbEntries;
+    }
+
+    /**
+     * Returns the list of {@link ResourceRef}.
+     *
+     * @return the resource-ref elements.
+     */
+    public List<ResourceRef> getResourceRefs() {
+        return resourceRefs;
+    }
+
+    /**
+     * Returns the display name.
+     *
+     * @return the display name
+     */
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    /**
+     * Returns the description.
+     *
+     * @return the description
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Returns the library directory (as per JavaEE 5).
+     *
+     * @return the library directory
+     */
+    public String getLibraryDirectory() {
+        return libraryDirectory;
+    }
+
+    /**
+     * Returns the application name (as per JavaEE 6).
+     *
+     * @return the application name
+     */
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    /**
+     * Returns the value of the initialize in order parameter (as per JavaEE 6).
+     *
+     * @return the initialize in order value
+     */
+    public Boolean getInitializeInOrder() {
+        return initializeInOrder;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarExecutionContext.java b/src/main/java/org/apache/maven/plugins/ear/EarExecutionContext.java
index fab4838..576e1cd 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarExecutionContext.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarExecutionContext.java
@@ -1,99 +1,122 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.plugins.ear.util.ArtifactRepository;

-import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;

-import org.apache.maven.project.MavenProject;

-

-/**

- * Contains various runtime parameters used to customize the generated EAR file.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarExecutionContext

-{

-    private String defaultLibBundleDir;

-

-    private JbossConfiguration jbossConfiguration;

-

-    private String outputFileNameMapping;

-

-    private ArtifactRepository artifactRepository;

-

-    /**

-     * @param project {@link MavenProject}

-     * @param mainArtifactId The artifactId.

-     * @param defaultLibBundleDir The defaultLibBundleDir.

-     * @param jbossConfiguration {@link JbossConfiguration}

-     * @param fileNameMappingName file name mapping.

-     * @param typeMappingService {@link ArtifactTypeMappingService}

-     */

-    public EarExecutionContext( MavenProject project, String mainArtifactId, String defaultLibBundleDir,

-                                JbossConfiguration jbossConfiguration, String fileNameMappingName,

-                                ArtifactTypeMappingService typeMappingService )

-    {

-        initialize( project, mainArtifactId, defaultLibBundleDir, jbossConfiguration, fileNameMappingName,

-                    typeMappingService );

-

-    }

-

-    /**

-     * @return {@link #defaultLibBundleDir}

-     */

-    public String getDefaultLibBundleDir()

-    {

-        return defaultLibBundleDir;

-    }

-

-    /**

-     * @return {@link #jbossConfiguration}

-     */

-    public boolean isJbossConfigured()

-    {

-        return jbossConfiguration != null;

-    }

-

-    /**

-     * @return {@link #outputFileNameMapping}

-     */

-    public String getOutputFileNameMapping()

-    {

-        return outputFileNameMapping;

-    }

-

-    /**

-     * @return {@link #artifactRepository}

-     */

-    public ArtifactRepository getArtifactRepository()

-    {

-        return artifactRepository;

-    }

-

-    private void initialize( MavenProject project, String mainArtifactId, String defaultLibBundleDir,

-                             JbossConfiguration jbossConfiguration, String outputFileNameMapping,

-                             ArtifactTypeMappingService typeMappingService )

-    {

-        this.artifactRepository = new ArtifactRepository( project.getArtifacts(), mainArtifactId, typeMappingService );

-        this.defaultLibBundleDir = defaultLibBundleDir;

-        this.jbossConfiguration = jbossConfiguration;

-        this.outputFileNameMapping = outputFileNameMapping;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugins.ear.util.ArtifactRepository;
+import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Contains various runtime parameters used to customize the generated EAR file.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarExecutionContext {
+    private String defaultLibBundleDir;
+
+    private JbossConfiguration jbossConfiguration;
+
+    private String outputFileNameMapping;
+
+    private ArtifactRepository artifactRepository;
+
+    /**
+     * @param project {@link MavenProject}
+     * @param mainArtifactId The artifactId.
+     * @param defaultLibBundleDir The defaultLibBundleDir.
+     * @param jbossConfiguration {@link JbossConfiguration}
+     * @param fileNameMappingName file name mapping.
+     * @param typeMappingService {@link ArtifactTypeMappingService}
+     */
+    public EarExecutionContext(
+            MavenProject project,
+            String mainArtifactId,
+            String defaultLibBundleDir,
+            JbossConfiguration jbossConfiguration,
+            String fileNameMappingName,
+            ArtifactTypeMappingService typeMappingService) {
+        initialize(
+                project,
+                mainArtifactId,
+                defaultLibBundleDir,
+                jbossConfiguration,
+                fileNameMappingName,
+                typeMappingService);
+    }
+
+    /**
+     * @return {@link #defaultLibBundleDir}
+     */
+    public String getDefaultLibBundleDir() {
+        return defaultLibBundleDir;
+    }
+
+    /**
+     * @return {@link #jbossConfiguration}
+     */
+    public boolean isJbossConfigured() {
+        return jbossConfiguration != null;
+    }
+
+    /**
+     * @return {@link #outputFileNameMapping}
+     */
+    public String getOutputFileNameMapping() {
+        return outputFileNameMapping;
+    }
+
+    /**
+     * @return {@link #artifactRepository}
+     */
+    public ArtifactRepository getArtifactRepository() {
+        return artifactRepository;
+    }
+
+    private void initialize(
+            MavenProject project,
+            String mainArtifactId,
+            String defaultLibBundleDir,
+            JbossConfiguration jbossConfiguration,
+            String outputFileNameMapping,
+            ArtifactTypeMappingService typeMappingService) {
+        this.artifactRepository = new ArtifactRepository(project.getArtifacts(), mainArtifactId, typeMappingService);
+        this.defaultLibBundleDir = defaultLibBundleDir;
+        this.jbossConfiguration = jbossConfiguration;
+        this.outputFileNameMapping = outputFileNameMapping;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarModule.java b/src/main/java/org/apache/maven/plugins/ear/EarModule.java
index 80b4f56..f5b1a37 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarModule.java
@@ -1,137 +1,152 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugin.MojoFailureException;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-import java.util.Set;

-

-/**

- * The ear module interface.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public interface EarModule

-{

-

-    /**

-     * Returns the {@link Artifact} representing this module.

-     * 

-     * Note that this might return {@code null} till the module has been resolved.

-     * 

-     * @return the artifact

-     * @see #resolveArtifact(java.util.Set)

-     */

-    Artifact getArtifact();

-

-    /**

-     * Returns the {@code URI} for this module.

-     * 

-     * @return the {@code URI}

-     */

-    String getUri();

-

-    /**

-     * Returns the type associated to the module.

-     * 

-     * @return the artifact's type of the module

-     */

-    String getType();

-

-    /**

-     * Specify whether this module should be excluded or not.

-     * 

-     * @return true if this module should be skipped, false otherwise

-     */

-    boolean isExcluded();

-

-    /**

-     * Specify whether this module should be unpacked in the EAR archive or not.

-     *

-     * Returns null if no configuration was specified so that defaulting may apply.

-     * 

-     * @return true if this module should be bundled unpacked, false otherwise

-     */

-    Boolean shouldUnpack();

-

-    /**

-     * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a

-     * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to

-     * the application's root directory.

-     * 

-     * @return the alternative deployment descriptor for this module

-     * @since JavaEE 5

-     */

-    String getAltDeploymentDescriptor();

-

-    /**

-     * Appends the {@code XML} representation of this module.

-     * 

-     * @param writer the writer to use

-     * @param version the version of the {@code application.xml} file

-     * @param generateId whether an id should be generated

-     */

-    void appendModule( XMLWriter writer, String version, Boolean generateId );

-

-    /**

-     * Resolves the {@link Artifact} represented by the module. Note that the {@link EarExecutionContext} might be used

-     * to customize further the resolution.

-     * 

-     * @param artifacts the project's artifacts

-     * @throws EarPluginException if the artifact could not be resolved

-     * @throws MojoFailureException if an unexpected error occurred

-     */

-    void resolveArtifact( Set<Artifact> artifacts )

-        throws EarPluginException, MojoFailureException;

-

-    /**

-     * @param earExecutionContext The execution context.

-     */

-    void setEarExecutionContext( EarExecutionContext earExecutionContext );

-

-    /**

-     * @return the state if manifest classpath will be changed or not.

-     */

-    boolean changeManifestClasspath();

-

-    /**

-     * @return The directory of the module which contains the JAR libraries packaged within the module.

-     * Can be {@code null}, which means that module doesn't contain any packaged libraries.

-     */

-    String getLibDir();

-

-    /**

-     * Returns the bundle file name. If {@code null}, the artifact's file name is returned.

-     *

-     * @return the bundle file name

-     */

-    String getBundleFileName();

-

-    /**

-     * If module should be included into the Class-Path entry of MANIFEST.mf. Doesn't impact Class-Path entry of

-     * MANIFEST.mf of modules which contain all of their dependencies unless skinnyWars / skinnyModules is turned on.

-     *

-     * @return {@code }True} if module should be included into the Class-Path entry of MANIFEST.mf

-     */

-    boolean isClassPathItem();

-

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The ear module interface.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public interface EarModule {
+
+    /**
+     * Returns the {@link Artifact} representing this module.
+     *
+     * Note that this might return {@code null} till the module has been resolved.
+     *
+     * @return the artifact
+     * @see #resolveArtifact(java.util.Set)
+     */
+    Artifact getArtifact();
+
+    /**
+     * Returns the {@code URI} for this module.
+     *
+     * @return the {@code URI}
+     */
+    String getUri();
+
+    /**
+     * Returns the type associated to the module.
+     *
+     * @return the artifact's type of the module
+     */
+    String getType();
+
+    /**
+     * Specify whether this module should be excluded or not.
+     *
+     * @return true if this module should be skipped, false otherwise
+     */
+    boolean isExcluded();
+
+    /**
+     * Specify whether this module should be unpacked in the EAR archive or not.
+     *
+     * Returns null if no configuration was specified so that defaulting may apply.
+     *
+     * @return true if this module should be bundled unpacked, false otherwise
+     */
+    Boolean shouldUnpack();
+
+    /**
+     * The alt-dd element specifies an optional URI to the post-assembly version of the deployment descriptor file for a
+     * particular Java EE module. The URI must specify the full pathname of the deployment descriptor file relative to
+     * the application's root directory.
+     *
+     * @return the alternative deployment descriptor for this module
+     * @since JavaEE 5
+     */
+    String getAltDeploymentDescriptor();
+
+    /**
+     * Appends the {@code XML} representation of this module.
+     *
+     * @param writer the writer to use
+     * @param version the version of the {@code application.xml} file
+     * @param generateId whether an id should be generated
+     */
+    void appendModule(XMLWriter writer, String version, Boolean generateId);
+
+    /**
+     * Resolves the {@link Artifact} represented by the module. Note that the {@link EarExecutionContext} might be used
+     * to customize further the resolution.
+     *
+     * @param artifacts the project's artifacts
+     * @throws EarPluginException if the artifact could not be resolved
+     * @throws MojoFailureException if an unexpected error occurred
+     */
+    void resolveArtifact(Set<Artifact> artifacts) throws EarPluginException, MojoFailureException;
+
+    /**
+     * @param earExecutionContext The execution context.
+     */
+    void setEarExecutionContext(EarExecutionContext earExecutionContext);
+
+    /**
+     * @return the state if manifest classpath will be changed or not.
+     */
+    boolean changeManifestClasspath();
+
+    /**
+     * @return The directory of the module which contains the JAR libraries packaged within the module.
+     * Can be {@code null}, which means that module doesn't contain any packaged libraries.
+     */
+    String getLibDir();
+
+    /**
+     * Returns the bundle file name. If {@code null}, the artifact's file name is returned.
+     *
+     * @return the bundle file name
+     */
+    String getBundleFileName();
+
+    /**
+     * If module should be included into the Class-Path entry of MANIFEST.mf. Doesn't impact Class-Path entry of
+     * MANIFEST.mf of modules which contain all of their dependencies unless skinnyWars / skinnyModules is turned on.
+     *
+     * @return {@code }True} if module should be included into the Class-Path entry of MANIFEST.mf
+     */
+    boolean isClassPathItem();
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarModuleFactory.java b/src/main/java/org/apache/maven/plugins/ear/EarModuleFactory.java
index e52827c..e2a9919 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarModuleFactory.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarModuleFactory.java
@@ -1,169 +1,157 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.util.Arrays;

-import java.util.Collections;

-import java.util.List;

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;

-import org.apache.maven.plugins.ear.util.JavaEEVersion;

-

-/**

- * Builds an {@link EarModule} based on an {@code Artifact}.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public final class EarModuleFactory

-{

-    private static final String TEST_JAR_ARTIFACT_TYPE = "test-jar";

-    private static final String JBOSS_PAR_ARTIFACT_TYPE = "jboss-par";

-    private static final String JBOSS_SAR_ARTIFACT_TYPE = "jboss-sar";

-    private static final String JBOSS_HAR_ARTIFACT_TYPE = "jboss-har";

-

-    /**

-     * The list of artifact types.

-     */

-    private static final List<String> STANDARD_ARTIFACT_TYPES =

-        Collections.unmodifiableList( Arrays.asList(

-            JarModule.DEFAULT_ARTIFACT_TYPE,

-            EjbModule.DEFAULT_ARTIFACT_TYPE,

-            ParModule.DEFAULT_ARTIFACT_TYPE,

-            EjbClientModule.DEFAULT_ARTIFACT_TYPE,

-            AppClientModule.DEFAULT_ARTIFACT_TYPE,

-            RarModule.DEFAULT_ARTIFACT_TYPE,

-            WebModule.DEFAULT_ARTIFACT_TYPE,

-            SarModule.DEFAULT_ARTIFACT_TYPE,

-            WsrModule.DEFAULT_ARTIFACT_TYPE,

-            HarModule.DEFAULT_ARTIFACT_TYPE,

-            TEST_JAR_ARTIFACT_TYPE,

-            JBOSS_PAR_ARTIFACT_TYPE,

-            JBOSS_SAR_ARTIFACT_TYPE,

-            JBOSS_HAR_ARTIFACT_TYPE ) );

-

-    /**

-     * Creates a new {@link EarModule} based on the specified {@link Artifact} and the specified execution

-     * configuration.

-     * 

-     * @param artifact the artifact

-     * @param javaEEVersion the javaEE version to use

-     * @param defaultLibBundleDir the default bundle dir for {@link org.apache.maven.plugins.ear.JarModule}

-     * @param includeInApplicationXml should {@link org.apache.maven.plugins.ear.JarModule} be included in application

-     *            Xml

-     * @param typeMappingService The artifact type mapping service

-     * @return an ear module for this artifact

-     * @throws UnknownArtifactTypeException if the artifact is not handled

-     */

-    public static EarModule newEarModule( Artifact artifact, JavaEEVersion javaEEVersion, String defaultLibBundleDir,

-                                          Boolean includeInApplicationXml,

-                                          ArtifactTypeMappingService typeMappingService )

-        throws UnknownArtifactTypeException

-    {

-        // Get the standard artifact type based on default config and user-defined mapping(s)

-        final String artifactType;

-        try

-        {

-            artifactType = typeMappingService.getStandardType( artifact.getType() );

-        }

-        catch ( UnknownArtifactTypeException e )

-        {

-            throw new UnknownArtifactTypeException( e.getMessage() + " for " + artifact.getArtifactId() );

-        }

-

-        if ( JarModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) || TEST_JAR_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new JarModule( artifact, defaultLibBundleDir, includeInApplicationXml );

-        }

-        else if ( EjbModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new EjbModule( artifact );

-        }

-        else if ( ParModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType )

-            || JBOSS_PAR_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new ParModule( artifact );

-        }

-        else if ( EjbClientModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            // Somewhat weird way to tackle the problem described in MEAR-85

-            if ( javaEEVersion.le( JavaEEVersion.ONE_DOT_FOUR ) )

-            {

-                return new EjbClientModule( artifact, null );

-            }

-            else

-            {

-                return new EjbClientModule( artifact, defaultLibBundleDir );

-            }

-        }

-        else if ( AppClientModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new AppClientModule( artifact );

-        }

-        else if ( RarModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new RarModule( artifact );

-        }

-        else if ( WebModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new WebModule( artifact );

-        }

-        else if ( SarModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType )

-            || JBOSS_SAR_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new SarModule( artifact );

-        }

-        else if ( WsrModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new WsrModule( artifact );

-        }

-        else if ( HarModule.DEFAULT_ARTIFACT_TYPE.equals( artifactType )

-            || JBOSS_HAR_ARTIFACT_TYPE.equals( artifactType ) )

-        {

-            return new HarModule( artifact );

-        }

-        else

-        {

-            throw new IllegalStateException( "Could not handle artifact type[" + artifactType + "]" );

-        }

-    }

-

-    /**

-     * Returns a list of standard artifact types.

-     * 

-     * @return the standard artifact types

-     */

-    public static List<String> getStandardArtifactTypes()

-    {

-        return STANDARD_ARTIFACT_TYPES;

-    }

-

-    /**

-     * Specify whether the specified type is standard artifact type.

-     * 

-     * @param type the type to check

-     * @return true if the specified type is a standard artifact type

-     */

-    public static boolean isStandardArtifactType( final String type )

-    {

-        return STANDARD_ARTIFACT_TYPES.contains( type );

-    }

-

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugins.ear.util.ArtifactTypeMappingService;
+import org.apache.maven.plugins.ear.util.JavaEEVersion;
+
+/**
+ * Builds an {@link EarModule} based on an {@code Artifact}.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public final class EarModuleFactory {
+    private static final String TEST_JAR_ARTIFACT_TYPE = "test-jar";
+    private static final String JBOSS_PAR_ARTIFACT_TYPE = "jboss-par";
+    private static final String JBOSS_SAR_ARTIFACT_TYPE = "jboss-sar";
+    private static final String JBOSS_HAR_ARTIFACT_TYPE = "jboss-har";
+
+    /**
+     * The list of artifact types.
+     */
+    private static final List<String> STANDARD_ARTIFACT_TYPES = Collections.unmodifiableList(Arrays.asList(
+            JarModule.DEFAULT_ARTIFACT_TYPE,
+            EjbModule.DEFAULT_ARTIFACT_TYPE,
+            ParModule.DEFAULT_ARTIFACT_TYPE,
+            EjbClientModule.DEFAULT_ARTIFACT_TYPE,
+            AppClientModule.DEFAULT_ARTIFACT_TYPE,
+            RarModule.DEFAULT_ARTIFACT_TYPE,
+            WebModule.DEFAULT_ARTIFACT_TYPE,
+            SarModule.DEFAULT_ARTIFACT_TYPE,
+            WsrModule.DEFAULT_ARTIFACT_TYPE,
+            HarModule.DEFAULT_ARTIFACT_TYPE,
+            TEST_JAR_ARTIFACT_TYPE,
+            JBOSS_PAR_ARTIFACT_TYPE,
+            JBOSS_SAR_ARTIFACT_TYPE,
+            JBOSS_HAR_ARTIFACT_TYPE));
+
+    /**
+     * Creates a new {@link EarModule} based on the specified {@link Artifact} and the specified execution
+     * configuration.
+     *
+     * @param artifact the artifact
+     * @param javaEEVersion the javaEE version to use
+     * @param defaultLibBundleDir the default bundle dir for {@link org.apache.maven.plugins.ear.JarModule}
+     * @param includeInApplicationXml should {@link org.apache.maven.plugins.ear.JarModule} be included in application
+     *            Xml
+     * @param typeMappingService The artifact type mapping service
+     * @return an ear module for this artifact
+     * @throws UnknownArtifactTypeException if the artifact is not handled
+     */
+    public static EarModule newEarModule(
+            Artifact artifact,
+            JavaEEVersion javaEEVersion,
+            String defaultLibBundleDir,
+            Boolean includeInApplicationXml,
+            ArtifactTypeMappingService typeMappingService)
+            throws UnknownArtifactTypeException {
+        // Get the standard artifact type based on default config and user-defined mapping(s)
+        final String artifactType;
+        try {
+            artifactType = typeMappingService.getStandardType(artifact.getType());
+        } catch (UnknownArtifactTypeException e) {
+            throw new UnknownArtifactTypeException(e.getMessage() + " for " + artifact.getArtifactId());
+        }
+
+        if (JarModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType) || TEST_JAR_ARTIFACT_TYPE.equals(artifactType)) {
+            return new JarModule(artifact, defaultLibBundleDir, includeInApplicationXml);
+        } else if (EjbModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            return new EjbModule(artifact);
+        } else if (ParModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)
+                || JBOSS_PAR_ARTIFACT_TYPE.equals(artifactType)) {
+            return new ParModule(artifact);
+        } else if (EjbClientModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            // Somewhat weird way to tackle the problem described in MEAR-85
+            if (javaEEVersion.le(JavaEEVersion.ONE_DOT_FOUR)) {
+                return new EjbClientModule(artifact, null);
+            } else {
+                return new EjbClientModule(artifact, defaultLibBundleDir);
+            }
+        } else if (AppClientModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            return new AppClientModule(artifact);
+        } else if (RarModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            return new RarModule(artifact);
+        } else if (WebModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            return new WebModule(artifact);
+        } else if (SarModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)
+                || JBOSS_SAR_ARTIFACT_TYPE.equals(artifactType)) {
+            return new SarModule(artifact);
+        } else if (WsrModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)) {
+            return new WsrModule(artifact);
+        } else if (HarModule.DEFAULT_ARTIFACT_TYPE.equals(artifactType)
+                || JBOSS_HAR_ARTIFACT_TYPE.equals(artifactType)) {
+            return new HarModule(artifact);
+        } else {
+            throw new IllegalStateException("Could not handle artifact type[" + artifactType + "]");
+        }
+    }
+
+    /**
+     * Returns a list of standard artifact types.
+     *
+     * @return the standard artifact types
+     */
+    public static List<String> getStandardArtifactTypes() {
+        return STANDARD_ARTIFACT_TYPES;
+    }
+
+    /**
+     * Specify whether the specified type is standard artifact type.
+     *
+     * @param type the type to check
+     * @return true if the specified type is a standard artifact type
+     */
+    public static boolean isStandardArtifactType(final String type) {
+        return STANDARD_ARTIFACT_TYPES.contains(type);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
index 3f11163..53d6423 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
@@ -1,1083 +1,947 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.BufferedWriter;

-import java.io.File;

-import java.io.IOException;

-import java.io.InputStream;

-import java.nio.charset.StandardCharsets;

-import java.nio.file.FileSystem;

-import java.nio.file.FileSystems;

-import java.nio.file.FileVisitResult;

-import java.nio.file.Files;

-import java.nio.file.LinkOption;

-import java.nio.file.Path;

-import java.nio.file.Paths;

-import java.nio.file.ProviderMismatchException;

-import java.nio.file.SimpleFileVisitor;

-import java.nio.file.StandardCopyOption;

-import java.nio.file.StandardOpenOption;

-import java.nio.file.attribute.BasicFileAttributes;

-import java.nio.file.attribute.FileTime;

-import java.util.ArrayList;

-import java.util.Arrays;

-import java.util.Collection;

-import java.util.List;

-import java.util.Objects;

-

-import org.apache.maven.archiver.MavenArchiveConfiguration;

-import org.apache.maven.archiver.MavenArchiver;

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.artifact.DependencyResolutionRequiredException;

-import org.apache.maven.execution.MavenSession;

-import org.apache.maven.plugin.MojoExecutionException;

-import org.apache.maven.plugin.MojoFailureException;

-import org.apache.maven.plugins.annotations.Component;

-import org.apache.maven.plugins.annotations.LifecyclePhase;

-import org.apache.maven.plugins.annotations.Mojo;

-import org.apache.maven.plugins.annotations.Parameter;

-import org.apache.maven.plugins.annotations.ResolutionScope;

-import org.apache.maven.plugins.ear.util.EarMavenArchiver;

-import org.apache.maven.plugins.ear.util.JavaEEVersion;

-import org.apache.maven.project.MavenProjectHelper;

-import org.apache.maven.shared.filtering.FilterWrapper;

-import org.apache.maven.shared.filtering.MavenFileFilter;

-import org.apache.maven.shared.filtering.MavenFilteringException;

-import org.apache.maven.shared.filtering.MavenResourcesExecution;

-import org.apache.maven.shared.filtering.MavenResourcesFiltering;

-import org.apache.maven.shared.mapping.MappingUtils;

-import org.apache.maven.shared.utils.io.FileUtils;

-import org.codehaus.plexus.archiver.Archiver;

-import org.codehaus.plexus.archiver.ArchiverException;

-import org.codehaus.plexus.archiver.UnArchiver;

-import org.codehaus.plexus.archiver.ear.EarArchiver;

-import org.codehaus.plexus.archiver.jar.JarArchiver;

-import org.codehaus.plexus.archiver.jar.Manifest;

-import org.codehaus.plexus.archiver.jar.Manifest.Attribute;

-import org.codehaus.plexus.archiver.jar.ManifestException;

-import org.codehaus.plexus.archiver.manager.ArchiverManager;

-import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;

-import org.codehaus.plexus.components.io.filemappers.FileMapper;

-import org.codehaus.plexus.interpolation.InterpolationException;

-import org.codehaus.plexus.util.DirectoryScanner;

-import org.codehaus.plexus.util.StringUtils;

-

-/**

- * Builds J2EE Enterprise Archive (EAR) files.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-@Mojo( name = "ear",

-       defaultPhase = LifecyclePhase.PACKAGE,

-       threadSafe = true,

-       requiresDependencyResolution = ResolutionScope.TEST )

-public class EarMojo

-    extends AbstractEarMojo

-{

-    /**

-     * Default file name mapping used by artifacts located in local repository.

-     */

-    private static final String ARTIFACT_DEFAULT_FILE_NAME_MAPPING =

-        "@{artifactId}@-@{version}@@{dashClassifier?}@.@{extension}@";

-

-    /**

-     * Single directory for extra files to include in the EAR.

-     */

-    @Parameter( defaultValue = "${basedir}/src/main/application", required = true )

-    private File earSourceDirectory;

-

-    /**

-     * The comma separated list of tokens to include in the EAR.

-     */

-    @Parameter( alias = "includes", defaultValue = "**" )

-    private String earSourceIncludes;

-

-    /**

-     * The comma separated list of tokens to exclude from the EAR.

-     */

-    @Parameter( alias = "excludes" )

-    private String earSourceExcludes;

-

-    /**

-     * Specify that the EAR sources should be filtered.

-     * 

-     * @since 2.3.2

-     */

-    @Parameter( defaultValue = "false" )

-    private boolean filtering;

-

-    /**

-     * Filters (property files) to include during the interpolation of the pom.xml.

-     * 

-     * @since 2.3.2

-     */

-    @Parameter

-    private List<String> filters;

-

-    /**

-     * A list of file extensions that should not be filtered if filtering is enabled.

-     * 

-     * @since 2.3.2

-     */

-    @Parameter

-    private List<String> nonFilteredFileExtensions;

-

-    /**

-     * To escape interpolated value with Windows path c:\foo\bar will be replaced with c:\\foo\\bar.

-     * 

-     * @since 2.3.2

-     */

-    @Parameter( defaultValue = "false" )

-    private boolean escapedBackslashesInFilePath;

-

-    /**

-     * Expression preceded with this String won't be interpolated \${foo} will be replaced with ${foo}.

-     * 

-     * @since 2.3.2

-     */

-    @Parameter

-    protected String escapeString;

-

-    /**

-     * In case of using the {@link #skinnyWars} and {@link #defaultLibBundleDir} usually the classpath will be modified.

-     * By settings this option {@code true} you can change this and keep the classpath untouched. This option has been

-     * introduced to keep the backward compatibility with earlier versions of the plugin.

-     * 

-     * @since 2.10

-     */

-    @Parameter( defaultValue = "false" )

-    private boolean skipClassPathModification;

-

-    /**

-     * The location of a custom application.xml file to be used within the EAR file.

-     */

-    @Parameter

-    private File applicationXml;

-

-    /**

-     * The directory for the generated EAR.

-     */

-    @Parameter( defaultValue = "${project.build.directory}", required = true )

-    private String outputDirectory;

-

-    /**

-     * The name of the EAR file to generate.

-     */

-    @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )

-    private String finalName;

-

-    /**

-     * The comma separated list of artifact's type(s) to unpack by default.

-     */

-    @Parameter

-    private String unpackTypes;

-

-    /**

-     * Classifier to add to the artifact generated. If given, the artifact will be an attachment instead.

-     */

-    @Parameter

-    private String classifier;

-

-    /**

-     * A comma separated list of tokens to exclude when packaging the EAR. By default nothing is excluded. Note that you

-     * can use the Java Regular Expressions engine to include and exclude specific pattern using the expression

-     * %regex[]. Hint: read the about (?!Pattern).

-     * 

-     * @since 2.7

-     */

-    @Parameter

-    private String packagingExcludes;

-

-    /**

-     * A comma separated list of tokens to include when packaging the EAR. By default everything is included. Note that

-     * you can use the Java Regular Expressions engine to include and exclude specific pattern using the expression

-     * %regex[].

-     * 

-     * @since 2.7

-     */

-    @Parameter

-    private String packagingIncludes;

-

-    /**

-     * Whether to create skinny WARs or not. A skinny WAR is a WAR that does not have all of its dependencies in

-     * WEB-INF/lib. Instead those dependencies are shared between the WARs through the EAR.

-     * 

-     * @since 2.7

-     */

-    @Parameter( defaultValue = "false" )

-    private boolean skinnyWars;

-

-    /**

-     * Whether to create skinny EAR modules or not. A skinny EAR module is a WAR, SAR, HAR, RAR or WSR module that

-     * does not contain all of its dependencies in it. Instead those dependencies are shared between the WARs, SARs,

-     * HARs, RARs and WSRs through the EAR. This option takes precedence over {@link #skinnyWars} option. That is if

-     * skinnyModules is {@code true} but {@link #skinnyWars} is {@code false} (explicitly or by default) then all

-     * modules including WARs are skinny.

-     *

-     * @since 3.2.0

-     */

-    @Parameter( defaultValue = "false" )

-    private boolean skinnyModules;

-

-    /**

-     * The Plexus EAR archiver to create the output archive.

-     */

-    @Component( role = Archiver.class, hint = "ear" )

-    private EarArchiver earArchiver;

-

-    /**

-     * The Plexus JAR archiver to create the output archive if not EAR application descriptor is provided (JavaEE 5+).

-     */

-    @Component( role = Archiver.class, hint = "jar" )

-    private JarArchiver jarArchiver;

-

-    /**

-     * The archive configuration to use. See <a href="https://maven.apache.org/shared/maven-archiver/">Maven Archiver

-     * Reference</a>.

-     */

-    @Parameter

-    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();

-

-    /**

-     * Timestamp for reproducible output archive entries, either formatted as ISO 8601

-     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like

-     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).

-     *

-     * @since 3.1.0

-     */

-    @Parameter( defaultValue = "${project.build.outputTimestamp}" )

-    private String outputTimestamp;

-

-    /**

-     */

-    @Component

-    private MavenProjectHelper projectHelper;

-

-    /**

-     * The archive manager.

-     */

-    @Component

-    private ArchiverManager archiverManager;

-

-    /**

-     */

-    @Component( role = MavenFileFilter.class, hint = "default" )

-    private MavenFileFilter mavenFileFilter;

-

-    /**

-     */

-    @Component( role = MavenResourcesFiltering.class, hint = "default" )

-    private MavenResourcesFiltering mavenResourcesFiltering;

-

-    /**

-     * @since 2.3.2

-     */

-    @Parameter( defaultValue = "${session}", readonly = true, required = true )

-    private MavenSession session;

-

-    private List<FilterWrapper> filterWrappers;

-

-    /** {@inheritDoc} */

-    public void execute()

-        throws MojoExecutionException, MojoFailureException

-    {

-        // Initializes ear modules

-        super.execute();

-

-        File earFile = getEarFile( outputDirectory, finalName, classifier );

-        MavenArchiver archiver = new EarMavenArchiver( getModules() );

-        File ddFile = new File( getWorkDirectory(), APPLICATION_XML_URI );

-

-        JarArchiver theArchiver;

-        if ( ddFile.exists() )

-        {

-            earArchiver.setAppxml( ddFile );

-            theArchiver = earArchiver;

-        }

-        else

-        {

-            // current Plexus EarArchiver does not support application.xml-less JavaEE 5+ case

-            // => fallback to Plexus Jar archiver 

-            theArchiver = jarArchiver;

-        }

-        getLog().debug( "Ear archiver implementation [" + theArchiver.getClass().getName() + "]" );

-        archiver.setArchiver( theArchiver );

-        archiver.setOutputFile( earFile );

-        archiver.setCreatedBy( "Maven EAR Plugin", "org.apache.maven.plugins", "maven-ear-plugin" );

-

-        // configure for Reproducible Builds based on outputTimestamp value

-        archiver.configureReproducibleBuild( outputTimestamp );

-

-        final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );

-

-        final Collection<String> outdatedResources = initOutdatedResources();

-

-        // Initializes unpack types

-        List<String> unpackTypesList = createUnpackList();

-

-        // Copy modules

-        copyModules( javaEEVersion, unpackTypesList, outdatedResources );

-

-        // Copy source files

-        try

-        {

-            File earSourceDir = earSourceDirectory;

-

-            if ( earSourceDir.exists() )

-            {

-                getLog().info( "Copy ear sources to " + getWorkDirectory().getAbsolutePath() );

-                String[] fileNames = getEarFiles( earSourceDir );

-                for ( String fileName : fileNames )

-                {

-                    copyFile( new File( earSourceDir, fileName ), new File( getWorkDirectory(), fileName ) );

-                    outdatedResources.remove( Paths.get( fileName ).toString() );

-                }

-            }

-

-            if ( applicationXml != null )

-            {

-                // rename to application.xml

-                getLog().info( "Including custom application.xml[" + applicationXml + "]" );

-                File metaInfDir = new File( getWorkDirectory(), META_INF );

-                copyFile( applicationXml, new File( metaInfDir, "/application.xml" ) );

-                outdatedResources.remove( Paths.get( "META-INF/application.xml" ).toString() );

-            }

-        }

-        catch ( IOException e )

-        {

-            throw new MojoExecutionException( "Error copying EAR sources", e );

-        }

-        catch ( MavenFilteringException e )

-        {

-            throw new MojoExecutionException( "Error filtering EAR sources", e );

-        }

-

-        // Check if deployment descriptor is there

-        if ( !ddFile.exists() && ( javaEEVersion.lt( JavaEEVersion.FIVE ) ) )

-        {

-            throw new MojoExecutionException( "Deployment descriptor: " + ddFile.getAbsolutePath()

-                + " does not exist." );

-        }

-        // no need to check timestamp for descriptors: removing if outdated does not really make sense

-        outdatedResources.remove( Paths.get( APPLICATION_XML_URI ).toString() );

-        if ( getJbossConfiguration() != null )

-        {

-            outdatedResources.remove( Paths.get( "META-INF/jboss-app.xml" ).toString() );

-        }

-

-        deleteOutdatedResources( outdatedResources );

-

-        try

-        {

-            getLog().debug( "Excluding " + Arrays.asList( getPackagingExcludes() ) + " from the generated EAR." );

-            getLog().debug( "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated EAR." );

-

-            archiver.getArchiver().addDirectory( getWorkDirectory(), getPackagingIncludes(), getPackagingExcludes() );

-

-            archiver.createArchive( session, getProject(), archive );

-        }

-        catch ( ManifestException | IOException | DependencyResolutionRequiredException e )

-        {

-            throw new MojoExecutionException( "Error assembling EAR", e );

-        }

-

-        if ( classifier != null )

-        {

-            projectHelper.attachArtifact( getProject(), "ear", classifier, earFile );

-        }

-        else

-        {

-            getProject().getArtifact().setFile( earFile );

-        }

-    }

-

-    private void copyModules( final JavaEEVersion javaEEVersion, 

-                              List<String> unpackTypesList, 

-                              Collection<String> outdatedResources )

-        throws MojoExecutionException, MojoFailureException

-    {

-        try

-        {

-            for ( EarModule module : getModules() )

-            {

-                final File sourceFile = module.getArtifact().getFile();

-                final File destinationFile = buildDestinationFile( getWorkDirectory(), module.getUri() );

-                if ( !sourceFile.isFile() )

-                {

-                    throw new MojoExecutionException( "Cannot copy a directory: " + sourceFile.getAbsolutePath()

-                        + "; Did you package/install " + module.getArtifact() + "?" );

-                }

-

-                if ( destinationFile.getCanonicalPath().equals( sourceFile.getCanonicalPath() ) )

-                {

-                    getLog().info( "Skipping artifact [" + module + "], as it already exists at [" + module.getUri()

-                        + "]" );

-                    // FIXME: Shouldn't that result in a build failure!?

-                    continue;

-                }

-

-                // If the module is within the unpack list, make sure that no unpack wasn't forced (null or true)

-                // If the module is not in the unpack list, it should be true

-                if ( ( unpackTypesList.contains( module.getType() )

-                    && ( module.shouldUnpack() == null || module.shouldUnpack() ) )

-                    || ( module.shouldUnpack() != null && module.shouldUnpack() ) )

-                {

-                    getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "] (unpacked)" );

-                    // Make sure that the destination is a directory to avoid plexus nasty stuff :)

-                    if ( !destinationFile.isDirectory() && !destinationFile.mkdirs() )

-                    {

-                        throw new MojoExecutionException( "Error creating " + destinationFile );

-                    }

-                    unpack( sourceFile, destinationFile, outdatedResources );

-

-                    if ( module.changeManifestClasspath() )

-                    {

-                        changeManifestClasspath( module, destinationFile, javaEEVersion, outdatedResources );

-                    }

-                }

-                else

-                {

-                    if ( sourceFile.lastModified() > destinationFile.lastModified() )

-                    {

-                        getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "]" );

-                        createParentIfNecessary( destinationFile );

-                        Files.copy( sourceFile.toPath(), destinationFile.toPath(),

-                            LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING );

-                        if ( module.changeManifestClasspath() )

-                        {

-                            changeManifestClasspath( module, destinationFile, javaEEVersion, outdatedResources );

-                        }

-                    }

-                    else

-                    {

-                        getLog().debug( "Skipping artifact [" + module + "], as it is already up to date at ["

-                            + module.getUri() + "]" );

-                    }

-                    removeFromOutdatedResources( destinationFile.toPath(), outdatedResources );

-                }

-            }

-        }

-        catch ( IOException e )

-        {

-            throw new MojoExecutionException( "Error copying EAR modules", e );

-        }

-        catch ( ArchiverException e )

-        {

-            throw new MojoExecutionException( "Error unpacking EAR modules", e );

-        }

-        catch ( NoSuchArchiverException e )

-        {

-            throw new MojoExecutionException( "No Archiver found for EAR modules", e );

-        }

-    }

-

-    private List<String> createUnpackList()

-        throws MojoExecutionException

-    {

-        List<String> unpackTypesList = new ArrayList<>();

-        if ( unpackTypes != null )

-        {

-            unpackTypesList = Arrays.asList( unpackTypes.split( "," ) );

-            for ( String type : unpackTypesList )

-            {

-                if ( !EarModuleFactory.isStandardArtifactType( type ) )

-                {

-                    throw new MojoExecutionException( "Invalid type [" + type + "] supported types are "

-                        + EarModuleFactory.getStandardArtifactTypes() );

-                }

-            }

-            getLog().debug( "Initialized unpack types " + unpackTypesList );

-        }

-        return unpackTypesList;

-    }

-

-    /**

-     * @return {@link #applicationXml}

-     */

-    public File getApplicationXml()

-    {

-        return applicationXml;

-    }

-

-    /**

-     * @param applicationXml {@link #applicationXml}

-     */

-    public void setApplicationXml( File applicationXml )

-    {

-        this.applicationXml = applicationXml;

-    }

-

-    /**

-     * Returns a string array of the excludes to be used when assembling/copying the ear.

-     * 

-     * @return an array of tokens to exclude

-     */

-    protected String[] getExcludes()

-    {

-        List<String> excludeList = new ArrayList<>( FileUtils.getDefaultExcludesAsList() );

-        if ( earSourceExcludes != null && !"".equals( earSourceExcludes ) )

-        {

-            excludeList.addAll( Arrays.asList( StringUtils.split( earSourceExcludes, "," ) ) );

-        }

-

-        // if applicationXml is specified, omit the one in the source directory

-        if ( getApplicationXml() != null && !"".equals( getApplicationXml() ) )

-        {

-            excludeList.add( "**/" + META_INF + "/application.xml" );

-        }

-

-        return excludeList.toArray( new String[excludeList.size()] );

-    }

-

-    /**

-     * Returns a string array of the includes to be used when assembling/copying the ear.

-     * 

-     * @return an array of tokens to include

-     */

-    protected String[] getIncludes()

-    {

-        return StringUtils.split( Objects.toString( earSourceIncludes, "" ), "," );

-    }

-

-    /**

-     * @return The array with the packaging excludes.

-     */

-    public String[] getPackagingExcludes()

-    {

-        if ( packagingExcludes == null || packagingExcludes.isEmpty() )

-        {

-            return new String[0];

-        }

-        else

-        {

-            return StringUtils.split( packagingExcludes, "," );

-        }

-    }

-

-    /**

-     * @param packagingExcludes {@link #packagingExcludes}

-     */

-    public void setPackagingExcludes( String packagingExcludes )

-    {

-        this.packagingExcludes = packagingExcludes;

-    }

-

-    /**

-     * @return the arrays with the includes

-     */

-    public String[] getPackagingIncludes()

-    {

-        if ( packagingIncludes == null || packagingIncludes.isEmpty() )

-        {

-            return new String[] { "**" };

-        }

-        else

-        {

-            return StringUtils.split( packagingIncludes, "," );

-        }

-    }

-

-    /**

-     * @param packagingIncludes {@link #packagingIncludes}

-     */

-    public void setPackagingIncludes( String packagingIncludes )

-    {

-        this.packagingIncludes = packagingIncludes;

-    }

-

-    private static File buildDestinationFile( File buildDir, String uri )

-    {

-        return new File( buildDir, uri );

-    }

-

-    /**

-     * Returns the EAR file to generate, based on an optional classifier.

-     * 

-     * @param basedir the output directory

-     * @param finalName the name of the ear file

-     * @param classifier an optional classifier

-     * @return the EAR file to generate

-     */

-    private static File getEarFile( String basedir, String finalName, String classifier )

-    {

-        if ( classifier == null )

-        {

-            classifier = "";

-        }

-        else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )

-        {

-            classifier = "-" + classifier;

-        }

-

-        return new File( basedir, finalName + classifier + ".ear" );

-    }

-

-    /**

-     * Returns a list of filenames that should be copied over to the destination directory.

-     * 

-     * @param sourceDir the directory to be scanned

-     * @return the array of filenames, relative to the sourceDir

-     */

-    private String[] getEarFiles( File sourceDir )

-    {

-        DirectoryScanner scanner = new DirectoryScanner();

-        scanner.setBasedir( sourceDir );

-        scanner.setExcludes( getExcludes() );

-        scanner.addDefaultExcludes();

-

-        scanner.setIncludes( getIncludes() );

-

-        scanner.scan();

-

-        return scanner.getIncludedFiles();

-    }

-

-    /**

-     * Unpacks the module into the EAR structure.

-     * 

-     * @param source file to be unpacked

-     * @param destDir where to put the unpacked files

-     * @param outdatedResources currently outdated resources

-     * @throws ArchiverException a corrupt archive

-     * @throws NoSuchArchiverException if we don't have an appropriate archiver

-     * @throws IOException in case of a general IOException

-     */

-    public void unpack( File source, final File destDir, final Collection<String> outdatedResources )

-        throws ArchiverException, NoSuchArchiverException, IOException

-    {

-        Path destPath = destDir.toPath();

-

-        UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );

-        unArchiver.setSourceFile( source );

-        unArchiver.setDestDirectory( destDir );

-        unArchiver.setFileMappers( new FileMapper[] {

-            pName ->

-            {

-                removeFromOutdatedResources( destPath.resolve( pName ), outdatedResources );

-                return pName;

-            }

-        } );

-

-        // Extract the module

-        unArchiver.extract();

-    }

-

-    private void copyFile( File source, File target )

-        throws MavenFilteringException, IOException, MojoExecutionException

-    {

-        createParentIfNecessary( target );

-        if ( filtering && !isNonFilteredExtension( source.getName() ) )

-        {

-            mavenFileFilter.copyFile( source, target, true, getFilterWrappers(), encoding );

-        }

-        else

-        {

-            Files.copy( source.toPath(), target.toPath(), LinkOption.NOFOLLOW_LINKS,

-                       StandardCopyOption.REPLACE_EXISTING );

-        }

-    }

-

-    private void createParentIfNecessary( File target )

-        throws IOException

-    {

-        // Silly that we have to do this ourselves

-        File parentDirectory = target.getParentFile();

-        if ( parentDirectory != null && !parentDirectory.exists() )

-        {

-            Files.createDirectories( parentDirectory.toPath() );

-        }

-    }

-

-    /**

-     * @param fileName the name of the file which should be checked

-     * @return {@code true} if the name is part of the non filtered extensions; {@code false} otherwise

-     */

-    public boolean isNonFilteredExtension( String fileName )

-    {

-        return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );

-    }

-

-    private List<FilterWrapper> getFilterWrappers()

-        throws MojoExecutionException

-    {

-        if ( filterWrappers == null )

-        {

-            try

-            {

-                MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();

-                mavenResourcesExecution.setMavenProject( getProject() );

-                mavenResourcesExecution.setEscapedBackslashesInFilePath( escapedBackslashesInFilePath );

-                mavenResourcesExecution.setFilters( filters );

-                mavenResourcesExecution.setEscapeString( escapeString );

-

-                filterWrappers = mavenFileFilter.getDefaultFilterWrappers( mavenResourcesExecution );

-            }

-            catch ( MavenFilteringException e )

-            {

-                getLog().error( "Fail to build filtering wrappers " + e.getMessage() );

-                throw new MojoExecutionException( e.getMessage(), e );

-            }

-        }

-        return filterWrappers;

-    }

-

-    private void changeManifestClasspath( EarModule module, File original, JavaEEVersion javaEEVersion,

-                                          Collection<String> outdatedResources )

-        throws MojoFailureException

-    {

-        final String moduleLibDir = module.getLibDir();

-        if ( !( ( moduleLibDir == null ) || skinnyModules || ( skinnyWars && module instanceof WebModule ) ) )

-        {

-            return;

-        }

-

-        // for new created items

-        FileTime outputFileTime = MavenArchiver.parseBuildOutputTimestamp( outputTimestamp )

-            .map( FileTime::from )

-            .orElse( null );

-

-        FileSystem fileSystem = null;

-

-        try

-        {

-            Path workDirectory;

-

-            // Handle the case that the destination might be a directory (project-038)

-            // We can get FileSystems only for files

-            if ( original.isFile() )

-            {

-                fileSystem = FileSystems.newFileSystem(

-                    original.toPath(), Thread.currentThread().getContextClassLoader() );

-                workDirectory = fileSystem.getRootDirectories().iterator().next();

-            }

-            else

-            {

-                workDirectory = original.toPath();

-            }

-

-            // Create a META-INF/MANIFEST.MF file if it doesn't exist (project-038)

-            Path metaInfDirectory = workDirectory.resolve( "META-INF" );

-            if ( !Files.exists( metaInfDirectory ) )

-            {

-                Files.createDirectory( metaInfDirectory );

-                if ( outputFileTime != null )

-                {

-                    Files.setLastModifiedTime( metaInfDirectory, outputFileTime );

-                }

-                getLog().debug(

-                    "This project did not have a META-INF directory before, so a new directory was created." );

-            }

-            Path manifestFile = metaInfDirectory.resolve( "MANIFEST.MF" );

-            if ( !Files.exists( manifestFile ) )

-            {

-                Files.createFile( manifestFile );

-                if ( outputFileTime != null )

-                {

-                    Files.setLastModifiedTime( manifestFile, outputFileTime );

-                }

-                getLog().debug(

-                    "This project did not have a META-INF/MANIFEST.MF file before, so a new file was created." );

-            }

-

-            Manifest mf = readManifest( manifestFile );

-            Attribute classPath = mf.getMainSection().getAttribute( "Class-Path" );

-            List<String> classPathElements = new ArrayList<>();

-

-            boolean classPathExists;

-            if ( classPath != null )

-            {

-                classPathExists = true;

-                classPathElements.addAll( Arrays.asList( classPath.getValue().split( " " ) ) );

-            }

-            else

-            {

-                classPathExists = false;

-                classPath = new Attribute( "Class-Path", "" );

-            }

-

-            if ( ( moduleLibDir != null ) && ( skinnyModules || ( skinnyWars && module instanceof WebModule ) ) )

-            {

-                // Remove modules

-                for ( EarModule otherModule : getAllEarModules() )

-                {

-                    if ( module.equals( otherModule ) )

-                    {

-                        continue;

-                    }

-                    // MEAR-189:

-                    // We use the original name, cause in case of outputFileNameMapping

-                    // we could not not delete it and it will end up in the resulting EAR and the WAR

-                    // will not be cleaned up.

-                    final Path workLibDir = workDirectory.resolve( moduleLibDir );

-                    Path artifact = workLibDir.resolve( module.getArtifact().getFile().getName() );

-

-                    // MEAR-217

-                    // If WAR contains files with timestamps, but EAR strips them away (useBaseVersion=true)

-                    // the artifact is not found. Therefore, respect the current fileNameMapping additionally.

-

-                    if ( !Files.exists( artifact ) )

-                    {

-                        getLog().debug( "module does not exist with original file name." );

-                        artifact = workLibDir.resolve( otherModule.getBundleFileName() );

-                        getLog().debug( "Artifact with mapping: " + artifact.toAbsolutePath() );

-                    }

-

-                    if ( !Files.exists( artifact ) )

-                    {

-                        getLog().debug( "Artifact with mapping does not exist." );

-                        artifact = workLibDir.resolve( otherModule.getArtifact().getFile().getName() );

-                        getLog().debug( "Artifact with original file name: " + artifact.toAbsolutePath() );

-                    }

-

-                    if ( !Files.exists( artifact ) )

-                    {

-                        getLog().debug( "Artifact with original file name does not exist." );

-                        final Artifact otherModuleArtifact = otherModule.getArtifact();

-                        if ( otherModuleArtifact.isSnapshot() )

-                        {

-                            try

-                            {

-                                artifact = workLibDir.resolve( MappingUtils.evaluateFileNameMapping(

-                                        ARTIFACT_DEFAULT_FILE_NAME_MAPPING, otherModuleArtifact ) );

-                                getLog()

-                                    .debug( "Artifact with default mapping file name: " + artifact.toAbsolutePath() );

-                            }

-                            catch ( InterpolationException e )

-                            {

-                                getLog().warn(

-                                    "Failed to evaluate file name for [" + otherModule + "] module using mapping: "

-                                        + ARTIFACT_DEFAULT_FILE_NAME_MAPPING );

-                            }

-                        }

-                    }

-

-                    if ( Files.exists( artifact ) )

-                    {

-                        getLog().debug( " -> Artifact to delete: " + artifact );

-                        Files.delete( artifact );

-                    }

-                }

-            }

-

-            // Modify the classpath entries in the manifest

-            final boolean forceClassPathModification =

-                javaEEVersion.lt( JavaEEVersion.FIVE ) || defaultLibBundleDir == null;

-            final boolean classPathExtension = !skipClassPathModification || forceClassPathModification;

-            for ( EarModule otherModule : getModules() )

-            {

-                if ( module.equals( otherModule ) )

-                {

-                    continue;

-                }

-                final int moduleClassPathIndex = findModuleInClassPathElements( classPathElements, otherModule );

-                if ( moduleClassPathIndex != -1 )

-                {

-                    if ( otherModule.isClassPathItem() )

-                    {

-                        classPathElements.set( moduleClassPathIndex, otherModule.getUri() );

-                    }

-                    else

-                    {

-                        classPathElements.remove( moduleClassPathIndex );

-                    }

-                }

-                else if ( otherModule.isClassPathItem() && classPathExtension )

-                {

-                    classPathElements.add( otherModule.getUri() );

-                }

-            }

-

-            // Remove provided modules from classpath

-            for ( EarModule otherModule : getProvidedEarModules() )

-            {

-                final int moduleClassPathIndex = findModuleInClassPathElements( classPathElements, otherModule );

-                if ( moduleClassPathIndex != -1 )

-                {

-                    classPathElements.remove( moduleClassPathIndex );

-                }

-            }

-

-            if ( !skipClassPathModification || !classPathElements.isEmpty() || classPathExists )

-            {

-                classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );

-                mf.getMainSection().addConfiguredAttribute( classPath );

-

-                // Write the manifest to disk, preserve timestamp

-                FileTime lastModifiedTime = Files.getLastModifiedTime( manifestFile );

-                try ( BufferedWriter writer = Files.newBufferedWriter( manifestFile, StandardCharsets.UTF_8,

-                                                                       StandardOpenOption.WRITE,

-                                                                       StandardOpenOption.CREATE,

-                                                                       StandardOpenOption.TRUNCATE_EXISTING ) )

-                {

-                    mf.write( writer );

-                }

-                Files.setLastModifiedTime( manifestFile, lastModifiedTime );

-                removeFromOutdatedResources( manifestFile, outdatedResources );

-            }

-

-            if ( fileSystem != null )

-            {

-                fileSystem.close();

-                fileSystem = null;

-            }

-        }

-        catch ( ManifestException | IOException | ArchiverException e )

-        {

-            throw new MojoFailureException( e.getMessage(), e );

-        }

-        finally

-        {

-            if ( fileSystem != null )

-            {

-                try

-                {

-                    fileSystem.close();

-                }

-                catch ( IOException e )

-                {

-                    // ignore here

-                }

-            }

-        }

-    }

-

-    private static Manifest readManifest( Path manifestFile )

-        throws IOException

-    {

-        // Read the manifest from disk

-        try ( InputStream in = Files.newInputStream( manifestFile ) )

-        {

-            return new Manifest( in );

-        }

-    }

-

-    private Collection<String> initOutdatedResources()

-    {

-        final Collection<String> outdatedResources = new ArrayList<>();

-        

-        if ( getWorkDirectory().exists() )

-        {

-            try

-            {

-                Files.walkFileTree( getWorkDirectory().toPath(), new SimpleFileVisitor<Path>() 

-                {

-                    @Override

-                    public FileVisitResult visitFile( Path file, BasicFileAttributes attrs )

-                        throws IOException

-                    {

-                        outdatedResources.add( getWorkDirectory().toPath().relativize( file ).toString() );

-                        return super.visitFile( file, attrs );

-                    }

-                } );

-            }

-            catch ( IOException e )

-            {

-                getLog().warn( "Can't detect outdated resources", e );

-            } 

-        }

-

-        getLog().debug( "initOutdatedResources: " + outdatedResources );

-        return outdatedResources;

-    }

-

-    private void deleteOutdatedResources( final Collection<String> outdatedResources )

-    {

-        getLog().debug( "deleteOutdatedResources: " + outdatedResources );

-        final long startTime = session.getStartTime().getTime();

-

-        getLog().debug( "deleteOutdatedResources session startTime: " + startTime );

-

-        for ( String outdatedResource : outdatedResources )

-        {

-            File resourceFile = new File( getWorkDirectory(), outdatedResource );

-            if ( resourceFile.lastModified() < startTime )

-            {

-                getLog().info( "deleting outdated resource " + outdatedResource );

-                getLog().debug( outdatedResource + " last modified: " + resourceFile.lastModified() );

-                resourceFile.delete();

-            }

-        }

-    }

-

-    private void removeFromOutdatedResources( Path destination, Collection<String> outdatedResources )

-    {

-        Path relativeDestFile;

-        try

-        {

-            relativeDestFile = getWorkDirectory().toPath().relativize( destination.normalize() );

-        }

-        catch ( ProviderMismatchException e )

-        {

-            relativeDestFile = destination.normalize();

-        }

-

-        if ( outdatedResources.remove( relativeDestFile.toString() ) )

-        {

-            getLog().debug( "Remove from outdatedResources: " + relativeDestFile );

-        }

-    }

-

-    /**

-     * Searches for the given JAR module in the list of classpath elements. If JAR module is found among specified

-     * classpath elements then returns index of first matching element. Returns -1 otherwise.

-     *

-     * @param classPathElements classpath elements to search among

-     * @param module module to find among classpath elements defined by {@code classPathElements}

-     * @return -1 if {@code module} was not found in {@code classPathElements} or index of item of

-     * {@code classPathElements} which matches {@code module}

-     */

-    private int findModuleInClassPathElements( final List<String> classPathElements, final EarModule module )

-    {

-        if ( classPathElements.isEmpty() )

-        {

-            return -1;

-        }

-        int moduleClassPathIndex = classPathElements.indexOf( module.getBundleFileName() );

-        if ( moduleClassPathIndex != -1 )

-        {

-            return moduleClassPathIndex;

-        }

-        final Artifact artifact = module.getArtifact();

-        moduleClassPathIndex = classPathElements.indexOf( artifact.getFile().getName() );

-        if ( moduleClassPathIndex != -1 )

-        {

-            return moduleClassPathIndex;

-        }

-        if ( artifact.isSnapshot() )

-        {

-            try

-            {

-                moduleClassPathIndex = classPathElements

-                    .indexOf( MappingUtils.evaluateFileNameMapping( ARTIFACT_DEFAULT_FILE_NAME_MAPPING, artifact ) );

-                if ( moduleClassPathIndex != -1 )

-                {

-                    return moduleClassPathIndex;

-                }

-            }

-            catch ( InterpolationException e )

-            {

-                getLog().warn( "Failed to evaluate file name for [" + module + "] module using mapping: "

-                    + ARTIFACT_DEFAULT_FILE_NAME_MAPPING );

-            }

-        }

-        return classPathElements.indexOf( module.getUri() );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.plugins.ear.util.EarMavenArchiver;
+import org.apache.maven.plugins.ear.util.JavaEEVersion;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.shared.filtering.FilterWrapper;
+import org.apache.maven.shared.filtering.MavenFileFilter;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.apache.maven.shared.filtering.MavenResourcesExecution;
+import org.apache.maven.shared.filtering.MavenResourcesFiltering;
+import org.apache.maven.shared.mapping.MappingUtils;
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.UnArchiver;
+import org.codehaus.plexus.archiver.ear.EarArchiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.jar.Manifest;
+import org.codehaus.plexus.archiver.jar.Manifest.Attribute;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.archiver.manager.ArchiverManager;
+import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
+import org.codehaus.plexus.components.io.filemappers.FileMapper;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Builds J2EE Enterprise Archive (EAR) files.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+@Mojo(
+        name = "ear",
+        defaultPhase = LifecyclePhase.PACKAGE,
+        threadSafe = true,
+        requiresDependencyResolution = ResolutionScope.TEST)
+public class EarMojo extends AbstractEarMojo {
+    /**
+     * Default file name mapping used by artifacts located in local repository.
+     */
+    private static final String ARTIFACT_DEFAULT_FILE_NAME_MAPPING =
+            "@{artifactId}@-@{version}@@{dashClassifier?}@.@{extension}@";
+
+    /**
+     * Single directory for extra files to include in the EAR.
+     */
+    @Parameter(defaultValue = "${basedir}/src/main/application", required = true)
+    private File earSourceDirectory;
+
+    /**
+     * The comma separated list of tokens to include in the EAR.
+     */
+    @Parameter(alias = "includes", defaultValue = "**")
+    private String earSourceIncludes;
+
+    /**
+     * The comma separated list of tokens to exclude from the EAR.
+     */
+    @Parameter(alias = "excludes")
+    private String earSourceExcludes;
+
+    /**
+     * Specify that the EAR sources should be filtered.
+     *
+     * @since 2.3.2
+     */
+    @Parameter(defaultValue = "false")
+    private boolean filtering;
+
+    /**
+     * Filters (property files) to include during the interpolation of the pom.xml.
+     *
+     * @since 2.3.2
+     */
+    @Parameter
+    private List<String> filters;
+
+    /**
+     * A list of file extensions that should not be filtered if filtering is enabled.
+     *
+     * @since 2.3.2
+     */
+    @Parameter
+    private List<String> nonFilteredFileExtensions;
+
+    /**
+     * To escape interpolated value with Windows path c:\foo\bar will be replaced with c:\\foo\\bar.
+     *
+     * @since 2.3.2
+     */
+    @Parameter(defaultValue = "false")
+    private boolean escapedBackslashesInFilePath;
+
+    /**
+     * Expression preceded with this String won't be interpolated \${foo} will be replaced with ${foo}.
+     *
+     * @since 2.3.2
+     */
+    @Parameter
+    protected String escapeString;
+
+    /**
+     * In case of using the {@link #skinnyWars} and {@link #defaultLibBundleDir} usually the classpath will be modified.
+     * By settings this option {@code true} you can change this and keep the classpath untouched. This option has been
+     * introduced to keep the backward compatibility with earlier versions of the plugin.
+     *
+     * @since 2.10
+     */
+    @Parameter(defaultValue = "false")
+    private boolean skipClassPathModification;
+
+    /**
+     * The location of a custom application.xml file to be used within the EAR file.
+     */
+    @Parameter
+    private File applicationXml;
+
+    /**
+     * The directory for the generated EAR.
+     */
+    @Parameter(defaultValue = "${project.build.directory}", required = true)
+    private String outputDirectory;
+
+    /**
+     * The name of the EAR file to generate.
+     */
+    @Parameter(defaultValue = "${project.build.finalName}", required = true, readonly = true)
+    private String finalName;
+
+    /**
+     * The comma separated list of artifact's type(s) to unpack by default.
+     */
+    @Parameter
+    private String unpackTypes;
+
+    /**
+     * Classifier to add to the artifact generated. If given, the artifact will be an attachment instead.
+     */
+    @Parameter
+    private String classifier;
+
+    /**
+     * A comma separated list of tokens to exclude when packaging the EAR. By default nothing is excluded. Note that you
+     * can use the Java Regular Expressions engine to include and exclude specific pattern using the expression
+     * %regex[]. Hint: read the about (?!Pattern).
+     *
+     * @since 2.7
+     */
+    @Parameter
+    private String packagingExcludes;
+
+    /**
+     * A comma separated list of tokens to include when packaging the EAR. By default everything is included. Note that
+     * you can use the Java Regular Expressions engine to include and exclude specific pattern using the expression
+     * %regex[].
+     *
+     * @since 2.7
+     */
+    @Parameter
+    private String packagingIncludes;
+
+    /**
+     * Whether to create skinny WARs or not. A skinny WAR is a WAR that does not have all of its dependencies in
+     * WEB-INF/lib. Instead those dependencies are shared between the WARs through the EAR.
+     *
+     * @since 2.7
+     */
+    @Parameter(defaultValue = "false")
+    private boolean skinnyWars;
+
+    /**
+     * Whether to create skinny EAR modules or not. A skinny EAR module is a WAR, SAR, HAR, RAR or WSR module that
+     * does not contain all of its dependencies in it. Instead those dependencies are shared between the WARs, SARs,
+     * HARs, RARs and WSRs through the EAR. This option takes precedence over {@link #skinnyWars} option. That is if
+     * skinnyModules is {@code true} but {@link #skinnyWars} is {@code false} (explicitly or by default) then all
+     * modules including WARs are skinny.
+     *
+     * @since 3.2.0
+     */
+    @Parameter(defaultValue = "false")
+    private boolean skinnyModules;
+
+    /**
+     * The Plexus EAR archiver to create the output archive.
+     */
+    @Component(role = Archiver.class, hint = "ear")
+    private EarArchiver earArchiver;
+
+    /**
+     * The Plexus JAR archiver to create the output archive if not EAR application descriptor is provided (JavaEE 5+).
+     */
+    @Component(role = Archiver.class, hint = "jar")
+    private JarArchiver jarArchiver;
+
+    /**
+     * The archive configuration to use. See <a href="https://maven.apache.org/shared/maven-archiver/">Maven Archiver
+     * Reference</a>.
+     */
+    @Parameter
+    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
+
+    /**
+     * Timestamp for reproducible output archive entries, either formatted as ISO 8601
+     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
+     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
+     *
+     * @since 3.1.0
+     */
+    @Parameter(defaultValue = "${project.build.outputTimestamp}")
+    private String outputTimestamp;
+
+    /**
+     */
+    @Component
+    private MavenProjectHelper projectHelper;
+
+    /**
+     * The archive manager.
+     */
+    @Component
+    private ArchiverManager archiverManager;
+
+    /**
+     */
+    @Component(role = MavenFileFilter.class, hint = "default")
+    private MavenFileFilter mavenFileFilter;
+
+    /**
+     */
+    @Component(role = MavenResourcesFiltering.class, hint = "default")
+    private MavenResourcesFiltering mavenResourcesFiltering;
+
+    /**
+     * @since 2.3.2
+     */
+    @Parameter(defaultValue = "${session}", readonly = true, required = true)
+    private MavenSession session;
+
+    private List<FilterWrapper> filterWrappers;
+
+    /** {@inheritDoc} */
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        // Initializes ear modules
+        super.execute();
+
+        File earFile = getEarFile(outputDirectory, finalName, classifier);
+        MavenArchiver archiver = new EarMavenArchiver(getModules());
+        File ddFile = new File(getWorkDirectory(), APPLICATION_XML_URI);
+
+        JarArchiver theArchiver;
+        if (ddFile.exists()) {
+            earArchiver.setAppxml(ddFile);
+            theArchiver = earArchiver;
+        } else {
+            // current Plexus EarArchiver does not support application.xml-less JavaEE 5+ case
+            // => fallback to Plexus Jar archiver
+            theArchiver = jarArchiver;
+        }
+        getLog().debug("Ear archiver implementation [" + theArchiver.getClass().getName() + "]");
+        archiver.setArchiver(theArchiver);
+        archiver.setOutputFile(earFile);
+        archiver.setCreatedBy("Maven EAR Plugin", "org.apache.maven.plugins", "maven-ear-plugin");
+
+        // configure for Reproducible Builds based on outputTimestamp value
+        archiver.configureReproducibleBuild(outputTimestamp);
+
+        final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion(version);
+
+        final Collection<String> outdatedResources = initOutdatedResources();
+
+        // Initializes unpack types
+        List<String> unpackTypesList = createUnpackList();
+
+        // Copy modules
+        copyModules(javaEEVersion, unpackTypesList, outdatedResources);
+
+        // Copy source files
+        try {
+            File earSourceDir = earSourceDirectory;
+
+            if (earSourceDir.exists()) {
+                getLog().info("Copy ear sources to " + getWorkDirectory().getAbsolutePath());
+                String[] fileNames = getEarFiles(earSourceDir);
+                for (String fileName : fileNames) {
+                    copyFile(new File(earSourceDir, fileName), new File(getWorkDirectory(), fileName));
+                    outdatedResources.remove(Paths.get(fileName).toString());
+                }
+            }
+
+            if (applicationXml != null) {
+                // rename to application.xml
+                getLog().info("Including custom application.xml[" + applicationXml + "]");
+                File metaInfDir = new File(getWorkDirectory(), META_INF);
+                copyFile(applicationXml, new File(metaInfDir, "/application.xml"));
+                outdatedResources.remove(Paths.get("META-INF/application.xml").toString());
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException("Error copying EAR sources", e);
+        } catch (MavenFilteringException e) {
+            throw new MojoExecutionException("Error filtering EAR sources", e);
+        }
+
+        // Check if deployment descriptor is there
+        if (!ddFile.exists() && (javaEEVersion.lt(JavaEEVersion.FIVE))) {
+            throw new MojoExecutionException("Deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist.");
+        }
+        // no need to check timestamp for descriptors: removing if outdated does not really make sense
+        outdatedResources.remove(Paths.get(APPLICATION_XML_URI).toString());
+        if (getJbossConfiguration() != null) {
+            outdatedResources.remove(Paths.get("META-INF/jboss-app.xml").toString());
+        }
+
+        deleteOutdatedResources(outdatedResources);
+
+        try {
+            getLog().debug("Excluding " + Arrays.asList(getPackagingExcludes()) + " from the generated EAR.");
+            getLog().debug("Including " + Arrays.asList(getPackagingIncludes()) + " in the generated EAR.");
+
+            archiver.getArchiver().addDirectory(getWorkDirectory(), getPackagingIncludes(), getPackagingExcludes());
+
+            archiver.createArchive(session, getProject(), archive);
+        } catch (ManifestException | IOException | DependencyResolutionRequiredException e) {
+            throw new MojoExecutionException("Error assembling EAR", e);
+        }
+
+        if (classifier != null) {
+            projectHelper.attachArtifact(getProject(), "ear", classifier, earFile);
+        } else {
+            getProject().getArtifact().setFile(earFile);
+        }
+    }
+
+    private void copyModules(
+            final JavaEEVersion javaEEVersion, List<String> unpackTypesList, Collection<String> outdatedResources)
+            throws MojoExecutionException, MojoFailureException {
+        try {
+            for (EarModule module : getModules()) {
+                final File sourceFile = module.getArtifact().getFile();
+                final File destinationFile = buildDestinationFile(getWorkDirectory(), module.getUri());
+                if (!sourceFile.isFile()) {
+                    throw new MojoExecutionException("Cannot copy a directory: " + sourceFile.getAbsolutePath()
+                            + "; Did you package/install " + module.getArtifact() + "?");
+                }
+
+                if (destinationFile.getCanonicalPath().equals(sourceFile.getCanonicalPath())) {
+                    getLog().info("Skipping artifact [" + module + "], as it already exists at [" + module.getUri()
+                            + "]");
+                    // FIXME: Shouldn't that result in a build failure!?
+                    continue;
+                }
+
+                // If the module is within the unpack list, make sure that no unpack wasn't forced (null or true)
+                // If the module is not in the unpack list, it should be true
+                if ((unpackTypesList.contains(module.getType())
+                                && (module.shouldUnpack() == null || module.shouldUnpack()))
+                        || (module.shouldUnpack() != null && module.shouldUnpack())) {
+                    getLog().info("Copying artifact [" + module + "] to [" + module.getUri() + "] (unpacked)");
+                    // Make sure that the destination is a directory to avoid plexus nasty stuff :)
+                    if (!destinationFile.isDirectory() && !destinationFile.mkdirs()) {
+                        throw new MojoExecutionException("Error creating " + destinationFile);
+                    }
+                    unpack(sourceFile, destinationFile, outdatedResources);
+
+                    if (module.changeManifestClasspath()) {
+                        changeManifestClasspath(module, destinationFile, javaEEVersion, outdatedResources);
+                    }
+                } else {
+                    if (sourceFile.lastModified() > destinationFile.lastModified()) {
+                        getLog().info("Copying artifact [" + module + "] to [" + module.getUri() + "]");
+                        createParentIfNecessary(destinationFile);
+                        Files.copy(
+                                sourceFile.toPath(),
+                                destinationFile.toPath(),
+                                LinkOption.NOFOLLOW_LINKS,
+                                StandardCopyOption.REPLACE_EXISTING);
+                        if (module.changeManifestClasspath()) {
+                            changeManifestClasspath(module, destinationFile, javaEEVersion, outdatedResources);
+                        }
+                    } else {
+                        getLog().debug("Skipping artifact [" + module + "], as it is already up to date at ["
+                                + module.getUri() + "]");
+                    }
+                    removeFromOutdatedResources(destinationFile.toPath(), outdatedResources);
+                }
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException("Error copying EAR modules", e);
+        } catch (ArchiverException e) {
+            throw new MojoExecutionException("Error unpacking EAR modules", e);
+        } catch (NoSuchArchiverException e) {
+            throw new MojoExecutionException("No Archiver found for EAR modules", e);
+        }
+    }
+
+    private List<String> createUnpackList() throws MojoExecutionException {
+        List<String> unpackTypesList = new ArrayList<>();
+        if (unpackTypes != null) {
+            unpackTypesList = Arrays.asList(unpackTypes.split(","));
+            for (String type : unpackTypesList) {
+                if (!EarModuleFactory.isStandardArtifactType(type)) {
+                    throw new MojoExecutionException("Invalid type [" + type + "] supported types are "
+                            + EarModuleFactory.getStandardArtifactTypes());
+                }
+            }
+            getLog().debug("Initialized unpack types " + unpackTypesList);
+        }
+        return unpackTypesList;
+    }
+
+    /**
+     * @return {@link #applicationXml}
+     */
+    public File getApplicationXml() {
+        return applicationXml;
+    }
+
+    /**
+     * @param applicationXml {@link #applicationXml}
+     */
+    public void setApplicationXml(File applicationXml) {
+        this.applicationXml = applicationXml;
+    }
+
+    /**
+     * Returns a string array of the excludes to be used when assembling/copying the ear.
+     *
+     * @return an array of tokens to exclude
+     */
+    protected String[] getExcludes() {
+        List<String> excludeList = new ArrayList<>(FileUtils.getDefaultExcludesAsList());
+        if (earSourceExcludes != null && !"".equals(earSourceExcludes)) {
+            excludeList.addAll(Arrays.asList(StringUtils.split(earSourceExcludes, ",")));
+        }
+
+        // if applicationXml is specified, omit the one in the source directory
+        if (getApplicationXml() != null && !"".equals(getApplicationXml())) {
+            excludeList.add("**/" + META_INF + "/application.xml");
+        }
+
+        return excludeList.toArray(new String[excludeList.size()]);
+    }
+
+    /**
+     * Returns a string array of the includes to be used when assembling/copying the ear.
+     *
+     * @return an array of tokens to include
+     */
+    protected String[] getIncludes() {
+        return StringUtils.split(Objects.toString(earSourceIncludes, ""), ",");
+    }
+
+    /**
+     * @return The array with the packaging excludes.
+     */
+    public String[] getPackagingExcludes() {
+        if (packagingExcludes == null || packagingExcludes.isEmpty()) {
+            return new String[0];
+        } else {
+            return StringUtils.split(packagingExcludes, ",");
+        }
+    }
+
+    /**
+     * @param packagingExcludes {@link #packagingExcludes}
+     */
+    public void setPackagingExcludes(String packagingExcludes) {
+        this.packagingExcludes = packagingExcludes;
+    }
+
+    /**
+     * @return the arrays with the includes
+     */
+    public String[] getPackagingIncludes() {
+        if (packagingIncludes == null || packagingIncludes.isEmpty()) {
+            return new String[] {"**"};
+        } else {
+            return StringUtils.split(packagingIncludes, ",");
+        }
+    }
+
+    /**
+     * @param packagingIncludes {@link #packagingIncludes}
+     */
+    public void setPackagingIncludes(String packagingIncludes) {
+        this.packagingIncludes = packagingIncludes;
+    }
+
+    private static File buildDestinationFile(File buildDir, String uri) {
+        return new File(buildDir, uri);
+    }
+
+    /**
+     * Returns the EAR file to generate, based on an optional classifier.
+     *
+     * @param basedir the output directory
+     * @param finalName the name of the ear file
+     * @param classifier an optional classifier
+     * @return the EAR file to generate
+     */
+    private static File getEarFile(String basedir, String finalName, String classifier) {
+        if (classifier == null) {
+            classifier = "";
+        } else if (classifier.trim().length() > 0 && !classifier.startsWith("-")) {
+            classifier = "-" + classifier;
+        }
+
+        return new File(basedir, finalName + classifier + ".ear");
+    }
+
+    /**
+     * Returns a list of filenames that should be copied over to the destination directory.
+     *
+     * @param sourceDir the directory to be scanned
+     * @return the array of filenames, relative to the sourceDir
+     */
+    private String[] getEarFiles(File sourceDir) {
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir(sourceDir);
+        scanner.setExcludes(getExcludes());
+        scanner.addDefaultExcludes();
+
+        scanner.setIncludes(getIncludes());
+
+        scanner.scan();
+
+        return scanner.getIncludedFiles();
+    }
+
+    /**
+     * Unpacks the module into the EAR structure.
+     *
+     * @param source file to be unpacked
+     * @param destDir where to put the unpacked files
+     * @param outdatedResources currently outdated resources
+     * @throws ArchiverException a corrupt archive
+     * @throws NoSuchArchiverException if we don't have an appropriate archiver
+     * @throws IOException in case of a general IOException
+     */
+    public void unpack(File source, final File destDir, final Collection<String> outdatedResources)
+            throws ArchiverException, NoSuchArchiverException, IOException {
+        Path destPath = destDir.toPath();
+
+        UnArchiver unArchiver = archiverManager.getUnArchiver("zip");
+        unArchiver.setSourceFile(source);
+        unArchiver.setDestDirectory(destDir);
+        unArchiver.setFileMappers(new FileMapper[] {
+            pName -> {
+                removeFromOutdatedResources(destPath.resolve(pName), outdatedResources);
+                return pName;
+            }
+        });
+
+        // Extract the module
+        unArchiver.extract();
+    }
+
+    private void copyFile(File source, File target)
+            throws MavenFilteringException, IOException, MojoExecutionException {
+        createParentIfNecessary(target);
+        if (filtering && !isNonFilteredExtension(source.getName())) {
+            mavenFileFilter.copyFile(source, target, true, getFilterWrappers(), encoding);
+        } else {
+            Files.copy(
+                    source.toPath(), target.toPath(), LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
+        }
+    }
+
+    private void createParentIfNecessary(File target) throws IOException {
+        // Silly that we have to do this ourselves
+        File parentDirectory = target.getParentFile();
+        if (parentDirectory != null && !parentDirectory.exists()) {
+            Files.createDirectories(parentDirectory.toPath());
+        }
+    }
+
+    /**
+     * @param fileName the name of the file which should be checked
+     * @return {@code true} if the name is part of the non filtered extensions; {@code false} otherwise
+     */
+    public boolean isNonFilteredExtension(String fileName) {
+        return !mavenResourcesFiltering.filteredFileExtension(fileName, nonFilteredFileExtensions);
+    }
+
+    private List<FilterWrapper> getFilterWrappers() throws MojoExecutionException {
+        if (filterWrappers == null) {
+            try {
+                MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
+                mavenResourcesExecution.setMavenProject(getProject());
+                mavenResourcesExecution.setEscapedBackslashesInFilePath(escapedBackslashesInFilePath);
+                mavenResourcesExecution.setFilters(filters);
+                mavenResourcesExecution.setEscapeString(escapeString);
+
+                filterWrappers = mavenFileFilter.getDefaultFilterWrappers(mavenResourcesExecution);
+            } catch (MavenFilteringException e) {
+                getLog().error("Fail to build filtering wrappers " + e.getMessage());
+                throw new MojoExecutionException(e.getMessage(), e);
+            }
+        }
+        return filterWrappers;
+    }
+
+    private void changeManifestClasspath(
+            EarModule module, File original, JavaEEVersion javaEEVersion, Collection<String> outdatedResources)
+            throws MojoFailureException {
+        final String moduleLibDir = module.getLibDir();
+        if (!((moduleLibDir == null) || skinnyModules || (skinnyWars && module instanceof WebModule))) {
+            return;
+        }
+
+        // for new created items
+        FileTime outputFileTime = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp)
+                .map(FileTime::from)
+                .orElse(null);
+
+        FileSystem fileSystem = null;
+
+        try {
+            Path workDirectory;
+
+            // Handle the case that the destination might be a directory (project-038)
+            // We can get FileSystems only for files
+            if (original.isFile()) {
+                fileSystem = FileSystems.newFileSystem(
+                        original.toPath(), Thread.currentThread().getContextClassLoader());
+                workDirectory = fileSystem.getRootDirectories().iterator().next();
+            } else {
+                workDirectory = original.toPath();
+            }
+
+            // Create a META-INF/MANIFEST.MF file if it doesn't exist (project-038)
+            Path metaInfDirectory = workDirectory.resolve("META-INF");
+            if (!Files.exists(metaInfDirectory)) {
+                Files.createDirectory(metaInfDirectory);
+                if (outputFileTime != null) {
+                    Files.setLastModifiedTime(metaInfDirectory, outputFileTime);
+                }
+                getLog().debug(
+                                "This project did not have a META-INF directory before, so a new directory was created.");
+            }
+            Path manifestFile = metaInfDirectory.resolve("MANIFEST.MF");
+            if (!Files.exists(manifestFile)) {
+                Files.createFile(manifestFile);
+                if (outputFileTime != null) {
+                    Files.setLastModifiedTime(manifestFile, outputFileTime);
+                }
+                getLog().debug(
+                                "This project did not have a META-INF/MANIFEST.MF file before, so a new file was created.");
+            }
+
+            Manifest mf = readManifest(manifestFile);
+            Attribute classPath = mf.getMainSection().getAttribute("Class-Path");
+            List<String> classPathElements = new ArrayList<>();
+
+            boolean classPathExists;
+            if (classPath != null) {
+                classPathExists = true;
+                classPathElements.addAll(Arrays.asList(classPath.getValue().split(" ")));
+            } else {
+                classPathExists = false;
+                classPath = new Attribute("Class-Path", "");
+            }
+
+            if ((moduleLibDir != null) && (skinnyModules || (skinnyWars && module instanceof WebModule))) {
+                // Remove modules
+                for (EarModule otherModule : getAllEarModules()) {
+                    if (module.equals(otherModule)) {
+                        continue;
+                    }
+                    // MEAR-189:
+                    // We use the original name, cause in case of outputFileNameMapping
+                    // we could not not delete it and it will end up in the resulting EAR and the WAR
+                    // will not be cleaned up.
+                    final Path workLibDir = workDirectory.resolve(moduleLibDir);
+                    Path artifact =
+                            workLibDir.resolve(module.getArtifact().getFile().getName());
+
+                    // MEAR-217
+                    // If WAR contains files with timestamps, but EAR strips them away (useBaseVersion=true)
+                    // the artifact is not found. Therefore, respect the current fileNameMapping additionally.
+
+                    if (!Files.exists(artifact)) {
+                        getLog().debug("module does not exist with original file name.");
+                        artifact = workLibDir.resolve(otherModule.getBundleFileName());
+                        getLog().debug("Artifact with mapping: " + artifact.toAbsolutePath());
+                    }
+
+                    if (!Files.exists(artifact)) {
+                        getLog().debug("Artifact with mapping does not exist.");
+                        artifact = workLibDir.resolve(
+                                otherModule.getArtifact().getFile().getName());
+                        getLog().debug("Artifact with original file name: " + artifact.toAbsolutePath());
+                    }
+
+                    if (!Files.exists(artifact)) {
+                        getLog().debug("Artifact with original file name does not exist.");
+                        final Artifact otherModuleArtifact = otherModule.getArtifact();
+                        if (otherModuleArtifact.isSnapshot()) {
+                            try {
+                                artifact = workLibDir.resolve(MappingUtils.evaluateFileNameMapping(
+                                        ARTIFACT_DEFAULT_FILE_NAME_MAPPING, otherModuleArtifact));
+                                getLog().debug("Artifact with default mapping file name: " + artifact.toAbsolutePath());
+                            } catch (InterpolationException e) {
+                                getLog().warn("Failed to evaluate file name for [" + otherModule
+                                        + "] module using mapping: " + ARTIFACT_DEFAULT_FILE_NAME_MAPPING);
+                            }
+                        }
+                    }
+
+                    if (Files.exists(artifact)) {
+                        getLog().debug(" -> Artifact to delete: " + artifact);
+                        Files.delete(artifact);
+                    }
+                }
+            }
+
+            // Modify the classpath entries in the manifest
+            final boolean forceClassPathModification =
+                    javaEEVersion.lt(JavaEEVersion.FIVE) || defaultLibBundleDir == null;
+            final boolean classPathExtension = !skipClassPathModification || forceClassPathModification;
+            for (EarModule otherModule : getModules()) {
+                if (module.equals(otherModule)) {
+                    continue;
+                }
+                final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule);
+                if (moduleClassPathIndex != -1) {
+                    if (otherModule.isClassPathItem()) {
+                        classPathElements.set(moduleClassPathIndex, otherModule.getUri());
+                    } else {
+                        classPathElements.remove(moduleClassPathIndex);
+                    }
+                } else if (otherModule.isClassPathItem() && classPathExtension) {
+                    classPathElements.add(otherModule.getUri());
+                }
+            }
+
+            // Remove provided modules from classpath
+            for (EarModule otherModule : getProvidedEarModules()) {
+                final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule);
+                if (moduleClassPathIndex != -1) {
+                    classPathElements.remove(moduleClassPathIndex);
+                }
+            }
+
+            if (!skipClassPathModification || !classPathElements.isEmpty() || classPathExists) {
+                classPath.setValue(StringUtils.join(classPathElements.iterator(), " "));
+                mf.getMainSection().addConfiguredAttribute(classPath);
+
+                // Write the manifest to disk, preserve timestamp
+                FileTime lastModifiedTime = Files.getLastModifiedTime(manifestFile);
+                try (BufferedWriter writer = Files.newBufferedWriter(
+                        manifestFile,
+                        StandardCharsets.UTF_8,
+                        StandardOpenOption.WRITE,
+                        StandardOpenOption.CREATE,
+                        StandardOpenOption.TRUNCATE_EXISTING)) {
+                    mf.write(writer);
+                }
+                Files.setLastModifiedTime(manifestFile, lastModifiedTime);
+                removeFromOutdatedResources(manifestFile, outdatedResources);
+            }
+
+            if (fileSystem != null) {
+                fileSystem.close();
+                fileSystem = null;
+            }
+        } catch (ManifestException | IOException | ArchiverException e) {
+            throw new MojoFailureException(e.getMessage(), e);
+        } finally {
+            if (fileSystem != null) {
+                try {
+                    fileSystem.close();
+                } catch (IOException e) {
+                    // ignore here
+                }
+            }
+        }
+    }
+
+    private static Manifest readManifest(Path manifestFile) throws IOException {
+        // Read the manifest from disk
+        try (InputStream in = Files.newInputStream(manifestFile)) {
+            return new Manifest(in);
+        }
+    }
+
+    private Collection<String> initOutdatedResources() {
+        final Collection<String> outdatedResources = new ArrayList<>();
+
+        if (getWorkDirectory().exists()) {
+            try {
+                Files.walkFileTree(getWorkDirectory().toPath(), new SimpleFileVisitor<Path>() {
+                    @Override
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                        outdatedResources.add(
+                                getWorkDirectory().toPath().relativize(file).toString());
+                        return super.visitFile(file, attrs);
+                    }
+                });
+            } catch (IOException e) {
+                getLog().warn("Can't detect outdated resources", e);
+            }
+        }
+
+        getLog().debug("initOutdatedResources: " + outdatedResources);
+        return outdatedResources;
+    }
+
+    private void deleteOutdatedResources(final Collection<String> outdatedResources) {
+        getLog().debug("deleteOutdatedResources: " + outdatedResources);
+        final long startTime = session.getStartTime().getTime();
+
+        getLog().debug("deleteOutdatedResources session startTime: " + startTime);
+
+        for (String outdatedResource : outdatedResources) {
+            File resourceFile = new File(getWorkDirectory(), outdatedResource);
+            if (resourceFile.lastModified() < startTime) {
+                getLog().info("deleting outdated resource " + outdatedResource);
+                getLog().debug(outdatedResource + " last modified: " + resourceFile.lastModified());
+                resourceFile.delete();
+            }
+        }
+    }
+
+    private void removeFromOutdatedResources(Path destination, Collection<String> outdatedResources) {
+        Path relativeDestFile;
+        try {
+            relativeDestFile = getWorkDirectory().toPath().relativize(destination.normalize());
+        } catch (ProviderMismatchException e) {
+            relativeDestFile = destination.normalize();
+        }
+
+        if (outdatedResources.remove(relativeDestFile.toString())) {
+            getLog().debug("Remove from outdatedResources: " + relativeDestFile);
+        }
+    }
+
+    /**
+     * Searches for the given JAR module in the list of classpath elements. If JAR module is found among specified
+     * classpath elements then returns index of first matching element. Returns -1 otherwise.
+     *
+     * @param classPathElements classpath elements to search among
+     * @param module module to find among classpath elements defined by {@code classPathElements}
+     * @return -1 if {@code module} was not found in {@code classPathElements} or index of item of
+     * {@code classPathElements} which matches {@code module}
+     */
+    private int findModuleInClassPathElements(final List<String> classPathElements, final EarModule module) {
+        if (classPathElements.isEmpty()) {
+            return -1;
+        }
+        int moduleClassPathIndex = classPathElements.indexOf(module.getBundleFileName());
+        if (moduleClassPathIndex != -1) {
+            return moduleClassPathIndex;
+        }
+        final Artifact artifact = module.getArtifact();
+        moduleClassPathIndex = classPathElements.indexOf(artifact.getFile().getName());
+        if (moduleClassPathIndex != -1) {
+            return moduleClassPathIndex;
+        }
+        if (artifact.isSnapshot()) {
+            try {
+                moduleClassPathIndex = classPathElements.indexOf(
+                        MappingUtils.evaluateFileNameMapping(ARTIFACT_DEFAULT_FILE_NAME_MAPPING, artifact));
+                if (moduleClassPathIndex != -1) {
+                    return moduleClassPathIndex;
+                }
+            } catch (InterpolationException e) {
+                getLog().warn("Failed to evaluate file name for [" + module + "] module using mapping: "
+                        + ARTIFACT_DEFAULT_FILE_NAME_MAPPING);
+            }
+        }
+        return classPathElements.indexOf(module.getUri());
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarPluginException.java b/src/main/java/org/apache/maven/plugins/ear/EarPluginException.java
index 9243b9b..0741f95 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarPluginException.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarPluginException.java
@@ -1,67 +1,78 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-/**

- * The base exception of the EAR plugin.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarPluginException

-    extends Exception

-{

-

-    /**

-     * 

-     */

-    private static final long serialVersionUID = -5540929953103327928L;

-

-    /**

-     * Create an instance.

-     */

-    public EarPluginException()

-    {

-    }

-

-    /**

-     * @param message The message for the exception.

-     */

-    public EarPluginException( String message )

-    {

-        super( message );

-    }

-

-    /**

-     * @param cause {@link Throwable}

-     */

-    public EarPluginException( Throwable cause )

-    {

-        super( cause );

-    }

-

-    /**

-     * @param message The message to emit.

-     * @param cause {@link Throwable}

-     */

-    public EarPluginException( String message, Throwable cause )

-    {

-        super( message, cause );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+/**
+ * The base exception of the EAR plugin.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarPluginException extends Exception {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -5540929953103327928L;
+
+    /**
+     * Create an instance.
+     */
+    public EarPluginException() {}
+
+    /**
+     * @param message The message for the exception.
+     */
+    public EarPluginException(String message) {
+        super(message);
+    }
+
+    /**
+     * @param cause {@link Throwable}
+     */
+    public EarPluginException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * @param message The message to emit.
+     * @param cause {@link Throwable}
+     */
+    public EarPluginException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EjbClientModule.java b/src/main/java/org/apache/maven/plugins/ear/EjbClientModule.java
index bd16ebc..73256eb 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EjbClientModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EjbClientModule.java
@@ -1,53 +1,67 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-

-/**

- * The {@link EarModule} implementation for an ejb client module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EjbClientModule

-    extends JarModule

-{

-    /**

-     * Default type of the artifact of an ejb client module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "ejb-client";

-

-    /**

-     * Create an instance.

-     */

-    public EjbClientModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     * @param defaultLibBundleDir The default lib bundle directory.

-     */

-    public EjbClientModule( Artifact a, String defaultLibBundleDir )

-    {

-        super( a, defaultLibBundleDir, Boolean.FALSE );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * The {@link EarModule} implementation for an ejb client module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EjbClientModule extends JarModule {
+    /**
+     * Default type of the artifact of an ejb client module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "ejb-client";
+
+    /**
+     * Create an instance.
+     */
+    public EjbClientModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     * @param defaultLibBundleDir The default lib bundle directory.
+     */
+    public EjbClientModule(Artifact a, String defaultLibBundleDir) {
+        super(a, defaultLibBundleDir, Boolean.FALSE);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EjbModule.java b/src/main/java/org/apache/maven/plugins/ear/EjbModule.java
index f9adb3c..cd94997 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EjbModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EjbModule.java
@@ -1,70 +1,83 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The {@link EarModule} implementation for an EJB module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EjbModule

-    extends AbstractEarModule

-{

-    /**

-     * Default type of the artifact of an EJB module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "ejb";

-

-    private static final String EJB_MODULE = "ejb";

-

-    /**

-     * Create an instance.

-     */

-    public EjbModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public EjbModule( Artifact a )

-    {

-        super( a );

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        startModuleElement( writer, generateId );

-        writer.startElement( EJB_MODULE );

-        writer.writeText( getUri() );

-        writer.endElement();

-

-        writeAltDeploymentDescriptor( writer, version );

-

-        writer.endElement();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for an EJB module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EjbModule extends AbstractEarModule {
+    /**
+     * Default type of the artifact of an EJB module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "ejb";
+
+    private static final String EJB_MODULE = "ejb";
+
+    /**
+     * Create an instance.
+     */
+    public EjbModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public EjbModule(Artifact a) {
+        super(a);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        startModuleElement(writer, generateId);
+        writer.startElement(EJB_MODULE);
+        writer.writeText(getUri());
+        writer.endElement();
+
+        writeAltDeploymentDescriptor(writer, version);
+
+        writer.endElement();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EjbRef.java b/src/main/java/org/apache/maven/plugins/ear/EjbRef.java
index e57b6c1..80675c4 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EjbRef.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EjbRef.java
@@ -1,3 +1,21 @@
+/*
+ * 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.maven.plugins.ear;
 
 /*
@@ -23,12 +41,11 @@
 
 /**
  * Representation of {@code ejb-ref} element in {@code application.xml} file.
- * 
+ *
  * @author Karl Heinz Marbaise
  * @since 2.10
  */
-public class EjbRef
-{
+public class EjbRef {
     static final String DESCRIPTION = "description";
 
     static final String EJB_REF = "ejb-ref";
@@ -53,120 +70,102 @@
      * @param type The ejb-ref-type
      * @param lookupName The lookupname.
      */
-    public EjbRef( String description, String name, String type, String lookupName )
-    {
-        if ( name == null || name.isEmpty() )
-        {
-            throw new IllegalArgumentException( EJB_NAME + " in " + EJB_REF + " element cannot be null." );
-        }
-        else if ( ( type == null || type.isEmpty() ) && ( lookupName == null || lookupName.isEmpty() ) )
-        {
-            throw new IllegalArgumentException( EJB_TYPE + " in " + EJB_REF + " element cannot be null if no "
-                + EJB_LOOKUP_NAME + " was specified." );
-
+    public EjbRef(String description, String name, String type, String lookupName) {
+        if (name == null || name.isEmpty()) {
+            throw new IllegalArgumentException(EJB_NAME + " in " + EJB_REF + " element cannot be null.");
+        } else if ((type == null || type.isEmpty()) && (lookupName == null || lookupName.isEmpty())) {
+            throw new IllegalArgumentException(EJB_TYPE + " in " + EJB_REF + " element cannot be null if no "
+                    + EJB_LOOKUP_NAME + " was specified.");
         }
 
         this.description = description;
         this.name = name;
         this.type = type;
         this.lookupName = lookupName;
-
     }
 
     /**
      * Appends the {@code XML} representation of this env-entry.
-     * 
+     *
      * @param writer the writer to use
      */
-    public void appendEjbRefEntry( XMLWriter writer )
-    {
-        writer.startElement( EJB_REF );
+    public void appendEjbRefEntry(XMLWriter writer) {
+        writer.startElement(EJB_REF);
 
         // description
-        if ( getDescription() != null )
-        {
-            doWriteElement( writer, DESCRIPTION, getDescription() );
+        if (getDescription() != null) {
+            doWriteElement(writer, DESCRIPTION, getDescription());
         }
 
         // ejb name
-        doWriteElement( writer, EJB_NAME, getName() );
+        doWriteElement(writer, EJB_NAME, getName());
 
         // ejb-type
-        if ( getType() != null )
-        {
-            doWriteElement( writer, EJB_TYPE, getType() );
+        if (getType() != null) {
+            doWriteElement(writer, EJB_TYPE, getType());
         }
 
         // lookup-name
-        if ( getLookupName() != null )
-        {
-            doWriteElement( writer, EJB_LOOKUP_NAME, getLookupName() );
+        if (getLookupName() != null) {
+            doWriteElement(writer, EJB_LOOKUP_NAME, getLookupName());
         }
 
         // end of ejb-ref
         writer.endElement();
     }
 
-    private void doWriteElement( XMLWriter writer, String element, String text )
-    {
-        writer.startElement( element );
-        writer.writeText( text );
+    private void doWriteElement(XMLWriter writer, String element, String text) {
+        writer.startElement(element);
+        writer.writeText(text);
         writer.endElement();
     }
 
     /**
      * @return {@link #name}
      */
-    public String getName()
-    {
+    public String getName() {
         return name;
     }
 
     /**
      * @param name {@link #name}
      */
-    public void setName( String name )
-    {
+    public void setName(String name) {
         this.name = name;
     }
 
     /**
      * @return {@link #type}
      */
-    public String getType()
-    {
+    public String getType() {
         return type;
     }
 
     /**
      * @param type {@link #type}
      */
-    public void setType( String type )
-    {
+    public void setType(String type) {
         this.type = type;
     }
 
     /**
      * @return {@link #lookupName}
      */
-    public String getLookupName()
-    {
+    public String getLookupName() {
         return lookupName;
     }
 
     /**
      * @param lookupName {@link #lookupName}
      */
-    public void setLookupName( String lookupName )
-    {
+    public void setLookupName(String lookupName) {
         this.lookupName = lookupName;
     }
 
     /**
      * @return {@link #description}
      */
-    public String getDescription()
-    {
+    public String getDescription() {
         return description;
     }
 }
diff --git a/src/main/java/org/apache/maven/plugins/ear/EnvEntry.java b/src/main/java/org/apache/maven/plugins/ear/EnvEntry.java
index e3fb775..9a4a95a 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EnvEntry.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EnvEntry.java
@@ -1,154 +1,153 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The representation of a env-entry entry within an application.xml file.

- * 

- * @author Jim Brownfield based on code by <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-class EnvEntry

-{

-

-    static final String ENV_ENTRY = "env-entry";

-

-    static final String DESCRIPTION = "description";

-

-    static final String ENV_ENTRY_NAME = "env-entry-name";

-

-    static final String ENV_ENTRY_TYPE = "env-entry-type";

-

-    static final String ENV_ENTRY_VALUE = "env-entry-value";

-

-    static final String ENV_LOOKUP_NAME = "lookup-name";

-

-    private final String description;

-

-    private final String name;

-

-    private final String type;

-

-    private final String value;

-

-    private final String lookupName;

-

-    EnvEntry( String description, String name, String type, String value, String lookupName )

-    {

-        if ( name == null || name.isEmpty() )

-        {

-            throw new IllegalArgumentException( ENV_ENTRY_NAME + " in " + ENV_ENTRY + " element cannot be null." );

-        }

-        else if ( ( type == null || type.isEmpty() ) && ( value == null || value.isEmpty() ) )

-

-        {

-            throw new IllegalArgumentException( ENV_ENTRY_TYPE + " in " + ENV_ENTRY + " element cannot be null if no "

-                + ENV_ENTRY_VALUE + " was specified." );

-

-        }

-

-        this.description = description;

-        this.name = name;

-        this.type = type;

-        this.value = value;

-        this.lookupName = lookupName;

-    }

-

-    public String getDescription()

-    {

-        return description;

-    }

-

-    public String getName()

-    {

-        return name;

-    }

-

-    public String getType()

-    {

-        return type;

-    }

-

-    public String getValue()

-    {

-        return value;

-    }

-

-    public String getLookupName()

-    {

-        return lookupName;

-    }

-

-    /**

-     * Appends the {@code XML} representation of this env-entry.

-     * 

-     * @param writer the writer to use

-     */

-    public void appendEnvEntry( XMLWriter writer )

-    {

-        System.out.println( "appendEnvEntry()" );

-        writer.startElement( ENV_ENTRY );

-

-        // description

-        if ( getDescription() != null )

-        {

-            doWriteElement( writer, DESCRIPTION, getDescription() );

-        }

-

-        // env entry name

-        doWriteElement( writer, ENV_ENTRY_NAME, getName() );

-

-        // env entry type

-        if ( getType() != null )

-        {

-            doWriteElement( writer, ENV_ENTRY_TYPE, getType() );

-        }

-

-        // env entry value

-        if ( getValue() != null )

-        {

-            doWriteElement( writer, ENV_ENTRY_VALUE, getValue() );

-        }

-

-        // lookup-name

-        if ( getLookupName() != null )

-        {

-            doWriteElement( writer, ENV_LOOKUP_NAME, getLookupName() );

-        }

-

-        // end of env-entry

-        writer.endElement();

-    }

-

-    private void doWriteElement( XMLWriter writer, String element, String text )

-    {

-        writer.startElement( element );

-        writer.writeText( text );

-        writer.endElement();

-    }

-

-    public String toString()

-    {

-        return "env-entry [name=" + getName() + ", type=" + getType() + ", value=" + getValue() + ", lookup-name="

-            + getLookupName() + "]";

-    }

-

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The representation of a env-entry entry within an application.xml file.
+ *
+ * @author Jim Brownfield based on code by <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+class EnvEntry {
+
+    static final String ENV_ENTRY = "env-entry";
+
+    static final String DESCRIPTION = "description";
+
+    static final String ENV_ENTRY_NAME = "env-entry-name";
+
+    static final String ENV_ENTRY_TYPE = "env-entry-type";
+
+    static final String ENV_ENTRY_VALUE = "env-entry-value";
+
+    static final String ENV_LOOKUP_NAME = "lookup-name";
+
+    private final String description;
+
+    private final String name;
+
+    private final String type;
+
+    private final String value;
+
+    private final String lookupName;
+
+    EnvEntry(String description, String name, String type, String value, String lookupName) {
+        if (name == null || name.isEmpty()) {
+            throw new IllegalArgumentException(ENV_ENTRY_NAME + " in " + ENV_ENTRY + " element cannot be null.");
+        } else if ((type == null || type.isEmpty()) && (value == null || value.isEmpty())) {
+
+            throw new IllegalArgumentException(ENV_ENTRY_TYPE + " in " + ENV_ENTRY + " element cannot be null if no "
+                    + ENV_ENTRY_VALUE + " was specified.");
+        }
+
+        this.description = description;
+        this.name = name;
+        this.type = type;
+        this.value = value;
+        this.lookupName = lookupName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getLookupName() {
+        return lookupName;
+    }
+
+    /**
+     * Appends the {@code XML} representation of this env-entry.
+     *
+     * @param writer the writer to use
+     */
+    public void appendEnvEntry(XMLWriter writer) {
+        System.out.println("appendEnvEntry()");
+        writer.startElement(ENV_ENTRY);
+
+        // description
+        if (getDescription() != null) {
+            doWriteElement(writer, DESCRIPTION, getDescription());
+        }
+
+        // env entry name
+        doWriteElement(writer, ENV_ENTRY_NAME, getName());
+
+        // env entry type
+        if (getType() != null) {
+            doWriteElement(writer, ENV_ENTRY_TYPE, getType());
+        }
+
+        // env entry value
+        if (getValue() != null) {
+            doWriteElement(writer, ENV_ENTRY_VALUE, getValue());
+        }
+
+        // lookup-name
+        if (getLookupName() != null) {
+            doWriteElement(writer, ENV_LOOKUP_NAME, getLookupName());
+        }
+
+        // end of env-entry
+        writer.endElement();
+    }
+
+    private void doWriteElement(XMLWriter writer, String element, String text) {
+        writer.startElement(element);
+        writer.writeText(text);
+        writer.endElement();
+    }
+
+    public String toString() {
+        return "env-entry [name=" + getName() + ", type=" + getType() + ", value=" + getValue() + ", lookup-name="
+                + getLookupName() + "]";
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/GenerateApplicationXmlMojo.java b/src/main/java/org/apache/maven/plugins/ear/GenerateApplicationXmlMojo.java
index d792f61..1e8a207 100644
--- a/src/main/java/org/apache/maven/plugins/ear/GenerateApplicationXmlMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/GenerateApplicationXmlMojo.java
@@ -1,531 +1,482 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.io.IOException;

-import java.util.ArrayList;

-import java.util.Arrays;

-import java.util.List;

-

-import org.apache.maven.plugin.MojoExecutionException;

-import org.apache.maven.plugin.MojoFailureException;

-import org.apache.maven.plugins.annotations.LifecyclePhase;

-import org.apache.maven.plugins.annotations.Mojo;

-import org.apache.maven.plugins.annotations.Parameter;

-import org.apache.maven.plugins.annotations.ResolutionScope;

-import org.apache.maven.plugins.ear.util.JavaEEVersion;

-import org.codehaus.plexus.configuration.PlexusConfiguration;

-import org.codehaus.plexus.interpolation.InterpolationException;

-import org.codehaus.plexus.interpolation.Interpolator;

-import org.codehaus.plexus.interpolation.MapBasedValueSource;

-import org.codehaus.plexus.interpolation.StringSearchInterpolator;

-import org.codehaus.plexus.interpolation.ValueSource;

-import org.codehaus.plexus.util.FileUtils;

-

-/**

- * Generates the EAR deployment descriptor file(s).

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-@Mojo( name = "generate-application-xml",

-       defaultPhase = LifecyclePhase.GENERATE_RESOURCES,

-       threadSafe = true,

-       requiresDependencyResolution = ResolutionScope.TEST )

-public class GenerateApplicationXmlMojo

-    extends AbstractEarMojo

-{

-

-    /**

-     * The DEFAULT library folder.

-     */

-    public static final String DEFAULT = "DEFAULT";

-

-    /**

-     * The empty folder.

-     */

-    public static final String EMPTY = "EMPTY";

-

-    /**

-     * The NONE not existent folder.

-     */

-    public static final String NONE = "NONE";

-

-    /**

-     * Whether the application.xml should be generated or not.

-     */

-    @Parameter( defaultValue = "true" )

-    private Boolean generateApplicationXml = Boolean.TRUE;

-

-    /**

-     * Whether a module ID should be generated if none is specified.

-     */

-    @Parameter( defaultValue = "false" )

-    private Boolean generateModuleId = Boolean.FALSE;

-

-    /**

-     * Application name of the application to be used when the application.xml file is auto-generated. Since JavaEE6.

-     */

-    @Parameter

-    private String applicationName;

-

-    /**

-     * Display name of the application to be used when the application.xml file is auto-generated.

-     */

-    @Parameter( defaultValue = "${project.artifactId}" )

-    private String displayName;

-

-    /**

-     * Description of the application to be used when the application.xml file is auto-generated.

-     */

-    @Parameter( defaultValue = "${project.description}" )

-    private String description;

-

-    /**

-     * Defines how the {@code library-directory} element should be written in the application.xml file.

-     * <p/>

-     * Three special values can be set:

-     * <ul>

-     * <li><code>DEFAULT</code> (default) generates a {@code library-directory} element with the value of the

-     * {@code defaultLibBundleDir} parameter</li>

-     * <li><code>EMPTY</code> generates an empty {@code library-directory} element. Per spec, this disables the

-     * scanning of jar files in the {@code lib} directory of the ear file</li>

-     * <li><code>NONE</code> does not write the library-directory element at all. A corner case that can be used in

-     * Oracle Weblogic to delegate the classloading to the container</li>

-     * </ul>

-     * <p/>

-     * Since JavaEE5.

-     */

-    @Parameter( defaultValue = DEFAULT )

-    private String libraryDirectoryMode;

-

-    /**

-     * Defines the value of the initialize in order element to be used when the application.xml file is auto-generated.

-     * When set to true, modules must be initialized in the order they're listed in this deployment descriptor, with the

-     * exception of application client modules, which can be initialized in any order. If initialize-in-order is not set

-     * or set to false, the order of initialization is unspecified and may be product-dependent. Since JavaEE6.

-     */

-    @Parameter

-    private Boolean initializeInOrder;

-

-    /**

-     * Defines the application id used when generating the deployment descriptor.

-     * 

-     * @since 2.9

-     */

-    @Parameter

-    private String applicationId;

-

-    /**

-     * The security-roles to be added to the auto-generated application.xml file.

-     */

-    @Parameter

-    private PlexusConfiguration security;

-

-    /**

-     * The env-entries to be added to the auto-generated application.xml file. Since JavaEE6.

-     */

-    @Parameter( alias = "env-entries" )

-    private PlexusConfiguration envEntries;

-

-    /**

-     * The {@code ejb-ref} entries.

-     */

-    @Parameter( alias = "ejb-refs" )

-    private PlexusConfiguration ejbRefs;

-

-    /**

-     * The {@code resource-ref} entries.

-     */

-    @Parameter

-    private PlexusConfiguration resourceRefs;

-

-    /**

-     * {@inheritDoc}

-     */

-    public void execute()

-        throws MojoExecutionException, MojoFailureException

-    {

-        // Initializes ear modules

-        super.execute();

-

-        // Handle application.xml

-        if ( !generateApplicationXml )

-        {

-            getLog().debug( "Generation of application.xml is disabled" );

-        }

-        else

-        {

-            final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );

-

-            // Generate deployment descriptor and copy it to the build directory

-            getLog().info( "Generating application.xml" );

-            try

-            {

-                generateStandardDeploymentDescriptor( javaEEVersion );

-            }

-            catch ( EarPluginException e )

-            {

-                throw new MojoExecutionException( "Failed to generate application.xml", e );

-            }

-

-            try

-            {

-                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "application.xml" ),

-                                               new File( getWorkDirectory(), "META-INF" ) );

-            }

-            catch ( IOException e )

-            {

-                throw new MojoExecutionException( "Unable to copy application.xml to final destination", e );

-            }

-        }

-

-        // Handle jboss-app.xml

-        if ( getJbossConfiguration() == null )

-        {

-            getLog().debug( "Generation of jboss-app.xml is disabled" );

-        }

-        else

-        {

-            // Generate deployment descriptor and copy it to the build directory

-            getLog().info( "Generating jboss-app.xml" );

-            try

-            {

-                generateJbossDeploymentDescriptor();

-            }

-            catch ( EarPluginException e )

-            {

-                throw new MojoExecutionException( "Failed to generate jboss-app.xml", e );

-            }

-

-            try

-            {

-                FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "jboss-app.xml" ),

-                                               new File( getWorkDirectory(), "META-INF" ) );

-            }

-            catch ( IOException e )

-            {

-                throw new MojoExecutionException( "Unable to copy jboss-app.xml to final destination", e );

-            }

-        }

-    }

-

-    /**

-     * Generates the deployment descriptor.

-     * 

-     * @param javaEEVersion {@link JavaEEVersion}

-     * @throws EarPluginException if the configuration is invalid

-     */

-    protected void generateStandardDeploymentDescriptor( JavaEEVersion javaEEVersion )

-        throws EarPluginException

-    {

-        File outputDir = new File( generatedDescriptorLocation );

-        if ( !outputDir.exists() )

-        {

-            if ( !outputDir.mkdirs() )

-            {

-                throw new EarPluginException( "Error creating " + outputDir );

-            }

-        }

-

-        File descriptor = new File( outputDir, "application.xml" );

-

-        final ApplicationXmlWriter writer = new ApplicationXmlWriter( javaEEVersion, encoding, generateModuleId );

-        final ApplicationXmlWriterContext context =

-            new ApplicationXmlWriterContext( descriptor, getModules(), buildSecurityRoles(), buildEnvEntries(),

-                                             buildEjbEntries(), buildResourceRefs(), displayName, description,

-                                             getActualLibraryDirectory(), applicationName,

-                                             initializeInOrder ).setApplicationId( applicationId );

-        writer.write( context );

-    }

-

-    /**

-     * Generates the JBoss deployment descriptor.

-     * 

-     * @throws EarPluginException if the configuration is invalid

-     */

-    protected void generateJbossDeploymentDescriptor()

-        throws EarPluginException

-    {

-        File outputDir = new File( generatedDescriptorLocation );

-        if ( !outputDir.exists() )

-        {

-            if ( !outputDir.mkdirs() )

-            {

-                throw new EarPluginException( "Error creating " + outputDir );

-            }

-        }

-

-        File descriptor = new File( outputDir, "jboss-app.xml" );

-

-        JbossAppXmlWriter writer = new JbossAppXmlWriter( encoding );

-        writer.write( descriptor, getJbossConfiguration(), getModules() );

-    }

-

-    /**

-     * Builds the security roles based on the configuration.

-     * 

-     * @return a list of SecurityRole object(s)

-     * @throws EarPluginException if the configuration is invalid

-     */

-    private List<SecurityRole> buildSecurityRoles()

-        throws EarPluginException

-    {

-        final List<SecurityRole> result = new ArrayList<>();

-        if ( security == null )

-        {

-            return result;

-        }

-        final PlexusConfiguration[] securityRoles = security.getChildren( SecurityRole.SECURITY_ROLE );

-

-        for ( PlexusConfiguration securityRole : securityRoles )

-        {

-            final String id = securityRole.getAttribute( SecurityRole.ID_ATTRIBUTE );

-            final String childRoleName = securityRole.getChild( SecurityRole.ROLE_NAME ).getValue();

-            final String childRoleNameId =

-                securityRole.getChild( SecurityRole.ROLE_NAME ).getAttribute( SecurityRole.ID_ATTRIBUTE );

-            final String childDescription = securityRole.getChild( SecurityRole.DESCRIPTION ).getValue();

-            final String childDescriptionId =

-                securityRole.getChild( SecurityRole.DESCRIPTION ).getAttribute( SecurityRole.ID_ATTRIBUTE );

-

-            if ( childRoleName == null )

-            {

-                throw new EarPluginException( "Invalid security-role configuration, role-name could not be null." );

-            }

-            else

-            {

-                result.add( new SecurityRole( childRoleName, childRoleNameId, id, childDescription,

-                                              childDescriptionId ) );

-            }

-        }

-        return result;

-    }

-

-    /**

-     * This help method was needed otherwise the interpolate method of interpolator will make an empty string of a

-     * {@code null} element which results in supplemental elements for env-entry.

-     * 

-     * @param interpolator The interpolator

-     * @param element The element

-     * @return The interpolated elements.

-     * @throws InterpolationException in case of an error.

-     */

-    private String interpolate( Interpolator interpolator, String element )

-        throws InterpolationException

-    {

-        if ( element == null )

-        {

-            return element;

-        }

-        else

-        {

-            return interpolator.interpolate( element );

-        }

-    }

-

-    /**

-     * Builds the env-entries based on the configuration.

-     * 

-     * @return a list of EnvEntry object(s)

-     * @throws EarPluginException if the configuration is invalid

-     */

-    private List<EnvEntry> buildEnvEntries()

-        throws EarPluginException

-    {

-        final List<EnvEntry> result = new ArrayList<>();

-        if ( envEntries == null )

-        {

-            return result;

-        }

-        try

-        {

-            StringSearchInterpolator ssi = new StringSearchInterpolator();

-            ValueSource vs = new MapBasedValueSource( project.getProperties() );

-            ssi.addValueSource( vs );

-

-            final PlexusConfiguration[] allEnvEntries = envEntries.getChildren( EnvEntry.ENV_ENTRY );

-

-            getLog().debug( "buildEnvEntries: allEnvEntries size:" + allEnvEntries.length );

-            for ( PlexusConfiguration envEntry : allEnvEntries )

-            {

-                final String childDescription =

-                    interpolate( ssi, envEntry.getChild( EnvEntry.DESCRIPTION ).getValue() );

-                final String childEnvEntryName =

-                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_NAME ).getValue() );

-                final String childEnvEntryType =

-                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_TYPE ).getValue() );

-                final String childEnvEntryValue =

-                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_ENTRY_VALUE ).getValue() );

-                final String childEnvLookupNameValue =

-                    interpolate( ssi, envEntry.getChild( EnvEntry.ENV_LOOKUP_NAME ).getValue() );

-

-                try

-                {

-                    result.add( new EnvEntry( childDescription, childEnvEntryName, childEnvEntryType,

-                                              childEnvEntryValue, childEnvLookupNameValue ) );

-                }

-                catch ( IllegalArgumentException e )

-                {

-                    throw new EarPluginException( "Invalid env-entry [" + envEntry + "]", e );

-                }

-            }

-            return result;

-        }

-        catch ( InterpolationException e )

-        {

-            throw new EarPluginException( "Interpolation exception:", e );

-        }

-

-    }

-

-    /**

-     * Builds the ejb-ref based on the configuration.

-     * 

-     * @return a list of EjbRef object(s)

-     * @throws EarPluginException if the configuration is invalid

-     */

-    private List<EjbRef> buildEjbEntries()

-        throws EarPluginException

-    {

-        final List<EjbRef> result = new ArrayList<>();

-        if ( ejbRefs == null )

-        {

-            return result;

-        }

-        try

-        {

-            StringSearchInterpolator ssi = new StringSearchInterpolator();

-            ValueSource vs = new MapBasedValueSource( project.getProperties() );

-            ssi.addValueSource( vs );

-

-            final PlexusConfiguration[] allEjbEntries = ejbRefs.getChildren( EjbRef.EJB_REF );

-

-            for ( PlexusConfiguration ejbEntry : allEjbEntries )

-            {

-                final String childDescription =

-                    interpolate( ssi, ejbEntry.getChild( EnvEntry.DESCRIPTION ).getValue() );

-                final String childEjbEntryName = interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_NAME ).getValue() );

-                final String childEjbEntryType = interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_TYPE ).getValue() );

-                final String childEjbLookupNameValue =

-                    interpolate( ssi, ejbEntry.getChild( EjbRef.EJB_LOOKUP_NAME ).getValue() );

-

-                try

-                {

-                    result.add( new EjbRef( childDescription, childEjbEntryName, childEjbEntryType,

-                                            childEjbLookupNameValue ) );

-                }

-                catch ( IllegalArgumentException e )

-                {

-                    throw new EarPluginException( "Invalid ejb-ref [" + ejbEntry + "]", e );

-                }

-            }

-            return result;

-        }

-        catch ( InterpolationException e )

-        {

-            throw new EarPluginException( "Interpolation exception:", e );

-        }

-

-    }

-

-    /**

-     * Builds the <code>resource-ref</code> based on the configuration.

-     * 

-     * @return a list of ResourceRef object(s)

-     * @throws EarPluginException if the configuration is invalid

-     */

-    private List<ResourceRef> buildResourceRefs()

-        throws EarPluginException

-    {

-        final List<ResourceRef> result = new ArrayList<>();

-        if ( resourceRefs == null )

-        {

-            return result;

-        }

-        try

-        {

-            getLog().debug( "Resources found" );

-            StringSearchInterpolator ssi = new StringSearchInterpolator();

-            ValueSource vs = new MapBasedValueSource( project.getProperties() );

-            ssi.addValueSource( vs );

-

-            // TODO: Check if this is a good idea hard code that here? Better idea?

-            final PlexusConfiguration[] allResourceRefEntries = resourceRefs.getChildren( "resourceRef" );

-

-            getLog().debug( "allResourceRefEntries length: " + allResourceRefEntries.length );

-            for ( PlexusConfiguration resEntry : allResourceRefEntries )

-            {

-                getLog().debug( "Resources resEntry:" + resEntry.getName() );

-

-                final String childResRefName =

-                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_REF_NAME ).getValue() );

-                final String childResType =

-                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_TYPE ).getValue() );

-                final String childResRefAuth =

-                    interpolate( ssi, resEntry.getChild( ResourceRef.RESOURCE_AUTH ).getValue() );

-                final String childResRefLookupName =

-                    interpolate( ssi, resEntry.getChild( ResourceRef.LOOKUP_NAME ).getValue() );

-

-                try

-                {

-                    result.add(

-                            new ResourceRef( childResRefName, childResType, childResRefAuth, childResRefLookupName ) );

-                }

-                catch ( IllegalArgumentException e )

-                {

-                    throw new EarPluginException( "Invalid resource-ref [" + resEntry + "]", e );

-                }

-            }

-            return result;

-        }

-        catch ( InterpolationException e )

-        {

-            throw new EarPluginException( "Interpolation exception:", e );

-        }

-

-    }

-

-    /**

-     * Returns the value to use for the {@code library-directory} element, based on the library directory mode.

-     */

-    private String getActualLibraryDirectory()

-        throws EarPluginException

-    {

-        final String mode = libraryDirectoryMode == null ? DEFAULT : libraryDirectoryMode.toUpperCase();

-

-        if ( DEFAULT.equals( mode ) )

-        {

-            return defaultLibBundleDir;

-        }

-        else if ( EMPTY.equals( mode ) )

-        {

-            return "";

-        }

-        else if ( NONE.equals( mode ) )

-        {

-            return null;

-        }

-        else

-        {

-            throw new EarPluginException( "Unsupported library directory mode [" + libraryDirectoryMode

-                + "] Supported modes " + ( Arrays.asList( DEFAULT, EMPTY, NONE ) ) );

-        }

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.plugins.ear.util.JavaEEVersion;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.MapBasedValueSource;
+import org.codehaus.plexus.interpolation.StringSearchInterpolator;
+import org.codehaus.plexus.interpolation.ValueSource;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Generates the EAR deployment descriptor file(s).
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+@Mojo(
+        name = "generate-application-xml",
+        defaultPhase = LifecyclePhase.GENERATE_RESOURCES,
+        threadSafe = true,
+        requiresDependencyResolution = ResolutionScope.TEST)
+public class GenerateApplicationXmlMojo extends AbstractEarMojo {
+
+    /**
+     * The DEFAULT library folder.
+     */
+    public static final String DEFAULT = "DEFAULT";
+
+    /**
+     * The empty folder.
+     */
+    public static final String EMPTY = "EMPTY";
+
+    /**
+     * The NONE not existent folder.
+     */
+    public static final String NONE = "NONE";
+
+    /**
+     * Whether the application.xml should be generated or not.
+     */
+    @Parameter(defaultValue = "true")
+    private Boolean generateApplicationXml = Boolean.TRUE;
+
+    /**
+     * Whether a module ID should be generated if none is specified.
+     */
+    @Parameter(defaultValue = "false")
+    private Boolean generateModuleId = Boolean.FALSE;
+
+    /**
+     * Application name of the application to be used when the application.xml file is auto-generated. Since JavaEE6.
+     */
+    @Parameter
+    private String applicationName;
+
+    /**
+     * Display name of the application to be used when the application.xml file is auto-generated.
+     */
+    @Parameter(defaultValue = "${project.artifactId}")
+    private String displayName;
+
+    /**
+     * Description of the application to be used when the application.xml file is auto-generated.
+     */
+    @Parameter(defaultValue = "${project.description}")
+    private String description;
+
+    /**
+     * Defines how the {@code library-directory} element should be written in the application.xml file.
+     * <p/>
+     * Three special values can be set:
+     * <ul>
+     * <li><code>DEFAULT</code> (default) generates a {@code library-directory} element with the value of the
+     * {@code defaultLibBundleDir} parameter</li>
+     * <li><code>EMPTY</code> generates an empty {@code library-directory} element. Per spec, this disables the
+     * scanning of jar files in the {@code lib} directory of the ear file</li>
+     * <li><code>NONE</code> does not write the library-directory element at all. A corner case that can be used in
+     * Oracle Weblogic to delegate the classloading to the container</li>
+     * </ul>
+     * <p/>
+     * Since JavaEE5.
+     */
+    @Parameter(defaultValue = DEFAULT)
+    private String libraryDirectoryMode;
+
+    /**
+     * Defines the value of the initialize in order element to be used when the application.xml file is auto-generated.
+     * When set to true, modules must be initialized in the order they're listed in this deployment descriptor, with the
+     * exception of application client modules, which can be initialized in any order. If initialize-in-order is not set
+     * or set to false, the order of initialization is unspecified and may be product-dependent. Since JavaEE6.
+     */
+    @Parameter
+    private Boolean initializeInOrder;
+
+    /**
+     * Defines the application id used when generating the deployment descriptor.
+     *
+     * @since 2.9
+     */
+    @Parameter
+    private String applicationId;
+
+    /**
+     * The security-roles to be added to the auto-generated application.xml file.
+     */
+    @Parameter
+    private PlexusConfiguration security;
+
+    /**
+     * The env-entries to be added to the auto-generated application.xml file. Since JavaEE6.
+     */
+    @Parameter(alias = "env-entries")
+    private PlexusConfiguration envEntries;
+
+    /**
+     * The {@code ejb-ref} entries.
+     */
+    @Parameter(alias = "ejb-refs")
+    private PlexusConfiguration ejbRefs;
+
+    /**
+     * The {@code resource-ref} entries.
+     */
+    @Parameter
+    private PlexusConfiguration resourceRefs;
+
+    /**
+     * {@inheritDoc}
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        // Initializes ear modules
+        super.execute();
+
+        // Handle application.xml
+        if (!generateApplicationXml) {
+            getLog().debug("Generation of application.xml is disabled");
+        } else {
+            final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion(version);
+
+            // Generate deployment descriptor and copy it to the build directory
+            getLog().info("Generating application.xml");
+            try {
+                generateStandardDeploymentDescriptor(javaEEVersion);
+            } catch (EarPluginException e) {
+                throw new MojoExecutionException("Failed to generate application.xml", e);
+            }
+
+            try {
+                FileUtils.copyFileToDirectory(
+                        new File(generatedDescriptorLocation, "application.xml"),
+                        new File(getWorkDirectory(), "META-INF"));
+            } catch (IOException e) {
+                throw new MojoExecutionException("Unable to copy application.xml to final destination", e);
+            }
+        }
+
+        // Handle jboss-app.xml
+        if (getJbossConfiguration() == null) {
+            getLog().debug("Generation of jboss-app.xml is disabled");
+        } else {
+            // Generate deployment descriptor and copy it to the build directory
+            getLog().info("Generating jboss-app.xml");
+            try {
+                generateJbossDeploymentDescriptor();
+            } catch (EarPluginException e) {
+                throw new MojoExecutionException("Failed to generate jboss-app.xml", e);
+            }
+
+            try {
+                FileUtils.copyFileToDirectory(
+                        new File(generatedDescriptorLocation, "jboss-app.xml"),
+                        new File(getWorkDirectory(), "META-INF"));
+            } catch (IOException e) {
+                throw new MojoExecutionException("Unable to copy jboss-app.xml to final destination", e);
+            }
+        }
+    }
+
+    /**
+     * Generates the deployment descriptor.
+     *
+     * @param javaEEVersion {@link JavaEEVersion}
+     * @throws EarPluginException if the configuration is invalid
+     */
+    protected void generateStandardDeploymentDescriptor(JavaEEVersion javaEEVersion) throws EarPluginException {
+        File outputDir = new File(generatedDescriptorLocation);
+        if (!outputDir.exists()) {
+            if (!outputDir.mkdirs()) {
+                throw new EarPluginException("Error creating " + outputDir);
+            }
+        }
+
+        File descriptor = new File(outputDir, "application.xml");
+
+        final ApplicationXmlWriter writer = new ApplicationXmlWriter(javaEEVersion, encoding, generateModuleId);
+        final ApplicationXmlWriterContext context = new ApplicationXmlWriterContext(
+                        descriptor,
+                        getModules(),
+                        buildSecurityRoles(),
+                        buildEnvEntries(),
+                        buildEjbEntries(),
+                        buildResourceRefs(),
+                        displayName,
+                        description,
+                        getActualLibraryDirectory(),
+                        applicationName,
+                        initializeInOrder)
+                .setApplicationId(applicationId);
+        writer.write(context);
+    }
+
+    /**
+     * Generates the JBoss deployment descriptor.
+     *
+     * @throws EarPluginException if the configuration is invalid
+     */
+    protected void generateJbossDeploymentDescriptor() throws EarPluginException {
+        File outputDir = new File(generatedDescriptorLocation);
+        if (!outputDir.exists()) {
+            if (!outputDir.mkdirs()) {
+                throw new EarPluginException("Error creating " + outputDir);
+            }
+        }
+
+        File descriptor = new File(outputDir, "jboss-app.xml");
+
+        JbossAppXmlWriter writer = new JbossAppXmlWriter(encoding);
+        writer.write(descriptor, getJbossConfiguration(), getModules());
+    }
+
+    /**
+     * Builds the security roles based on the configuration.
+     *
+     * @return a list of SecurityRole object(s)
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private List<SecurityRole> buildSecurityRoles() throws EarPluginException {
+        final List<SecurityRole> result = new ArrayList<>();
+        if (security == null) {
+            return result;
+        }
+        final PlexusConfiguration[] securityRoles = security.getChildren(SecurityRole.SECURITY_ROLE);
+
+        for (PlexusConfiguration securityRole : securityRoles) {
+            final String id = securityRole.getAttribute(SecurityRole.ID_ATTRIBUTE);
+            final String childRoleName =
+                    securityRole.getChild(SecurityRole.ROLE_NAME).getValue();
+            final String childRoleNameId =
+                    securityRole.getChild(SecurityRole.ROLE_NAME).getAttribute(SecurityRole.ID_ATTRIBUTE);
+            final String childDescription =
+                    securityRole.getChild(SecurityRole.DESCRIPTION).getValue();
+            final String childDescriptionId =
+                    securityRole.getChild(SecurityRole.DESCRIPTION).getAttribute(SecurityRole.ID_ATTRIBUTE);
+
+            if (childRoleName == null) {
+                throw new EarPluginException("Invalid security-role configuration, role-name could not be null.");
+            } else {
+                result.add(new SecurityRole(childRoleName, childRoleNameId, id, childDescription, childDescriptionId));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * This help method was needed otherwise the interpolate method of interpolator will make an empty string of a
+     * {@code null} element which results in supplemental elements for env-entry.
+     *
+     * @param interpolator The interpolator
+     * @param element The element
+     * @return The interpolated elements.
+     * @throws InterpolationException in case of an error.
+     */
+    private String interpolate(Interpolator interpolator, String element) throws InterpolationException {
+        if (element == null) {
+            return element;
+        } else {
+            return interpolator.interpolate(element);
+        }
+    }
+
+    /**
+     * Builds the env-entries based on the configuration.
+     *
+     * @return a list of EnvEntry object(s)
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private List<EnvEntry> buildEnvEntries() throws EarPluginException {
+        final List<EnvEntry> result = new ArrayList<>();
+        if (envEntries == null) {
+            return result;
+        }
+        try {
+            StringSearchInterpolator ssi = new StringSearchInterpolator();
+            ValueSource vs = new MapBasedValueSource(project.getProperties());
+            ssi.addValueSource(vs);
+
+            final PlexusConfiguration[] allEnvEntries = envEntries.getChildren(EnvEntry.ENV_ENTRY);
+
+            getLog().debug("buildEnvEntries: allEnvEntries size:" + allEnvEntries.length);
+            for (PlexusConfiguration envEntry : allEnvEntries) {
+                final String childDescription =
+                        interpolate(ssi, envEntry.getChild(EnvEntry.DESCRIPTION).getValue());
+                final String childEnvEntryName = interpolate(
+                        ssi, envEntry.getChild(EnvEntry.ENV_ENTRY_NAME).getValue());
+                final String childEnvEntryType = interpolate(
+                        ssi, envEntry.getChild(EnvEntry.ENV_ENTRY_TYPE).getValue());
+                final String childEnvEntryValue = interpolate(
+                        ssi, envEntry.getChild(EnvEntry.ENV_ENTRY_VALUE).getValue());
+                final String childEnvLookupNameValue = interpolate(
+                        ssi, envEntry.getChild(EnvEntry.ENV_LOOKUP_NAME).getValue());
+
+                try {
+                    result.add(new EnvEntry(
+                            childDescription,
+                            childEnvEntryName,
+                            childEnvEntryType,
+                            childEnvEntryValue,
+                            childEnvLookupNameValue));
+                } catch (IllegalArgumentException e) {
+                    throw new EarPluginException("Invalid env-entry [" + envEntry + "]", e);
+                }
+            }
+            return result;
+        } catch (InterpolationException e) {
+            throw new EarPluginException("Interpolation exception:", e);
+        }
+    }
+
+    /**
+     * Builds the ejb-ref based on the configuration.
+     *
+     * @return a list of EjbRef object(s)
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private List<EjbRef> buildEjbEntries() throws EarPluginException {
+        final List<EjbRef> result = new ArrayList<>();
+        if (ejbRefs == null) {
+            return result;
+        }
+        try {
+            StringSearchInterpolator ssi = new StringSearchInterpolator();
+            ValueSource vs = new MapBasedValueSource(project.getProperties());
+            ssi.addValueSource(vs);
+
+            final PlexusConfiguration[] allEjbEntries = ejbRefs.getChildren(EjbRef.EJB_REF);
+
+            for (PlexusConfiguration ejbEntry : allEjbEntries) {
+                final String childDescription =
+                        interpolate(ssi, ejbEntry.getChild(EnvEntry.DESCRIPTION).getValue());
+                final String childEjbEntryName =
+                        interpolate(ssi, ejbEntry.getChild(EjbRef.EJB_NAME).getValue());
+                final String childEjbEntryType =
+                        interpolate(ssi, ejbEntry.getChild(EjbRef.EJB_TYPE).getValue());
+                final String childEjbLookupNameValue = interpolate(
+                        ssi, ejbEntry.getChild(EjbRef.EJB_LOOKUP_NAME).getValue());
+
+                try {
+                    result.add(new EjbRef(
+                            childDescription, childEjbEntryName, childEjbEntryType, childEjbLookupNameValue));
+                } catch (IllegalArgumentException e) {
+                    throw new EarPluginException("Invalid ejb-ref [" + ejbEntry + "]", e);
+                }
+            }
+            return result;
+        } catch (InterpolationException e) {
+            throw new EarPluginException("Interpolation exception:", e);
+        }
+    }
+
+    /**
+     * Builds the <code>resource-ref</code> based on the configuration.
+     *
+     * @return a list of ResourceRef object(s)
+     * @throws EarPluginException if the configuration is invalid
+     */
+    private List<ResourceRef> buildResourceRefs() throws EarPluginException {
+        final List<ResourceRef> result = new ArrayList<>();
+        if (resourceRefs == null) {
+            return result;
+        }
+        try {
+            getLog().debug("Resources found");
+            StringSearchInterpolator ssi = new StringSearchInterpolator();
+            ValueSource vs = new MapBasedValueSource(project.getProperties());
+            ssi.addValueSource(vs);
+
+            // TODO: Check if this is a good idea hard code that here? Better idea?
+            final PlexusConfiguration[] allResourceRefEntries = resourceRefs.getChildren("resourceRef");
+
+            getLog().debug("allResourceRefEntries length: " + allResourceRefEntries.length);
+            for (PlexusConfiguration resEntry : allResourceRefEntries) {
+                getLog().debug("Resources resEntry:" + resEntry.getName());
+
+                final String childResRefName = interpolate(
+                        ssi, resEntry.getChild(ResourceRef.RESOURCE_REF_NAME).getValue());
+                final String childResType = interpolate(
+                        ssi, resEntry.getChild(ResourceRef.RESOURCE_TYPE).getValue());
+                final String childResRefAuth = interpolate(
+                        ssi, resEntry.getChild(ResourceRef.RESOURCE_AUTH).getValue());
+                final String childResRefLookupName = interpolate(
+                        ssi, resEntry.getChild(ResourceRef.LOOKUP_NAME).getValue());
+
+                try {
+                    result.add(new ResourceRef(childResRefName, childResType, childResRefAuth, childResRefLookupName));
+                } catch (IllegalArgumentException e) {
+                    throw new EarPluginException("Invalid resource-ref [" + resEntry + "]", e);
+                }
+            }
+            return result;
+        } catch (InterpolationException e) {
+            throw new EarPluginException("Interpolation exception:", e);
+        }
+    }
+
+    /**
+     * Returns the value to use for the {@code library-directory} element, based on the library directory mode.
+     */
+    private String getActualLibraryDirectory() throws EarPluginException {
+        final String mode = libraryDirectoryMode == null ? DEFAULT : libraryDirectoryMode.toUpperCase();
+
+        if (DEFAULT.equals(mode)) {
+            return defaultLibBundleDir;
+        } else if (EMPTY.equals(mode)) {
+            return "";
+        } else if (NONE.equals(mode)) {
+            return null;
+        } else {
+            throw new EarPluginException("Unsupported library directory mode [" + libraryDirectoryMode
+                    + "] Supported modes " + (Arrays.asList(DEFAULT, EMPTY, NONE)));
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/HarModule.java b/src/main/java/org/apache/maven/plugins/ear/HarModule.java
index 1d2198d..c5438bc 100644
--- a/src/main/java/org/apache/maven/plugins/ear/HarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/HarModule.java
@@ -1,80 +1,91 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The {@link EarModule} implementation for a JBoss Hibernate archive.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class HarModule

-    extends AbstractEarModule

-    implements JbossEarModule

-{

-    /**

-     * Default type of the artifact of a JBoss Hibernate archive.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "har";

-

-    private static final String DEFAULT_LIB_DIRECTORY = "lib";

-

-    /**

-     * Create an instance.

-     */

-    public HarModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public HarModule( Artifact a )

-    {

-        super( a );

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        // No entry is generated by this artifact ; it should be

-        // defined in the jboss-app.xml.

-        // See http://docs.jboss.org/jbossas/getting_started/v4/html/hibernate.html

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendJbossModule( XMLWriter writer, String version )

-    {

-        writer.startElement( MODULE_ELEMENT );

-        writer.startElement( "har" );

-        writer.writeText( getUri() );

-        writer.endElement();

-        writer.endElement();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for a JBoss Hibernate archive.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class HarModule extends AbstractEarModule implements JbossEarModule {
+    /**
+     * Default type of the artifact of a JBoss Hibernate archive.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "har";
+
+    private static final String DEFAULT_LIB_DIRECTORY = "lib";
+
+    /**
+     * Create an instance.
+     */
+    public HarModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public HarModule(Artifact a) {
+        super(a);
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        // No entry is generated by this artifact ; it should be
+        // defined in the jboss-app.xml.
+        // See http://docs.jboss.org/jbossas/getting_started/v4/html/hibernate.html
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendJbossModule(XMLWriter writer, String version) {
+        writer.startElement(MODULE_ELEMENT);
+        writer.startElement("har");
+        writer.writeText(getUri());
+        writer.endElement();
+        writer.endElement();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/JarModule.java b/src/main/java/org/apache/maven/plugins/ear/JarModule.java
index 0a925c8..fc38f7e 100644
--- a/src/main/java/org/apache/maven/plugins/ear/JarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/JarModule.java
@@ -1,119 +1,126 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugin.MojoFailureException;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-import java.util.Set;

-

-/**

- * The {@link EarModule} implementation for a non J2EE module such as third party libraries.

- *

- * <p>Such module is not incorporated in the generated {@code application.xml}

- * but some application servers support it. To include it in the generated

- * deployment descriptor anyway, set the {@code includeInApplicationXml} boolean flag.

- * </p>

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class JarModule

-    extends AbstractEarModule

-{

-    /**

-     * Default type of the artifact of a non Java EE module such as third party library.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "jar";

-

-    private Boolean includeInApplicationXml = Boolean.FALSE;

-

-    /**

-     * Create an instance.

-     */

-    public JarModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-        this.classPathItem = true;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     * @param defaultLibBundleDir The default library bundle directory.

-     * @param includeInApplicationXml Include the application xml or not.

-     */

-    public JarModule( Artifact a, String defaultLibBundleDir, Boolean includeInApplicationXml )

-    {

-        super( a );

-        setLibBundleDir( defaultLibBundleDir );

-        this.includeInApplicationXml = includeInApplicationXml;

-        this.classPathItem = true;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        // Generates an entry in the application.xml only if

-        // includeInApplicationXml is set

-        if ( includeInApplicationXml )

-        {

-            startModuleElement( writer, generateId );

-            writer.startElement( JAVA_MODULE );

-            writer.writeText( getUri() );

-            writer.endElement();

-

-            writeAltDeploymentDescriptor( writer, version );

-

-            writer.endElement();

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void resolveArtifact( Set<Artifact> artifacts )

-        throws EarPluginException, MojoFailureException

-    {

-        // Let's resolve the artifact

-        super.resolveArtifact( artifacts );

-

-        // If the defaultLibBundleDir is set and no bundle dir is

-        // set, set the default as bundle dir

-        setLibBundleDir( earExecutionContext.getDefaultLibBundleDir() );

-    }

-

-    private void setLibBundleDir( String defaultLibBundleDir )

-    {

-        if ( defaultLibBundleDir != null && bundleDir == null )

-        {

-            this.bundleDir = defaultLibBundleDir;

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public boolean changeManifestClasspath()

-    {

-        return false;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for a non J2EE module such as third party libraries.
+ *
+ * <p>Such module is not incorporated in the generated {@code application.xml}
+ * but some application servers support it. To include it in the generated
+ * deployment descriptor anyway, set the {@code includeInApplicationXml} boolean flag.
+ * </p>
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class JarModule extends AbstractEarModule {
+    /**
+     * Default type of the artifact of a non Java EE module such as third party library.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "jar";
+
+    private Boolean includeInApplicationXml = Boolean.FALSE;
+
+    /**
+     * Create an instance.
+     */
+    public JarModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+        this.classPathItem = true;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     * @param defaultLibBundleDir The default library bundle directory.
+     * @param includeInApplicationXml Include the application xml or not.
+     */
+    public JarModule(Artifact a, String defaultLibBundleDir, Boolean includeInApplicationXml) {
+        super(a);
+        setLibBundleDir(defaultLibBundleDir);
+        this.includeInApplicationXml = includeInApplicationXml;
+        this.classPathItem = true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        // Generates an entry in the application.xml only if
+        // includeInApplicationXml is set
+        if (includeInApplicationXml) {
+            startModuleElement(writer, generateId);
+            writer.startElement(JAVA_MODULE);
+            writer.writeText(getUri());
+            writer.endElement();
+
+            writeAltDeploymentDescriptor(writer, version);
+
+            writer.endElement();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void resolveArtifact(Set<Artifact> artifacts) throws EarPluginException, MojoFailureException {
+        // Let's resolve the artifact
+        super.resolveArtifact(artifacts);
+
+        // If the defaultLibBundleDir is set and no bundle dir is
+        // set, set the default as bundle dir
+        setLibBundleDir(earExecutionContext.getDefaultLibBundleDir());
+    }
+
+    private void setLibBundleDir(String defaultLibBundleDir) {
+        if (defaultLibBundleDir != null && bundleDir == null) {
+            this.bundleDir = defaultLibBundleDir;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean changeManifestClasspath() {
+        return false;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/JbossAppXmlWriter.java b/src/main/java/org/apache/maven/plugins/ear/JbossAppXmlWriter.java
index 666acbc..259914b 100644
--- a/src/main/java/org/apache/maven/plugins/ear/JbossAppXmlWriter.java
+++ b/src/main/java/org/apache/maven/plugins/ear/JbossAppXmlWriter.java
@@ -1,198 +1,189 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.io.IOException;

-import java.io.Writer;

-import java.util.List;

-

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * An {@code XmlWriter} based implementation used to generate a {@code jboss-app.xml} file

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-final class JbossAppXmlWriter

-    extends AbstractXmlWriter

-{

-

-    public static final String DOCTYPE_3_2 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.3//EN\"\n"

-        + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_3_2.dtd\"";

-

-    public static final String DOCTYPE_4 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.4//EN\"\n"

-        + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd\"";

-

-    public static final String DOCTYPE_4_2 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 4.2//EN\"\n"

-        + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd\"";

-

-    public static final String DOCTYPE_5 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD Java EE Application 5.0//EN\"\n"

-        + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_5_0.dtd\"";

-

-    private static final String JBOSS_APP_ELEMENT = "jboss-app";

-    

-    private static final String MODULE_ELEMENT = "module";

-

-    private static final String SERVICE_ELEMENT = "service";

-

-    JbossAppXmlWriter( String encoding )

-    {

-        super( encoding );

-    }

-

-    public void write( File destinationFile, JbossConfiguration jbossConfiguration, List<EarModule> earModules )

-        throws EarPluginException

-    {

-        try ( Writer w = initializeWriter( destinationFile ) )

-        {

-            XMLWriter writer;

-            if ( jbossConfiguration.isJbossThreeDotTwo() )

-            {

-                writer = initializeXmlWriter( w, DOCTYPE_3_2 );

-            }

-            else if ( jbossConfiguration.isJbossFour() )

-            {

-                writer = initializeXmlWriter( w, DOCTYPE_4 );

-            }

-            else if ( jbossConfiguration.isJbossFourDotTwo() )

-            {

-                writer = initializeXmlWriter( w, DOCTYPE_4_2 );

-            }

-            else

-            {

-                writer = initializeXmlWriter( w, DOCTYPE_5 );

-            }

-            writer.startElement( JBOSS_APP_ELEMENT );

-    

-            // Make sure to write the things in the right order so that the DTD validates

-    

-            // module-order (only available as from 4.2)

-            if ( jbossConfiguration.isJbossFourDotTwoOrHigher() && jbossConfiguration.getModuleOrder() != null )

-            {

-                writer.startElement( JbossConfiguration.MODULE_ORDER );

-                writer.writeText( jbossConfiguration.getModuleOrder() );

-                writer.endElement();

-            }

-    

-            // If JBoss 4, write the jboss4 specific stuff

-            if ( jbossConfiguration.isJbossFourOrHigher() )

-            {

-                if ( jbossConfiguration.getSecurityDomain() != null )

-                {

-                    writer.startElement( JbossConfiguration.SECURITY_DOMAIN );

-                    writer.writeText( jbossConfiguration.getSecurityDomain() );

-                    writer.endElement();

-                }

-                if ( jbossConfiguration.getUnauthenticatedPrincipal() != null )

-                {

-                    writer.startElement( JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL );

-                    writer.writeText( jbossConfiguration.getUnauthenticatedPrincipal() );

-                    writer.endElement();

-                }

-            }

-    

-            // classloader repository

-            if ( jbossConfiguration.getLoaderRepository() != null

-                || jbossConfiguration.getLoaderRepositoryConfig() != null )

-            {

-                writer.startElement( JbossConfiguration.LOADER_REPOSITORY );

-    

-                // classloader repository class

-                if ( jbossConfiguration.getLoaderRepositoryClass() != null )

-                {

-                    writer.addAttribute( JbossConfiguration.LOADER_REPOSITORY_CLASS_ATTRIBUTE,

-                                         jbossConfiguration.getLoaderRepositoryClass() );

-                }

-    

-                // we don't need to write any text if only the loader repo configuration is changed

-                if ( jbossConfiguration.getLoaderRepository() != null )

-                {

-                    writer.writeText( jbossConfiguration.getLoaderRepository() );

-                }

-    

-                // classloader configuration

-                if ( jbossConfiguration.getLoaderRepositoryConfig() != null )

-                {

-                    writer.startElement( JbossConfiguration.LOADER_REPOSITORY_CONFIG );

-    

-                    // classloader configuration parser

-                    if ( jbossConfiguration.getConfigParserClass() != null )

-                    {

-                        writer.addAttribute( JbossConfiguration.CONFIG_PARSER_CLASS_ATTRIBUTE,

-                                             jbossConfiguration.getConfigParserClass() );

-                    }

-                    writer.writeText( jbossConfiguration.getLoaderRepositoryConfig() );

-                    writer.endElement();

-                }

-    

-                writer.endElement();

-            }

-    

-            // jmx name

-            if ( jbossConfiguration.getJmxName() != null )

-            {

-                writer.startElement( JbossConfiguration.JMX_NAME );

-                writer.writeText( jbossConfiguration.getJmxName() );

-                writer.endElement();

-            }

-    

-            // library-directory (only available as from 4.2)

-            if ( jbossConfiguration.isJbossFourDotTwoOrHigher() && jbossConfiguration.getLibraryDirectory() != null )

-            {

-                writer.startElement( JbossConfiguration.LIBRARY_DIRECTORY );

-                writer.writeText( jbossConfiguration.getLibraryDirectory() );

-                writer.endElement();

-            }

-    

-            // Modules

-    

-            List<String> dataSources = jbossConfiguration.getDataSources();

-            // Write out data source modules first

-            if ( dataSources != null )

-            {

-                for ( String dsPath : dataSources )

-                {

-                    writer.startElement( MODULE_ELEMENT );

-                    writer.startElement( SERVICE_ELEMENT );

-                    writer.writeText( dsPath );

-                    writer.endElement();

-                    writer.endElement();

-                }

-            }

-    

-            // Write the JBoss specific modules

-            for ( EarModule earModule : earModules )

-            {

-                if ( JbossEarModule.class.isInstance( earModule ) )

-                {

-                    JbossEarModule jbossEarModule = (JbossEarModule) earModule;

-                    jbossEarModule.appendJbossModule( writer, jbossConfiguration.getVersion() );

-                }

-            }

-            writer.endElement();

-

-        }

-        catch ( IOException ex )

-        {

-            throw new EarPluginException( ex );

-        }

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * An {@code XmlWriter} based implementation used to generate a {@code jboss-app.xml} file
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+final class JbossAppXmlWriter extends AbstractXmlWriter {
+
+    public static final String DOCTYPE_3_2 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.3//EN\"\n"
+            + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_3_2.dtd\"";
+
+    public static final String DOCTYPE_4 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 1.4//EN\"\n"
+            + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd\"";
+
+    public static final String DOCTYPE_4_2 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD J2EE Application 4.2//EN\"\n"
+            + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd\"";
+
+    public static final String DOCTYPE_5 = "jboss-app PUBLIC\n" + "\t\"-//JBoss//DTD Java EE Application 5.0//EN\"\n"
+            + "\t\"http://www.jboss.org/j2ee/dtd/jboss-app_5_0.dtd\"";
+
+    private static final String JBOSS_APP_ELEMENT = "jboss-app";
+
+    private static final String MODULE_ELEMENT = "module";
+
+    private static final String SERVICE_ELEMENT = "service";
+
+    JbossAppXmlWriter(String encoding) {
+        super(encoding);
+    }
+
+    public void write(File destinationFile, JbossConfiguration jbossConfiguration, List<EarModule> earModules)
+            throws EarPluginException {
+        try (Writer w = initializeWriter(destinationFile)) {
+            XMLWriter writer;
+            if (jbossConfiguration.isJbossThreeDotTwo()) {
+                writer = initializeXmlWriter(w, DOCTYPE_3_2);
+            } else if (jbossConfiguration.isJbossFour()) {
+                writer = initializeXmlWriter(w, DOCTYPE_4);
+            } else if (jbossConfiguration.isJbossFourDotTwo()) {
+                writer = initializeXmlWriter(w, DOCTYPE_4_2);
+            } else {
+                writer = initializeXmlWriter(w, DOCTYPE_5);
+            }
+            writer.startElement(JBOSS_APP_ELEMENT);
+
+            // Make sure to write the things in the right order so that the DTD validates
+
+            // module-order (only available as from 4.2)
+            if (jbossConfiguration.isJbossFourDotTwoOrHigher() && jbossConfiguration.getModuleOrder() != null) {
+                writer.startElement(JbossConfiguration.MODULE_ORDER);
+                writer.writeText(jbossConfiguration.getModuleOrder());
+                writer.endElement();
+            }
+
+            // If JBoss 4, write the jboss4 specific stuff
+            if (jbossConfiguration.isJbossFourOrHigher()) {
+                if (jbossConfiguration.getSecurityDomain() != null) {
+                    writer.startElement(JbossConfiguration.SECURITY_DOMAIN);
+                    writer.writeText(jbossConfiguration.getSecurityDomain());
+                    writer.endElement();
+                }
+                if (jbossConfiguration.getUnauthenticatedPrincipal() != null) {
+                    writer.startElement(JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL);
+                    writer.writeText(jbossConfiguration.getUnauthenticatedPrincipal());
+                    writer.endElement();
+                }
+            }
+
+            // classloader repository
+            if (jbossConfiguration.getLoaderRepository() != null
+                    || jbossConfiguration.getLoaderRepositoryConfig() != null) {
+                writer.startElement(JbossConfiguration.LOADER_REPOSITORY);
+
+                // classloader repository class
+                if (jbossConfiguration.getLoaderRepositoryClass() != null) {
+                    writer.addAttribute(
+                            JbossConfiguration.LOADER_REPOSITORY_CLASS_ATTRIBUTE,
+                            jbossConfiguration.getLoaderRepositoryClass());
+                }
+
+                // we don't need to write any text if only the loader repo configuration is changed
+                if (jbossConfiguration.getLoaderRepository() != null) {
+                    writer.writeText(jbossConfiguration.getLoaderRepository());
+                }
+
+                // classloader configuration
+                if (jbossConfiguration.getLoaderRepositoryConfig() != null) {
+                    writer.startElement(JbossConfiguration.LOADER_REPOSITORY_CONFIG);
+
+                    // classloader configuration parser
+                    if (jbossConfiguration.getConfigParserClass() != null) {
+                        writer.addAttribute(
+                                JbossConfiguration.CONFIG_PARSER_CLASS_ATTRIBUTE,
+                                jbossConfiguration.getConfigParserClass());
+                    }
+                    writer.writeText(jbossConfiguration.getLoaderRepositoryConfig());
+                    writer.endElement();
+                }
+
+                writer.endElement();
+            }
+
+            // jmx name
+            if (jbossConfiguration.getJmxName() != null) {
+                writer.startElement(JbossConfiguration.JMX_NAME);
+                writer.writeText(jbossConfiguration.getJmxName());
+                writer.endElement();
+            }
+
+            // library-directory (only available as from 4.2)
+            if (jbossConfiguration.isJbossFourDotTwoOrHigher() && jbossConfiguration.getLibraryDirectory() != null) {
+                writer.startElement(JbossConfiguration.LIBRARY_DIRECTORY);
+                writer.writeText(jbossConfiguration.getLibraryDirectory());
+                writer.endElement();
+            }
+
+            // Modules
+
+            List<String> dataSources = jbossConfiguration.getDataSources();
+            // Write out data source modules first
+            if (dataSources != null) {
+                for (String dsPath : dataSources) {
+                    writer.startElement(MODULE_ELEMENT);
+                    writer.startElement(SERVICE_ELEMENT);
+                    writer.writeText(dsPath);
+                    writer.endElement();
+                    writer.endElement();
+                }
+            }
+
+            // Write the JBoss specific modules
+            for (EarModule earModule : earModules) {
+                if (JbossEarModule.class.isInstance(earModule)) {
+                    JbossEarModule jbossEarModule = (JbossEarModule) earModule;
+                    jbossEarModule.appendJbossModule(writer, jbossConfiguration.getVersion());
+                }
+            }
+            writer.endElement();
+
+        } catch (IOException ex) {
+            throw new EarPluginException(ex);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/JbossConfiguration.java b/src/main/java/org/apache/maven/plugins/ear/JbossConfiguration.java
index 3f712f5..5cec988 100644
--- a/src/main/java/org/apache/maven/plugins/ear/JbossConfiguration.java
+++ b/src/main/java/org/apache/maven/plugins/ear/JbossConfiguration.java
@@ -1,358 +1,352 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import java.util.List;

-

-/**

- * The JBoss specific configuration, used to generate the jboss-app.xml deployment descriptor file

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-class JbossConfiguration

-{

-    static final String VERSION_3_2 = "3.2";

-

-    static final String VERSION_4 = "4";

-

-    static final String VERSION_4_2 = "4.2";

-

-    static final String VERSION_5 = "5";

-

-    static final String VERSION = "version";

-

-    static final String SECURITY_DOMAIN = "security-domain";

-

-    static final String UNAUHTHENTICTED_PRINCIPAL = "unauthenticated-principal";

-

-    static final String JMX_NAME = "jmx-name";

-

-    static final String LOADER_REPOSITORY = "loader-repository";

-

-    static final String LOADER_REPOSITORY_CLASS_ATTRIBUTE = "loaderRepositoryClass";

-

-    static final String LOADER_REPOSITORY_CONFIG = "loader-repository-config";

-

-    static final String CONFIG_PARSER_CLASS_ATTRIBUTE = "configParserClass";

-

-    static final String MODULE_ORDER = "module-order";

-

-    static final String DATASOURCES = "data-sources";

-

-    static final String DATASOURCE = "data-source";

-

-    static final String LIBRARY_DIRECTORY = "library-directory";

-

-    private final String version;

-

-    private boolean jbossThreeDotTwo;

-

-    private boolean jbossFour;

-

-    private boolean jbossFourDotTwo;

-

-    private boolean jbossFive;

-

-    private final String securityDomain;

-

-    private final String unauthenticatedPrincipal;

-

-    private final String jmxName;

-

-    private final String loaderRepository;

-

-    private final String loaderRepositoryConfig;

-

-    private final String loaderRepositoryClass;

-

-    private final String configParserClass;

-

-    private final String moduleOrder;

-

-    private final List<String> dataSources;

-

-    private final String libraryDirectory;

-

-    JbossConfiguration( String version, String securityDomain, String unauthenticatedPrincipal, String jmxName,

-                               String loaderRepository, String moduleOrder, List<String> dataSources,

-                               String libraryDirectory, String loaderRepositoryConfig, String loaderRepositoryClass,

-                               String configParserClass )

-        throws EarPluginException

-    {

-        if ( version == null )

-        {

-            throw new EarPluginException( "jboss version could not be null." );

-        }

-        else

-        {

-            this.version = version;

-            if ( version.equals( JbossConfiguration.VERSION_3_2 ) )

-            {

-                this.jbossThreeDotTwo = true;

-            }

-            else if ( version.equals( JbossConfiguration.VERSION_4 ) )

-            {

-                this.jbossFour = true;

-            }

-            else if ( version.equals( JbossConfiguration.VERSION_4_2 ) )

-            {

-                this.jbossFourDotTwo = true;

-            }

-            else if ( version.equals( JbossConfiguration.VERSION_5 ) )

-            {

-                this.jbossFive = true;

-            }

-            else

-            {

-                throw new EarPluginException(

-                        "Invalid JBoss configuration, version[" + version + "] is not supported." );

-            }

-            this.securityDomain = securityDomain;

-            this.unauthenticatedPrincipal = unauthenticatedPrincipal;

-            this.jmxName = jmxName;

-            this.loaderRepository = loaderRepository;

-            this.moduleOrder = moduleOrder;

-            this.dataSources = dataSources;

-            this.libraryDirectory = libraryDirectory;

-            this.loaderRepositoryConfig = loaderRepositoryConfig;

-            this.loaderRepositoryClass = loaderRepositoryClass;

-            this.configParserClass = configParserClass;

-        }

-    }

-

-    /**

-     * Returns the targeted version of JBoss.

-     * 

-     * @return the jboss version

-     */

-    public String getVersion()

-    {

-        return version;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version is 3.2.

-     * 

-     * @return if the targeted version is 3.2

-     */

-    public boolean isJbossThreeDotTwo()

-    {

-        return jbossThreeDotTwo;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version is 4.

-     * 

-     * @return if the targeted version is 4

-     */

-    public boolean isJbossFour()

-    {

-        return jbossFour;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version if 4 or higher (that is 4, 4.2 or 5).

-     * 

-     * @return true if the targeted version is 4+

-     */

-    public boolean isJbossFourOrHigher()

-    {

-        return jbossFour || jbossFourDotTwo || jbossFive;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version is 4.2.

-     * 

-     * @return if the targeted version is 4.2

-     */

-    public boolean isJbossFourDotTwo()

-    {

-        return jbossFourDotTwo;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version if 4.2 or higher (that is 4.2 or 5).

-     * 

-     * @return true if the targeted version is 4.2+

-     */

-    public boolean isJbossFourDotTwoOrHigher()

-    {

-        return jbossFourDotTwo || jbossFive;

-    }

-

-    /**

-     * Returns true if the targeted JBoss version is 5.

-     * 

-     * @return if the targeted version is 5

-     */

-    public boolean isJbossFive()

-    {

-        return jbossFive;

-    }

-

-    /**

-     * The security-domain element specifies the JNDI name of the security manager that implements the

-     * EJBSecurityManager and RealmMapping for the domain. When specified at the jboss level it specifies the security

-     * domain for all j2ee components in the deployment unit.

-     * <p/>

-     * One can override the global security-domain at the container level using the security-domain element at the

-     * container-configuration level.

-     * <p/>

-     * Only available as from JBoss 4.

-     * 

-     * @return the JNDI name of the security manager

-     */

-    public String getSecurityDomain()

-    {

-        return securityDomain;

-    }

-

-    /**

-     * The unauthenticated-principal element specifies the name of the principal that will be returned by the

-     * EJBContext.getCallerPrincipal() method if there is no authenticated user. This Principal has no roles or

-     * privileges to call any other beans.

-     * <p/>

-     * Only available as from JBoss 4.

-     * 

-     * @return the unauthenticated principal

-     */

-    public String getUnauthenticatedPrincipal()

-    {

-        return unauthenticatedPrincipal;

-    }

-

-    /**

-     * The jmx-name element allows one to specify the JMX ObjectName to use for the MBean associated with the ear

-     * module. This must be a unique name and valid JMX ObjectName string.

-     * 

-     * @return the object name of the ear mbean

-     */

-    public String getJmxName()

-    {

-        return jmxName;

-    }

-

-    /**

-     * The loader-repository specifies the name of the UnifiedLoaderRepository MBean to use for the ear to provide ear

-     * level scoping of classes deployed in the ear. It is a unique JMX ObjectName string.

-     * <p/>

-     * <P>

-     * Example:

-     * </P>

-     * &lt;loader-repository>jboss.test:loader=cts-cmp2v1-sar.ear&lt;/loader-repository>

-     * 

-     * @return the object name of the ear mbean

-     */

-    public String getLoaderRepository()

-    {

-        return loaderRepository;

-    }

-

-    /**

-     * The module-order specifies the order in which the modules specified in the application.xml file gets loaded.

-     * Allowed values are:

-     * <p/>

-     * <module-order>strict</module-order> The strict value indicates that the deployments of the modules will be done

-     * in the order that would be specified in the application.xml and jboss-app.xml file.

-     * <p/>

-     * <module-order>implicit</module-order> The implicit value indicates the deployment would follow the order which

-     * would be specified in the DeploymentSorter.

-     * <p/>

-     * Returns {@code null} if no module order is set.

-     * <p/>

-     * Only available in JBoss 4.2 and 4.3. Has no effect in JBoss 5 and is not added when mentioned version is used.

-     * 

-     * @return the module order

-     */

-    public String getModuleOrder()

-    {

-        return moduleOrder;

-    }

-

-    /**

-     * Returns the list of datasources to include in the {@code jboss-app.xml} file as services. Each element of the

-     * list is the relative path to the datasource file contained in the EAR archive.

-     * 

-     * @return the list of datasources paths

-     */

-    public List<String> getDataSources()

-    {

-        return dataSources;

-    }

-

-    /**

-     * Returns the library directory to include in the {@code jboss-app.xml} file. It tells JBoss where to find

-     * non-Java EE libraries included in the EAR.

-     * 

-     * @return the library directory

-     */

-    public String getLibraryDirectory()

-    {

-        return libraryDirectory;

-    }

-

-    /**

-     * Returns the class loader repository configuration to include in the {@code jboss-app.xml} file. The content of

-     * this element is handed to the class loader, thereby altering it's default behaviour.

-     * <p/>

-     * This element is added as a child to the {@code loader-repository} element. If the element is not present in the

-     * configuration, it will be added.

-     * <p/>

-     * Example: &lt;loader-repository-config>java2ParentDelegaton=true&lt;/loader-repository-config>

-     * 

-     * @return the class loader repository configuration

-     */

-    public String getLoaderRepositoryConfig()

-    {

-        return loaderRepositoryConfig;

-    }

-

-    /**

-     * Returns the class loader repository class to include in the {@code jboss-app.xml} file. It tells JBoss which

-     * loader repository implementation to use.

-     * <p/>

-     * This element is added as an attribute to the {@code loader-repository} element, therefore it is not added if no

-     * such element configuration is present.

-     * <p/>

-     * Example: &lt;loader-repository-class>org.mindbug.jboss.AlternateLoaderRepository&lt;/loader-repository-class>

-     * 

-     * @return the class loader repository class

-     */

-    public String getLoaderRepositoryClass()

-    {

-        return loaderRepositoryClass;

-    }

-

-    /**

-     * Returns the class loader's configuration parser class to include in the {@code jboss-app.xml} file. It tells

-     * JBoss how to parse the configuration given in the {@code loader-repository-config} element.

-     * <p/>

-     * This element is added as an attribute to the {@code loader-repository-config} element, therefore it is not added

-     * if no such element configuration is present.

-     * <p/>

-     * Example: &lt;config-parser-class>org.mindbug.jboss.AlternateLoaderRepositoryConfigParser&lt;/config-parser-class>

-     * 

-     * @return the class loader's configuration parser class

-     */

-    public String getConfigParserClass()

-    {

-        return configParserClass;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.List;
+
+/**
+ * The JBoss specific configuration, used to generate the jboss-app.xml deployment descriptor file
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+class JbossConfiguration {
+    static final String VERSION_3_2 = "3.2";
+
+    static final String VERSION_4 = "4";
+
+    static final String VERSION_4_2 = "4.2";
+
+    static final String VERSION_5 = "5";
+
+    static final String VERSION = "version";
+
+    static final String SECURITY_DOMAIN = "security-domain";
+
+    static final String UNAUHTHENTICTED_PRINCIPAL = "unauthenticated-principal";
+
+    static final String JMX_NAME = "jmx-name";
+
+    static final String LOADER_REPOSITORY = "loader-repository";
+
+    static final String LOADER_REPOSITORY_CLASS_ATTRIBUTE = "loaderRepositoryClass";
+
+    static final String LOADER_REPOSITORY_CONFIG = "loader-repository-config";
+
+    static final String CONFIG_PARSER_CLASS_ATTRIBUTE = "configParserClass";
+
+    static final String MODULE_ORDER = "module-order";
+
+    static final String DATASOURCES = "data-sources";
+
+    static final String DATASOURCE = "data-source";
+
+    static final String LIBRARY_DIRECTORY = "library-directory";
+
+    private final String version;
+
+    private boolean jbossThreeDotTwo;
+
+    private boolean jbossFour;
+
+    private boolean jbossFourDotTwo;
+
+    private boolean jbossFive;
+
+    private final String securityDomain;
+
+    private final String unauthenticatedPrincipal;
+
+    private final String jmxName;
+
+    private final String loaderRepository;
+
+    private final String loaderRepositoryConfig;
+
+    private final String loaderRepositoryClass;
+
+    private final String configParserClass;
+
+    private final String moduleOrder;
+
+    private final List<String> dataSources;
+
+    private final String libraryDirectory;
+
+    JbossConfiguration(
+            String version,
+            String securityDomain,
+            String unauthenticatedPrincipal,
+            String jmxName,
+            String loaderRepository,
+            String moduleOrder,
+            List<String> dataSources,
+            String libraryDirectory,
+            String loaderRepositoryConfig,
+            String loaderRepositoryClass,
+            String configParserClass)
+            throws EarPluginException {
+        if (version == null) {
+            throw new EarPluginException("jboss version could not be null.");
+        } else {
+            this.version = version;
+            if (version.equals(JbossConfiguration.VERSION_3_2)) {
+                this.jbossThreeDotTwo = true;
+            } else if (version.equals(JbossConfiguration.VERSION_4)) {
+                this.jbossFour = true;
+            } else if (version.equals(JbossConfiguration.VERSION_4_2)) {
+                this.jbossFourDotTwo = true;
+            } else if (version.equals(JbossConfiguration.VERSION_5)) {
+                this.jbossFive = true;
+            } else {
+                throw new EarPluginException("Invalid JBoss configuration, version[" + version + "] is not supported.");
+            }
+            this.securityDomain = securityDomain;
+            this.unauthenticatedPrincipal = unauthenticatedPrincipal;
+            this.jmxName = jmxName;
+            this.loaderRepository = loaderRepository;
+            this.moduleOrder = moduleOrder;
+            this.dataSources = dataSources;
+            this.libraryDirectory = libraryDirectory;
+            this.loaderRepositoryConfig = loaderRepositoryConfig;
+            this.loaderRepositoryClass = loaderRepositoryClass;
+            this.configParserClass = configParserClass;
+        }
+    }
+
+    /**
+     * Returns the targeted version of JBoss.
+     *
+     * @return the jboss version
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 3.2.
+     *
+     * @return if the targeted version is 3.2
+     */
+    public boolean isJbossThreeDotTwo() {
+        return jbossThreeDotTwo;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 4.
+     *
+     * @return if the targeted version is 4
+     */
+    public boolean isJbossFour() {
+        return jbossFour;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version if 4 or higher (that is 4, 4.2 or 5).
+     *
+     * @return true if the targeted version is 4+
+     */
+    public boolean isJbossFourOrHigher() {
+        return jbossFour || jbossFourDotTwo || jbossFive;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 4.2.
+     *
+     * @return if the targeted version is 4.2
+     */
+    public boolean isJbossFourDotTwo() {
+        return jbossFourDotTwo;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version if 4.2 or higher (that is 4.2 or 5).
+     *
+     * @return true if the targeted version is 4.2+
+     */
+    public boolean isJbossFourDotTwoOrHigher() {
+        return jbossFourDotTwo || jbossFive;
+    }
+
+    /**
+     * Returns true if the targeted JBoss version is 5.
+     *
+     * @return if the targeted version is 5
+     */
+    public boolean isJbossFive() {
+        return jbossFive;
+    }
+
+    /**
+     * The security-domain element specifies the JNDI name of the security manager that implements the
+     * EJBSecurityManager and RealmMapping for the domain. When specified at the jboss level it specifies the security
+     * domain for all j2ee components in the deployment unit.
+     * <p/>
+     * One can override the global security-domain at the container level using the security-domain element at the
+     * container-configuration level.
+     * <p/>
+     * Only available as from JBoss 4.
+     *
+     * @return the JNDI name of the security manager
+     */
+    public String getSecurityDomain() {
+        return securityDomain;
+    }
+
+    /**
+     * The unauthenticated-principal element specifies the name of the principal that will be returned by the
+     * EJBContext.getCallerPrincipal() method if there is no authenticated user. This Principal has no roles or
+     * privileges to call any other beans.
+     * <p/>
+     * Only available as from JBoss 4.
+     *
+     * @return the unauthenticated principal
+     */
+    public String getUnauthenticatedPrincipal() {
+        return unauthenticatedPrincipal;
+    }
+
+    /**
+     * The jmx-name element allows one to specify the JMX ObjectName to use for the MBean associated with the ear
+     * module. This must be a unique name and valid JMX ObjectName string.
+     *
+     * @return the object name of the ear mbean
+     */
+    public String getJmxName() {
+        return jmxName;
+    }
+
+    /**
+     * The loader-repository specifies the name of the UnifiedLoaderRepository MBean to use for the ear to provide ear
+     * level scoping of classes deployed in the ear. It is a unique JMX ObjectName string.
+     * <p/>
+     * <P>
+     * Example:
+     * </P>
+     * &lt;loader-repository>jboss.test:loader=cts-cmp2v1-sar.ear&lt;/loader-repository>
+     *
+     * @return the object name of the ear mbean
+     */
+    public String getLoaderRepository() {
+        return loaderRepository;
+    }
+
+    /**
+     * The module-order specifies the order in which the modules specified in the application.xml file gets loaded.
+     * Allowed values are:
+     * <p/>
+     * <module-order>strict</module-order> The strict value indicates that the deployments of the modules will be done
+     * in the order that would be specified in the application.xml and jboss-app.xml file.
+     * <p/>
+     * <module-order>implicit</module-order> The implicit value indicates the deployment would follow the order which
+     * would be specified in the DeploymentSorter.
+     * <p/>
+     * Returns {@code null} if no module order is set.
+     * <p/>
+     * Only available in JBoss 4.2 and 4.3. Has no effect in JBoss 5 and is not added when mentioned version is used.
+     *
+     * @return the module order
+     */
+    public String getModuleOrder() {
+        return moduleOrder;
+    }
+
+    /**
+     * Returns the list of datasources to include in the {@code jboss-app.xml} file as services. Each element of the
+     * list is the relative path to the datasource file contained in the EAR archive.
+     *
+     * @return the list of datasources paths
+     */
+    public List<String> getDataSources() {
+        return dataSources;
+    }
+
+    /**
+     * Returns the library directory to include in the {@code jboss-app.xml} file. It tells JBoss where to find
+     * non-Java EE libraries included in the EAR.
+     *
+     * @return the library directory
+     */
+    public String getLibraryDirectory() {
+        return libraryDirectory;
+    }
+
+    /**
+     * Returns the class loader repository configuration to include in the {@code jboss-app.xml} file. The content of
+     * this element is handed to the class loader, thereby altering it's default behaviour.
+     * <p/>
+     * This element is added as a child to the {@code loader-repository} element. If the element is not present in the
+     * configuration, it will be added.
+     * <p/>
+     * Example: &lt;loader-repository-config>java2ParentDelegaton=true&lt;/loader-repository-config>
+     *
+     * @return the class loader repository configuration
+     */
+    public String getLoaderRepositoryConfig() {
+        return loaderRepositoryConfig;
+    }
+
+    /**
+     * Returns the class loader repository class to include in the {@code jboss-app.xml} file. It tells JBoss which
+     * loader repository implementation to use.
+     * <p/>
+     * This element is added as an attribute to the {@code loader-repository} element, therefore it is not added if no
+     * such element configuration is present.
+     * <p/>
+     * Example: &lt;loader-repository-class>org.mindbug.jboss.AlternateLoaderRepository&lt;/loader-repository-class>
+     *
+     * @return the class loader repository class
+     */
+    public String getLoaderRepositoryClass() {
+        return loaderRepositoryClass;
+    }
+
+    /**
+     * Returns the class loader's configuration parser class to include in the {@code jboss-app.xml} file. It tells
+     * JBoss how to parse the configuration given in the {@code loader-repository-config} element.
+     * <p/>
+     * This element is added as an attribute to the {@code loader-repository-config} element, therefore it is not added
+     * if no such element configuration is present.
+     * <p/>
+     * Example: &lt;config-parser-class>org.mindbug.jboss.AlternateLoaderRepositoryConfigParser&lt;/config-parser-class>
+     *
+     * @return the class loader's configuration parser class
+     */
+    public String getConfigParserClass() {
+        return configParserClass;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/JbossEarModule.java b/src/main/java/org/apache/maven/plugins/ear/JbossEarModule.java
index 4dedb4a..8e806b5 100644
--- a/src/main/java/org/apache/maven/plugins/ear/JbossEarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/JbossEarModule.java
@@ -1,38 +1,55 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * Represents a JBoss specific ear module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public interface JbossEarModule

-{

-    /**

-     * Appends the {@code XML} representation of this module for the jboss-app.xml file.

-     * 

-     * @param writer the writer to use

-     * @param version the version of the {@code jboss-app.xml} file

-     */

-    void appendJbossModule( XMLWriter writer, String version );

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * Represents a JBoss specific ear module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public interface JbossEarModule {
+    /**
+     * Appends the {@code XML} representation of this module for the jboss-app.xml file.
+     *
+     * @param writer the writer to use
+     * @param version the version of the {@code jboss-app.xml} file
+     */
+    void appendJbossModule(XMLWriter writer, String version);
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/ParModule.java b/src/main/java/org/apache/maven/plugins/ear/ParModule.java
index 53fbcc9..50f05ee 100644
--- a/src/main/java/org/apache/maven/plugins/ear/ParModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/ParModule.java
@@ -1,52 +1,66 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-

-/**

- * The {@link EarModule} implementation for a Par module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ParModule

-    extends EjbModule

-{

-    /**

-     * Default type of the artifact of a Par module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "par";

-

-    /**

-     * Create an instance.

-     */

-    public ParModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public ParModule( Artifact a )

-    {

-        super( a );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * The {@link EarModule} implementation for a Par module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ParModule extends EjbModule {
+    /**
+     * Default type of the artifact of a Par module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "par";
+
+    /**
+     * Create an instance.
+     */
+    public ParModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public ParModule(Artifact a) {
+        super(a);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/RarModule.java b/src/main/java/org/apache/maven/plugins/ear/RarModule.java
index 0b3ec8b..297427b 100644
--- a/src/main/java/org/apache/maven/plugins/ear/RarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/RarModule.java
@@ -1,74 +1,87 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The {@link EarModule} implementation for an J2EE connector module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class RarModule

-    extends AbstractEarModule

-{

-    /**

-     * Default type of the artifact of an Java EE connector module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "rar";

-

-    private static final String RAR_MODULE = "connector";

-

-    private static final String DEFAULT_LIB_DIRECTORY = "/";

-

-    /**

-     * Create an instance.

-     */

-    public RarModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public RarModule( Artifact a )

-    {

-        super( a );

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        startModuleElement( writer, generateId );

-        writer.startElement( RAR_MODULE );

-        writer.writeText( getUri() );

-        writer.endElement();

-

-        writeAltDeploymentDescriptor( writer, version );

-

-        writer.endElement();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for an J2EE connector module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class RarModule extends AbstractEarModule {
+    /**
+     * Default type of the artifact of an Java EE connector module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "rar";
+
+    private static final String RAR_MODULE = "connector";
+
+    private static final String DEFAULT_LIB_DIRECTORY = "/";
+
+    /**
+     * Create an instance.
+     */
+    public RarModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public RarModule(Artifact a) {
+        super(a);
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        startModuleElement(writer, generateId);
+        writer.startElement(RAR_MODULE);
+        writer.writeText(getUri());
+        writer.endElement();
+
+        writeAltDeploymentDescriptor(writer, version);
+
+        writer.endElement();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/ResourceRef.java b/src/main/java/org/apache/maven/plugins/ear/ResourceRef.java
index 339dfb2..5964064 100644
--- a/src/main/java/org/apache/maven/plugins/ear/ResourceRef.java
+++ b/src/main/java/org/apache/maven/plugins/ear/ResourceRef.java
@@ -1,3 +1,21 @@
+/*
+ * 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.maven.plugins.ear;
 
 /*
@@ -23,7 +41,7 @@
 
 /**
  * Representation of {@code resource-ref} element in {@code application.xml} file.
- * 
+ *
  * <pre>
  * &lt;resource-ref&gt;
  *   &lt;res-ref-name&gt;jdbc/myDs&lt;/res-ref-name&gt;
@@ -39,12 +57,11 @@
  *   &lt;lookup-name&gt;jdbc/lookup/myDs&lt;/lookup-name&gt;
  * &lt;/resource-ref&gt;
  * </pre>
- * 
+ *
  * @author Karl Heinz Marbaise
  * @since 3.0.0
  */
-public class ResourceRef
-{
+public class ResourceRef {
     static final String RESOURCE_REF = "resource-ref";
 
     static final String RESOURCE_REF_NAME = "res-ref-name";
@@ -53,7 +70,7 @@
 
     static final String RESOURCE_AUTH = "res-auth";
 
-   static final String LOOKUP_NAME = "lookup-name";
+    static final String LOOKUP_NAME = "lookup-name";
 
     private String name;
 
@@ -61,7 +78,7 @@
 
     private String auth;
 
-   private String lookupName;
+    private String lookupName;
 
     /**
      * @param name The res-ref-name.
@@ -69,129 +86,109 @@
      * @param auth The res-auth.
      * @param lookupName The lookup-name.
      */
-   public ResourceRef( String name, String type, String auth, String lookupName )
-    {
-        if ( name == null || name.isEmpty() )
-        {
-            throw new IllegalArgumentException( RESOURCE_REF_NAME + " in " + RESOURCE_REF_NAME
-                + " element cannot be null." );
-        }
-        else if ( ( type == null || type.isEmpty() ) && ( auth == null || auth.isEmpty() ) )
-        {
-            throw new IllegalArgumentException( RESOURCE_TYPE + " in " + RESOURCE_REF_NAME
-                + " element cannot be null " );
+    public ResourceRef(String name, String type, String auth, String lookupName) {
+        if (name == null || name.isEmpty()) {
+            throw new IllegalArgumentException(
+                    RESOURCE_REF_NAME + " in " + RESOURCE_REF_NAME + " element cannot be null.");
+        } else if ((type == null || type.isEmpty()) && (auth == null || auth.isEmpty())) {
+            throw new IllegalArgumentException(RESOURCE_TYPE + " in " + RESOURCE_REF_NAME + " element cannot be null ");
         }
 
         this.name = name;
         this.type = type;
         this.auth = auth;
         this.lookupName = lookupName;
-
     }
 
     /**
      * Appends the {@code XML} representation of this env-entry.
-     * 
+     *
      * @param writer the writer to use
      */
-    public void appendResourceRefEntry( XMLWriter writer )
-    {
-        writer.startElement( RESOURCE_REF );
+    public void appendResourceRefEntry(XMLWriter writer) {
+        writer.startElement(RESOURCE_REF);
 
         // res-name
-        doWriteElement( writer, RESOURCE_REF_NAME, getName() );
+        doWriteElement(writer, RESOURCE_REF_NAME, getName());
 
         // res_ref-type
-        if ( getType() != null )
-        {
-            doWriteElement( writer, RESOURCE_TYPE, getType() );
+        if (getType() != null) {
+            doWriteElement(writer, RESOURCE_TYPE, getType());
         }
 
         // ref-auth
-        if ( getAuth() != null )
-        {
-            doWriteElement( writer, RESOURCE_AUTH, getAuth() );
+        if (getAuth() != null) {
+            doWriteElement(writer, RESOURCE_AUTH, getAuth());
         }
 
         // lookup-name
-        if ( getLookupName() != null ) 
-        {
-            doWriteElement( writer, LOOKUP_NAME, getLookupName() );
+        if (getLookupName() != null) {
+            doWriteElement(writer, LOOKUP_NAME, getLookupName());
         }
 
         // end of ejb-ref
         writer.endElement();
     }
 
-    private void doWriteElement( XMLWriter writer, String element, String text )
-    {
-        writer.startElement( element );
-        writer.writeText( text );
+    private void doWriteElement(XMLWriter writer, String element, String text) {
+        writer.startElement(element);
+        writer.writeText(text);
         writer.endElement();
     }
 
     /**
      * @return {@link #name}
      */
-    public String getName()
-    {
+    public String getName() {
         return name;
     }
 
     /**
      * @param name {@link #name}
      */
-    public void setName( String name )
-    {
+    public void setName(String name) {
         this.name = name;
     }
 
     /**
      * @return {@link #type}
      */
-    public String getType()
-    {
+    public String getType() {
         return type;
     }
 
     /**
      * @param type {@link #type}
      */
-    public void setType( String type )
-    {
+    public void setType(String type) {
         this.type = type;
     }
 
     /**
      * @return {@link #auth}
      */
-    public String getAuth()
-    {
+    public String getAuth() {
         return auth;
     }
 
     /**
      * @param auth {@link #auth}
      */
-    public void setAuth( String auth )
-    {
+    public void setAuth(String auth) {
         this.auth = auth;
     }
-    
+
     /**
      * @return {@link #lookupName}
      */
-    public String getLookupName() 
-    {
+    public String getLookupName() {
         return lookupName;
     }
 
-   /**
-    * @param lookupName {@link #lookupName}
-    */
-    public void setLookupName( String lookupName ) 
-    {
+    /**
+     * @param lookupName {@link #lookupName}
+     */
+    public void setLookupName(String lookupName) {
         this.lookupName = lookupName;
     }
-
 }
diff --git a/src/main/java/org/apache/maven/plugins/ear/SarModule.java b/src/main/java/org/apache/maven/plugins/ear/SarModule.java
index deb9944..8375a0e 100644
--- a/src/main/java/org/apache/maven/plugins/ear/SarModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/SarModule.java
@@ -1,94 +1,104 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The {@link EarModule} implementation for a JBoss sar module.

- * 

- * @author Stephane Nicoll <snicoll@apache.org>

- * @author $Author: khmarbaise $ (last edit)

- * @version $Revision: 1645331 $

- */

-/**

- * @author kama

- *

- */

-public class SarModule

-    extends AbstractEarModule

-    implements JbossEarModule

-{

-    /**

-     * Default type of the artifact of a JBoss sar module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "sar";

-

-    private static final String SAR_MODULE = "connector";

-

-    private static final String DEFAULT_LIB_DIRECTORY = "lib";

-

-    /**

-     * Create an instance.

-     */

-    public SarModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public SarModule( Artifact a )

-    {

-        super( a );

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        // If JBoss is not configured, add the module as a connector element

-        if ( !earExecutionContext.isJbossConfigured() )

-        {

-            startModuleElement( writer, generateId );

-            writer.startElement( SAR_MODULE );

-            writer.writeText( getUri() );

-            writer.endElement();

-            writer.endElement();

-        }

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendJbossModule( XMLWriter writer, String version )

-    {

-        writer.startElement( MODULE_ELEMENT );

-        writer.startElement( "service" );

-        writer.writeText( getUri() );

-        writer.endElement();

-        writer.endElement();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for a JBoss sar module.
+ *
+ * @author Stephane Nicoll <snicoll@apache.org>
+ * @author $Author: khmarbaise $ (last edit)
+ * @version $Revision: 1645331 $
+ */
+/**
+ * @author kama
+ *
+ */
+public class SarModule extends AbstractEarModule implements JbossEarModule {
+    /**
+     * Default type of the artifact of a JBoss sar module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "sar";
+
+    private static final String SAR_MODULE = "connector";
+
+    private static final String DEFAULT_LIB_DIRECTORY = "lib";
+
+    /**
+     * Create an instance.
+     */
+    public SarModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public SarModule(Artifact a) {
+        super(a);
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        // If JBoss is not configured, add the module as a connector element
+        if (!earExecutionContext.isJbossConfigured()) {
+            startModuleElement(writer, generateId);
+            writer.startElement(SAR_MODULE);
+            writer.writeText(getUri());
+            writer.endElement();
+            writer.endElement();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendJbossModule(XMLWriter writer, String version) {
+        writer.startElement(MODULE_ELEMENT);
+        writer.startElement("service");
+        writer.writeText(getUri());
+        writer.endElement();
+        writer.endElement();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/SecurityRole.java b/src/main/java/org/apache/maven/plugins/ear/SecurityRole.java
index 1f4a0d8..527acdc 100644
--- a/src/main/java/org/apache/maven/plugins/ear/SecurityRole.java
+++ b/src/main/java/org/apache/maven/plugins/ear/SecurityRole.java
@@ -1,134 +1,136 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-/**

- * The representation of a security-role entry within an application.xml file.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-class SecurityRole

-{

-

-    protected static final String SECURITY_ROLE = "security-role";

-

-    protected static final String ID_ATTRIBUTE = "id";

-

-    protected static final String DESCRIPTION = "description";

-

-    protected static final String ROLE_NAME = "role-name";

-

-    private final String roleName;

-

-    private final String roleNameId;

-

-    private final String roleId;

-

-    private final String description;

-

-    private final String descriptionId;

-

-    SecurityRole( String roleName, String roleNameId, String roleId, String description, String descriptionId )

-    {

-        if ( roleName == null )

-        {

-            throw new NullPointerException( "role-name in security-role element could not be null." );

-        }

-        this.roleName = roleName;

-        this.roleNameId = roleNameId;

-        this.roleId = roleId;

-        this.description = description;

-        this.descriptionId = descriptionId;

-    }

-

-    public String getRoleName()

-    {

-        return roleName;

-    }

-

-    public String getRoleNameId()

-    {

-        return roleNameId;

-    }

-

-    public String getRoleId()

-    {

-        return roleId;

-    }

-

-    public String getDescription()

-    {

-        return description;

-    }

-

-    public String getDescriptionId()

-    {

-        return descriptionId;

-    }

-

-    /**

-     * Appends the {@code XML} representation of this security role.

-     * 

-     * @param writer the writer to use

-     */

-    public void appendSecurityRole( XMLWriter writer )

-    {

-        writer.startElement( SECURITY_ROLE );

-

-        // role id

-        if ( getRoleId() != null )

-        {

-            writer.addAttribute( ID_ATTRIBUTE, getRoleId() );

-        }

-

-        // description

-        if ( getDescription() != null )

-        {

-            writer.startElement( DESCRIPTION );

-            if ( getDescriptionId() != null )

-            {

-                writer.addAttribute( ID_ATTRIBUTE, getDescriptionId() );

-            }

-            writer.writeText( getDescription() );

-            writer.endElement();

-

-        }

-

-        // role name

-        writer.startElement( ROLE_NAME );

-        if ( getRoleNameId() != null )

-        {

-            writer.addAttribute( ID_ATTRIBUTE, getRoleNameId() );

-        }

-        writer.writeText( getRoleName() );

-        writer.endElement();

-

-        // end of security-role

-        writer.endElement();

-    }

-

-    public String toString()

-    {

-        return "Security role " + getRoleName();

-    }

-

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The representation of a security-role entry within an application.xml file.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+class SecurityRole {
+
+    protected static final String SECURITY_ROLE = "security-role";
+
+    protected static final String ID_ATTRIBUTE = "id";
+
+    protected static final String DESCRIPTION = "description";
+
+    protected static final String ROLE_NAME = "role-name";
+
+    private final String roleName;
+
+    private final String roleNameId;
+
+    private final String roleId;
+
+    private final String description;
+
+    private final String descriptionId;
+
+    SecurityRole(String roleName, String roleNameId, String roleId, String description, String descriptionId) {
+        if (roleName == null) {
+            throw new NullPointerException("role-name in security-role element could not be null.");
+        }
+        this.roleName = roleName;
+        this.roleNameId = roleNameId;
+        this.roleId = roleId;
+        this.description = description;
+        this.descriptionId = descriptionId;
+    }
+
+    public String getRoleName() {
+        return roleName;
+    }
+
+    public String getRoleNameId() {
+        return roleNameId;
+    }
+
+    public String getRoleId() {
+        return roleId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getDescriptionId() {
+        return descriptionId;
+    }
+
+    /**
+     * Appends the {@code XML} representation of this security role.
+     *
+     * @param writer the writer to use
+     */
+    public void appendSecurityRole(XMLWriter writer) {
+        writer.startElement(SECURITY_ROLE);
+
+        // role id
+        if (getRoleId() != null) {
+            writer.addAttribute(ID_ATTRIBUTE, getRoleId());
+        }
+
+        // description
+        if (getDescription() != null) {
+            writer.startElement(DESCRIPTION);
+            if (getDescriptionId() != null) {
+                writer.addAttribute(ID_ATTRIBUTE, getDescriptionId());
+            }
+            writer.writeText(getDescription());
+            writer.endElement();
+        }
+
+        // role name
+        writer.startElement(ROLE_NAME);
+        if (getRoleNameId() != null) {
+            writer.addAttribute(ID_ATTRIBUTE, getRoleNameId());
+        }
+        writer.writeText(getRoleName());
+        writer.endElement();
+
+        // end of security-role
+        writer.endElement();
+    }
+
+    public String toString() {
+        return "Security role " + getRoleName();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/UnknownArtifactTypeException.java b/src/main/java/org/apache/maven/plugins/ear/UnknownArtifactTypeException.java
index ae4b507..8c3da31 100644
--- a/src/main/java/org/apache/maven/plugins/ear/UnknownArtifactTypeException.java
+++ b/src/main/java/org/apache/maven/plugins/ear/UnknownArtifactTypeException.java
@@ -1,50 +1,63 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-/**

- * Thrown if an unknown artifact type is encountered.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class UnknownArtifactTypeException

-    extends EarPluginException

-{

-

-    /**

-     * 

-     */

-    private static final long serialVersionUID = 2738931967722457793L;

-

-    /**

-     * Create an instance.

-     */

-    public UnknownArtifactTypeException()

-    {

-    }

-

-    /**

-     * @param message The message of the problem.

-     */

-    public UnknownArtifactTypeException( String message )

-    {

-        super( message );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+/**
+ * Thrown if an unknown artifact type is encountered.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class UnknownArtifactTypeException extends EarPluginException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 2738931967722457793L;
+
+    /**
+     * Create an instance.
+     */
+    public UnknownArtifactTypeException() {}
+
+    /**
+     * @param message The message of the problem.
+     */
+    public UnknownArtifactTypeException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/WebModule.java b/src/main/java/org/apache/maven/plugins/ear/WebModule.java
index 9a0796b..ec5268a 100644
--- a/src/main/java/org/apache/maven/plugins/ear/WebModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/WebModule.java
@@ -1,134 +1,141 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugin.MojoFailureException;

-import org.codehaus.plexus.util.xml.XMLWriter;

-

-import java.util.Set;

-

-/**

- * The {@link EarModule} implementation for a Web application module.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class WebModule

-    extends AbstractEarModule

-{

-    /**

-     * Default type of the artifact of a Web application module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "war";

-

-    private static final String WEB_MODULE = "web";

-

-    private static final String WEB_URI_FIELD = "web-uri";

-

-    private static final String CONTEXT_ROOT_FIELD = "context-root";

-

-    private static final String DEFAULT_LIB_DIRECTORY = "WEB-INF/lib";

-

-    private String contextRoot;

-

-    /**

-     * Create an instance.

-     */

-    public WebModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public WebModule( Artifact a )

-    {

-        super( a );

-        this.contextRoot = getDefaultContextRoot( a );

-        this.libDirectory = DEFAULT_LIB_DIRECTORY;

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void appendModule( XMLWriter writer, String version, Boolean generateId )

-    {

-        startModuleElement( writer, generateId );

-        writer.startElement( WEB_MODULE );

-        writer.startElement( WEB_URI_FIELD );

-        writer.writeText( getUri() );

-        writer.endElement(); // web-uri

-

-        writer.startElement( CONTEXT_ROOT_FIELD );

-        writer.writeText( getContextRoot() );

-        writer.endElement(); // context-root

-

-        writer.endElement(); // web

-

-        writeAltDeploymentDescriptor( writer, version );

-

-        writer.endElement(); // module

-    }

-

-    /**

-     * {@inheritDoc}

-     */

-    public void resolveArtifact( Set<Artifact> artifacts )

-        throws EarPluginException, MojoFailureException

-    {

-        // Let's resolve the artifact

-        super.resolveArtifact( artifacts );

-

-        // Context root has not been customized - using default

-        if ( contextRoot == null )

-        {

-            contextRoot = getDefaultContextRoot( getArtifact() );

-        }

-    }

-

-    /**

-     * Returns the context root to use for the web module.

-     *

-     * Note that this might return {@code null} till the artifact has been resolved.

-     * 

-     * @return the context root

-     */

-    public String getContextRoot()

-    {

-        return contextRoot;

-    }

-

-    /**

-     * Generates a default context root for the given artifact, based on the {@code artifactId}.

-     * 

-     * @param a the artifact

-     * @return a context root for the artifact

-     */

-    private static String getDefaultContextRoot( Artifact a )

-    {

-        if ( a == null )

-        {

-            throw new NullPointerException( "Artifact could not be null." );

-        }

-        return "/" + a.getArtifactId();

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.xml.XMLWriter;
+
+/**
+ * The {@link EarModule} implementation for a Web application module.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class WebModule extends AbstractEarModule {
+    /**
+     * Default type of the artifact of a Web application module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "war";
+
+    private static final String WEB_MODULE = "web";
+
+    private static final String WEB_URI_FIELD = "web-uri";
+
+    private static final String CONTEXT_ROOT_FIELD = "context-root";
+
+    private static final String DEFAULT_LIB_DIRECTORY = "WEB-INF/lib";
+
+    private String contextRoot;
+
+    /**
+     * Create an instance.
+     */
+    public WebModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public WebModule(Artifact a) {
+        super(a);
+        this.contextRoot = getDefaultContextRoot(a);
+        this.libDirectory = DEFAULT_LIB_DIRECTORY;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void appendModule(XMLWriter writer, String version, Boolean generateId) {
+        startModuleElement(writer, generateId);
+        writer.startElement(WEB_MODULE);
+        writer.startElement(WEB_URI_FIELD);
+        writer.writeText(getUri());
+        writer.endElement(); // web-uri
+
+        writer.startElement(CONTEXT_ROOT_FIELD);
+        writer.writeText(getContextRoot());
+        writer.endElement(); // context-root
+
+        writer.endElement(); // web
+
+        writeAltDeploymentDescriptor(writer, version);
+
+        writer.endElement(); // module
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void resolveArtifact(Set<Artifact> artifacts) throws EarPluginException, MojoFailureException {
+        // Let's resolve the artifact
+        super.resolveArtifact(artifacts);
+
+        // Context root has not been customized - using default
+        if (contextRoot == null) {
+            contextRoot = getDefaultContextRoot(getArtifact());
+        }
+    }
+
+    /**
+     * Returns the context root to use for the web module.
+     *
+     * Note that this might return {@code null} till the artifact has been resolved.
+     *
+     * @return the context root
+     */
+    public String getContextRoot() {
+        return contextRoot;
+    }
+
+    /**
+     * Generates a default context root for the given artifact, based on the {@code artifactId}.
+     *
+     * @param a the artifact
+     * @return a context root for the artifact
+     */
+    private static String getDefaultContextRoot(Artifact a) {
+        if (a == null) {
+            throw new NullPointerException("Artifact could not be null.");
+        }
+        return "/" + a.getArtifactId();
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/WsrModule.java b/src/main/java/org/apache/maven/plugins/ear/WsrModule.java
index e2456e6..790371d 100644
--- a/src/main/java/org/apache/maven/plugins/ear/WsrModule.java
+++ b/src/main/java/org/apache/maven/plugins/ear/WsrModule.java
@@ -1,52 +1,66 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.Artifact;

-

-/**

- * The {@link EarModule} implementation for a JBoss wsr module.

- * 

- * @author <a href="mailto:brado@neurofire.com">brado@neurofire.com</a>

- */

-public class WsrModule

-    extends RarModule

-{

-    /**

-     * Default type of the artifact of a JBoss wsr module.

-     */

-    public static final String DEFAULT_ARTIFACT_TYPE = "wsr";

-

-    /**

-     * Create an instance.

-     */

-    public WsrModule()

-    {

-        this.type = DEFAULT_ARTIFACT_TYPE;

-    }

-

-    /**

-     * @param a {@link Artifact}

-     */

-    public WsrModule( Artifact a )

-    {

-        super( a );

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * The {@link EarModule} implementation for a JBoss wsr module.
+ *
+ * @author <a href="mailto:brado@neurofire.com">brado@neurofire.com</a>
+ */
+public class WsrModule extends RarModule {
+    /**
+     * Default type of the artifact of a JBoss wsr module.
+     */
+    public static final String DEFAULT_ARTIFACT_TYPE = "wsr";
+
+    /**
+     * Create an instance.
+     */
+    public WsrModule() {
+        this.type = DEFAULT_ARTIFACT_TYPE;
+    }
+
+    /**
+     * @param a {@link Artifact}
+     */
+    public WsrModule(Artifact a) {
+        super(a);
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/util/ArtifactRepository.java b/src/main/java/org/apache/maven/plugins/ear/util/ArtifactRepository.java
index 5baed1f..f7c3b0b 100644
--- a/src/main/java/org/apache/maven/plugins/ear/util/ArtifactRepository.java
+++ b/src/main/java/org/apache/maven/plugins/ear/util/ArtifactRepository.java
@@ -1,146 +1,148 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import java.util.Set;

-import java.util.TreeSet;

-

-import org.apache.maven.artifact.Artifact;

-

-/**

- * An artifact repository used to resolve {@link org.apache.maven.plugins.ear.EarModule}.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ArtifactRepository

-{

-    private final Set<Artifact> artifacts;

-

-    private final String mainArtifactId;

-

-    private final ArtifactTypeMappingService artifactTypeMappingService;

-

-    /**

-     * Creates a new repository with the specified artifacts.

-     * 

-     * @param artifacts the artifacts

-     * @param mainArtifactId the id to use for the main artifact (no classifier)

-     * @param artifactTypeMappingService {@link ArtifactTypeMappingService}

-     */

-    public ArtifactRepository( Set<Artifact> artifacts, String mainArtifactId,

-                               ArtifactTypeMappingService artifactTypeMappingService )

-    {

-        this.artifacts = artifacts;

-        this.mainArtifactId = mainArtifactId;

-        this.artifactTypeMappingService = artifactTypeMappingService;

-    }

-

-    /**

-     * Returns the artifact with the specified parameters.

-     * <p>

-     * If the artifact is classified and is the only one with the specified groupI, artifactId and type, it will be

-     * returned.</p>

-     * <p>

-     * If the artifact is classified and is not the only one with the specified groupI, artifactId and type, it returns

-     * null.</p>

-     * 

-     * If the artifact is not found, it returns null.

-     * 

-     * @param groupId the group id

-     * @param artifactId the artifact id

-     * @param type the type

-     * @param classifier the classifier

-     * @return the artifact or null if no artifact were found

-     */

-    public Artifact getUniqueArtifact( String groupId, String artifactId, String type, String classifier )

-    {

-        final Set<Artifact> candidates = getArtifacts( groupId, artifactId, type );

-        if ( candidates.size() == 0 )

-        {

-            return null;

-        }

-        else if ( candidates.size() == 1 && classifier == null )

-        {

-            return candidates.iterator().next();

-        }

-        else if ( classifier != null )

-        {

-            for ( Artifact a : candidates )

-            {

-                if ( a.getClassifier() == null && classifier.equals( mainArtifactId ) )

-                {

-                    return a;

-                }

-                else if ( classifier.equals( a.getClassifier() ) )

-                {

-                    return a;

-                }

-            }

-        }

-        // All other cases, classifier is null and more than one candidate ; artifact not found

-        return null;

-    }

-

-    /**

-     * Returns the artifact with the specified parameters.

-     * <p>

-     * If the artifact is classified and is the only one with the specified groupI, artifactId and type, it will be

-     * returned.</p>

-     * <p>

-     * If the artifact is classified and is not the only one with the specified groupI, artifactId and type, it returns

-     * null.</p>

-     * 

-     * If the artifact is not found, it returns null.

-     * 

-     * @param groupId the group id

-     * @param artifactId the artifact id

-     * @param type the type

-     * @return the artifact or null if no artifact were found

-     */

-    public Artifact getUniqueArtifact( String groupId, String artifactId, String type )

-    {

-        return getUniqueArtifact( groupId, artifactId, type, null );

-    }

-

-    /**

-     * Returns the artifacts with the specified parameters.

-     * 

-     * @param groupId the group id

-     * @param artifactId the artifact id

-     * @param type the type

-     * @return the artifacts or an empty set if no artifact were found

-     */

-    public Set<Artifact> getArtifacts( String groupId, String artifactId, String type )

-    {

-        final Set<Artifact> result = new TreeSet<>();

-        for ( Artifact a : artifacts )

-        {

-            // If the groupId, the artifactId and if the

-            // artifact's type is known, then we have found a candidate.

-            if ( a.getGroupId().equals( groupId ) && a.getArtifactId().equals( artifactId )

-                && artifactTypeMappingService.isMappedToType( type, a.getType() ) )

-            {

-                result.add( a );

-

-            }

-        }

-        return result;

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * An artifact repository used to resolve {@link org.apache.maven.plugins.ear.EarModule}.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ArtifactRepository {
+    private final Set<Artifact> artifacts;
+
+    private final String mainArtifactId;
+
+    private final ArtifactTypeMappingService artifactTypeMappingService;
+
+    /**
+     * Creates a new repository with the specified artifacts.
+     *
+     * @param artifacts the artifacts
+     * @param mainArtifactId the id to use for the main artifact (no classifier)
+     * @param artifactTypeMappingService {@link ArtifactTypeMappingService}
+     */
+    public ArtifactRepository(
+            Set<Artifact> artifacts, String mainArtifactId, ArtifactTypeMappingService artifactTypeMappingService) {
+        this.artifacts = artifacts;
+        this.mainArtifactId = mainArtifactId;
+        this.artifactTypeMappingService = artifactTypeMappingService;
+    }
+
+    /**
+     * Returns the artifact with the specified parameters.
+     * <p>
+     * If the artifact is classified and is the only one with the specified groupI, artifactId and type, it will be
+     * returned.</p>
+     * <p>
+     * If the artifact is classified and is not the only one with the specified groupI, artifactId and type, it returns
+     * null.</p>
+     *
+     * If the artifact is not found, it returns null.
+     *
+     * @param groupId the group id
+     * @param artifactId the artifact id
+     * @param type the type
+     * @param classifier the classifier
+     * @return the artifact or null if no artifact were found
+     */
+    public Artifact getUniqueArtifact(String groupId, String artifactId, String type, String classifier) {
+        final Set<Artifact> candidates = getArtifacts(groupId, artifactId, type);
+        if (candidates.size() == 0) {
+            return null;
+        } else if (candidates.size() == 1 && classifier == null) {
+            return candidates.iterator().next();
+        } else if (classifier != null) {
+            for (Artifact a : candidates) {
+                if (a.getClassifier() == null && classifier.equals(mainArtifactId)) {
+                    return a;
+                } else if (classifier.equals(a.getClassifier())) {
+                    return a;
+                }
+            }
+        }
+        // All other cases, classifier is null and more than one candidate ; artifact not found
+        return null;
+    }
+
+    /**
+     * Returns the artifact with the specified parameters.
+     * <p>
+     * If the artifact is classified and is the only one with the specified groupI, artifactId and type, it will be
+     * returned.</p>
+     * <p>
+     * If the artifact is classified and is not the only one with the specified groupI, artifactId and type, it returns
+     * null.</p>
+     *
+     * If the artifact is not found, it returns null.
+     *
+     * @param groupId the group id
+     * @param artifactId the artifact id
+     * @param type the type
+     * @return the artifact or null if no artifact were found
+     */
+    public Artifact getUniqueArtifact(String groupId, String artifactId, String type) {
+        return getUniqueArtifact(groupId, artifactId, type, null);
+    }
+
+    /**
+     * Returns the artifacts with the specified parameters.
+     *
+     * @param groupId the group id
+     * @param artifactId the artifact id
+     * @param type the type
+     * @return the artifacts or an empty set if no artifact were found
+     */
+    public Set<Artifact> getArtifacts(String groupId, String artifactId, String type) {
+        final Set<Artifact> result = new TreeSet<>();
+        for (Artifact a : artifacts) {
+            // If the groupId, the artifactId and if the
+            // artifact's type is known, then we have found a candidate.
+            if (a.getGroupId().equals(groupId)
+                    && a.getArtifactId().equals(artifactId)
+                    && artifactTypeMappingService.isMappedToType(type, a.getType())) {
+                result.add(a);
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingService.java b/src/main/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingService.java
index 3c11213..1e5b23d 100644
--- a/src/main/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingService.java
+++ b/src/main/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingService.java
@@ -1,178 +1,169 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import java.util.ArrayList;

-import java.util.HashMap;

-import java.util.List;

-import java.util.Map;

-

-import org.apache.maven.plugins.ear.EarModuleFactory;

-import org.apache.maven.plugins.ear.EarPluginException;

-import org.apache.maven.plugins.ear.UnknownArtifactTypeException;

-import org.codehaus.plexus.configuration.PlexusConfiguration;

-import org.codehaus.plexus.configuration.PlexusConfigurationException;

-

-/**

- * Allows to map custom artifact type to standard type.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ArtifactTypeMappingService

-{

-    static final String ARTIFACT_TYPE_MAPPING_ELEMENT = "artifactTypeMapping";

-

-    static final String TYPE_ATTRIBUTE = "type";

-

-    static final String MAPPING_ATTRIBUTE = "mapping";

-

-    // A standard type to a list of customType

-    private final Map<String, List<String>> typeMappings;

-

-    // The user-defined mapping for direct access

-    private final Map<String, String> customMappings;

-

-    /**

-     * Create an instance.

-     */

-    public ArtifactTypeMappingService()

-    {

-        this.typeMappings = new HashMap<>();

-        this.customMappings = new HashMap<>();

-        init();

-    }

-

-    /**

-     * @param plexusConfiguration {@link PlexusConfiguration}

-     * @throws EarPluginException {@link EarPluginException}

-     * @throws PlexusConfigurationException {@link PlexusConfigurationException}

-     */

-    public void configure( final PlexusConfiguration plexusConfiguration )

-        throws EarPluginException, PlexusConfigurationException

-    {

-

-        // No user defined configuration

-        if ( plexusConfiguration == null )

-        {

-            return;

-        }

-

-        // Inject users configuration

-        final PlexusConfiguration[] artifactTypeMappings =

-            plexusConfiguration.getChildren( ARTIFACT_TYPE_MAPPING_ELEMENT );

-        for ( PlexusConfiguration artifactTypeMapping : artifactTypeMappings )

-        {

-            final String customType = artifactTypeMapping.getAttribute( TYPE_ATTRIBUTE );

-            final String mapping = artifactTypeMapping.getAttribute( MAPPING_ATTRIBUTE );

-

-            if ( customType == null )

-            {

-                throw new EarPluginException( "Invalid artifact type mapping, type attribute should be set." );

-            }

-            else if ( mapping == null )

-            {

-                throw new EarPluginException( "Invalid artifact type mapping, mapping attribute should be set." );

-            }

-            else if ( !EarModuleFactory.isStandardArtifactType( mapping ) )

-            {

-                throw new EarPluginException( "Invalid artifact type mapping, mapping[" + mapping

-                    + "] must be a standard Ear artifact type[" + EarModuleFactory.getStandardArtifactTypes() + "]" );

-            }

-            else if ( customMappings.containsKey( customType ) )

-            {

-                throw new EarPluginException( "Invalid artifact type mapping, type[" + customType

-                    + "] is already registered." );

-            }

-            else

-            {

-                // Add the custom mapping

-                customMappings.put( customType, mapping );

-

-                // Register the custom mapping to its standard type

-                List<String> typeMapping = typeMappings.get( mapping );

-                typeMapping.add( customType );

-            }

-        }

-    }

-

-    /**

-     * Specify whether the {@code customType} could be mapped to the {@code standardType}.

-     * 

-     * @param standardType the standard type (ejb, jar, war, ...)

-     * @param customType a user-defined type

-     * @return true if the customType could be mapped to the standard type

-     */

-    public boolean isMappedToType( final String standardType, final String customType )

-    {

-        if ( !EarModuleFactory.isStandardArtifactType( standardType ) )

-        {

-            throw new IllegalStateException( "Artifact type[" + standardType + "] is not a standard Ear artifact type["

-                + EarModuleFactory.getStandardArtifactTypes() + "]" );

-        }

-        return this.typeMappings.get( standardType ).contains( customType );

-

-    }

-

-    /**

-     * Returns the standard type for the specified {@code type}. If the specified type is already a standard type, the

-     * orignal type is returned.

-     * 

-     * @param type a type

-     * @return the standard type (ejb, jar, war, ...) for this type

-     * @throws UnknownArtifactTypeException In case of missing mappings types.

-     */

-    public String getStandardType( final String type )

-        throws UnknownArtifactTypeException

-    {

-        if ( type == null )

-        {

-            throw new IllegalStateException( "custom type could not be null." );

-        }

-        else if ( EarModuleFactory.getStandardArtifactTypes().contains( type ) )

-        {

-            return type;

-        }

-        else if ( !customMappings.containsKey( type ) )

-        {

-            throw new UnknownArtifactTypeException( "Unknown artifact type[" + type + "]" );

-        }

-        else

-        {

-            return customMappings.get( type );

-        }

-    }

-

-    private void init()

-    {

-        // Initialize the typeMappings

-        typeMappings.clear();

-

-        // Clear the customMappings

-        customMappings.clear();

-

-        // Initialize the mapping with the standard artifact types

-        for ( String type : EarModuleFactory.getStandardArtifactTypes() )

-        {

-            List<String> typeMapping = new ArrayList<>();

-            typeMapping.add( type );

-            this.typeMappings.put( type, typeMapping );

-        }

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.plugins.ear.EarModuleFactory;
+import org.apache.maven.plugins.ear.EarPluginException;
+import org.apache.maven.plugins.ear.UnknownArtifactTypeException;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+/**
+ * Allows to map custom artifact type to standard type.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ArtifactTypeMappingService {
+    static final String ARTIFACT_TYPE_MAPPING_ELEMENT = "artifactTypeMapping";
+
+    static final String TYPE_ATTRIBUTE = "type";
+
+    static final String MAPPING_ATTRIBUTE = "mapping";
+
+    // A standard type to a list of customType
+    private final Map<String, List<String>> typeMappings;
+
+    // The user-defined mapping for direct access
+    private final Map<String, String> customMappings;
+
+    /**
+     * Create an instance.
+     */
+    public ArtifactTypeMappingService() {
+        this.typeMappings = new HashMap<>();
+        this.customMappings = new HashMap<>();
+        init();
+    }
+
+    /**
+     * @param plexusConfiguration {@link PlexusConfiguration}
+     * @throws EarPluginException {@link EarPluginException}
+     * @throws PlexusConfigurationException {@link PlexusConfigurationException}
+     */
+    public void configure(final PlexusConfiguration plexusConfiguration)
+            throws EarPluginException, PlexusConfigurationException {
+
+        // No user defined configuration
+        if (plexusConfiguration == null) {
+            return;
+        }
+
+        // Inject users configuration
+        final PlexusConfiguration[] artifactTypeMappings =
+                plexusConfiguration.getChildren(ARTIFACT_TYPE_MAPPING_ELEMENT);
+        for (PlexusConfiguration artifactTypeMapping : artifactTypeMappings) {
+            final String customType = artifactTypeMapping.getAttribute(TYPE_ATTRIBUTE);
+            final String mapping = artifactTypeMapping.getAttribute(MAPPING_ATTRIBUTE);
+
+            if (customType == null) {
+                throw new EarPluginException("Invalid artifact type mapping, type attribute should be set.");
+            } else if (mapping == null) {
+                throw new EarPluginException("Invalid artifact type mapping, mapping attribute should be set.");
+            } else if (!EarModuleFactory.isStandardArtifactType(mapping)) {
+                throw new EarPluginException(
+                        "Invalid artifact type mapping, mapping[" + mapping + "] must be a standard Ear artifact type["
+                                + EarModuleFactory.getStandardArtifactTypes() + "]");
+            } else if (customMappings.containsKey(customType)) {
+                throw new EarPluginException(
+                        "Invalid artifact type mapping, type[" + customType + "] is already registered.");
+            } else {
+                // Add the custom mapping
+                customMappings.put(customType, mapping);
+
+                // Register the custom mapping to its standard type
+                List<String> typeMapping = typeMappings.get(mapping);
+                typeMapping.add(customType);
+            }
+        }
+    }
+
+    /**
+     * Specify whether the {@code customType} could be mapped to the {@code standardType}.
+     *
+     * @param standardType the standard type (ejb, jar, war, ...)
+     * @param customType a user-defined type
+     * @return true if the customType could be mapped to the standard type
+     */
+    public boolean isMappedToType(final String standardType, final String customType) {
+        if (!EarModuleFactory.isStandardArtifactType(standardType)) {
+            throw new IllegalStateException("Artifact type[" + standardType + "] is not a standard Ear artifact type["
+                    + EarModuleFactory.getStandardArtifactTypes() + "]");
+        }
+        return this.typeMappings.get(standardType).contains(customType);
+    }
+
+    /**
+     * Returns the standard type for the specified {@code type}. If the specified type is already a standard type, the
+     * orignal type is returned.
+     *
+     * @param type a type
+     * @return the standard type (ejb, jar, war, ...) for this type
+     * @throws UnknownArtifactTypeException In case of missing mappings types.
+     */
+    public String getStandardType(final String type) throws UnknownArtifactTypeException {
+        if (type == null) {
+            throw new IllegalStateException("custom type could not be null.");
+        } else if (EarModuleFactory.getStandardArtifactTypes().contains(type)) {
+            return type;
+        } else if (!customMappings.containsKey(type)) {
+            throw new UnknownArtifactTypeException("Unknown artifact type[" + type + "]");
+        } else {
+            return customMappings.get(type);
+        }
+    }
+
+    private void init() {
+        // Initialize the typeMappings
+        typeMappings.clear();
+
+        // Clear the customMappings
+        customMappings.clear();
+
+        // Initialize the mapping with the standard artifact types
+        for (String type : EarModuleFactory.getStandardArtifactTypes()) {
+            List<String> typeMapping = new ArrayList<>();
+            typeMapping.add(type);
+            this.typeMappings.put(type, typeMapping);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/util/EarMavenArchiver.java b/src/main/java/org/apache/maven/plugins/ear/util/EarMavenArchiver.java
index e813bef..a2cad80 100644
--- a/src/main/java/org/apache/maven/plugins/ear/util/EarMavenArchiver.java
+++ b/src/main/java/org/apache/maven/plugins/ear/util/EarMavenArchiver.java
@@ -1,146 +1,146 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import java.util.List;

-import java.util.Set;

-

-import org.apache.maven.archiver.MavenArchiveConfiguration;

-import org.apache.maven.archiver.MavenArchiver;

-import org.apache.maven.artifact.DependencyResolutionRequiredException;

-import org.apache.maven.execution.MavenSession;

-import org.apache.maven.plugins.ear.EarModule;

-import org.apache.maven.project.MavenProject;

-import org.codehaus.plexus.archiver.jar.Manifest;

-import org.codehaus.plexus.archiver.jar.ManifestException;

-

-/**

- * A custom {@link MavenArchiver} implementation that takes care of setting the right classpath value according to the

- * actual path of bundled files.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarMavenArchiver

-    extends MavenArchiver

-{

-    /**

-     * {@code Class-Path}.

-     */

-    public static final String CLASS_PATH_KEY = "Class-Path";

-

-    private final List<EarModule> earModules;

-

-    /**

-     * Creates an instance with the ear modules that will be packaged in the EAR archive.

-     * 

-     * @param earModules the intitialized list of ear modules

-     */

-    public EarMavenArchiver( List<EarModule> earModules )

-    {

-        this.earModules = earModules;

-    }

-

-    /**

-     * @param project {@link MavenProject}

-     * @param config {@link MavenArchiveConfiguration}

-     * @throws ManifestException in case of an error

-     * @throws DependencyResolutionRequiredException in case of an resolution error.

-     * @return Manifest

-     * @deprecated

-     */

-    public Manifest getManifest( MavenProject project, MavenArchiveConfiguration config )

-        throws ManifestException, DependencyResolutionRequiredException

-    {

-        return this.getManifest( null, project, config );

-    }

-

-    /** {@inheritDoc} */

-    public Manifest getManifest( MavenSession session, MavenProject project, MavenArchiveConfiguration config )

-        throws ManifestException, DependencyResolutionRequiredException

-    {

-        final Manifest manifest = super.getManifest( session, project, config );

-        if ( config.getManifest().isAddClasspath() )

-        {

-            String earManifestClassPathEntry = generateClassPathEntry( config.getManifest().getClasspathPrefix() );

-            // Class-path can be customized. Let's make sure we don't overwrite this

-            // with our custom change!

-            final String userSuppliedClassPathEntry = getUserSuppliedClassPathEntry( config );

-            if ( userSuppliedClassPathEntry != null )

-            {

-                earManifestClassPathEntry = userSuppliedClassPathEntry + " " + earManifestClassPathEntry;

-            }

-

-            // Overwrite the existing one, if any

-            final Manifest.Attribute classPathAttr = manifest.getMainSection().getAttribute( CLASS_PATH_KEY );

-            if ( classPathAttr != null )

-            {

-                classPathAttr.setValue( earManifestClassPathEntry );

-            }

-            else

-            {

-                final Manifest.Attribute attr = new Manifest.Attribute( CLASS_PATH_KEY, earManifestClassPathEntry );

-                manifest.addConfiguredAttribute( attr );

-            }

-        }

-        return manifest;

-    }

-

-    /**

-     * Generates the {@code Class-Path} entry of the manifest according to the list of ear modules.

-     * 

-     * @param classPathPrefix the classpath prefix to use

-     * @return the {@code Class-Path} entry

-     */

-    protected String generateClassPathEntry( String classPathPrefix )

-    {

-        final StringBuilder classpath = new StringBuilder();

-        for ( final EarModule earModule : earModules )

-        {

-            if ( !earModule.isExcluded() )

-            {

-                classpath.append( classPathPrefix ).append( earModule.getUri() ).append( " " );

-            }

-        }

-        return classpath.toString().trim();

-    }

-

-    /**

-     * @param config {@link MavenArchiveConfiguration}

-     * @return The class path entry.

-     */

-    protected String getUserSuppliedClassPathEntry( MavenArchiveConfiguration config )

-    {

-        if ( config.getManifestEntries() != null )

-        {

-            final Set<String> keys = config.getManifestEntries().keySet();

-            for ( String key : keys )

-            {

-                String value = config.getManifestEntries().get( key );

-                if ( "Class-Path".equals( key ) && value != null )

-                {

-                    return value;

-

-                }

-

-            }

-        }

-        return null;

-    }

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugins.ear.EarModule;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.jar.Manifest;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+
+/**
+ * A custom {@link MavenArchiver} implementation that takes care of setting the right classpath value according to the
+ * actual path of bundled files.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarMavenArchiver extends MavenArchiver {
+    /**
+     * {@code Class-Path}.
+     */
+    public static final String CLASS_PATH_KEY = "Class-Path";
+
+    private final List<EarModule> earModules;
+
+    /**
+     * Creates an instance with the ear modules that will be packaged in the EAR archive.
+     *
+     * @param earModules the intitialized list of ear modules
+     */
+    public EarMavenArchiver(List<EarModule> earModules) {
+        this.earModules = earModules;
+    }
+
+    /**
+     * @param project {@link MavenProject}
+     * @param config {@link MavenArchiveConfiguration}
+     * @throws ManifestException in case of an error
+     * @throws DependencyResolutionRequiredException in case of an resolution error.
+     * @return Manifest
+     * @deprecated
+     */
+    public Manifest getManifest(MavenProject project, MavenArchiveConfiguration config)
+            throws ManifestException, DependencyResolutionRequiredException {
+        return this.getManifest(null, project, config);
+    }
+
+    /** {@inheritDoc} */
+    public Manifest getManifest(MavenSession session, MavenProject project, MavenArchiveConfiguration config)
+            throws ManifestException, DependencyResolutionRequiredException {
+        final Manifest manifest = super.getManifest(session, project, config);
+        if (config.getManifest().isAddClasspath()) {
+            String earManifestClassPathEntry =
+                    generateClassPathEntry(config.getManifest().getClasspathPrefix());
+            // Class-path can be customized. Let's make sure we don't overwrite this
+            // with our custom change!
+            final String userSuppliedClassPathEntry = getUserSuppliedClassPathEntry(config);
+            if (userSuppliedClassPathEntry != null) {
+                earManifestClassPathEntry = userSuppliedClassPathEntry + " " + earManifestClassPathEntry;
+            }
+
+            // Overwrite the existing one, if any
+            final Manifest.Attribute classPathAttr = manifest.getMainSection().getAttribute(CLASS_PATH_KEY);
+            if (classPathAttr != null) {
+                classPathAttr.setValue(earManifestClassPathEntry);
+            } else {
+                final Manifest.Attribute attr = new Manifest.Attribute(CLASS_PATH_KEY, earManifestClassPathEntry);
+                manifest.addConfiguredAttribute(attr);
+            }
+        }
+        return manifest;
+    }
+
+    /**
+     * Generates the {@code Class-Path} entry of the manifest according to the list of ear modules.
+     *
+     * @param classPathPrefix the classpath prefix to use
+     * @return the {@code Class-Path} entry
+     */
+    protected String generateClassPathEntry(String classPathPrefix) {
+        final StringBuilder classpath = new StringBuilder();
+        for (final EarModule earModule : earModules) {
+            if (!earModule.isExcluded()) {
+                classpath.append(classPathPrefix).append(earModule.getUri()).append(" ");
+            }
+        }
+        return classpath.toString().trim();
+    }
+
+    /**
+     * @param config {@link MavenArchiveConfiguration}
+     * @return The class path entry.
+     */
+    protected String getUserSuppliedClassPathEntry(MavenArchiveConfiguration config) {
+        if (config.getManifestEntries() != null) {
+            final Set<String> keys = config.getManifestEntries().keySet();
+            for (String key : keys) {
+                String value = config.getManifestEntries().get(key);
+                if ("Class-Path".equals(key) && value != null) {
+                    return value;
+                }
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/util/InvalidJavaEEVersion.java b/src/main/java/org/apache/maven/plugins/ear/util/InvalidJavaEEVersion.java
index f5c886c..f65a6a2 100644
--- a/src/main/java/org/apache/maven/plugins/ear/util/InvalidJavaEEVersion.java
+++ b/src/main/java/org/apache/maven/plugins/ear/util/InvalidJavaEEVersion.java
@@ -1,58 +1,72 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import org.apache.maven.plugin.MojoExecutionException;

-

-/**

- * @author Stephane Nicoll

- */

-public class InvalidJavaEEVersion

-    extends MojoExecutionException

-{

-

-    /**

-     * 

-     */

-    private static final long serialVersionUID = 3189028517550801372L;

-

-    /**

-     * The invalid version

-     */

-    private final String invalidVersion;

-

-    /**

-     * @param message The message for the error

-     * @param invalidVersion The invalid version.

-     */

-    public InvalidJavaEEVersion( String message, String invalidVersion )

-    {

-        super( message );

-        this.invalidVersion = invalidVersion;

-    }

-

-    /**

-     * @return The invalid version.

-     */

-    public String getInvalidVersion()

-    {

-        return invalidVersion;

-    }

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class InvalidJavaEEVersion extends MojoExecutionException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 3189028517550801372L;
+
+    /**
+     * The invalid version
+     */
+    private final String invalidVersion;
+
+    /**
+     * @param message The message for the error
+     * @param invalidVersion The invalid version.
+     */
+    public InvalidJavaEEVersion(String message, String invalidVersion) {
+        super(message);
+        this.invalidVersion = invalidVersion;
+    }
+
+    /**
+     * @return The invalid version.
+     */
+    public String getInvalidVersion() {
+        return invalidVersion;
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/ear/util/JavaEEVersion.java b/src/main/java/org/apache/maven/plugins/ear/util/JavaEEVersion.java
index 8e6173f..432d756 100644
--- a/src/main/java/org/apache/maven/plugins/ear/util/JavaEEVersion.java
+++ b/src/main/java/org/apache/maven/plugins/ear/util/JavaEEVersion.java
@@ -1,216 +1,218 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import java.util.HashMap;

-import java.util.Map;

-

-/**

- * Represents the supported JavaEE version.

- * 

- * @author Stephane Nicoll

- */

-public class JavaEEVersion

-    implements Comparable<JavaEEVersion>

-{

-

-    private static final String VERSION_1_3 = "1.3";

-

-    private static final String VERSION_1_4 = "1.4";

-

-    private static final String VERSION_5 = "5";

-

-    private static final String VERSION_6 = "6";

-

-    private static final String VERSION_7 = "7";

-    

-    private static final String VERSION_8 = "8";

-

-    private static final String VERSION_9 = "9";

-

-    private static final String VERSION_10 = "10";

-

-    private static final Map<String, JavaEEVersion> VERSION_MAP = new HashMap<>();

-

-    /**

-     * Represents the J2EE 1.3 version.

-     */

-    public static final JavaEEVersion ONE_DOT_THREE = new JavaEEVersion( Integer.valueOf( 0 ), VERSION_1_3 );

-

-    /**

-     * Represents the J2EE 1.4 version.

-     */

-    public static final JavaEEVersion ONE_DOT_FOUR = new JavaEEVersion( Integer.valueOf( 1 ), VERSION_1_4 );

-

-    /**

-     * Represents the JavaEE 5 version.

-     */

-    public static final JavaEEVersion FIVE = new JavaEEVersion( Integer.valueOf( 2 ), VERSION_5 );

-

-    /**

-     * Represents the JavaEE 6 version.

-     */

-    public static final JavaEEVersion SIX = new JavaEEVersion( Integer.valueOf( 3 ), VERSION_6 );

-

-    /**

-     * Represents the JavaEE 7 version.

-     */

-    public static final JavaEEVersion SEVEN = new JavaEEVersion( Integer.valueOf( 4 ), VERSION_7 );

-

-    /**

-     * Represents the JavaEE 8 version.

-     */

-    public static final JavaEEVersion EIGHT = new JavaEEVersion( Integer.valueOf( 5 ), VERSION_8 );

-

-    /**

-     * Represents the JakartaEE 9 version.

-     */

-    public static final JavaEEVersion NINE = new JavaEEVersion( Integer.valueOf( 6 ), VERSION_9 );

-

-    /**

-     * Represents the JakartaEE 10 version.

-     */

-    public static final JavaEEVersion TEN = new JavaEEVersion( Integer.valueOf( 7 ), VERSION_10 );

-

-    private final Integer index;

-

-    private final String version;

-

-    private JavaEEVersion( Integer index, String version )

-    {

-        this.index = index;

-        this.version = version;

-        VERSION_MAP.put( version, this );

-    }

-

-    /**

-     * @param paramVersion The version.

-     * @return {@link JavaEEVersion}

-     * @throws InvalidJavaEEVersion in case of a wrong version.

-     */

-    public static JavaEEVersion getJavaEEVersion( String paramVersion )

-        throws InvalidJavaEEVersion

-    {

-        if ( !isValid( paramVersion ) )

-        {

-            throw new InvalidJavaEEVersion( "Invalid version [" + paramVersion + "]", paramVersion );

-        }

-        return VERSION_MAP.get( paramVersion );

-    }

-

-    /**

-     * Returns the version as a string.

-     * 

-     * @return the version string

-     */

-    public String getVersion()

-    {

-        return version;

-    }

-

-    /**

-     * Specifies if this version is greater or equal to the specified version.

-     * 

-     * @param paramVersion the version to check

-     * @return true if this version is greater or equal to {@code version}

-     */

-    public boolean ge( JavaEEVersion paramVersion )

-    {

-        return this.compareTo( paramVersion ) >= 0;

-    }

-

-    /**

-     * Specifies if this version is greater than the specified version.

-     * 

-     * @param paramVersion the version to check

-     * @return true if this version is greater to {@code version}

-     */

-    public boolean gt( JavaEEVersion paramVersion )

-    {

-        return this.compareTo( paramVersion ) > 0;

-    }

-

-    /**

-     * Specifies if this version is equal to the specified version.

-     * 

-     * @param paramVersion the version to check

-     * @return true if this version is equal to {@code version}

-     */

-    public boolean eq( JavaEEVersion paramVersion )

-    {

-        return this.compareTo( paramVersion ) == 0;

-    }

-

-    /**

-     * Specifies if this version is less or equal to the specified version.

-     * 

-     * @param paramVersion the version to check

-     * @return true if this version is less or equal to {@code version}

-     */

-    public boolean le( JavaEEVersion paramVersion )

-    {

-        return this.compareTo( paramVersion ) <= 0;

-    }

-

-    /**

-     * Specifies if this version is less than the specified version.

-     * 

-     * @param paramVersion the version to check

-     * @return true if this version is less or equal to {@code version}

-     */

-    public boolean lt( JavaEEVersion paramVersion )

-    {

-        return this.compareTo( paramVersion ) < 0;

-    }

-

-    /**

-     * Checks if the specified version string is valid.

-     * 

-     * @param paramVersion the version string to check

-     * @return {@code true} if the version is valid

-     */

-    private static boolean isValid( String paramVersion )

-    {

-        if ( paramVersion == null )

-        {

-            throw new NullPointerException( "version cannot be null." );

-        }

-        // @formatter:off

-        return VERSION_1_3.equals( paramVersion ) 

-            || VERSION_1_4.equals( paramVersion )

-            || VERSION_5.equals( paramVersion ) 

-            || VERSION_6.equals( paramVersion ) 

-            || VERSION_7.equals( paramVersion )

-            || VERSION_8.equals( paramVersion )

-            || VERSION_9.equals( paramVersion )

-            || VERSION_10.equals( paramVersion );

-        // @formatter:on

-    }

-

-    /** {@inheritDoc} */

-    public int compareTo( JavaEEVersion otherVersion )

-    {

-        if ( otherVersion == null )

-        {

-            throw new NullPointerException( "other object to compare to could not be null." );

-        }

-        return index.compareTo( otherVersion.index );

-    }

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents the supported JavaEE version.
+ *
+ * @author Stephane Nicoll
+ */
+public class JavaEEVersion implements Comparable<JavaEEVersion> {
+
+    private static final String VERSION_1_3 = "1.3";
+
+    private static final String VERSION_1_4 = "1.4";
+
+    private static final String VERSION_5 = "5";
+
+    private static final String VERSION_6 = "6";
+
+    private static final String VERSION_7 = "7";
+
+    private static final String VERSION_8 = "8";
+
+    private static final String VERSION_9 = "9";
+
+    private static final String VERSION_10 = "10";
+
+    private static final Map<String, JavaEEVersion> VERSION_MAP = new HashMap<>();
+
+    /**
+     * Represents the J2EE 1.3 version.
+     */
+    public static final JavaEEVersion ONE_DOT_THREE = new JavaEEVersion(Integer.valueOf(0), VERSION_1_3);
+
+    /**
+     * Represents the J2EE 1.4 version.
+     */
+    public static final JavaEEVersion ONE_DOT_FOUR = new JavaEEVersion(Integer.valueOf(1), VERSION_1_4);
+
+    /**
+     * Represents the JavaEE 5 version.
+     */
+    public static final JavaEEVersion FIVE = new JavaEEVersion(Integer.valueOf(2), VERSION_5);
+
+    /**
+     * Represents the JavaEE 6 version.
+     */
+    public static final JavaEEVersion SIX = new JavaEEVersion(Integer.valueOf(3), VERSION_6);
+
+    /**
+     * Represents the JavaEE 7 version.
+     */
+    public static final JavaEEVersion SEVEN = new JavaEEVersion(Integer.valueOf(4), VERSION_7);
+
+    /**
+     * Represents the JavaEE 8 version.
+     */
+    public static final JavaEEVersion EIGHT = new JavaEEVersion(Integer.valueOf(5), VERSION_8);
+
+    /**
+     * Represents the JakartaEE 9 version.
+     */
+    public static final JavaEEVersion NINE = new JavaEEVersion(Integer.valueOf(6), VERSION_9);
+
+    /**
+     * Represents the JakartaEE 10 version.
+     */
+    public static final JavaEEVersion TEN = new JavaEEVersion(Integer.valueOf(7), VERSION_10);
+
+    private final Integer index;
+
+    private final String version;
+
+    private JavaEEVersion(Integer index, String version) {
+        this.index = index;
+        this.version = version;
+        VERSION_MAP.put(version, this);
+    }
+
+    /**
+     * @param paramVersion The version.
+     * @return {@link JavaEEVersion}
+     * @throws InvalidJavaEEVersion in case of a wrong version.
+     */
+    public static JavaEEVersion getJavaEEVersion(String paramVersion) throws InvalidJavaEEVersion {
+        if (!isValid(paramVersion)) {
+            throw new InvalidJavaEEVersion("Invalid version [" + paramVersion + "]", paramVersion);
+        }
+        return VERSION_MAP.get(paramVersion);
+    }
+
+    /**
+     * Returns the version as a string.
+     *
+     * @return the version string
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Specifies if this version is greater or equal to the specified version.
+     *
+     * @param paramVersion the version to check
+     * @return true if this version is greater or equal to {@code version}
+     */
+    public boolean ge(JavaEEVersion paramVersion) {
+        return this.compareTo(paramVersion) >= 0;
+    }
+
+    /**
+     * Specifies if this version is greater than the specified version.
+     *
+     * @param paramVersion the version to check
+     * @return true if this version is greater to {@code version}
+     */
+    public boolean gt(JavaEEVersion paramVersion) {
+        return this.compareTo(paramVersion) > 0;
+    }
+
+    /**
+     * Specifies if this version is equal to the specified version.
+     *
+     * @param paramVersion the version to check
+     * @return true if this version is equal to {@code version}
+     */
+    public boolean eq(JavaEEVersion paramVersion) {
+        return this.compareTo(paramVersion) == 0;
+    }
+
+    /**
+     * Specifies if this version is less or equal to the specified version.
+     *
+     * @param paramVersion the version to check
+     * @return true if this version is less or equal to {@code version}
+     */
+    public boolean le(JavaEEVersion paramVersion) {
+        return this.compareTo(paramVersion) <= 0;
+    }
+
+    /**
+     * Specifies if this version is less than the specified version.
+     *
+     * @param paramVersion the version to check
+     * @return true if this version is less or equal to {@code version}
+     */
+    public boolean lt(JavaEEVersion paramVersion) {
+        return this.compareTo(paramVersion) < 0;
+    }
+
+    /**
+     * Checks if the specified version string is valid.
+     *
+     * @param paramVersion the version string to check
+     * @return {@code true} if the version is valid
+     */
+    private static boolean isValid(String paramVersion) {
+        if (paramVersion == null) {
+            throw new NullPointerException("version cannot be null.");
+        }
+        // @formatter:off
+        return VERSION_1_3.equals(paramVersion)
+                || VERSION_1_4.equals(paramVersion)
+                || VERSION_5.equals(paramVersion)
+                || VERSION_6.equals(paramVersion)
+                || VERSION_7.equals(paramVersion)
+                || VERSION_8.equals(paramVersion)
+                || VERSION_9.equals(paramVersion)
+                || VERSION_10.equals(paramVersion);
+        // @formatter:on
+    }
+
+    /** {@inheritDoc} */
+    public int compareTo(JavaEEVersion otherVersion) {
+        if (otherVersion == null) {
+            throw new NullPointerException("other object to compare to could not be null.");
+        }
+        return index.compareTo(otherVersion.index);
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/AbstractEarTestBase.java b/src/test/java/org/apache/maven/plugins/ear/AbstractEarTestBase.java
index 31c312e..5f1da31 100644
--- a/src/test/java/org/apache/maven/plugins/ear/AbstractEarTestBase.java
+++ b/src/test/java/org/apache/maven/plugins/ear/AbstractEarTestBase.java
@@ -1,73 +1,90 @@
-package org.apache.maven.plugins.ear;

-

-import java.util.Objects;

-import java.util.Set;

-import java.util.TreeSet;

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.artifact.DefaultArtifact;

-import org.apache.maven.plugins.ear.stub.ArtifactHandlerTestStub;

-

-/*

- * 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.

- */

-

-/**

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public abstract class AbstractEarTestBase

-{

-

-    protected static final String DEFAULT_GROUPID = "eartest";

-

-    private static final String DEFAULT_TYPE = "jar";

-

-    protected void setUri( EarModule module, String uri )

-    {

-        ( (AbstractEarModule) module ).setUri( uri );

-    }

-

-    protected Set<Artifact> createArtifacts( String[] artifactIds )

-    {

-        return createArtifacts( artifactIds, null );

-    }

-

-    protected Set<Artifact> createArtifacts( String[] artifactIds, String[] classifiers )

-    {

-        Set<Artifact> result = new TreeSet<>();

-        ArtifactHandlerTestStub artifactHandler = new ArtifactHandlerTestStub( "jar" );

-        for ( int i = 0; i < artifactIds.length; i++ )

-        {

-            String artifactId = artifactIds[i];

-            String classifier = classifiers == null ? null : classifiers[i];

-            Artifact artifactTestStub = new DefaultArtifact(

-                DEFAULT_GROUPID, artifactId, "1.0", "compile", DEFAULT_TYPE, classifier, artifactHandler );

-            result.add( artifactTestStub );

-        }

-        return result;

-    }

-

-    protected Artifact createArtifact( String artifactId, String type )

-    {

-        Artifact artifactTestStub = new DefaultArtifact(

-            DEFAULT_GROUPID, artifactId, "1.0", "compile", Objects.toString( type, DEFAULT_TYPE ),

-            null, new ArtifactHandlerTestStub( "jar" ) );

-        

-        return artifactTestStub;

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.plugins.ear.stub.ArtifactHandlerTestStub;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractEarTestBase {
+
+    protected static final String DEFAULT_GROUPID = "eartest";
+
+    private static final String DEFAULT_TYPE = "jar";
+
+    protected void setUri(EarModule module, String uri) {
+        ((AbstractEarModule) module).setUri(uri);
+    }
+
+    protected Set<Artifact> createArtifacts(String[] artifactIds) {
+        return createArtifacts(artifactIds, null);
+    }
+
+    protected Set<Artifact> createArtifacts(String[] artifactIds, String[] classifiers) {
+        Set<Artifact> result = new TreeSet<>();
+        ArtifactHandlerTestStub artifactHandler = new ArtifactHandlerTestStub("jar");
+        for (int i = 0; i < artifactIds.length; i++) {
+            String artifactId = artifactIds[i];
+            String classifier = classifiers == null ? null : classifiers[i];
+            Artifact artifactTestStub = new DefaultArtifact(
+                    DEFAULT_GROUPID, artifactId, "1.0", "compile", DEFAULT_TYPE, classifier, artifactHandler);
+            result.add(artifactTestStub);
+        }
+        return result;
+    }
+
+    protected Artifact createArtifact(String artifactId, String type) {
+        Artifact artifactTestStub = new DefaultArtifact(
+                DEFAULT_GROUPID,
+                artifactId,
+                "1.0",
+                "compile",
+                Objects.toString(type, DEFAULT_TYPE),
+                null,
+                new ArtifactHandlerTestStub("jar"));
+
+        return artifactTestStub;
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/EarModuleTest.java b/src/test/java/org/apache/maven/plugins/ear/EarModuleTest.java
index 8acb18b..926eef5 100644
--- a/src/test/java/org/apache/maven/plugins/ear/EarModuleTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/EarModuleTest.java
@@ -1,46 +1,62 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertNull;

-

-import org.junit.Test;

-

-/**

- * Ear module test case.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarModuleTest

-{

-

-    @Test

-    public void testCleanArchivePath()

-    {

-        assertEquals( "APP-INF/lib/", AbstractEarModule.cleanArchivePath( "APP-INF/lib" ) );

-        assertEquals( "APP-INF/lib/", AbstractEarModule.cleanArchivePath( "APP-INF/lib/" ) );

-        assertEquals( "APP-INF/lib/", AbstractEarModule.cleanArchivePath( "/APP-INF/lib" ) );

-        assertEquals( "APP-INF/lib/", AbstractEarModule.cleanArchivePath( "/APP-INF/lib/" ) );

-        assertEquals( "", AbstractEarModule.cleanArchivePath( "/" ) );

-        assertEquals( "", AbstractEarModule.cleanArchivePath( "" ) );

-        assertNull( AbstractEarModule.cleanArchivePath( null ) );

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Ear module test case.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarModuleTest {
+
+    @Test
+    public void testCleanArchivePath() {
+        assertEquals("APP-INF/lib/", AbstractEarModule.cleanArchivePath("APP-INF/lib"));
+        assertEquals("APP-INF/lib/", AbstractEarModule.cleanArchivePath("APP-INF/lib/"));
+        assertEquals("APP-INF/lib/", AbstractEarModule.cleanArchivePath("/APP-INF/lib"));
+        assertEquals("APP-INF/lib/", AbstractEarModule.cleanArchivePath("/APP-INF/lib/"));
+        assertEquals("", AbstractEarModule.cleanArchivePath("/"));
+        assertEquals("", AbstractEarModule.cleanArchivePath(""));
+        assertNull(AbstractEarModule.cleanArchivePath(null));
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/EnvEntryTest.java b/src/test/java/org/apache/maven/plugins/ear/EnvEntryTest.java
index f1ba390..f58d6a8 100644
--- a/src/test/java/org/apache/maven/plugins/ear/EnvEntryTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/EnvEntryTest.java
@@ -1,100 +1,107 @@
-package org.apache.maven.plugins.ear;

-

-/*

- * 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.

- */

-

-import org.junit.Test;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertNotNull;

-

-/**

- * @author Stephane Nicoll

- */

-public class EnvEntryTest

-{

-

-    public static final String DESCRIPTION = "description";

-

-    public static final String NAME = "name";

-

-    public static final String TYPE = Integer.class.getName();

-

-    public static final String VALUE = "34";

-

-    public static final String LOOKUP_NAME = "lookupName";

-

-    @Test

-    public void createComplete()

-    {

-        final EnvEntry envEntry = new EnvEntry( DESCRIPTION, NAME, TYPE, VALUE, LOOKUP_NAME );

-        assertEnvEntry( envEntry, DESCRIPTION, NAME, TYPE, VALUE, LOOKUP_NAME );

-    }

-

-    @Test

-    public void createWithoutTypeButValue()

-    {

-        final EnvEntry envEntry = new EnvEntry( null, NAME, null, VALUE, LOOKUP_NAME );

-        assertEnvEntry( envEntry, null, NAME, null, VALUE, LOOKUP_NAME );

-    }

-

-    @Test( expected = IllegalArgumentException.class )

-    public void createWithoutName()

-    {

-        new EnvEntry( DESCRIPTION, null, TYPE, VALUE, LOOKUP_NAME );

-

-    }

-

-    @Test( expected = IllegalArgumentException.class )

-    public void createWithEmptyName()

-    {

-        new EnvEntry( DESCRIPTION, "", TYPE, VALUE, LOOKUP_NAME );

-    }

-

-    @Test( expected = IllegalArgumentException.class )

-    public void createWithNullTypeAndNoValue()

-    {

-        new EnvEntry( DESCRIPTION, NAME, null, null, LOOKUP_NAME );

-    }

-

-    @Test( expected = IllegalArgumentException.class )

-    public void createWithEmptyTypeAndNoValue()

-    {

-        new EnvEntry( DESCRIPTION, NAME, "", null, LOOKUP_NAME );

-    }

-

-    @Test

-    public void createWithEmptyLookupName()

-    {

-        new EnvEntry( DESCRIPTION, NAME, TYPE, VALUE, null );

-    }

-

-    private void assertEnvEntry( EnvEntry actual, String description, String name, String type, String value,

-                                 String lookupName )

-    {

-        assertNotNull( "Env entry could not be null", actual );

-        assertNotNull( "ToString could not be null", actual.toString() );

-        assertEquals( "Wrong env entry description for [" + actual + "]", description, actual.getDescription() );

-        assertEquals( "Wrong env entry name for [" + actual + "]", name, actual.getName() );

-        assertEquals( "Wrong env entry type for [" + actual + "]", type, actual.getType() );

-        assertEquals( "Wrong env entry value for [" + actual + "]", value, actual.getValue() );

-        assertEquals( "Wrong env entry value for [" + actual + "]", lookupName, actual.getLookupName() );

-

-    }

-}

+/*
+ * 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.maven.plugins.ear;
+
+/*
+ * 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.
+ */
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class EnvEntryTest {
+
+    public static final String DESCRIPTION = "description";
+
+    public static final String NAME = "name";
+
+    public static final String TYPE = Integer.class.getName();
+
+    public static final String VALUE = "34";
+
+    public static final String LOOKUP_NAME = "lookupName";
+
+    @Test
+    public void createComplete() {
+        final EnvEntry envEntry = new EnvEntry(DESCRIPTION, NAME, TYPE, VALUE, LOOKUP_NAME);
+        assertEnvEntry(envEntry, DESCRIPTION, NAME, TYPE, VALUE, LOOKUP_NAME);
+    }
+
+    @Test
+    public void createWithoutTypeButValue() {
+        final EnvEntry envEntry = new EnvEntry(null, NAME, null, VALUE, LOOKUP_NAME);
+        assertEnvEntry(envEntry, null, NAME, null, VALUE, LOOKUP_NAME);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void createWithoutName() {
+        new EnvEntry(DESCRIPTION, null, TYPE, VALUE, LOOKUP_NAME);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void createWithEmptyName() {
+        new EnvEntry(DESCRIPTION, "", TYPE, VALUE, LOOKUP_NAME);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void createWithNullTypeAndNoValue() {
+        new EnvEntry(DESCRIPTION, NAME, null, null, LOOKUP_NAME);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void createWithEmptyTypeAndNoValue() {
+        new EnvEntry(DESCRIPTION, NAME, "", null, LOOKUP_NAME);
+    }
+
+    @Test
+    public void createWithEmptyLookupName() {
+        new EnvEntry(DESCRIPTION, NAME, TYPE, VALUE, null);
+    }
+
+    private void assertEnvEntry(
+            EnvEntry actual, String description, String name, String type, String value, String lookupName) {
+        assertNotNull("Env entry could not be null", actual);
+        assertNotNull("ToString could not be null", actual.toString());
+        assertEquals("Wrong env entry description for [" + actual + "]", description, actual.getDescription());
+        assertEquals("Wrong env entry name for [" + actual + "]", name, actual.getName());
+        assertEquals("Wrong env entry type for [" + actual + "]", type, actual.getType());
+        assertEquals("Wrong env entry value for [" + actual + "]", value, actual.getValue());
+        assertEquals("Wrong env entry value for [" + actual + "]", lookupName, actual.getLookupName());
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java b/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
index b3c6cd1..bf09158 100644
--- a/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
+++ b/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
@@ -1,652 +1,625 @@
-package org.apache.maven.plugins.ear.it;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.io.FilenameFilter;

-import java.io.IOException;

-import java.io.InputStream;

-import java.util.ArrayList;

-import java.util.Arrays;

-import java.util.List;

-import java.util.Properties;

-import java.util.jar.JarFile;

-import java.util.jar.JarInputStream;

-import java.util.jar.Manifest;

-import java.util.zip.ZipEntry;

-

-import javax.xml.parsers.DocumentBuilder;

-import javax.xml.parsers.DocumentBuilderFactory;

-import javax.xml.parsers.ParserConfigurationException;

-

-import junit.framework.TestCase;

-

-import org.apache.maven.plugins.ear.util.ResourceEntityResolver;

-import org.apache.maven.shared.verifier.VerificationException;

-import org.apache.maven.shared.verifier.Verifier;

-import org.apache.maven.shared.verifier.util.ResourceExtractor;

-import org.custommonkey.xmlunit.Diff;

-import org.custommonkey.xmlunit.XMLAssert;

-import org.junit.Assert;

-import org.xml.sax.SAXException;

-import org.xml.sax.helpers.DefaultHandler;

-

-/**

- * Base class for ear test cases.

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public abstract class AbstractEarPluginIT

-    extends TestCase

-{

-

-    private final String FINAL_NAME_PREFIX = "maven-ear-plugin-test-";

-

-    private final String FINAL_NAME_SUFFIX = "-99.0";

-

-    /**

-     * The base directory.

-     */

-    private File basedir;

-

-    private File settingsFile = new File( getBasedir().getAbsolutePath(), "target/test-classes/settings.xml" );

-

-    /**

-     * Execute the EAR plugin for the specified project.

-     * 

-     * @param projectName the name of the project

-     * @param expectNoError true/false

-     * @param cleanBeforeExecute call clean plugin before execution

-     * @return the base directory of the project

-     */

-    protected File executeMojo( final String projectName, boolean expectNoError,

-                                boolean cleanBeforeExecute ) throws VerificationException, IOException

-    {

-        System.out.println( "  Building: " + projectName );

-

-        File testDir = getTestDir( projectName );

-        Verifier verifier = new Verifier( testDir.getAbsolutePath() );

-        verifier.setAutoclean( cleanBeforeExecute );

-        // Let's add alternate settings.xml setting so that the latest dependencies are used

-        String localRepo = System.getProperty( "localRepositoryPath" );

-        verifier.setLocalRepo( localRepo );

-

-        verifier.addCliArguments( "-s", settingsFile.getAbsolutePath() );//

-        verifier.addCliArgument( "-X" );

-        verifier.addCliArgument( "package" );

-

-        // On linux and MacOS X, an exception is thrown if a build failure occurs underneath

-        try

-        {

-            verifier.execute();

-        }

-        catch ( VerificationException e )

-        {

-            // @TODO needs to be handled nicely in the verifier

-            if ( expectNoError || !e.getMessage().contains( "Exit code was non-zero" ) )

-            {

-                throw e;

-            }

-        }

-

-        // If no error is expected make sure that error logs are free

-        if ( expectNoError )

-        {

-            verifier.verifyErrorFreeLog();

-        }

-        return testDir;

-    }

-

-    /**

-     * Execute the EAR plugin for the specified project.

-     * 

-     * @param projectName the name of the project

-     * @return the base directory of the project

-     */

-    protected File executeMojo( final String projectName )

-        throws VerificationException, IOException

-    {

-        return executeMojo( projectName, true, true );

-    }

-

-    /**

-     * Executes the specified projects and asserts the given artifacts. Asserts the deployment descriptors are valid.

-     * Asserts Class-Path entry of manifest of EAR modules.

-     *

-     * @param projectName the project to test

-     * @param earModuleName the name of 1st level EAR module in multi-module project or {@code null}

-     *                      if project is single-module

-     * @param expectedArtifacts the list of artifacts to be found in the EAR archive

-     * @param artifactsDirectory whether the artifact from {@code expectedArtifacts} list is an exploded or not

-     * @param artifactsToValidateManifest the list of EAR archive artifacts to validate Class-Path entry of artifact

-     *                                    manifest or {@code null} if there is no need to validate Class-Path entry

-     * @param artifactsToValidateManifestDirectory whether the artifact from {@code artifactsToValidateManifest} list is

-     *                                             an exploded or not, can be {@code null} if

-     *                                             {@code artifactsToValidateManifest} is {@code null}

-     * @param expectedClassPathElements the list of elements of Class-Path entry of manifest, rows should match

-     *                                  artifacts passed in {@code artifactsToValidateManifest} parameter;

-     *                                  can be {@code null} if {@code artifactsToValidateManifest} is {@code null}

-     * @param cleanBeforeExecute call clean plugin before execution

-     * @return the base directory of the project

-     */

-    protected File doTestProject( final String projectName, final String earModuleName,

-                                  final String[] expectedArtifacts, boolean[] artifactsDirectory,

-                                  final String[] artifactsToValidateManifest,

-                                  boolean[] artifactsToValidateManifestDirectory,

-                                  final String[][] expectedClassPathElements,

-                                  final boolean cleanBeforeExecute )

-        throws VerificationException, IOException

-    {

-        final File baseDir = executeMojo( projectName, true, cleanBeforeExecute );

-

-        final File earModuleDir = getEarModuleDirectory( baseDir, earModuleName );

-        assertEarArchive( earModuleDir, projectName );

-        assertEarDirectory( earModuleDir, projectName );

-        assertArchiveContent( earModuleDir, projectName, expectedArtifacts, artifactsDirectory );

-        assertDeploymentDescriptors( earModuleDir, projectName );

-        assertClassPathElements( earModuleDir, projectName, artifactsToValidateManifest,

-                                 artifactsToValidateManifestDirectory, expectedClassPathElements );

-

-        return baseDir;

-    }

-

-    /**

-     * Executes the specified projects and asserts the given artifacts. Assert the deployment descriptors are valid.

-     *

-     * @param projectName the project to test

-     * @param expectedArtifacts the list of artifacts to be found in the EAR archive

-     * @param artifactsDirectory whether the artifact from {@code expectedArtifacts} list is an exploded or not

-     * @return the base directory of the project

-     */

-    protected File doTestProject( final String projectName, final String[] expectedArtifacts,

-                                  final boolean[] artifactsDirectory )

-        throws VerificationException, IOException

-    {

-        return doTestProject( projectName, null, expectedArtifacts, artifactsDirectory, null, null, null, true );

-    }

-

-    /**

-     * Executes the specified projects and asserts the given artifacts as artifacts (non directory)

-     * 

-     * @param projectName the project to test

-     * @param expectedArtifacts the list of artifacts to be found in the EAR archive

-     * @return the base directory of the project

-     */

-    protected File doTestProject( final String projectName, final String[] expectedArtifacts )

-        throws VerificationException, IOException

-    {

-        return doTestProject( projectName, expectedArtifacts, new boolean[expectedArtifacts.length] );

-    }

-

-    /**

-     * Executes the specified projects and asserts the given artifacts as artifacts (non directory)

-     *

-     * @param projectName the project to test

-     * @param expectedArtifacts the list of artifacts to be found in the EAR archive

-     * @param cleanBeforeExecute call clean plugin before execution

-     * @return the base directory of the project

-     */

-    protected File doTestProject( final String projectName, final String[] expectedArtifacts, boolean cleanBeforeExecute)

-        throws VerificationException, IOException

-    {

-        return doTestProject( projectName, null, expectedArtifacts, new boolean[expectedArtifacts.length], null, null, null, cleanBeforeExecute );

-    }

-

-    protected void assertEarArchive( final File baseDir, final String projectName )

-    {

-        assertTrue( "EAR archive does not exist", getEarArchive( baseDir, projectName ).exists() );

-    }

-

-    protected void assertEarDirectory( final File baseDir, final String projectName )

-    {

-        assertTrue( "EAR archive directory does not exist", getEarDirectory( baseDir, projectName ).exists() );

-    }

-

-    protected File getEarModuleDirectory( final File baseDir, final String earModuleName)

-    {

-        return earModuleName == null ? baseDir : new File( baseDir, earModuleName );

-    }

-

-    protected File getTargetDirectory( final File basedir )

-    {

-        return new File( basedir, "target" );

-    }

-

-    protected File getEarArchive( final File baseDir, final String projectName )

-    {

-        return new File( getTargetDirectory( baseDir ), buildFinalName( projectName ) + ".ear" );

-    }

-

-    protected File getEarDirectory( final File baseDir, final String projectName )

-    {

-        return new File( getTargetDirectory( baseDir ), buildFinalName( projectName ) );

-    }

-

-    protected String buildFinalName( final String projectName )

-    {

-        return FINAL_NAME_PREFIX + projectName + FINAL_NAME_SUFFIX;

-    }

-

-    private void assertArchiveContent( final File baseDir, final String projectName, final String[] artifactNames,

-                                         final boolean[] artifactsDirectory )

-    {

-        // sanity check

-        assertEquals( "Wrong parameter, artifacts mismatch directory flags", artifactNames.length,

-                      artifactsDirectory.length );

-

-        File dir = getEarDirectory( baseDir, projectName );

-

-        // Let's build the expected directories sort list

-        final List<File> expectedDirectories = new ArrayList<>();

-        for ( int i = 0; i < artifactsDirectory.length; i++ )

-        {

-            if ( artifactsDirectory[i] )

-            {

-                expectedDirectories.add( new File( dir, artifactNames[i] ) );

-            }

-        }

-

-        final List<File> actualFiles = buildArchiveContentFiles( dir, expectedDirectories );

-        assertEquals( "Artifacts mismatch " + actualFiles, artifactNames.length, actualFiles.size() );

-        for ( int i = 0; i < artifactNames.length; i++ )

-        {

-            String artifactName = artifactNames[i];

-            final boolean isDirectory = artifactsDirectory[i];

-            File expectedFile = new File( dir, artifactName );

-

-            assertEquals( "Artifact[" + artifactName + "] not in the right form (exploded/archive", isDirectory,

-                          expectedFile.isDirectory() );

-            assertTrue( "Artifact[" + artifactName + "] not found in ear archive", actualFiles.contains( expectedFile ) );

-

-        }

-    }

-

-    /**

-     * Asserts that given EAR archive artifacts have expected entries and don't have unexpected entries.

-     *

-     * @param baseDir the directory of the tested project

-     * @param projectName the project to test

-     * @param earModuleName the name of 1st level EAR module in multi-module project or {@code null}

-     *                      if project is single-module

-     * @param artifacts the list of artifacts to be found in the EAR archive

-     * @param artifactsDirectory whether the artifact from {@code artifacts} list is an exploded or not

-     * @param includedEntries entries which should exist in artifacts, rows should match artifacts passed in

-     *                        {@code artifacts} parameter; can be {@code null} if there is no need to assert

-     *                        existence of entries in artifacts

-     * @param excludedEntries entries which should not exist in artifacts, rows should match artifacts passed in

-     *                        {@code artifacts} parameter; can be {@code null} if there is no need to assert

-     *                        absence of paths in artifacts

-     * @throws IOException exception in case of failure during reading of artifact archive.

-     */

-    protected void assertEarModulesContent( final File baseDir, final String projectName, final String earModuleName,

-                                            final String[] artifacts, final boolean[] artifactsDirectory,

-                                            final String[][] includedEntries, final String[][] excludedEntries )

-        throws IOException

-    {

-        assertTrue( "Wrong parameter, artifacts mismatch directory flags",

-            artifacts.length <= artifactsDirectory.length );

-        if ( includedEntries != null )

-        {

-            assertTrue( "Rows of includedEntries parameter should match items of artifacts parameter",

-                artifacts.length <= includedEntries.length );

-        }

-        if ( excludedEntries != null )

-        {

-            assertTrue( "Rows of excludedEntries parameter should match items of artifacts parameter",

-                artifacts.length <= excludedEntries.length );

-        }

-

-        final File earDirectory = getEarDirectory( getEarModuleDirectory( baseDir, earModuleName ), projectName );

-        for ( int i = 0; i != artifacts.length; ++i )

-        {

-            final String artifactName = artifacts[i];

-            final File module = new File( earDirectory, artifactName );

-            assertTrue( "Artifact [" + artifactName + "] should exist in EAR", module.exists() );

-

-            final boolean artifactDirectory = artifactsDirectory[i];

-            assertEquals( "Artifact [" + artifactName + "] should be a " + ( artifactDirectory ? "directory" : "file" ),

-                artifactDirectory, module.isDirectory() );

-

-            if ( includedEntries == null && excludedEntries == null )

-            {

-                continue;

-            }

-

-            final boolean includedEntriesDefined =

-                includedEntries != null && includedEntries[i] != null && includedEntries[i].length != 0;

-            final boolean excludedEntriesDefined =

-                excludedEntries != null && excludedEntries[i] != null && excludedEntries[i].length != 0;

-            if ( !includedEntriesDefined && !excludedEntriesDefined )

-            {

-                continue;

-            }

-

-            if ( artifactDirectory )

-            {

-                if ( includedEntriesDefined )

-                {

-                    for ( String includedEntry : includedEntries[i] )

-                    {

-                        if ( includedEntry == null || includedEntry.length() == 0 )

-                        {

-                            continue;

-                        }

-                        final File inclusion = new File( artifactName, includedEntry );

-                        assertTrue(

-                            "Entry [" + includedEntry + "] should exist in artifact [" + artifactName + "] of EAR",

-                            inclusion.exists() );

-                    }

-                }

-                if ( excludedEntriesDefined )

-                {

-                    for ( String excludedEntry : excludedEntries[i] )

-                    {

-                        if ( excludedEntry == null || excludedEntry.length() == 0 )

-                        {

-                            continue;

-                        }

-                        final File exclusion = new File( artifactName, excludedEntry );

-                        assertFalse(

-                            "Entry [" + excludedEntry + "] should not exist in artifact [" + artifactName + "] of EAR",

-                            exclusion.exists() );

-                    }

-                }

-            }

-            else

-            {

-                try ( JarFile moduleJar = new JarFile( module ) )

-                {

-                    if ( includedEntriesDefined )

-                    {

-                        for ( String includedEntry : includedEntries[i] )

-                        {

-                            if ( includedEntry == null || includedEntry.length() == 0 )

-                            {

-                                continue;

-                            }

-                            final ZipEntry inclusion = moduleJar.getEntry( includedEntry );

-                            assertNotNull(

-                                "Entry [" + includedEntry + "] should exist in artifact [" + artifactName + "] of EAR",

-                                inclusion );

-                        }

-                    }

-                    if ( excludedEntriesDefined )

-                    {

-                        for ( String excludedEntry : excludedEntries[i] )

-                        {

-                            if ( excludedEntry == null || excludedEntry.length() == 0 )

-                            {

-                                continue;

-                            }

-                            final ZipEntry exclusion = moduleJar.getEntry( excludedEntry );

-                            assertNull( "Entry [" + excludedEntry + "] should not exist in artifact [" + artifactName

-                                + "] of EAR", exclusion );

-                        }

-                    }

-                }

-            }

-        }

-    }

-

-    private static List<File> buildArchiveContentFiles( final File baseDir, final List<File> expectedDirectories )

-    {

-        final List<File> result = new ArrayList<>();

-        addFiles( baseDir, result, expectedDirectories );

-

-        return result;

-    }

-

-    private static void addFiles( final File directory, final List<File> files, final List<File> expectedDirectories )

-    {

-        File[] result = directory.listFiles( new FilenameFilter()

-        {

-            public boolean accept( File dir, String name )

-            {

-                return !name.equals( "META-INF" );

-            }

-

-        } );

-

-        /*

-         * Kinda complex. If we found a file, we always add it to the list of files. If a directory is within the

-         * expectedDirectories short list we add it but we don't add it's content. Otherwise, we don't add the directory

-         * *BUT* we browse it's content

-         */

-        for ( File file : result )

-        {

-            if ( file.isFile() )

-            {

-                files.add( file );

-            }

-            else if ( expectedDirectories.contains( file ) )

-            {

-                files.add( file );

-            }

-            else

-            {

-                addFiles( file, files, expectedDirectories );

-            }

-        }

-    }

-

-    private File getBasedir()

-    {

-        if ( basedir != null )

-        {

-            return basedir;

-        }

-

-        final String basedirString = System.getProperty( "basedir" );

-        if ( basedirString == null )

-        {

-            basedir = new File( "" );

-        }

-        else

-        {

-            basedir = new File( basedirString );

-        }

-        return basedir;

-    }

-

-    protected File getTestDir( String projectName )

-        throws IOException

-    {

-        return ResourceExtractor.simpleExtractResources( getClass(), "/projects/" + projectName );

-    }

-

-    // Generated application.xml stuff

-

-    /**

-     * Asserts that the deployment descriptors have been generated successfully.

-     * 

-     * This test assumes that deployment descriptors are located in the {@code expected-META-INF} directory of the

-     * project. Note that the {@code MANIFEST.mf} file is ignored and is not tested.

-     * 

-     * @param baseDir the directory of the tested project

-     * @param projectName the name of the project

-     * @throws IOException exception in case of an error.

-     */

-    protected void assertDeploymentDescriptors( final File baseDir, final String projectName )

-        throws IOException

-    {

-        final File earDirectory = getEarDirectory( baseDir, projectName );

-        final File[] actualDeploymentDescriptors = getDeploymentDescriptors( new File( earDirectory, "META-INF" ) );

-        final File[] expectedDeploymentDescriptors =

-            getDeploymentDescriptors( new File( baseDir, "expected-META-INF" ) );

-

-        if ( expectedDeploymentDescriptors == null )

-        {

-            assertNull( "No deployment descriptor was expected", actualDeploymentDescriptors );

-        }

-        else

-        {

-            assertNotNull( "Missing deployment descriptor", actualDeploymentDescriptors );

-

-            // Make sure we have the same number of files

-            assertEquals( "Number of Deployment descriptor(s) mismatch", expectedDeploymentDescriptors.length,

-                          actualDeploymentDescriptors.length );

-

-            // Sort the files so that we have the same behavior here

-            Arrays.sort( expectedDeploymentDescriptors );

-            Arrays.sort( actualDeploymentDescriptors );

-

-            for ( int i = 0; i < expectedDeploymentDescriptors.length; i++ )

-            {

-                File expectedDeploymentDescriptor = expectedDeploymentDescriptors[i];

-                File actualDeploymentDescriptor = actualDeploymentDescriptors[i];

-

-                assertEquals( "File name mismatch", expectedDeploymentDescriptor.getName(),

-                              actualDeploymentDescriptor.getName() );

-

-                try

-                {

-                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

-                    dbf.setNamespaceAware( true );

-                    dbf.setValidating( true );

-                    DocumentBuilder docBuilder = dbf.newDocumentBuilder();

-                    docBuilder.setEntityResolver( new ResourceEntityResolver() );

-                    docBuilder.setErrorHandler( new DefaultHandler() );

-

-                    final Diff myDiff =

-                        new Diff( docBuilder.parse( expectedDeploymentDescriptor ),

-                                  docBuilder.parse( actualDeploymentDescriptor ) );

-                    XMLAssert.assertXMLEqual( "Wrong deployment descriptor generated for["

-                        + expectedDeploymentDescriptor.getName() + "]", myDiff, true );

-                }

-                catch ( SAXException | ParserConfigurationException e )

-                {

-                    e.printStackTrace();

-                    fail( "Could not assert deployment descriptor " + e.getMessage() );

-                }

-            }

-        }

-    }

-

-    private static File[] getDeploymentDescriptors( final File ddDirectory )

-    {

-        return ddDirectory.listFiles( new FilenameFilter()

-        {

-            public boolean accept( File dir, String name )

-            {

-                return !name.equalsIgnoreCase( "manifest.mf" );

-            }

-        } );

-    }

-

-    /**

-     * Asserts that given EAR archive artifacts have expected elements in artifact manifest Class-Path entry.

-     *

-     * @param baseDir the directory of the tested project

-     * @param projectName the name of the project

-     * @param artifacts the list of EAR archive artifacts to validate Class-Path entry of artifact manifest or

-     *                  {@code null} if there is no need to validate Class-Path entry

-     * @param artifactsDirectory whether the artifact from {@code artifacts} list is an exploded or not,

-     *                           can be {@code null} if {@code artifacts} is {@code null}

-     * @param expectedClassPathElements the list of expected elements of Class-Path entry of manifest, rows should match

-     *                                  artifacts passed in {@code artifacts} parameter; can be {@code null}

-     *                                  if {@code artifacts} is {@code null}

-     * @throws IOException exception in case of failure during reading of artifact manifest.

-     */

-    protected void assertClassPathElements( final File baseDir, String projectName, String[] artifacts,

-                                          boolean[] artifactsDirectory, String[][] expectedClassPathElements )

-        throws IOException

-    {

-        if ( artifacts == null )

-        {

-            return;

-        }

-

-        assertNotNull( "artifactsDirectory should be provided if artifacts is provided",

-            artifactsDirectory );

-        assertTrue( "Size of artifactsDirectory should match size of artifacts parameter",

-            artifacts.length <= artifactsDirectory.length );

-        assertNotNull( "expectedClassPathElements should be provided if artifacts is provided",

-            expectedClassPathElements );

-        assertTrue( "Rows of expectedClassPathElements parameter should match items of artifacts parameter",

-            artifacts.length <= expectedClassPathElements.length );

-

-        final File earFile = getEarArchive( baseDir, projectName );

-        for ( int i = 0; i != artifacts.length; ++i )

-        {

-            final String moduleArtifact = artifacts[i];

-            final String[] classPathElements = getClassPathElements( earFile, moduleArtifact, artifactsDirectory[i] );

-            if ( expectedClassPathElements[i] == null )

-            {

-                assertNull( "Class-Path entry should not exist in module [" + moduleArtifact + "] manifest",

-                    classPathElements );

-            }

-            else

-            {

-                Assert.assertArrayEquals( "Wrong elements of Class-Path entry of module [" + moduleArtifact + "] manifest",

-                    expectedClassPathElements[i], classPathElements );

-            }

-        }

-    }

-

-    /**

-     * Retrieves elements of Class-Path entry of manifest of given EAR module.

-     *

-     * @param earFile the EAR file to investigate

-     * @param artifact the name of artifact in EAR archive representing EAR module

-     * @return elements of Class-Path entry of manifest of EAR module which is represented by

-     * {@code artifact} artifact in {@code earFile} file

-     */

-    protected String[] getClassPathElements( final File earFile, final String artifact, final boolean directory )

-        throws IOException

-    {

-        final String classPath;

-        try ( JarFile earJarFile = new JarFile( earFile ) )

-        {

-            final ZipEntry moduleEntry = earJarFile.getEntry( artifact );

-            assertNotNull( "Artifact [" + artifact + "] should exist in EAR", moduleEntry );

-            if (directory)

-            {

-                final String manifestEntryName = artifact + "/META-INF/MANIFEST.MF";

-                final ZipEntry manifestEntry = earJarFile.getEntry( manifestEntryName );

-                assertNotNull( manifestEntryName + " manifest file should exist in EAR", manifestEntry );

-                try ( InputStream manifestInputStream = earJarFile.getInputStream( manifestEntry ) )

-                {

-                    final Manifest manifest = new Manifest(manifestInputStream);

-                    classPath = manifest.getMainAttributes().getValue( "Class-Path" );

-                }

-            }

-            else

-            {

-                try ( InputStream moduleInputStream = earJarFile.getInputStream( moduleEntry );

-                      JarInputStream moduleJarInputStream = new JarInputStream( moduleInputStream ) )

-                {

-                    final Manifest manifest = moduleJarInputStream.getManifest();

-                    assertNotNull( "Artifact [" + artifact + "] of EAR should have manifest", manifest );

-                    classPath = manifest.getMainAttributes().getValue( "Class-Path" );

-                }

-            }

-        }

-        if ( classPath == null )

-        {

-            return null;

-        }

-        final String trimmedClassPath = classPath.trim();

-        if ( trimmedClassPath.length() == 0 )

-        {

-            return new String[0];

-        }

-        return trimmedClassPath.split( " " );

-    }

-}

+/*
+ * 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.maven.plugins.ear.it;
+
+/*
+ * 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.
+ */
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import junit.framework.TestCase;
+import org.apache.maven.plugins.ear.util.ResourceEntityResolver;
+import org.apache.maven.shared.verifier.VerificationException;
+import org.apache.maven.shared.verifier.Verifier;
+import org.apache.maven.shared.verifier.util.ResourceExtractor;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLAssert;
+import org.junit.Assert;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Base class for ear test cases.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractEarPluginIT extends TestCase {
+
+    private final String FINAL_NAME_PREFIX = "maven-ear-plugin-test-";
+
+    private final String FINAL_NAME_SUFFIX = "-99.0";
+
+    /**
+     * The base directory.
+     */
+    private File basedir;
+
+    private File settingsFile = new File(getBasedir().getAbsolutePath(), "target/test-classes/settings.xml");
+
+    /**
+     * Execute the EAR plugin for the specified project.
+     *
+     * @param projectName the name of the project
+     * @param expectNoError true/false
+     * @param cleanBeforeExecute call clean plugin before execution
+     * @return the base directory of the project
+     */
+    protected File executeMojo(final String projectName, boolean expectNoError, boolean cleanBeforeExecute)
+            throws VerificationException, IOException {
+        System.out.println("  Building: " + projectName);
+
+        File testDir = getTestDir(projectName);
+        Verifier verifier = new Verifier(testDir.getAbsolutePath());
+        verifier.setAutoclean(cleanBeforeExecute);
+        // Let's add alternate settings.xml setting so that the latest dependencies are used
+        String localRepo = System.getProperty("localRepositoryPath");
+        verifier.setLocalRepo(localRepo);
+
+        verifier.addCliArguments("-s", settingsFile.getAbsolutePath()); //
+        verifier.addCliArgument("-X");
+        verifier.addCliArgument("package");
+
+        // On linux and MacOS X, an exception is thrown if a build failure occurs underneath
+        try {
+            verifier.execute();
+        } catch (VerificationException e) {
+            // @TODO needs to be handled nicely in the verifier
+            if (expectNoError || !e.getMessage().contains("Exit code was non-zero")) {
+                throw e;
+            }
+        }
+
+        // If no error is expected make sure that error logs are free
+        if (expectNoError) {
+            verifier.verifyErrorFreeLog();
+        }
+        return testDir;
+    }
+
+    /**
+     * Execute the EAR plugin for the specified project.
+     *
+     * @param projectName the name of the project
+     * @return the base directory of the project
+     */
+    protected File executeMojo(final String projectName) throws VerificationException, IOException {
+        return executeMojo(projectName, true, true);
+    }
+
+    /**
+     * Executes the specified projects and asserts the given artifacts. Asserts the deployment descriptors are valid.
+     * Asserts Class-Path entry of manifest of EAR modules.
+     *
+     * @param projectName the project to test
+     * @param earModuleName the name of 1st level EAR module in multi-module project or {@code null}
+     *                      if project is single-module
+     * @param expectedArtifacts the list of artifacts to be found in the EAR archive
+     * @param artifactsDirectory whether the artifact from {@code expectedArtifacts} list is an exploded or not
+     * @param artifactsToValidateManifest the list of EAR archive artifacts to validate Class-Path entry of artifact
+     *                                    manifest or {@code null} if there is no need to validate Class-Path entry
+     * @param artifactsToValidateManifestDirectory whether the artifact from {@code artifactsToValidateManifest} list is
+     *                                             an exploded or not, can be {@code null} if
+     *                                             {@code artifactsToValidateManifest} is {@code null}
+     * @param expectedClassPathElements the list of elements of Class-Path entry of manifest, rows should match
+     *                                  artifacts passed in {@code artifactsToValidateManifest} parameter;
+     *                                  can be {@code null} if {@code artifactsToValidateManifest} is {@code null}
+     * @param cleanBeforeExecute call clean plugin before execution
+     * @return the base directory of the project
+     */
+    protected File doTestProject(
+            final String projectName,
+            final String earModuleName,
+            final String[] expectedArtifacts,
+            boolean[] artifactsDirectory,
+            final String[] artifactsToValidateManifest,
+            boolean[] artifactsToValidateManifestDirectory,
+            final String[][] expectedClassPathElements,
+            final boolean cleanBeforeExecute)
+            throws VerificationException, IOException {
+        final File baseDir = executeMojo(projectName, true, cleanBeforeExecute);
+
+        final File earModuleDir = getEarModuleDirectory(baseDir, earModuleName);
+        assertEarArchive(earModuleDir, projectName);
+        assertEarDirectory(earModuleDir, projectName);
+        assertArchiveContent(earModuleDir, projectName, expectedArtifacts, artifactsDirectory);
+        assertDeploymentDescriptors(earModuleDir, projectName);
+        assertClassPathElements(
+                earModuleDir,
+                projectName,
+                artifactsToValidateManifest,
+                artifactsToValidateManifestDirectory,
+                expectedClassPathElements);
+
+        return baseDir;
+    }
+
+    /**
+     * Executes the specified projects and asserts the given artifacts. Assert the deployment descriptors are valid.
+     *
+     * @param projectName the project to test
+     * @param expectedArtifacts the list of artifacts to be found in the EAR archive
+     * @param artifactsDirectory whether the artifact from {@code expectedArtifacts} list is an exploded or not
+     * @return the base directory of the project
+     */
+    protected File doTestProject(
+            final String projectName, final String[] expectedArtifacts, final boolean[] artifactsDirectory)
+            throws VerificationException, IOException {
+        return doTestProject(projectName, null, expectedArtifacts, artifactsDirectory, null, null, null, true);
+    }
+
+    /**
+     * Executes the specified projects and asserts the given artifacts as artifacts (non directory)
+     *
+     * @param projectName the project to test
+     * @param expectedArtifacts the list of artifacts to be found in the EAR archive
+     * @return the base directory of the project
+     */
+    protected File doTestProject(final String projectName, final String[] expectedArtifacts)
+            throws VerificationException, IOException {
+        return doTestProject(projectName, expectedArtifacts, new boolean[expectedArtifacts.length]);
+    }
+
+    /**
+     * Executes the specified projects and asserts the given artifacts as artifacts (non directory)
+     *
+     * @param projectName the project to test
+     * @param expectedArtifacts the list of artifacts to be found in the EAR archive
+     * @param cleanBeforeExecute call clean plugin before execution
+     * @return the base directory of the project
+     */
+    protected File doTestProject(final String projectName, final String[] expectedArtifacts, boolean cleanBeforeExecute)
+            throws VerificationException, IOException {
+        return doTestProject(
+                projectName,
+                null,
+                expectedArtifacts,
+                new boolean[expectedArtifacts.length],
+                null,
+                null,
+                null,
+                cleanBeforeExecute);
+    }
+
+    protected void assertEarArchive(final File baseDir, final String projectName) {
+        assertTrue(
+                "EAR archive does not exist",
+                getEarArchive(baseDir, projectName).exists());
+    }
+
+    protected void assertEarDirectory(final File baseDir, final String projectName) {
+        assertTrue(
+                "EAR archive directory does not exist",
+                getEarDirectory(baseDir, projectName).exists());
+    }
+
+    protected File getEarModuleDirectory(final File baseDir, final String earModuleName) {
+        return earModuleName == null ? baseDir : new File(baseDir, earModuleName);
+    }
+
+    protected File getTargetDirectory(final File basedir) {
+        return new File(basedir, "target");
+    }
+
+    protected File getEarArchive(final File baseDir, final String projectName) {
+        return new File(getTargetDirectory(baseDir), buildFinalName(projectName) + ".ear");
+    }
+
+    protected File getEarDirectory(final File baseDir, final String projectName) {
+        return new File(getTargetDirectory(baseDir), buildFinalName(projectName));
+    }
+
+    protected String buildFinalName(final String projectName) {
+        return FINAL_NAME_PREFIX + projectName + FINAL_NAME_SUFFIX;
+    }
+
+    private void assertArchiveContent(
+            final File baseDir,
+            final String projectName,
+            final String[] artifactNames,
+            final boolean[] artifactsDirectory) {
+        // sanity check
+        assertEquals(
+                "Wrong parameter, artifacts mismatch directory flags", artifactNames.length, artifactsDirectory.length);
+
+        File dir = getEarDirectory(baseDir, projectName);
+
+        // Let's build the expected directories sort list
+        final List<File> expectedDirectories = new ArrayList<>();
+        for (int i = 0; i < artifactsDirectory.length; i++) {
+            if (artifactsDirectory[i]) {
+                expectedDirectories.add(new File(dir, artifactNames[i]));
+            }
+        }
+
+        final List<File> actualFiles = buildArchiveContentFiles(dir, expectedDirectories);
+        assertEquals("Artifacts mismatch " + actualFiles, artifactNames.length, actualFiles.size());
+        for (int i = 0; i < artifactNames.length; i++) {
+            String artifactName = artifactNames[i];
+            final boolean isDirectory = artifactsDirectory[i];
+            File expectedFile = new File(dir, artifactName);
+
+            assertEquals(
+                    "Artifact[" + artifactName + "] not in the right form (exploded/archive",
+                    isDirectory,
+                    expectedFile.isDirectory());
+            assertTrue("Artifact[" + artifactName + "] not found in ear archive", actualFiles.contains(expectedFile));
+        }
+    }
+
+    /**
+     * Asserts that given EAR archive artifacts have expected entries and don't have unexpected entries.
+     *
+     * @param baseDir the directory of the tested project
+     * @param projectName the project to test
+     * @param earModuleName the name of 1st level EAR module in multi-module project or {@code null}
+     *                      if project is single-module
+     * @param artifacts the list of artifacts to be found in the EAR archive
+     * @param artifactsDirectory whether the artifact from {@code artifacts} list is an exploded or not
+     * @param includedEntries entries which should exist in artifacts, rows should match artifacts passed in
+     *                        {@code artifacts} parameter; can be {@code null} if there is no need to assert
+     *                        existence of entries in artifacts
+     * @param excludedEntries entries which should not exist in artifacts, rows should match artifacts passed in
+     *                        {@code artifacts} parameter; can be {@code null} if there is no need to assert
+     *                        absence of paths in artifacts
+     * @throws IOException exception in case of failure during reading of artifact archive.
+     */
+    protected void assertEarModulesContent(
+            final File baseDir,
+            final String projectName,
+            final String earModuleName,
+            final String[] artifacts,
+            final boolean[] artifactsDirectory,
+            final String[][] includedEntries,
+            final String[][] excludedEntries)
+            throws IOException {
+        assertTrue(
+                "Wrong parameter, artifacts mismatch directory flags", artifacts.length <= artifactsDirectory.length);
+        if (includedEntries != null) {
+            assertTrue(
+                    "Rows of includedEntries parameter should match items of artifacts parameter",
+                    artifacts.length <= includedEntries.length);
+        }
+        if (excludedEntries != null) {
+            assertTrue(
+                    "Rows of excludedEntries parameter should match items of artifacts parameter",
+                    artifacts.length <= excludedEntries.length);
+        }
+
+        final File earDirectory = getEarDirectory(getEarModuleDirectory(baseDir, earModuleName), projectName);
+        for (int i = 0; i != artifacts.length; ++i) {
+            final String artifactName = artifacts[i];
+            final File module = new File(earDirectory, artifactName);
+            assertTrue("Artifact [" + artifactName + "] should exist in EAR", module.exists());
+
+            final boolean artifactDirectory = artifactsDirectory[i];
+            assertEquals(
+                    "Artifact [" + artifactName + "] should be a " + (artifactDirectory ? "directory" : "file"),
+                    artifactDirectory,
+                    module.isDirectory());
+
+            if (includedEntries == null && excludedEntries == null) {
+                continue;
+            }
+
+            final boolean includedEntriesDefined =
+                    includedEntries != null && includedEntries[i] != null && includedEntries[i].length != 0;
+            final boolean excludedEntriesDefined =
+                    excludedEntries != null && excludedEntries[i] != null && excludedEntries[i].length != 0;
+            if (!includedEntriesDefined && !excludedEntriesDefined) {
+                continue;
+            }
+
+            if (artifactDirectory) {
+                if (includedEntriesDefined) {
+                    for (String includedEntry : includedEntries[i]) {
+                        if (includedEntry == null || includedEntry.length() == 0) {
+                            continue;
+                        }
+                        final File inclusion = new File(artifactName, includedEntry);
+                        assertTrue(
+                                "Entry [" + includedEntry + "] should exist in artifact [" + artifactName + "] of EAR",
+                                inclusion.exists());
+                    }
+                }
+                if (excludedEntriesDefined) {
+                    for (String excludedEntry : excludedEntries[i]) {
+                        if (excludedEntry == null || excludedEntry.length() == 0) {
+                            continue;
+                        }
+                        final File exclusion = new File(artifactName, excludedEntry);
+                        assertFalse(
+                                "Entry [" + excludedEntry + "] should not exist in artifact [" + artifactName
+                                        + "] of EAR",
+                                exclusion.exists());
+                    }
+                }
+            } else {
+                try (JarFile moduleJar = new JarFile(module)) {
+                    if (includedEntriesDefined) {
+                        for (String includedEntry : includedEntries[i]) {
+                            if (includedEntry == null || includedEntry.length() == 0) {
+                                continue;
+                            }
+                            final ZipEntry inclusion = moduleJar.getEntry(includedEntry);
+                            assertNotNull(
+                                    "Entry [" + includedEntry + "] should exist in artifact [" + artifactName
+                                            + "] of EAR",
+                                    inclusion);
+                        }
+                    }
+                    if (excludedEntriesDefined) {
+                        for (String excludedEntry : excludedEntries[i]) {
+                            if (excludedEntry == null || excludedEntry.length() == 0) {
+                                continue;
+                            }
+                            final ZipEntry exclusion = moduleJar.getEntry(excludedEntry);
+                            assertNull(
+                                    "Entry [" + excludedEntry + "] should not exist in artifact [" + artifactName
+                                            + "] of EAR",
+                                    exclusion);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static List<File> buildArchiveContentFiles(final File baseDir, final List<File> expectedDirectories) {
+        final List<File> result = new ArrayList<>();
+        addFiles(baseDir, result, expectedDirectories);
+
+        return result;
+    }
+
+    private static void addFiles(final File directory, final List<File> files, final List<File> expectedDirectories) {
+        File[] result = directory.listFiles(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return !name.equals("META-INF");
+            }
+        });
+
+        /*
+         * Kinda complex. If we found a file, we always add it to the list of files. If a directory is within the
+         * expectedDirectories short list we add it but we don't add it's content. Otherwise, we don't add the directory
+         * *BUT* we browse it's content
+         */
+        for (File file : result) {
+            if (file.isFile()) {
+                files.add(file);
+            } else if (expectedDirectories.contains(file)) {
+                files.add(file);
+            } else {
+                addFiles(file, files, expectedDirectories);
+            }
+        }
+    }
+
+    private File getBasedir() {
+        if (basedir != null) {
+            return basedir;
+        }
+
+        final String basedirString = System.getProperty("basedir");
+        if (basedirString == null) {
+            basedir = new File("");
+        } else {
+            basedir = new File(basedirString);
+        }
+        return basedir;
+    }
+
+    protected File getTestDir(String projectName) throws IOException {
+        return ResourceExtractor.simpleExtractResources(getClass(), "/projects/" + projectName);
+    }
+
+    // Generated application.xml stuff
+
+    /**
+     * Asserts that the deployment descriptors have been generated successfully.
+     *
+     * This test assumes that deployment descriptors are located in the {@code expected-META-INF} directory of the
+     * project. Note that the {@code MANIFEST.mf} file is ignored and is not tested.
+     *
+     * @param baseDir the directory of the tested project
+     * @param projectName the name of the project
+     * @throws IOException exception in case of an error.
+     */
+    protected void assertDeploymentDescriptors(final File baseDir, final String projectName) throws IOException {
+        final File earDirectory = getEarDirectory(baseDir, projectName);
+        final File[] actualDeploymentDescriptors = getDeploymentDescriptors(new File(earDirectory, "META-INF"));
+        final File[] expectedDeploymentDescriptors = getDeploymentDescriptors(new File(baseDir, "expected-META-INF"));
+
+        if (expectedDeploymentDescriptors == null) {
+            assertNull("No deployment descriptor was expected", actualDeploymentDescriptors);
+        } else {
+            assertNotNull("Missing deployment descriptor", actualDeploymentDescriptors);
+
+            // Make sure we have the same number of files
+            assertEquals(
+                    "Number of Deployment descriptor(s) mismatch",
+                    expectedDeploymentDescriptors.length,
+                    actualDeploymentDescriptors.length);
+
+            // Sort the files so that we have the same behavior here
+            Arrays.sort(expectedDeploymentDescriptors);
+            Arrays.sort(actualDeploymentDescriptors);
+
+            for (int i = 0; i < expectedDeploymentDescriptors.length; i++) {
+                File expectedDeploymentDescriptor = expectedDeploymentDescriptors[i];
+                File actualDeploymentDescriptor = actualDeploymentDescriptors[i];
+
+                assertEquals(
+                        "File name mismatch",
+                        expectedDeploymentDescriptor.getName(),
+                        actualDeploymentDescriptor.getName());
+
+                try {
+                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+                    dbf.setNamespaceAware(true);
+                    dbf.setValidating(true);
+                    DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+                    docBuilder.setEntityResolver(new ResourceEntityResolver());
+                    docBuilder.setErrorHandler(new DefaultHandler());
+
+                    final Diff myDiff = new Diff(
+                            docBuilder.parse(expectedDeploymentDescriptor),
+                            docBuilder.parse(actualDeploymentDescriptor));
+                    XMLAssert.assertXMLEqual(
+                            "Wrong deployment descriptor generated for[" + expectedDeploymentDescriptor.getName() + "]",
+                            myDiff,
+                            true);
+                } catch (SAXException | ParserConfigurationException e) {
+                    e.printStackTrace();
+                    fail("Could not assert deployment descriptor " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    private static File[] getDeploymentDescriptors(final File ddDirectory) {
+        return ddDirectory.listFiles(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return !name.equalsIgnoreCase("manifest.mf");
+            }
+        });
+    }
+
+    /**
+     * Asserts that given EAR archive artifacts have expected elements in artifact manifest Class-Path entry.
+     *
+     * @param baseDir the directory of the tested project
+     * @param projectName the name of the project
+     * @param artifacts the list of EAR archive artifacts to validate Class-Path entry of artifact manifest or
+     *                  {@code null} if there is no need to validate Class-Path entry
+     * @param artifactsDirectory whether the artifact from {@code artifacts} list is an exploded or not,
+     *                           can be {@code null} if {@code artifacts} is {@code null}
+     * @param expectedClassPathElements the list of expected elements of Class-Path entry of manifest, rows should match
+     *                                  artifacts passed in {@code artifacts} parameter; can be {@code null}
+     *                                  if {@code artifacts} is {@code null}
+     * @throws IOException exception in case of failure during reading of artifact manifest.
+     */
+    protected void assertClassPathElements(
+            final File baseDir,
+            String projectName,
+            String[] artifacts,
+            boolean[] artifactsDirectory,
+            String[][] expectedClassPathElements)
+            throws IOException {
+        if (artifacts == null) {
+            return;
+        }
+
+        assertNotNull("artifactsDirectory should be provided if artifacts is provided", artifactsDirectory);
+        assertTrue(
+                "Size of artifactsDirectory should match size of artifacts parameter",
+                artifacts.length <= artifactsDirectory.length);
+        assertNotNull(
+                "expectedClassPathElements should be provided if artifacts is provided", expectedClassPathElements);
+        assertTrue(
+                "Rows of expectedClassPathElements parameter should match items of artifacts parameter",
+                artifacts.length <= expectedClassPathElements.length);
+
+        final File earFile = getEarArchive(baseDir, projectName);
+        for (int i = 0; i != artifacts.length; ++i) {
+            final String moduleArtifact = artifacts[i];
+            final String[] classPathElements = getClassPathElements(earFile, moduleArtifact, artifactsDirectory[i]);
+            if (expectedClassPathElements[i] == null) {
+                assertNull(
+                        "Class-Path entry should not exist in module [" + moduleArtifact + "] manifest",
+                        classPathElements);
+            } else {
+                Assert.assertArrayEquals(
+                        "Wrong elements of Class-Path entry of module [" + moduleArtifact + "] manifest",
+                        expectedClassPathElements[i],
+                        classPathElements);
+            }
+        }
+    }
+
+    /**
+     * Retrieves elements of Class-Path entry of manifest of given EAR module.
+     *
+     * @param earFile the EAR file to investigate
+     * @param artifact the name of artifact in EAR archive representing EAR module
+     * @return elements of Class-Path entry of manifest of EAR module which is represented by
+     * {@code artifact} artifact in {@code earFile} file
+     */
+    protected String[] getClassPathElements(final File earFile, final String artifact, final boolean directory)
+            throws IOException {
+        final String classPath;
+        try (JarFile earJarFile = new JarFile(earFile)) {
+            final ZipEntry moduleEntry = earJarFile.getEntry(artifact);
+            assertNotNull("Artifact [" + artifact + "] should exist in EAR", moduleEntry);
+            if (directory) {
+                final String manifestEntryName = artifact + "/META-INF/MANIFEST.MF";
+                final ZipEntry manifestEntry = earJarFile.getEntry(manifestEntryName);
+                assertNotNull(manifestEntryName + " manifest file should exist in EAR", manifestEntry);
+                try (InputStream manifestInputStream = earJarFile.getInputStream(manifestEntry)) {
+                    final Manifest manifest = new Manifest(manifestInputStream);
+                    classPath = manifest.getMainAttributes().getValue("Class-Path");
+                }
+            } else {
+                try (InputStream moduleInputStream = earJarFile.getInputStream(moduleEntry);
+                        JarInputStream moduleJarInputStream = new JarInputStream(moduleInputStream)) {
+                    final Manifest manifest = moduleJarInputStream.getManifest();
+                    assertNotNull("Artifact [" + artifact + "] of EAR should have manifest", manifest);
+                    classPath = manifest.getMainAttributes().getValue("Class-Path");
+                }
+            }
+        }
+        if (classPath == null) {
+            return null;
+        }
+        final String trimmedClassPath = classPath.trim();
+        if (trimmedClassPath.length() == 0) {
+            return new String[0];
+        }
+        return trimmedClassPath.split(" ");
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java
index 66b8122..0c97e03 100644
--- a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java
+++ b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java
@@ -1,1335 +1,1347 @@
-package org.apache.maven.plugins.ear.it;

-

-/*

- * 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.

- */

-

-import java.io.File;

-import java.io.FileInputStream;

-import java.util.Properties;

-import java.util.jar.JarFile;

-import java.util.jar.Manifest;

-

-import org.apache.commons.io.IOUtils;

-import org.codehaus.plexus.util.FileUtils;

-import org.codehaus.plexus.util.ReaderFactory;

-

-/**

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarMojoIT

-    extends AbstractEarPluginIT

-{

-

-    /**

-     * Builds an EAR with a single EJB and no configuration.

-     */

-    public void testProject001()

-        throws Exception

-    {

-        doTestProject( "project-001", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a customized artifact location and a customized artifact name.

-     */

-    public void testProject002()

-        throws Exception

-    {

-        doTestProject( "project-002",

-                       new String[] { "APP-INF/lib/eartest-ejb-sample-one-1.0.jar", "ejb-sample-two.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a default bundle directory for {@code java} modules.

-     */

-    public void testProject003()

-        throws Exception

-    {

-        doTestProject( "project-003", new String[] { "eartest-ejb-sample-one-1.0.jar",

-            "APP-INF/lib/eartest-jar-sample-one-1.0.jar", "APP-INF/lib/eartest-jar-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a default bundle directory for _java_ modules and a custom location overriding the default.

-     */

-    public void testProject004()

-        throws Exception

-    {

-        doTestProject( "project-004", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-one-1.0.jar",

-            "APP-INF/lib/eartest-jar-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a custom URI.

-     */

-    public void testProject005()

-        throws Exception

-    {

-        doTestProject( "project-005", new String[] { "eartest-ejb-sample-one-1.0.jar", "libs/another-name.jar" } );

-    }

-

-    /**

-     * Builds an EAR with an excluded module.

-     */

-    public void testProject006()

-        throws Exception

-    {

-        doTestProject( "project-006",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a classified artifact and no extra configuration.

-     */

-    public void testProject007()

-        throws Exception

-    {

-        doTestProject( "project-007", new String[] { "eartest-ejb-sample-one-1.0-classified.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for J2EE 1.3.

-     */

-    public void testProject008()

-        throws Exception

-    {

-        doTestProject( "project-008", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for J2EE 1.4.

-     */

-    public void testProject009()

-        throws Exception

-    {

-        doTestProject( "project-009", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for Java EE 5.

-     */

-    public void testProject010()

-        throws Exception

-    {

-        doTestProject( "project-010", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that deployment descriptor default settings are applied.

-     */

-    public void testProject011()

-        throws Exception

-    {

-        doTestProject( "project-011", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that EAR resources are bundled within the EAR.

-     */

-    public void testProject012()

-        throws Exception

-    {

-        doTestProject( "project-012", new String[] { "README.txt", "LICENSE.txt", "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that EAR resources in a customized resources directory are bundled within the EAR.

-     */

-    public void testProject013()

-        throws Exception

-    {

-        doTestProject( "project-013", new String[] { "README.txt", "LICENSE.txt", "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that EAR resources are bundled within the EAR using includes and excludes.

-     */

-    public void testProject014()

-        throws Exception

-    {

-        doTestProject( "project-014", new String[] { "LICENSE.txt", "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that default manifest is taken into account.

-     */

-    public void testProject015()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-015", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-        final File expectedManifest = new File( baseDir, "src/main/application/META-INF/MANIFEST.MF" );

-        final File actualManifest = new File( getEarDirectory( baseDir, "project-015" ), "META-INF/MANIFEST.MF" );

-        assertTrue( "Manifest was not copied", actualManifest.exists() );

-        assertTrue( FileUtils.contentEquals( expectedManifest, actualManifest ) );

-    }

-

-    /**

-     * Builds an EAR and make sure that custom manifest is taken into account.

-     */

-    public void testProject016()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-016", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-

-        final File createdEarFile = getEarArchive( baseDir, "project-016" );

-

-        final File sourceManifestFile = new File( baseDir, "src/main/ear/MANIFEST.MF" );

-

-        try ( JarFile jarFile = new JarFile( createdEarFile );

-              FileInputStream in = new FileInputStream( sourceManifestFile ) )

-        {    

-            Manifest manifestFromCreatedEARFile = jarFile.getManifest();

-            Manifest sourceManifest = new Manifest( in );

-            assertEquals( "There are differences in the manifest.", sourceManifest, manifestFromCreatedEARFile );

-        }

-     }

-

-    /**

-     * Builds an EAR and make sure that custom application.xml is taken into account.

-     */

-    public void testProject017()

-        throws Exception

-    {

-        doTestProject( "project-017", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a custom final name.

-     */

-    public void testProject018()

-        throws Exception

-    {

-        final File baseDir = executeMojo( "project-018" );

-        final File expectedFile = new File( baseDir, "target/my-custom-file.ear" );

-        assertTrue( "EAR archive not found", expectedFile.exists() );

-    }

-

-    /**

-     * Builds an EAR with unpacked archives using the unpackTypes.

-     */

-    public void testProject019()

-        throws Exception

-    {

-        doTestProject( "project-019", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-sar-sample-one-1.0.sar",

-            "eartest-jar-sample-one-1.0.jar" }, new boolean[] { false, true, true } );

-    }

-

-    /**

-     * Builds an EAR with unpacked archives using the unpack module attribute.

-     */

-    public void testProject020()

-        throws Exception

-    {

-        doTestProject( "project-020", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-sar-sample-one-1.0.sar",

-            "eartest-jar-sample-one-1.0.jar" }, new boolean[] { true, false, false } );

-    }

-

-    /**

-     * Builds an EAR with unpacked archives using both unpackTypes and the unpack module attribute.

-     */

-    public void testProject021()

-        throws Exception

-    {

-        doTestProject( "project-021",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar",

-                           "eartest-sar-sample-one-1.0.sar", "eartest-jar-sample-one-1.0.jar",

-                           "eartest-jar-sample-two-1.0.jar" },

-                       new boolean[] { false, true, false, false, true } );

-    }

-

-    /**

-     * Builds an EAR with a classifier.

-     */

-    public void testProject022()

-        throws Exception

-    {

-        final File baseDir = executeMojo( "project-022" );

-        final File expectedFile = new File( baseDir, "target/maven-ear-plugin-test-project-022-99.0-myclassifier.ear" );

-        assertTrue( "EAR archive not found", expectedFile.exists() );

-    }

-

-    /**

-     * Builds an EAR and make sure that a single classified dependency is detected without specifying the classifier.

-     */

-    public void testProject023()

-        throws Exception

-    {

-        doTestProject( "project-023",

-                       new String[] { "eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-two-1.0.jar" },

-                       new boolean[] { true, false } );

-    }

-

-    /**

-     * Builds an EAR and make sure that a single classified dependency is detected when specifying the classifier.

-     */

-    public void testProject024()

-        throws Exception

-    {

-        doTestProject( "project-024",

-                       new String[] { "eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-two-1.0.jar" },

-                       new boolean[] { true, false } );

-    }

-

-    /**

-     * Builds an EAR and make sure that a classified dependency with multiple candidates is detected when specifying the

-     * classifier.

-     */

-    public void testProject025()

-        throws Exception

-    {

-        doTestProject( "project-025",

-                       new String[] { "eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-one-1.0.jar" },

-                       new boolean[] { true, false } );

-    }

-

-    /**

-     * Builds an EAR and make sure that the build fails if a unclassifed module configuration with multiple candidates is

-     * specified.

-     */

-    public void testProject026()

-        throws Exception

-    {

-        final File baseDir = executeMojo( "project-026", false, true );

-        // Stupido, checks that the ear archive is not there

-        assertFalse( "Execution should have failed", getEarArchive( baseDir, "project-026" ).exists() );

-    }

-

-    /**

-     * Builds an EAR and make sure that provided dependencies are not included in the EAR.

-     */

-    public void testProject027()

-        throws Exception

-    {

-        doTestProject( "project-027", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that test dependencies are not included in the EAR.

-     */

-    public void testProject028()

-        throws Exception

-    {

-        doTestProject( "project-028", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that system dependencies are not included in the EAR.

-     */

-    public void testProject029()

-        throws Exception

-    {

-        doTestProject( "project-029", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that ejb-client dependencies are detected and not added by default in the generated

-     * application.xml.

-     */

-    public void testProject030()

-        throws Exception

-    {

-        doTestProject( "project-030",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 4 configuration specifying the security domain and the unauthenticated-principal to

-     * use.

-     */

-    public void testProject031()

-        throws Exception

-    {

-        doTestProject( "project-031",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 3.2 configuration specifying the jmx-name to use.

-     */

-    public void testProject032()

-        throws Exception

-    {

-        doTestProject( "project-032",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 4 configuration and Jboss specific modules.

-     */

-    public void testProject033()

-        throws Exception

-    {

-        doTestProject( "project-033", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar",

-            "eartest-sar-sample-one-1.0.sar", "eartest-har-sample-one-1.0.har" } );

-    }

-

-    /**

-     * Builds an EAR with custom security settings.

-     */

-    public void testProject034()

-        throws Exception

-    {

-        doTestProject( "project-034",

-                       new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a full filename mapping and make sure that custom locations are not overridden.

-     */

-    public void testProject035()

-        throws Exception

-    {

-        doTestProject( "project-035",

-                       new String[] { "foo/eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar",

-                           "libs/eartest-jar-sample-one-1.0.jar", "libs/eartest-jar-sample-two-1.0.jar",

-                           "sar-sample-one.sar" } );

-    }

-

-    /**

-     * Builds an EAR with a full filename mapping and make sure that groupIds with dots are replaced by dashes in

-     * filenames.

-     */

-    public void testProject036()

-        throws Exception

-    {

-        doTestProject( "project-036",

-                       new String[] { "foo/eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar",

-                           "com.foo.bar-ejb-sample-one-1.0.jar", "com.foo.bar-ejb-sample-two-1.0.jar",

-                           "libs/eartest-jar-sample-one-1.0.jar", "libs/eartest-jar-sample-two-1.0.jar",

-                           "sar-sample-one.sar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that ejb-client dependencies are detected and added in the generated application.xml

-     * if includeInApplicationXml is set.

-     */

-    public void testProject037()

-        throws Exception

-    {

-        doTestProject( "project-037", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR and make sure that a non-classified dependency with multiple candidates is detected when specifying

-     * the mainArtifactId as classifier.

-     */

-    public void testProject038()

-        throws Exception

-    {

-        doTestProject( "project-038", new String[] { "eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-one-1.0.jar" },

-                       new boolean[] { false, true } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 4 configuration specifying specifying the loader repository to use.

-     */

-    public void testProject039()

-        throws Exception

-    {

-        doTestProject( "project-039", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for Java EE 5 and an alternative deployment descriptor.

-     */

-    public void testProject040()

-        throws Exception

-    {

-        doTestProject( "project-040", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 4.2 configuration specifying the module order to use.

-     */

-    public void testProject041()

-        throws Exception

-    {

-        doTestProject( "project-041", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 4.2 configuration specifying a datasource to add.

-     */

-    public void testProject042()

-        throws Exception

-    {

-        doTestProject( "project-042", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a custom descriptor location (generatedDescriptorLocation setting).

-     */

-    public void testProject043()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-043", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-        final File expectedApplicationXml = new File( baseDir, "target/custom-descriptor-dir/application.xml" );

-        assertTrue( "Application.xml file not found", expectedApplicationXml.exists() );

-        assertFalse( "Application.xml file should not be empty", expectedApplicationXml.length() == 0 );

-    }

-

-    /**

-     * Builds an EAR with a custom library-directory.

-     */

-    public void testProject044()

-        throws Exception

-    {

-        doTestProject( "project-044", new String[] { "eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR and filter the content of the sources directory.

-     */

-    public void testProject045()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-045", new String[] { "README.txt", "eartest-ejb-sample-one-1.0.jar" } );

-        final File actualReadme = new File( getEarDirectory( baseDir, "project-045" ), "README.txt" );

-        final String content = IOUtils.toString( ReaderFactory.newReader( actualReadme, "UTF-8" ) );

-        assertTrue( "application name and version was not filtered properly", content.contains( "my-app 99.0" ) );

-        assertTrue( "Escaping did not work properly", content.contains( "will not be filtered ${application.name}." ) );

-    }

-

-    /**

-     * Builds an EAR and filter the content of the sources directory using a custom filter file.

-     */

-    public void testProject046()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-046", new String[] { "README.txt", "eartest-ejb-sample-one-1.0.jar" } );

-        final File actualReadme = new File( getEarDirectory( baseDir, "project-046" ), "README.txt" );

-        final String content = IOUtils.toString( ReaderFactory.newReader( actualReadme, "UTF-8" ) );

-        assertTrue( "application name and version was not filtered properly", content.contains( "my-app 99.0" ) );

-        assertTrue( "application build was not filtered properly", content.contains( "(Build 2)" ) );

-        assertTrue( "Unknown property should not have been filtered",

-                    content.contains( "will not be filtered ${application.unknown}." ) );

-    }

-

-    /**

-     * Builds an EAR and filter the content with a list of extensions.

-     */

-    public void testProject047()

-        throws Exception

-    {

-        final File baseDir = doTestProject( "project-047", new String[] { "README.txt", "eartest-ejb-sample-one-1.0.jar" } );

-        final File actualReadme = new File( getEarDirectory( baseDir, "project-047" ), "README.txt" );

-        final String content = IOUtils.toString( ReaderFactory.newReader( actualReadme, "UTF-8" ) );

-        assertTrue( "application name and version should not have been filtered", !content.contains( "my-app 99.0" ) );

-        assertTrue( "original properties not found", content.contains( "${application.name} ${project.version}" ) );

-    }

-

-    /**

-     * Builds an EAR with a JBoss 5 configuration containing library directory.

-     */

-    public void testProject048()

-        throws Exception

-    {

-        doTestProject( "project-048", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a JBoss 4.2 configuration containing a library directory.

-     */

-    public void testProject049()

-        throws Exception

-    {

-        doTestProject( "project-049", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 5 configuration containing a loader repository configuration definition.

-     */

-    public void testProject050()

-        throws Exception

-    {

-        doTestProject( "project-050", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 5 configuration containing a loader repository class definition.

-     */

-    public void testProject051()

-        throws Exception

-    {

-        doTestProject( "project-051", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 5 configuration containing a configuration parser class definition.

-     */

-    public void testProject052()

-        throws Exception

-    {

-        doTestProject( "project-052", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a Jboss 5 configuration containing only the loader repo configuration

-     */

-    public void testProject053()

-        throws Exception

-    {

-        doTestProject( "project-053", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for Java EE 5 and no application.xml

-     */

-    public void testProject054()

-        throws Exception

-    {

-        doTestProject( "project-054", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with jar dependencies added in application.xml.

-     */

-    public void testProject055()

-        throws Exception

-    {

-        doTestProject( "project-055", new String[] { "eartest-jar-sample-one-1.0.jar", "eartest-jar-sample-two-1.0.jar",

-            "eartest-jar-sample-three-with-deps-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for J2EE 1.4 and an alternative deployment descriptor.

-     */

-    public void testProject056()

-        throws Exception

-    {

-        doTestProject( "project-056", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a complete JBoss 4.2 configuration and validate it matches the DTD (MEAR-104).

-     */

-    public void testProject057()

-        throws Exception

-    {

-        doTestProject( "project-057", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for Java EE 6.

-     */

-    public void testProject058()

-        throws Exception

-    {

-        doTestProject( "project-058", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with no display name entry at all.

-     */

-    public void testProject059()

-        throws Exception

-    {

-        doTestProject( "project-059", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with ejb-client packaged for J2EE 1.3 (MEAR-85)

-     */

-    public void testProject060()

-        throws Exception

-    {

-        doTestProject( "project-060", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with ejb-client packaged for J2EE 1.4 (MEAR-85)

-     */

-    public void testProject061()

-        throws Exception

-    {

-        doTestProject( "project-061", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with ejb-client packaged for JavaEE 5 (MEAR-85)

-     */

-    public void testProject062()

-        throws Exception

-    {

-        doTestProject( "project-062", new String[] { "eartest-ejb-sample-one-1.0.jar", "lib/eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with ejb-client packaged for JavaEE 6 (MEAR-85)

-     */

-    public void testProject063()

-        throws Exception

-    {

-        doTestProject( "project-063", new String[] { "lib/eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with ejb-client packaged for JavaEE 5 and still put it in the root (MEAR-85)

-     */

-    public void testProject064()

-        throws Exception

-    {

-        doTestProject( "project-064", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a custom moduleId.

-     */

-    public void testProject065()

-        throws Exception

-    {

-        doTestProject( "project-065", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with generateModuleId enabled.

-     */

-    public void testProject066()

-        throws Exception

-    {

-        doTestProject( "project-066", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with generateModuleId enabled and a custom module.

-     */

-    public void testProject067()

-        throws Exception

-    {

-        doTestProject( "project-067", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with the no-version file name mapping.

-     */

-    public void testProject068()

-        throws Exception

-    {

-        doTestProject( "project-068", new String[] { "eartest-ejb-sample-one.jar", "eartest-ejb-sample-two.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a custom library-directory and JavaEE 6.

-     */

-    public void testProject069()

-        throws Exception

-    {

-        doTestProject( "project-069", new String[] { "eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with application-name and initialize-in-order tags.

-     */

-    public void testProject070()

-        throws Exception

-    {

-        doTestProject( "project-070", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with application-name and initialize-in-order tags for unsupported version.

-     */

-    public void testProject071()

-        throws Exception

-    {

-        doTestProject( "project-071", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with an application client module (app-client).

-     */

-    public void testProject072()

-        throws Exception

-    {

-        doTestProject( "project-072", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-app-client-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with an application client module (app-client) and a default bundle directory for _java_ modules.

-     */

-    public void testProject073()

-        throws Exception

-    {

-        doTestProject( "project-073", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-app-client-sample-one-1.0.jar",

-            "APP-INF/lib/eartest-jar-sample-one-1.0.jar", "APP-INF/lib/eartest-jar-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom env entries settings and J2EE 1.3. Not supported by the specification so this should be

-     * ignored.

-     */

-    public void testProject074()

-        throws Exception

-    {

-        doTestProject( "project-074", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom env entries settings and J2EE 1.4. Not supported by the specification so this should be

-     * ignored.

-     */

-    public void testProject075()

-        throws Exception

-    {

-        doTestProject( "project-075", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom env entries settings and JavaEE 5. Not supported by the specification so this should be

-     * ignored.

-     */

-    public void testProject076()

-        throws Exception

-    {

-        doTestProject( "project-076", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom env entries settings and JavaEE 6.

-     */

-    public void testProject077()

-        throws Exception

-    {

-        doTestProject( "project-077", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with the no version for ejb file name mapping.

-     */

-    public void testProject078()

-        throws Exception

-    {

-        doTestProject( "project-078",

-                       new String[] { "ejb-sample-one.jar", "war-sample-one.war", "jar-sample-two.jar" } );

-    }

-

-    /**

-     * Builds an EAR with the 'default' library directory mode. Uses the value of the defaultLibBundleDir.

-     */

-    public void testProject079()

-        throws Exception

-    {

-        doTestProject( "project-079", new String[] { "eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with the 'empty' library directory mode. Generate an empty library-directory element.

-     */

-    public void testProject080()

-        throws Exception

-    {

-        doTestProject( "project-080", new String[] { "eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with the 'none' library directory mode. Does not generate an library-directory element.

-     */

-    public void testProject081()

-        throws Exception

-    {

-        doTestProject( "project-081", new String[] { "eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for JavaEE 7.

-     */

-    public void testProject082()

-        throws Exception

-    {

-        doTestProject( "project-082", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with a library directory and custom env entries. The library-directory element must come first

-     * (MEAR-158).

-     */

-    public void testProject083()

-        throws Exception

-    {

-        doTestProject( "project-083", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Support of an application id (MEAR-174).

-     */

-    public void testProject084()

-        throws Exception

-    {

-        doTestProject( "project-084", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom ejbRef entries settings and JavaEE 6.

-     */

-    public void testProject085()

-        throws Exception

-    {

-        doTestProject( "project-085", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with custom ejbRef entries plus lookup-name entry.

-     */

-    public void testProject086()

-        throws Exception

-    {

-        doTestProject( "project-086", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with resource-ref entries.

-     */

-    public void testProject087()

-        throws Exception

-    {

-        doTestProject( "project-087", new String[] { "eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar" } );

-    }

-

-    /**

-     * Builds WAR and EAR as part of multi-module project twice so that the 2nd build is guaranteed to be performed when

-     * target directories and files exist.

-     */

-    public void testProject088()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-two-1.0.war";

-        final String ejbModule = "eartest-ejb-sample-one-1.0.jar";

-        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";

-        final String[] expectedArtifacts = { warModule, ejbModule, jarSampleTwoLibrary };

-        final boolean[] artifactsDirectory = { false, true, false };

-        final String[] artifactsToValidateManifest = { warModule, ejbModule };

-        final boolean[] artifactsToValidateManifestDirectory = { false, true };

-        final String[][] expectedClassPathElements = { { jarSampleTwoLibrary }, { jarSampleTwoLibrary } };

-

-        // "Clean" build - target directories and files do not exist

-        // Pass cleanBeforeExecute parameter to ensure that target location is cleaned before Mojo execution

-        doTestProject( "project-088", "ear", expectedArtifacts, artifactsDirectory,

-            artifactsToValidateManifest, artifactsToValidateManifestDirectory, expectedClassPathElements, true );

-        // "Dirty" build - target directories and files exist

-        doTestProject( "project-088", "ear", expectedArtifacts, artifactsDirectory,

-            artifactsToValidateManifest, artifactsToValidateManifestDirectory, expectedClassPathElements, false );

-    }

-

-    /**

-     * Validates modification of Class-Path entry of EAR modules manifest when

-     * <ul>

-     * <li>skinnyWars option is turned on</li>

-     * <li>skipClassPathModification option is turned off</li>

-     * </ul>

-     */

-    public void testProject089()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";

-        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";

-        doTestProject( "project-089", "ear",

-            new String[] { warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary },

-            new boolean[] { false, false, false, false},

-            new String[] { warModule, ejbModule },

-            new boolean[] { false, false },

-            new String[][] { { jarSampleTwoLibrary, jarSampleThreeLibrary }, { jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-    }

-

-    /**

-     * Validates modification of Class-Path entry of EAR modules manifest when

-     * <ul>

-     * <li>skinnyWars option is turned on</li>

-     * <li>skipClassPathModification option is turned on</li>

-     * </ul>

-     */

-    public void testProject090()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";

-        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";

-        doTestProject( "project-090", "ear",

-            new String[] { warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary },

-            new boolean[] { false, false, false, false },

-            new String[] { warModule, ejbModule },

-            new boolean[] { false, false },

-            new String[][] { { jarSampleTwoLibrary }, { jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-    }

-

-    /**

-     * Validates modification of Class-Path entry of EAR modules manifest when

-     * <ul>

-     * <li>skinnyWars option is turned off</li>

-     * <li>skipClassPathModification option is turned off</li>

-     * <li>unpacking of EJB JARs is turned on</li>

-     * </ul>

-     */

-    public void testProject091()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";

-        final String jarSampleTwoLibrary = "eartest-jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "eartest-jar-sample-three-with-deps-1.0.jar";

-        doTestProject( "project-091", "ear",

-            new String[] { warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary },

-            new boolean[] { false, true, false, false },

-            new String[] { warModule, ejbModule },

-            new boolean[] { false, true },

-            new String[][] { { "jar-sample-two-1.0.jar" }, { jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-    }

-

-    /**

-     * Ensures that when

-     * <ul>

-     * <li>skinnyWars option is turned off (has default value)</li>

-     * <li>skinnyModules options is turned on</li>

-     * </ul>

-     * then movement of JARs and modification of manifest Class-Path entry is performed for WAR, SAR, HAR and RAR

-     * modules. Additionally this test ensures that

-     * <ul>

-     * <li>movement of JARs is not performed for modules whose libDirectory property doesn't point to the correct module

-     * entry containing JAR libraries packaged into the module</li>

-     * <li>JAR with provided scope is removed from modules and from Class-Path entries</li>

-     * </ul>

-     */

-    public void testProject092()

-        throws Exception

-    {

-        final String projectName = "project-092";

-        final String earModuleName = "ear";

-        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";

-        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";

-        final String jarSampleOneEarLibrary = "libs/eartest-" + jarSampleOneLibrary;

-        final String jarSampleTwoEarLibrary = "libs/eartest-" + jarSampleTwoLibrary;

-        final String jarSampleThreeEarLibrary = "libs/eartest-" + jarSampleThreeLibrary;

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String sarModuleTwo = "eartest-sar-sample-two-1.0.sar";

-        final String sarModuleThree = "eartest-sar-sample-three-1.0.sar";

-        final String sarModuleFour = "eartest-sar-sample-four-1.0.sar";

-        final String harModule = "eartest-har-sample-two-1.0.har";

-        final String rarModule = "eartest-rar-sample-one-1.0.rar";

-        final String[] earModules = { warModule, sarModuleTwo, sarModuleThree, sarModuleFour, harModule, rarModule };

-        final boolean[] earModuleDirectory = { false, false, false, false, false, false };

-        final String warModuleLibDir = "WEB-INF/lib/";

-        final String sarModuleTwoLibDir = "libraries/";

-        final String sarModuleThreeLibDir = "";

-        final String sarModuleFourLibDir = "lib/";

-        final String harModuleLibDir = "lib/";

-        final String rarModuleLibDir = "";

-

-        final File baseDir = doTestProject( projectName, earModuleName,

-            new String[] { warModule, sarModuleTwo, sarModuleThree, sarModuleFour, harModule, rarModule,

-                jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary },

-            new boolean[] { false, false, false, false, false, false, false, false, false },

-            earModules, earModuleDirectory,

-            new String[][] {

-                { jarSampleTwoEarLibrary, jarSampleOneEarLibrary, jarSampleThreeEarLibrary },

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary },

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary },

-                { jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary },

-                { jarSampleOneEarLibrary, jarSampleThreeEarLibrary, jarSampleTwoEarLibrary },

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary } },

-            true );

-

-        assertEarModulesContent( baseDir, projectName, earModuleName, earModules, earModuleDirectory,

-            new String[][] {

-                { warModuleLibDir },

-                { sarModuleTwoLibDir },

-                { sarModuleThreeLibDir },

-                { sarModuleFourLibDir + jarSampleOneLibrary },

-                { harModuleLibDir },

-                { rarModuleLibDir } },

-            new String[][] {

-                { warModuleLibDir + jarSampleTwoLibrary },

-                { sarModuleTwoLibDir + jarSampleTwoLibrary, sarModuleTwoLibDir + jarSampleThreeLibrary },

-                { sarModuleThreeLibDir + jarSampleTwoLibrary, sarModuleThreeLibDir + jarSampleThreeLibrary },

-                { },

-                { harModuleLibDir + jarSampleOneLibrary, harModuleLibDir + jarSampleTwoLibrary, harModuleLibDir + jarSampleThreeLibrary },

-                { rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary } } );

-    }

-

-    /**

-     * Ensures that when

-     * <ul>

-     * <li>skinnyWars option is turned on</li>

-     * <li>skinnyModules options is turned off (has default value)</li>

-     * </ul>

-     * then movement of JARs and modification of manifest Class-Path entry is performed only for WAR module and not for

-     * SAR, HAR and RAR modules.

-     */

-    public void testProject093()

-        throws Exception

-    {

-        final String projectName = "project-093";

-        final String earModuleName = "ear";

-        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";

-        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";

-        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;

-        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String sarModule = "eartest-sar-sample-two-1.0.sar";

-        final String harModule = "eartest-har-sample-two-1.0.har";

-        final String rarModule = "eartest-rar-sample-one-1.0.rar";

-        final String[] earModules = { warModule, sarModule, harModule, rarModule };

-        final boolean[] earModuleDirectory = { false, false, false, false };

-        final String warModuleLibDir = "WEB-INF/lib/";

-        final String sarModuleLibDir = "lib/";

-        final String harModuleLibDir = "lib/";

-        final String rarModuleLibDir = "";

-

-        final File baseDir = doTestProject( projectName, earModuleName,

-            new String[] { warModule, sarModule, harModule, rarModule, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary },

-            new boolean[] { false, false, false, false, false, false },

-            earModules, earModuleDirectory,

-            new String[][] {

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary },

-                { jarSampleThreeLibrary, jarSampleTwoLibrary, jarSampleOneLibrary },

-                null,

-                { jarSampleOneLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-

-        assertEarModulesContent( baseDir, projectName, earModuleName, earModules, earModuleDirectory,

-            new String[][] {

-                { warModuleLibDir },

-                { sarModuleLibDir + jarSampleOneLibrary, sarModuleLibDir + jarSampleTwoLibrary, sarModuleLibDir + jarSampleThreeLibrary },

-                { harModuleLibDir + jarSampleOneLibrary, harModuleLibDir + jarSampleTwoLibrary, harModuleLibDir + jarSampleThreeLibrary },

-                { rarModuleLibDir + jarSampleOneLibrary, rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary } } ,

-            new String[][] {

-                { warModuleLibDir + jarSampleTwoLibrary, warModuleLibDir + jarSampleThreeLibrary },

-                { },

-                { },

-                { } } );

-    }

-

-    /**

-     * Ensures that when

-     * <ul>

-     * <li>skinnyWars option is turned off (has default value)</li>

-     * <li>skinnyModules options is turned off (has default value)</li>

-     * </ul>

-     * then

-     * <ul>

-     * <li>movement of JARs and modification of the manifest Class-Path entry is not performed for WAR, SAR, HAR and

-     * RAR modules</li>

-     * <li>modification of the manifest Class-Path entry is performed for EJB module</li>

-     * <li>provided JAR is removed from the manifest Class-Path entry of EJB module</li>

-     * </ul>

-     */

-    public void testProject094()

-        throws Exception

-    {

-        final String projectName = "project-094";

-        final String earModuleName = "ear";

-        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";

-        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";

-        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;

-        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String sarModule = "eartest-sar-sample-two-1.0.sar";

-        final String harModule = "eartest-har-sample-two-1.0.har";

-        final String rarModule = "eartest-rar-sample-one-1.0.rar";

-        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";

-        final String[] earModules = { warModule, sarModule, harModule, rarModule, ejbModule };

-        final boolean[] earModuleDirectory = { false, false, false, false, false };

-        final String warModuleLibDir = "WEB-INF/lib/";

-        final String sarModuleLibDir = "lib/";

-        final String harModuleLibDir = "lib/";

-        final String rarModuleLibDir = "";

-

-        final File baseDir = doTestProject( projectName, earModuleName,

-            new String[] { warModule, sarModule, harModule, rarModule, ejbModule, jarSampleTwoEarLibrary,

-                jarSampleThreeEarLibrary },

-            new boolean[] { false, false, false, false, false, false, false },

-            earModules, earModuleDirectory,

-            new String[][] { null, null, null, null,

-                new String[] { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary } },

-            true );

-

-        assertEarModulesContent( baseDir, projectName, earModuleName, earModules, earModuleDirectory,

-            new String[][] {

-                { warModuleLibDir + jarSampleTwoLibrary, warModuleLibDir + jarSampleThreeLibrary },

-                { sarModuleLibDir + jarSampleOneLibrary, sarModuleLibDir + jarSampleTwoLibrary, sarModuleLibDir + jarSampleThreeLibrary },

-                { harModuleLibDir + jarSampleOneLibrary, harModuleLibDir + jarSampleTwoLibrary, harModuleLibDir + jarSampleThreeLibrary },

-                { rarModuleLibDir + jarSampleOneLibrary, rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary },

-                null } ,

-            null );

-    }

-

-    /**

-     * Ensures that test JAR dependency of WAR is handled as regular JAR in terms of packaging and manifest modification

-     * when skinnyWars option is turned on.

-     */

-    public void testProject095()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-two-1.0.war";

-        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";

-        final String jarSampleFourTestLibrary = "lib/eartest-jar-sample-four-1.0-tests.jar";

-        doTestProject( "project-095", "ear",

-            new String[] { warModule, jarSampleTwoLibrary, jarSampleThreeLibrary, jarSampleFourTestLibrary },

-            new boolean[] { false, false, false, false },

-            new String[] { warModule },

-            new boolean[] { false },

-            new String[][] { { jarSampleFourTestLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-    }

-

-    /**

-     * Ensures that test JAR dependency representing Java module is described in deployment descriptor

-     * if includeInApplicationXml property of module is {@code true}.

-     */

-    public void testProject096()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-two-1.0.war";

-        final String jarSampleTwoLibrary = "eartest-jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "eartest-jar-sample-three-with-deps-1.0.jar";

-        final String jarSampleFourTestLibrary = "eartest-jar-sample-four-1.0-tests.jar";

-        final String jarSampleFiveLibrary = "eartest-jar-sample-five-1.0.jar";

-        doTestProject( "project-096", "ear",

-            new String[] { warModule, jarSampleTwoLibrary, jarSampleThreeLibrary, jarSampleFourTestLibrary, jarSampleFiveLibrary },

-            new boolean[] { false, false, false, false, false },

-            new String[] { warModule },

-            new boolean[] { false },

-            new String[][] { { jarSampleFourTestLibrary, jarSampleFiveLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary } },

-            true );

-    }

-

-    /**

-     * Ensures that artifacts with jboss-sar, jboss-har and jboss-par types are packaged in EAR and

-     * described in deployment descriptor when respective types are configured for EAR modules.

-     */

-    public void testProject097()

-        throws Exception

-    {

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String sarSampleTwo = "eartest-sar-sample-two-1.0.sar";

-        final String harSampleTwo = "eartest-har-sample-two-1.0.har";

-        final String parSampleTwo = "eartest-par-sample-one-1.0.par";

-        final String[] artifacts = { warModule, sarSampleTwo, harSampleTwo, parSampleTwo };

-        final boolean[] artifactsDirectory = { false, false, false, false };

-        doTestProject( "project-097", "ear", artifacts, artifactsDirectory, null, null, null , true );

-    }

-

-    /**

-     * Ensures that when skinnyModules option is turned on then

-     * <ul>

-     * <li>EAR module whose classPathItem property is {@code false} is removed from the Class-Path entry of

-     * MANIFEST.mf of other modules</li>

-     * <li>EAR module whose classPathItem property is {@code true} is added into the Class-Path entry of MANIFEST.mf

-     * or existing reference is updated to match location of the module</li>

-     * <li>EAR module is removed from WARs and RARs (from modules which include their dependencies)</li>

-     * </ul>

-     */

-    public void testProject098()

-        throws Exception

-    {

-        final String projectName = "project-098";

-        final String earModuleName = "ear";

-        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";

-        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";

-        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";

-        final String ejbFourClientLibrary = "ejb-sample-four-1.0-client.jar";

-        final String jarSampleOneEarLibrary = "lib/eartest-" + jarSampleOneLibrary;

-        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;

-        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;

-        final String ejbFourClientEarLibrary = "lib/eartest-" + ejbFourClientLibrary;

-        final String ejbThreeLibrary = "ejb-sample-three-1.0.jar";

-        final String ejbFourLibrary = "ejb-sample-four-1.0.jar";

-        final String ejbThreeModule = "eartest-" + ejbThreeLibrary;

-        final String ejbFourModule = "eartest-" + ejbFourLibrary;

-        final String rarLibrary = "rar-sample-one-1.0.rar";

-        final String rarModule = "eartest-" + rarLibrary;

-        final String warModule = "eartest-war-sample-three-1.0.war";

-        final String[] earModules = { ejbThreeModule, ejbFourModule, rarModule, warModule };

-        final boolean[] earModuleDirectory = { false, false, false, false };

-        final String warModuleLibDir = "WEB-INF/lib/";

-        final String rarModuleLibDir = "";

-

-        final File baseDir = doTestProject( projectName, earModuleName,

-            new String[] { ejbThreeModule, ejbFourModule, rarModule, warModule,

-                jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary, ejbFourClientEarLibrary },

-            new boolean[] { false, false, false, false, false, false, false, false },

-            earModules, earModuleDirectory,

-            new String[][] {

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, ejbFourClientEarLibrary, jarSampleOneEarLibrary },

-                { jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary, ejbFourClientEarLibrary },

-                { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary, ejbFourClientEarLibrary },

-                { jarSampleOneEarLibrary, jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, ejbFourClientEarLibrary } },

-            true );

-

-        assertEarModulesContent( baseDir, projectName, earModuleName, earModules, earModuleDirectory,

-            new String[][] { null, null, null, { warModuleLibDir } },

-            new String[][] { null, null,

-                {

-                    rarModuleLibDir + jarSampleTwoLibrary,

-                    rarModuleLibDir + jarSampleThreeLibrary,

-                    rarModuleLibDir + ejbFourLibrary,

-                    rarModuleLibDir + ejbFourClientLibrary,

-                },

-                {

-                    warModuleLibDir + jarSampleOneLibrary,

-                    rarModuleLibDir + jarSampleThreeLibrary,

-                    rarModuleLibDir + jarSampleTwoLibrary,

-                    warModuleLibDir + ejbThreeLibrary,

-                    warModuleLibDir + ejbFourLibrary,

-                    warModuleLibDir + ejbFourClientLibrary,

-                    warModuleLibDir + rarLibrary,

-                    warModuleLibDir + rarLibrary

-                } } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for JakartaEE 9.

-     */

-    public void testProject099()

-            throws Exception

-    {

-        doTestProject( "project-099", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Builds an EAR with deployment descriptor configuration for JakartaEE 10.

-     */

-    public void testProject100()

-            throws Exception

-    {

-        doTestProject( "project-100", new String[] { "eartest-ejb-sample-one-1.0.jar" } );

-    }

-

-    /**

-     * Ensure that {@code defaultLibBundleDir} with dot at begin don't remove artifacts during second execution.

-     */

-    public void testProject101() throws Exception

-    {

-        String[] expectedArtifacts = new String[] {

-            "eartest-jar-sample-one-1.0.jar", "eartest-jar-sample-two-1.0.jar", "eartest-jar-sample-three-with-deps-1.0.jar" };

-

-        boolean[] artifactsDirectory = new boolean[expectedArtifacts.length];

-

-        doTestProject( "project-101", expectedArtifacts, true );

-        doTestProject( "project-101", expectedArtifacts, false );

-    }

-}

+/*
+ * 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.maven.plugins.ear.it;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.commons.io.IOUtils;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.ReaderFactory;
+
+/**
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarMojoIT extends AbstractEarPluginIT {
+
+    /**
+     * Builds an EAR with a single EJB and no configuration.
+     */
+    public void testProject001() throws Exception {
+        doTestProject("project-001", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a customized artifact location and a customized artifact name.
+     */
+    public void testProject002() throws Exception {
+        doTestProject("project-002", new String[] {"APP-INF/lib/eartest-ejb-sample-one-1.0.jar", "ejb-sample-two.jar"});
+    }
+
+    /**
+     * Builds an EAR with a default bundle directory for {@code java} modules.
+     */
+    public void testProject003() throws Exception {
+        doTestProject("project-003", new String[] {
+            "eartest-ejb-sample-one-1.0.jar",
+            "APP-INF/lib/eartest-jar-sample-one-1.0.jar",
+            "APP-INF/lib/eartest-jar-sample-two-1.0.jar"
+        });
+    }
+
+    /**
+     * Builds an EAR with a default bundle directory for _java_ modules and a custom location overriding the default.
+     */
+    public void testProject004() throws Exception {
+        doTestProject("project-004", new String[] {
+            "eartest-ejb-sample-one-1.0.jar",
+            "eartest-jar-sample-one-1.0.jar",
+            "APP-INF/lib/eartest-jar-sample-two-1.0.jar"
+        });
+    }
+
+    /**
+     * Builds an EAR with a custom URI.
+     */
+    public void testProject005() throws Exception {
+        doTestProject("project-005", new String[] {"eartest-ejb-sample-one-1.0.jar", "libs/another-name.jar"});
+    }
+
+    /**
+     * Builds an EAR with an excluded module.
+     */
+    public void testProject006() throws Exception {
+        doTestProject("project-006", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a classified artifact and no extra configuration.
+     */
+    public void testProject007() throws Exception {
+        doTestProject("project-007", new String[] {"eartest-ejb-sample-one-1.0-classified.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for J2EE 1.3.
+     */
+    public void testProject008() throws Exception {
+        doTestProject("project-008", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for J2EE 1.4.
+     */
+    public void testProject009() throws Exception {
+        doTestProject("project-009", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for Java EE 5.
+     */
+    public void testProject010() throws Exception {
+        doTestProject("project-010", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that deployment descriptor default settings are applied.
+     */
+    public void testProject011() throws Exception {
+        doTestProject("project-011", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that EAR resources are bundled within the EAR.
+     */
+    public void testProject012() throws Exception {
+        doTestProject("project-012", new String[] {"README.txt", "LICENSE.txt", "eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that EAR resources in a customized resources directory are bundled within the EAR.
+     */
+    public void testProject013() throws Exception {
+        doTestProject("project-013", new String[] {"README.txt", "LICENSE.txt", "eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that EAR resources are bundled within the EAR using includes and excludes.
+     */
+    public void testProject014() throws Exception {
+        doTestProject("project-014", new String[] {"LICENSE.txt", "eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that default manifest is taken into account.
+     */
+    public void testProject015() throws Exception {
+        final File baseDir = doTestProject("project-015", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+        final File expectedManifest = new File(baseDir, "src/main/application/META-INF/MANIFEST.MF");
+        final File actualManifest = new File(getEarDirectory(baseDir, "project-015"), "META-INF/MANIFEST.MF");
+        assertTrue("Manifest was not copied", actualManifest.exists());
+        assertTrue(FileUtils.contentEquals(expectedManifest, actualManifest));
+    }
+
+    /**
+     * Builds an EAR and make sure that custom manifest is taken into account.
+     */
+    public void testProject016() throws Exception {
+        final File baseDir = doTestProject("project-016", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+
+        final File createdEarFile = getEarArchive(baseDir, "project-016");
+
+        final File sourceManifestFile = new File(baseDir, "src/main/ear/MANIFEST.MF");
+
+        try (JarFile jarFile = new JarFile(createdEarFile);
+                FileInputStream in = new FileInputStream(sourceManifestFile)) {
+            Manifest manifestFromCreatedEARFile = jarFile.getManifest();
+            Manifest sourceManifest = new Manifest(in);
+            assertEquals("There are differences in the manifest.", sourceManifest, manifestFromCreatedEARFile);
+        }
+    }
+
+    /**
+     * Builds an EAR and make sure that custom application.xml is taken into account.
+     */
+    public void testProject017() throws Exception {
+        doTestProject("project-017", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a custom final name.
+     */
+    public void testProject018() throws Exception {
+        final File baseDir = executeMojo("project-018");
+        final File expectedFile = new File(baseDir, "target/my-custom-file.ear");
+        assertTrue("EAR archive not found", expectedFile.exists());
+    }
+
+    /**
+     * Builds an EAR with unpacked archives using the unpackTypes.
+     */
+    public void testProject019() throws Exception {
+        doTestProject(
+                "project-019",
+                new String[] {
+                    "eartest-ejb-sample-one-1.0.jar", "eartest-sar-sample-one-1.0.sar", "eartest-jar-sample-one-1.0.jar"
+                },
+                new boolean[] {false, true, true});
+    }
+
+    /**
+     * Builds an EAR with unpacked archives using the unpack module attribute.
+     */
+    public void testProject020() throws Exception {
+        doTestProject(
+                "project-020",
+                new String[] {
+                    "eartest-ejb-sample-one-1.0.jar", "eartest-sar-sample-one-1.0.sar", "eartest-jar-sample-one-1.0.jar"
+                },
+                new boolean[] {true, false, false});
+    }
+
+    /**
+     * Builds an EAR with unpacked archives using both unpackTypes and the unpack module attribute.
+     */
+    public void testProject021() throws Exception {
+        doTestProject(
+                "project-021",
+                new String[] {
+                    "eartest-ejb-sample-one-1.0.jar",
+                    "eartest-ejb-sample-two-1.0.jar",
+                    "eartest-sar-sample-one-1.0.sar",
+                    "eartest-jar-sample-one-1.0.jar",
+                    "eartest-jar-sample-two-1.0.jar"
+                },
+                new boolean[] {false, true, false, false, true});
+    }
+
+    /**
+     * Builds an EAR with a classifier.
+     */
+    public void testProject022() throws Exception {
+        final File baseDir = executeMojo("project-022");
+        final File expectedFile = new File(baseDir, "target/maven-ear-plugin-test-project-022-99.0-myclassifier.ear");
+        assertTrue("EAR archive not found", expectedFile.exists());
+    }
+
+    /**
+     * Builds an EAR and make sure that a single classified dependency is detected without specifying the classifier.
+     */
+    public void testProject023() throws Exception {
+        doTestProject(
+                "project-023",
+                new String[] {"eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-two-1.0.jar"},
+                new boolean[] {true, false});
+    }
+
+    /**
+     * Builds an EAR and make sure that a single classified dependency is detected when specifying the classifier.
+     */
+    public void testProject024() throws Exception {
+        doTestProject(
+                "project-024",
+                new String[] {"eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-two-1.0.jar"},
+                new boolean[] {true, false});
+    }
+
+    /**
+     * Builds an EAR and make sure that a classified dependency with multiple candidates is detected when specifying the
+     * classifier.
+     */
+    public void testProject025() throws Exception {
+        doTestProject(
+                "project-025",
+                new String[] {"eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-one-1.0.jar"},
+                new boolean[] {true, false});
+    }
+
+    /**
+     * Builds an EAR and make sure that the build fails if a unclassifed module configuration with multiple candidates is
+     * specified.
+     */
+    public void testProject026() throws Exception {
+        final File baseDir = executeMojo("project-026", false, true);
+        // Stupido, checks that the ear archive is not there
+        assertFalse(
+                "Execution should have failed",
+                getEarArchive(baseDir, "project-026").exists());
+    }
+
+    /**
+     * Builds an EAR and make sure that provided dependencies are not included in the EAR.
+     */
+    public void testProject027() throws Exception {
+        doTestProject("project-027", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that test dependencies are not included in the EAR.
+     */
+    public void testProject028() throws Exception {
+        doTestProject("project-028", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that system dependencies are not included in the EAR.
+     */
+    public void testProject029() throws Exception {
+        doTestProject("project-029", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that ejb-client dependencies are detected and not added by default in the generated
+     * application.xml.
+     */
+    public void testProject030() throws Exception {
+        doTestProject(
+                "project-030",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 4 configuration specifying the security domain and the unauthenticated-principal to
+     * use.
+     */
+    public void testProject031() throws Exception {
+        doTestProject("project-031", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 3.2 configuration specifying the jmx-name to use.
+     */
+    public void testProject032() throws Exception {
+        doTestProject("project-032", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 4 configuration and Jboss specific modules.
+     */
+    public void testProject033() throws Exception {
+        doTestProject("project-033", new String[] {
+            "eartest-ejb-sample-one-1.0.jar",
+            "eartest-ejb-sample-two-1.0.jar",
+            "eartest-sar-sample-one-1.0.sar",
+            "eartest-har-sample-one-1.0.har"
+        });
+    }
+
+    /**
+     * Builds an EAR with custom security settings.
+     */
+    public void testProject034() throws Exception {
+        doTestProject("project-034", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a full filename mapping and make sure that custom locations are not overridden.
+     */
+    public void testProject035() throws Exception {
+        doTestProject("project-035", new String[] {
+            "foo/eartest-ejb-sample-one-1.0.jar",
+            "eartest-ejb-sample-two-1.0.jar",
+            "libs/eartest-jar-sample-one-1.0.jar",
+            "libs/eartest-jar-sample-two-1.0.jar",
+            "sar-sample-one.sar"
+        });
+    }
+
+    /**
+     * Builds an EAR with a full filename mapping and make sure that groupIds with dots are replaced by dashes in
+     * filenames.
+     */
+    public void testProject036() throws Exception {
+        doTestProject("project-036", new String[] {
+            "foo/eartest-ejb-sample-one-1.0.jar",
+            "eartest-ejb-sample-two-1.0.jar",
+            "com.foo.bar-ejb-sample-one-1.0.jar",
+            "com.foo.bar-ejb-sample-two-1.0.jar",
+            "libs/eartest-jar-sample-one-1.0.jar",
+            "libs/eartest-jar-sample-two-1.0.jar",
+            "sar-sample-one.sar"
+        });
+    }
+
+    /**
+     * Builds an EAR and make sure that ejb-client dependencies are detected and added in the generated application.xml
+     * if includeInApplicationXml is set.
+     */
+    public void testProject037() throws Exception {
+        doTestProject(
+                "project-037",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR and make sure that a non-classified dependency with multiple candidates is detected when specifying
+     * the mainArtifactId as classifier.
+     */
+    public void testProject038() throws Exception {
+        doTestProject(
+                "project-038",
+                new String[] {"eartest-ejb-sample-one-1.0-classified.jar", "eartest-ejb-sample-one-1.0.jar"},
+                new boolean[] {false, true});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 4 configuration specifying specifying the loader repository to use.
+     */
+    public void testProject039() throws Exception {
+        doTestProject("project-039", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for Java EE 5 and an alternative deployment descriptor.
+     */
+    public void testProject040() throws Exception {
+        doTestProject("project-040", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 4.2 configuration specifying the module order to use.
+     */
+    public void testProject041() throws Exception {
+        doTestProject("project-041", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 4.2 configuration specifying a datasource to add.
+     */
+    public void testProject042() throws Exception {
+        doTestProject("project-042", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a custom descriptor location (generatedDescriptorLocation setting).
+     */
+    public void testProject043() throws Exception {
+        final File baseDir = doTestProject("project-043", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+        final File expectedApplicationXml = new File(baseDir, "target/custom-descriptor-dir/application.xml");
+        assertTrue("Application.xml file not found", expectedApplicationXml.exists());
+        assertFalse("Application.xml file should not be empty", expectedApplicationXml.length() == 0);
+    }
+
+    /**
+     * Builds an EAR with a custom library-directory.
+     */
+    public void testProject044() throws Exception {
+        doTestProject(
+                "project-044",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR and filter the content of the sources directory.
+     */
+    public void testProject045() throws Exception {
+        final File baseDir =
+                doTestProject("project-045", new String[] {"README.txt", "eartest-ejb-sample-one-1.0.jar"});
+        final File actualReadme = new File(getEarDirectory(baseDir, "project-045"), "README.txt");
+        final String content = IOUtils.toString(ReaderFactory.newReader(actualReadme, "UTF-8"));
+        assertTrue("application name and version was not filtered properly", content.contains("my-app 99.0"));
+        assertTrue("Escaping did not work properly", content.contains("will not be filtered ${application.name}."));
+    }
+
+    /**
+     * Builds an EAR and filter the content of the sources directory using a custom filter file.
+     */
+    public void testProject046() throws Exception {
+        final File baseDir =
+                doTestProject("project-046", new String[] {"README.txt", "eartest-ejb-sample-one-1.0.jar"});
+        final File actualReadme = new File(getEarDirectory(baseDir, "project-046"), "README.txt");
+        final String content = IOUtils.toString(ReaderFactory.newReader(actualReadme, "UTF-8"));
+        assertTrue("application name and version was not filtered properly", content.contains("my-app 99.0"));
+        assertTrue("application build was not filtered properly", content.contains("(Build 2)"));
+        assertTrue(
+                "Unknown property should not have been filtered",
+                content.contains("will not be filtered ${application.unknown}."));
+    }
+
+    /**
+     * Builds an EAR and filter the content with a list of extensions.
+     */
+    public void testProject047() throws Exception {
+        final File baseDir =
+                doTestProject("project-047", new String[] {"README.txt", "eartest-ejb-sample-one-1.0.jar"});
+        final File actualReadme = new File(getEarDirectory(baseDir, "project-047"), "README.txt");
+        final String content = IOUtils.toString(ReaderFactory.newReader(actualReadme, "UTF-8"));
+        assertTrue("application name and version should not have been filtered", !content.contains("my-app 99.0"));
+        assertTrue("original properties not found", content.contains("${application.name} ${project.version}"));
+    }
+
+    /**
+     * Builds an EAR with a JBoss 5 configuration containing library directory.
+     */
+    public void testProject048() throws Exception {
+        doTestProject("project-048", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a JBoss 4.2 configuration containing a library directory.
+     */
+    public void testProject049() throws Exception {
+        doTestProject("project-049", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 5 configuration containing a loader repository configuration definition.
+     */
+    public void testProject050() throws Exception {
+        doTestProject("project-050", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 5 configuration containing a loader repository class definition.
+     */
+    public void testProject051() throws Exception {
+        doTestProject("project-051", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 5 configuration containing a configuration parser class definition.
+     */
+    public void testProject052() throws Exception {
+        doTestProject("project-052", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a Jboss 5 configuration containing only the loader repo configuration
+     */
+    public void testProject053() throws Exception {
+        doTestProject("project-053", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for Java EE 5 and no application.xml
+     */
+    public void testProject054() throws Exception {
+        doTestProject("project-054", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with jar dependencies added in application.xml.
+     */
+    public void testProject055() throws Exception {
+        doTestProject("project-055", new String[] {
+            "eartest-jar-sample-one-1.0.jar",
+            "eartest-jar-sample-two-1.0.jar",
+            "eartest-jar-sample-three-with-deps-1.0.jar"
+        });
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for J2EE 1.4 and an alternative deployment descriptor.
+     */
+    public void testProject056() throws Exception {
+        doTestProject("project-056", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a complete JBoss 4.2 configuration and validate it matches the DTD (MEAR-104).
+     */
+    public void testProject057() throws Exception {
+        doTestProject("project-057", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for Java EE 6.
+     */
+    public void testProject058() throws Exception {
+        doTestProject("project-058", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with no display name entry at all.
+     */
+    public void testProject059() throws Exception {
+        doTestProject("project-059", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with ejb-client packaged for J2EE 1.3 (MEAR-85)
+     */
+    public void testProject060() throws Exception {
+        doTestProject(
+                "project-060",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with ejb-client packaged for J2EE 1.4 (MEAR-85)
+     */
+    public void testProject061() throws Exception {
+        doTestProject(
+                "project-061",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with ejb-client packaged for JavaEE 5 (MEAR-85)
+     */
+    public void testProject062() throws Exception {
+        doTestProject(
+                "project-062",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "lib/eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with ejb-client packaged for JavaEE 6 (MEAR-85)
+     */
+    public void testProject063() throws Exception {
+        doTestProject("project-063", new String[] {"lib/eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with ejb-client packaged for JavaEE 5 and still put it in the root (MEAR-85)
+     */
+    public void testProject064() throws Exception {
+        doTestProject(
+                "project-064",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0-client.jar"});
+    }
+
+    /**
+     * Builds an EAR with a custom moduleId.
+     */
+    public void testProject065() throws Exception {
+        doTestProject("project-065", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with generateModuleId enabled.
+     */
+    public void testProject066() throws Exception {
+        doTestProject("project-066", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with generateModuleId enabled and a custom module.
+     */
+    public void testProject067() throws Exception {
+        doTestProject("project-067", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with the no-version file name mapping.
+     */
+    public void testProject068() throws Exception {
+        doTestProject("project-068", new String[] {"eartest-ejb-sample-one.jar", "eartest-ejb-sample-two.jar"});
+    }
+
+    /**
+     * Builds an EAR with a custom library-directory and JavaEE 6.
+     */
+    public void testProject069() throws Exception {
+        doTestProject(
+                "project-069",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with application-name and initialize-in-order tags.
+     */
+    public void testProject070() throws Exception {
+        doTestProject("project-070", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with application-name and initialize-in-order tags for unsupported version.
+     */
+    public void testProject071() throws Exception {
+        doTestProject("project-071", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with an application client module (app-client).
+     */
+    public void testProject072() throws Exception {
+        doTestProject(
+                "project-072",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-app-client-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with an application client module (app-client) and a default bundle directory for _java_ modules.
+     */
+    public void testProject073() throws Exception {
+        doTestProject("project-073", new String[] {
+            "eartest-ejb-sample-one-1.0.jar",
+            "eartest-app-client-sample-one-1.0.jar",
+            "APP-INF/lib/eartest-jar-sample-one-1.0.jar",
+            "APP-INF/lib/eartest-jar-sample-two-1.0.jar"
+        });
+    }
+
+    /**
+     * Builds an EAR with custom env entries settings and J2EE 1.3. Not supported by the specification so this should be
+     * ignored.
+     */
+    public void testProject074() throws Exception {
+        doTestProject("project-074", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with custom env entries settings and J2EE 1.4. Not supported by the specification so this should be
+     * ignored.
+     */
+    public void testProject075() throws Exception {
+        doTestProject("project-075", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with custom env entries settings and JavaEE 5. Not supported by the specification so this should be
+     * ignored.
+     */
+    public void testProject076() throws Exception {
+        doTestProject("project-076", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with custom env entries settings and JavaEE 6.
+     */
+    public void testProject077() throws Exception {
+        doTestProject("project-077", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with the no version for ejb file name mapping.
+     */
+    public void testProject078() throws Exception {
+        doTestProject("project-078", new String[] {"ejb-sample-one.jar", "war-sample-one.war", "jar-sample-two.jar"});
+    }
+
+    /**
+     * Builds an EAR with the 'default' library directory mode. Uses the value of the defaultLibBundleDir.
+     */
+    public void testProject079() throws Exception {
+        doTestProject(
+                "project-079",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with the 'empty' library directory mode. Generate an empty library-directory element.
+     */
+    public void testProject080() throws Exception {
+        doTestProject(
+                "project-080",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with the 'none' library directory mode. Does not generate an library-directory element.
+     */
+    public void testProject081() throws Exception {
+        doTestProject(
+                "project-081",
+                new String[] {"eartest-ejb-sample-one-1.0.jar", "myLibs/eartest-jar-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for JavaEE 7.
+     */
+    public void testProject082() throws Exception {
+        doTestProject("project-082", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with a library directory and custom env entries. The library-directory element must come first
+     * (MEAR-158).
+     */
+    public void testProject083() throws Exception {
+        doTestProject("project-083", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Support of an application id (MEAR-174).
+     */
+    public void testProject084() throws Exception {
+        doTestProject("project-084", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with custom ejbRef entries settings and JavaEE 6.
+     */
+    public void testProject085() throws Exception {
+        doTestProject("project-085", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with custom ejbRef entries plus lookup-name entry.
+     */
+    public void testProject086() throws Exception {
+        doTestProject("project-086", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with resource-ref entries.
+     */
+    public void testProject087() throws Exception {
+        doTestProject("project-087", new String[] {"eartest-ejb-sample-one-1.0.jar", "eartest-ejb-sample-two-1.0.jar"});
+    }
+
+    /**
+     * Builds WAR and EAR as part of multi-module project twice so that the 2nd build is guaranteed to be performed when
+     * target directories and files exist.
+     */
+    public void testProject088() throws Exception {
+        final String warModule = "eartest-war-sample-two-1.0.war";
+        final String ejbModule = "eartest-ejb-sample-one-1.0.jar";
+        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";
+        final String[] expectedArtifacts = {warModule, ejbModule, jarSampleTwoLibrary};
+        final boolean[] artifactsDirectory = {false, true, false};
+        final String[] artifactsToValidateManifest = {warModule, ejbModule};
+        final boolean[] artifactsToValidateManifestDirectory = {false, true};
+        final String[][] expectedClassPathElements = {{jarSampleTwoLibrary}, {jarSampleTwoLibrary}};
+
+        // "Clean" build - target directories and files do not exist
+        // Pass cleanBeforeExecute parameter to ensure that target location is cleaned before Mojo execution
+        doTestProject(
+                "project-088",
+                "ear",
+                expectedArtifacts,
+                artifactsDirectory,
+                artifactsToValidateManifest,
+                artifactsToValidateManifestDirectory,
+                expectedClassPathElements,
+                true);
+        // "Dirty" build - target directories and files exist
+        doTestProject(
+                "project-088",
+                "ear",
+                expectedArtifacts,
+                artifactsDirectory,
+                artifactsToValidateManifest,
+                artifactsToValidateManifestDirectory,
+                expectedClassPathElements,
+                false);
+    }
+
+    /**
+     * Validates modification of Class-Path entry of EAR modules manifest when
+     * <ul>
+     * <li>skinnyWars option is turned on</li>
+     * <li>skipClassPathModification option is turned off</li>
+     * </ul>
+     */
+    public void testProject089() throws Exception {
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";
+        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";
+        doTestProject(
+                "project-089",
+                "ear",
+                new String[] {warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary},
+                new boolean[] {false, false, false, false},
+                new String[] {warModule, ejbModule},
+                new boolean[] {false, false},
+                new String[][] {
+                    {jarSampleTwoLibrary, jarSampleThreeLibrary}, {jarSampleThreeLibrary, jarSampleTwoLibrary}
+                },
+                true);
+    }
+
+    /**
+     * Validates modification of Class-Path entry of EAR modules manifest when
+     * <ul>
+     * <li>skinnyWars option is turned on</li>
+     * <li>skipClassPathModification option is turned on</li>
+     * </ul>
+     */
+    public void testProject090() throws Exception {
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";
+        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";
+        doTestProject(
+                "project-090",
+                "ear",
+                new String[] {warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary},
+                new boolean[] {false, false, false, false},
+                new String[] {warModule, ejbModule},
+                new boolean[] {false, false},
+                new String[][] {{jarSampleTwoLibrary}, {jarSampleThreeLibrary, jarSampleTwoLibrary}},
+                true);
+    }
+
+    /**
+     * Validates modification of Class-Path entry of EAR modules manifest when
+     * <ul>
+     * <li>skinnyWars option is turned off</li>
+     * <li>skipClassPathModification option is turned off</li>
+     * <li>unpacking of EJB JARs is turned on</li>
+     * </ul>
+     */
+    public void testProject091() throws Exception {
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";
+        final String jarSampleTwoLibrary = "eartest-jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "eartest-jar-sample-three-with-deps-1.0.jar";
+        doTestProject(
+                "project-091",
+                "ear",
+                new String[] {warModule, ejbModule, jarSampleTwoLibrary, jarSampleThreeLibrary},
+                new boolean[] {false, true, false, false},
+                new String[] {warModule, ejbModule},
+                new boolean[] {false, true},
+                new String[][] {{"jar-sample-two-1.0.jar"}, {jarSampleThreeLibrary, jarSampleTwoLibrary}},
+                true);
+    }
+
+    /**
+     * Ensures that when
+     * <ul>
+     * <li>skinnyWars option is turned off (has default value)</li>
+     * <li>skinnyModules options is turned on</li>
+     * </ul>
+     * then movement of JARs and modification of manifest Class-Path entry is performed for WAR, SAR, HAR and RAR
+     * modules. Additionally this test ensures that
+     * <ul>
+     * <li>movement of JARs is not performed for modules whose libDirectory property doesn't point to the correct module
+     * entry containing JAR libraries packaged into the module</li>
+     * <li>JAR with provided scope is removed from modules and from Class-Path entries</li>
+     * </ul>
+     */
+    public void testProject092() throws Exception {
+        final String projectName = "project-092";
+        final String earModuleName = "ear";
+        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";
+        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleOneEarLibrary = "libs/eartest-" + jarSampleOneLibrary;
+        final String jarSampleTwoEarLibrary = "libs/eartest-" + jarSampleTwoLibrary;
+        final String jarSampleThreeEarLibrary = "libs/eartest-" + jarSampleThreeLibrary;
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String sarModuleTwo = "eartest-sar-sample-two-1.0.sar";
+        final String sarModuleThree = "eartest-sar-sample-three-1.0.sar";
+        final String sarModuleFour = "eartest-sar-sample-four-1.0.sar";
+        final String harModule = "eartest-har-sample-two-1.0.har";
+        final String rarModule = "eartest-rar-sample-one-1.0.rar";
+        final String[] earModules = {warModule, sarModuleTwo, sarModuleThree, sarModuleFour, harModule, rarModule};
+        final boolean[] earModuleDirectory = {false, false, false, false, false, false};
+        final String warModuleLibDir = "WEB-INF/lib/";
+        final String sarModuleTwoLibDir = "libraries/";
+        final String sarModuleThreeLibDir = "";
+        final String sarModuleFourLibDir = "lib/";
+        final String harModuleLibDir = "lib/";
+        final String rarModuleLibDir = "";
+
+        final File baseDir = doTestProject(
+                projectName,
+                earModuleName,
+                new String[] {
+                    warModule,
+                    sarModuleTwo,
+                    sarModuleThree,
+                    sarModuleFour,
+                    harModule,
+                    rarModule,
+                    jarSampleOneEarLibrary,
+                    jarSampleTwoEarLibrary,
+                    jarSampleThreeEarLibrary
+                },
+                new boolean[] {false, false, false, false, false, false, false, false, false},
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {jarSampleTwoEarLibrary, jarSampleOneEarLibrary, jarSampleThreeEarLibrary},
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary},
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary},
+                    {jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary},
+                    {jarSampleOneEarLibrary, jarSampleThreeEarLibrary, jarSampleTwoEarLibrary},
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary}
+                },
+                true);
+
+        assertEarModulesContent(
+                baseDir,
+                projectName,
+                earModuleName,
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {warModuleLibDir},
+                    {sarModuleTwoLibDir},
+                    {sarModuleThreeLibDir},
+                    {sarModuleFourLibDir + jarSampleOneLibrary},
+                    {harModuleLibDir},
+                    {rarModuleLibDir}
+                },
+                new String[][] {
+                    {warModuleLibDir + jarSampleTwoLibrary},
+                    {sarModuleTwoLibDir + jarSampleTwoLibrary, sarModuleTwoLibDir + jarSampleThreeLibrary},
+                    {sarModuleThreeLibDir + jarSampleTwoLibrary, sarModuleThreeLibDir + jarSampleThreeLibrary},
+                    {},
+                    {
+                        harModuleLibDir + jarSampleOneLibrary,
+                        harModuleLibDir + jarSampleTwoLibrary,
+                        harModuleLibDir + jarSampleThreeLibrary
+                    },
+                    {rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary}
+                });
+    }
+
+    /**
+     * Ensures that when
+     * <ul>
+     * <li>skinnyWars option is turned on</li>
+     * <li>skinnyModules options is turned off (has default value)</li>
+     * </ul>
+     * then movement of JARs and modification of manifest Class-Path entry is performed only for WAR module and not for
+     * SAR, HAR and RAR modules.
+     */
+    public void testProject093() throws Exception {
+        final String projectName = "project-093";
+        final String earModuleName = "ear";
+        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";
+        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;
+        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String sarModule = "eartest-sar-sample-two-1.0.sar";
+        final String harModule = "eartest-har-sample-two-1.0.har";
+        final String rarModule = "eartest-rar-sample-one-1.0.rar";
+        final String[] earModules = {warModule, sarModule, harModule, rarModule};
+        final boolean[] earModuleDirectory = {false, false, false, false};
+        final String warModuleLibDir = "WEB-INF/lib/";
+        final String sarModuleLibDir = "lib/";
+        final String harModuleLibDir = "lib/";
+        final String rarModuleLibDir = "";
+
+        final File baseDir = doTestProject(
+                projectName,
+                earModuleName,
+                new String[] {
+                    warModule, sarModule, harModule, rarModule, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary
+                },
+                new boolean[] {false, false, false, false, false, false},
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary},
+                    {jarSampleThreeLibrary, jarSampleTwoLibrary, jarSampleOneLibrary},
+                    null,
+                    {jarSampleOneLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary}
+                },
+                true);
+
+        assertEarModulesContent(
+                baseDir,
+                projectName,
+                earModuleName,
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {warModuleLibDir},
+                    {
+                        sarModuleLibDir + jarSampleOneLibrary,
+                        sarModuleLibDir + jarSampleTwoLibrary,
+                        sarModuleLibDir + jarSampleThreeLibrary
+                    },
+                    {
+                        harModuleLibDir + jarSampleOneLibrary,
+                        harModuleLibDir + jarSampleTwoLibrary,
+                        harModuleLibDir + jarSampleThreeLibrary
+                    },
+                    {
+                        rarModuleLibDir + jarSampleOneLibrary,
+                        rarModuleLibDir + jarSampleTwoLibrary,
+                        rarModuleLibDir + jarSampleThreeLibrary
+                    }
+                },
+                new String[][] {
+                    {warModuleLibDir + jarSampleTwoLibrary, warModuleLibDir + jarSampleThreeLibrary},
+                    {},
+                    {},
+                    {}
+                });
+    }
+
+    /**
+     * Ensures that when
+     * <ul>
+     * <li>skinnyWars option is turned off (has default value)</li>
+     * <li>skinnyModules options is turned off (has default value)</li>
+     * </ul>
+     * then
+     * <ul>
+     * <li>movement of JARs and modification of the manifest Class-Path entry is not performed for WAR, SAR, HAR and
+     * RAR modules</li>
+     * <li>modification of the manifest Class-Path entry is performed for EJB module</li>
+     * <li>provided JAR is removed from the manifest Class-Path entry of EJB module</li>
+     * </ul>
+     */
+    public void testProject094() throws Exception {
+        final String projectName = "project-094";
+        final String earModuleName = "ear";
+        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";
+        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;
+        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String sarModule = "eartest-sar-sample-two-1.0.sar";
+        final String harModule = "eartest-har-sample-two-1.0.har";
+        final String rarModule = "eartest-rar-sample-one-1.0.rar";
+        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";
+        final String[] earModules = {warModule, sarModule, harModule, rarModule, ejbModule};
+        final boolean[] earModuleDirectory = {false, false, false, false, false};
+        final String warModuleLibDir = "WEB-INF/lib/";
+        final String sarModuleLibDir = "lib/";
+        final String harModuleLibDir = "lib/";
+        final String rarModuleLibDir = "";
+
+        final File baseDir = doTestProject(
+                projectName,
+                earModuleName,
+                new String[] {
+                    warModule,
+                    sarModule,
+                    harModule,
+                    rarModule,
+                    ejbModule,
+                    jarSampleTwoEarLibrary,
+                    jarSampleThreeEarLibrary
+                },
+                new boolean[] {false, false, false, false, false, false, false},
+                earModules,
+                earModuleDirectory,
+                new String[][] {null, null, null, null, new String[] {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary}
+                },
+                true);
+
+        assertEarModulesContent(
+                baseDir,
+                projectName,
+                earModuleName,
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {warModuleLibDir + jarSampleTwoLibrary, warModuleLibDir + jarSampleThreeLibrary},
+                    {
+                        sarModuleLibDir + jarSampleOneLibrary,
+                        sarModuleLibDir + jarSampleTwoLibrary,
+                        sarModuleLibDir + jarSampleThreeLibrary
+                    },
+                    {
+                        harModuleLibDir + jarSampleOneLibrary,
+                        harModuleLibDir + jarSampleTwoLibrary,
+                        harModuleLibDir + jarSampleThreeLibrary
+                    },
+                    {
+                        rarModuleLibDir + jarSampleOneLibrary,
+                        rarModuleLibDir + jarSampleTwoLibrary,
+                        rarModuleLibDir + jarSampleThreeLibrary
+                    },
+                    null
+                },
+                null);
+    }
+
+    /**
+     * Ensures that test JAR dependency of WAR is handled as regular JAR in terms of packaging and manifest modification
+     * when skinnyWars option is turned on.
+     */
+    public void testProject095() throws Exception {
+        final String warModule = "eartest-war-sample-two-1.0.war";
+        final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleFourTestLibrary = "lib/eartest-jar-sample-four-1.0-tests.jar";
+        doTestProject(
+                "project-095",
+                "ear",
+                new String[] {warModule, jarSampleTwoLibrary, jarSampleThreeLibrary, jarSampleFourTestLibrary},
+                new boolean[] {false, false, false, false},
+                new String[] {warModule},
+                new boolean[] {false},
+                new String[][] {{jarSampleFourTestLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary}},
+                true);
+    }
+
+    /**
+     * Ensures that test JAR dependency representing Java module is described in deployment descriptor
+     * if includeInApplicationXml property of module is {@code true}.
+     */
+    public void testProject096() throws Exception {
+        final String warModule = "eartest-war-sample-two-1.0.war";
+        final String jarSampleTwoLibrary = "eartest-jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "eartest-jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleFourTestLibrary = "eartest-jar-sample-four-1.0-tests.jar";
+        final String jarSampleFiveLibrary = "eartest-jar-sample-five-1.0.jar";
+        doTestProject(
+                "project-096",
+                "ear",
+                new String[] {
+                    warModule,
+                    jarSampleTwoLibrary,
+                    jarSampleThreeLibrary,
+                    jarSampleFourTestLibrary,
+                    jarSampleFiveLibrary
+                },
+                new boolean[] {false, false, false, false, false},
+                new String[] {warModule},
+                new boolean[] {false},
+                new String[][] {
+                    {jarSampleFourTestLibrary, jarSampleFiveLibrary, jarSampleThreeLibrary, jarSampleTwoLibrary}
+                },
+                true);
+    }
+
+    /**
+     * Ensures that artifacts with jboss-sar, jboss-har and jboss-par types are packaged in EAR and
+     * described in deployment descriptor when respective types are configured for EAR modules.
+     */
+    public void testProject097() throws Exception {
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String sarSampleTwo = "eartest-sar-sample-two-1.0.sar";
+        final String harSampleTwo = "eartest-har-sample-two-1.0.har";
+        final String parSampleTwo = "eartest-par-sample-one-1.0.par";
+        final String[] artifacts = {warModule, sarSampleTwo, harSampleTwo, parSampleTwo};
+        final boolean[] artifactsDirectory = {false, false, false, false};
+        doTestProject("project-097", "ear", artifacts, artifactsDirectory, null, null, null, true);
+    }
+
+    /**
+     * Ensures that when skinnyModules option is turned on then
+     * <ul>
+     * <li>EAR module whose classPathItem property is {@code false} is removed from the Class-Path entry of
+     * MANIFEST.mf of other modules</li>
+     * <li>EAR module whose classPathItem property is {@code true} is added into the Class-Path entry of MANIFEST.mf
+     * or existing reference is updated to match location of the module</li>
+     * <li>EAR module is removed from WARs and RARs (from modules which include their dependencies)</li>
+     * </ul>
+     */
+    public void testProject098() throws Exception {
+        final String projectName = "project-098";
+        final String earModuleName = "ear";
+        final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";
+        final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";
+        final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";
+        final String ejbFourClientLibrary = "ejb-sample-four-1.0-client.jar";
+        final String jarSampleOneEarLibrary = "lib/eartest-" + jarSampleOneLibrary;
+        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;
+        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;
+        final String ejbFourClientEarLibrary = "lib/eartest-" + ejbFourClientLibrary;
+        final String ejbThreeLibrary = "ejb-sample-three-1.0.jar";
+        final String ejbFourLibrary = "ejb-sample-four-1.0.jar";
+        final String ejbThreeModule = "eartest-" + ejbThreeLibrary;
+        final String ejbFourModule = "eartest-" + ejbFourLibrary;
+        final String rarLibrary = "rar-sample-one-1.0.rar";
+        final String rarModule = "eartest-" + rarLibrary;
+        final String warModule = "eartest-war-sample-three-1.0.war";
+        final String[] earModules = {ejbThreeModule, ejbFourModule, rarModule, warModule};
+        final boolean[] earModuleDirectory = {false, false, false, false};
+        final String warModuleLibDir = "WEB-INF/lib/";
+        final String rarModuleLibDir = "";
+
+        final File baseDir = doTestProject(
+                projectName,
+                earModuleName,
+                new String[] {
+                    ejbThreeModule,
+                    ejbFourModule,
+                    rarModule,
+                    warModule,
+                    jarSampleOneEarLibrary,
+                    jarSampleTwoEarLibrary,
+                    jarSampleThreeEarLibrary,
+                    ejbFourClientEarLibrary
+                },
+                new boolean[] {false, false, false, false, false, false, false, false},
+                earModules,
+                earModuleDirectory,
+                new String[][] {
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, ejbFourClientEarLibrary, jarSampleOneEarLibrary},
+                    {jarSampleOneEarLibrary, jarSampleTwoEarLibrary, jarSampleThreeEarLibrary, ejbFourClientEarLibrary},
+                    {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, jarSampleOneEarLibrary, ejbFourClientEarLibrary},
+                    {jarSampleOneEarLibrary, jarSampleThreeEarLibrary, jarSampleTwoEarLibrary, ejbFourClientEarLibrary}
+                },
+                true);
+
+        assertEarModulesContent(
+                baseDir,
+                projectName,
+                earModuleName,
+                earModules,
+                earModuleDirectory,
+                new String[][] {null, null, null, {warModuleLibDir}},
+                new String[][] {
+                    null,
+                    null,
+                    {
+                        rarModuleLibDir + jarSampleTwoLibrary,
+                        rarModuleLibDir + jarSampleThreeLibrary,
+                        rarModuleLibDir + ejbFourLibrary,
+                        rarModuleLibDir + ejbFourClientLibrary,
+                    },
+                    {
+                        warModuleLibDir + jarSampleOneLibrary,
+                        rarModuleLibDir + jarSampleThreeLibrary,
+                        rarModuleLibDir + jarSampleTwoLibrary,
+                        warModuleLibDir + ejbThreeLibrary,
+                        warModuleLibDir + ejbFourLibrary,
+                        warModuleLibDir + ejbFourClientLibrary,
+                        warModuleLibDir + rarLibrary,
+                        warModuleLibDir + rarLibrary
+                    }
+                });
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for JakartaEE 9.
+     */
+    public void testProject099() throws Exception {
+        doTestProject("project-099", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Builds an EAR with deployment descriptor configuration for JakartaEE 10.
+     */
+    public void testProject100() throws Exception {
+        doTestProject("project-100", new String[] {"eartest-ejb-sample-one-1.0.jar"});
+    }
+
+    /**
+     * Ensure that {@code defaultLibBundleDir} with dot at begin don't remove artifacts during second execution.
+     */
+    public void testProject101() throws Exception {
+        String[] expectedArtifacts = new String[] {
+            "eartest-jar-sample-one-1.0.jar",
+            "eartest-jar-sample-two-1.0.jar",
+            "eartest-jar-sample-three-with-deps-1.0.jar"
+        };
+
+        boolean[] artifactsDirectory = new boolean[expectedArtifacts.length];
+
+        doTestProject("project-101", expectedArtifacts, true);
+        doTestProject("project-101", expectedArtifacts, false);
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/stub/ArtifactHandlerTestStub.java b/src/test/java/org/apache/maven/plugins/ear/stub/ArtifactHandlerTestStub.java
index 38ed9ef..4e078f8 100644
--- a/src/test/java/org/apache/maven/plugins/ear/stub/ArtifactHandlerTestStub.java
+++ b/src/test/java/org/apache/maven/plugins/ear/stub/ArtifactHandlerTestStub.java
@@ -1,72 +1,80 @@
-package org.apache.maven.plugins.ear.stub;

-

-/*

- * 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.

- */

-

-import org.apache.maven.artifact.handler.ArtifactHandler;

-

-/**

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ArtifactHandlerTestStub

-    implements ArtifactHandler

-{

-

-    private final String extension;

-

-    public ArtifactHandlerTestStub( String extension )

-    {

-        this.extension = extension;

-    }

-

-    public String getExtension()

-    {

-        return extension;

-    }

-

-    public String getDirectory()

-    {

-        throw new UnsupportedOperationException( "not implemented ; fake artifact stub" );

-    }

-

-    public String getClassifier()

-    {

-        return null;

-    }

-

-    public String getPackaging()

-    {

-        throw new UnsupportedOperationException( "not implemented ; fake artifact stub" );

-    }

-

-    public boolean isIncludesDependencies()

-    {

-        throw new UnsupportedOperationException( "not implemented ; fake artifact stub" );

-    }

-

-    public String getLanguage()

-    {

-        throw new UnsupportedOperationException( "not implemented ; fake artifact stub" );

-    }

-

-    public boolean isAddedToClasspath()

-    {

-        throw new UnsupportedOperationException( "not implemented ; fake artifact stub" );

-    }

-}

+/*
+ * 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.maven.plugins.ear.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+/**
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ArtifactHandlerTestStub implements ArtifactHandler {
+
+    private final String extension;
+
+    public ArtifactHandlerTestStub(String extension) {
+        this.extension = extension;
+    }
+
+    public String getExtension() {
+        return extension;
+    }
+
+    public String getDirectory() {
+        throw new UnsupportedOperationException("not implemented ; fake artifact stub");
+    }
+
+    public String getClassifier() {
+        return null;
+    }
+
+    public String getPackaging() {
+        throw new UnsupportedOperationException("not implemented ; fake artifact stub");
+    }
+
+    public boolean isIncludesDependencies() {
+        throw new UnsupportedOperationException("not implemented ; fake artifact stub");
+    }
+
+    public String getLanguage() {
+        throw new UnsupportedOperationException("not implemented ; fake artifact stub");
+    }
+
+    public boolean isAddedToClasspath() {
+        throw new UnsupportedOperationException("not implemented ; fake artifact stub");
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/util/ArtifactRepositoryTest.java b/src/test/java/org/apache/maven/plugins/ear/util/ArtifactRepositoryTest.java
index 0f8218c..596ceda 100644
--- a/src/test/java/org/apache/maven/plugins/ear/util/ArtifactRepositoryTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/util/ArtifactRepositoryTest.java
@@ -1,104 +1,118 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import static org.junit.Assert.assertNotNull;

-import static org.junit.Assert.assertNull;

-

-import java.util.HashSet;

-import java.util.Set;

-

-import org.apache.maven.artifact.Artifact;

-import org.apache.maven.plugins.ear.AbstractEarTestBase;

-import org.junit.Test;

-

-/**

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ArtifactRepositoryTest

-    extends AbstractEarTestBase

-{

-

-    private static final String MAIN_ARTIFACT_ID = "none";

-

-    private ArtifactTypeMappingService artifactTypeMappingService = new ArtifactTypeMappingService();

-

-    @Test

-    public void testEmptyRepository()

-    {

-        Set<Artifact> artifacts = new HashSet<>();

-        ArtifactRepository repo = new ArtifactRepository( artifacts, MAIN_ARTIFACT_ID, artifactTypeMappingService );

-        assertNull( repo.getUniqueArtifact( "ear", "ar", "jar" ) );

-        assertNull( repo.getUniqueArtifact( "ear", "ar", "jar", null ) );

-        assertNull( repo.getUniqueArtifact( "ear", "ar", "jar", "class" ) );

-    }

-

-    @Test

-    public void testRepositoryWithOneUnclassifiedArtifact()

-    {

-        ArtifactRepository repo =

-            new ArtifactRepository( createArtifacts( new String[] { "myartifact" } ), MAIN_ARTIFACT_ID,

-                                    artifactTypeMappingService );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", null ) );

-    }

-

-    @Test

-    public void testRepositoryWithOneClassifiedArtifact()

-    {

-        ArtifactRepository repo =

-            new ArtifactRepository( createArtifacts( new String[] { "myartifact" },

-                                                     new String[] { "classified" } ), MAIN_ARTIFACT_ID,

-                                    artifactTypeMappingService );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "classified" ) );

-        assertNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "wrong" ) );

-    }

-

-    @Test

-    public void testRepositoryWithMultipleClassifiedArtifacts()

-    {

-        ArtifactRepository repo =

-            new ArtifactRepository( createArtifacts( new String[] { "myartifact", "myartifact", "myartifact" }, 

-                                                     new String[] { "class1", "class2", "class3" } ),

-                                    MAIN_ARTIFACT_ID, artifactTypeMappingService );

-

-        assertNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "class1" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "class2" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "class3" ) );

-        assertNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "wrong" ) );

-    }

-

-    @Test

-    public void testRepositoryWithMultipleClassifiedArtifactsAndMainArtifact()

-    {

-        ArtifactRepository repo =

-            new ArtifactRepository( createArtifacts( new String[] { "myartifact", "myartifact", "myartifact" },

-                                                     new String[] { "class1", "class2", null } ),

-                                    MAIN_ARTIFACT_ID, artifactTypeMappingService );

-

-        assertNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "class1" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "class2" ) );

-        assertNotNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", MAIN_ARTIFACT_ID ) );

-        assertNull( repo.getUniqueArtifact( DEFAULT_GROUPID, "myartifact", "jar", "wrong" ) );

-    }

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugins.ear.AbstractEarTestBase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ArtifactRepositoryTest extends AbstractEarTestBase {
+
+    private static final String MAIN_ARTIFACT_ID = "none";
+
+    private ArtifactTypeMappingService artifactTypeMappingService = new ArtifactTypeMappingService();
+
+    @Test
+    public void testEmptyRepository() {
+        Set<Artifact> artifacts = new HashSet<>();
+        ArtifactRepository repo = new ArtifactRepository(artifacts, MAIN_ARTIFACT_ID, artifactTypeMappingService);
+        assertNull(repo.getUniqueArtifact("ear", "ar", "jar"));
+        assertNull(repo.getUniqueArtifact("ear", "ar", "jar", null));
+        assertNull(repo.getUniqueArtifact("ear", "ar", "jar", "class"));
+    }
+
+    @Test
+    public void testRepositoryWithOneUnclassifiedArtifact() {
+        ArtifactRepository repo = new ArtifactRepository(
+                createArtifacts(new String[] {"myartifact"}), MAIN_ARTIFACT_ID, artifactTypeMappingService);
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", null));
+    }
+
+    @Test
+    public void testRepositoryWithOneClassifiedArtifact() {
+        ArtifactRepository repo = new ArtifactRepository(
+                createArtifacts(new String[] {"myartifact"}, new String[] {"classified"}),
+                MAIN_ARTIFACT_ID,
+                artifactTypeMappingService);
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "classified"));
+        assertNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "wrong"));
+    }
+
+    @Test
+    public void testRepositoryWithMultipleClassifiedArtifacts() {
+        ArtifactRepository repo = new ArtifactRepository(
+                createArtifacts(
+                        new String[] {"myartifact", "myartifact", "myartifact"},
+                        new String[] {"class1", "class2", "class3"}),
+                MAIN_ARTIFACT_ID,
+                artifactTypeMappingService);
+
+        assertNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "class1"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "class2"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "class3"));
+        assertNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "wrong"));
+    }
+
+    @Test
+    public void testRepositoryWithMultipleClassifiedArtifactsAndMainArtifact() {
+        ArtifactRepository repo = new ArtifactRepository(
+                createArtifacts(
+                        new String[] {"myartifact", "myartifact", "myartifact"},
+                        new String[] {"class1", "class2", null}),
+                MAIN_ARTIFACT_ID,
+                artifactTypeMappingService);
+
+        assertNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "class1"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "class2"));
+        assertNotNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", MAIN_ARTIFACT_ID));
+        assertNull(repo.getUniqueArtifact(DEFAULT_GROUPID, "myartifact", "jar", "wrong"));
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingServiceTest.java b/src/test/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingServiceTest.java
index 4805368..8e897af 100644
--- a/src/test/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingServiceTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/util/ArtifactTypeMappingServiceTest.java
@@ -1,248 +1,214 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import junit.framework.TestCase;

-

-import org.apache.maven.plugins.ear.EarModuleFactory;

-import org.apache.maven.plugins.ear.EarPluginException;

-import org.apache.maven.plugins.ear.UnknownArtifactTypeException;

-import org.codehaus.plexus.configuration.PlexusConfigurationException;

-import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;

-

-/**

- * Tests for the {@link ArtifactTypeMappingService}

- * 

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class ArtifactTypeMappingServiceTest

-    extends TestCase

-{

-

-    public void testDefaultConfiguration()

-    {

-        ArtifactTypeMappingService service = getDefaultService();

-        for ( String type : EarModuleFactory.getStandardArtifactTypes() )

-        {

-            assertTrue( "Standard type could not be found", service.isMappedToType( type, type ) );

-        }

-    }

-

-    public void testIsMappedToTypeForUnknownType()

-    {

-        ArtifactTypeMappingService service = getDefaultService();

-        assertFalse( service.isMappedToType( "rar", "MyKoolCustomType" ) );

-    }

-

-    public void testIsMappedToTypeForKnownType()

-    {

-        ArtifactTypeMappingService service = getServiceWithRarMappingToMyRar();

-        assertTrue( service.isMappedToType( "rar", "MyRar" ) );

-    }

-

-    public void testGetStandardTypeForUknonwnType()

-    {

-        try

-        {

-            ArtifactTypeMappingService service = getDefaultService();

-            service.getStandardType( "MyKoolCustomType" );

-            fail( "Should have failed to retrieve a unknwon custom type" );

-        }

-        catch ( UnknownArtifactTypeException e )

-        {

-            // That's good

-        }

-    }

-

-    public void testGetStandardTypeForKnownType()

-    {

-        try

-        {

-            ArtifactTypeMappingService service = getServiceWithRarMappingToMyRar();

-            assertEquals( "rar", service.getStandardType( "MyRar" ) );

-        }

-        catch ( UnknownArtifactTypeException e )

-        {

-            fail( "Should not have failed to retrieve a knwon custom type " + e.getMessage() );

-        }

-    }

-

-    public void testConfigWithSameCustomType()

-    {

-        try

-        {

-            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration( "dummy" );

-            XmlPlexusConfiguration childConfig =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "type", "generic" );

-            childConfig.setAttribute( "mapping", "rar" );

-            XmlPlexusConfiguration childConfig2 =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "type", "generic" );

-            childConfig.setAttribute( "mapping", "ejb" );

-

-            rootConfig.addChild( childConfig );

-            rootConfig.addChild( childConfig2 );

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( rootConfig );

-            fail( "Should have failed" );

-        }

-        catch ( EarPluginException e )

-        {

-            // OK

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( "Unexpected " + e.getMessage() );

-        }

-    }

-

-    public void testConfigWithUnknownStandardType()

-    {

-        try

-        {

-            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration( "dummy" );

-            XmlPlexusConfiguration childConfig =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "type", "generic" );

-            childConfig.setAttribute( "mapping", "notAStandardType" );

-

-            rootConfig.addChild( childConfig );

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( rootConfig );

-            fail( "Should have failed" );

-        }

-        catch ( EarPluginException e )

-        {

-            // OK

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( "Unexpected " + e.getMessage() );

-        }

-    }

-

-    public void testConfigWithNoType()

-    {

-        try

-        {

-            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration( "dummy" );

-            XmlPlexusConfiguration childConfig =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "mapping", "ejb" );

-

-            rootConfig.addChild( childConfig );

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( rootConfig );

-            fail( "Should have failed" );

-        }

-        catch ( EarPluginException e )

-        {

-            // OK

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( "Unexpected " + e.getMessage() );

-        }

-    }

-

-    public void testConfigWithNoMapping()

-    {

-        try

-        {

-            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration( "dummy" );

-            XmlPlexusConfiguration childConfig =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "type", "generic" );

-

-            rootConfig.addChild( childConfig );

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( rootConfig );

-            fail( "Should have failed" );

-        }

-        catch ( EarPluginException e )

-        {

-            // OK

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( "Unexpected " + e.getMessage() );

-        }

-    }

-

-    // Utilities

-

-    protected ArtifactTypeMappingService getServiceWithRarMappingToMyRar()

-    {

-        try

-        {

-            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration( "artifact-type-mappings" );

-            XmlPlexusConfiguration childConfig =

-                new XmlPlexusConfiguration( ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT );

-            childConfig.setAttribute( "type", "MyRar" );

-            childConfig.setAttribute( "mapping", "rar" );

-            rootConfig.addChild( childConfig );

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( rootConfig );

-

-            return service;

-        }

-        catch ( EarPluginException e )

-        {

-            e.printStackTrace();

-            fail( e.getMessage() );

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( e.getMessage() );

-        }

-        // Won't occur

-        return null;

-

-    }

-

-    protected ArtifactTypeMappingService getDefaultService()

-    {

-        try

-        {

-            ArtifactTypeMappingService service = new ArtifactTypeMappingService();

-            service.configure( new XmlPlexusConfiguration( "dummy" ) );

-

-            return service;

-        }

-        catch ( EarPluginException e )

-        {

-            e.printStackTrace();

-            fail( e.getMessage() );

-        }

-        catch ( PlexusConfigurationException e )

-        {

-            e.printStackTrace();

-            fail( e.getMessage() );

-        }

-        // Won't occur

-        return null;

-    }

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.plugins.ear.EarModuleFactory;
+import org.apache.maven.plugins.ear.EarPluginException;
+import org.apache.maven.plugins.ear.UnknownArtifactTypeException;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+
+/**
+ * Tests for the {@link ArtifactTypeMappingService}
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class ArtifactTypeMappingServiceTest extends TestCase {
+
+    public void testDefaultConfiguration() {
+        ArtifactTypeMappingService service = getDefaultService();
+        for (String type : EarModuleFactory.getStandardArtifactTypes()) {
+            assertTrue("Standard type could not be found", service.isMappedToType(type, type));
+        }
+    }
+
+    public void testIsMappedToTypeForUnknownType() {
+        ArtifactTypeMappingService service = getDefaultService();
+        assertFalse(service.isMappedToType("rar", "MyKoolCustomType"));
+    }
+
+    public void testIsMappedToTypeForKnownType() {
+        ArtifactTypeMappingService service = getServiceWithRarMappingToMyRar();
+        assertTrue(service.isMappedToType("rar", "MyRar"));
+    }
+
+    public void testGetStandardTypeForUknonwnType() {
+        try {
+            ArtifactTypeMappingService service = getDefaultService();
+            service.getStandardType("MyKoolCustomType");
+            fail("Should have failed to retrieve a unknwon custom type");
+        } catch (UnknownArtifactTypeException e) {
+            // That's good
+        }
+    }
+
+    public void testGetStandardTypeForKnownType() {
+        try {
+            ArtifactTypeMappingService service = getServiceWithRarMappingToMyRar();
+            assertEquals("rar", service.getStandardType("MyRar"));
+        } catch (UnknownArtifactTypeException e) {
+            fail("Should not have failed to retrieve a knwon custom type " + e.getMessage());
+        }
+    }
+
+    public void testConfigWithSameCustomType() {
+        try {
+            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration("dummy");
+            XmlPlexusConfiguration childConfig =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("type", "generic");
+            childConfig.setAttribute("mapping", "rar");
+            XmlPlexusConfiguration childConfig2 =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("type", "generic");
+            childConfig.setAttribute("mapping", "ejb");
+
+            rootConfig.addChild(childConfig);
+            rootConfig.addChild(childConfig2);
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(rootConfig);
+            fail("Should have failed");
+        } catch (EarPluginException e) {
+            // OK
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail("Unexpected " + e.getMessage());
+        }
+    }
+
+    public void testConfigWithUnknownStandardType() {
+        try {
+            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration("dummy");
+            XmlPlexusConfiguration childConfig =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("type", "generic");
+            childConfig.setAttribute("mapping", "notAStandardType");
+
+            rootConfig.addChild(childConfig);
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(rootConfig);
+            fail("Should have failed");
+        } catch (EarPluginException e) {
+            // OK
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail("Unexpected " + e.getMessage());
+        }
+    }
+
+    public void testConfigWithNoType() {
+        try {
+            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration("dummy");
+            XmlPlexusConfiguration childConfig =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("mapping", "ejb");
+
+            rootConfig.addChild(childConfig);
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(rootConfig);
+            fail("Should have failed");
+        } catch (EarPluginException e) {
+            // OK
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail("Unexpected " + e.getMessage());
+        }
+    }
+
+    public void testConfigWithNoMapping() {
+        try {
+            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration("dummy");
+            XmlPlexusConfiguration childConfig =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("type", "generic");
+
+            rootConfig.addChild(childConfig);
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(rootConfig);
+            fail("Should have failed");
+        } catch (EarPluginException e) {
+            // OK
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail("Unexpected " + e.getMessage());
+        }
+    }
+
+    // Utilities
+
+    protected ArtifactTypeMappingService getServiceWithRarMappingToMyRar() {
+        try {
+            XmlPlexusConfiguration rootConfig = new XmlPlexusConfiguration("artifact-type-mappings");
+            XmlPlexusConfiguration childConfig =
+                    new XmlPlexusConfiguration(ArtifactTypeMappingService.ARTIFACT_TYPE_MAPPING_ELEMENT);
+            childConfig.setAttribute("type", "MyRar");
+            childConfig.setAttribute("mapping", "rar");
+            rootConfig.addChild(childConfig);
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(rootConfig);
+
+            return service;
+        } catch (EarPluginException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+        // Won't occur
+        return null;
+    }
+
+    protected ArtifactTypeMappingService getDefaultService() {
+        try {
+            ArtifactTypeMappingService service = new ArtifactTypeMappingService();
+            service.configure(new XmlPlexusConfiguration("dummy"));
+
+            return service;
+        } catch (EarPluginException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        } catch (PlexusConfigurationException e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+        // Won't occur
+        return null;
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/util/EarMavenArchiverTest.java b/src/test/java/org/apache/maven/plugins/ear/util/EarMavenArchiverTest.java
index 96830c9..dff0039 100644
--- a/src/test/java/org/apache/maven/plugins/ear/util/EarMavenArchiverTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/util/EarMavenArchiverTest.java
@@ -1,81 +1,90 @@
-package org.apache.maven.plugins.ear.util;

-

-import static org.junit.Assert.assertEquals;

-

-import java.util.ArrayList;

-import java.util.List;

-

-import org.apache.maven.plugins.ear.AbstractEarTestBase;

-import org.apache.maven.plugins.ear.EarModule;

-import org.apache.maven.plugins.ear.EjbModule;

-import org.junit.Test;

-

-/*

- * 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.

- */

-

-/**

- * @author <a href="snicoll@apache.org">Stephane Nicoll</a>

- */

-public class EarMavenArchiverTest

-    extends AbstractEarTestBase

-{

-

-    private List<EarModule> modules = new ArrayList<>();

-

-    @Test

-    public void testSimpleEjbModule()

-    {

-        final EarModule module = new EjbModule( createArtifact( "foo", "ejb" ) );

-        setUri( module, "foo-1.0.jar" );

-        modules.add( module );

-

-        final EarMavenArchiver archiver = new EarMavenArchiver( modules );

-        assertEquals( "foo-1.0.jar", archiver.generateClassPathEntry( "" ) );

-

-    }

-

-    @Test

-    public void testSimpleJarModuleWithCustomBundleDir()

-    {

-        final EarModule module = new EjbModule( createArtifact( "foo", "jar" ) );

-        setUri( module, "libs/foo-1.0.jar" );

-        modules.add( module );

-

-        final EarMavenArchiver archiver = new EarMavenArchiver( modules );

-        assertEquals( "libs/foo-1.0.jar", archiver.generateClassPathEntry( "" ) );

-

-    }

-

-    @Test

-    public void testTwoModules()

-    {

-        final EarModule module = new EjbModule( createArtifact( "foo", "ejb" ) );

-        setUri( module, "foo-1.0.jar" );

-        modules.add( module );

-

-        final EarModule module2 = new EjbModule( createArtifact( "bar", "war" ) );

-        setUri( module2, "bar-2.0.1.war" );

-        modules.add( module2 );

-

-        final EarMavenArchiver archiver = new EarMavenArchiver( modules );

-        assertEquals( "foo-1.0.jar bar-2.0.1.war", archiver.generateClassPathEntry( "" ) );

-

-    }

-

-}
\ No newline at end of file
+/*
+ * 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.maven.plugins.ear.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.plugins.ear.AbstractEarTestBase;
+import org.apache.maven.plugins.ear.EarModule;
+import org.apache.maven.plugins.ear.EjbModule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EarMavenArchiverTest extends AbstractEarTestBase {
+
+    private List<EarModule> modules = new ArrayList<>();
+
+    @Test
+    public void testSimpleEjbModule() {
+        final EarModule module = new EjbModule(createArtifact("foo", "ejb"));
+        setUri(module, "foo-1.0.jar");
+        modules.add(module);
+
+        final EarMavenArchiver archiver = new EarMavenArchiver(modules);
+        assertEquals("foo-1.0.jar", archiver.generateClassPathEntry(""));
+    }
+
+    @Test
+    public void testSimpleJarModuleWithCustomBundleDir() {
+        final EarModule module = new EjbModule(createArtifact("foo", "jar"));
+        setUri(module, "libs/foo-1.0.jar");
+        modules.add(module);
+
+        final EarMavenArchiver archiver = new EarMavenArchiver(modules);
+        assertEquals("libs/foo-1.0.jar", archiver.generateClassPathEntry(""));
+    }
+
+    @Test
+    public void testTwoModules() {
+        final EarModule module = new EjbModule(createArtifact("foo", "ejb"));
+        setUri(module, "foo-1.0.jar");
+        modules.add(module);
+
+        final EarModule module2 = new EjbModule(createArtifact("bar", "war"));
+        setUri(module2, "bar-2.0.1.war");
+        modules.add(module2);
+
+        final EarMavenArchiver archiver = new EarMavenArchiver(modules);
+        assertEquals("foo-1.0.jar bar-2.0.1.war", archiver.generateClassPathEntry(""));
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/util/JavaEEVersionTest.java b/src/test/java/org/apache/maven/plugins/ear/util/JavaEEVersionTest.java
index ac3070d..5de496e 100644
--- a/src/test/java/org/apache/maven/plugins/ear/util/JavaEEVersionTest.java
+++ b/src/test/java/org/apache/maven/plugins/ear/util/JavaEEVersionTest.java
@@ -1,138 +1,128 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * 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.

- */

-

-import junit.framework.TestCase;

-

-/**

- * @author Stephane Nicoll

- */

-public class JavaEEVersionTest

-    extends TestCase

-{

-

-    public void testGtSameVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.gt( JavaEEVersion.FIVE ) );

-    }

-

-    public void testGtNextVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.gt( JavaEEVersion.SIX ) );

-    }

-

-    public void testGtPreviousVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.gt( JavaEEVersion.ONE_DOT_FOUR ) );

-    }

-

-    public void testGeSameVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.ge( JavaEEVersion.FIVE ) );

-    }

-

-    public void testGePreviousVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.ge( JavaEEVersion.ONE_DOT_FOUR ) );

-    }

-

-    public void testGeNextVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.ge( JavaEEVersion.SIX ) );

-    }

-

-    public void testLtSameVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.lt( JavaEEVersion.FIVE ) );

-    }

-

-    public void testLtPreviousVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.lt( JavaEEVersion.ONE_DOT_FOUR ) );

-    }

-

-    public void testLtNextVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.lt( JavaEEVersion.SIX ) );

-    }

-

-    public void testLeSameVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.le( JavaEEVersion.FIVE ) );

-    }

-

-    public void testLePreviousVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.le( JavaEEVersion.ONE_DOT_FOUR ) );

-    }

-

-    public void testLeNextVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.le( JavaEEVersion.SIX ) );

-    }

-

-    public void testEqSameVersion()

-    {

-        assertTrue( JavaEEVersion.FIVE.eq( JavaEEVersion.FIVE ) );

-    }

-

-    public void testEqAnotherVersion()

-    {

-        assertFalse( JavaEEVersion.FIVE.eq( JavaEEVersion.ONE_DOT_THREE ) );

-    }

-

-    public void testGetVersion()

-    {

-        assertEquals( "5", JavaEEVersion.FIVE.getVersion() );

-    }

-

-    public void testGetJavaEEVersionValid() throws InvalidJavaEEVersion

-    {

-        assertEquals( JavaEEVersion.SIX, JavaEEVersion.getJavaEEVersion( "6" ) );

-    }

-

-    public void testGetJavaEEVersionInvalid()

-    {

-        try

-        {

-            JavaEEVersion.getJavaEEVersion( "2.4" );

-            fail( "Should have failed to get an invalid version." );

-        }

-        catch ( InvalidJavaEEVersion expected )

-        {

-            // OK

-        }

-    }

-

-    public void testGetJavaEEVersionNull() throws InvalidJavaEEVersion

-    {

-        try

-        {

-            JavaEEVersion.getJavaEEVersion( null );

-            fail( "Should have failed to get a 'null' version." );

-        }

-        catch ( NullPointerException expected )

-        {

-            // OK

-        }

-

-    }

-

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * 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.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class JavaEEVersionTest extends TestCase {
+
+    public void testGtSameVersion() {
+        assertFalse(JavaEEVersion.FIVE.gt(JavaEEVersion.FIVE));
+    }
+
+    public void testGtNextVersion() {
+        assertFalse(JavaEEVersion.FIVE.gt(JavaEEVersion.SIX));
+    }
+
+    public void testGtPreviousVersion() {
+        assertTrue(JavaEEVersion.FIVE.gt(JavaEEVersion.ONE_DOT_FOUR));
+    }
+
+    public void testGeSameVersion() {
+        assertTrue(JavaEEVersion.FIVE.ge(JavaEEVersion.FIVE));
+    }
+
+    public void testGePreviousVersion() {
+        assertTrue(JavaEEVersion.FIVE.ge(JavaEEVersion.ONE_DOT_FOUR));
+    }
+
+    public void testGeNextVersion() {
+        assertFalse(JavaEEVersion.FIVE.ge(JavaEEVersion.SIX));
+    }
+
+    public void testLtSameVersion() {
+        assertFalse(JavaEEVersion.FIVE.lt(JavaEEVersion.FIVE));
+    }
+
+    public void testLtPreviousVersion() {
+        assertFalse(JavaEEVersion.FIVE.lt(JavaEEVersion.ONE_DOT_FOUR));
+    }
+
+    public void testLtNextVersion() {
+        assertTrue(JavaEEVersion.FIVE.lt(JavaEEVersion.SIX));
+    }
+
+    public void testLeSameVersion() {
+        assertTrue(JavaEEVersion.FIVE.le(JavaEEVersion.FIVE));
+    }
+
+    public void testLePreviousVersion() {
+        assertFalse(JavaEEVersion.FIVE.le(JavaEEVersion.ONE_DOT_FOUR));
+    }
+
+    public void testLeNextVersion() {
+        assertTrue(JavaEEVersion.FIVE.le(JavaEEVersion.SIX));
+    }
+
+    public void testEqSameVersion() {
+        assertTrue(JavaEEVersion.FIVE.eq(JavaEEVersion.FIVE));
+    }
+
+    public void testEqAnotherVersion() {
+        assertFalse(JavaEEVersion.FIVE.eq(JavaEEVersion.ONE_DOT_THREE));
+    }
+
+    public void testGetVersion() {
+        assertEquals("5", JavaEEVersion.FIVE.getVersion());
+    }
+
+    public void testGetJavaEEVersionValid() throws InvalidJavaEEVersion {
+        assertEquals(JavaEEVersion.SIX, JavaEEVersion.getJavaEEVersion("6"));
+    }
+
+    public void testGetJavaEEVersionInvalid() {
+        try {
+            JavaEEVersion.getJavaEEVersion("2.4");
+            fail("Should have failed to get an invalid version.");
+        } catch (InvalidJavaEEVersion expected) {
+            // OK
+        }
+    }
+
+    public void testGetJavaEEVersionNull() throws InvalidJavaEEVersion {
+        try {
+            JavaEEVersion.getJavaEEVersion(null);
+            fail("Should have failed to get a 'null' version.");
+        } catch (NullPointerException expected) {
+            // OK
+        }
+    }
+}
diff --git a/src/test/java/org/apache/maven/plugins/ear/util/ResourceEntityResolver.java b/src/test/java/org/apache/maven/plugins/ear/util/ResourceEntityResolver.java
index d5fcee3..1387f0a 100644
--- a/src/test/java/org/apache/maven/plugins/ear/util/ResourceEntityResolver.java
+++ b/src/test/java/org/apache/maven/plugins/ear/util/ResourceEntityResolver.java
@@ -1,37 +1,50 @@
-package org.apache.maven.plugins.ear.util;

-

-/*

- * Licensed 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.

- */

-

-import java.io.InputStream;

-import org.xml.sax.EntityResolver;

-import org.xml.sax.InputSource;

-

-public class ResourceEntityResolver

-    implements EntityResolver

-{

-    public InputSource resolveEntity( String publicId, String systemId )

-    {

-        String dtd = "/dtd" + systemId.substring( systemId.lastIndexOf( '/' ) );

-        InputStream in = ResourceEntityResolver.class.getResourceAsStream( dtd );

-        if ( in == null )

-        {

-            throw new RuntimeException( "unable to load DTD " + dtd + " for " + systemId );

-        }

-        else

-        {

-            return new InputSource( in );

-        }

-    }

-}

+/*
+ * 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.maven.plugins.ear.util;
+
+/*
+ * Licensed 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.
+ */
+
+import java.io.InputStream;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+public class ResourceEntityResolver implements EntityResolver {
+    public InputSource resolveEntity(String publicId, String systemId) {
+        String dtd = "/dtd" + systemId.substring(systemId.lastIndexOf('/'));
+        InputStream in = ResourceEntityResolver.class.getResourceAsStream(dtd);
+        if (in == null) {
+            throw new RuntimeException("unable to load DTD " + dtd + " for " + systemId);
+        } else {
+            return new InputSource(in);
+        }
+    }
+}